/* Office Manager Group — Air Corsica. Feuille unique, aucune dependance.
 *
 * Reprise de la charte de la maquette validee par le client le 29/07/2026 :
 * bleu froid, ombres douces, coins arrondis. L'ancienne charte etait creme et
 * brune — ce n'etaient pas deux variantes, c'etaient deux chartes.
 *
 * LES NOMS DE CLASSES RESTENT EN FRANCAIS, et restent ceux d'avant. La maquette
 * emploie `.card`, `.panel`, `.btn`, `.badge` ; le projet emploie `.carte`,
 * `.panneau`, `.bouton`, `.mvt-type`. Garder les noms existants tient la
 * convention du depot ET evite de toucher cinquante gabarits : on reecrit UNE
 * feuille, pas cinquante fichiers.
 *
 * Deux jetons de la maquette ont ete RENOMMES : `--brown` y valait #004B86,
 * c'est-a-dire du bleu marine, et `--cream` du bleu pale. Garder ces noms aurait
 * fait chercher du brun a qui aurait trouve du bleu. Les valeurs, elles, sont
 * exactes au caractere pres.
 */

:root {
  --fond:        #F4F7FA;
  --surface:     #FFFFFF;
  --surface-2:   #EDF2F8;
  --surface-3:   #E1EAF3;

  --encre:       #15283A;
  --doux:        #4C6076;
  /* ⚠️ MESURE SUR TOUS LES FONDS OU IL SE POSE, PAS SUR UN SEUL.
     Il etait regle sur --surface-2 (4,62:1) et tombait a 4,26:1 sur
     --surface-3 et sur les fonds teintes des cartes d'alerte — sous le seuil,
     sans que rien ne le dise : la charte ne declare pas ces paires-la.
     Trouve en RENDANT les 224 ecrans dans les deux modes. */
  --efface:      #5A6B79;   /* 4,53:1 au pire, sur les huit fonds employes */
  --ligne:       #DBE5EF;
  --ligne-douce: #EAF0F6;

  /* ⚠️ C'EST AUSSI LA COULEUR DES LIENS, donc du TEXTE — seuil 4,5:1.
     A #0079B3 il tenait sur le blanc et tombait a 3,94:1 sur les fonds
     teintes : un lien « Ajouter un contact » dans un bandeau d'alerte, un
     numero de dossier dans une note, la pagination sur --surface-2. Trente-six
     occurrences du seul « suivante ». Assombri de 8 % : invisible a l'oeil,
     decisif a la mesure. Le blanc qui s'ecrit DESSUS y gagne aussi. */
  --accent:      #006FA5;   /* 4,52:1 au pire, sur les huit fonds employes */
  --accent-fort: #005E8C;
  --accent-pale: #DCEDF7;
  /* Ce qui s'ECRIT SUR l'accent. En clair l'accent est fonce, donc blanc ;
     en sombre il s'eclaircit — et le blanc y tombait a 2,92:1, sous le seuil,
     sur le bouton primaire, le controle le plus important de l'application.
     Ce jeton bascule ; `color: #fff` en dur ne pouvait pas. */
  --sur-accent:  #FFFFFF;

  --marine:      #004B86;   /* etait « --brown » dans la maquette */
  --marine-pale: #EAF3FA;   /* etait « --cream » */

  /* Categorie d'agence — c'est ce champ qui decide si XK facture 8 EUR, 3 EUR
     ou rien. La maquette lui donne trois couleurs pour qu'il se lise en
     balayant une liste, sans ouvrir la fiche. */
  --emet:        #C0392B;  --emet-fond:    #FBEBE8;  --emet-ligne:    #F0C9C2;
  --nonemet:     #2563EB;  --nonemet-fond: #E9F0FD;  --nonemet-ligne: #CBDCF8;
  --compte:      #5B6470;  --compte-fond:  #EFF1F3;  --compte-ligne:  #DCE0E5;

  --ok:    #1B7B44;  --ok-fond:    #E7F4EC;  --ok-ligne:   #BFE3CD;   /* 4,01 -> 4,67 */
  --avert: #936316;  --avert-fond: #FBF1DC;  --avert-ligne:#E8CF9A;   /* 3,40 -> 4,64 */
  --crit:  #C0392B;  --crit-fond:  #FBEBE8;  --crit-ligne: #F0C9C2;

  --ombre:  0 1px 2px rgba(21,40,58,.06), 0 4px 16px rgba(21,40,58,.08);
  --rayon:  12px;
  --rayon-s: 8px;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --largeur-lateral: 236px;
  --largeur-rail:    58px;
}

/* Mode sombre. Trois formes : la preference du systeme, et les deux forcages
   par attribut, pour que le bouton de bascule l'emporte dans les deux sens. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fond:#0D1620; --surface:#152230; --surface-2:#1C2C3B; --surface-3:#243748;
    --encre:#DCE8F2; --doux:#9DB2C6; --efface:#8C9FB3; --ligne:#293A4C; --ligne-douce:#1D2D3D;
    --accent:#3CA6E1; --accent-fort:#5BB4E4; --accent-pale:#14303F;
    --sur-accent:#0D1620;
    --marine:#0E1D2B; --marine-pale:#DCE8F2;
    --emet:#E8776B; --emet-fond:#331E1B; --emet-ligne:#4E2A25;
    --nonemet:#6EA0F5; --nonemet-fond:#17263B; --nonemet-ligne:#2A3A55;
    --compte:#9BA8B6; --compte-fond:#212C38; --compte-ligne:#33404E;
    --ok:#5FC489; --ok-fond:#132A20; --ok-ligne:#1F4433;
    --avert:#DDA23F; --avert-fond:#2C2513; --avert-ligne:#4A3D1C;
    --crit:#E8776B; --crit-fond:#331E1B; --crit-ligne:#4E2A25;
    --ombre: 0 1px 2px rgba(0,0,0,.3), 0 6px 20px rgba(0,0,0,.4);
  }
}
:root[data-theme="dark"] {
  --fond:#0D1620; --surface:#152230; --surface-2:#1C2C3B; --surface-3:#243748;
  --encre:#DCE8F2; --doux:#9DB2C6; --efface:#8C9FB3; --ligne:#293A4C; --ligne-douce:#1D2D3D;
  --accent:#3CA6E1; --accent-fort:#5BB4E4; --accent-pale:#14303F;
  --sur-accent:#0D1620;
  --marine:#0E1D2B; --marine-pale:#DCE8F2;
  --emet:#E8776B; --emet-fond:#331E1B; --emet-ligne:#4E2A25;
  --nonemet:#6EA0F5; --nonemet-fond:#17263B; --nonemet-ligne:#2A3A55;
  --compte:#9BA8B6; --compte-fond:#212C38; --compte-ligne:#33404E;
  --ok:#5FC489; --ok-fond:#132A20; --ok-ligne:#1F4433;
  --avert:#DDA23F; --avert-fond:#2C2513; --avert-ligne:#4A3D1C;
  --crit:#E8776B; --crit-fond:#331E1B; --crit-ligne:#4E2A25;
  --ombre: 0 1px 2px rgba(0,0,0,.3), 0 6px 20px rgba(0,0,0,.4);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--encre);
  background: var(--fond);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }

/* ⚠️ L'ANNEAU DE FOCUS — IL N'EXISTAIT SUR AUCUN BOUTON NI AUCUN LIEN.
 *
 * Trois regles `:focus` dans toute la feuille : les champs de saisie, et le
 * `summary` d'un repli. Rien pour `.bouton`, rien pour les liens, rien pour les
 * onglets. Qui navigue AU CLAVIER ne voyait donc pas ou il etait — il tabulait
 * jusqu'a « Emettre l'avoir » sans le savoir, et appuyait sur Entree.
 *
 * Meme famille que les onglets invisibles, mais sur les commandes qui AGISSENT
 * plutot que sur celles qui naviguent.
 *
 * ⚠️ ET L'ANNEAU DES CHAMPS ETAIT A 1,20:1. Il employait `--accent-pale`, un
 * bleu de FOND, la ou il faut un TRAIT. Le WCAG demande 3:1 pour un indicateur
 * de focus ; on en etait au tiers, dans les deux modes. Le jeton juste existait
 * deja — `--accent` donne 4,79:1 en clair et 5,52:1 en sombre.
 *
 * ⚠️ `:focus-visible` ET NON `:focus`. Le premier ne se declenche qu'au clavier ;
 * le second cerclerait chaque bouton qu'on vient de CLIQUER, et un anneau qui
 * reste apres un clic se lit comme un defaut d'affichage. On finirait par le
 * retirer, et le clavier le perdrait avec.
 *
 * `outline-offset` decolle le trait du bord : colle, il se confond avec la
 * bordure de l'element et disparait sur ceux qui en portent deja une.
 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 16px; margin-bottom: 10px; }
h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
     color: var(--efface); font-weight: 700; margin: 20px 0 10px; }
.num  { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono); font-size: 12.5px; letter-spacing: -.02em;
        font-variant-numeric: tabular-nums; }

/* ============================================================ la coquille
 * Menu lateral RETRACTABLE, et non barre haute.
 *
 * Deux raisons, et aucune n'est de gout. La loi de Fitts : les bords de l'ecran
 * sont des cibles infinies, on ne peut pas les depasser — mais dans un
 * navigateur, une barre en haut de PAGE n'est pas au bord de l'ECRAN, les
 * onglets et la barre d'adresse sont au-dessus. Le lateral, lui, touche
 * vraiment le bord gauche. Et le menu portait deja onze entrees : il a
 * deborde une fois (voir `flex-wrap`, incident du 29/07), et le virage en
 * ajoute.
 *
 * Retractable parce que les tableaux sont larges. Deploye 236 px, replie 58.
 */
.appli {
  display: grid;
  grid-template-columns: var(--largeur-lateral) 1fr;
  min-height: 100vh;
}
.appli.replie { grid-template-columns: var(--largeur-rail) 1fr; }

.lateral {
  background: var(--marine);
  color: var(--marine-pale);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.marque { padding: 18px 16px 13px; border-bottom: 1px solid rgba(255,255,255,.12); }
.marque a { color: inherit; text-decoration: none; font-weight: 800; letter-spacing: .01em;
            display: block; font-size: 15px; }
.marque span {
  display: block; font-size: 10px; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; opacity: .6; margin-top: 6px;
}
.appli.replie .marque { padding: 18px 10px 13px; text-align: center; }
.appli.replie .marque span,
.appli.replie .menu .libelle-menu,
.appli.replie .groupe-menu,
.appli.replie .pied-lateral { display: none; }

.menu { padding: 9px; display: flex; flex-direction: column; gap: 2px; flex: 1; }
.menu a {
  display: flex; align-items: center; gap: 11px; padding: 8px 11px;
  border-radius: 9px; color: rgba(255,255,255,.8); text-decoration: none;
  font-size: 13.5px; font-weight: 500; white-space: nowrap;
}
.menu a:hover { background: rgba(255,255,255,.09); color: #fff; }
.menu a.actif { background: var(--accent); color: var(--sur-accent); font-weight: 600; }
/* ⚠️ LA CLASSE PORTE SA PROPRE TAILLE, elle n'est plus dimensionnee PAR SON
   PARENT. La regle valait `.menu a .ic` : posee ailleurs — au pied du menu —
   l'icone retombait au `fill: black` par defaut de SVG et prenait toute la
   place du conteneur flex. Un triangle noir de deux centimetres.
   Deux `<svg class="ic">` du meme fichier portaient deja un `width="17"` EN
   DUR : quelqu'un avait bute dessus et contourne, sans corriger la cause. */
.ic { width: 17px; height: 17px; flex: none; stroke: currentColor;
      fill: none; stroke-width: 1.7; }
.menu a .ic { opacity: .9; }
.menu a .compteur {
  margin-left: auto; font-size: 9.5px; font-weight: 800; letter-spacing: .05em;
  background: rgba(255,255,255,.2); padding: 1px 6px; border-radius: 5px;
}
.groupe-menu {
  font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  font-weight: 800; color: rgba(255,255,255,.45); padding: 14px 12px 4px;
}
.appli.replie .menu a { justify-content: center; padding: 9px 0; }
.appli.replie .menu a .compteur { display: none; }
.pied-lateral {
  padding: 12px 16px; border-top: 1px solid rgba(255,255,255,.12);
  font-size: 11.5px; color: rgba(255,255,255,.55);
}
/* ⚠️ MESURE : `--accent-fort` donnait 1,27:1 en clair (seuil AA 4,5) — du bleu
   sur du bleu. En sombre le meme jeton donne 7,40:1, d'ou un defaut qui ne se
   voyait que dans UN mode. `--marine-pale` : 7,95:1 en clair, 13,72:1 en sombre,
   et c'est deja le jeton du reste du panneau. La paire est desormais mesuree par
   controler-charte, sans quoi elle rederiverait. */
.pied-lateral a {
  color: var(--marine-pale); text-decoration: none;
  display: flex; align-items: center; gap: 9px;
}
.pied-lateral a:hover { text-decoration: underline; }
.pied-lateral .version {
  display: block; margin-top: 7px; font-size: 10.5px;
  color: rgba(255,255,255,.55); font-variant-numeric: tabular-nums;
}

.principal { min-width: 0; display: flex; flex-direction: column; }

/* La barre haute ne porte plus la navigation : le titre, la recherche, qui
   est connecte, et la bascule du menu. */
.bandeau {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 24px; border-bottom: 1px solid var(--ligne);
  background: var(--surface); position: sticky; top: 0; z-index: 5;
}
.bandeau .titre { font-size: 17px; font-weight: 680; }
.grandir { flex: 1; }
.qui { color: var(--doux); font-size: 12.5px; }
.avatar {
  width: 32px; height: 32px; border-radius: 50%; background: var(--accent);
  color: var(--sur-accent); display: grid; place-items: center;
  font-weight: 650; font-size: 12.5px;
}
.bouton-icone {
  cursor: pointer; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 9px; border: 1px solid var(--ligne); background: var(--surface-2);
  color: var(--doux); padding: 0; font: inherit;
}
.bouton-icone:hover { color: var(--accent); border-color: var(--accent); }

.page { padding: 20px 24px 44px; max-width: 1320px; width: 100%; }
.page.etroite { max-width: 430px; padding-top: 54px; margin: 0 auto; }
.page.etroite-public { max-width: 720px; padding-top: 30px; margin: 0 auto; }
.pied {
  border-top: 1px solid var(--ligne); padding: 13px 24px;
  font-size: 11.5px; color: var(--efface); margin-top: auto;
}
.pied a { color: var(--accent); }

.intro { color: var(--doux); margin: 6px 0 0; font-size: 13px; }
.fil { font-size: 12.5px; color: var(--efface); margin: 0 0 12px; }
.fil a { color: var(--doux); text-decoration: none; }
.fil a:hover { color: var(--accent); text-decoration: underline; }
.entete-page { margin-bottom: 18px; }
.titre-section {
  margin: 26px 0 12px; font-size: 15px; font-weight: 680;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  text-transform: none; letter-spacing: -.01em; color: var(--encre);
}
.vide { color: var(--efface); font-style: normal; padding: 14px 2px; }
.a-confirmer { color: var(--avert); font-size: 12.5px; font-weight: 600; }

/* ============================================================ alertes et notes */
.alerte {
  border-radius: 10px; padding: 10px 14px; font-size: 13px; margin: 0 0 14px;
  border: 1px solid; border-left-width: 3px;
}
.alerte.info   { background: var(--nonemet-fond); border-color: var(--nonemet-ligne); color: var(--nonemet); }
.alerte.ok     { background: var(--ok-fond);      border-color: var(--ok-ligne);      color: var(--ok); }
.alerte.danger { background: var(--crit-fond);    border-color: var(--crit-ligne);    color: var(--crit); }
/* Bandeau « SITE DE TEST » — voir le pave de src/Vue/gabarit.php.
   Il remplace la garde nginx retiree le 08/08/2026 : sans lui, le site de test
   et la production sont indiscernables — meme apparence, memes comptes, memes
   donnees.
   ⚠️ Il emploie le couple --crit / --crit-fond, DEJA MESURE par
   controler-charte dans les deux modes. Un rouge plein ecrit en dur aurait cree
   une paire que personne ne mesure — et c'est exactement ce que le controle a
   refuse au premier jet. */
.bandeau-test {
  background: var(--crit-fond); color: var(--crit);
  border-bottom: 2px solid var(--crit-ligne);
  text-align: center; padding: .45rem .75rem;
  font-weight: 700; letter-spacing: .05em; font-size: .85rem; line-height: 1.35;
}
/* Le cran manquant entre « info » et « danger » : ce qui n'est pas encore une
   faute mais qui va detruire. Le couple --avert/--avert-fond est celui de
   .pastille-alerte, deja mesure par controler-charte.php dans les deux modes ;
   poser --avert sur une surface neutre aurait cree une paire non mesuree. */
.alerte.attention { background: var(--avert-fond); border-color: var(--avert-ligne); color: var(--avert); }
/* Dans un champ de formulaire, la boite reste serree : elle explique le champ
   au-dessus, elle ne le remplace pas. */
.champ .alerte { font-size: 12px; padding: 8px 11px; margin: 6px 0 0; max-width: 620px; }
/* `display: block` N'EST PAS DECORATIF.
   `.note` porte 10 px de remplissage vertical, une bordure et un fond ; posee
   sur un `<span>` — 27 fois dans les gabarits — elle restait EN LIGNE. Or un
   element en ligne ne pousse pas les lignes voisines : son fond et sa bordure
   debordent par-dessus. Sur la fiche dossier, la note du tarif resident
   recouvrait « frais de service au tarif resident », etiquette de la case a
   cocher juste au-dessus. Le HTML etait juste ; c'est le mode d'affichage qui
   ne l'etait pas. */
.note {
  display: block;
  font-size: 12px; color: var(--efface); margin-top: 12px; padding: 10px 13px;
  background: var(--surface-2); border: 1px solid var(--ligne);
  border-radius: 9px; border-left: 3px solid var(--accent);
}
.note b, .note strong { color: var(--doux); }
/* LA VALEUR QU'UNE NOTE PROPOSE, et qui doit se lire d'un coup d'oeil.
   Une note est en `--efface` — volontairement en retrait, c'est un
   commentaire. Mais « pre-remplie avec KDI TRAVEL » contient UN mot qui n'est
   pas du commentaire : le nom qu'on s'apprete a poser sur une fiche client,
   puis sur des factures. Il etait au meme gris que le reste de la phrase.
   `<strong>` ne suffisait pas : la regle ci-dessus le rend en `--doux`, donc
   plus pale encore que l'intention. */
.note .valeur { color: var(--encre); font-weight: 700; }

/* ============================================================ cartes de tete */
.cartes {
  display: grid; gap: 13px; margin: 16px 0 6px;
  grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
}
.carte {
  background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon); padding: 14px 15px; box-shadow: var(--ombre);
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 2px;
}
.carte::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--accent);
}
.carte.attention::before { background: var(--avert); }
.carte.danger::before    { background: var(--crit); }
.carte.attention { background: var(--avert-fond); border-color: var(--avert-ligne); }
.carte.danger    { background: var(--crit-fond);  border-color: var(--crit-ligne); }
.etiq {
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--doux); font-weight: 650;
}
.chiffre { font-size: 25px; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; margin-top: 5px; }
.chiffre.petit { font-size: 18px; }
.sous { font-size: 11.5px; color: var(--efface); }

/* ============================================================ barre d'outils */
.barre-outils {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-bottom: 13px;
}
/* ⚠️ LE LISERE EXISTAIT DEJA — LE DEFAUT ETAIT AILLEURS, ET IL SE MESURE.
 *
 * La barre portait un `border` depuis le premier jour, et elle ne se voyait
 * pas. Le contraste dit pourquoi :
 *
 *     conteneur sur la page      #EDF2F8 / #F4F7FA   1,05:1
 *     lisere sur la page         #DBE5EF / #F4F7FA   1,19:1
 *     onglet ACTIF sur conteneur #FFFFFF / #EDF2F8   1,13:1
 *     texte inactif                                  5,75:1
 *
 * Le TEXTE se lit tres bien. C'est le BLOC qui est invisible : 1,05:1 entre le
 * conteneur et le fond de page, autant dire rien. Renforcer le trait aurait
 * rendu le contour visible autour d'un contenu toujours plat — soigner le
 * symptome.
 *
 * On creuse donc le conteneur d'un cran (`--surface-3`) et l'on assombrit son
 * trait (`--ligne` -> `--surface-3` compose avec l'ombre interne). L'onglet
 * actif, reste blanc : l'ecart actif/conteneur passe de 1,13 a 1,22, et la
 * barre entiere se detache enfin de la page.
 *
 * ⚠️ ON TOUCHE LA REGLE, JAMAIS LE JETON. Deplacer `--surface-2` aurait
 * deplace du meme coup les en-tetes de tableau et les champs de saisie qui
 * l'emploient : on aurait repare un ecran en en dereglant six.
 *
 * ⚠️ ET CETTE BARRE VIT SUR TREIZE ECRANS. Verifie en rendant trois d'entre eux
 * — clients, support, journal d'audit — avant et apres. Juger sur un seul aurait
 * ete juger sur le seul ou l'on regardait.
 */
.onglets {
  display: inline-flex; background: var(--surface-3); border: 1px solid var(--surface-3);
  border-radius: 9px; padding: 3px; gap: 2px; flex-wrap: wrap;
  box-shadow: inset 0 1px 2px rgba(21,40,58,.05);
}
.onglet {
  padding: 6px 12px; border-radius: 7px; font-size: 12.5px; font-weight: 550;
  text-decoration: none; color: var(--doux);
}
.onglet:hover { color: var(--encre); }
/* ⚠️ PREMIERE TENTATIVE INSUFFISANTE, ET LA MESURE L'A DIT.
 *
 * Creuser le conteneur portait l'ecart conteneur/page de 1,047 a 1,131 et
 * l'actif de 1,126 a 1,216 — huit pour cent, c'est-a-dire rien. Il aurait fallu
 * descendre le fond a #BFD2E4 pour atteindre 1,44:1, et l'interface entiere s'en
 * serait alourdie.
 *
 * DANS UNE PALETTE AUSSI CLAIRE, AUCUN REMPLISSAGE NE PORTE LA DIFFERENCE. Ce
 * qui se lit a faible contraste est un BORD, pas un fond : un trait est un
 * signal a haute frequence, l'oeil l'attrape la ou deux blancs voisins se
 * confondent.
 *
 * Et ce qu'on cherche des yeux n'est pas le conteneur : c'est L'ONGLET ACTIF.
 * Il prend donc l'accent — trait et texte — sur fond blanc. Le fond reste clair,
 * la couleur ne se repand pas, et la position courante se voit d'un coup d'oeil.
 *
 * L'ombre portee ne suffisait pas a le designer : elle disparait sur un ecran
 * mat et dans une capture d'ecran. Le trait, lui, tient partout.
 */
.onglet.actif {
  background: var(--surface); color: var(--accent-fort); font-weight: 650;
  border: 1px solid var(--accent); padding: 5px 11px;
  box-shadow: 0 1px 2px rgba(21,40,58,.10);
}
/* `flex-wrap` : la barre ne portait qu'un champ, elle en porte cinq sur
   « À traiter » — nature, recherche, nombre de passagers, bouton, effacer.
   Sans repli, les derniers sortent de la fenêtre sur un portable, et cela ne
   se voit dans aucun HTML : il faut rendre la page pour s'en apercevoir. */
.recherche { display: flex; gap: 6px; margin: 0; flex-wrap: wrap; align-items: center; }
.recherche input, .recherche select {
  padding: 8px 12px; border: 1px solid var(--ligne); border-radius: 9px;
  font: inherit; font-size: 13px; min-width: 210px;
  background: var(--surface-2); color: var(--encre);
}
/* `min-width` est repris, pas seulement `width` : sans cela le 210px ci-dessus
   l'emporte et le champ « pax ≥ » occupe la largeur d'une recherche. */
.recherche .ch-large  { min-width: 268px; flex: 1 1 268px; }
.recherche .ch-etroit { min-width: 92px; width: 92px; flex: 0 0 92px; }

/* ⚠️ CE N'EST PAS `.deux-colonnes`, ET C'EST DELIBERE.
   `.deux-colonnes` existe deja plus bas — `repeat(auto-fit, minmax(340px, 1fr))`,
   des colonnes EGALES — et sert neuf gabarits : fiche dossier, contrat, demande,
   facture, passagers, ticket… Reutiliser le nom pour une grille asymetrique
   aurait reecrit les neuf, et rien ne l'aurait dit : `php -l` ne lit pas la
   feuille de style, et les deux regles auraient coexiste sans erreur, la
   derniere gagnant en silence.

   Ici il faut du DESEQUILIBRE : a gauche ce qui TOMBE, a droite ce qu'on
   CHERCHE, dans une largeur fixe.

   `minmax(0, …)` sur la premiere : sans le zero, une cellule de tableau plus
   large que sa colonne repousse la grille et la seconde sort de l'ecran — la
   valeur implicite est `auto`, qui refuse de retrecir. */
.liste-et-recherche {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px;
  gap: 18px; align-items: start;
}
.liste-et-recherche > .colonne-large { min-width: 0; }
/* En dessous de 1040 px, on empile : a 320 px fixes, la gauche tomberait sous
   400 px et le tableau des natures deborderait. */
@media (max-width: 1040px) {
  .liste-et-recherche { grid-template-columns: 1fr; }
  .liste-et-recherche > .colonne-etroite { max-width: 420px; }
}
/* ============================================== blocs repliables
 * `<details>` NATIF, et pas une bascule en JavaScript.
 *
 * Un formulaire de saisie qui cohabite avec une liste occupe plus de place que
 * la donnee — sept champs pour ajouter un contact, au-dessus d'une liste qu'on
 * vient consulter neuf fois sur dix. Replier rend la donnee premiere.
 *
 * `<details>` fonctionne au clavier, s'annonce aux lecteurs d'ecran, survit a
 * une page rendue sans JavaScript, et son etat s'impose depuis le SERVEUR par
 * l'attribut `open` — c'est ce qui permet d'ouvrir le bloc quand la liste est
 * vide ou quand une saisie vient d'etre refusee.
 */
.repliable > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: 9px;
  border: 1px solid var(--ligne); background: var(--surface-2);
  font-size: 13px; font-weight: 600; color: var(--accent-fort);
}
.repliable > summary::-webkit-details-marker { display: none; }
/* Le chevron dit l'etat AVANT le clic. Sans lui, un bloc replie ressemble a un
   bouton, et on ne sait pas qu'il cache quelque chose. */
.repliable > summary::before {
  content: '▸'; font-size: 11px; line-height: 1; transition: transform .12s;
}
.repliable[open] > summary::before { transform: rotate(90deg); }
.repliable > summary:hover { border-color: var(--accent); }
.repliable > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.repliable[open] > summary { margin-bottom: 12px; }
/* En panneau, le bloc porte deja fond et bordure : le resume s'y fond. */
.repliable.panneau > summary { border: 0; background: none; padding: 0 0 0 2px; }

/* La ligne de tableau qui porte le bloc replie n'a ni bordure ni fond : elle
   ne doit pas se lire comme une seconde ligne de donnees. */
.ligne-repliable > td { border-top: 0; padding-top: 0; padding-bottom: 10px; }
.ligne-repliable .champ { margin-bottom: 8px; }

.titre-panneau {
  font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--doux); margin: 0 0 10px; font-weight: 650;
}
/* L'identite du CLIENT, dans l'en-tete du dossier — le titre, lui, porte le
   groupe qui voyage, et les deux ne se ressemblent presque jamais.
   Aucune couleur nouvelle : `--encre` sur `--fond` et l'accent des liens sont
   deja mesures par `controler-charte.php` dans les deux modes. Un nom mis en
   evidence par une teinte inedite serait un contraste non verifie. */
.identite-client { margin: 8px 0 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.identite-client .etiq {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--doux); font-weight: 650;
}
.identite-client .nom-client {
  font-size: 17px; font-weight: 650; color: var(--accent-fort);
  text-decoration: none; border-bottom: 2px solid var(--accent-pale);
}
.identite-client .nom-client:hover { border-bottom-color: var(--accent); }
.identite-client .sous { font-size: 12px; }

/* Un tableau large defile DANS SA BOITE, jamais en emportant la page.
   Sans cela, huit colonnes qui demandent 1 120 px font glisser lateralement
   les cartes, les onglets et la recherche — qui tiennent tous largement. Le
   defaut ne se voit pas sur un grand ecran, et c'est ce qui le rend durable. */
/* 900 px est la mesure de l'echeancier, pas une verite. Un tableau plus etroit
   declare la sienne (`style="--tab-min:640px"`) : lui imposer 900 l'etirerait
   et le ferait defiler sur des ecrans ou il tient largement.
   Le defaut est pose ICI, pas en repli de `var()` : un jeton qui n'existe que
   dans son propre repli est invisible a qui relit la charte — et
   `controler-charte.php` le refuse, a juste titre. */
.table-defilante { --tab-min: 900px; overflow-x: auto; max-width: 100%; }
.table-defilante > .tableau { min-width: var(--tab-min); }
/* La meme barre de recherche, empilee : en colonne etroite, cinq controles
   cote a cote se replieraient un par ligne de toute facon — autant l'assumer
   et rendre chaque champ pleinement cliquable. */
.recherche.empilee { flex-direction: column; align-items: stretch; gap: 8px; }
.recherche.empilee .ligne-champs { display: flex; gap: 6px; align-items: center; }
.recherche.empilee .ch-plein { min-width: 0; width: 100%; }
.recherche.empilee select { min-width: 0; flex: 1 1 auto; }
.recherche.empilee .sous { margin-top: 2px; }
/* `--accent` et non `--accent-pale` : mesure a 1,20:1, sous le seuil de 3:1 —
   voir la regle `:focus-visible` en tete de feuille. */
.recherche input:focus, .recherche select:focus {
  outline: 2px solid var(--accent); border-color: var(--accent);
}
.recherche .lg-reset { align-self: center; }

/* ============================================================ tableaux */
.tableau {
  width: 100%; border-collapse: collapse; background: var(--surface);
  border: 1px solid var(--ligne); border-radius: var(--rayon);
  overflow: hidden; font-size: 13px; box-shadow: var(--ombre);
}
.tableau th {
  background: var(--surface); color: var(--efface); text-align: left; padding: 11px 13px;
  font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  white-space: nowrap; font-weight: 650; border-bottom: 1px solid var(--ligne);
}
.tableau td { padding: 10px 13px; border-top: 1px solid var(--ligne-douce); vertical-align: middle; }
.tableau tbody tr:hover { background: var(--surface-2); }
.tableau .num { text-align: right; white-space: nowrap; }
.tableau .num.ok { color: var(--ok); font-weight: 650; }
.tableau.compact td, .tableau.compact th { padding: 7px 11px; }
.tableau tr.terne td { color: var(--efface); }
.tableau tfoot th {
  background: var(--surface-2); color: var(--encre); text-transform: none;
  font-size: 13px; letter-spacing: 0; border-top: 1px solid var(--ligne);
}
.tableau thead a.tri { color: inherit; text-decoration: none; white-space: nowrap; }
.tableau thead a.tri:hover { color: var(--accent); text-decoration: underline; }
a.ref { font-family: var(--mono); font-weight: 650; text-decoration: none; color: var(--accent); }
a.ref:hover { text-decoration: underline; }
tr.en-anomalie td { background: var(--crit-fond); }

/* ============================================================ pastilles et etats */
.mvt-type {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; text-transform: none;
  padding: 3px 9px; border-radius: 7px; white-space: nowrap;
  background: var(--surface-2); color: var(--doux); border: 1px solid var(--ligne);
}
.mvt-type.creation, .mvt-type.rapproche, .mvt-type.payee, .mvt-type.execute,
.mvt-type.resolue
  { background: var(--ok-fond);   color: var(--ok);      border-color: var(--ok-ligne); }
.mvt-type.disparition, .mvt-type.ecart, .mvt-type.rejete, .mvt-type.annulee,
.mvt-type.refuse
  { background: var(--crit-fond); color: var(--crit);    border-color: var(--crit-ligne); }
.mvt-type.resurrection, .mvt-type.brouillon, .mvt-type.a_rapprocher,
.mvt-type.a_traiter, .mvt-type.nouvelle
  { background: var(--avert-fond); color: var(--avert);  border-color: var(--avert-ligne); }
.mvt-type.emise, .mvt-type.envoyee, .mvt-type.recu, .mvt-type.traite,
.mvt-type.en_cours, .mvt-type.demande, .mvt-type.prise_en_compte
  { background: var(--nonemet-fond); color: var(--nonemet); border-color: var(--nonemet-ligne); }
.mvt-type.rejetee, .mvt-type.reportee
  { background: var(--surface-2); color: var(--efface); border-color: var(--ligne); }

.pastille-alerte {
  background: var(--avert-fond); color: var(--avert); border: 1px solid var(--avert-ligne);
  border-radius: 999px; padding: 2px 9px; font-size: 11.5px; font-weight: 650;
  /* Sans cela « +52 j » se coupe entre le nombre et l'unite, et le fond arrondi
     se dessine deux fois : une pastille, puis un « j » seul en dessous. */
  display: inline-block; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.badge-chg {
  background: var(--accent); color: var(--sur-accent); border-radius: 999px;
  padding: 2px 8px; font-size: 11px; font-weight: 700;
}

/* ── BLOCS REPLIABLES — `<details>`, du HTML pur, sans JavaScript.
   Ils portent les ACTIONS d'un ecran dont la liste est l'essentiel : on vient
   regarder, on agit parfois. Repliees, elles ne poussent plus ce qu'on vient
   voir quatre ecrans plus bas.
   Aucune paire de couleurs nouvelle : meme fond et meme encre qu'un `.panneau`,
   deja mesures par controler-charte dans les deux modes. */
.repli {
  background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon); box-shadow: var(--ombre); margin-top: 12px;
}
.repli > summary {
  cursor: pointer; padding: 14px 18px; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--doux);
  list-style: none;
}
.repli > summary::-webkit-details-marker { display: none; }
/* Le chevron dit l'etat sans dependre d'une image : replie il pointe a droite,
   deplie vers le bas. */
.repli > summary::before {
  content: "▸"; display: inline-block; width: 14px; color: var(--efface);
}
.repli[open] > summary::before { content: "▾"; }
.repli > summary:hover { color: var(--encre); }
.repli > *:not(summary) { padding: 0 18px; }
.repli > *:last-child { padding-bottom: 18px; }

/* ── AIDE REPLIABLE — la meme mecanique, en LEGER.
 *
 * `.repli` est une carte : bordure, ombre, coins. Sous un champ de formulaire
 * elle pese plus que le texte qu'elle cache. Ici rien qu'un lien.
 *
 * ⚠️ CE QUI SE REPLIE ET CE QUI RESTE N'EST PAS UN CHOIX DE PLACE.
 * Reste dehors la phrase qui CHANGE UN GESTE — « cocher videra le SIREN »,
 * une consequence destructrice qu'on doit lire avant de cliquer. Se replie ce
 * qui EXPLIQUE — a quoi sert la case, d'ou viennent les donnees. Replier un
 * avertissement le supprime : personne n'ouvre un depliant pour apprendre
 * qu'il va perdre une valeur.
 *
 * Aucun JavaScript : `<details>` est natif, et fonctionne meme si la feuille
 * ne charge pas — le triangle par defaut reapparait, le texte reste atteignable.
 */
.aide-repli { margin: 5px 0 0; }
.aide-repli > summary {
  cursor: pointer; font-size: 12.5px; color: var(--accent);
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
  width: fit-content;
}
.aide-repli > summary::-webkit-details-marker { display: none; }
.aide-repli > summary::before {
  content: "▸"; font-size: 10px; color: var(--efface); line-height: 1;
}
.aide-repli[open] > summary::before { content: "▾"; }
.aide-repli > summary:hover { text-decoration: underline; }
.aide-repli > .aide:first-of-type { margin-top: 6px; }

/* ── ALLER SIMPLE : le bloc retour se masque en CSS PUR, sans JavaScript.
   La case vit dans un <label>, donc dans un frere du bloc — d'ou `:has()`
   plutot qu'un simple `~`. Si le selecteur n'est pas applique, le bloc reste
   visible et le SERVEUR ignore le retour de toute facon : la saisie reste
   juste, seulement moins jolie. Rien ne depend du navigateur. */
.champ:has(#aller_simple:checked) ~ .bloc-retour { display: none; }

/* ── BILLETS ÉMIS : la question ne se pose QU'AVEC la pénalité, seul cas où la
   réponse change quelque chose. Même mécanique que ci-dessus, dans l'autre
   sens — et le sens compte : le bloc est masqué PAR DÉFAUT et révélé par la
   règle. Si la feuille ne charge pas, aucune des deux ne s'applique et la
   question reste VISIBLE. Une question de trop vaut mieux qu'une question
   invisible qui bloque l'enregistrement sans se montrer. */
/* ── HISTOGRAMME SANS BIBLIOTHEQUE ET SANS IMAGE.
   Une largeur en pourcentage sur un fond : c'est tout ce qu'une barre demande.
   Le projet n'a AUCUNE dependance front, et une dependance se justifie une par
   une — pour dessiner un rectangle, elle ne se justifie pas.
   `min-width` pour qu'une valeur minuscule reste visible : une barre invisible
   se lit comme une valeur nulle, et ce n'est pas la meme chose. */
.barre {
  display: block; height: 9px; border-radius: 4px;
  background: var(--accent); min-width: 2px; opacity: .75;
}

.bloc-billets { display: none; }
.champ:has(input[name="penalite"]:checked) ~ .bloc-billets { display: block; }

/* ============================================================ fil de suivi
   ⚠️ AUCUNE PAIRE DE COULEURS NOUVELLE, ET C'EST DELIBERE.

   Le texte de tous les messages reste `--encre` sur `--surface-2` — la seule
   paire deja mesuree par controler-charte pour du corps de texte sur ce fond.
   Ce qui distingue un message d'un autre est le LISERE, qui ne porte aucun
   texte : il n'a donc pas de contraste a tenir, et rien ne peut passer sous le
   seuil AA sans qu'on le sache.

   ⚠️ ET LA COULEUR NE PORTE JAMAIS SEULE LE SENS. « Note interne » s'ecrit en
   toutes lettres dans la pastille : un liseré orange que personne ne distingue
   ne doit pas etre la seule chose qui separe un mot destine au client d'un mot
   qui ne l'est pas. */
.fil-suivi { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.msg {
  background: var(--surface-2); color: var(--encre);
  border: 1px solid var(--ligne); border-left: 3px solid var(--ligne);
  border-radius: var(--rayon); padding: 10px 14px;
}
.msg > header {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 6px; font-size: 12.5px;
}
.msg > header time { color: var(--efface); font-size: 12px; margin-left: auto; }
.msg > p { margin: 0; font-size: 13.5px; line-height: 1.55; }
.msg-client  { border-left-color: var(--nonemet); }
.msg-interne { border-left-color: var(--avert); }

/* CATEGORIE D'AGENCE — trois couleurs, parce que c'est de l'argent.
   Emettrice : XK ne facture pas. Non emettrice : XK facture 8 EUR par passager,
   3 EUR en tarif resident. En compte : accord particulier. Inconnu : on ne
   devine pas, on ne facture rien, et on le signale. */
.categorie {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px; font-size: 11.5px;
  font-weight: 650; border: 1px solid; white-space: nowrap;
}
.categorie::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.categorie.emettrice     { background: var(--emet-fond);    color: var(--emet);    border-color: var(--emet-ligne); }
.categorie.non_emettrice { background: var(--nonemet-fond); color: var(--nonemet); border-color: var(--nonemet-ligne); }
.categorie.en_compte     { background: var(--compte-fond);  color: var(--compte);  border-color: var(--compte-ligne); }
.categorie.inconnu       { background: var(--avert-fond);   color: var(--avert);   border-color: var(--avert-ligne); }

/* Natures d'echeance : trois familles, trois teintes.
   L'orange et le rouge disent un ETAT — en retard, anomalie. Les employer aussi
   pour une nature ferait porter deux sens a la meme couleur. Les natures
   prennent donc des teintes qu'aucun etat n'utilise. */
.nature {
  display: inline-block; white-space: nowrap; border-radius: 7px;
  padding: 3px 9px; font-size: 11.5px; font-weight: 650; border: 1px solid transparent;
}
.nature.argent        { background: var(--nonemet-fond); color: var(--nonemet); border-color: var(--nonemet-ligne); }
.nature.exploitation  { background: #F1ECF8; color: #5B3E8C; border-color: #DCD0EE; }
.nature.administratif { background: var(--surface-2); color: var(--doux); border-color: var(--ligne); }

.legende-natures {
  display: flex; flex-wrap: wrap; gap: 8px; font-size: 12.5px;
  color: var(--doux); margin: 12px 0 0; align-items: center;
}
.legende-natures .lg-titre { font-weight: 650; color: var(--encre); margin-right: 6px; }
.legende-natures a.lg, .legende-natures .lg {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px; border-radius: 8px; text-decoration: none; color: var(--doux);
  border: 1px solid transparent;
}
.legende-natures a.lg:hover { background: var(--surface-2); border-color: var(--ligne); }
.legende-natures a.lg.actif { background: var(--surface-2); border-color: var(--accent);
                              color: var(--encre); font-weight: 600; }
.legende-natures .lg-reset { font-size: 12.5px; color: var(--accent); }

/* ============================================================ panneaux et fiches */
/* ⚠️ `min(340px, 100%)` ET PAS `340px`.
   `minmax(340px, 1fr)` impose un plancher ABSOLU : sous 340 px de large, la
   colonne reste a 340 et la page glisse lateralement — 35 px de trop sur un
   telephone de 320 px, sur les neuf gabarits qui emploient cette grille. Avec
   `min()`, le plancher devient la largeur disponible des qu'elle est moindre,
   et `auto-fit` continue de faire deux colonnes des qu'il y a la place. */
.deux-colonnes {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
}
.panneau {
  background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon); padding: 17px 18px; box-shadow: var(--ombre);
}
.panneau h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
              color: var(--efface); font-weight: 700; margin-bottom: 13px; }
/* ⚠️ `minmax(0, 1fr)` ET PAS `1fr`.
   `1fr` vaut `minmax(auto, 1fr)` : son plancher est la largeur MINIMALE DE
   CONTENU de la cellule, et une piste ne descend jamais en dessous. Une valeur
   sans espace — une adresse, un identifiant technique — faisait donc deborder
   la grille, qui emportait la PAGE entiere en glissant lateralement. Mesure :
   783 px de contenu dans une fenetre de 375 px, sur l'ecran d'un ticket. */
.paires {
  display: grid; grid-template-columns: minmax(140px, auto) minmax(0, 1fr);
  gap: 8px 13px; margin: 0; font-size: 13px;
}
.paires dt { color: var(--doux); }
/* Et la valeur se coupe au besoin : `anywhere` plutot que `break-word`, qui ne
   coupe un mot qu'en dernier recours et laisse deborder les grilles. */
.paires dd { margin: 0; font-weight: 550; overflow-wrap: anywhere; }
.paires dd.ok { color: var(--ok); font-weight: 650; }

/* ============================================================ boutons */
/* Le corps d'un courriel, tel qu'il partira : chasse fixe, sauts de ligne
   conserves, et il DEFILE plutot que de pousser la page en largeur. */
.apercu-courriel {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
  background: var(--surface-2); border: 1px solid var(--ligne);
  border-radius: var(--rayon-s); padding: 14px 16px; margin: 0;
  color: var(--encre); overflow-x: auto;
}
/* Une grille de champs qui RETOMBE en colonne : le debordement d'un flex sans
   retour ne se voit dans aucun HTML — la lecon est ecrite. */
.grille-champs {
  display: flex; flex-wrap: wrap; gap: 14px 20px; align-items: flex-start;
}
.grille-champs > .champ { flex: 1 1 260px; min-width: 0; }

.bouton {
  cursor: pointer; padding: 9px 15px; border: 0; border-radius: 9px;
  font: inherit; font-size: 13px; font-weight: 600;
  background: var(--accent); color: var(--sur-accent);
  display: inline-flex; align-items: center; gap: 8px; justify-content: center;
}
.bouton:hover { background: var(--accent-fort); }
.bouton.discret {
  background: var(--surface-2); color: var(--encre); border: 1px solid var(--ligne);
  padding: 7px 13px; font-size: 12.5px;
}
.bouton.discret:hover { border-color: var(--accent); color: var(--accent); background: var(--surface-2); }
/* Meme bascule : en sombre `--crit` s'eclaircit en #E8776B, ou le blanc
   tomberait plus bas encore que sur l'accent. */
.bouton.danger { background: var(--crit); color: var(--sur-accent); border-color: transparent; }
.bouton.danger:hover { background: var(--crit); filter: brightness(.88);
                       color: var(--sur-accent); }
.bouton.mini { padding: 5px 10px; font-size: 12px; }
a.bouton, a.bouton.discret, a.lien-bouton { display: inline-flex; text-decoration: none; }
.actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.enligne { display: inline; margin: 0; }
.lien {
  background: none; border: 0; color: inherit; cursor: pointer;
  font: inherit; text-decoration: underline; padding: 0; opacity: .85;
}
.lien:hover { opacity: 1; }

/* ============================================================ formulaires */
.champ { padding: 11px 0; border-bottom: 1px solid var(--ligne-douce); }
.champ:last-child { border-bottom: 0; }
.champ.en-erreur { background: var(--crit-fond); margin: 0 -18px; padding: 11px 18px;
                   border-radius: var(--rayon-s); }
.champ label { display: block; font-weight: 600; font-size: 12px; color: var(--doux);
               margin-bottom: 5px; }
.champ input[type=text], .champ input[type=email], .champ input[type=date],
.champ input[type=number], .champ input[type=password], .champ input[type=search],
.champ select, .champ textarea {
  width: 100%; max-width: 460px; padding: 9px 11px; font: inherit; font-size: 13px;
  border: 1px solid var(--ligne); border-radius: var(--rayon-s);
  background: var(--surface-2); color: var(--encre);
}
/* Idem : l'anneau des champs etait a 1,20:1. */
.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline: 2px solid var(--accent); border-color: var(--accent);
}
.champ.en-erreur input, .champ.en-erreur select { border-color: var(--crit); background: var(--surface); }
.champ input[readonly] { background: var(--surface-3); color: var(--doux); }
.champ input[type=checkbox], .champ input[type=radio] { width: auto; margin-right: 6px; }
.champ label.radio { display: block; font-weight: 400; margin: 4px 0; font-size: 13px; color: var(--encre); }
.champ .aide { color: var(--efface); font-size: 11.5px; margin: 5px 0 0; max-width: 620px; }
.champ .aide.erreur, .aide.erreur { color: var(--crit); font-weight: 600; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px; }
.form-grid .full, .field.full { grid-column: 1 / -1; }
.form-sect {
  font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--accent-fort); font-weight: 700; margin: 20px 0 12px;
  padding-bottom: 6px; border-bottom: 1px solid var(--ligne);
}
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 12px; font-weight: 600; color: var(--doux); }
.field input, .field select, .field textarea {
  background: var(--surface-2); border: 1px solid var(--ligne); border-radius: var(--rayon-s);
  padding: 9px 11px; color: var(--encre); font-size: 13px; font-family: inherit; width: 100%;
}
@media (max-width: 700px) { .form-grid { grid-template-columns: 1fr; } }
/* ⚠️ EN COLONNE ETROITE, `.paires` PASSE A UNE SEULE COLONNE.
   Le libelle reserve 140 px et l'espacement 13 : sur un telephone de 375 px il
   ne restait que 192 px a la valeur — trop peu pour un champ de saisie, deux
   boutons ou une phrase. Le contenu ne se repliait pas, la grille debordait, et
   la page glissait avec elle. Mesure sur la fiche d'un dossier sans client :
   599 px de contenu pour 345 px disponibles. */
@media (max-width: 620px) {
  /* ⚠️ `minmax(0, 1fr)` ICI AUSSI, et pas `1fr`.
     Passer a une colonne ne suffit pas : `1fr` garde pour plancher la largeur
     minimale de contenu, et un champ de saisie en a une que le repli du texte
     ne reduit pas. Mesure : une piste de 400 px dans un conteneur de 302. */
  .paires { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .paires dt { margin-top: 9px; }
  .paires dt:first-child { margin-top: 0; }
}

select.mini, input.mini {
  font: inherit; font-size: 12.5px; padding: 5px 9px; border: 1px solid var(--ligne);
  border-radius: var(--rayon-s); background: var(--surface-2); color: var(--encre);
  max-width: 300px;
}
input.mini { max-width: 200px; }
textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--ligne); border-radius: var(--rayon-s);
  font-family: var(--mono); font-size: 12.5px; background: var(--surface-2);
  color: var(--encre); resize: vertical;
}
textarea[readonly] { background: var(--surface-3); }
.requis {
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
  color: var(--crit); background: transparent; padding: 0; margin-left: 4px;
}
.cle-technique {
  font-family: var(--mono); font-size: 11px; color: var(--efface); margin: 3px 0 0;
}
.libelle { display: block; font-size: 12.5px; }
code {
  font-family: var(--mono); font-size: 12px; background: var(--surface-2);
  padding: 1px 5px; border-radius: 4px; border: 1px solid var(--ligne-douce);
}
code.secret {
  font-size: 15px; font-weight: 700; letter-spacing: .04em;
  background: var(--surface); border: 1px solid var(--ligne); padding: 4px 10px;
}
ul.obstacles { margin: -6px 0 16px; padding-left: 22px; font-size: 13px; color: var(--crit); }
ul.obstacles li { margin-bottom: 3px; }

/* ============================================================ connexion */
.cadre-connexion {
  background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon); padding: 26px; box-shadow: var(--ombre);
}
.cadre-connexion label { display: block; font-size: 12px; font-weight: 600;
                         color: var(--doux); margin: 14px 0 5px; }
.cadre-connexion input {
  width: 100%; padding: 9px 11px; border: 1px solid var(--ligne);
  border-radius: var(--rayon-s); font: inherit; background: var(--surface-2); color: var(--encre);
}
.cadre-connexion .bouton { margin-top: 18px; width: 100%; }

/* ============================================================ mouvements */
.mouvements { list-style: none; padding: 0; margin: 0; }
.mvt {
  background: var(--surface); border: 1px solid var(--ligne); border-radius: var(--rayon-s);
  padding: 9px 13px; margin-bottom: 6px; font-size: 13px;
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
}
.mvt .type {
  font-size: 11px; font-weight: 650; letter-spacing: .03em;
  padding: 2px 8px; border-radius: 7px;
  background: var(--nonemet-fond); color: var(--nonemet);
}
.mvt.disparition .type  { background: var(--crit-fond);  color: var(--crit); }
.mvt.resurrection .type { background: var(--avert-fond); color: var(--avert); }
.mvt .nom { color: var(--doux); }
.mvt .detail { margin-left: auto; font-size: 12.5px; color: var(--efface); }

/* ============================================================ support */
.fil-messages { list-style: none; padding: 0; margin: 0; }
.message {
  background: var(--surface-2); border: 1px solid var(--ligne);
  border-radius: 10px; padding: 10px 13px; margin-bottom: 8px;
}
.message.interne { background: var(--avert-fond); border-color: var(--avert-ligne); }
.message-tete {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  font-size: 11px; color: var(--efface); margin-bottom: 4px;
}
.message-tete b { color: var(--doux); }
.message-corps { font-size: 13px; line-height: 1.55; margin: 0; }

/* ============================================================ depot de fichier */
.zone-depot {
  border: 2px dashed var(--ligne); border-radius: var(--rayon); padding: 24px 18px;
  text-align: center; background: var(--surface-2); color: var(--doux); font-size: 13px;
  transition: background .12s, border-color .12s;
}
.zone-depot.survol { border-color: var(--accent); background: var(--accent-pale); color: var(--accent); }
.zone-depot input[type="file"] { max-width: 100%; }

/* ============================================================ tunnel du dossier
 * Une file d'etapes verticale : ce qui est fait, ce qui se joue maintenant, ce
 * qui reste. C'est la representation du parcours demande -> facture. */
.tunnel { margin-top: 8px; }
.etape { display: flex; gap: 13px; position: relative; padding-bottom: 15px; }
.etape:not(:last-child)::before {
  content: ""; position: absolute; left: 11px; top: 24px; bottom: -2px;
  width: 2px; background: var(--ligne);
}
.etape.faite:not(:last-child)::before { background: var(--ok); }
.etape .puce {
  width: 24px; height: 24px; border-radius: 50%; flex: none; display: grid;
  place-items: center; font-size: 12px; font-weight: 700;
  border: 2px solid var(--ligne); background: var(--surface); color: var(--efface); z-index: 1;
}
.etape.faite .puce { background: var(--ok); border-color: var(--ok);
                     color: var(--sur-accent); }
.etape.encours .puce {
  background: var(--accent); border-color: var(--accent); color: var(--sur-accent);
  box-shadow: 0 0 0 4px var(--accent-pale);
}
.etape .t { font-weight: 600; font-size: 13.5px; }
.etape .d { font-size: 12.5px; color: var(--doux); margin-top: 1px; }
.etape.encours .t { color: var(--accent-fort); }

/* ============================================================ parametrage */
.parametres-nav {
  display: flex; flex-wrap: wrap; gap: 20px; margin: 0 0 18px;
  padding: 13px 15px; background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon); box-shadow: var(--ombre);
}
.parametres-nav .famille { display: flex; flex-direction: column; gap: 7px; }
.parametres-nav .famille-titre {
  font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  font-weight: 800; color: var(--efface); display: flex; align-items: center; gap: 7px;
}
.parametres-nav .onglets { background: none; border: 0; padding: 0; }
.parametres-nav .onglet { padding: 5px 11px; font-size: 12.5px; }
.sommaire {
  display: grid; gap: 12px; margin: 14px 0 24px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.sommaire a {
  display: block; padding: 14px 16px; background: var(--surface);
  border: 1px solid var(--ligne); border-left: 3px solid var(--accent);
  border-radius: var(--rayon); text-decoration: none; color: var(--encre);
  box-shadow: var(--ombre);
}
.sommaire a:hover { border-color: var(--accent); }
.sommaire a.technique { border-left-color: var(--compte); }
.sommaire .t { font-weight: 650; display: block; margin-bottom: 3px; }
.sommaire .a { font-size: 12.5px; color: var(--doux); }

/* ============================================================ pied de liste */
.pagination {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap; margin-top: 12px; padding: 10px 14px; font-size: 12.5px;
  color: var(--doux); background: var(--surface); border: 1px solid var(--ligne);
  border-radius: var(--rayon);
}
.pagination .compte strong { color: var(--encre); }
.pagination .pages { display: inline-flex; gap: 4px; }
.pagination .pages a {
  padding: 5px 11px; border: 1px solid var(--ligne); border-radius: var(--rayon-s);
  background: var(--surface-2); text-decoration: none; color: var(--accent); font-weight: 600;
}
.pagination .pages a:hover { border-color: var(--accent); }

/* ============================================================ pages publiques
 * Le client et le visiteur n'ont pas de menu lateral : leur en-tete est une
 * simple banniere de marque. `.bandeau` et `.marque` servent aux deux contextes,
 * mais leur habillage differe — ici marine sur toute la largeur, la-bas une
 * barre claire au-dessus du contenu. */
body.public { display: flex; flex-direction: column; min-height: 100vh; }
body.public .bandeau {
  background: var(--marine); color: var(--marine-pale); border-bottom: 0;
  padding: 15px 26px; position: static;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
body.public .marque { padding: 0; border: 0; }
body.public .marque a, body.public .marque > span {
  color: inherit; text-decoration: none; font-weight: 800; font-size: 15px; display: block;
}
/* ⚠️ `a span` AUTANT QUE `span span`. L'en-tete de l'espace porte desormais un
   LIEN vers l'accueil — c'est sa seule navigation — et le sous-titre y est donc
   `a > span`, pas `span > span`. Sans cette premiere alternative, « SERVICE
   GROUPES » perdrait sa petite capitale sans que le HTML change d'un caractere :
   une page se verifie en la RENDANT. `gabarit-public`, lui, garde la forme sans
   lien — il n'y a nulle part ou revenir avant d'etre connecte. */
body.public .marque a span, body.public .marque span span {
  display: block; font-size: 10px; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; opacity: .6; margin-top: 5px;
}
body.public .qui { color: rgba(255,255,255,.85); text-align: right; }
body.public .qui .sous { color: rgba(255,255,255,.6); display: block; }
body.public .qui .lien { color: rgba(255,255,255,.85); }
body.public .pied { background: var(--surface); }
body.public .panneau { padding: 22px; }
body.public h2 { margin-top: 22px; padding-bottom: 5px; border-bottom: 1px solid var(--ligne);
                 text-transform: none; letter-spacing: -.01em; color: var(--encre);
                 font-size: 16px; }
body.public h2:first-of-type { margin-top: 0; }

/* ============================================================ aide
 *
 * L'aide a la decouverte : deux schemas et une fiche par entree de menu.
 *
 * ⚠️ `minmax(0, 1fr)` et NON `1fr` : une piste de grille ne descend pas sous la
 * largeur minimale de contenu de sa cellule, et un mot long dans une fiche
 * ferait deborder la PAGE ENTIERE, pas seulement la fiche. Trois debordements
 * horizontaux du projet venaient exactement de la.
 */
.chapeau { color: var(--doux); margin: 0 0 20px; max-width: 62ch; }

/* Le SVG defile DANS sa boite plutot que d'elargir la page — meme raison que
   `.table-defilante` pour les tableaux larges. */
.schema { margin: 0 0 10px; overflow-x: auto; }
.schema svg { display: block; min-width: 640px; max-width: 100%; height: auto; }

.fiche { display: grid; grid-template-columns: minmax(0, 1fr); gap: 9px; margin: 0; }
@media (min-width: 720px) {
  .fiche { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.fiche > div {
  background: var(--surface-2); border-radius: 9px; padding: 11px 14px;
  border-left: 3px solid var(--accent);
}
.fiche dt {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--efface); margin: 0 0 3px; font-weight: 600;
}
.fiche dd { margin: 0; }

/* La regle metier que l'ecran applique — c'est ce qu'un agent de premier mois
   ne peut PAS deviner, donc ce qui justifie l'aide. Elle occupe la largeur
   entiere sous les quatre cases. */
.fiche > div.regle {
  grid-column: 1 / -1; background: var(--accent-pale);
  border-left-color: var(--marine);
}

/* ============================================================ etroit */
@media (max-width: 960px) {
  .appli, .appli.replie { grid-template-columns: 1fr; }
  .lateral { position: static; height: auto; flex-direction: row; align-items: center;
             flex-wrap: wrap; }
  .marque { border: none; padding: 11px 15px; }
  .marque span, .pied-lateral, .groupe-menu { display: none; }
  .menu { flex-direction: row; flex-wrap: wrap; flex: 1; }
  .page { padding: 16px 15px 40px; }
  .bandeau { padding: 11px 15px; }
}

/* ── Le tableau par ETATS ─────────────────────────────────────────────────
   Des colonnes cote a cote, chacune un statut Amadeus. La largeur minimale
   d'une colonne est ce qui rend le tableau lisible : plus etroite, le numero
   de dossier passe a la ligne ; plus large, on ne voit plus que trois
   colonnes sur neuf.

   AUCUNE couleur en dur : tout vient des jetons, sans quoi le mode sombre
   rendrait des cartes blanches et `controler-charte` le dirait. */
.kanban { display: flex; gap: 10px; align-items: flex-start; }
.kanban-col {
  flex: 1 0 190px; background: var(--surface-2);
  border: 1px solid var(--ligne); border-radius: 8px; padding: 8px;
}
/* Une SORTIE — rejete, annule — ne demande plus rien. Elle reste lisible,
   mais cesse d'attirer l'oeil : la melanger aux vivants ferait chercher du
   travail la ou il n'y en a plus. */
.kanban-col.terne { opacity: .62; }
/* Un statut qu'Amadeus a envoye sans qu'il figure au tableau de
   correspondance. Il se voit, il ne se fond pas. */
.kanban-col.a-qualifier { border-color: var(--accent); border-style: dashed; }
.kanban-tete {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px solid var(--ligne);
}
.kanban-tete .etiq { flex: 1 1 auto; }
.carte-dossier {
  background: var(--surface); border: 1px solid var(--ligne-douce);
  border-radius: 6px; padding: 6px 8px; margin-bottom: 6px;
}
.carte-dossier .sous { display: block; }
/* Une seule colonne a l'ecran : les cartes s'etalent au lieu de s'empiler
   sur 190 px, sinon ouvrir « Confirmé » donnerait trois cents cartes en
   colonne unique. */
.kanban-colonne-seule {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

/* ── L'AGV EN COULEUR STRUCTURANTE ────────────────────────────────────────
   C'est ce champ qui decide si Air Corsica facture, et a quel tarif. L'audit
   en fait la couleur de premier plan : elle doit se lire EN BALAYANT une
   liste, sans ouvrir les fiches.

   ⚠️ UN LISERE, PAS UN FOND. Mesure du 01/08 : 431 dossiers sur 433 sont
   « inconnu ». Un fond teinte ferait un mur d'une seule couleur, que l'oeil
   apprend a ignorer en trois jours — et il ajouterait des paires texte/fond
   qu'il faudrait mesurer. Le bord distingue sans noyer.

   Les teintes sont celles de la charte, deja mesurees pour la pastille. */
.agv-emettrice     { border-left: 3px solid var(--emet); }
.agv-non_emettrice { border-left: 3px solid var(--nonemet); }
.agv-en_compte     { border-left: 3px solid var(--compte); }
/* « Inconnu » n'est PAS une categorie decidee : c'est l'etat ou l'on ignore
   si XK facture. Le trait discontinu le dit sans crier — la pastille, elle,
   porte deja la couleur d'alerte. */
.agv-inconnu       { border-left: 3px dashed var(--avert); }

/* Sur une LIGNE de tableau, le bord se pose sur la premiere cellule : un
   `<tr>` ne prend pas de bordure de facon fiable selon `border-collapse`. */
.tableau tr > td.agv-emettrice,
.tableau tr > td.agv-non_emettrice,
.tableau tr > td.agv-en_compte,
.tableau tr > td.agv-inconnu { border-left-width: 3px; }
