/*
  ==========================================================================
  L'ORDRE DES ÉCRITURES
  ==========================================================================

  Le site écrit dans trois fontes, et pas une quatrième. Elles sont nommées
  ici, une seule fois, et rien plus bas ne nomme une fonte directement : une
  page ne peut donc plus s'écarter des autres, et changer le romain du site
  se fait en une ligne.

    --titre   le romain à empattements des travaux universitaires. Il porte
              tout ce qui se lit comme un titre : l'enseigne, l'accroche de
              l'accueil, les titres de rubrique, les titres de fiche, les
              titres des pages annexes. Il portait auparavant une linéale
              étroite, serrée d'un interlettrage négatif (-.03em) : l'écriture
              des tableaux de bord, pas celle d'un mémoire. La rubrique de
              relecture (assets/relecture.css) écrivait déjà ses titres dans
              ce romain ; le reste du site l'y rejoint.

    --texte   la linéale du texte courant, des paragraphes, des listes, des
              formulaires et des boutons — tout ce qui se lit à l'écran plutôt
              que sur une page de titre. Elle porte aussi les mentions en
              petites capitales espacées (.section-kicker, .footer-title) : le
              contraste du romain et de la capitale linéale est celui des
              pages de titre universitaires.

    --sigle   la linéale étroite, gardée pour les chiffres seuls : taux,
              montants, compteurs, numéros de fiche. Un chiffre a besoin de
              chasses égales pour s'aligner d'une ligne à l'autre ; un romain
              à empattements le donnerait plus beau et moins lisible.

    --mono    la fonte à chasse fixe des empreintes, des codes d'ouverture et
              des liens de vérification : un caractère qui se recopie sans
              confondre le 1 et le l, le 0 et le O.

  Et quatre degrés de titre, un par étage de lecture, pour que deux rubriques
  ne s'ouvrent jamais sur deux tailles différentes :

    --t1  la page      (accroche d'accueil, titre des pages annexes)
    --t2  la rubrique  (les h2 des grandes divisions)
    --t3  la fiche     (les h3 des cartes, des cartouches, des panneaux)
    --t4  la mention   (les petites capitales espacées qui annoncent)
*/
:root {
  --titre: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif;
  --texte: "DM Sans", system-ui, sans-serif;
  --sigle: Manrope, "DM Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  --t1: clamp(27px, 2.9vw, 37px);
  --t2: clamp(23px, 2.4vw, 30px);
  --t3: 18px;
  --t4: 10.5px;

  --navy: #0a1730;
  --navy-2: #0f2344;
  --ink: #15243d;
  --muted: #66748a;
  --line: #e4eaf1;
  --soft: #f5f8fb;
  --blue: #1769e0;
  --cyan: #18a6d9;
  --white: #fff;
  --shadow: 0 22px 60px rgba(10, 23, 48, .12);
}

* { box-sizing: border-box; }
/* L'attribut hidden passe avant toute règle de classe. Sans cela, un bloc
   masqué en HTML — le rapport scellé, le bandeau des exemplaires, la fiche du
   fichier déposé — dont la classe pose un display (flex, grid, block) reste
   affiché : la règle d'auteur l'emporte sur celle du navigateur. Il s'ouvrait
   alors des cadres vides au milieu de la page, qui écartaient la suite sans
   rien dire. La rubrique de relecture pose la même règle chez elle
   (assets/relecture.css) ; le reste du site l'y rejoint, et les gardes
   écrites une à une plus bas n'ont plus à être répétées. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--texte);
  color: var(--ink);
  background: var(--white);
  line-height: 1.65;
}
a { color: inherit; text-decoration: none; }
.container { width: min(1160px, calc(100% - 40px)); margin: 0 auto; }

.site-header {
  position: sticky; top: 0; z-index: 20;
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(228,234,241,.8);
}
.nav-wrap { min-height: 66px; display:flex; align-items:center; justify-content:space-between; gap: 30px; }
/* L'enseigne de FONTEXTE, composée comme la page de titre d'un mémoire : le
   sceau, le nom en romain largement espacé, un filet, et sous le filet les
   trois fonctions du site.

   Elle portait auparavant un carré bleu marqué d'un « F » collé au nom, si
   bien qu'on lisait la lettre deux fois — « F FONTEXTE ». Le sceau
   (assets/icons/sceau.svg) ne porte plus de lettre : il porte l'emblème du
   site, la loupe de la favicon et de l'icône de l'application. Le nom ne se
   redit donc plus.

   Tout est décrit ici, et rien dans les pages : les sept en-têtes du site
   (accueil, vérification, rapport, ouverture, connexion, administration, 404)
   portent la même enseigne parce qu'ils portent le même balisage. */
.brand { display:flex; align-items:center; gap:14px; }
.brand-seal {
  flex:none; width:44px; height:44px;
  background:url("/assets/icons/sceau.svg") center/contain no-repeat;
}
.brand-name { display:flex; flex-direction:column; align-items:stretch; }
/* Le nom, dans le romain à empattements des travaux universitaires. La marge
   négative reprend le blanc que l'espacement des lettres ajoute après la
   dernière : sans elle, le nom paraîtrait poussé vers la gauche de son
   bloc — ce qui se verrait sur téléphone, où il est seul à le tenir. */
.brand-word {
  margin-right:-.2em;
  font-family:var(--titre); font-weight:600;
  font-size:20px; line-height:1.15; letter-spacing:.2em; color:var(--navy);
}
/* Les trois fonctions, sous le filet : en capitales espacées, dans la fonte du
   texte courant — le contraste du romain à empattements et de la capitale sans
   empattement est celui des pages de titre universitaires. */
.brand-scope {
  margin-top:5px; padding-top:5px; border-top:1px solid var(--line);
  font-family:var(--texte); color:var(--muted); font-size:8.4px; font-weight:600;
  letter-spacing:.09em;
  text-transform:uppercase;
}

.nav { display:flex; align-items:center; gap:28px; font-size:14px; font-weight:600; }
.nav a:not(.nav-cta):hover { color:var(--blue); }
.nav-cta { padding:11px 17px; background:var(--navy); color:#fff; border-radius:9px; }
.menu-toggle { display:none; border:0; background:none; font-size:25px; color:var(--navy); }

.hero {
  position:relative; overflow:hidden; background:
  radial-gradient(circle at 90% 20%, rgba(24,166,217,.14), transparent 32%),
  linear-gradient(135deg,#f7fbff 0%,#fff 55%);
  padding: 38px 0 32px;
}
/* La bannière ne porte plus de carte de démonstration : le texte d'accueil
   occupe la première colonne, le globe terrestre la seconde. */
.hero-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,320px); gap:28px; align-items:center; }
.hero-copy { max-width:780px; }

/* Globe terrestre de la bannière. Le disque est fixe — ombré comme une sphère,
   quadrillé de ses parallèles et de ses méridiens —, et c'est la carte qui
   défile dessous, de la droite vers la gauche. La carte est posée deux fois
   bout à bout et le déplacement d'un tour vaut exactement sa largeur (360
   degrés de longitude) : la boucle se referme sans saut. */
.hero-globe { display:flex; justify-content:center; }
.globe { width:100%; max-width:300px; height:auto; filter:drop-shadow(0 18px 34px rgba(12,52,120,.28)); }
.globe-spin { animation:globe-turn 36s linear infinite; will-change:transform; }
.globe-grid { stroke-width:.7; opacity:.28; }
@keyframes globe-turn {
  from { transform:translateX(0); }
  to   { transform:translateX(-360px); }
}
/* Un appareil qui demande moins d'animation garde le globe, immobile. */
@media (prefers-reduced-motion:reduce) {
  .globe-spin { animation:none; }
}
@media (max-width:900px) {
  .globe { max-width:210px; }
}
/* ------------------------------------------------ tous les titres du site --

   Un seul endroit donne à un titre son romain, sa graisse et son
   interlettrage ; les règles particulières, plus bas, ne règlent plus que la
   taille, la couleur et les marges. Trois choses s'y décident :

   La graisse — 600, la seule graisse de titre chargée. Laissé libre, un
   navigateur prend le gras des titres (700) et, ne le trouvant pas, l'imite en
   épaississant le 600 : le trait s'empâte et les empattements se ferment.
   Écrite ici, elle ne peut plus être oubliée d'une règle à l'autre.

   L'interlettrage — nul. Les titres étaient serrés d'un vingtième de cadratin
   (-.03em) : la lettre resserrée des tableaux de bord. Un romain à
   empattements se lit sur sa chasse naturelle, sans qu'on le comprime.

   L'équilibre des lignes — `text-wrap:balance` répartit un titre de deux ou
   trois lignes en lignes de longueur voisine, au lieu d'en laisser un mot seul
   sur la dernière. C'est ce qu'un metteur en pages fait à la main.

   La liste nomme les titres qui ne sont pas des `h1`/`h2`/`h3` : dans une
   fiche, un cartouche ou un panneau, le titre est porté par un `strong`, la
   fiche entière tenant déjà sous le titre de sa rubrique. */
h1, h2, h3,
.eyebrow, .sim-label,
.contact-head strong, .cert-head strong, .auth-body strong, .alert-card strong,
.verify-status strong, .pay-locked strong, .report-score strong,
.passage header strong, .ai-head strong {
  font-family:var(--titre); font-weight:600; letter-spacing:0;
  line-height:1.18; text-wrap:balance;
}

/* La mention qui annonce une rubrique — « Fonction 1 », « Tarifs », « CAMES ».
   Petites capitales largement espacées, dans la linéale du texte : le contraste
   de la capitale linéale et du romain à empattements qui la suit est celui des
   pages de titre universitaires. Le rang de la rubrique la précède, séparé
   d'elle par un filet vertical (voir .section-rank). */
.section-kicker {
  display:flex; align-items:center; margin:0;
  font-family:var(--texte); font-size:var(--t4); font-weight:700;
  letter-spacing:.19em; text-transform:uppercase; color:var(--blue);
}
/* Le rang de la rubrique, en chiffres romains : l'accueil est une seule page
   longue, et sans ces rangs ses sept divisions se suivent sans qu'on sache
   laquelle on lit ni combien il en reste. Le chiffre est écrit dans le romain
   des titres, et un filet le sépare de la mention, comme le numéro d'une
   partie sur un sommaire. Les pages annexes n'en portent pas : elles n'ont
   qu'une seule division, et un rang isolé ne classerait rien. */
.section-rank {
  flex:none; font-family:var(--titre); font-weight:600; font-size:13px;
  letter-spacing:.1em; color:var(--navy);
  padding-right:12px; margin-right:12px; border-right:1px solid var(--line);
}
/*
  L'accroche de l'accueil et le titre ne forment qu'un seul bloc de texte :
  même romain, même taille, même graisse, même interlettrage. La couleur
  d'accent reste réservée à la dernière ligne du titre.
*/
.eyebrow,.hero h1 { font-size:var(--t1); color:var(--navy); text-transform:none; }
.eyebrow { margin:0; }
/* La seconde fonction, nommée sous la première dans l'enseigne d'accueil :
   même romain, un cran plus petite, en bleu et en italique — l'italique dit
   qu'on ajoute une précision au titre sans ouvrir un second titre. */
.eyebrow-second {
  display:block; margin-top:3px; font-size:clamp(18px,1.8vw,23px);
  font-style:italic; font-weight:500; color:var(--blue);
}
.hero h1 { margin:10px 0 12px; }
.hero h1 span { color:var(--blue); }
.hero-text { max-width:640px; color:var(--muted); font-size:15.5px; }
/* La promesse d'accès, posée seule sous le paragraphe d'accueil. */
.hero-claim { margin-top:8px; font-weight:700; color:var(--ink); }
.hero-actions { display:flex; gap:12px; flex-wrap:wrap; margin:16px 0 0; }
.btn { display:inline-flex; align-items:center; gap:14px; padding:12px 18px; border-radius:10px; font-weight:700; font-size:13.5px; transition:.2s; }
/* Un bouton masqué reste masqué : `display:inline-flex` l'emporterait sinon sur
   l'attribut `hidden`, et un bouton sans objet — « Plier les encaissées » quand
   rien n'est encaissé — resterait à l'écran. */
.btn[hidden] { display:none; }
.btn span { font-size:20px; line-height:0; }
.btn-primary { background:var(--blue); color:#fff; box-shadow:0 12px 30px rgba(23,105,224,.2); }
.btn-primary:hover { transform:translateY(-2px); }
.btn-secondary { border:1px solid var(--line); background:#fff; }

/* Bouton « Installer l'application » : révélé par assets/pwa-install.js quand
   le navigateur accepte d'ajouter FONTEXTE à l'écran d'accueil. La loupe du
   bouton est celle de l'icône installée, pour qu'on la reconnaisse ensuite. */
.btn-install {
  gap:10px; border:1px solid #cfe1fa; background:#f1f7ff; color:var(--navy);
}
.btn-install:hover { background:#e4f0fe; }
.btn-install[hidden] { display:none; }
.btn-install img { width:20px; height:20px; border-radius:5px; flex:none; }

/* Même bouton dans la barre de navigation, à côté de « Services » : il y prend
   la taille des autres entrées du menu. */
.nav-install { padding:9px 13px; font-size:13px; gap:8px; }
.nav-install img { width:17px; height:17px; }

/* Même bouton dans la bannière d'accueil, à la suite des deux appels à l'action.
   Il y garde la taille des boutons voisins, et reste visible sur téléphone, là
   où la barre de navigation se replie derrière le menu ☰. */
.hero-install { padding:12px 18px; font-size:13.5px; }

/* Dans l'application déjà installée, il n'y a plus rien à installer : le bouton
   s'efface sans attendre que le script s'en charge, pour qu'il n'apparaisse pas
   le temps du chargement. */
@media all and (display-mode: standalone) {
  .btn-install { display:none; }
}
@media all and (display-mode: fullscreen) {
  .btn-install { display:none; }
}

/* Bande d'assistance, juste sous la bannière : les deux cas qui sortent du
   parcours ordinaire — le blocage technique et l'accès illimité — et l'adresse
   qui les règle. Écrite en gras pour se voir avant tout le reste de l'accueil. */
.support-band { padding:16px 0 0; }
.support-callout {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:10px 24px; padding:15px 20px; border:1px solid #cfe0f7; border-radius:14px;
  background:linear-gradient(180deg,#f2f7ff,#eaf2ff); color:var(--ink);
}
.support-cases { margin:0; padding:0 0 0 19px; list-style:disc; font-size:14px; line-height:1.55; }
.support-cases li { margin:0 0 2px; }
.support-cases li::marker { color:var(--blue); }
.support-cases strong { color:var(--navy); font-weight:800; }
.support-call { margin:0; font-size:14px; font-weight:700; color:var(--navy); }
.support-call strong { display:block; font-weight:800; }
.support-call a { color:var(--blue); font-weight:800; word-break:break-word; }
.support-call a:hover { text-decoration:underline; }
@media (max-width:720px) {
  .support-band { padding-top:18px; }
  .support-callout { padding:17px 18px; }
  .support-cases, .support-call { font-size:14px; }
}

/* Panneau « Contact / Demander un accès » — même fiche sur toutes les pages,
   construite par assets/contact-panel.js. La typographie reprend, en un peu plus
   grand, celle du bloc de présentation ci-dessus. */
.contact-panel { position:fixed; inset:0; z-index:80; display:grid; place-items:center; padding:20px; }
.contact-panel[hidden] { display:none; }
.contact-backdrop { position:absolute; inset:0; background:rgba(10,23,48,.55); backdrop-filter:blur(3px); }
.contact-card {
  position:relative; z-index:1; width:min(560px,100%); max-height:calc(100vh - 40px);
  overflow:auto; background:#fff; border:1px solid var(--line); border-radius:20px;
  padding:26px 28px; box-shadow:0 30px 70px rgba(10,23,48,.32);
}
.contact-close {
  position:absolute; top:12px; right:14px; width:32px; height:32px; border:0; cursor:pointer;
  border-radius:50%; background:#f2f6fb; color:#42546d; font-size:20px; line-height:1;
}
.contact-close:hover { background:#e6eef8; }
.contact-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding-right:34px; }
.contact-tag {
  flex:none; text-transform:uppercase; letter-spacing:.16em; font-size:var(--t4); font-weight:700;
  color:var(--blue); background:#edf4fc; border-radius:99px; padding:5px 11px;
}
.contact-head strong { font-family:var(--titre); font-size:18px; color:var(--navy); }
.contact-points { list-style:none; padding:0; margin:18px 0 0; display:grid; gap:13px; }
.contact-points li { position:relative; padding-left:26px; font-size:15px; line-height:1.5; }
.contact-points li::before {
  content:"✓"; position:absolute; left:0; top:1px; color:#1c9c6b; font-weight:800; font-size:14px;
}
.contact-points b { color:var(--navy); }
.contact-points span { display:block; color:#647286; font-size:14px; }
.contact-mail {
  margin:19px 0 0; padding-top:16px; border-top:1px dashed var(--line);
  color:#647286; font-size:15px; line-height:1.6;
}
.contact-mail b { display:block; color:var(--navy); font-size:15.5px; margin-bottom:3px; }
.contact-mail a { color:var(--blue); font-weight:700; word-break:break-word; }
.contact-mail a:hover { text-decoration:underline; }
.contact-actions { display:flex; flex-wrap:wrap; gap:12px; margin-top:22px; }

/* La même fiche, en plus courte : la fenêtre de « Corriger et nettoyer »
   (assets/clean-panel.js) ne porte qu'une phrase et l'adresse à écrire, aussi
   la carte est-elle resserrée et son unique paragraphe dispensé du filet de
   séparation, qui ne séparerait rien. */
.clean-panel .contact-card-courte { width:min(430px,100%); padding:24px 26px; }
.clean-panel .contact-mail { margin-top:16px; padding-top:0; border-top:0; color:#42546d; }

.section { padding:38px 0; }
h2 { font-size:var(--t2); margin:9px 0 0; color:var(--navy); }

/* La tête d'une rubrique : le rang et la mention, le titre, et le chapeau
   qui l'accompagne à droite. Un filet la ferme par le bas — chaque rubrique
   s'ouvre donc comme un chapitre, et le lecteur voit du premier coup d'œil où
commentaire des divisions
.section-heading {
  display:flex; justify-content:space-between; align-items:end; gap:28px;
  padding-bottom:17px; margin-bottom:24px; border-bottom:1px solid var(--line);
}
/* Le chapeau : une seule phrase, tenue sur une largeur de lecture (une ligne
   trop longue se relit mal), alignée sur le bas du titre. */
.section-heading p { max-width:44ch; color:var(--muted); margin:0; font-size:14.5px; line-height:1.6; }
.footer { background:#071225; color:#fff; padding:30px 0 14px; }
.footer-grid { display:grid; grid-template-columns:1.4fr .7fr .7fr; gap:32px; padding-bottom:22px; }
/* Le nom au pied de page reprend l'enseigne de l'en-tête — même romain, même
   espacement, même filet dessous — pour que le site s'ouvre et se ferme sur la
   même signature. */
.footer-brand {
  font-family:var(--titre); font-weight:600;
  font-size:21px; letter-spacing:.18em; padding-bottom:10px;
  border-bottom:1px solid rgba(255,255,255,.14); margin-bottom:12px;
}
.footer p { max-width:360px; color:#94a3b8; font-size:13px; }
.footer a { display:block; color:#b8c3d2; font-size:13px; margin:6px 0; }
.footer-title { display:block; text-transform:uppercase; letter-spacing:.16em; color:#6f8099; font-size:var(--t4); font-weight:700; margin-bottom:13px; }
.footer-bottom { border-top:1px solid rgba(255,255,255,.09); padding-top:18px; display:flex; justify-content:space-between; gap:20px; color:#718097; font-size:11px; }

@media (max-width: 900px) {
  .nav { display:none; position:absolute; left:20px; right:20px; top:70px; background:#fff; border:1px solid var(--line); border-radius:12px; padding:15px; box-shadow:var(--shadow); flex-direction:column; align-items:stretch; }
  .nav.open { display:flex; }
  .menu-toggle { display:block; }
  .hero-grid { grid-template-columns:1fr; gap:22px; }
  .hero { padding-top:30px; }
  .footer-grid { grid-template-columns:1fr 1fr; }
}
@media (max-width: 560px) {
  .container { width:min(100% - 28px,1160px); }
  /* Sur un téléphone, l'enseigne garde le sceau et le nom ; la ligne des trois
     fonctions se retire plutôt que de s'enrouler sur trois lignes et de
     pousser l'en-tête vers le bas. Le titre de la page la redit de toute
     façon, juste dessous. */
  .brand { gap:11px; }
  .brand-seal { width:38px; height:38px; }
  .brand-word { font-size:17px; letter-spacing:.16em; margin-right:-.16em; }
  /* Le rang d'une rubrique se resserre contre sa mention : sur une ligne
     étroite, chaque millimètre repris est un mot de plus avant le retour. */
  .section-rank { font-size:12px; padding-right:9px; margin-right:9px; }
  .section-kicker { letter-spacing:.14em; }
  .brand-scope { display:none; }
  .eyebrow,.hero h1 { font-size:25px; }
  .hero-text { font-size:15px; }
  .section { padding:42px 0; }
  .section-heading { display:block; }
  .section-heading p { margin-top:14px; }
  .footer-grid { grid-template-columns:1fr; gap:24px; }
  .footer-bottom { flex-direction:column; }
}

/* ============================================================
   Outil d'analyse et rapport
   ============================================================ */
.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* L'espace qui sépare le bas de l'analyse (« Ce qui n'est jamais compté comme
   plagiat ») du titre de la seconde fonction est resserré au minimum : les deux
   blocs se suivent immédiatement, sans respiration entre eux. */
.analyse { background:linear-gradient(180deg,#fff 0%,#f7fafd 100%); border-top:1px solid var(--line); padding-bottom:0; }
/* Le dépôt occupe toute la largeur de la rubrique. Il partageait la ligne avec
   un encart bleu nuit — « Demander l'expertise humaine » —, retiré : l'adresse
   qu'il donnait est déjà celle de « Contact » dans l'en-tête et celle de la
   bande d'assistance, juste sous la bannière. Le cadre reste une grille d'une
   seule colonne, pour que le dépôt garde sa gouttière et son alignement. */
.analyse-shell { display:grid; grid-template-columns:minmax(0,1fr); gap:20px; align-items:start; }

.analyse-form {
  background:#fff; border:1px solid var(--line); border-radius:20px; padding:22px;
  box-shadow:0 10px 40px rgba(15,35,68,.05);
}

.drop {
  display:grid; place-items:center; gap:6px; text-align:center; cursor:pointer;
  padding:22px 20px; border:2px dashed #cddced; border-radius:16px; background:#fafcfe;
  transition:border-color .2s, background .2s, transform .2s;
}
.drop:hover, .drop:focus-visible { border-color:var(--blue); background:#f4f9ff; }
.drop:focus-visible { outline:3px solid rgba(23,105,224,.25); outline-offset:2px; }
.drop.is-over { border-color:var(--blue); background:#eef6ff; transform:scale(1.005); }
.drop-icon {
  width:46px; height:46px; border-radius:14px; display:grid; place-items:center; font-size:22px;
  background:linear-gradient(145deg,var(--blue),var(--cyan)); color:#fff;
}
.drop strong { font-family:var(--texte); font-weight:700; font-size:15px; color:var(--navy); }
.drop small { color:var(--muted); font-size:11.5px; }
/* Zone de dépôt inerte tant que la session n'est pas confirmée. */
.drop[aria-disabled="true"] { cursor:not-allowed; opacity:.5; }
.drop[aria-disabled="true"]:hover { border-color:#cddced; background:#fafcfe; }

.file-info {
  display:flex; align-items:center; gap:12px; margin-top:12px; padding:11px 14px;
  background:#f1f7ff; border:1px solid #d9e7fa; border-radius:11px; font-size:13px;
}
.file-info strong { font-weight:700; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.file-info span { color:var(--muted); font-size:11.5px; flex:none; }
.file-info button {
  margin-left:auto; flex:none; border:1px solid #cbdcf2; background:#fff; color:#3f6cbe;
  border-radius:7px; padding:5px 10px; font-size:11px; font-weight:700; cursor:pointer;
}
.file-info button:hover { background:#e9f2fe; }

.or-line { display:flex; align-items:center; gap:14px; margin:20px 0 14px; color:#9aa7b7; font-size:11px; letter-spacing:.08em; text-transform:uppercase; font-weight:800; }
.or-line::before, .or-line::after { content:""; height:1px; flex:1; background:var(--line); }

/* La zone de saisie a quitté le formulaire : le champ subsiste, masqué, et ne
   doit rien occuper. Le style demeure pour les rares textarea encore posées
   dans ce formulaire (les références, elles aussi repliées hors de la page). */
.analyse-form textarea[hidden] { display:none; }
.analyse-form textarea {
  width:100%; margin-top:14px; border:1px solid var(--line); border-radius:13px; padding:15px;
  font-family:inherit; font-size:14px; color:var(--ink); line-height:1.6; resize:vertical;
  background:#fcfdfe;
}
.analyse-form textarea:focus { outline:none; border-color:var(--blue); box-shadow:0 0 0 4px rgba(23,105,224,.1); }

.refs-panel { padding:14px 2px 0; }
.refs-panel p { margin:0 0 10px; color:var(--muted); font-size:12.5px; }
.refs-panel code, .side-note code { background:#eef4fc; color:#33608f; padding:1px 5px; border-radius:5px; font-size:11.5px; }

.options { margin:12px 0 0; padding:12px 15px; border:1px solid var(--line); border-radius:12px; }
.options legend { padding:0 7px; font-size:var(--t4); font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
.options label { display:inline-flex; align-items:center; gap:8px; margin:4px 18px 4px 0; font-size:13px; font-weight:600; cursor:pointer; }
.options input { accent-color:var(--blue); width:16px; height:16px; }
.options label.option-net { display:flex; align-items:flex-start; margin:10px 0 0; padding-top:10px; border-top:1px solid var(--line); flex-wrap:wrap; }
/* Étape acquise : la case est cochée pour de bon, donc ni cliquable ni grisée —
   elle dit ce qui est fait, elle ne demande plus rien. */
.options label.option-locked { cursor:default; }
.options label.option-locked input { pointer-events:none; }

.analyse-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:14px; }
.btn-danger { background:#c8452f; color:#fff; }
.btn-danger:hover { background:#b03a26; }
.btn-ghost { color:var(--blue); background:#f1f7ff; }
.btn-ghost:hover { background:#e4f0fe; }
.btn[disabled] { opacity:.45; cursor:not-allowed; transform:none; box-shadow:none; }

.counter { margin:11px 0 0; color:var(--muted); font-size:12px; }
.form-error {
  margin:13px 0 0; padding:11px 14px; border-radius:10px; font-size:13px;
  background:#fdeceb; color:#a5321f; border:1px solid #f6d3cd;
}

.progress { margin-top:16px; padding:16px 18px; border:1px solid #dceafa; background:#f6faff; border-radius:14px; }
.progress-top { display:flex; justify-content:space-between; align-items:baseline; gap:14px; font-size:13px; }
.progress-top strong { font-family:var(--sigle); color:var(--navy); }
.progress-top span { color:var(--muted); font-size:12px; }
.progress-top b { color:var(--blue); font-size:14px; }
.progress-top i { font-style:normal; }
.progress-track { height:9px; margin-top:11px; border-radius:99px; background:#e3edf9; overflow:hidden; }
.progress-track i {
  display:block; height:100%; border-radius:99px; transform:scaleX(0); transform-origin:left;
  background:linear-gradient(90deg,var(--blue),var(--cyan)); transition:transform .18s linear;
}
.progress-wait { margin:11px 0 0; color:#c62f2f; font-size:13px; font-weight:800; }

.side-note { background:rgba(102,212,240,.1); border:1px solid rgba(102,212,240,.25); border-radius:12px; padding:14px; font-size:12px; color:#c3d4e4; margin-bottom:18px; }
.side-note strong { display:block; color:#66d4f0; font-size:var(--t4); font-weight:700; text-transform:uppercase; letter-spacing:.16em; margin-bottom:7px; }

/* ------------------------------------------------------------- rapport */
.report { margin-top:24px; }
.report h4 {
  font-family:var(--texte); font-size:12px; font-weight:700; text-transform:uppercase;
  letter-spacing:.16em; color:var(--blue); margin:0 0 15px; display:flex; align-items:center; flex-wrap:wrap;
}
.report-head, .report-block, .certificate {
  background:#fff; border:1px solid var(--line); border-radius:18px; padding:24px; margin-bottom:16px;
}
.report-head { display:flex; justify-content:space-between; align-items:center; gap:26px; flex-wrap:wrap; }
.report-head-main { flex:1 1 320px; min-width:0; }
.report-head-main h3, .report-meta { overflow-wrap:anywhere; }
.report-head h3 { font-family:var(--titre); font-size:23px; margin:8px 0 6px; color:var(--navy); }
/* Nom reconnu dans le document, annoncé avant les mesures. */
.report-author { margin:0 0 6px; color:var(--navy); font-size:13.5px; overflow-wrap:anywhere; }
.report-meta { margin:0; color:#4d5c72; font-size:13px; }
.report-score { display:flex; align-items:center; gap:15px; }
.report-score .ring {
  width:86px; height:86px; border-radius:50%; display:grid; place-items:center; flex:none;
  font-family:var(--sigle); font-weight:800; font-size:23px; color:var(--navy);
  background:conic-gradient(var(--ring,#1769e0) calc(var(--v) * 1%), #eaf0f7 0);
  position:relative;
}
.report-score .ring::before { content:""; position:absolute; inset:9px; background:#fff; border-radius:50%; }
/* Le taux affiché dans l'anneau comporte une décimale et le signe % : la
   taille de police laisse la place à « 100,0 % ». */
.report-score .ring span { position:relative; font-size:19px; }
.report-score.good .ring { --ring:#1c9c6b; }
.report-score.warn .ring { --ring:#d98324; }
.report-score.bad .ring { --ring:#c8452f; }
/* Anneau du taux de similitude : même barème de couleurs que le bandeau. */
.report-score.sim-green .ring { --ring:#1c9c6b; }
.report-score.sim-green strong { color:#127750; }
.report-score.sim-orange .ring { --ring:#e08a1e; }
.report-score.sim-orange strong { color:#96601a; }
.report-score.sim-red .ring { --ring:#c8452f; }
.report-score.sim-red strong { color:#b23a26; }
.report-score strong { display:block; font-family:var(--titre); font-size:16px; color:var(--navy); }
.report-score small { color:#55647b; font-size:12px; }

.metric-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(206px,1fr)); gap:12px; margin-bottom:16px; }
.metric { background:#fff; border:1px solid var(--line); border-radius:14px; padding:16px; }
.metric-top { display:flex; justify-content:space-between; align-items:baseline; gap:10px; font-size:13px; font-weight:700; color:#3f4f66; }
.metric-top strong { font-family:var(--sigle); font-size:16px; color:var(--navy); }
.metric-track { height:7px; border-radius:99px; background:#eef3f8; margin:11px 0 8px; overflow:hidden; }
.metric-track i { display:block; height:100%; border-radius:99px; background:var(--blue); }
.metric.good .metric-track i { background:#1c9c6b; }
.metric.warn .metric-track i { background:#d98324; }
.metric.bad .metric-track i { background:#c8452f; }
.metric small { color:#55647b; font-size:12.5px; }

.stat-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(158px,1fr)); gap:10px; }
.stat { background:#f7fafd; border:1px solid #eaf0f6; border-radius:11px; padding:12px 14px; }
.stat span { display:block; color:#55647b; font-size:12.5px; }
.stat strong { font-family:var(--sigle); font-size:18px; color:var(--navy); }

.reco { margin:0; padding-left:20px; }
.reco li { margin:9px 0; font-size:15px; }
/* Les recommandations sont annoncées en rouge : elles disent ce qu'il reste à
   reprendre dans le document, avant le reste du rapport. */
.report-reco h4, .reco li, .reco li strong { color:#c8452f; }
.reco li::marker { color:#c8452f; font-weight:700; }
.report-note { background:#f1f7ff; border:1px solid #d8e7fb; color:#34526f; border-radius:12px; padding:14px 16px; font-size:13.5px; margin-bottom:16px; }
.block-intro { margin:0 0 14px; color:#55647b; font-size:14px; }
.empty { margin:0; color:#55647b; font-size:14px; }
.badge { background:#edf4fc; color:var(--blue); border-radius:99px; padding:3px 10px; font-size:12px; margin-left:9px; letter-spacing:0; text-transform:none; }

.passages { display:grid; gap:11px; }
.passage { border:1px solid var(--line); border-radius:13px; padding:15px; background:#fdfefe; }
.passage header { display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:13px; margin-bottom:11px; }
.passage-num { width:24px; height:24px; flex:none; border-radius:7px; background:#edf4fc; color:var(--blue); display:grid; place-items:center; font-weight:800; font-size:12px; }
.passage header strong { font-family:var(--titre); color:var(--navy); }
.passage-pos { margin-left:auto; color:#5f6e83; }
.passage blockquote {
  margin:0; padding:13px 15px; background:#f5f8fb; border-left:3px solid var(--blue);
  border-radius:0 9px 9px 0; font-size:15px; line-height:1.6; color:#22314a; overflow-wrap:anywhere;
}
.passage-echo { margin-top:11px; font-size:14px; line-height:1.6; color:#3d4c62; overflow-wrap:anywhere; }
.passage-echo span { font-weight:800; color:var(--blue); margin-right:8px; font-size:11px; text-transform:uppercase; letter-spacing:.08em; }

/* Ce qui est repéré, mentionné et non compté : citations dont la référence est
   donnée, notes de bas de page, extraits du corpus. Le bloc se distingue des
   relevés de similitude — ce n'est pas un reproche, c'est une déduction — et son
   vert repose sur le même gris de fond que le reste du rapport. */
.report-excluded { border-left:4px solid #2f8f6b; }
.report-excluded h4 .badge { background:#e8f6f0; color:#227054; }
.excluded-counts { margin:0 0 14px; color:#227054; font-size:13.5px; font-weight:600; }
.passage-excluded { background:#f8fdfa; border-color:#cfe8dd; }
.passage-excluded blockquote { background:#eff9f4; border-left-color:#2f8f6b; }
.passage-excluded .passage-num { background:#e8f6f0; color:#227054; }
.passage-excluded .passage-echo span { color:#227054; }
.block-note { margin:14px 0 0; color:#55647b; font-size:13.5px; }

.source-list { display:grid; gap:9px; margin-bottom:15px; }
.source-list div { border:1px solid var(--line); border-radius:10px; padding:11px 13px; font-size:14px; }
.source-list span { display:block; color:#55647b; font-size:12.5px; }

/* Le détail que l'on peut vouloir vérifier, sans qu'il encombre la lecture :
   liste exacte des corpus, sources de faible emprise, passages supplémentaires. */
.corpus-detail { margin:0 0 15px; border:1px solid var(--line); border-radius:10px; background:#fbfcfe; }
.corpus-detail > summary { cursor:pointer; padding:10px 13px; font-size:13px; color:#42618a; list-style:none; }
.corpus-detail > summary::-webkit-details-marker { display:none; }
.corpus-detail > summary::before { content:'▸ '; color:#8aa0bd; }
.corpus-detail[open] > summary::before { content:'▾ '; }
.corpus-detail > summary:hover { color:var(--blue); }
.corpus-detail > p { margin:0; padding:0 13px 12px; font-size:12.5px; color:#55647b; word-break:break-word; }
.corpus-detail > .source-list,
.corpus-detail > .passages { margin:0; padding:0 13px 13px; }

.rule-counts { display:flex; flex-wrap:wrap; gap:7px; margin-top:15px; }
.rule-counts span { background:#f2f6fb; border-radius:99px; padding:6px 12px; font-size:12.5px; color:#39485f; }
.rule-counts i { font-style:normal; color:var(--blue); font-weight:800; margin-left:7px; }
.rule-counts { margin-top:18px; }

.certificate { border:2px solid var(--navy); }
.cert-head { display:flex; align-items:center; gap:15px; margin-bottom:18px; }
.cert-seal {
  width:56px; height:56px; flex:none; border-radius:50%; background:var(--navy); color:#fff;
  display:grid; place-items:center; font-family:var(--sigle); font-size:11px; font-weight:800; letter-spacing:.08em;
}
.cert-head strong { display:block; font-family:var(--titre); font-size:17px; color:var(--navy); }
.cert-head small { color:#55647b; font-size:12.5px; }
.cert-grid { margin-top:2px; }
.cert-row { display:flex; justify-content:space-between; gap:18px; padding:10px 0; border-bottom:1px dashed #dfe6ee; font-size:14px; }
.cert-grid .cert-row:last-child { border-bottom:none; }
.cert-row span { color:#55647b; flex:none; max-width:240px; }
.cert-row strong { text-align:right; font-weight:600; word-break:break-all; }

.report-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:18px; align-items:center; }
.cert-register-state, .report-pdf-state { font-size:13px; color:#55647b; }
.cert-register-state.is-ok, .report-pdf-state.is-ok { color:#127750; font-weight:700; }
.cert-register-state.is-bad, .report-pdf-state.is-bad { color:#b23a26; font-weight:700; }
/* La mise en pages du PDF prend quelques secondes : le bouton reste en place,
   désactivé, et l'état s'écrit à côté plutôt que de déplacer les commandes. */
.report-actions .btn[disabled] { opacity:.62; cursor:progress; }

/* ------------------------------- authentification du rapport (code QR) */
/* Premier bloc du rapport, donc première page à l'impression comme à
   l'export : le code QR ouvre /verifier.html, qui recalcule le sceau. */
.report-auth {
  display:flex; gap:24px; align-items:flex-start; flex-wrap:wrap;
  background:#fff; border:2px solid var(--navy); border-radius:16px;
  padding:20px 24px; margin-bottom:16px;
}
.auth-qr { flex:none; text-align:center; }
.auth-qr svg { display:block; width:150px; height:150px; border-radius:8px; }
.auth-qr small { display:block; margin-top:7px; font-size:12px; color:#4d5c72; letter-spacing:.02em; }
.auth-qr-fallback { display:grid; place-items:center; width:150px; height:150px; background:#f2f6fb; border-radius:8px; font-size:12.5px; color:#42546d; padding:10px; }
.auth-body { flex:1; min-width:255px; }
.auth-tag {
  display:inline-block; font-size:11px; font-weight:800; letter-spacing:.13em; text-transform:uppercase;
  color:var(--blue); background:#edf4fc; border-radius:99px; padding:5px 11px;
}
.auth-body strong { display:block; font-family:var(--titre); font-size:18px; color:var(--navy); margin:10px 0 7px; }
.auth-lede { margin:0 0 12px; font-size:14px; line-height:1.55; color:#42546d; }
.auth-rows { margin:0; display:grid; gap:0; }
.auth-rows div { display:flex; justify-content:space-between; gap:16px; padding:8px 0; border-bottom:1px dashed #dfe6ee; }
.auth-rows div:last-child { border-bottom:none; }
.auth-rows dt { color:#55647b; font-size:13px; flex:none; }
.auth-rows dd { margin:0; font-size:13px; font-weight:600; text-align:right; word-break:break-all; }
.auth-rows code { font-family:var(--mono); font-size:12.5px; color:var(--navy); }
.auth-link { margin:11px 0 0; font-size:12.5px; color:#4d5c72; word-break:break-all; }
.auth-link span { color:#42546d; }

/* ---------------------------------------- taux de similitude en couleur */
/* 0 à 10 % bleu, 11 à 19 % orange, 20 % et plus rouge. */
.sim-banner {
  display:flex; gap:22px; align-items:center; flex-wrap:wrap;
  background:#fff; border:1px solid var(--line); border-left-width:7px;
  border-radius:16px; padding:20px 24px; margin-bottom:16px;
}
.sim-figure { text-align:center; min-width:132px; }
.sim-figure strong { display:block; font-family:var(--sigle); font-size:36px; line-height:1.05; font-weight:800; }
.sim-figure span { font-size:var(--t4); font-weight:700; text-transform:uppercase; letter-spacing:.16em; color:#55647b; }
.sim-body { flex:1; min-width:250px; }
.sim-label { font-family:var(--titre); font-size:var(--t3); color:var(--navy); margin-bottom:10px; }
.sim-scale { position:relative; height:12px; border-radius:99px; background:#eef3f8; overflow:hidden; }
.sim-fill { display:block; height:100%; border-radius:99px; transition:width .5s ease; }
.sim-tick { position:absolute; top:0; bottom:0; width:2px; background:#fff; opacity:.9; }
.sim-tick-10 { left:10%; }
.sim-tick-20 { left:20%; }
.sim-legend { display:flex; gap:8px; flex-wrap:wrap; margin:10px 0 8px; }
.sim-key { font-size:11px; font-weight:800; border-radius:99px; padding:3px 11px; letter-spacing:.04em; }
.sim-key.sim-green { background:#e6f6ee; color:#127750; }
.sim-key.sim-orange { background:#fdf2e3; color:#96601a; }
.sim-key.sim-red { background:#fdeceb; color:#b23a26; }
.sim-message { margin:0; font-size:14px; color:#39485f; }
.sim-parts { color:#42546d; }
/* Décomposition du taux : d'où vient le chiffre, nature de reprise par nature. */
.sim-formula { margin:7px 0 0; font-size:12.5px; color:#55647b; }
/* Le relevé des reprises complète le calcul du taux : même paragraphe, une
   nuance de moins, pour que le calcul reste la première chose lue. */
.sim-formula.sim-detail { color:#6b7891; font-size:12px; }
.sim-banner.sim-green { border-left-color:#1c9c6b; }
.sim-banner.sim-green .sim-figure strong { color:#127750; }
.sim-banner.sim-green .sim-fill { background:#1c9c6b; }
.sim-banner.sim-orange { border-left-color:#e08a1e; }
.sim-banner.sim-orange .sim-figure strong { color:#96601a; }
.sim-banner.sim-orange .sim-fill { background:#e08a1e; }
.sim-banner.sim-red { border-left-color:#c8452f; }
.sim-banner.sim-red .sim-figure strong { color:#b23a26; }
.sim-banner.sim-red .sim-fill { background:#c8452f; }

/* -------------------------------------------- similitudes externes (web) */
.web-source strong a { color:#1055b5; text-decoration:none; word-break:break-word; }
.web-source strong a:hover { text-decoration:underline; }
/* Corpus qui a trouvé la page et chemin par lequel son texte a été lu :
   une indication de provenance, plus discrète que la référence elle-même. */
.source-route { display:block; color:#77869c; font-size:12px; margin-top:3px; font-style:italic; }
/* Référence bibliographique de la source — auteurs, année, revue, DOI — telle
   que le corpus la publie. Elle prime sur les chiffres de similitude dans la
   lecture : c'est elle qui permet de vérifier la source, et c'est ce qu'on
   recopie dans une bibliographie. Les sélecteurs portent le conteneur parce que
   `.source-list span` et `.web-matches span` sont plus spécifiques qu'une
   classe seule et imposeraient sinon leur couleur et leur corps. */
.source-list .source-citation,
.web-matches .source-citation {
  display:block; color:#2b3a51; font-size:13px; margin-top:4px; line-height:1.45;
}
.source-citation a { color:#1055b5; text-decoration:none; }
.source-citation a:hover { text-decoration:underline; }
/* Où lire le passage dans la source : page du document, lien qui l'ouvre à cet
   endroit précis. */
.source-list .source-locator,
.web-matches .source-locator {
  display:block; font-size:12.5px; margin-top:3px; color:#4d5c72;
}
.source-locator a { color:#1055b5; font-weight:600; text-decoration:none; }
.source-locator a:hover { text-decoration:underline; }
.web-matches { list-style:none; margin:11px 0 0; padding:0; display:grid; gap:8px; }
.web-matches li { background:#f7fafd; border:1px solid #eaf0f6; border-radius:10px; padding:11px 13px; font-size:13.5px; }
.web-matches a { color:#1055b5; font-weight:700; text-decoration:none; word-break:break-word; }
.web-matches a:hover { text-decoration:underline; }
.web-matches em { color:#42546d; font-style:normal; margin-left:7px; }
.web-matches span { display:block; color:#4d5c72; font-size:12.5px; margin-top:4px; }
.web-matches code { display:block; margin-top:8px; background:#fff; border-radius:7px; padding:9px 11px; color:#2b3a51; font-size:13px; line-height:1.55; overflow-wrap:anywhere; }
/* Portion exactement retrouvée, côté document comme côté source. */
mark.src-hit { background:#ffe9b3; color:#5c4300; padding:0 2px; border-radius:3px; font-weight:600; }
.passage-web { border-left:3px solid #c8452f; }
.passage-ai { border-left:3px solid #7c5cd6; }

.report-note-alert { background:#fdeceb; border-color:#f4cfc9; color:#93301f; }

/* ------------------------------------------------- indices d'écriture IA */
.ai-head { display:flex; gap:15px; align-items:center; flex-wrap:wrap; margin-bottom:15px; }
.ai-gauge { flex:1; min-width:170px; height:12px; border-radius:99px; background:#eef3f8; overflow:hidden; }
.ai-gauge i { display:block; height:100%; border-radius:99px; background:#7c5cd6; }
.ai-head.warn .ai-gauge i { background:#d98324; }
.ai-head.bad .ai-gauge i { background:#c8452f; }
.ai-head.good .ai-gauge i { background:#1c9c6b; }
.ai-head strong { display:block; font-family:var(--titre); font-size:15px; color:var(--navy); }
.ai-head span { color:#55647b; font-size:13.5px; }
.ai-signals { list-style:none; margin:0 0 15px; padding:0; display:grid; gap:11px; }
.ai-signals li { background:#f7fafd; border:1px solid #eaf0f6; border-radius:11px; padding:12px 14px; }
.ai-signal-top { display:flex; justify-content:space-between; gap:10px; font-size:13.5px; font-weight:700; color:var(--navy); }
.ai-signals small { color:#55647b; font-size:12.5px; }
.ai-signals .metric-track { margin:9px 0 7px; }
.ai-signals .metric-track i { background:#7c5cd6; }
.ai-signal-family {
  display:inline-block; margin-top:4px; font-style:normal; font-size:11.5px;
  font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#5b46a8;
}

/* Confiance de la mesure : dite à part, pour qu'une note calculée sur deux
   cents mots ne soit jamais lue comme un verdict. */
.ai-confidence {
  margin:0 0 14px; font-size:13px; color:#42546d; background:#f7fafd;
  border:1px solid #eaf0f6; border-left:3px solid #b7c2d0;
  border-radius:9px; padding:9px 12px;
}
.ai-confidence-elevee { border-left-color:#1c9c6b; }
.ai-confidence-moyenne { border-left-color:#d98324; }
.ai-confidence-faible { border-left-color:#c8452f; }

/* Contribution des quatre familles d'indices. */
.ai-families { list-style:none; margin:0 0 15px; padding:0; display:grid; gap:7px; }
.ai-families li {
  display:grid; grid-template-columns:96px 1fr 52px; align-items:center;
  gap:11px; font-size:12.5px; color:#42546d;
}
.ai-families b { text-align:right; font-size:12.5px; color:var(--navy); }
.ai-families .metric-track { margin:0; }
.ai-families .metric-track i { background:#a494dd; }

@media (max-width: 560px) {
  .analyse-form { padding:18px; }
  .report-head, .report-block, .certificate { padding:18px; }
  .report-head { flex-direction:column; align-items:flex-start; }
  .cert-row { flex-direction:column; gap:3px; }
  .cert-row strong { text-align:left; }
  .analyse-actions .btn, .report-actions .btn { flex:1 1 100%; justify-content:center; }
  .report-auth { padding:18px; gap:16px; }
  .auth-rows div { flex-direction:column; gap:3px; }
  .auth-rows dd { text-align:left; }
}

@media print {
  .site-header, .hero, .support-band, .footer,
  .analyse-form, .section-heading, .report-actions { display:none !important; }
  body { background:#fff; }
  .analyse { padding:0; background:#fff; border:0; }
  .report { margin:0; }
  .report-head, .report-block, .certificate, .metric, .passage { break-inside:avoid; box-shadow:none; }
  /* L'encart d'authentification ouvre le document : il doit rester entier,
     sur la première page. */
  .report-auth { break-inside:avoid; break-after:avoid; box-shadow:none; }
  mark.src-hit, .metric-track i, .ai-gauge i, .report-reco h4, .reco li {
    -webkit-print-color-adjust:exact; print-color-adjust:exact;
  }
}

/* =====================================================================
   Contrôle d'accès : en-tête connecté, portail de l'outil, connexion,
   administration des mots de passe.
   ===================================================================== */

/* ------------------------------------------------- en-tête et session */
.nav-session { display:inline-flex; align-items:center; gap:16px; }
.nav-admin { padding:9px 14px; border:1px solid var(--line); border-radius:9px; background:#f1f7ff; color:var(--blue); }
.nav-admin:hover { background:#e4f0fe; }
.nav-logout {
  border:0; background:var(--navy); color:#fff; border-radius:9px; padding:10px 15px;
  font:inherit; font-size:13px; font-weight:700; cursor:pointer; transition:.2s;
}
.nav-logout:hover { background:var(--navy-2); }
.nav-logout[disabled] { opacity:.5; cursor:progress; }

/* ------------------------------------------- portail de l'outil d'analyse */
.access-checking, .admin-checking {
  margin:0; padding:16px 18px; border:1px dashed #cfe0f5; border-radius:14px;
  background:#f7fbff; color:var(--muted); font-size:13px;
}
.admin-checking { margin:40px 0; }
.access-gate {
  text-align:center; padding:44px 30px; border-radius:22px;
  border:1px solid var(--line); background:
    radial-gradient(circle at 50% 0%, rgba(23,105,224,.08), transparent 60%), #fff;
  box-shadow:var(--shadow);
}
.access-gate .gate-icon { font-size:30px; line-height:1; margin-bottom:14px; }
.access-gate h1, .access-gate h3 {
  font-family:var(--titre); color:var(--navy); margin:0 0 12px;
  font-size:clamp(21px,2.6vw,27px);
}
.access-gate p { max-width:620px; margin:0 auto; color:var(--muted); font-size:14.5px; }
.gate-actions { display:flex; justify-content:center; flex-wrap:wrap; gap:12px; margin-top:24px; }

/* ------------------------------------------------------ page de connexion */
.auth-main { padding:70px 0 90px; background:linear-gradient(135deg,#f7fbff 0%,#fff 60%); }
.auth-grid { display:grid; grid-template-columns:1.1fr .9fr; gap:34px; align-items:start; }
.auth-card {
  background:#fff; border:1px solid var(--line); border-radius:22px;
  padding:38px; box-shadow:var(--shadow);
}
.auth-card h1 { font-family:var(--titre); color:var(--navy); font-size:var(--t1); margin:16px 0 14px; }
.auth-lead { color:var(--muted); font-size:14.5px; margin:0 0 26px; }
.auth-form { display:block; }
.auth-label { display:block; font-size:var(--t4); font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--muted); margin-bottom:9px; }
.auth-field { display:flex; gap:9px; align-items:stretch; }
.auth-field input {
  flex:1 1 auto; min-width:0; font:inherit; font-size:15px; letter-spacing:.04em;
  padding:14px 15px; border:1px solid var(--line); border-radius:11px; background:#fcfdff; color:var(--ink);
}
.auth-field input:focus { outline:2px solid rgba(23,105,224,.35); outline-offset:1px; border-color:var(--blue); }
.auth-reveal {
  border:1px solid var(--line); background:#f1f7ff; color:var(--blue); border-radius:11px;
  padding:0 15px; font:inherit; font-size:12.5px; font-weight:700; cursor:pointer;
}
.auth-reveal:hover { background:#e4f0fe; }
.auth-submit { width:100%; justify-content:center; margin-top:18px; }
.auth-help { margin:22px 0 0; color:var(--muted); font-size:12.5px; }
.auth-help a { color:var(--blue); font-weight:700; }
.auth-side { background:var(--navy); color:#fff; border-radius:22px; padding:30px; }
.auth-side h2 { font-family:var(--titre); font-size:18px; margin:0 0 20px; }
.auth-role { padding:14px 0; border-bottom:1px solid rgba(255,255,255,.09); }
.auth-role p { margin:9px 0 0; color:#b9c6d7; font-size:12.5px; }
.auth-side .side-note { margin:20px 0 0; }

/* ----------------------------------------------------------- rôles et états */
.role-badge {
  display:inline-block; border-radius:99px; padding:4px 12px;
  font-size:10.5px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
}
.role-admin { background:#e9e2fb; color:#5a3fbd; }
.role-user { background:#e3ecfb; color:#1a5cb8; }
.state-badge {
  display:inline-block; border-radius:99px; padding:4px 11px;
  font-size:10.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
}
.state-badge.is-on { background:#ddf3e8; color:#17734c; }
.state-badge.is-off { background:#f1f3f6; color:#7b8798; }
.state-badge.is-warn { background:#fdf0d8; color:#8a6d2f; }
.tag-self { font-size:10px; font-weight:800; color:var(--blue); letter-spacing:.05em; text-transform:uppercase; }
/* Un compte qui accepte encore le mot de passe d'un compte absorbé par la fusion
   des administrateurs : la ligne le dit, pour qu'on sache ce qui ouvre le compte. */
.tag-legacy { display:block; margin-top:3px; color:#8a6d2f; font-size:11px; }

/* ------------------------------------------------------ page d'administration */
.admin-main { padding:46px 0 80px; background:var(--soft); min-height:60vh; }
.admin-head { display:flex; justify-content:space-between; align-items:flex-end; gap:24px; flex-wrap:wrap; }
.admin-head h1 { font-family:var(--titre); color:var(--navy); font-size:var(--t1); margin:16px 0 12px; }
.admin-lead { max-width:720px; color:var(--muted); font-size:14px; margin:0; }
/* L'administration tient en une seule page : ces raccourcis mènent d'un geste à
   la rubrique cherchée sans avoir à la faire défiler. */
.admin-jump { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 0; }
.admin-jump a {
  border:1px solid var(--line); background:#fff; border-radius:999px;
  padding:6px 13px; font-size:12px; font-weight:700; color:var(--navy); text-decoration:none;
}
.admin-jump a:hover { border-color:var(--blue); color:var(--blue); }
.admin-stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:14px; margin:28px 0; }
.admin-stats .stat { background:#fff; border:1px solid var(--line); border-radius:16px; padding:18px 20px; }
.admin-stats strong { display:block; font-family:var(--sigle); font-size:27px; color:var(--navy); line-height:1.1; }
.admin-stats small { display:block; margin-top:5px; color:var(--muted); font-size:11.5px; }
/* Les ouvertures demandées sont le seul chiffre où quelqu'un attend en direct,
   fenêtre ouverte : la tuile se distingue pour qu'on la traite d'abord. */
.admin-stats .stat.is-asked { border-color:#e6d6ae; background:#fdf8ec; }
.admin-stats .stat.is-asked strong { color:#96601a; }
.admin-card {
  background:#fff; border:1px solid var(--line); border-radius:20px;
  padding:26px; margin-bottom:20px;
}
.admin-card h2 { font-family:var(--titre); font-size:18px; color:var(--navy); margin:0 0 20px; }
.admin-hint { margin:16px 0 0; color:var(--muted); font-size:12px; }
.codes-empty { margin:16px 0 0; color:var(--muted); font-size:13px; }

/* Les alertes de validation en attente : une carte par alerte, et l'état de son
   envoi. Celles qui restent à traiter portent un liseré, pour se voir d'un coup
   d'œil ; celles qui sont traitées se replient d'un bouton. */
.alerts-count { margin:0 0 10px; font-weight:700; color:var(--navy); font-size:14px; }
/* Confidentialité : le compteur des relevés encore en magasin. */
.privacy-count { margin:0 0 10px; font-weight:700; color:var(--navy); font-size:14px; }
.alerts-list { display:grid; gap:12px; margin-top:14px; }
.alert-card { border:1px solid var(--line); border-radius:16px; padding:16px 18px; background:#fcfdff; }
.alert-card.alert-open { border-color:#e6d6ae; background:#fdf8ec; }
.alert-card header { display:flex; flex-wrap:wrap; gap:10px; justify-content:space-between; align-items:baseline; }
.alert-card strong { font-family:var(--titre); font-size:15px; color:var(--navy); }
.alert-date { color:var(--muted); font-size:12px; }
.alert-body { margin:8px 0 0; font-size:13px; line-height:1.6; color:var(--ink); }
.alert-targets { list-style:none; margin:12px 0 0; padding:0; display:grid; gap:5px; }
.alert-target { font-size:12px; color:var(--muted); }
.alert-channel {
  display:inline-block; min-width:62px; font-weight:800; font-size:10.5px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--navy);
}
.alert-to { color:var(--ink); font-weight:600; }
.alert-status { font-weight:700; }
.alert-target.alert-envoye .alert-status { color:#1c7a4a; }
.alert-target.alert-en_attente .alert-status { color:#8a6d2f; }
.alert-target.alert-echoue .alert-status,
.alert-target.alert-sans_relais .alert-status { color:#a3391f; }
.alert-actions { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:14px; }
.alert-done { color:var(--muted); font-size:12px; }
/* La carte d'une alerte traitée : plus rien n'y attend, elle s'efface du regard
   sans quitter la page — et disparaît tout à fait quand la pile est pliée. */
.alert-card.alert-closed { background:#fbfcfd; }
.alerts-list.alerts-folded .alert-card.alert-closed { display:none; }

/* La fréquentation du site — rubrique « Visiteurs » de l'administration.
   Une courbe en barres : la hauteur pleine dit les pages vues, la part foncée
   les visiteurs distincts du jour. Les deux se lisent toujours ensemble, d'où
   la superposition plutôt que deux graphiques côte à côte. */
.visits-range { display:flex; align-items:center; gap:8px; font-size:10.5px; font-weight:800;
  letter-spacing:.09em; text-transform:uppercase; color:var(--muted); }
.visits-range select {
  font:inherit; font-size:12.5px; font-weight:600; text-transform:none; letter-spacing:0;
  color:var(--ink); padding:8px 10px; border:1px solid var(--line); border-radius:9px;
  background:#fcfdff;
}
.visits-range select:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.visits-live { margin:0; font-weight:700; color:var(--navy); font-size:14px; }
.visits-chart {
  display:flex; align-items:flex-end; gap:3px; height:190px; margin-top:16px;
  padding:14px 14px 0; border:1px solid var(--line); border-radius:16px;
  background:linear-gradient(180deg,#fbfdff,#f4f8fc); overflow-x:auto;
}
.visits-day { flex:1 1 0; min-width:9px; height:100%; display:grid; grid-template-rows:1fr 14px;
  gap:5px; justify-items:center; }
.visits-col {
  align-self:end; width:100%; max-width:26px; min-height:2px; border-radius:5px 5px 0 0;
  background:linear-gradient(180deg, rgba(24,166,217,.5), rgba(24,166,217,.22));
  display:flex; align-items:flex-end;
}
/* Un jour sans visite : le socle reste visible, la barre non — un creux se voit
   mieux qu'il ne se lit. */
.visits-col.is-empty { background:#e9eff6; height:2px; }
.visits-col i { display:block; width:100%; border-radius:5px 5px 0 0;
  background:linear-gradient(180deg,var(--blue),var(--navy-2)); }
.visits-tick { font-size:9.5px; color:var(--muted); white-space:nowrap; line-height:14px; }
.visits-legend { display:flex; align-items:center; gap:7px; margin:10px 0 0;
  color:var(--muted); font-size:11.5px; }
.visits-key { display:inline-block; width:11px; height:11px; border-radius:3px; }
.visits-key-views { background:rgba(24,166,217,.45); }
.visits-key-visitors { background:var(--blue); margin-left:12px; }
.visits-tables { display:grid; grid-template-columns:repeat(auto-fit,minmax(272px,1fr));
  gap:24px; margin-top:24px; }
.visits-tables h3 { margin:0 0 10px; font-family:var(--titre); font-size:13px;
  letter-spacing:.03em; color:var(--navy); }
.visits-tables .codes-table { min-width:0; }

/* Le relevé de l'archive du site n'a que trois colonnes : il tient dans la
   largeur de la page, sans le défilement horizontal des grands tableaux. */
.source-table .codes-table { min-width:0; }
.source-table td:nth-child(2), .source-table td:nth-child(3),
.source-table th:nth-child(2), .source-table th:nth-child(3) { text-align:right; }
.source-table td:first-child { font-family:var(--mono); }
.visits-tables .codes-table th { padding:0 10px 9px; }
.visits-tables .codes-table td { padding:11px 10px; }
.visits-tables .codes-table td a { color:var(--blue); font-weight:600; word-break:break-all; }
@media (max-width: 700px) {
  .visits-chart { height:150px; }
  .visits-legend { flex-wrap:wrap; }
}

.admin-form { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px; }
.admin-form .field { display:flex; flex-direction:column; gap:7px; min-width:0; }
.admin-form .field-wide { grid-column:1 / -1; }
.admin-form label { font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--muted); }
.admin-form label span { text-transform:none; letter-spacing:0; font-weight:600; color:#9aa7b7; }
.admin-form input, .admin-form select {
  font:inherit; font-size:14px; padding:12px 13px; border:1px solid var(--line);
  border-radius:11px; background:#fcfdff; color:var(--ink); min-width:0;
}
.admin-form input:focus, .admin-form select:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.field-inline { display:flex; gap:9px; }
.field-inline input { flex:1 1 auto; }
.admin-form .form-foot { display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.admin-form .form-foot .form-error { margin:0; flex:1 1 240px; }
.btn-xs { padding:9px 13px; font-size:12px; gap:0; border-radius:9px; }

.table-scroll { overflow-x:auto; }
.codes-table { width:100%; border-collapse:collapse; font-size:13px; min-width:860px; }
.codes-table th {
  text-align:left; font-size:10.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); padding:0 12px 11px; border-bottom:1px solid var(--line); white-space:nowrap;
}
.codes-table td { padding:14px 12px; border-bottom:1px solid #eef2f7; vertical-align:top; }
.codes-table tr.row-off { background:#fbfcfd; color:#8b97a7; }
/* La ligne d'un client qui a déclaré son versement et attend l'ouverture :
   elle remonte en tête de tableau, et se voit. */
.codes-table tr.row-asked { background:#fdfaf1; }
.codes-table tr.row-asked td { border-bottom-color:#f0e7d2; }
.pay-asked { color:#96601a; font-weight:700; }
/* La confirmation signée par le client, sous la ligne de son adresse. En rouge
   quand elle ne concorde pas avec ce qu'il avait donné avant de payer : le
   rapprochement du versement demande alors un coup d'œil de plus. */
.pay-confirmed { color:#1c7a3e; font-weight:700; }
.pay-confirmed.is-off { color:#c62f2f; }
/* La ligne d'une commande encaissée : une affaire close. Elle se replie d'un
   bouton pour que le tableau montre d'abord ce qui attend une décision. */
.codes-table tbody.pay-folded tr.row-collected { display:none; }
.codes-table td strong { display:block; font-size:13.5px; color:var(--navy); }
.codes-table td small { display:block; margin-top:4px; color:var(--muted); font-size:11px; }
.row-actions { display:flex; flex-wrap:wrap; gap:7px; }

.secret-panel {
  display:flex; justify-content:space-between; align-items:flex-start; gap:22px; flex-wrap:wrap;
  background:var(--navy); color:#fff; border-radius:20px; padding:24px 26px; margin-bottom:20px;
}
.secret-kicker { display:block; font-size:var(--t4); font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:#66d4f0; }
.secret-value {
  display:block; margin:12px 0 8px; font-family:var(--mono); font-size:clamp(20px,3vw,28px);
  letter-spacing:.14em; color:#fff; word-break:break-all;
}
.secret-panel small { display:block; color:#b9c6d7; font-size:12px; }
.secret-warning { margin:12px 0 0; max-width:560px; color:#ffd7a8; font-size:12.5px; }
.secret-actions { display:flex; gap:9px; flex-wrap:wrap; }

@media (max-width: 900px) {
  .auth-grid { grid-template-columns:1fr; }
  .admin-form { grid-template-columns:1fr; }
  .nav-session { width:100%; justify-content:flex-start; flex-wrap:wrap; gap:10px; }
}

/* =====================================================================
   Vérification d'un rapport (verifier.html) : la page ouverte par le
   code QR de la première page du rapport.
   ===================================================================== */
.verify-main { padding:70px 0 90px; background:linear-gradient(135deg,#f7fbff 0%,#fff 60%); }
.verify-main h1 { font-family:var(--titre); color:var(--navy); font-size:var(--t1); margin:16px 0 16px; }
.verify-lead { color:var(--muted); font-size:14.5px; line-height:1.65; max-width:760px; margin:0 0 26px; }
.verify-lead strong { color:var(--navy); }

.verify-status {
  display:block; border:1px solid var(--line); border-left-width:7px; border-radius:16px;
  background:#fff; padding:20px 24px; margin-bottom:20px; box-shadow:var(--shadow);
}
.verify-status strong { display:block; font-family:var(--titre); font-size:19px; color:var(--navy); }
.verify-status p { margin:8px 0 0; font-size:14px; line-height:1.6; color:#42546d; }
.verify-status.is-ok { border-left-color:#1c9c6b; }
.verify-status.is-ok strong { color:#127750; }
.verify-status.is-bad { border-left-color:#c8452f; }
.verify-status.is-bad strong { color:#b23a26; }
.verify-status.is-warn { border-left-color:#e08a1e; }
.verify-status.is-warn strong { color:#96601a; }

.verify-card {
  background:#fff; border:1px solid var(--line); border-radius:18px;
  padding:26px 28px; margin-bottom:16px;
}
.verify-card h2 { font-family:var(--titre); font-size:17px; color:var(--navy); margin:0 0 12px; }
.verify-card p { margin:0 0 14px; font-size:14px; line-height:1.6; color:#42546d; }
.verify-card code { font-family:var(--mono); font-size:13px; }
.verify-card textarea {
  width:100%; box-sizing:border-box; font:inherit; font-size:13.5px; padding:13px 14px;
  border:1px solid var(--line); border-radius:12px; background:#fcfdff; color:var(--ink);
  resize:vertical; margin-bottom:12px;
}
.verify-card textarea:focus { outline:none; border-color:var(--blue); box-shadow:0 0 0 4px rgba(23,105,224,.1); }
.verify-rows { margin:0; }
.verify-rows div { display:flex; justify-content:space-between; gap:18px; padding:9px 0; border-bottom:1px dashed #dfe6ee; }
.verify-rows div:last-child { border-bottom:none; }
.verify-rows dt { color:#55647b; font-size:13.5px; flex:none; }
.verify-rows dd { margin:0; font-size:13.5px; font-weight:600; text-align:right; word-break:break-all; color:var(--navy); }
.verify-registry-state, .verify-doc-state { margin:0 0 10px; font-size:14px; line-height:1.6; }
.verify-registry-state.is-ok, .verify-doc-state.is-ok { color:#127750; font-weight:700; }
.verify-registry-state.is-bad, .verify-doc-state.is-bad { color:#b23a26; font-weight:700; }
.verify-registry-state.is-warn, .verify-doc-state.is-warn { color:#96601a; font-weight:700; }
.verify-note { color:var(--muted); font-size:12.5px; margin:0; }
.verify-card .drop { margin-bottom:6px; }

@media (max-width: 560px) {
  .verify-card { padding:20px; }
  .verify-rows div { flex-direction:column; gap:3px; }
  .verify-rows dd { text-align:left; }
}

/* --- page « Rapport » : les commandes déjà payées, reprises par le client */
.report-slot + .report-slot { margin-top:14px; }
.report-item {
  border:1px solid #e3e9f2; border-left:4px solid #c9d4e4; border-radius:14px;
  padding:18px 20px; background:#fbfdff;
}
.report-item.is-ok { border-left-color:#1c9c6b; background:#f6fdf9; }
.report-item.is-warn { border-left-color:#e08a1e; background:#fffaf1; }
.report-item.is-bad { border-left-color:#c8452f; background:#fff7f5; }
.report-item-head {
  display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  flex-wrap:wrap; margin-bottom:8px;
}
.report-item-head strong {
  font-family:var(--mono); font-size:15px;
  letter-spacing:.02em; color:var(--navy);
}
.report-item-head span { font-size:12.5px; color:var(--muted); font-weight:600; }
.report-item-state { margin:0 0 12px; font-size:13.5px; line-height:1.6; color:#42546d; }
.report-item.is-ok .report-item-state { color:#127750; font-weight:600; }
.report-item.is-warn .report-item-state { color:#96601a; font-weight:600; }
.report-item.is-bad .report-item-state { color:#b23a26; font-weight:600; }
.report-item .verify-rows { margin:0 0 14px; }
.report-item-actions { display:flex; flex-wrap:wrap; gap:10px; }
.report-item-note { margin:12px 0 0; font-size:13px; line-height:1.6; color:#42546d; }
/* Ce que le client fait de son fichier scellé, sous le bouton qui vient de le
   lui remettre : il a un fichier qu'il ne peut pas lire, et la note dit en deux
   lignes par où il s'ouvre. */
.report-item-note.is-open {
  margin-top:10px; padding:11px 13px; border:1px solid #bfe4d2; border-radius:11px;
  background:#f4fbf7; color:#2f5245;
}
.report-item-note.is-open strong { color:#0f5236; }
.report-item-note.is-open code {
  font-family:var(--mono); font-size:12.5px;
  letter-spacing:.06em; color:var(--navy); background:#fff; border:1px solid #d6e7de;
  border-radius:6px; padding:1px 5px; white-space:nowrap;
}
.report-item-note a { color:var(--blue); font-weight:700; }

.report-find { display:grid; gap:6px; }
.report-find label { font-size:13px; font-weight:600; color:#42546d; margin-top:8px; }
.report-find input {
  width:100%; border:1px solid #d8e0ea; border-radius:10px; padding:11px 13px;
  font-family:inherit; font-size:14px; color:var(--navy); background:#fff;
}
.report-find input:focus {
  outline:none; border-color:var(--blue); box-shadow:0 0 0 4px rgba(23,105,224,.1);
}
.report-find button { margin-top:14px; justify-self:start; }
/* Le fichier scellé se dépose dans le même formulaire que le numéro de reçu :
   un champ de fichier ne se met pas en forme comme un champ de texte, mais il
   doit s'aligner sur lui. */
.report-find input[type="file"] { padding:9px 11px; background:#fbfdff; cursor:pointer; }
/* Les douze signes du code se saisissent gros et espacés : le client les recopie
   d'un courrier, et une lettre lue de travers ne donne rien. */
.report-find input.report-code {
  font-family:var(--mono); font-size:17px;
  letter-spacing:.16em; text-transform:uppercase;
}

@media (max-width: 560px) {
  .report-item { padding:16px; }
  .report-item-actions .btn { width:100%; justify-content:center; }
  .report-find button { justify-self:stretch; width:100%; }
}

/* =====================================================================
   PAIEMENT DU RAPPORT
   Tarifs affichés sur la page d'accueil, fenêtre de paiement qui s'ouvre
   à la fin de l'analyse, et bandeau des exemplaires restants.
   ===================================================================== */


/* --- rapport scellé et exemplaires restants */
.pay-locked {
  display:flex; align-items:center; gap:20px; flex-wrap:wrap;
  background:#fff; border:1px solid var(--line); border-left:4px solid var(--blue);
  border-radius:18px; padding:22px 24px; margin-top:26px;
}
.pay-locked-icon { font-size:26px; line-height:1; }
.pay-locked strong { display:block; font-family:var(--titre); font-size:16px; color:var(--navy); }
.pay-locked p { margin:4px 0 0; color:var(--muted); font-size:13.5px; max-width:520px; }
.pay-locked .btn { margin-left:auto; }

.pay-copies {
  display:flex; align-items:center; gap:12px;
  background:#eefaf3; border:1px solid #c7ead9; border-radius:14px;
  padding:14px 18px; margin-top:22px; color:#146c4b; font-size:13.5px;
}
.pay-copies-mark {
  flex:none; width:24px; height:24px; border-radius:50%; background:#1a8a5f; color:#fff;
  display:inline-flex; align-items:center; justify-content:center; font-size:13px; font-weight:800;
}
.pay-copies strong { color:#0f5236; }

/* --- fenêtre des modalités de paiement */
.pay-modal { position:fixed; inset:0; z-index:60; display:flex; align-items:center; justify-content:center; padding:22px; }
.pay-modal[hidden] { display:none; }
.pay-backdrop { position:absolute; inset:0; background:rgba(10,23,48,.62); backdrop-filter:blur(3px); }
.pay-panel {
  position:relative; width:min(680px,100%); max-height:92vh; overflow-y:auto;
  background:#fff; border-radius:22px; box-shadow:0 34px 80px rgba(10,23,48,.34);
}
.pay-head { padding:28px 30px 20px; border-bottom:1px solid var(--line); }
.pay-kicker { display:block; font-size:var(--t4); font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--blue); }
.pay-head h3 { font-family:var(--titre); font-size:22px; color:var(--navy); margin:9px 0 8px; }
.pay-head p { margin:0; color:var(--muted); font-size:13.5px; line-height:1.6; }
.pay-body { padding:22px 30px 4px; }
.pay-section { margin-bottom:24px; }
.pay-section h4 {
  font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); margin:0 0 12px;
}

.pay-tiers { display:grid; gap:10px; }
.pay-tier {
  display:flex; align-items:center; gap:14px; cursor:pointer;
  border:1px solid var(--line); border-radius:14px; padding:14px 16px; background:#fcfdff;
}
.pay-tier.is-on { border-color:var(--blue); background:#f2f8ff; box-shadow:0 0 0 3px rgba(23,105,224,.08); }
/* Palier arrêté par l'analyse : il s'affiche, il ne se clique pas. */
.pay-tier.is-fixed { cursor:default; }
.pay-tier-fixed {
  display:inline-block; margin-top:6px; padding:2px 8px; border-radius:999px;
  background:var(--blue); color:#fff; font-size:11px; letter-spacing:.02em; text-transform:uppercase;
}
.pay-tier-body { flex:1 1 auto; min-width:0; }
.pay-tier-body strong { display:block; font-size:14px; color:var(--navy); }
.pay-tier-body small { display:block; color:var(--muted); font-size:12px; }

.pay-methods { display:grid; gap:10px; }
.pay-method { border:1px solid var(--line); border-radius:14px; background:#fcfdff; overflow:hidden; }
.pay-method.is-on { border-color:var(--blue); background:#f2f8ff; }
.pay-method-head { display:flex; align-items:center; gap:12px; padding:14px 16px; cursor:pointer; font-size:14px; color:var(--navy); }
.pay-method-body { padding:0 16px 16px; }
.pay-method-body[hidden] { display:none; }
.pay-fields { display:grid; gap:1px; background:var(--line); border:1px solid var(--line); border-radius:11px; overflow:hidden; margin-bottom:12px; }
.pay-field-row { display:flex; justify-content:space-between; gap:16px; padding:11px 14px; background:#fff; font-size:13px; }
.pay-field-row span { color:var(--muted); flex:none; }
.pay-field-row strong { color:var(--navy); text-align:right; word-break:break-all; }
.pay-note { margin:0 0 12px; color:var(--muted); font-size:12.5px; line-height:1.6; }
.pay-missing { margin:0 0 12px; padding:12px 14px 12px 30px; border:1px solid var(--line); border-radius:11px; background:#fff8ee; color:var(--muted); font-size:12.5px; line-height:1.7; }
.pay-missing li { margin:0; }

/* Rubrique activée mais pas encore renseignée : annoncée, jamais choisissable. */
.pay-method.is-waiting { background:#fbfbfc; border-style:dashed; }
.pay-method.is-waiting .pay-method-head { cursor:default; color:var(--muted); }
.pay-method-wait {
  margin-left:auto; padding:4px 9px; border-radius:999px; background:#fff2dd;
  color:#8a5a12; font-size:10.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
}
.pay-pending { margin:0 0 12px; padding:11px 13px; border-radius:11px; background:#fff8ee; color:#8a5a12; font-size:12.5px; line-height:1.6; }

/* Assistance et accès illimité : la voie hors tarif à l'unité, en gras. */
.pay-institution {
  margin:0 0 16px; padding:14px 16px; border:1px solid #cfe0f7; border-radius:11px;
  background:#eef5ff; color:var(--ink); font-size:13px; line-height:1.7;
}
.pay-institution-cases { margin:0 0 8px; padding:0 0 0 18px; list-style:disc; }
.pay-institution-cases li { margin:0 0 3px; }
.pay-institution-cases strong { color:var(--navy); font-weight:800; }
.pay-institution-call { margin:0; color:var(--navy); font-weight:700; }
.pay-institution a { color:var(--blue); font-weight:800; word-break:break-all; }

/* Code QR Wave : donné en image, à scanner depuis le téléphone. */
.pay-qr { margin:0 0 12px; display:flex; flex-direction:column; align-items:center; gap:8px; }
.pay-qr-image { width:180px; height:180px; object-fit:contain; border:1px solid var(--line); border-radius:11px; background:#fff; padding:8px; }
.pay-qr figcaption { color:var(--muted); font-size:12px; text-align:center; }

/* Paiement Wave par commande : le bouton ouvre une commande au montant du
   service, puis conduit chez Wave. Le montant n'est jamais dans le lien. */
.pay-wave {
  margin:0 0 12px; padding:13px 15px; border:1px solid #cfe0f7; border-radius:11px;
  background:#f2f8ff; display:flex; flex-direction:column; align-items:flex-start; gap:9px;
}
.pay-wave-note { margin:0; color:var(--muted); font-size:12.5px; line-height:1.6; }
.pay-wave-test {
  margin:0; align-self:stretch; padding:4px 9px; border-radius:999px; background:#fff2dd;
  color:#8a5a12; font-size:10.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
}
.pay-link-row { margin:0 0 12px; }

/* Le prénom, le nom et l'adresse email, demandés avant le paiement.
   ----------------------------------------------------------------
   C'est la première marche, et la seule que le client ait à écrire : il donne le
   nom sous lequel son versement Wave sera retrouvé, et l'adresse à laquelle
   FONTEXTE lui enverra son rapport ; puis il va payer. Le bloc est mis en avant
   comme l'était l'ancienne déclaration d'identifiant de transaction, mais il
   vient désormais *avant* le règlement. Le même bloc revient pour la
   confirmation du paiement, où les trois champs sont réécrits. */
.pay-mail {
  margin:0 0 12px; padding:15px 16px; border:1px solid #cfe0f7; border-radius:13px;
  background:#f7fbff; display:flex; flex-direction:column; gap:9px;
}
.pay-mail-label {
  display:flex; flex-direction:column; gap:4px; font-size:14px; font-weight:700;
  color:var(--navy); cursor:pointer;
}
/* Trois champs sur une ligne quand la place le permet, l'un sous l'autre
   sinon : le prénom et le nom sont courts, l'adresse ne l'est pas. */
.pay-mail-grid {
  display:grid; grid-template-columns:1fr 1fr; gap:10px 12px;
}
.pay-mail-field {
  margin:0; display:flex; flex-direction:column; gap:5px;
}
.pay-mail-field:last-child { grid-column:1 / -1; }
/* La confirmation d'après paiement : les mêmes champs, vides, sur un fond qui
   dit que l'on n'en est plus à la commande mais à la signature du versement. */
.pay-confirm-fields {
  border-color:#f0d9a8; background:#fffaf0;
}
.pay-confirm-fields .pay-mail-step { color:#a2681c; }
.pay-mail-step {
  margin:0; font-size:10.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--blue);
}
.pay-mail-input {
  font:inherit; font-size:15px; padding:12px 13px;
  border:1.5px solid var(--line); border-radius:11px; background:#fff; color:var(--ink);
}
.pay-mail-input:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.pay-mail-help { margin:0; color:var(--muted); font-size:12.5px; line-height:1.6; }

/* La réponse à « Vérifier maintenant ». Deux issues seulement : le rapport
   s'ouvre — et la fenêtre disparaît —, ou la validation se fait attendre et le
   client le lit ici même, à l'endroit où il vient de cliquer. Sans cette ligne,
   le clic restait sans effet visible et paraissait cassé. */
.pay-waiting {
  margin:0 0 12px; padding:12px 14px; border:1px solid #cfe0f5; border-radius:11px;
  background:#eef5fe; color:var(--navy); font-size:13.5px; font-weight:700;
  line-height:1.6;
}
.pay-waiting.is-busy { border-color:#ded2b6; background:#fbf6ea; color:var(--ink); font-weight:600; }
/* Le scellé est descendu sur l'appareil du client : c'est une bonne nouvelle, et
   elle doit se lire comme telle — il ne lui manque plus que son code. */
.pay-waiting.is-done { border-color:#bfe4d2; background:#f0faf5; color:#12684a; }
.pay-waiting[hidden] { display:none; }

/* --- la pièce scellée, dans la fenêtre de paiement
   Le client vient de télécharger un fichier qu'il ne peut pas lire. C'est
   déconcertant, et rien ne le rassure mieux que la marche à suivre, numérotée,
   là où il se trouve : ouvrir avec le navigateur, saisir les douze signes,
   garder la pièce en clair. Le bloc se démarque du reste de la fenêtre — cadre
   vert, fond pâle — parce que ce qu'il annonce est acquis, pas en attente. */
.pay-seal {
  margin:0 0 14px; padding:14px 16px; border:1px solid #bfe4d2; border-radius:12px;
  background:#f4fbf7; color:var(--ink); font-size:13px; line-height:1.7;
}
.pay-seal-title { margin:0 0 8px; }
.pay-seal-title strong { color:#0f5236; font-size:13.5px; }
.pay-seal-steps { margin:0; padding:0 0 0 20px; display:grid; gap:5px; }
.pay-seal-steps li { color:var(--ink); }
.pay-seal-steps strong { color:var(--navy); font-weight:800; }
.pay-seal-steps code {
  font-family:var(--mono); font-size:12.5px;
  letter-spacing:.06em; color:var(--navy); background:#fff; border:1px solid #d6e7de;
  border-radius:6px; padding:1px 5px; white-space:nowrap;
}
.pay-seal a { color:var(--blue); font-weight:800; }
.pay-seal-again { margin:10px 0 0; }

/* Le mot qui rassure quand le rapport tarde : la validation est faite par une
   personne. Le client lit d'abord ce qu'il a à faire — attendre —, puis les
   trois issues, dans l'ordre où elles viennent. */
.pay-delay {
  margin:0 0 16px; padding:14px 16px; border:1px solid #e6d6ae; border-radius:11px;
  background:#fdf8ec; color:var(--ink); font-size:13px; line-height:1.7;
}
.pay-delay p { margin:0; }
.pay-delay-lead { text-transform:none; }
.pay-delay-ways { margin:8px 0 0; padding:0 0 0 18px; display:grid; gap:4px; }
.pay-delay-ways li { color:var(--muted); }
.pay-delay strong { color:var(--navy); }
.pay-delay a { color:var(--blue); font-weight:800; word-break:break-all; }

/* Les trois temps de l'attente — paiement déclaré, validation demandée,
   ouverture automatique. Le client doit voir d'un coup d'œil ce qui est fait,
   ce qui se joue maintenant, et ce qui viendra sans qu'il ait à cliquer :
   le trait vertical relie les étapes, la pastille dit laquelle est en cours. */
.pay-steps {
  list-style:none; margin:0 0 16px; padding:0;
  display:flex; flex-direction:column; gap:2px;
}
.pay-step {
  position:relative; display:flex; gap:13px; align-items:flex-start;
  padding:0 0 16px 0;
}
.pay-step::before {
  content:''; position:absolute; left:12px; top:26px; bottom:2px;
  width:2px; background:var(--line); border-radius:2px;
}
.pay-step:last-child { padding-bottom:0; }
.pay-step:last-child::before { display:none; }
.pay-step.is-done::before { background:#bfe4d2; }
.pay-step-mark {
  flex:0 0 auto; width:26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:800; font-family:var(--sigle);
  background:#eef1f5; color:#8c99a9; border:2px solid transparent;
}
.pay-step.is-done .pay-step-mark { background:#e2f6ec; color:#146c4b; }
.pay-step.is-now .pay-step-mark {
  background:#fdf1dc; color:#96601a; border-color:#e6d6ae;
}
.pay-step-body { display:flex; flex-direction:column; gap:3px; padding-top:2px; }
.pay-step-body strong { font-size:13.5px; color:#8c99a9; font-weight:700; }
.pay-step-body small { font-size:12.5px; line-height:1.6; color:var(--muted); }
.pay-step.is-done .pay-step-body strong { color:var(--navy); }
.pay-step.is-now .pay-step-body strong { color:var(--navy); }
.pay-step.is-now .pay-step-body small { color:var(--ink); }

/* Les coordonnées du moyen choisi — Wave ou carte bancaire —, ouvertes une fois
   l'identité du client enregistrée. */
.pay-method-details { margin:0 0 14px; }

.pay-inputs { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.pay-inputs label { display:flex; flex-direction:column; gap:7px; font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--muted); }
.pay-inputs label span { text-transform:none; letter-spacing:0; font-weight:600; color:#9aa7b7; }
.pay-inputs input {
  font:inherit; font-size:14px; padding:12px 13px; border:1px solid var(--line);
  border-radius:11px; background:#fcfdff; color:var(--ink); min-width:0;
}
.pay-inputs input:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.pay-error { margin:0 0 6px; color:#b23a26; font-size:13px; font-weight:600; }
.pay-error[hidden] { display:none; }

.pay-foot {
  display:flex; align-items:center; justify-content:space-between; gap:18px; flex-wrap:wrap;
  padding:18px 30px 26px; border-top:1px solid var(--line); background:#fbfcfe;
  border-radius:0 0 22px 22px;
}
.pay-total { font-family:var(--sigle); font-size:16px; color:var(--navy); }
.pay-wait { color:var(--muted); font-size:12.5px; }
.pay-actions { display:flex; gap:10px; flex-wrap:wrap; margin-left:auto; }

/* --- paiements, côté administration */
.pay-setup {
  margin:0 0 18px; padding:14px 16px; border-radius:12px; border:1px solid var(--line);
  background:#f6f8fb; color:var(--navy); font-size:13px; line-height:1.65;
}
.pay-setup ul { margin:8px 0 0; padding-left:20px; }
.pay-setup li { margin:2px 0; }
.pay-setup.is-ok { border-color:#bfe4d2; background:#f0faf5; }
.pay-setup.is-alert { border-color:#f0c4b9; background:#fdf1ee; }
.pay-setup.is-off { border-color:#e6d6ae; background:#fdf8ec; }
.pay-settings-group { grid-column:1 / -1; margin-top:8px; }
.pay-settings-group h3 {
  font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--blue); margin:0 0 4px; padding-top:14px; border-top:1px solid var(--line);
}
.pay-settings-group p { margin:0; color:var(--muted); font-size:12.5px; }
.status-en_attente { background:#fdf1dc; color:#96601a; }
.status-valide { background:#e2f6ec; color:#146c4b; }
.status-refuse { background:#fbe4e0; color:#b23a26; }
.status-echoue { background:#fbe4e0; color:#b23a26; }
.status-annule { background:#eef1f5; color:#5c6a7c; }
.pay-amount { font-family:var(--sigle); font-weight:700; color:var(--navy); white-space:nowrap; }
/* Ce que la commande a payé : le rapport d'analyse, nommé sur la ligne pour que
   l'administrateur sache ce qu'il envoie. */
.pay-service { font-weight:600; color:var(--navy); }
/* Ce qui manque à une ligne — adresse non donnée, rapport non archivé — se lit
   en gris : ce n'est pas une faute, c'est une pièce absente. */
.pay-archive-missing { color:var(--muted); font-style:italic; }
/* Une commande payée dont le rapport n'est jamais arrivé dans l'archive : elle
   figure au tableau, et elle doit s'y voir du premier coup d'œil. */
.pay-row-missing > td { background:#fff6f4; }
.pay-row-missing > td:first-child { box-shadow:inset 3px 0 0 #c8452f; }
.pay-sent { color:#1c7a52; font-weight:700; }
/* La pièce scellée est partie chez le client sans consommer d'exemplaire : la
   ligne le dit, pour qu'un compteur d'exemplaires intact ne passe pas pour un
   téléchargement manqué. */
.pay-sealed { color:#5b6b80; font-weight:600; }
/* Le code qui ouvre la pièce du client, en clair et lisible d'un coup d'œil :
   l'administrateur le recopie dans son courrier. C'est le seul endroit du site
   où il s'affiche, et il doit se lire sans hésitation possible entre deux
   signes voisins — d'où la fonte à espacement fixe et l'interlettrage. */
.pay-code { color:var(--navy); font-weight:700; }
.pay-code code {
  font-family:var(--mono); font-size:12.5px;
  letter-spacing:.1em; color:var(--navy); background:#f2f6fb;
  border:1px solid #dbe5f0; border-radius:6px; padding:1px 6px; white-space:nowrap;
  user-select:all;
}

/* --- page « Paiements Wave » */
.wave-state {
  margin:0 0 18px; padding:14px 16px; border-radius:12px; border:1px solid var(--line);
  background:#f6f8fb; color:var(--navy); font-size:13px; line-height:1.65;
}
.wave-state.is-ok { border-color:#bfe4d2; background:#f0faf5; }
.wave-state.is-alert { border-color:#f0c4b9; background:#fdf1ee; }
.wave-state.is-off { border-color:#e6d6ae; background:#fdf8ec; }
.wave-filters {
  display:flex; align-items:flex-end; justify-content:space-between; gap:16px;
  flex-wrap:wrap; margin:0 0 14px;
}
.wave-tabs { display:flex; gap:6px; flex-wrap:wrap; }
.wave-tab {
  font:inherit; font-size:12.5px; font-weight:700; padding:8px 13px; border-radius:999px;
  border:1px solid var(--line); background:#fff; color:var(--muted); cursor:pointer;
}
.wave-tab:hover { border-color:#cfe0f7; color:var(--navy); }
.wave-tab.is-on { border-color:var(--blue); background:#f2f8ff; color:var(--navy); }
.wave-search { display:flex; gap:8px; align-items:center; margin-left:auto; }
.wave-search input {
  font:inherit; font-size:13.5px; padding:9px 12px; border:1px solid var(--line);
  border-radius:11px; background:#fcfdff; color:var(--ink); min-width:220px;
}
.wave-search input:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.wave-id {
  font-family:var(--mono); font-size:12px;
  color:var(--muted); word-break:break-all;
}
.field-hint { display:block; margin-top:5px; color:var(--muted); font-size:12px; line-height:1.55; }

@media (max-width: 640px) {
  .pay-inputs { grid-template-columns:1fr; }
  .pay-head, .pay-body, .pay-foot { padding-left:20px; padding-right:20px; }
  .pay-actions { width:100%; }
  .pay-actions .btn { flex:1 1 100%; justify-content:center; }
  .pay-locked .btn { margin-left:0; width:100%; justify-content:center; }
  .pay-wave .btn { width:100%; justify-content:center; }
  .pay-mail { padding:13px 14px; }
  .pay-mail-grid { grid-template-columns:1fr; }
  /* 16px : en dessous, l'iPhone zoome tout seul sur le champ. */
  .pay-mail-input { font-size:16px; }
  .wave-search { width:100%; }
  .wave-search input { min-width:0; flex:1 1 auto; }
}

/* ===================================================================
   Réglementation
   -------------------------------------------------------------------
   La rubrique de la page (#reglementation) et la fenêtre de consentement
   qui s'ouvre au clic sur « Lancer l'analyse » montrent le même texte :
   les styles du corps du texte (.terms-body, .terms-clauses) servent donc
   aux deux, la fenêtre n'ajoutant que son cadre.
   =================================================================== */

/* Le lien de l'en-tête : libellé entier sur grand écran, abrégé quand la
   barre de navigation manque de place — le lien et sa cible ne changent pas. */
.nav-terms-short { display:none; }
@media (max-width:1180px) and (min-width:901px) {
  .nav-terms-long { display:none; }
  .nav-terms-short { display:inline; }
}

.terms-body {
  border:1px solid var(--line); border-radius:18px; background:#fcfdff;
  padding:26px 28px; color:var(--ink);
}
.terms-body h3 {
  font-family:var(--titre); font-size:16px; color:var(--navy);
  margin:0 0 12px;
}
.terms-body h3 + p { margin-top:0; }
.terms-body > h3 ~ h3 { margin-top:26px; }
.terms-body p { margin:0 0 12px; font-size:14px; line-height:1.75; color:var(--muted); }
.terms-body em { color:#7d8b9d; font-style:italic; }
.terms-body strong { color:var(--navy); }

.terms-clauses { margin:0; padding-left:22px; display:grid; gap:16px; counter-reset:none; }
.terms-clauses li { font-size:14px; line-height:1.7; color:var(--muted); }
.terms-clauses li strong { display:block; color:var(--navy); font-size:14.5px; margin-bottom:3px; }
.terms-clauses li p { margin:0; }

.terms-accept {
  margin:22px 0 0; padding:14px 18px; border:1px solid #cfe0f7; border-radius:14px;
  background:#f2f8ff; color:var(--navy); font-size:14px;
}
.terms-note { margin:12px 0 0; color:var(--muted); font-size:13px; line-height:1.7; }

/* --- la fenêtre de consentement, ouverte au clic sur « Lancer l'analyse » */
.terms-modal { position:fixed; inset:0; z-index:70; display:flex; align-items:center; justify-content:center; padding:14px; overscroll-behavior:contain; }
.terms-modal[hidden] { display:none; }
.terms-backdrop { position:absolute; inset:0; background:rgba(10,23,48,.62); backdrop-filter:blur(3px); }
/* La fenêtre prend toute la largeur utile de l'écran : le texte réglementaire
   doit se lire d'un trait, sans colonne étroite ni défilement interminable. */
.terms-panel {
  position:relative; display:flex; flex-direction:column; width:min(1180px,100%); max-height:96vh;
  background:#fff; border-radius:20px; box-shadow:0 34px 80px rgba(10,23,48,.34); overflow:hidden;
}
/* En-tête, formulaire et pied ne se compriment jamais : les deux boutons du
   bas — « Annuler » et « J'ACCEPTE » — doivent rester atteignables, y compris
   sur un écran court, où c'est le texte à lire qui cède la place. */
.terms-head, .terms-form, .terms-foot { flex:0 0 auto; }
/* L'en-tête et le formulaire se font discrets : la place va au texte à lire. */
.terms-head { padding:16px 30px 12px; border-bottom:1px solid var(--line); }
.terms-kicker { display:block; font-size:var(--t4); font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--blue); }
.terms-head h3 { font-family:var(--titre); font-size:17px; color:var(--navy); margin:5px 0 5px; }
.terms-head p { margin:0; color:var(--muted); font-size:12.5px; line-height:1.5; }

/* Le texte réglementaire défile dans la fenêtre : les boutons restent visibles
   sans qu'il faille faire défiler la page entière pour les atteindre. */
/* `overscroll-behavior:contain` : arrivé au bout des vingt clauses, le
   défilement s'arrête là. Sans cela il se prolongeait sur la page cachée
   derrière la fenêtre, qui descendait jusqu'au pied du site — et « J'ACCEPTE »
   ne ramenait plus la rubrique d'analyse à l'écran. */
.terms-scroll {
  flex:1 1 auto; min-height:34vh; overflow-y:auto; padding:18px 30px;
  overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
}
/* Écran court : la zone de lecture se réduit sans repousser le pied dehors. */
@media (max-height: 720px) {
  .terms-scroll { min-height:0; }
}
.terms-scroll .terms-body { border:0; border-radius:0; background:none; padding:0; }
.terms-scroll .terms-body p, .terms-scroll .terms-clauses li { font-size:14.5px; line-height:1.7; }
/* Sur les grands écrans, les 20 clauses se lisent sur deux colonnes : tout le
   texte tient sous les yeux avant l'acceptation. */
@media (min-width: 1000px) {
  .terms-scroll .terms-clauses { grid-template-columns:repeat(2,minmax(0,1fr)); column-gap:34px; align-items:start; }
}
.terms-scroll:focus { outline:2px solid rgba(23,105,224,.3); outline-offset:-4px; }

.terms-form { padding:2px 30px 12px; border-top:1px solid var(--line); }
/* Prénom, nom et adresse tiennent sur une seule ligne : trois champs compacts
   plutôt qu'un bloc qui mange la hauteur de lecture. */
.terms-inputs { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; margin-top:10px; }
.terms-field { display:flex; flex-direction:column; gap:4px; font-size:9.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.terms-field-wide { grid-column:auto; }
.terms-field input {
  font:inherit; font-size:13.5px; padding:8px 10px; border:1px solid var(--line);
  border-radius:9px; background:#fcfdff; color:var(--ink); min-width:0;
  text-transform:none; letter-spacing:0; font-weight:400;
}
.terms-field input:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.terms-check { display:flex; align-items:flex-start; gap:9px; margin-top:10px; font-size:12px; color:var(--ink); line-height:1.5; cursor:pointer; }
.terms-check input { margin-top:1px; width:16px; height:16px; flex:none; accent-color:var(--blue); }
.terms-check strong { color:var(--navy); }
/* Une étape que le site ne peut pas rendre : la case le dit à côté de son intitulé. */
.option-note { margin-left: 6px; font-size: 11.5px; font-style: italic; color: #6b7a90; }
.terms-error { margin:8px 0 0; color:#b23a26; font-size:12.5px; font-weight:600; }
.terms-error[hidden] { display:none; }

.terms-foot {
  display:flex; align-items:center; justify-content:flex-end; gap:10px; flex-wrap:wrap;
  padding:10px 30px 14px; border-top:1px solid var(--line); background:#fbfcfe;
}
.terms-foot .btn { padding:10px 18px; font-size:13px; }

@media (max-width: 900px) {
  .terms-inputs { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .terms-field-wide { grid-column:1 / -1; }
}

@media (max-width: 640px) {
  .terms-body { padding:20px 18px; }
  .terms-modal { padding:8px; }
  .terms-panel { max-height:97vh; border-radius:16px; }
  .terms-head, .terms-scroll, .terms-form, .terms-foot { padding-left:16px; padding-right:16px; }
  .terms-inputs { grid-template-columns:1fr; gap:8px; }
  .terms-scroll { min-height:0; }
  /* 16px : en dessous, l'iPhone zoome tout seul sur le champ. */
  .terms-field input { font-size:16px; padding:9px 10px; }
  .terms-foot .btn { flex:1 1 100%; justify-content:center; }
}


/* =====================================================================
   L'entrée de la fonction, dans le bandeau
   ---------------------------------------------------------------------
   Le bandeau annonce la fonction du site et son bouton dans un même cadre.
   La rubrique « Nos services » monte contre l'analyse qui la précède : son
   espace est resserré ici, en un seul endroit.
   ===================================================================== */

/* Les trois fonctions du site tiennent sur une seule ligne, en trois colonnes
   d'égale largeur : elles se lisent d'un coup d'œil, dans leur ordre — analyser,
   évaluer, corriger —, et aucune ne paraît plus importante qu'une autre.
   Les trois cartes sont taillées à l'identique : la grille leur donne la même
   largeur, l'alignement `stretch` la même hauteur, et le bouton de chacune
   occupe tout ce qui reste sous sa mention. Les intitulés n'ont pourtant pas la
   même longueur — « Corriger et nettoyer » est plus court qu'« Évaluer et
   annoter un texte » : le texte est donc centré et peut passer à la ligne sans
   que la carte change de taille. */
.hero-fonctions {
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  align-items:stretch; gap:12px; margin:16px 0 0;
}
.hero-fonction {
  display:flex; flex-direction:column; align-items:stretch; gap:10px;
  padding:14px; border:1px solid var(--line); border-radius:16px; background:rgba(255,255,255,.72);
}
.hero-fonction-num {
  flex:none; text-align:center; text-transform:uppercase; letter-spacing:.16em;
  font-size:var(--t4); font-weight:700; color:var(--blue);
}
/* Le bouton prend toute la carte : trois boutons de même largeur et de même
   hauteur, quel que soit le nombre de lignes de leur intitulé. */
.hero-fonction .btn {
  flex:1 1 auto; min-height:48px; justify-content:center; text-align:center;
  gap:10px; line-height:1.35;
}

/* Sous cette largeur, trois colonnes ne laisseraient plus qu'un mot par ligne :
   les cartes se rangent alors l'une sous l'autre, toujours de mêmes dimensions
   et dans le même ordre. */
@media (max-width:760px) {
  .hero-fonctions { grid-template-columns:minmax(0,1fr); }
}

.services { padding-top:14px; }


/* =====================================================================
   CAMES — la note sur l'agrément des plateformes de détection de plagiat
   ---------------------------------------------------------------------

/* ---------------------------------------------------------------------
   CAMES-PRECISION — la pièce dépliée en tête de la page de garde
   ---------------------------------------------------------------------
   Le bouton est le premier élément de l'accueil, au-dessus de l'enseigne :
   il garde donc le bleu des boutons d'action, mais reste seul sur sa ligne
   et à sa propre largeur (inline-flex hérité de .btn), pour ne pas se lire
   comme un titre. Le panneau qui se déplie dessous porte les pages du PDF,
   dessinées par assets/cames-precision.js dans des <canvas> : ils ne
   dépassent jamais la largeur disponible, et le panneau se fait défilant
   au-delà d'une hauteur d'écran pour que l'enseigne ne soit pas repoussée
   hors de vue.
   --------------------------------------------------------------------- */

/* À qui la pièce paraît, et à qui elle ne paraît pas.
   La note du CAMES ne règle la vie universitaire que des pays membres du
   Conseil africain et malgache pour l'enseignement supérieur : elle est donc
   fermée par défaut, et seule une page servie à un lecteur d'Afrique
   subsaharienne l'ouvre. La zone est écrite sur la balise <html> au bord du
   réseau — `data-fontexte-zone="cames"` (netlify/edge-functions/langue.ts et
   netlify/lib/zones.mjs) —, et rétablie de son cookie sur une page lue hors
   connexion (assets/cames-precision.js).
   C'est la feuille de style qui décide, et non un script : un visiteur hors
   zone ne voit jamais la pièce paraître puis disparaître, et une page dont le
   marquage manquerait la garde fermée plutôt que de l'ouvrir à tort. */
.cames-precision { display:none; margin:0 0 18px; }
html[data-fontexte-zone="cames"] .cames-precision { display:block; }
.cames-precision-bouton { letter-spacing:.04em; gap:10px; }
/* Le chevron dit dans quel sens ira le prochain clic : vers le bas quand la
   pièce est repliée, vers le haut quand elle est ouverte. */
.cames-precision-chevron {
  display:inline-block; font-size:14px; line-height:1; transition:transform .2s;
}
.cames-precision-bouton[aria-expanded="true"] .cames-precision-chevron {
  transform:rotate(180deg);
}
.cames-precision-panneau {
  margin:14px 0 0; padding:16px; border:1px solid var(--line); border-radius:16px;
  background:#fcfdff;
}
.cames-precision-panneau[hidden] { display:none; }
.cames-precision-titre {
  margin:0 0 12px; font-size:12.5px; line-height:1.6; color:var(--muted);
}
.cames-precision-etat { margin:0 0 12px; font-size:13px; line-height:1.6; color:var(--blue); }
.cames-precision-etat[hidden] { display:none; }
.cames-precision-pages {
  display:grid; gap:12px; max-height:70vh; overflow:auto;
  overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
}
.cames-precision-page {
  display:block; width:100%; height:auto; border:1px solid var(--line);
  border-radius:10px; background:#fff;
}
.cames-precision-liens {
  margin:12px 0 0; display:flex; flex-wrap:wrap; gap:16px;
  font-size:13px; font-weight:700;
}
.cames-precision-liens a { color:var(--blue); }
.cames-precision-liens a:hover { text-decoration:underline; }

@media (max-width:640px) {
  .cames-precision-panneau { padding:12px; }
  .cames-precision-pages { max-height:60vh; }
}


/* =====================================================================
   L'atelier de correction « Texte propre », dans la console
   ---------------------------------------------------------------------
   Repris de l'Atelier de relecture (assets/propre.js, et la feuille
   bureau.css de cette archive-là), rendu ici avec les couleurs et les
   mesures de FONTEXTE. Trois pièces : le feuillet de bilan qui dit ce
   que la pièce importée contient, la ligne d'état qui dit où en est la
   correction, et l'aperçu du texte propre.
   ===================================================================== */

.propre-actions { margin-top:18px; }

/* Le feuillet : une ligne par constat — volume, langue, annotations,
   forme du document rendu. Les cases se posent côte à côte et passent à
   la ligne d'elles-mêmes. */
.bilan-bureau {
  display:flex; flex-wrap:wrap; gap:8px; margin:16px 0 0; padding:0; list-style:none;
}
.bilan-bureau:empty { margin:0; }
.bilan-bureau li {
  border:1px solid var(--line); border-left:3px solid var(--blue);
  background:#f7fafd; border-radius:6px; padding:6px 12px;
  font-size:12px; color:var(--muted);
}
.bilan-bureau b { color:var(--navy); font-variant-numeric:tabular-nums; }

/* La ligne d'état. Elle parle beaucoup — une correction dure —, et elle
   passe au rouge quand elle annonce un ennui. */
.avis-bureau { margin:14px 0 0; font-size:13px; line-height:1.55; color:var(--muted); }
.avis-bureau.erreur { color:#b4232a; }
.avis-bureau[hidden] { display:none; }

/* L'aperçu du texte propre : du texte déjà mis en forme au fil des
   lignes, qui ne demande qu'à être respecté. */
.lecture-rapport {
  margin:16px 0 0; padding:16px 18px; max-height:min(70vh,820px); overflow:auto;
  white-space:pre-wrap; overflow-wrap:break-word;
  border:1px solid var(--line); border-radius:10px; background:#fbfcfe;
  font-family:var(--texte); font-size:13px; line-height:1.7; color:var(--navy);
}
.lecture-rapport[hidden] { display:none; }


/* =====================================================================
   CORRECTION — la troisième fonction, rubrique d'accueil
   ---------------------------------------------------------------------
   Trois cartes d'égale largeur : ce que la correction reprend, ce que le
   client reçoit, comment il la demande. Le même dessin que les cartes de
   l'enseigne d'accueil (.hero-fonction) — bord fin, angle largement
   arrondi, fond presque blanc —, pour que la rubrique ne paraisse pas
   venir d'un autre site que celle qui l'annonce en haut de page.
   ===================================================================== */
.correction-grid {
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  align-items:stretch; gap:14px; margin:20px 0 0;
}
.correction-carte {
  display:flex; flex-direction:column; gap:10px;
  padding:20px; border:1px solid var(--line); border-radius:18px; background:#fff;
}
.correction-carte h3 {
  font-family:var(--titre); font-size:15.5px; color:var(--navy); margin:0;
}
.correction-carte p { margin:0; color:var(--muted); font-size:13.5px; line-height:1.65; }
.correction-carte ul { margin:0; padding-left:18px; }
.correction-carte li {
  color:var(--muted); font-size:13.5px; line-height:1.6; margin-bottom:6px;
}
.correction-carte li:last-child { margin-bottom:0; }
/* Le bouton de la troisième carte se pose en bas : les trois cartes n'ont pas
   le même nombre de lignes, et un bouton flottant au milieu de la colonne
   donnerait l'impression d'une carte inachevée. */
.correction-carte .btn { margin-top:auto; justify-content:center; }

/* Sous cette largeur, trois colonnes ne laissent plus qu'un ou deux mots par
   ligne : les cartes se rangent l'une sous l'autre, dans le même ordre. */
@media (max-width:860px) {
  .correction-grid { grid-template-columns:minmax(0,1fr); }
}


/* =====================================================================
   CODE — la rubrique qui accueille les codes de gratuité
   ---------------------------------------------------------------------
   Trois cartes encore, mais elles ne pèsent pas le même poids. Celle de
   gauche porte la règle des deux appareils, et c'est elle qu'on doit lire
   avant d'écrire son code : elle est donc marquée d'un liseré bleu sur son
   flanc, comme les pièces qui énoncent une condition ailleurs dans le site.
   Celle de droite n'existe que lorsqu'une gratuité est ouverte sur
   l'appareil — elle est masquée par `hidden` jusque-là (assets/gratuite.js).
   ===================================================================== */
.gratuite-grid {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(272px,1fr));
  align-items:start; gap:14px; margin:20px 0 0;
}
.gratuite-carte {
  display:flex; flex-direction:column; gap:10px;
  padding:20px; border:1px solid var(--line); border-radius:18px; background:#fff;
}
.gratuite-carte[hidden] { display:none; }
.gratuite-carte h3 {
  font-family:var(--titre); font-size:15.5px; color:var(--navy); margin:0;
}
.gratuite-carte p { margin:0; color:var(--muted); font-size:13.5px; line-height:1.65; }

/* La carte de la règle. Le liseré la désigne sans la crier. */
.gratuite-regle { border-left:3px solid var(--blue); background:#f7fafd; }

/* La règle elle-même, en capitales : un client qui ne l'a pas lue prendra le
   refus du troisième appareil pour une panne. Elle est dite dans le romain des
   titres, en bleu, largement interlettrée — le ton d'une mention portée sur un
   document, non celui d'une alerte. */
.gratuite-loi {
  margin:0; font-family:var(--titre); font-size:14px; font-weight:600;
  letter-spacing:.06em; line-height:1.6; color:var(--navy);
}

/* Le champ du code. Il est écrit dans une chasse fixe et largement espacé :
   un code se relit signe par signe, souvent à voix haute au téléphone, et le
   zéro doit se distinguer de la lettre O. */
.gratuite-form { display:flex; flex-direction:column; gap:10px; }
.gratuite-label {
  font-family:var(--texte); font-size:var(--t4); font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--blue);
}
.gratuite-input {
  font:inherit; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:15px; letter-spacing:.12em; text-transform:uppercase;
  padding:13px 14px; border:1px solid var(--line); border-radius:11px;
  background:#fcfdff; color:var(--ink); min-width:0;
}
.gratuite-input:focus { outline:2px solid rgba(23,105,224,.3); border-color:var(--blue); }
.gratuite-aide { margin:0; color:var(--muted); font-size:12px; line-height:1.55; }
.gratuite-form .btn { justify-content:center; }

/* Le seul endroit où l'on parle au client : le refus du serveur y est recopié
   tel quel — « les deux places de ce code sont déjà prises » comme le reste. */
.gratuite-message {
  margin:0; padding:10px 12px; border-radius:10px;
  font-size:13px; line-height:1.55;
  border:1px solid var(--line); background:#f7fafd; color:var(--navy);
}
.gratuite-message[hidden] { display:none; }
.gratuite-message.is-good { border-color:rgba(23,105,224,.35); }
.gratuite-message.is-bad { border-color:rgba(180,35,42,.35); background:#fdf6f6; color:#b4232a; }

/* La fiche de la gratuité ouverte : deux colonnes, l'intitulé et la valeur,
   comme les fiches de la page d'administration. */
.gratuite-fiche { margin:0; display:grid; gap:10px; }
.gratuite-fiche > div { display:grid; gap:2px; }
.gratuite-fiche dt {
  font-family:var(--texte); font-size:var(--t4); font-weight:700;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted);
}
.gratuite-fiche dd {
  margin:0; font-size:14px; color:var(--navy); overflow-wrap:break-word;
}
.gratuite-etat .btn { margin-top:auto; justify-content:center; }

/* Le tableau des codes, dans la console d'administration. Les deux places de
   chaque code y tiennent dans une seule cellule : c'est la colonne qu'on lit
   quand un client appelle pour dire qu'il est refusé. */
.gratuite-appareils { margin:0; padding:0; list-style:none; display:grid; gap:8px; }
.gratuite-appareils li { font-size:12.5px; line-height:1.5; color:var(--muted); }
.gratuite-appareils strong { color:var(--navy); }
.gratuite-libre { color:var(--blue); }
.gratuite-note, .gratuite-agent { color:var(--muted); font-size:11.5px; }
.gratuite-agent { overflow-wrap:anywhere; }
