/* =====================================================================
   ALICEA × Espaces Atypiques — coquille applicative
   Jetons et composants du shell, extraits des maquettes validées (SPEC §8).
   Aucun composant de tableau de bord ici : c'est l'étape 3.
   ===================================================================== */

/* ---------- Polices (SPEC §8.2 : fichiers .woff2, font-display:swap) ---------- */
/* §23 — DM Sans, la famille du portail, CONSERVÉE : c'est la graisse qui change (300 à 600).
   La 300 et DM Mono 400 (identifiants) déposées en WOFF2 latin (OFL) ; la 700 est partie avec
   les titres épais. Graisses en clair : un descripteur @font-face n'accepte pas var(). */
@font-face{font-family:'DM Sans';font-weight:300;font-style:normal;font-display:swap;
  src:url(../fonts/dmsans-300.woff2) format('woff2');}
@font-face{font-family:'DM Sans';font-weight:400;font-style:normal;font-display:swap;
  src:url(../fonts/dmsans-400.woff2) format('woff2');}
@font-face{font-family:'DM Sans';font-weight:500;font-style:normal;font-display:swap;
  src:url(../fonts/dmsans-500.woff2) format('woff2');}
@font-face{font-family:'DM Sans';font-weight:600;font-style:normal;font-display:swap;
  src:url(../fonts/dmsans-600.woff2) format('woff2');}
@font-face{font-family:'DM Mono';font-weight:400;font-style:normal;font-display:swap;
  src:url(../fonts/dmmono-400.woff2) format('woff2');}

/* Les jetons (couleurs, tailles, graisses, formes) : assets/css/tokens.css, §23. */

*{margin:0;padding:0;box-sizing:border-box;}
html,body{height:100%;}
body{background:var(--bg);color:var(--ink);font-family:var(--font);font-size:var(--fs-13);
  line-height:var(--lh);-webkit-font-smoothing:antialiased;}
/* Pas de chiffres tabulaires : DM Sans n'a pas de `tnum` (décision du 18/09, colonnes de
   chiffres alignées à droite). Le gras, 600 : jamais de 700 (§1). */
b,strong{font-weight:var(--w6);}
/* Un contrôle ne tient pas sa police du corps (le navigateur lui remet la sienne) : il l'hérite. */
button,input,select,textarea{font-family:inherit;color:inherit;accent-color:var(--corail);}
/* Champs (§2) : 30 px, filet --line, rayon 6 ; focus en fin de feuille. */
.coef-champ input,.msg-recherche,.msg-texte,.qs-form input,.qs-form select,.qs-form textarea,.devlog input{height:30px;padding:0 10px;font:inherit;font-size:var(--fs-13);font-weight:var(--w4);color:var(--ink);border:1px solid var(--line);border-radius:6px;background:var(--surface);}
.msg-texte,.qs-form textarea{height:auto;padding:8px 10px;}
[hidden]{display:none !important;}

/* Étape 9.C — plein écran : plus de carte centrée (ni marge, ni ombre, ni coin
   arrondi) — le shell colle aux bords du viewport. --sb-w pilote la largeur de la
   colonne sidebar, basculée en JS entre 236px et 64px (cf. shell.js, réduction). */
.app{background:var(--bg);display:grid;grid-template-columns:var(--sb-w) 1fr;min-height:100vh;}

/* ---------- SIDEBAR ---------- */
/* `sticky` (pas `fixed`) : reste dans le flux de la grille de .app — pas de calcul de
   marge de compensation sur .main — mais se fige au défilement grâce à top:0 et à sa
   propre hauteur de 100vh ; overflow-y défile son contenu seul si la nav déborde. */
.sidebar{background:var(--rail);color:var(--sur-marine-2);display:flex;flex-direction:column;padding:20px 0;
  position:sticky;top:0;align-self:start;height:100vh;overflow-y:auto;transition:width .15s;}
.sb-brand{display:flex;align-items:center;gap:10px;padding:2px 20px 22px;}
.sb-brand .box{width:22px;height:22px;border-radius:4px;background:var(--corail);
  display:flex;align-items:center;justify-content:center;}
.sb-brand .box svg{width:62%;height:62%;}
.sb-brand .wm{font-weight:var(--w6);font-size:var(--fs-12);letter-spacing:.12em;}
.sb-brand .wm .lite{color:var(--sur-marine);}.sb-brand .wm .cor{color:var(--corail);}
.sb-sec{font-size:var(--fs-10);letter-spacing:1.5px;text-transform:uppercase;font-weight:var(--w6);
  color:var(--sur-marine-55);padding:14px 22px 6px;}
.nav{display:flex;flex-direction:column;gap:2px;padding:0 10px;}
.nav a{display:flex;align-items:center;gap:9px;padding:8px;border-radius:6px;color:var(--sur-marine-2);
  text-decoration:none;white-space:nowrap;font-weight:var(--w4);transition:.15s;}
.nav a svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.9;flex:0 0 auto;}
.nav a:hover{background:var(--sur-marine-12);color:var(--sur-marine-90);}
.nav a.active{background:var(--corail-12);color:var(--sur-marine);font-weight:var(--w5);}
.nav a.active svg{stroke:var(--corail);}
.nav .badge{margin-left:auto;font-family:var(--mono);color:var(--sur-marine-55);font-size:var(--fs-11);
  padding:1px 0;}
.nav a.active .badge{color:var(--sur-marine-2);}
/* 23/09 — sous-menu d'une BU (Siège, shell.js `sousMenuBu`) */
.nav a.ouverte{color:var(--sur-marine);}
.nav-sous{display:flex;flex-direction:column;gap:2px;margin:0 0 4px 16px;padding-left:6px;border-left:1px solid var(--sur-marine-12);}
.nav-sous-titre{font-size:var(--fs-10);letter-spacing:.08em;text-transform:uppercase;padding:4px 8px 2px;overflow:hidden;text-overflow:ellipsis;}
.nav-sous a{padding:6px 8px;white-space:normal;}
.sb-user{margin-top:auto;display:flex;align-items:center;gap:11px;padding:16px 20px 4px;
  border-top:1px solid var(--sur-marine-12);margin:16px 12px 0;}
.sb-user .av{width:38px;height:38px;border-radius:50%;background:var(--corail);
  display:flex;align-items:center;justify-content:center;font-weight:var(--w5);
  color:var(--sur-marine);border:2px solid var(--corail-soft);flex:0 0 auto;}
.sb-user .who{line-height:1.25;display:flex;flex-direction:column;min-width:0;}
.sb-user .who .n{font-weight:var(--w5);color:var(--sur-marine);display:block;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sb-user .who .r{font-size:var(--fs-11);color:var(--sur-marine-55);display:block;margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Sortie de session : présente uniquement sur un jeu de démonstration. */
.sb-quit{margin:10px 12px 0;}
.sb-quit button{width:100%;background:none;border:1px solid var(--sur-marine-12);color:var(--muted);
  border-radius:6px;padding:7px 10px;font-size:var(--fs-11);white-space:nowrap;cursor:pointer;
  display:flex;align-items:center;gap:8px;}
.sb-quit button svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9;flex:0 0 auto;}
.sb-quit button:hover{color:var(--sur-marine-2);border-color:var(--sur-marine-12);}
/* Étape 22 — lien « Mentions », discret, sous la sortie de session. */
.sb-mentions{margin:8px 20px 0;font-size:var(--fs-10);color:var(--muted);text-decoration:none;align-self:flex-start;}
.sb-mentions:hover,.sb-mentions:focus-visible{color:var(--sur-marine-2);text-decoration:underline;}
.mentions-texte{margin:0;line-height:1.55;max-width:70ch;}

/* Étape 9.C — réduction en mode icônes seules (~64px) : libellés masqués (tooltip
   natif via title, déjà posé sur chaque lien par rendreNav), avatar/icônes seuls
   restent visibles. Le bandeau démo (.demo, dans .main) n'en dépend pas — il
   s'élargit tout seul avec la colonne 1fr, cf. shell.js. */

/* Étape 9-bis.C — repli par la bordure : plus de chevron en pied de barre, la bande
   de 8px posée sur le bord droit de .sidebar EST le contrôle (un vrai <button>, en
   position:absolute — .sidebar, en position:sticky, lui sert de bloc conteneur, cf.
   shell.js). Silencieuse au repos ; liseré corail + flèche n'apparaissent qu'au
   survol/focus (jamais en permanence, contrairement à l'ancien chevron). */
.sb-edge{position:absolute;top:0;right:0;bottom:0;width:8px;background:none;border:none;
  padding:0;margin:0;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.sb-edge svg{width:14px;height:14px;stroke:var(--corail);fill:none;stroke-width:2.2;
  opacity:0;transition:opacity .15s;transform:rotate(90deg);}
/* .chevron pointe vers le bas au repos (icône partagée, profiles.js) : tourné à 90°
   il pointe vers la gauche (« replier »), à -90° vers la droite (« déplier »). */
.sb-edge:hover,.sb-edge:focus-visible{box-shadow:inset -2px 0 0 var(--corail);}
.sb-edge:hover svg,.sb-edge:focus-visible svg{opacity:1;}
.sb-edge:focus-visible{outline:2px solid var(--corail);outline-offset:-2px;}
.sidebar.collapsed .sb-edge svg{transform:rotate(-90deg);}

/* Sous 900px la nav redevient une rangée horizontale (cf. media query plus bas) : la
   réduction en icônes seules n'a de sens qu'au-delà, seule largeur où .sidebar reste
   une colonne verticale sticky. */
@media (min-width:901px){
  .sidebar.collapsed .sb-brand{justify-content:center;padding:2px 0 22px;}
  .sidebar.collapsed .sb-brand .wm,
  .sidebar.collapsed .sb-sec,
  .sidebar.collapsed .nav a .lbl,
  .sidebar.collapsed .nav .badge,
  .sidebar.collapsed .sb-user .who,
  .sidebar.collapsed .sb-quit button .txt,
  .sidebar.collapsed .sb-mentions,
  .sidebar.collapsed .nav-sous-titre{display:none;}
  .sidebar.collapsed .nav-sous{margin-left:0;padding-left:0;border-left:0;border-top:1px solid var(--sur-marine-12);}
  .sidebar.collapsed .nav a{justify-content:center;padding:10px;}
  .sidebar.collapsed .sb-user{justify-content:center;padding:16px 0 4px;}
  /* Étape 9-ter.A — le cadenas partage l'axe des icônes de nav et de l'avatar : MÊME
     conteneur pleine largeur (marge/padding horizontal retirés, comme .sb-user
     ci-dessus) + MÊME centrage (justify-content, comme .nav a et .sb-user) — pas un
     nudge de marge sur le seul bouton, qui aurait dérivé au prochain changement de
     largeur. */
  .sidebar.collapsed .sb-quit{margin:10px 0 0;padding:0;}
  .sidebar.collapsed .sb-quit button{justify-content:center;padding:7px 0;}
}

/* ---------- MAIN ---------- */
.main{display:flex;flex-direction:column;min-width:0;}
/* §25 — les nœuds de la coquille MOBILE sont posés par le JS sur TOUS les écrans (aucun
   matchMedia). Au bureau, `display:none` les sort aussi de l'ordre de tabulation. */
.tb-burger,.tb-av,.tabbar,.reg-appliquer,.tr-compact,.tr-sec,.tr-voile,
.tabrow,.tp-pied,.francemap-ouvrir,.francemap-fermer{display:none;}
/* §25 (22/09) — le périmètre a son propre groupe pour être une SECTION de la feuille
   mobile. `display:contents` le rend transparent ici : au bureau, la pastille et lui
   restent côte à côte dans `.tr-gauche`, au pixel près. */
.tr-perimetre,.tr-actions{display:contents;}
.topbar{background:var(--surface);border-bottom:1px solid var(--line);padding:16px 26px;
  display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;}
.topbar .tt{min-width:0;}
.topbar .tt h1{font-weight:var(--w-titre);font-size:var(--fs-20);letter-spacing:-.01em;}
.topbar .tt p{font-size:var(--fs-12);color:var(--muted);margin-top:2px;}
/* Étape 9-ter.B — un seul rail : sélecteurs à gauche (.tr-gauche), actions à droite
   (.tr-droite), cf. shell.js rendreControles(). flex-grow:1 (9-quater.B-bis) : seul sur sa
   ligne, .tr s'étire, et .tr-droite atteint la bordure droite des cartes. */
.topbar .tr{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;flex-grow:1;flex-basis:100%;}
/* Étape 21 (relecture) — flex-basis:100% : le rail a TOUJOURS sa ligne, sous le titre,
   comme la maquette. Sur la ligne du titre, déplier la pastille le renvoyait dessous. */
.tr-gauche,.tr-droite{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.tr-droite{margin-left:auto;justify-content:flex-end;}
/* 21/09 — les FILTRES DE LA PAGE, dans le rail : la barre intermédiaire des listes (trier,
   colonnes, recherche, liste/carte) remonte ici. `flex-basis:100%` leur donne leur propre
   ligne, sous les réglages de la coquille : à 1 440 px, les mettre dans le groupe gauche le
   faisait déborder et c'était la cloche qui tombait à la ligne, seule. Vide, il disparaît —
   pas même un gap. */
.tr-page{display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0;flex-basis:100%;}
.tr-page:empty{display:none;}
/* `.mediane .mp` retiré par la vue BU (classe orpheline, plus aucun JS ne la posait) : la
   fusion garde leur version. Notre moyenne du 21/09 porte `.mv.moy`, pas `.mp`. */
.pill-lib,.comparer-lib,.tphead .n,.mediane .ml{font-size:var(--fs-11);color:var(--muted);}
/* Étape 21 — pastille d'affichage (docs/maquettes/maquette-rail-affichage.html) :
   repliée elle DIT l'état, dépliée elle porte les réglages EN PLACE. La coque est un
   `.seg` (fond, bordure, rayon, boutons, focus hérités). Les réglages d'AFFICHAGE d'une page
   y entrent aussi ; ses FILTRES, eux, ont repris leur place à côté (`.tr-page`, 21/09). */
.reglages{align-items:center;flex-wrap:wrap;gap:6px;max-width:100%;}
.reglages.ouverte{border-radius:6px;padding-top:2px;padding-bottom:2px;}
.reglages:not(.ouverte):hover{border-color:var(--corail);}
/* Page en chargement (cycle de vie, shell.js) : réglages inactifs, et ça se voit. La tête
   d'une pastille ouverte referme, elle : son curseur reste celui d'un bouton. */
.reglages[aria-busy="true"] .reg-corps>*,.reglages[aria-busy="true"] .reg-actions{opacity:.55;}
.reglages[aria-busy="true"]:not(.ouverte) .reg-tete{cursor:progress;}
/* Le canvas d'une page quittée, le temps que la suivante se rende (shell.js) : visible,
   estompé, et inerte — aucun de ses contrôles ne pilote plus rien. */
.canvas[inert]{opacity:.55;}
.reglages[aria-busy="true"] .reg-segs button:not(.reg-x),
.reglages[aria-busy="true"] .reg-segs select{cursor:progress;}
.seg .reg-tete{display:inline-flex;align-items:center;gap:8px;padding:0 10px 0 0;font-size:var(--fs-12);}
.ouverte .reg-tete{padding:0;}
.ouverte .reg-etat,.ouverte .reg-tete>svg{display:none;}
.reg-ico{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;color:var(--muted);}
.reg-etat>span+span{margin-left:8px;padding-left:8px;border-left:1px solid var(--line);}
.reg-tete>svg{transform:rotate(-90deg);}
.reg-segs,.reg-corps,.reg-fin{display:contents;}
/* Lot Siège du 23/09 — avec « Actions » : elles et la croix restent sur la 1re ligne, à
   droite ; ce sont les réglages qui passent à la ligne. */
.reglages.avec-actions{flex-wrap:nowrap;align-items:flex-start;}
.avec-actions .reg-corps{display:flex;flex-wrap:wrap;align-items:center;gap:6px;flex:1 1 auto;min-width:0;}
.avec-actions .reg-fin{display:flex;align-items:center;gap:6px;flex:none;margin-left:auto;white-space:nowrap;}
.reglages .seg{background:var(--surface);padding:2px;align-items:center;}
.reglages .pill{height:26px;padding:0 10px 0 2px;cursor:default;}
.reglages .pill-lib{padding:0 4px 0 8px;text-transform:uppercase;letter-spacing:.05em;}
.seg .reg-x{width:26px;height:26px;padding:0;border:1px solid var(--line);background:var(--surface);font-size:var(--fs-16);line-height:1;}
@media (max-width:767px), (pointer:coarse) and (max-height:500px){.reg-etat>:nth-child(n+3),.reglages .pill-lib,.reglages .pill>svg:first-of-type{display:none;}
  .reglages{gap:4px;}.reglages .seg button{padding:5px 6px;}.reglages .pill{padding:0 6px;}}

/* Fil d'Ariane — tronqué à la racine du rôle (SPEC §2.2). Aucun équivalent dans les
   maquettes : composé dans leur grammaire (12,5 px, texte secondaire, chevron ›). */
.bc{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:var(--fs-11);color:var(--muted);letter-spacing:.02em;
  margin-bottom:5px;min-height:17px;}
.bc a{color:var(--corail);text-decoration:none;}
.bc a:hover{text-decoration:underline;}
.bc .sep{color:var(--muted);}
.bc .ici{color:var(--ink-2);}

/* Contrôles */
.pill{display:inline-flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--line);
  border-radius:6px;height:30px;padding:0 10px;font-size:var(--fs-12);color:var(--ink-2);cursor:pointer;}
.pill svg,.reg-tete>svg{width:14px;height:14px;stroke:var(--muted);fill:none;stroke-width:2;flex:0 0 auto;}
/* `.pill input` (étape 24) : les deux dates de la boîte d'analyse des ventes BU se règlent
   dans la même pastille de contrôle que les sélecteurs, sans second gabarit de champ. */
.pill select,.pill input{appearance:none;background:none;border:none;font-size:var(--fs-12);
  color:inherit;cursor:pointer;padding:0;margin:0;border-radius:4px;}

/* Retour PE 09/09 (B8, étape 16) — panneau « Colonnes » (liste des Business Units) :
   un <details> plutôt qu'une modale, même grammaire visuelle que .pill pour le
   <summary> qui l'ouvre (masque son triangle natif). */
.colonnes-bu{position:relative;}
.colonnes-bu summary{list-style:none;}
.colonnes-bu summary::-webkit-details-marker{display:none;}
.colonnes-bu summary::after{content:'';display:inline-block;width:6px;height:6px;margin-left:2px;
  border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(45deg);
  translate:0 -2px;}
.colonnes-bu[open] summary::after{transform:rotate(-135deg);translate:0 2px;}
.colonnes-bu-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:20;min-width:190px;
  background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:8px;}
.colonnes-bu-menu label{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;
  font-size:var(--fs-12);font-weight:var(--w5);cursor:pointer;}
.colonnes-bu-menu label:hover{background:var(--bg);}

/* Bascules à deux états — grammaire de .pill, état actif emprunté à .nav a.active */
.seg{display:inline-flex;background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:2px;}
.seg button{background:none;border:none;font-size:var(--fs-11);font-weight:var(--w5);
  color:var(--muted);padding:4px 10px;border-radius:4px;cursor:pointer;line-height:1.2;}
.seg button[aria-pressed="true"]{background:var(--marine);color:var(--sur-marine);}

/* Étape 9-bis.B — variante icônes seules (toggle Liste/Carte, rail d'outils des pages
   de liste) : même grammaire que .seg (Période/Base ci-dessus), boutons carrés plutôt
   que texte, couleur portée par currentColor (blanc actif via la règle ci-dessus,
   var(--muted) au repos, héritée de .seg button). */
.seg.icons button{padding:4px 10px;display:flex;align-items:center;justify-content:center;}
.seg.icons svg,.reg-ico svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.9;display:block;}

.rolebadge{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--corail);color:var(--corail);
  border-radius:6px;height:30px;padding:0 10px;font-size:var(--fs-12);font-weight:var(--w5);}
.rolebadge .dot{width:7px;height:7px;border-radius:50%;background:var(--corail);}

/* Retour PE 09/09, Lot B (B3) — cloche d'alertes (réseau/zone/groupe) : remplace le
   bandeau « Signaux d'action » retiré de ces niveaux, même famille visuelle que
   .topbtn-sec (icône seule, fond neutre), un badge chiffré en superposition.
   Retouche préprod du 12/09 — <button> depuis que le clic ouvre un panneau au lieu
   de naviguer directement (alertesPanel.js), plus jamais un <a href>. */
.cloche-alertes,.signal-mode-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:6px;background:var(--surface);color:var(--muted);
  border:1px solid var(--line);cursor:pointer;}
.cloche-alertes:hover,.signal-mode-btn:hover{background:var(--surface);border-color:var(--corail);color:var(--marine);}
.cloche-alertes svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;}
.cloche-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 3px;
  border-radius:6px;background:var(--corail);color:var(--sur-marine);font-size:var(--fs-10);font-weight:var(--w5);
  line-height:16px;text-align:center;}

/* Retour PE 09/09, Lot B (B7) — bouton « mode signalement » : le gabarit rond de
   .cloche-alertes, avec qui il PARTAGE désormais la règle (icône seule, sans badge) ;
   jamais .topbtn, qui reste le marqueur « Siège + réseau entier ». */
.signal-mode-btn svg{width:16px;height:16px;}
.signal-mode-btn[aria-pressed="true"]{background:var(--marine);border-color:var(--marine);color:var(--sur-marine);}
/* Lot rail Siège (22/09) — la section « Actions » de la pastille dépliée, EN DERNIER : un
   filet vertical la sépare des réglages (ce ne sont pas des réglages : ils ne changent aucun
   chiffre). Depuis le 23/09, la seule icône du signalement, à la hauteur des segments ; celle
   du rail Siège ne se montre plus qu'au téléphone (`.hors-bureau`, rallumée par mobile.css). */
.reglages .reg-actions{margin-left:6px;padding-left:10px;border:0;border-left:1px solid var(--line);
  border-radius:0;gap:6px;}
/* 23/09 — le gabarit de la cloche (pas un bouton de segment vidé) : carré à la hauteur des
   segments, icône 20 px, cible de 44 px (26 + 2 × 9, depuis le bord intérieur) qui
   s’arrête au bord de la croix. */
.reglages .reg-actions .signal-mode-btn{width:28px;height:28px;padding:0;border-radius:6px;
  border:1px solid var(--line);background:var(--surface);}
.reglages .reg-actions .signal-mode-btn:hover{border-color:var(--corail);color:var(--marine);}
.reglages .reg-actions .signal-mode-btn[aria-pressed="true"]{background:var(--marine);border-color:var(--marine);color:var(--sur-marine);}
.reg-actions .signal-mode-btn svg{width:20px;height:20px;}
.reg-actions .signal-mode-btn::after{content:'';position:absolute;inset:-9px;}
.signal-mode-btn.hors-bureau{display:none;}
/* … et les filtres de liste, sur la ligne de la pastille, dans le groupe de droite : ils y
   prennent leur largeur, pas une ligne entière. */
.tr-droite>.tr-page{flex-basis:auto;justify-content:flex-end;}

/* Bouton d'action de la topbar (Rapport PPTX, Siège seul, étape hors gel réunion du
   26, 3/3) — fond marine (§23) : seule action « pleine » du rail, distincte des
   sélecteurs qui ne font que choisir un état. */
.topbtn,.coef-actions button,.msg-fil-actions button,.kpirevue button,.devlog form button,.cmp-flottant,.etat .act a{display:inline-flex;align-items:center;justify-content:center;gap:7px;background:var(--marine);
  color:var(--sur-marine);border:1px solid var(--marine);border-radius:6px;height:30px;padding:0 12px;
  font-size:var(--fs-12);font-weight:var(--w5);cursor:pointer;text-decoration:none;}
.topbtn svg{width:14px;height:14px;stroke:var(--sur-marine);fill:none;stroke-width:2;flex:0 0 auto;}
.topbtn:hover,.cmp-flottant:hover{background:var(--marine-2);border-color:var(--marine-2);}
.topbtn:disabled,.coef-actions button:disabled,.devlog form button:disabled{opacity:.5;cursor:default;}

/* Étape 9-ter.C — « Exporter » : même gabarit que .topbtn, mais en CONTOUR (§23) —
   secondaire face à Rapport, la seule action pleine du rail. */
.topbtn.topbtn-sec,.coef-actions .sec,.msg-fil-actions button,.kpirevue button,.etat .act a.sec{background:var(--surface);color:var(--ink);border-color:var(--line);}
.topbtn.topbtn-sec svg{stroke:var(--muted);}
.topbtn.topbtn-sec:hover,.coef-actions .sec:hover,.msg-fil-actions button:hover{background:var(--surface);border-color:var(--corail);}

.canvas{padding:22px 26px 28px;overflow:auto;}

/* Bandeau de démonstration (SPEC §9.5) — disparaît dès que meta.is_demo_data passe à false */
.demo{background:var(--corail-soft);border-bottom:1px solid var(--line);color:var(--corail);
  font-size:var(--fs-11);font-weight:var(--w5);padding:6px 26px;letter-spacing:.02em;}
/* 22/09 — En PRODUCTION le bandeau ne prévient plus, il informe : il dit d'où viennent les
   chiffres, et il n'y a rien à craindre. Le corail est la teinte d'alerte du dépôt ; la garder
   sous une phrase neutre aurait fait lire un avertissement là où il n'y en a plus.
   --marine sur --bg : 14:1, bien au-delà du seuil d'un texte. */
.demo.neutre{background:var(--bg);color:var(--marine);}

/* ---------- États de page ---------- */
.etat{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:28px 26px;
  max-width:620px;}
.etat h2,.devlog h1,.cmp-tete h2,.kpisection-tete h3,.msg-fil-tete h3{font-weight:var(--w5);font-size:var(--fs-16);color:var(--marine);}
.etat p{color:var(--ink-2);margin-top:8px;line-height:1.5;}
.etat.refus{border-left:4px solid var(--corail);}
.etat .ic{width:38px;height:38px;border-radius:6px;background:var(--corail-soft);
  display:flex;align-items:center;justify-content:center;margin-bottom:14px;}
.etat .ic svg{width:20px;height:20px;stroke:var(--corail);fill:none;stroke-width:2;}
.etat .act{margin-top:16px;display:flex;gap:10px;flex-wrap:wrap;}
.etat .act a{text-decoration:none;}

/* Réserve de l'étape 3 : le canvas n'affiche pour l'instant que son intitulé. */
.reserve{background:var(--surface);border:1px dashed var(--line);border-radius:6px;padding:26px;}
.reserve .sc{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-24);color:var(--marine);}
.reserve .rb{color:var(--corail);font-weight:var(--w5);margin-top:4px;text-transform:uppercase;
  letter-spacing:.06em;}
.reserve .no{font-size:var(--fs-12);color:var(--muted);margin-top:14px;line-height:1.6;}
.reserve dl{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;margin-top:16px;font-size:var(--fs-12);}
.reserve dt{color:var(--muted);font-weight:var(--w5);}
.reserve dd{color:var(--marine);font-weight:var(--w5);}

/* ---------- Écran de choix de compte (développement) ---------- */
.devlog{max-width:520px;margin:60px auto;background:var(--bg);border-radius:6px;
  box-shadow:var(--ombre-modale);overflow:hidden;}
.devlog header{background:var(--marine);padding:22px 26px;display:flex;align-items:center;gap:11px;}
.devlog header .wm{font-weight:var(--w6);font-size:var(--fs-16);letter-spacing:.14em;color:var(--sur-marine);}
.devlog header .wm .cor{color:var(--corail);}
.devlog .corps{padding:22px 26px 26px;}
.devlog p{font-size:var(--fs-12);color:var(--muted);margin-top:6px;line-height:1.5;}
.devlog ul{list-style:none;margin-top:18px;display:flex;flex-direction:column;gap:8px;}
.devlog button.compte{width:100%;display:flex;align-items:center;gap:12px;background:var(--surface);
  border:1px solid var(--line);border-radius:6px;padding:12px 14px;cursor:pointer;text-align:left;
  }
.devlog button.compte:hover{border-color:var(--corail);}
.devlog button.compte .av{width:34px;height:34px;border-radius:50%;
  background:var(--corail);display:flex;align-items:center;justify-content:center;
  font-weight:var(--w5);color:var(--sur-marine);font-size:var(--fs-12);flex:0 0 auto;}
.devlog button.compte .n{font-weight:var(--w5);font-size:var(--fs-13);color:var(--marine);display:block;}
.devlog button.compte .r{font-size:var(--fs-11);color:var(--muted);display:block;margin-top:1px;}
.devlog .err{margin-top:14px;font-size:var(--fs-12);color:var(--corail);font-weight:var(--w5);}
/* Étape 11a — organigramme : une section par niveau (Siège / Directions régionales /
   Directions multi-BU / Business Unit / Agence / Négociateur) au lieu d'une liste à
   plat, devenue illisible une fois les 12 Directions multi-BU ajoutées. */
.devlog-groupe{margin-top:20px;}
.devlog-groupe:first-of-type{margin-top:18px;}
.devlog-groupe-titre{font-weight:var(--w5);font-size:var(--fs-11);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);}
.devlog-groupe ul{margin-top:8px;}

/* ---------- Écran de connexion (authentification réelle, étape 6) ----------
   Même carte que .devlog (charte §8.1) : un seul des deux écrans est jamais monté,
   selon la capacité que le serveur déclare — ils partagent donc leur habillage. */
.devlog .form-connexion{margin-top:18px;display:flex;flex-direction:column;gap:14px;}
.devlog .form-connexion label{display:flex;flex-direction:column;gap:6px;
  font-size:var(--fs-12);font-weight:var(--w5);color:var(--muted);}

/* ---------- Chargement ---------- */
.chargement{padding:40px 26px;color:var(--ink-2);}

@media (max-width:900px){
  /* `align-content:start` : sur une page plus courte que la fenêtre, les rangées de la
     grille se partageaient l'espace restant — déplier la pastille remontait alors tout
     l'en-tête de 22 px, et le dépliage n'était plus « en place » (relecture 2). */
  .app{grid-template-columns:1fr;align-content:start;}
  /* Sous 900px, la nav redevient une rangée horizontale qui défile avec la page —
     le collage sticky (position/height) et la réduction en icônes seules (au-dessus,
     min-width:901px) n'ont plus de sens ici ; .collapsed reste sans effet visuel. */
  .sidebar{position:static;height:auto;padding:16px 0;}
  .nav{flex-direction:row;overflow-x:auto;}
  .nav .badge{margin-left:6px;}
  .nav-sous{flex-direction:row;align-items:center;margin:0 4px;flex:0 0 auto;}
  .sb-user{margin-top:16px;}
  /* .sidebar redevient position:static ici : elle ne sert plus de bloc conteneur à
     .sb-edge (position:absolute), qui se positionnerait alors n'importe où sur la
     page. Le repli en icônes n'a de sens qu'au-dessus de 900px (cf. commentaire plus
     haut) : la bordure cliquable disparaît avec lui plutôt que de mal se positionner. */
  .sb-edge{display:none;}
}

/* =====================================================================
   CANVAS — composants du tableau de bord (SPEC §7.2, §8.3)
   Valeurs reprises des maquettes validées, sans exception.
   ===================================================================== */

/* ---------- KPI ---------- */
/* Atelier 28/08 — la rangée n'est plus figée à 5 colonnes : une Business Unit en
   compte 7 depuis les cartes PAS/PS. `auto-fit` + une largeur PLANCHER vaut mieux
   qu'un nombre de colonnes imposé : à 5 cartes le rendu est identique à avant (les
   pistes vides se replient, les cartes s'étirent), à 7 la rangée reste sur une ligne
   dès qu'il y a la place et passe d'elle-même à la ligne suivante sinon — jamais de
   carte écrasée sous un écran de 1200 px. */
.kpirow{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;}
.card{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:12px 14px 11px;min-height:86px;}
.card .lab{font-size:var(--fs-11);color:var(--muted);line-height:1.3;}
.card .val{font-weight:var(--w5);font-size:var(--fs-24);line-height:1;margin-top:6px;letter-spacing:var(--ls-chiffres);}
.card .val .u{font-size:var(--fs-12);font-weight:var(--w4);color:var(--corail);margin-left:4px;}
/* Montant d'une carte double (PAS/PS) : à côté de la valeur, comme l'unité (§23, maquette). */
.card .val small{margin-left:6px;font-size:var(--fs-12);font-weight:var(--w4);color:var(--corail);}
/* Décision de Fred (04/10) — composition du chiffre (« apports compris » / réserve api) : gris
   --muted (thème), taille et graisse de l'unité, une seule ligne (nowrap), jamais corail. */
.card .val small.apports-note{color:var(--muted);font-size:var(--fs-12);font-weight:var(--w4);white-space:nowrap;}
/* RÉSERVE d'une BU pilote dans un tableau (04/10) : en ligne, à gauche du chiffre, sur une seule ligne. */
.tablepanel td .rsv{color:var(--muted);font-size:var(--fs-11);margin-right:6px;white-space:nowrap}
.card .delta,.tablepanel td .delta{display:inline-flex;align-items:center;gap:3px;font-size:var(--fs-11);font-weight:var(--w5);color:var(--vert);}
.card .delta{margin-top:8px;}
.card .delta.down,.tablepanel td .delta.down{color:var(--rouge);}
.card .delta.ns,.tablepanel td .delta.ns,td.ns .delta{color:var(--muted);}
/* « 2025 : — » sur une carte MARINE (05/10) : --muted (#6B7280) y tombait à 3,7:1 ; le gris clair des autres lignes secondaires de la carte. */

/* Retour PE 09/09 (A1, étape 16) : l'année/valeur de référence, neutre — ne doit
   pas hériter le vert/corail du sens de la variation qui la suit. */
/* Étape 18 (retouche du 16/09) — la base de référence porte une infobulle de MÉTHODE
   sur les mesures de cumul (« Cumul 2025 au mois — profil mensuel… »). Le curseur est
   le SEUL signal ajouté : aucun glyphe, donc aucune légende à inventer sous la rangée
   et aucun texte de carte modifié. `[title]` : les cartes sans note gardent le curseur
   par défaut, elles n'ont rien à promettre. */
.delta-base{color:var(--muted);}
.delta-base[title]{cursor:help;}
.card.feat{background:var(--marine);border-color:var(--marine);
  /* TEXTE SECONDAIRE, HAUSSE, BAISSE SUR MARINE (05/10) : --muted (3,7:1), --vert (3,6:1) et --rouge (3,5:1) tombaient sous l'AA sur ce
     fond. Redéfinis DANS la carte, ils corrigent d'un coup `.delta`, `.delta.down`, `.delta.ns`, `.delta-base` et `.apports-note`, et toute
     ligne qu'on y ajoutera — au lieu d'une règle par classe (a0816f8 n'en avait écrit qu'une). Le sombre garde ses règles (sombre.css). */
  --muted:var(--sur-marine-2);--vert:var(--vert-sur-marine);--rouge:var(--corail-sur-marine);}
.card.feat .lab{color:var(--sur-marine-2);}.card.feat .val{color:var(--sur-marine);}.card.feat .val .u{color:var(--corail);}
.card.act .val,.card.act .lab b{color:var(--corail);}

/* Marqueur de disponibilité §6 — absent des maquettes, composé dans leur grammaire :
   une pastille discrète, du même gabarit que .chip, visible en mode démonstration. */
.card .lab .dispo{display:inline-block;width:6px;height:6px;border-radius:50%;margin-left:5px;
  vertical-align:middle;background:var(--line-2);cursor:help;}
.card .lab .dispo.histo,.card .lab .dispo.saisie{background:var(--corail);}
.card .lab .dispo.bloque{background:var(--muted);}
.card.feat .lab .dispo{background:var(--ink-2);}

/* Compteurs de phase du négociateur (atelier 28/08) — même gabarit que .realise, en
   bloc séparé : trois colonnes, un filet de séparation au-dessus. */
.phases{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px;
  padding-top:12px;border-top:1px solid var(--line);}
.phstat .rl{font-size:var(--fs-10);color:var(--muted);}
.phstat .rv{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-20);color:var(--marine);margin-top:3px;}
.phstat .rv small{display:block;margin-top:1px;font-size:var(--fs-10);
  font-weight:var(--w5);color:var(--corail);}

/* ---------- Panneaux ---------- */
/* Étape 17 (C1) — la fusion CA/Trajectoire fait disparaître `.grid2` (Série+Contribution
   à mi-largeur) : chaque panneau du tableau de bord prend maintenant sa propre ligne
   pleine largeur, espacée de la précédente — scopé à `.dashboard-bloc` (pas une règle
   `.panel` globale, qui affecterait aussi les panneaux d'autres pages, déjà espacés
   autrement, ex. projectionCa.js). */
/* Retouche de passe finale (étape 17) — « Contribution par Business Unit » et
   « Cycles d'activité » côte à côte en 2/5–3/5 sous le panneau CA, pour supprimer le
   vide à droite. La grille est portée par `.dashboard-bloc` LUI-MÊME plutôt que par un
   conteneur enveloppant les deux panneaux : le DOM reste strictement inchangé (le
   contrôle de structure §7.2 lit `.dashboard-bloc > .panel`, un enfant DIRECT, et
   tomberait au premier emballage).
   `minmax(0,1fr)` et non `1fr` : le classement des BU (`.tablepanel`, en-têtes
   `white-space:nowrap`) est un élément de grille à `min-width:auto` et élargirait
   sinon sa piste jusqu'à faire déborder l'écran. */
.dashboard-bloc{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));column-gap:14px;}
/* Repli par défaut : tout occupe la largeur. Seuls les deux panneaux du duo en
   sortent, et seulement quand le second existe réellement (classes posées en JS). */
.dashboard-bloc>*{grid-column:1 / -1;}
.dashboard-bloc>.panel{margin-top:14px;}
.dashboard-bloc>.panel.duo-etroit{grid-column:span 2;}
.dashboard-bloc>.panel.duo-large{grid-column:span 3;}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:14px 16px;}
.panel h3{font-size:var(--fs-13);font-weight:var(--w-titre);}
/* `.sub` n'avait de taille QUE sous `.panel` : ailleurs (simulateur, modales) elle héritait
   du corps et paraissait plus grosse. Retouche du 16/09, point 5. */
.panel .sub,.sim-boite .sub,.sim-atterrissage .sub,.cmp-corps .sub,.cmp-pied .sub{
  font-size:var(--fs-11);color:var(--muted);margin-top:2px;margin-bottom:12px;}
.panel .sub.coef{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;}
.vide{font-size:var(--fs-12);color:var(--ink-2);padding:18px 0;}
/* Étape 9-bis.D — emplacement de contrôles du panneau (slot du composant, cf.
   dashboard.js panneau()) : même ligne que le titre, aligné sur le bord droit. Sans
   cette règle .panel-tete n'était qu'un div de bloc ordinaire — h3 et contrôles se
   sont empilés verticalement au lieu de partager une ligne (bug constaté en démo). */
.panel-tete{display:flex;align-items:center;justify-content:space-between;gap:12px;}
.panel-tete h3{flex:1;min-width:0;}
/* Sélecteur d'année de comparaison du graphe (atelier 28/08) — remplace la pill
   « N-1 ». Réutilise le .seg de la topbar (même gabarit segmenté), en plus compact
   puisqu'il vit dans un en-tête de panneau. */
/* Retour PE 09/09, Lot B (B1) — slot `controles` à deux éléments (le sélecteur
   d'année existant + le nouveau bouton ⤢) : un seul enfant pour panneau-tete, ce
   petit conteneur les met côte à côte sans toucher à .panel-tete lui-même. */
.panel-controles{display:flex;align-items:center;gap:10px;}
.comparer{display:inline-flex;align-items:center;gap:7px;}
.comparer .seg{padding:2px;border-radius:6px;}
.comparer .seg button{font-size:var(--fs-11);padding:3px 10px;}
.seg button:disabled{opacity:.4;cursor:not-allowed;}

/* ---------- Histogramme ---------- */
/* v1.8.1 — une grille : ligne 1 = la zone de tracé (barres, graduations, référence,
   réticule, même hauteur de référence), lignes 2-3 = valeurs et libellés. Réserve haute
   et colonnes posées par barChart.js (GEOMETRIE_BARRES). 164 = 150 + 14 : la zone de
   tracé garde sa hauteur d'avant malgré la réserve. */
.bars{position:relative;display:grid;grid-template-rows:minmax(0,1fr) auto auto;column-gap:18px;row-gap:7px;height:164px;}
.barcol{display:contents;}
.barwrap{grid-row:1;position:relative;width:100%;height:100%;display:flex;align-items:flex-end;justify-content:center;gap:2px;}
.barcol .bv,.barcol .bl{text-align:center;font-size:var(--fs-10);color:var(--muted);}
.barcol .bv{grid-row:2;color:var(--ink-2);}.barcol .bl{grid-row:3;}
.bars-aire{grid-row:1;grid-column:1/-1;position:relative;pointer-events:none;}
/* §2 : axe zéro (trait inset, sans nœud). */
.bars-fond{box-shadow:inset 0 -1px var(--line);}
/* §2 : 8 px, rayon 1 ; la comparaison grise À CÔTÉ. */
.bar{width:8px;border-radius:1px;background:var(--corail);}
.bar.n1{background:var(--serie-2);}
/* Étape 9.D — cumul N-1 non mensualisé (n1_ytd seul) : ligne pointillée plutôt que des
   barres inventées (règle 7) ; jamais affichée en même temps que .bar.n1. */
.bars-ref{position:absolute;left:0;right:0;border-top:2px dashed var(--muted);pointer-events:none;}
.bars-ref-lib{position:absolute;right:0;font-size:var(--fs-10);color:var(--muted);
  background:var(--surface);padding:0 4px;white-space:nowrap;}
/* v1.8.1 — au maximum, le libellé entre dans la réserve haute : dans une vignette, il se
   décale de la loupe d'agrandissement (.gr-loupe : 2 + 26 px, + 4 d'espace). */
.graphe-agrandissable .bars-ref-lib{right:32px;}
/* Retour PE 15/09 (B2), retouche v1.8.1 — réticule des barres : PLUS DE TRAIT. La
   colonne survolée est surlignée, l'étiquette suit la souris (posée par barChart.js aux
   coordonnées du curseur dans `.bars`). Rien de tout cela n'intercepte le pointeur. */
.bars .brt-lib{display:none;pointer-events:none;}
.bars.reticule-visible .brt-lib{display:block;}
/* multiply : grilles, axe et graduations restent visibles dessous. */
.barwrap.survolee{background:var(--line-2);mix-blend-mode:multiply;}
.brt-lib{position:absolute;transform:translate(12px,calc(-100% - 10px));background:var(--marine);color:var(--sur-marine);
  font-size:var(--fs-11);font-weight:var(--w5);padding:3px 7px;border-radius:6px;white-space:nowrap;z-index:4;}
.brt-lib.gauche{transform:translate(calc(-100% - 12px),calc(-100% - 10px));}
.brt-lib.dessous{transform:translate(12px,16px);}
.brt-lib.gauche.dessous{transform:translate(calc(-100% - 12px),16px);}
/* Retouche préprod du 12/09 (B1) — axe Y gradué (même mécanisme que .bars-ref juste
   au-dessus, réutilisé pour une graduation plutôt qu'une référence N-1). Sous les
   barres (z-index implicite : premier dans le DOM, cf. barChart.js), jamais dessus. */
.bars-grille{position:absolute;left:0;right:0;border-top:1px solid var(--line-2);pointer-events:none;}
.bars-grille-val{position:absolute;left:0;font-size:var(--fs-10);color:var(--muted);
  background:var(--surface);padding-right:4px;white-space:nowrap;}
.bars-axe-nom,.ligne-axe-nom{text-align:center;font-size:var(--fs-10);color:var(--muted);
  text-transform:uppercase;letter-spacing:.04em;margin-top:6px;}
.legend{display:flex;gap:14px;margin-top:8px;font-size:var(--fs-11);font-weight:var(--w5);color:var(--muted);}
.legend span{display:inline-flex;align-items:center;gap:6px;}
.legend i{width:14px;height:2px;border-radius:1px;display:inline-block;}

/* ---------- Donut ---------- */
.donut-wrap{display:flex;align-items:center;gap:16px;}
/* §2 : chiffre en 300 ; sa taille reste un attribut calculé (pas de font-size ici). */
.donut{flex:0 0 auto;fill:var(--muted);font-size:var(--fs-10);}
.donut .dc{fill:var(--ink);font-weight:var(--w5);letter-spacing:var(--ls-chiffres);}

/* ---------- Cycles (lignes, frere du barChart) ---------- */
/* Retour PE 15/09 (A2) — « trois graphiques sur la première ligne et un seul sur la
   seconde, ce qui laisse un espace vide en bas à droite ». `auto-fit` + `minmax(210px)`
   donnait 2 colonnes sur un écran moyen mais 3 sur un grand (le panneau fait alors 3/5
   de la largeur, soit ~770 px utiles) — donc 3 + 1, avec son trou. Le nombre de
   colonnes est désormais ARRÊTÉ, pas calculé : 1 en mobile, 2 partout ailleurs. Quatre
   graphes se rangent en 2 × 2, jamais autrement. */
.cycles-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;}
@media(min-width:640px){.cycles-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
.ligne-cycle-wrap{display:flex;flex-direction:column;gap:5px;position:relative;}
.ligne-titre{font-size:var(--fs-12);font-weight:var(--w5);}
.ligne-cycle{width:100%;height:auto;display:block;}
.ligne-cycle:focus-visible{outline:2px solid var(--corail);outline-offset:2px;border-radius:6px;}
/* Retour PE 15/09 (B2) — réticule du graphe en lignes. Les bandes sont la seule partie
   sensible au pointeur ; le réticule lui-même ne l'est jamais, sans quoi il se
   placerait sous le curseur et volerait l'événement suivant. */
.lrt-bande{fill:transparent;pointer-events:all;}
.ligne-reticule{display:none;pointer-events:none;}
.ligne-reticule[data-visible]{display:block;}
.lrt-halo{opacity:.32;}
.lrt-point{fill:var(--surface);stroke-width:2.2;vector-effect:non-scaling-stroke;}
.lrt-fond{fill:var(--marine);opacity:.94;}
.lrt-texte{fill:var(--sur-marine);font-weight:var(--w5);}
.ligne-axe-nom{margin-top:1px;}
.dleg{display:flex;flex-direction:column;gap:6px;min-width:0;}
.dleg .row{display:flex;align-items:center;gap:8px;font-size:var(--fs-12);}
.dleg .row i{width:8px;height:8px;border-radius:2px;flex:0 0 auto;}
.dleg .row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dleg .row b{margin-left:auto;font-weight:var(--w5);padding-left:8px;}
/* 22/09 — `auto-fit` et non `repeat(3,1fr)` : le négociateur n'a plus que DEUX
   statistiques depuis le retrait de « Ma rétrocession », et une grille figée à trois
   colonnes lui laissait un trou à droite. À trois cartes, la mise en page est celle
   d'avant, au pixel près ; à deux, elles se partagent la largeur. */
.realise{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-top:12px;}
.rstat{border:1px solid var(--line-2);border-radius:6px;padding:8px 10px;}
.rstat .rl{font-size:var(--fs-10);color:var(--muted);}
.rstat .rv{font-size:var(--fs-16);font-weight:var(--w5);letter-spacing:var(--ls-chiffres);margin-top:4px;}
.rstat .rv small{font-size:var(--fs-11);color:var(--corail);margin-left:4px;}
/* Casse — étape hors gel (réunion du 26) : des honoraires perdus ne sont pas un
   résultat comme un autre, la valeur le dit par sa couleur. */
.rstat.casse .rv{color:var(--corail);}

/* Réunion du 26 — l'année en cours (partielle) pâle, la projection hachurée. Le contour
   corail donne les 3:1 (pâle seul : 1,23) ; 2 px, car 1 px retombe à 2:1 à 125 % (§23). */
.bar.distinct{background:var(--corail-soft);box-shadow:inset 0 0 0 2px var(--corail);}
.bar.hachure{background:repeating-linear-gradient(45deg,var(--corail) 0 2px,var(--corail-soft) 2px 4px);}

/* ---------- Signaux ---------- */
.signals{margin-top:14px;background:var(--surface);border:1px solid var(--line);border-left:4px solid var(--corail);
  border-radius:6px;padding:14px 18px;display:flex;align-items:center;gap:22px;flex-wrap:wrap;}
.signals .sh{font-weight:var(--w5);color:var(--marine);}
.signals .sig{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--ink);}
.signals .sig .ic{width:30px;height:30px;border-radius:6px;background:var(--corail-soft);
  display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.signals .sig .ic svg{width:16px;height:16px;stroke:var(--corail);fill:none;stroke-width:2;}
.signals .sig .tx{font-size:var(--fs-12);line-height:1.25;}
.signals .sig .tx b{color:var(--corail);}

/* ---------- Tableau ---------- */
.tablepanel{margin-top:14px;background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:6px 4px 4px;}
/* §4 : un tableau trop large défile dans sa carte, pas la page — et, depuis le 21/09, dans un
   cadre BORNÉ EN HAUTEUR (`.tp-defile`) plutôt que la carte entière. C'est ce qui donne un sens
   à `position:sticky` sur l'en-tête : collé au cadre qui défile, il reste visible sur une liste
   longue. Le titre de la carte et la pagination vivent DEHORS, ils n'ont pas à défiler avec les
   lignes. En modale, rien ne change : `.cmp-corps` est déjà ce cadre borné (plus bas). */
.canvas .tp-defile{overflow:auto;max-height:72dvh;}
/* LES DEUX MODÈLES COEXISTENT, et cette règle est celle du plus ancien : la CARTE défile.
   Sur une carte qui a reçu son cadre (`.tp-defile`, au-dessus) elle est inerte — le cadre
   borne le tableau, la carte ne déborde plus de rien. Sur une carte qui n'en a pas, elle
   reste le seul défilement : les tableaux de `dashboard`, `projectionCa`, `qualiteSaisie`,
   `rapprochement`, `simulateur`, et les grilles de SAISIE du formulaire de `buGrille`, qui
   n'en veulent pas (des champs en tableau ne sont pas une liste — voir le fichier).
   Son pendant mobile, `.canvas .tablepanel>:not(table){position:sticky;left:0}`, est en
   fin de feuille et suppose lui aussi ce défilement. */
.canvas .tablepanel{overflow-x:auto;}
.canvas .tp-defile thead th{position:sticky;top:0;z-index:2;background:var(--surface);
  /* `border-collapse:collapse` donne les bordures au TABLEAU : celle du `th` ne voyage pas avec
     lui quand il colle. Une ombre intérieure, elle, appartient à la cellule. */
  box-shadow:inset 0 -1px 0 var(--line);}
.tphead{display:flex;align-items:center;justify-content:space-between;padding:12px 16px 10px;}
.tphead h3{font-size:var(--fs-13);font-weight:var(--w-titre);}
.lnk{font-size:var(--fs-12);color:var(--corail);font-weight:var(--w5);cursor:pointer;text-decoration:none;}
.lnk:hover{text-decoration:underline;}
.tablepanel table{width:100%;border-collapse:collapse;}
.tablepanel thead th{font-size:var(--fs-10);text-transform:uppercase;letter-spacing:.06em;color:var(--muted);font-weight:var(--w-titre);
  text-align:left;padding:8px 16px;border-bottom:1px solid var(--line);}
.tablepanel thead th.r,.tablepanel tbody td.r{text-align:right;}
.tablepanel tbody td,.tablepanel tbody th{padding:8px 16px;font-size:var(--fs-12);border-bottom:1px solid var(--line-2);text-align:left;}
.tablepanel tbody tr:last-child>*{border-bottom:none;}
/* Étape 9.E — colonne de sélection du comparateur : étroite, jamais de tri. */
.tablepanel th.sel,.tablepanel td.sel{width:34px;padding-right:0;}
/* Retour PE 09/09 (A5, étape 16) — colonne « var. » entre deux années côte à côte
   (Comparaison d'un mois, Projection CA) : fine, comme .sel ci-dessus. */
.tablepanel th.var,.tablepanel td.var{width:64px;padding:8px;}
.tablepanel td.sel input[type="checkbox"]{width:15px;height:15px;cursor:pointer;}
.tablepanel tbody tr[data-lien]{cursor:pointer;}
.tablepanel tbody tr[data-lien]:hover{background:var(--bg);}
.tablepanel tbody tr[data-lien]:focus-visible{outline:2px solid var(--corail);outline-offset:-2px;}
.zebre tr:nth-child(even)>*{background:var(--bg);}
.zebre tr[data-lien]:hover>*{background:var(--line-2);}
.tablepanel tbody th,.tablepanel td .bn,.tablepanel td b{font-weight:var(--w5);color:var(--marine);}
.tablepanel .vide{padding:20px 16px 26px;}
td.ref,th.ref,.rn.ref,th .ref,code{font-family:var(--mono);}
.chip{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-11);font-weight:var(--w5);border-radius:6px;padding:3px 10px;}
.chip.ok{background:var(--line-2);color:var(--vert);}
.chip.ech,.chip.dor{background:var(--corail-soft);color:var(--corail);}
.chip.comp{background:var(--line-2);color:var(--marine-2);}
/* §23, États : « non mesuré », « non évaluable » en italique muted, sans fond (Rapprochement). */
.chip.nm{background:none;padding:3px 0;color:var(--muted);font-style:italic;font-weight:var(--w4);}
.tablepanel tr:not(.reprow)>td>.sub{margin-top:2px;max-width:60ch;font-size:var(--fs-11);color:var(--muted);font-style:italic;}
/* Un montant ne se coupe jamais (les motifs de Rapprochement resserraient ses colonnes). */
.tablepanel td.r{white-space:nowrap;}
.chip .d{width:6px;height:6px;border-radius:50%;background:currentColor;}
.rank,.gr-rang{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;border-radius:4px;
  background:var(--line-2);color:var(--ink-2);font:var(--fs-11) var(--mono);margin-right:8px;vertical-align:middle;}
.rcell{display:inline-flex;align-items:center;gap:10px;}
.mbar{width:64px;height:3px;border-radius:2px;background:var(--line);position:relative;overflow:hidden;}
.mbar>i{position:absolute;left:0;top:0;bottom:0;background:var(--corail);}

@media (max-width:1100px){
  .kpirow{grid-template-columns:repeat(2,1fr);}  /* deux colonnes fixes sous 1100px, quel que soit le nombre de cartes */
  /* Le duo Contribution/Cycles retombe en une colonne : à cette largeur, 2/5 ne laisse
     plus la place à un donut lisible. */
  .dashboard-bloc>.panel.duo-etroit,.dashboard-bloc>.panel.duo-large{grid-column:1 / -1;}
}

/* =====================================================================
   PAGES DE CONTENU — étape 4 (portefeuille, ventes, enfants, classement)
   Aucune maquette de référence pour ces écrans (seuls les tableaux de bord en ont) :
   composé dans la grammaire §8.1/§8.3 — jetons, rayons et composants déjà établis
   (.pill, .chip, .tablepanel, .rank, .mbar), sans en inventer de nouveaux hors de ce
   vocabulaire.
   ===================================================================== */

/* Barre d'outils générique d'une page de contenu : titre de page + contrôles propres
   (recherche, sélecteur d'indicateur) au-dessus du panneau principal. */
.pagebar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:14px;}
.pagebar h2{font-weight:var(--w5);font-size:var(--fs-16);}
.pagebar .out{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}

/* Barre de filtres (§7.3) — grammaire de .pill, cliquable ; l'actif en marine, comme .seg (§23). */
.pillbar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;}
.pillbar button{display:inline-flex;align-items:center;gap:6px;background:var(--surface);
  border:1px solid var(--line);border-radius:6px;height:30px;padding:0 12px;
  font-size:var(--fs-12);font-weight:var(--w5);cursor:pointer;}
.pillbar button[aria-pressed="true"],.pillbar .actif{background:var(--marine);
  color:var(--sur-marine);border-color:var(--marine);}
.pillbar .n{font-size:var(--fs-11);opacity:.75;}

/* Champ de recherche (§7.5) */
.recherche{display:inline-flex;align-items:center;gap:8px;background:var(--surface);
  border:1px solid var(--line);border-radius:6px;height:30px;padding:0 12px;min-width:220px;}
.recherche svg{width:14px;height:14px;stroke:var(--muted);fill:none;stroke-width:2;flex:0 0 auto;}
.recherche input{border:none;outline:none;font-size:var(--fs-12);
  width:100%;background:none;}

/* Onglets (§7.4 — PAS / PS / Actes) — la grammaire de .seg, en plus large. Retour PE
   15/09 (C2) : « PAS des boutons flottants » — la coque est blanche, jamais le fond de
   page (testé), et l'onglet actif marine : le groupe se lit comme un groupe. */
.tabs{display:inline-flex;background:var(--surface);border:1px solid var(--line);
  border-radius:6px;padding:2px;margin-bottom:14px;}
.tabs button{background:none;border:none;font-size:var(--fs-12);font-weight:var(--w5);
  color:var(--muted);padding:5px 12px;line-height:1.2;border-radius:4px;cursor:pointer;transition:background .12s,color .12s;}
.tabs button[aria-selected="true"]{background:var(--marine);color:var(--surface);}
.tabs button:hover:not([aria-selected="true"]){background:var(--bg);color:var(--marine);}

/* En-tête de colonne triable (§7.3, §7.4, §7.5) */
.tablepanel th.triable{cursor:pointer;user-select:none;white-space:nowrap;}
.tablepanel th.triable:hover{color:var(--marine);}
.tablepanel th .fleche{margin-left:3px;color:var(--corail);font-size:var(--fs-10);}


/* Répartition dépliable (§7.4) */
.tablepanel td.rep{text-align:center;}
.repbtn{background:none;border:1px solid var(--line);border-radius:6px;width:26px;height:26px;
  color:var(--corail);cursor:pointer;font:inherit;line-height:1;}
.reprow td{background:var(--bg);}
.repligne{display:flex;align-items:center;gap:10px;font-size:var(--fs-12);padding:4px 0;}
.repligne .rn{font-weight:var(--w5);color:var(--marine);min-width:160px;}
.repligne .rr{color:var(--muted);font-size:var(--fs-11);}
.repligne b{margin-left:auto;}
.repsum{margin-top:6px;padding-top:6px;border-top:1px dashed var(--line);font-size:var(--fs-11);
  color:var(--muted);}

/* Pagination (règle 5) */
.pagination{display:flex;align-items:center;justify-content:center;gap:6px;padding:14px 16px;}
.pagination button{background:var(--surface);border:1px solid var(--line);border-radius:6px;
  width:30px;height:30px;cursor:pointer;font:var(--fs-12) var(--font);}
.pagination button[disabled]{opacity:.4;cursor:default;}
.pagination button[aria-current="true"]{background:var(--marine);border-color:var(--marine);color:var(--sur-marine);}
.pagination button:not([disabled]):hover{border-color:var(--corail);}
.pagination .info{font-size:var(--fs-11);color:var(--muted);margin:0 8px;}

/* Sélecteur d'indicateur (§7.6) et encart médiane */
.mediane{display:flex;align-items:center;gap:18px;background:var(--surface);border:1px solid var(--line);
  border-radius:6px;padding:14px 18px;margin-bottom:14px;flex-wrap:wrap;}
.mediane .mv{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-18);color:var(--marine);margin-left:6px;}

/* =====================================================================
   FACTURATION — étape 5 (§7.7). Bandeau informatif dans le canvas, mêmes jetons de
   couleur que .demo (§9.5) mais en bloc arrondi de page, pas en bandeau plein-large
   de la coquille : sémantiques distinctes (données de démo vs module non activé),
   déclenchées par des conditions indépendantes.
   ===================================================================== */
.avis{background:var(--corail-soft);border:1px solid var(--line);border-radius:6px;
  color:var(--corail);font-size:var(--fs-12);font-weight:var(--w5);padding:12px 18px;margin-bottom:14px;line-height:1.5;}

/* =====================================================================
   INDICATEURS — réunion du 26 (exception au gel du code, hors étapes numérotées).
   Sept statuts de faisabilité (api, registre_actif, histo, if_saisi, saisie, sans_source,
   bloque — revue du 18/09), lus dans les jetons §23 : sept couleurs DISTINCTES (écart
   minimal 18 ΔE ; --marine se confondait avec --marine-2, --rouge est réservé aux baisses)
   — un système distinct des pastilles §6 : il porte sur le CATALOGUE, pas sur un KPI.
   ===================================================================== */
.kpisynthese{margin-bottom:16px;}
.kpisynthese-compteurs{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:12px;}
.kpicompteur{background:var(--surface);border:1px solid var(--line);
  border-radius:6px;padding:10px 14px;border-top:3px solid var(--line-2);}
.kpicompteur .n{display:block;font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-20);color:var(--marine);}
.kpicompteur .lib{display:block;font-size:var(--fs-11);color:var(--muted);margin-top:2px;}
.kpicompteur.api{border-top-color:var(--vert);}
.kpicompteur.registre_actif{border-top-color:var(--ink-2);}
.kpicompteur.histo{border-top-color:var(--corail-2);}
.kpicompteur.if_saisi{border-top-color:var(--marine-2);}
.kpicompteur.saisie{border-top-color:var(--muted);}
.kpicompteur.sans_source{border-top-color:var(--serie-3);}
.kpicompteur.bloque{border-top-color:var(--corail);}

.kpisection{margin-top:22px;padding-left:14px;border-left:4px solid var(--line-2);}
.kpisection.api{border-left-color:var(--vert);}
.kpisection.registre_actif{border-left-color:var(--ink-2);}
.kpisection.histo{border-left-color:var(--corail-2);}
.kpisection.if_saisi{border-left-color:var(--marine-2);}
.kpisection.saisie{border-left-color:var(--muted);}
.kpisection.sans_source{border-left-color:var(--serie-3);}
.kpisection.bloque{border-left-color:var(--corail);}
.kpisection-tete{display:flex;align-items:baseline;gap:10px;}
.kpisection-tete .n{font-size:var(--fs-11);color:var(--muted);}
.kpisection-detail{font-size:var(--fs-11);color:var(--muted);margin-top:2px;max-width:760px;line-height:1.5;}

.kpigrille{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px;margin-top:12px;}
.kpicarte{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:12px 14px;}
.kpicarte-tete{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-bottom:4px;min-height:16px;}
.kpicarte-tete input[type="checkbox"]{margin-right:auto;width:15px;height:15px;}
.kpicarte-cat{font-size:var(--fs-10);color:var(--muted);text-transform:uppercase;letter-spacing:.04em;}
.kpicarte-lib{font-weight:var(--w5);color:var(--marine);margin-top:3px;line-height:1.3;}
.kpicarte-source{font-family:var(--mono);font-size:var(--fs-11);color:var(--corail);background:var(--bg);
  border-radius:6px;padding:4px 7px;margin-top:8px;word-break:break-word;}
.kpicarte details{margin-top:8px;}
.kpicarte summary{font-size:var(--fs-11);color:var(--muted);cursor:pointer;}
.kpicarte details p{font-size:var(--fs-11);color:var(--muted);margin-top:6px;line-height:1.5;}

/* Pastille d'état portail — même gabarit que .dispo (§6), palette propre à cet écran. */
.etatportail{display:inline-block;width:8px;height:8px;border-radius:50%;cursor:help;
  background:var(--line-2);flex:0 0 auto;}
.etatportail.affiche{background:var(--vert);}
.etatportail.extrait{background:var(--corail);}
.etatportail.absent{background:var(--line-2);}

/* Étape 9.A — légende de synthèse : explique les pastilles .etatportail des cartes ci-dessous. */
.kpilegende{display:flex;gap:16px;flex-wrap:wrap;font-size:var(--fs-11);font-weight:var(--w5);color:var(--muted);margin-bottom:12px;}
.kpilegende-item{display:flex;align-items:center;gap:6px;}
.kpilegende-item .etatportail{cursor:default;}

.kpirevue{display:flex;align-items:center;gap:12px;margin:14px 0;flex-wrap:wrap;}
.kpirevue.actif button[aria-pressed="true"]{background:var(--marine);border-color:var(--marine);color:var(--sur-marine);}
.kpirevue-compteur{font-size:var(--fs-12);color:var(--marine);font-weight:var(--w5);}
.kpirevue-copie{font-size:var(--fs-11);color:var(--muted);}

/* ---------- Carte de France — Leaflet (9-quinquies), repli SVG hérité de 9.B→9-quater ---------- */
.francemap-wrap{background:var(--surface);border:1px solid var(--line);border-radius:6px;
  padding:14px;overflow:hidden;position:relative;}

/* Leaflet — chemin principal. Hauteur FIXE obligatoire (Leaflet mesure son
   conteneur au montage, contrairement au SVG maison qui suivait un viewBox) ; le
   fond crème comble l'instant entre l'insertion et le premier rendu des tuiles.
   640px (pas 520px) : à 520px, le rail plein-largeur (~1150px) donne un cadre
   deux fois plus large que haut — trop large pour la France (bbox ≈ 1,5:1), donc
   fitBounds() (zoom entier le plus proche) retombe un cran plus bas que voulu et
   cadre toute l'Europe de l'Ouest plutôt que la métropole (constaté en direct au
   navigateur). Vérifié : 640px cadre bien la métropole entière au Siège. */
/* `position:relative` déclaré ICI : sinon Leaflet le pose EN LIGNE au montage (il ne remplace
   que `static`), et un style en ligne bat n'importe quelle feuille — le `position:fixed` du
   plein écran §25 perdait en silence. Même valeur : le bureau ne bouge pas d'un pixel. */
.leaflet-conteneur{width:100%;height:640px;border-radius:6px;background:var(--bg);position:relative;}
.francemap-repli-avis{margin:0 0 10px;font-size:var(--fs-11);color:var(--muted);}

/* Repli SVG (carteSvgFallback.js) — inchangé depuis 9-quater. Muette au repos (plus
   d'étiquette permanente) : le survol seul raconte, via le <title> natif déjà posé
   sur chaque .francemap-pt. */
.francemap{width:100%;height:auto;display:block;max-height:70vh;cursor:default;}
.francemap.zoomed{cursor:grab;}
.francemap.dragging{cursor:grabbing;}
.francemap-fond{fill:var(--bg);stroke:var(--line);stroke-width:1.5;}
.francemap-pt circle{fill:var(--corail);opacity:.75;stroke:var(--surface);stroke-width:1;
  cursor:pointer;transition:opacity .12s;}
.francemap-pt:hover circle,.francemap-pt:focus-visible circle{opacity:1;}
.francemap-pt:focus-visible{outline:none;}
.francemap-pt:focus-visible circle{stroke:var(--marine);stroke-width:2;}
.francemap-cm{fill:var(--corail);stroke:var(--surface);}

/* Bouton « vue entière » (⟲) — visuel partagé par le repli SVG ET le contrôle
   Leaflet équivalent (franceMap.js, L.Control). Le POSITIONNEMENT, lui, diffère :
   le repli SVG le place lui-même (position:absolute, enfant direct de
   .francemap-wrap, cf. le sélecteur `>` ci-dessous) ; le contrôle Leaflet vit déjà
   dans le coin que Leaflet gère (.leaflet-top.leaflet-right) — un second
   position:absolute par-dessus le placerait n'importe où, donc aucun ici. */
.francemap-reset{width:32px;height:32px;border-radius:6px;background:var(--surface);
  border:1px solid var(--line);display:flex;align-items:center;justify-content:center;
  cursor:pointer;margin:10px 10px 0 0;}
.francemap-reset:hover{background:var(--bg);}
.francemap-reset svg{width:16px;height:16px;stroke:var(--muted);fill:none;stroke-width:2;}
.francemap-wrap>.francemap-reset{position:absolute;top:24px;right:24px;margin:0;
  opacity:0;pointer-events:none;transition:opacity .15s;}
.francemap-wrap>.francemap-reset.visible{opacity:1;pointer-events:auto;}

.francemap-manquantes{margin-top:14px;padding-top:12px;border-top:1px solid var(--line);
  font-size:var(--fs-12);color:var(--muted);}
.francemap-manquantes p{font-weight:var(--w5);margin-bottom:6px;}
.francemap-manquantes ul{list-style:none;display:flex;flex-wrap:wrap;gap:6px 14px;}
.francemap-manquantes a{color:var(--corail);text-decoration:none;font-weight:var(--w5);}
.francemap-manquantes a:hover{text-decoration:underline;}

/* ---------- Étape 9.E — comparateur de Business Units ---------- */
.cmp-flottant{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:40;}
.cmp-refus{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:40;
  background:var(--marine);color:var(--sur-marine);border-radius:6px;padding:10px 18px;font-size:var(--fs-12);
  font-weight:var(--w5);}
.cmp-fond{position:fixed;inset:0;background:var(--voile);z-index:50;
  display:flex;align-items:center;justify-content:center;padding:24px;}
.cmp-modale{background:var(--surface);border-radius:8px;max-width:820px;width:100%;
  max-height:min(640px,86vh);display:flex;flex-direction:column;overflow:hidden;
  box-shadow:var(--ombre-modale);}
.cmp-tete{display:flex;align-items:center;justify-content:space-between;padding:18px 22px;
  border-bottom:1px solid var(--line);}
.cmp-fermer{background:none;border:none;font-size:var(--fs-24);line-height:1;color:var(--muted);
  cursor:pointer;padding:2px 6px;border-radius:6px;}
.cmp-fermer:hover{background:var(--bg);}
.cmp-corps{overflow:auto;padding:0 22px 22px;}
.cmp-corps table{width:100%;border-collapse:collapse;font-size:var(--fs-12);}
.cmp-corps th,.cmp-corps td{padding:9px 12px;font-size:var(--fs-12);text-align:right;border-bottom:1px solid var(--line-2);
  white-space:nowrap;}
.cmp-corps thead th{font-weight:var(--w-titre);color:var(--muted);font-size:var(--fs-10);text-transform:uppercase;letter-spacing:.06em;
  position:sticky;top:0;background:var(--surface);}
.cmp-corps tbody th{text-align:left;font-weight:var(--w5);color:var(--muted);}
.cmp-corps td.gagnant{font-weight:var(--w5);color:var(--marine);}
.cmp-corps td .pt{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--corail);
  margin-right:6px;vertical-align:middle;}
/* B6 (étape 16) — mode « additionner » : colonne Total distincte de .gagnant (qui
   signale la meilleure valeur PAR LIGNE, jamais une somme) ; .cmp-inerte marque les
   deux lignes qui ne s'additionnent pas (variation, taux), cellule Total tenue à part. */
.cmp-corps th.cmp-total-col,.cmp-corps td.cmp-total-col{font-weight:var(--w6);color:var(--marine);
  background:var(--bg);}
.cmp-corps td.cmp-inerte{color:var(--muted);font-style:italic;font-weight:var(--w4);}
.cmp-note{margin-top:10px;font-size:var(--fs-12);color:var(--muted);}

/* Étape 9-ter.C — modale d'export : même grammaire de modale que ci-dessus
   (.cmp-fond/.cmp-modale/.cmp-tete/.cmp-fermer/.cmp-corps, réutilisées telles
   quelles), gabarit propre au contenu (liste de cases, pas un tableau). */
.exp-modale{max-width:420px;max-height:none;}
.exp-corps{padding:0 22px 22px;overflow:visible;}
.exp-contexte{font-size:var(--fs-12);color:var(--muted);margin:2px 0 16px;}
.exp-liste{display:flex;flex-direction:column;gap:1px;margin-bottom:18px;}
.exp-item{display:flex;align-items:center;gap:10px;padding:9px 6px;
  cursor:pointer;border-radius:6px;}
.exp-item:hover{background:var(--bg);}
.exp-item input{width:16px;height:16px;cursor:pointer;flex:0 0 auto;}
.exp-pied{display:flex;justify-content:flex-end;}

/* Modale d'agrandissement (B1) : grammaire .cmp, gabarit .gr ; le graphe agrandi est refait par
   le code de la vignette, ces règles ne lui donnent que de la place. */
.gr-corps{padding:4px 26px 26px;}
.gr-sous{padding:0 22px 8px;font-size:var(--fs-12);color:var(--muted);}
/* v1.8.1 : 374 = 360 + 14 (réserve haute) ; 449 = 420 × 139/130 (HAUTEUR_LIGNE). */
.gr-corps .bars{height:374px;}
.gr-corps .cycles-grid{gap:28px;}
/* Retour PE 15/09 (B1) — « une modale PROPRE À CE GRAPHIQUE, avec un axe des X et un
   axe des Y bien lisibles » : chaque vignette de Cycles ouvre désormais la sienne, donc
   la modale ne contient qu'UN graphe et peut lui donner toute la place. */
.gr-corps .ligne-cycle{max-height:452px;}
/* Étape 17 (C0) — « l'icône ⤢ disparaît : c'est le GRAPHE LUI-MÊME qui s'agrandit au
   clic ». Remplace .agrandir-btn : plus de bouton séparé, le corps du panneau entier
   (`agrandirAuClic`, modaleAgrandir.js) devient la cible. Halo léger au survol/focus
   seulement — jamais au survol d'une barre précise, qui reste le territoire de son
   infobulle (`title`, natif, indépendant de ce halo). */
.graphe-agrandissable{cursor:zoom-in;border-radius:6px;position:relative;}
.graphe-agrandissable:hover{outline:1px solid var(--line);outline-offset:2px;}
/* Retour PE 15/09 (B1) — l'icône ⤢ revient, en haut à droite de CHAQUE vignette. Elle
   est TOUJOURS visible (pas seulement au survol) : son rôle est justement de dire, sans
   qu'on ait à essayer, que ce graphe s'agrandit. Discrète au repos, franche au survol. */
.gr-loupe{position:absolute;top:2px;right:2px;z-index:3;display:inline-flex;align-items:center;
  justify-content:center;width:26px;height:26px;padding:0;border-radius:6px;cursor:zoom-in;
  background:var(--surface);border:1px solid var(--line);color:var(--muted);opacity:.75;
  transition:opacity .15s,color .15s,border-color .15s;}
.gr-loupe:hover,.gr-loupe:focus-visible{opacity:1;color:var(--marine);border-color:var(--corail);}
.gr-loupe:focus-visible{outline:2px solid var(--corail);outline-offset:1px;}
.gr-loupe-icone{width:13px;height:13px;display:block;}
/* Dans la modale, le corps est déjà agrandi : une seconde loupe n'y mènerait nulle part. */
.gr-corps .gr-loupe{display:none;}

/* Retour PE 15/09 (B3) — ce que la modale « CA réalisé » apporte EN PLUS de la
   vignette : deux onglets et leurs tableaux. Grammaire déjà en place (.tabs,
   .tablepanel, .delta) — aucun second jeu de styles pour un contenu de modale. */
.gr-onglets{margin-top:22px;border-top:1px solid var(--line);padding-top:16px;}
.gr-detail .tablepanel{margin-top:0;}
.tablepanel tr.fort>*{font-weight:var(--w6);color:var(--marine);background:var(--bg);}
.tablepanel .gr-autres>*{color:var(--muted);}
.gr-detail .sub{margin-top:10px;}

/* Éditeur de coefficients (13b) — grammaire existante : .panel, .creme, .realise. */
.coef-grille{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px;}
.coef-famille{background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:10px 12px;}
.coef-titre{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--fs-11);font-weight:var(--w5);
  text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:8px;}
.coef-titre b{font-size:var(--fs-16);color:var(--marine);letter-spacing:0;}
.coef-champ{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px;font-size:var(--fs-12);}
.coef-champ input{width:78px;font-size:var(--fs-12);text-align:right;color:var(--marine);}
.coef-avert{background:var(--corail-soft);border:1px solid var(--corail);border-radius:6px;padding:8px 11px;
  font-size:var(--fs-11);margin-bottom:12px;}
.coef-resultat,.coef-actions{margin-top:12px;}
.coef-msg{margin-top:10px;font-size:var(--fs-12);font-weight:var(--w5);color:var(--vert);}
.coef-msg.err{color:var(--corail);}
.coef-actions{display:flex;gap:10px;}
/* Boutons : la base est celle de .topbtn (§1). Le corail en fond, pour la seule action qui
   enregistre un formulaire (Enregistrer, Garder, Appliquer) ; « Télécharger » reste marine. */
.sim-actions .primaire,.aff-pied .primaire,.coef-editeur .primaire,.qs-form [type=submit],.devlog form [type=submit]{background:var(--corail-fond);border-color:var(--corail-fond);}

/* ---------- Messagerie contextuelle (étape 15, SPEC §16) ---------- */

/* Icône « Signaler » + marqueur — cartes KPI, lignes de classement/liste/projection/rapprochement. */
.signal-cellule{display:inline-flex;align-items:center;gap:4px;margin-left:6px;vertical-align:middle;}
/* Retour PE 09/09 (B7, étape 16) — masquée par défaut, visible seulement en « mode
   signalement » (classe posée sur <body>, shell.js) : jamais le marqueur `.corail`
   juste en dessous, qui reste un signal d'INFORMATION (fil déjà ouvert), pas l'action
   « Signaler » elle-même — les deux vivent dans le même `.signal-cellule` mais n'ont
   pas la même règle de visibilité. */
.signaler{display:none;background:none;border:none;padding:2px;cursor:pointer;color:var(--muted);
  border-radius:4px;}
body.mode-signalement .signaler{display:inline-flex;}
.signaler:hover,.signaler:focus-visible{color:var(--corail);background:var(--bg);}
.marqueur.corail{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--corail);cursor:pointer;}

/* « Voir le chiffre » (ancre.js) — la carte visée est DÉSIGNÉE 2 s (durée tenue par ancre.js).
   C'était une ombre portée : le §23 les a retirées des panneaux et la règle ne faisait plus
   rien, la page défilait jusqu'à la bonne carte sans que rien ne la montre. Un contour ne
   dépend d'aucune ombre ; sans transition (§25 §4 borne les animations à 200 ms). */
.card.mis-en-evidence{outline:2px solid var(--corail);outline-offset:2px;}

/* §25 §4 — une note qui EXPLIQUE un chiffre est un bouton, pas une infobulle : au doigt, un
   `title` ne se déclenche jamais. L'encre ne bouge pas (pastille de 6 px, astérisque). */
.note-btn{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:help;}
.cmp-modale.note-feuille{max-width:420px;}

/* Panneau « Signaler » — grammaire .cmp-*, ancré à droite (`:has()` isole la variante). */
.cmp-fond:has(.msg-panel){justify-content:flex-end;padding:0;}
.msg-panel{width:420px;max-width:92vw;height:100%;max-height:100%;border-radius:0;}
.msg-chip{display:inline-block;background:var(--bg);border:1px solid var(--line);
  border-radius:6px;padding:7px 11px;font-size:var(--fs-12);font-weight:var(--w5);color:var(--marine);
  margin:16px 0 12px;}
.msg-existant{font-size:var(--fs-12);color:var(--muted);background:var(--corail-soft);border:1px solid var(--corail);
  border-radius:6px;padding:8px 11px;margin-bottom:12px;}
.msg-texte{width:100%;min-height:70px;resize:vertical;}
.msg-erreur{font-size:var(--fs-12);color:var(--corail);font-weight:var(--w5);min-height:15px;margin:6px 0 0;}
.msg-pied{display:flex;justify-content:flex-end;margin-top:8px;}

/* Panneau « Alertes » (topbar) — retouches préprod du 12/09 (B3). Même grammaire de
   ligne que .msg-ligne un peu plus bas, colonne de valeur alignée à droite. */
.alertes-corps{padding-top:8px;}
.alertes-liste{display:flex;flex-direction:column;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:6px;overflow:hidden;list-style:none;margin:0;padding:0;}
.alertes-ligne{display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:var(--surface);padding:13px 14px;text-decoration:none;}
.alertes-ligne:hover{background:var(--bg);}
/* §24 v3 : une ligne « changement à valider » empile champ, instant, vente et lien. */
.alertes-libelle{color:var(--marine);display:grid;gap:2px;justify-items:start;}
.alertes-valeur{font-weight:var(--w5);color:var(--corail);flex:0 0 auto;}
.alertes-vide{font-size:var(--fs-12);color:var(--muted);padding:6px 2px;}

/* Boîte de réception (pages/messagerie.js). */
.msg-page .msg-filtres{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:14px;}
.msg-checkbox{display:flex;align-items:center;gap:6px;font-size:var(--fs-12);color:var(--muted);cursor:pointer;}
.msg-checkbox input{cursor:pointer;}
.msg-recherche{font-size:var(--fs-12);min-width:200px;}
.msg-corps-page{display:grid;grid-template-columns:minmax(280px,380px) 1fr;gap:18px;align-items:start;}
.msg-liste{display:flex;flex-direction:column;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:6px;overflow:hidden;}
.msg-ligne{background:var(--surface);padding:12px 14px;cursor:pointer;}
.msg-ligne:hover{background:var(--bg);}
.msg-ligne-tete{display:flex;justify-content:space-between;align-items:center;gap:8px;}
.msg-ligne .msg-chip{margin:0;padding:3px 8px;font-size:var(--fs-10);font-weight:var(--w5);
  text-transform:uppercase;letter-spacing:.03em;}
.msg-titre{color:var(--marine);margin-top:6px;}
.msg-ligne.non-lu .msg-titre{font-weight:var(--w6);}
.msg-apercu{font-size:var(--fs-12);color:var(--muted);margin-top:3px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.msg-quand{font-size:var(--fs-10);color:var(--muted);margin-top:5px;}

/* Fil ouvert — conversation. */
.msg-fil{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:18px;}
.msg-fil-tete{display:flex;flex-direction:column;gap:8px;margin-bottom:14px;
  padding-bottom:12px;border-bottom:1px solid var(--line);}
.msg-fil-actions{display:flex;gap:8px;}
.lien-retour{background:none;border:none;color:var(--corail);font-size:var(--fs-12);font-weight:var(--w5);
  cursor:pointer;padding:0;align-self:flex-start;}
.msg-conversation{display:flex;flex-direction:column;gap:12px;max-height:420px;overflow:auto;}
.msg-message{background:var(--bg);border-radius:6px;padding:9px 12px;}
.msg-message.supprime{color:var(--ink-2);font-style:italic;}
.msg-message-tete{display:flex;justify-content:space-between;font-size:var(--fs-11);
  color:var(--muted);font-weight:var(--w5);margin-bottom:4px;}
.msg-message-texte{white-space:pre-wrap;overflow-wrap:anywhere;}
.msg-repondre{margin-top:14px;padding-top:14px;border-top:1px solid var(--line);}

/* =====================================================================
   Étape 17 (C2) — « Depuis votre dernière visite »
   ===================================================================== */

/* Ligne discrète, en tête du canvas (juste sous le titre porté par la coquille) :
   le ton d'une annotation, jamais d'une alerte — c'est un « ce qui a bougé », pas
   un signal d'action (ceux-là ont leur propre bandeau corail, .signals). */
.depuis-visite{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px;
  margin-bottom:14px;font-size:var(--fs-12);color:var(--muted);}
.depuis-visite .dv-lib{font-weight:var(--w5);}
.depuis-visite .dv-faits{color:var(--marine);font-weight:var(--w5);}

/* Puce d'une Business Unit dans le classement : posée après le nom, assez légère
   pour ne pas concurrencer la valeur de la ligne. */
.puce-visite{margin-left:8px;padding:1px 7px;border-radius:4px;
  background:var(--corail-soft);color:var(--corail);
  font-size:var(--fs-10);font-weight:var(--w5);white-space:nowrap;vertical-align:middle;}

/* « Apparition douce au chargement (fondu 400 ms, une fois, pas d'animation
   permanente) » : une seule passe, `both` pour que l'état final persiste. Aucune
   boucle — rien ne continue de bouger une fois la page lue. */
@keyframes puce-visite-apparition{from{opacity:0;}to{opacity:1;}}
.puce-visite{animation:puce-visite-apparition 400ms ease-out both;}

/* Respect de prefers-reduced-motion : la puce reste, seule l'animation disparaît —
   l'information n'est jamais la récompense d'un mouvement. */
@media (prefers-reduced-motion:reduce){
  .puce-visite{animation:none;}
  .graphe-agrandissable{transition:none;}
}

/* LA MENTION PASSE AU SURVOL (décision de Fred, 03/10) — elle n'est plus un bloc permanent.
   CE QU'ELLE NE FAIT PLUS : changer la hauteur d'une carte. Posée en flux, elle allongeait la
   carte qui la portait et la rangée perdait son alignement ; c'est ce désalignement, avec le
   corail, qui s'est lu comme « le design a été perdu ». L'infobulle est donc ABSOLUE, hors du
   flux : une carte a la même hauteur avec et sans mention, et la règle du 03/10 — une mention ne
   change jamais fond, bordure ni hauteur — est tenue par le dessin lui-même, pas par une
   vigilance.
   L'ASTÉRISQUE, LUI, RESTE TOUJOURS VISIBLE : il porte la règle du 25/09 (« une somme partielle
   n'est jamais présentée comme complète »), et seul son TEXTE passe au survol. */
/* PLUS DE `position:relative` AU SURVOL (04/10) : la bulle est fixe dans la fenêtre, la carte n'a plus à être son
   bloc conteneur — et elle reste statique, donc son texte garde le rendu sous-pixel (la garde visuelle l'a payé). */
/* LA CARTE DEVIENT ATTEIGNABLE AU CLAVIER (`tabindex="0"`) : sans cette règle, le navigateur y
   pose SON anneau — un trait noir épais qui n'est pas celui de la charte. Même anneau que les
   lignes de tableau navigables, qui sont le même geste : un conteneur qu'on atteint au clavier. */
.card:focus-visible{outline:2px solid var(--corail);outline-offset:-2px;}
/* LARGEUR ET POSITION HORIZONTALE VIENNENT DE JS (kpiRow.js, `positionnerBulle`) : une carte
   du tableau de bord ne mesure jamais 260 px (175 à 194 px mesurés le 03/10), `left`/`right`
   en dur seraient donc TOUJOURS sur-contraints et le résultat dépendrait d'un comportement de
   résolution que la charte n'a pas à connaître. `left:12px` et `min-width` restent un REPLI —
   la valeur d'avant ce lot — pour tout chemin qui ouvrirait la bulle sans passer par le JS. */
/* FIXE dans la fenêtre (04/10) : un tableau qui défile (`.tp-defile`) ne rogne plus la bulle ; largeur,
   gauche et haut sont posés par noteFeuille.js (`positionnerBulle`) — 260 à 320 px, retournée en haut
   si le bas manque. `max-width` ici est le filet si le JS n'a pas encore parlé. */
.note-bulle{position:fixed;max-width:320px;z-index:60;
  padding:6px 8px;border:1px solid var(--line);border-radius:6px;background:var(--surface);
  box-shadow:var(--ombre-modale);font-size:var(--fs-12);font-weight:var(--w5);color:var(--ink-2);
  text-align:left;white-space:normal;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .12s ease;}
/* Au survol de la CARTE comme de l'astérisque (§2 de la spec), au clavier (`:focus-visible` sur
   le bouton, `:focus-within` sur la carte), et au TOUCHER — `.ouverte`, posée par JS au tap,
   fermée par un tap ailleurs ou par Échap (noteFeuille.js, `basculerBulle`). */
/* SURVOL OU FOCUS DE LA CARTE : sa propre bulle (`>`) et celle de sa mention (`.mc`) — pas toutes celles de ses boutons, qui
   se recouvraient (04/10 : « — » et « 2025 : — » d'une carte pilote). Chaque bouton montre la sienne, au survol comme au focus. */
.card:is(:hover,:focus-within)>.note-bulle,.card:is(:hover,:focus-within) .mc,.note-btn:is(:hover,:focus-visible)>.note-bulle,
.note-bulle.ouverte{opacity:1;visibility:visible;pointer-events:auto;}
/* Échap pendant que le pointeur reste sur la carte : la bulle se ferme malgré :hover (WCAG 1.4.13). État posé
   par JS (noteFeuille.js, echapFermeLesBulles) et retiré au départ du pointeur ; règle placée APRÈS :hover. */
.card[data-bulle-fermee] .note-bulle,.note-btn[data-bulle-fermee] .note-bulle{opacity:0;visibility:hidden;pointer-events:none;}
/* Le mouvement n'est jamais ce qui porte l'information (cf. prefers-reduced-motion plus haut). */
@media (prefers-reduced-motion:reduce){.note-bulle{transition:none;}}

/* Retouche de passe finale (étape 17) — Business Unit navigable depuis le donut.
   Même grammaire que le seul autre SVG navigable du portail (`.francemap-pt`) : le
   curseur et le halo portent sur l'élément interne, le focus reste visible au clavier. */
.donut-secteur{cursor:pointer;}
.donut-secteur:hover circle,.donut-secteur:focus-visible circle{stroke-width:11;}
.donut-secteur:focus-visible{outline:none;}
.dleg .row.navigable{cursor:pointer;border-radius:6px;padding:1px 4px;margin:0 -4px;}
.dleg .row.navigable:hover,.dleg .row.navigable:focus-visible{background:var(--bg);outline:none;}
.dleg .row.navigable:focus-visible{outline:1px solid var(--corail);outline-offset:1px;}

/* Fond Plan IGN (14/09/2026) — sobriété du calque de tuiles.
   Le Plan IGN est un plan RICHE (routes colorées, bâti, toponymie dense) : tel quel,
   il concurrence les marqueurs corail et les rend difficiles à suivre. On le
   désature et on l'éclaircit pour qu'il redevienne un FOND — la France reste lisible,
   les données passent devant. Réglage porté sur `.leaflet-tile-pane` seul : ni les
   marqueurs, ni les infobulles, ni le contrôle d'attribution ne vivent dans ce calque,
   ils gardent donc leurs couleurs pleines. */
.leaflet-tile-pane{filter:grayscale(1) contrast(.9) opacity(.55);}
/* `filter` sur un parent crée un contexte d'empilement : sans ce rappel, un navigateur
   peut réordonner les calques et faire passer les tuiles devant les marqueurs. */
.leaflet-marker-pane,.leaflet-overlay-pane,.leaflet-tooltip-pane,.leaflet-popup-pane{filter:none;}

/* ---------- Simulateur de projection (étape 19, volet 2) ----------
   Reprend la grammaire du dépôt plutôt que celle de la maquette : `.panel`, `.sub`,
   `.coef-actions`, `.graphe-agrandissable` et `.gr-loupe` existent déjà et portent
   halo, curseur loupe et icône ⤢ — la maquette les redessinait faute de les avoir. */
.simulateur{display:flex;flex-direction:column;gap:14px;}
.scen-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;}
.scen{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:13px 15px;
  cursor:pointer;position:relative;transition:border-color .12s,box-shadow .12s;}
.scen:hover{border-color:var(--corail);}
.scen[aria-selected="true"]{border-color:var(--corail);box-shadow:inset 0 0 0 1px var(--corail);}
.scen-tete{display:flex;align-items:center;gap:6px;margin-bottom:6px;}
.scen-nom{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:var(--w5);color:var(--marine);}
.scen-jeton{font-size:var(--fs-10);font-weight:var(--w5);color:var(--marine);background:var(--bg);
  border:1px solid var(--line);border-radius:999px;padding:2px 8px;white-space:nowrap;}
.scen-jeton.fin{color:var(--muted);background:transparent;}
/* Le brouillon (passe du 16/09) : une colonne qui n'existe pas en base le DIT — trait
   discontinu, comme la courbe pointillée dit « ceci est un calcul, pas un relevé ». */
.scen-brouillon{border-style:dashed;}
.sim-depuis{margin:-8px 0 12px;}
/* Les trois boutons sur UNE ligne, quelle que soit la largeur de la boîte : sans
   `nowrap`, « Revenir au classeur » se coupait en deux et emportait sa rangée. */
.sim-actions{flex-wrap:nowrap;}
.sim-actions button{white-space:nowrap;}
.scen-x{border:0;background:transparent;color:var(--muted);font:inherit;font-size:var(--fs-16);line-height:1;
  cursor:pointer;padding:0 3px;border-radius:6px;}
.scen-x:hover{color:var(--corail);background:var(--bg);}
.scen-gros{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-24);color:var(--marine);}
.scen-ecart{font-size:var(--fs-11);font-weight:var(--w5);color:var(--muted);}

.sim-grille{display:grid;grid-template-columns:minmax(0,360px) minmax(0,1fr);gap:14px;}
@media(max-width:860px){.sim-grille{grid-template-columns:minmax(0,1fr);}}
/* La zone porte le halo et la loupe ; son contenu garde le fond blanc du panneau. */
.sim-zone{display:block;}
.sim-boite,.sim-atterrissage{background:var(--surface);border:1px solid var(--line);
  border-radius:6px;padding:16px 18px;height:100%;}
.sim-loupe{border:0;background:transparent;font-size:var(--fs-16);line-height:1;width:auto;height:auto;}
.sim-regime{margin:4px 0 14px;}
.sim-curseurs{display:grid;gap:14px;}
.cur{display:grid;grid-template-columns:1fr auto;gap:2px 12px;align-items:center;}
.cur label{font-size:var(--fs-12);font-weight:var(--w5);}
.cur .cur-val{font-weight:var(--w5);color:var(--corail);
  text-align:right;min-width:4.5ch;}
.cur small{grid-column:1/3;color:var(--muted);font-size:var(--fs-11);}
.cur input[type="range"]{grid-column:1/3;width:100%;margin:4px 0 0;}
.sim-gros{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-30);color:var(--marine);
  line-height:1.05;margin:2px 0 4px;}
.sim-ecart{font-weight:var(--w5);color:var(--muted);}
.scen-ecart.up,.sim-ecart.up,.tablepanel td.up{color:var(--vert);}.scen-ecart.down,.sim-ecart.down,.tablepanel td.down{color:var(--corail);}
.sim-split{display:flex;gap:18px;margin-top:10px;font-size:var(--fs-12);color:var(--muted);flex-wrap:wrap;}
.sim-split b{color:var(--marine);}
/* Étape 19 (volet 3) — la part PROJETÉE de la trajectoire : un fond, pas un calque.
   La courbe seule ne dit pas où le relevé s'arrête et où le calcul commence. */
.ligne-projete{fill:var(--corail-soft);}
.sim-note-fine{margin-top:6px;}

/* ---------- Modale d'affinage (étape 19, volet 3) ----------
   Grammaire `.cmp-*` du portail, trois ajouts seulement : un pied (les modales
   existantes n'en avaient pas), la cellule réglable et le pli du mode expert. */
.aff-modale{max-width:980px;}
.aff-modale .tabs{margin:14px 22px 0;}
.aff-corps{padding-top:14px;}
.aff-corps>.sub{margin-bottom:12px;}
.aff-regle{max-width:78ch;}
.aff-table{margin:0;}
.rap-table th[scope="row"],.aff-table th[scope="row"]{color:var(--marine);}
/* La cellule réglable : curseur au-dessus, valeur et « annuel » dessous, sur une
   colonne étroite — la table en porte quatre et doit rester lisible. */
.aff-table td input[type="range"]{width:110px;
  display:block;margin:0 0 2px;}
.aff-v{font-weight:var(--w5);color:var(--muted);}
.aff-v.reglee{color:var(--corail);font-weight:var(--w5);}
.aff-annuel{border:0;background:transparent;font:inherit;font-size:var(--fs-11);color:var(--corail);
  text-decoration:underline;cursor:pointer;padding:0 0 0 6px;}
.aff-annuel:hover{color:var(--marine);}
.aff-deplier{border:0;background:transparent;font:inherit;font-weight:var(--w5);color:var(--marine);
  cursor:pointer;padding:0;}
.aff-autres th{background:var(--bg);}
.aff-expert{margin-top:18px;border-top:1px solid var(--line);padding-top:12px;}
.aff-expert summary{font-size:var(--fs-12);font-weight:var(--w5);color:var(--marine);cursor:pointer;}
.aff-expert .sub{margin:6px 0 12px;max-width:78ch;}
.cmp-pied{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;
  flex-wrap:wrap;padding:14px 22px;border-top:1px solid var(--line);background:var(--bg);}
.cmp-pied .coef-actions{margin:0;}
.aff-gros{font-weight:var(--w5);letter-spacing:var(--ls-chiffres);font-size:var(--fs-30);color:var(--marine);
  line-height:1.05;}
.aff-note{max-width:52ch;margin-top:6px;}

/* ---------- Rapport de projection (étape 19, volet 4) ----------
   Réutilise `.cmp-*`, `.gr-corps` (hauteurs de graphe en modale) et `.tablepanel`.
   Cinq règles seulement : le gabarit large, la remise à gauche des libellés (voir
   ci-dessous), le signe de la décomposition, la ligne fille et la ligne de somme. */
.rap-modale{max-width:1080px;}
.rap-modale .tabs{margin:14px 22px 0;}
.rap-signe{display:inline-block;width:1.4em;color:var(--muted);}
.rap-somme th[scope="row"]{color:var(--corail);}
.rap-fille th[scope="row"]{padding-left:34px;color:var(--muted);}
.rap-projete th[scope="row"]{color:var(--corail);}
.rap-note-bas{max-width:88ch;margin-top:10px;}

/* ---------- Qualité de saisie (étape 20) ----------
   Reprend `.panel`, `.tablepanel`, `.tabs` et `.seg`. Quatre familles neuves : la
   phrase du bandeau, la barre de remplissage, les mots « non mesuré / à qualifier »
   (qui ne sont PAS des zéros et ne doivent pas leur ressembler), et la pastille de
   criticité. */
.qs-bandeau{padding:16px 18px;}
.qs-phrase{font-size:var(--fs-16);color:var(--marine);line-height:1.5;margin:0;}
.qs-fort{color:var(--corail);}
.qs-bloques{margin-top:8px;}
.qs-periode,.qs-source{margin:0 0 10px;}
.qs-filtre{margin-left:auto;}
.rap-note,.qs-note{display:block;color:var(--muted);font-size:var(--fs-10);}
.qs-ligne{cursor:pointer;}
.qs-ligne:hover th[scope="row"],.qs-active th[scope="row"]{color:var(--corail);}
.qs-barre{display:inline-grid;grid-template-columns:110px auto;align-items:center;gap:8px;}
.qs-barre::before{content:'';grid-area:1/1;height:3px;border-radius:2px;background:var(--line);}
.qs-barre i{grid-area:1/1;height:3px;border-radius:2px;background:var(--corail);min-width:2px;}
.qs-barre b{font-size:var(--fs-11);white-space:nowrap;}
/* « non mesuré » et « à qualifier » : en creux, jamais en rouge — ce ne sont pas des
   mauvaises notes, ce sont des absences de note. */
.qs-nm{color:var(--muted);font-style:italic;font-size:var(--fs-11);}
.qs-crit{font-size:var(--fs-10);font-weight:var(--w5);border-radius:4px;padding:2px 6px;
  border:1px solid var(--line);text-transform:capitalize;}
.qs-crit.bloquant{color:var(--corail);border-color:var(--corail);}
/* Écran 2026 — « à qualifier » n'est ni un défaut avéré ni un champ qu'on tait : le sable
   la distingue du corail (bloquant) sans la ranger avec les mentions en creux. */
.qs-crit.a_qualifier{color:var(--sable);border-color:var(--sable);}
/* La ligne d'un STADE (promesse, acte, mandat) : un intertitre dans le tableau, pas une
   donnée. Son fond le détache des champs qu'elle coiffe ; son motif, quand tout le stade le
   partage, se lit sous son titre plutôt que répété sous chaque ligne. */
.qs-stade th{background:var(--line-2);font-weight:var(--w-titre);}
.qs-stade small{display:block;font-weight:var(--w4);}
/* Le motif d'un champ non mesuré appartient à la ligne du dessus : pas de filet entre eux. */
.qs-motif td{border-top:0;padding-top:0;}
.qs-orphelins summary{font-size:var(--fs-11);color:var(--muted);cursor:pointer;}
.qs-liste-orphelins{margin:8px 0 0 18px;font-size:var(--fs-11);color:var(--muted);}
.qs-repartition,.qs-objets,.qs-guide{margin-top:14px;}
/* Volet 3 — la liste, le guide, la descente. La ligne « hors répartition » est en
   creux : elle n'est le périmètre de personne, elle ne se clique pas. */
/* `tbody th.nd` : une réf. absente perdait le muted contre `.tablepanel tbody th`. */
.tablepanel .qs-hors>*,.nd,.tablepanel td.nd *,.tablepanel tbody th.nd{color:var(--muted);font-style:italic;}
.qs-remonter{background:none;border:0;padding:0;color:var(--corail);font:inherit;cursor:pointer;}
/* .qs-export retirée le 22/09 avec le bouton « Exporter la liste (CSV) » (point 3). */
.qs-guide-texte{white-space:pre-line;margin:0 0 8px;line-height:1.5;}
.qs-capture{display:block;max-width:100%;border:1px solid var(--line);border-radius:6px;margin-top:8px;}
.qs-form{display:grid;gap:6px;max-width:70ch;}
.qs-form label{font-size:var(--fs-11);font-weight:var(--w5);color:var(--marine);margin-top:6px;}
.qs-actions{display:flex;gap:8px;margin-top:8px;}
.qs-suite{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:10px;}
.qs-suite .sub{margin:0;}
/* Étape 21 — sans sélecteur d'unité, les contrôles d'une modale agrandie restent contre
   son titre, la croix à droite. */
.cmp-tete h2+.panel-controles{margin:0 auto 0 14px;}

/* Le focus au clavier, une fois pour toutes (§23) : un anneau corail pour tout ce qui se clique
   (boutons, sélecteurs, plis, cases, curseurs) — regroupé ici, jamais répété sur chaque règle. */
.nav a:focus-visible,
button:focus-visible,
select:focus-visible,
summary:focus-visible,
[type=checkbox]:focus-visible,
[type=range]:focus-visible,
.topbtn:focus-visible,
.marqueur.corail:focus-visible,
.graphe-agrandissable:focus-visible,
.sim-zone:focus-visible,
.bu-negl:focus-visible,
.scen:focus-visible{outline:2px solid var(--corail);outline-offset:2px;}
/* Un champ de saisie : son filet passe au corail, avec un halo --corail-soft (§2, Formulaires).
   §24 : DESCENDANT, pas `>` — les champs chiffrés de l'édition vivent dans des tableaux. */
.coef-champ input:focus-visible,.msg-recherche:focus-visible,.msg-texte:focus-visible,.qs-form :is(input,textarea,select):focus-visible,.devlog input:focus-visible,.recherche:focus-within{outline:1px solid var(--corail);outline-offset:-1px;box-shadow:0 0 0 3px var(--corail-soft);}

body:has(.cmp-flottant) .canvas{padding-bottom:84px;}

/* Étape 23, volet 5 — MOBILE. En FIN de feuille : le bloc mobile du rail, plus haut, perd
 contre les composants. §25 — borne portée de 599 à 767 px (le point de bascule du portail) :
 entre 600 et 767, mesuré, aucun bloc ne s'appliquait — titre cassé à côté de ses contrôles,
 champs à 12,5 px donc zoom iOS. La condition exacte est tenue par le test d'hygiène.
 Depuis le 22/09, ce bloc ne décrit plus qu'un des DEUX modèles de défilement : les cartes
 qui n'ont pas de cadre `.tp-defile` (voir plus haut). */
@media (max-width:900px){
.msg-page .msg-corps-page{grid-template-columns:minmax(0,1fr);}
.msg-corps-page:has(.msg-fil) .msg-liste-enveloppe{display:none;}
.nav{scroll-padding-inline:10px;}
.nav a.active{scroll-initial-target:nearest;scroll-snap-align:end;}
}
@media (max-width:767px), (pointer:coarse) and (max-height:500px){
.reglages .seg button{min-width:24px;min-height:24px;}
.pill select,.recherche input{align-self:stretch;}
.panel-tete,.panel-controles,.cmp-tete{flex-wrap:wrap;}
.panel-tete h3{flex-basis:auto;}
.cmp-tete h2{flex:1;}
.cmp-tete h2+.panel-controles{order:1;flex-basis:100%;margin:10px 0 0;}
.cmp-tete>.panel-controles:first-child{flex:1;min-width:0;}
.cmp-fond{padding:8px;}
.cmp-corps .tablepanel{min-width:min-content;}
.cmp-pied button{height:auto;min-height:30px;}
.tabs{flex-wrap:wrap;}
.tabs button{white-space:nowrap;}
.canvas{padding:16px 16px 24px;}
.panel{padding:12px;}
.bars{column-gap:2px;}
.bars .bars-grille-val{z-index:1;}
.card .delta{flex-wrap:wrap;}
.card .delta-base{white-space:nowrap;}
.realise{grid-template-columns:repeat(auto-fit,minmax(90px,1fr));}
.sim-actions{flex-wrap:wrap;}
:has(>.bars){overflow-x:auto;}
.graphe-agrandissable .bars{margin-top:10px;}
.donut-wrap{flex-wrap:wrap;}
.realise .rstat .rv small{display:block;margin:0;}
.canvas td.r,.canvas td:has(>.rank),.chip{white-space:nowrap;}
.canvas .tablepanel>:not(table){position:sticky;left:0;}
.pagebar .out{position:relative;}
.out .colonnes-bu{position:static;}
.out .colonnes-bu-menu{top:auto;left:auto;right:0;margin-top:6px;}
.sim-actions button{padding:0 8px;}
.leaflet-conteneur{height:420px;}
#portail>.devlog{margin:16px max(16px,calc(50% - 260px));}
#portail>.etat{margin:16px;}
/* iOS agrandit la page quand on touche un champ écrit sous 16 px : en mobile seulement, les
 champs passent à 16 px (bureau inchangé). Les cases, boutons radio et curseurs n'ont pas de texte. */
input:not([type=checkbox]):not([type=radio]):not([type=range]),select,textarea,.pill select,.qs-form select,.qs-form textarea,.msg-texte{font-size:var(--fs-16);}
}
.note-sobre{font-size:var(--fs-13);color:var(--muted);margin:0 0 12px}

