/*
 * apps/_shared/static/css/page.css
 * --------------------------------
 * LE SYSTÈME DE PAGE COMMUN À TOUTES LES MARQUES : les BLOCS d'une page,
 * au-dessus des pièces de `composants.css` (bouton, carte, tableau, tuile).
 *
 *   m-page        la page elle-même : sa marge sous l'en-tête, son rythme
 *   m-flux        la colonne de contenu à côté d'un sommaire, au même rythme
 *   m-tete        le haut de page : surtitre, titre, chapeau, repères, états
 *   m-etat        une pastille d'état (« En liquidation », « Vacant »)
 *   m-section     une section : son titre, son intro, son contenu
 *   m-chiffres    la rangée de chiffres clés (tuiles `m-stat` du socle)
 *   m-encadre     un encadré dans la page : alerte, attention, information
 *   m-graph       les graphiques (barres, courbes, répartition, annotations)
 *   m-grille      une grille de cartes ou d'encadrés, à colonnes égales
 *   m-actions     une rangée de boutons (`m-bouton` du socle)
 *   m-lecture     la colonne de lecture d'un texte
 *   m-note        un texte secondaire (source, date, précision)
 *
 * 🚨 POURQUOI (10/11/2026, Benjamin : « y'a pas deux pages ou modules qui
 * sont faits de la même façon, c'est zéro système graphique »). MESURÉ sur
 * les gabarits Zero Bullshit ce jour-là : 6 styles de titre de page, 9 de
 * titre de section, 5 gris de texte secondaire, 80 couleurs et 63 tailles de
 * texte écrites à la main, 3 rangées de chiffres et 3 graphiques en barres
 * construits chacun autrement, 4 navigations de rubrique différentes. Le
 * cadre unique (11/10/2026) avait rendu commun l'en-tête et le pied, le lot 5
 * (12/10/2026) les pièces ; rien ne disait à quoi ressemble une PAGE.
 *
 * LES RÈGLES QUE CETTE FEUILLE PORTE, et qu'aucune page ne réécrit :
 * - un seul titre de page, un seul titre de section, un seul intertitre ;
 * - un seul gris de texte secondaire, `--marque-gris` ;
 * - deux largeurs : la colonne de lecture pour le texte (`--m-lecture`),
 *   toute la largeur de la page pour les données. On ne centre qu'un bloc qui
 *   se suffit à lui-même (bandeau, page de service, état vide) ;
 * - un seul rythme vertical : l'écart entre deux sections est le même partout.
 *
 * UN BLOC, DES VALEURS PAR MARQUE, comme `composants.css` : chaque détail
 * visible se lit dans une variable que la marque peut poser dans son
 * `valeurs_marque`, avec un repli lisible pour toutes. Les macros qui écrivent
 * le HTML de ces blocs sont dans `apps/_shared/templates/_page.html` ; la
 * planche qui les montre tous, `/planche-graphique/` (admin seul). Doctrine
 * et règles d'usage : `MD Manuels/SYSTEME_GRAPHIQUE.md`.
 *
 * LA NAVIGATION N'EST PAS ICI : le menu du site dit la rubrique, le fil
 * d'Ariane et le sommaire d'une page longue sont dans `composants.css` et
 * `apps/_shared/templates/_navigation.html` (même jour, autre session). Une
 * seule navigation, jamais une seconde.
 *
 * PRÉFIXE `m-`, celui du socle. Aucune collision mesurée le 10/11/2026.
 */

/* ── La page ── La marge sous l'en-tête et l'écart entre les blocs. */
.m-page {
  padding-top: var(--m-page-haut, 28px);
  color: var(--marque-encre, #1a1a1a);
}
/* UN SEUL ESPACE SOUS L'EN-TÊTE, celui de la page (11/11/2026). Le cadre des
   pages Zero Bullshit ajoutait le sien (`py-10`, 40 px) : 68 px de vide entre
   l'en-tête et le fil d'Ariane (Benjamin : « le trou »). Quand une page est
   faite de blocs de la charte, le cadre cède son espace du haut. */
[class*="py-10"]:has(> .m-page:first-child) { padding-top: 0; }
/* `m-flux` : la colonne de contenu à côté d'un sommaire (`m-avec-sommaire`)
   prend le même rythme que la page. */
.m-page > * + *,
.m-flux > * + * { margin-top: var(--m-page-rythme, var(--m-esp-7, 48px)); }
/* Le fil d'Ariane (`composants.css`) porte sa propre marge : le haut de page
   le suit sans l'écart d'une section. */
.m-page > .m-fil + * { margin-top: 0; }

/* Un lien posé dans un bloc commun sans classe à lui (une tuile, une case de
   tableau, une note, une source) prend la couleur des liens de la marque
   (charte §3.7) : il sortait dans le bleu souligné du navigateur (étape 2,
   RealT, 11/11/2026). Les composants qui dessinent leurs liens gardent les
   leurs. */
/* `:where()` : la règle n'a AUCUN poids. Elle ne s'applique qu'aux liens
   qu'aucun composant ne colore lui-même ; posée sans `:where()` le 11/11/2026,
   elle passait devant le choix segmenté (lien actif prune sur fond noir,
   illisible, capture de Benjamin). */
:where(.m-page) :where(a:not([class])) { color: var(--m-lien); text-underline-offset: 0.15em; }

/* ── La colonne de lecture ── Un texte ne court jamais sur toute la largeur. */
.m-lecture { max-width: var(--m-lecture, 68ch); }

/* ── Le texte secondaire ── UN gris, une taille. */
.m-note {
  font-size: var(--m-t-note); line-height: 1.55;
  color: var(--marque-gris, #666);
  text-wrap: pretty;
  margin: var(--m-esp-3, 12px) 0 0;
}

/* ── Le haut de page ── */
.m-tete__surtitre {
  font-family: var(--m-label-police, inherit);
  font-size: var(--m-label-taille, 0.8rem);
  text-transform: var(--m-label-casse, uppercase);
  letter-spacing: var(--m-label-espacement, 0.08em);
  /* La couleur de la marque, la seule touche de couleur du haut de page
     (Benjamin, 11/11/2026 : « parfois noirs, parfois rouge clair, on doit
     décider »). Les autres petits libellés (champs, axes, en-têtes de
     tableau) restent gris. */
  color: var(--m-surtitre-couleur, var(--m-lien, var(--color-primary)));
  margin: 0 0 var(--m-esp-3, 12px);
}
.m-tete__titre {
  font-family: var(--font-heading, inherit);
  font-size: var(--m-titre-taille, clamp(2rem, 1.35rem + 2.6vw, 3.25rem));
  font-weight: var(--m-titre-graisse, 800);
  line-height: 1.08;
  letter-spacing: var(--m-titre-espacement, -0.02em);
  color: var(--marque-encre, #1a1a1a);
  margin: 0;
  text-wrap: balance;
}
.m-tete__chapeau {
  font-size: var(--m-t-chapeau); line-height: 1.6;
  color: var(--marque-encre, #1a1a1a);
  text-wrap: pretty;
  margin: var(--m-esp-4, 16px) 0 0;
}
/* Les types de haut de page : la même échelle, une composition par type. */
/* Le haut d'un article n'a plus de largeur à lui : le titre occupait la
   moitié d'un écran large (Benjamin, 11/11/2026 : « le titre sur 50 % de la
   page »). Il prend la colonne, comme tout haut de page. */

/* Un libellé au-dessus du titre ne répète jamais le fil d'Ariane : quand la
   page en a un, il ne s'affiche pas (« Comprendre le crowdfunding » écrit
   deux fois, l'une sous l'autre, relevé le 11/11/2026). */
.m-page:has(.m-fil) .m-tete__surtitre { display: none; }
.m-tete--rubrique .m-tete__chapeau { margin-top: var(--m-esp-3, 12px); }
.m-tete__signature { font-size: var(--m-t-note, 0.8125rem); color: var(--m-texte-2, #666); margin: var(--m-esp-4, 16px) 0 0; }
/* Les repères du sujet (adresse, date, taille), séparés par un point. */
.m-tete__reperes {
  display: flex; flex-wrap: wrap; gap: var(--m-esp-1, 4px) 0;
  list-style: none; padding: 0; margin: var(--m-esp-4, 16px) 0 0;
  font-size: var(--m-t-petit); color: var(--marque-gris, #666);
}
/* Le point FINIT un repère au lieu d'ouvrir le suivant : sur téléphone, une
   ligne ne commence jamais par « · ». */
.m-tete__reperes li:not(:last-child)::after { content: "·"; margin: 0 var(--m-esp-3, 12px); }
.m-tete__etats { display: flex; flex-wrap: wrap; gap: var(--m-esp-2, 8px); margin: var(--m-esp-4, 16px) 0 0; }
.m-tete__actions { margin-top: var(--m-esp-5, 24px); }

/* ── La pastille d'état ── Un état dit un FAIT sur le sujet. Quatre niveaux,
   les couleurs d'usage (vert, ambre, rouge) : elles disent un état, pas une
   marque, et ne servent à rien d'autre. */
.m-etat {
  display: inline-flex; align-items: center; gap: var(--m-esp-2, 8px);
  border-radius: var(--m-rayon-pilule, 999px); padding: var(--m-esp-1, 4px) var(--m-esp-3, 12px);
  font-size: var(--m-t-note); font-weight: 500; line-height: 1.4; white-space: nowrap;
  background: var(--neutre-surface-2, #f0f0f0); color: var(--marque-encre, #1a1a1a);
}
.m-etat::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--marque-gris, #666);
}
.m-etat--ok { background: var(--etat-ok-fond, #eaf4ee); color: var(--etat-ok-texte, #1f5c3f); }
.m-etat--ok::before { background: var(--etat-ok-texte, #1f5c3f); }
.m-etat--attention { background: var(--etat-alerte-fond, #fbf3e2); color: var(--etat-alerte-texte, #7a5408); }
.m-etat--attention::before { background: var(--etat-alerte-texte, #7a5408); }
.m-etat--alerte { background: var(--etat-erreur-fond, #fbe9e7); color: var(--etat-erreur-texte, #a1201a); }
.m-etat--alerte::before { background: var(--etat-erreur-texte, #a1201a); }

/* ── La section ── Un titre, une intro facultative, le contenu. */
.m-section__titre {
  font-family: var(--font-heading, inherit);
  font-size: var(--m-section-taille, var(--m-t-section, 1.625rem));
  font-weight: var(--m-section-graisse, 700);
  line-height: 1.2;
  letter-spacing: var(--m-titre-espacement, -0.01em);
  color: var(--marque-encre, #1a1a1a);
  margin: 0;
}
.m-section__intro {
  font-size: var(--m-t-petit); line-height: 1.6;
  color: var(--marque-gris, #666);
  text-wrap: pretty;
  margin: var(--m-esp-2, 8px) 0 0;
}
.m-section__corps { margin-top: var(--m-esp-5, 24px); }
/* Dans une section, deux éléments qui se suivent ont 16 px entre eux par
   défaut ; un élément qui porte sa propre marge (sous-titre) la garde
   (`:where`, spécificité nulle). */
:where(.m-section__corps > * + *) { margin-top: var(--m-esp-4, 16px); }
/* Une section qui ouvre une nouvelle partie de la page : un filet au-dessus. */
.m-section--partie { border-top: 1px solid var(--marque-filet, #e3e3e3); padding-top: var(--m-esp-7, 48px); }
/* L'intertitre, à l'intérieur d'une section ou d'une carte : le titre de carte
   du socle, pour qu'une page n'ait qu'un seul style de troisième niveau. */
/* `.m-intertitre` est défini avec `.m-carte__titre` dans `composants.css` :
   un seul troisième niveau, une seule règle (audit du 10/11/2026). */
/* Un intertitre qui ouvre un sous-bloc AU MILIEU d'une section prend de l'air
   au-dessus (11/11/2026, fiche plateforme du crowdfunding) : sa marge propre
   (`0 0 1rem`) l'emportait sur l'écart de 16 px, et il se collait au
   paragraphe d'avant, qui semblait alors lui appartenir. */
.m-section__corps > .m-intertitre:not(:first-child) { margin-top: var(--m-esp-6, 32px); }

/* ── La rangée de chiffres clés ── Les tuiles `m-stat` du socle, en grille
   alignée à gauche : chaque tuile a la même largeur, la rangée suit la page. */
.m-chiffres {
  display: grid; gap: var(--m-esp-3, 12px);
  grid-template-columns: repeat(auto-fill, minmax(var(--m-chiffres-min, 190px), 1fr));
}
.m-chiffres .m-stat { min-width: 0; }
.m-chiffres .m-stat__num { font-size: var(--m-chiffres-taille, 1.875rem); }
.m-stat--alerte .m-stat__num { color: var(--etat-erreur-texte, #a1201a); }

/* ── L'encadré ── Une information DANS la page, à lire avant la suite.
   Ce n'est PAS `m-alerte`, qui répond à un geste (formulaire envoyé, erreur
   de saisie). Trois niveaux, un filet à gauche, le fond doux de l'état. */
.m-encadre {
  border-left: 3px solid var(--marque-accent, var(--color-primary));
  background: var(--m-carte-plate-fond, var(--neutre-surface-2, #f5f5f5));
  border-radius: 0 var(--m-rayon, 8px) var(--m-rayon, 8px) 0;
  padding: var(--m-esp-4, 16px) var(--m-esp-4, 16px);
  font-size: var(--m-t-petit); line-height: 1.6;
  color: var(--marque-encre, #1a1a1a);
  text-wrap: pretty;
}
.m-encadre__titre { font-weight: 700; }
.m-encadre p { margin: 0; }
.m-encadre p + p { margin-top: var(--m-esp-2, 8px); }
.m-encadre--attention { border-left-color: var(--etat-alerte-trait, #8a6410); background: var(--etat-alerte-fond, #fbf3e2); }
.m-encadre--alerte { border-left-color: var(--etat-erreur-trait, #b42318); background: var(--etat-erreur-fond, #fbe9e7); }

/* ── Les graphiques ──
   Le calcul est dans `apps/_shared/graphiques.py`, le dessin dans
   `apps/_shared/templates/_graphiques.html`. Chaque marque reçoit sa couleur
   par une classe : `m-s1` à `m-s8` (la palette, par rang), `m-e-*` (un état).
   Les positions arrivent en variables (`--x`, `--y`, `--l`, `--h`, en % de
   la zone de tracé) ; le texte reste du HTML, lisible sur téléphone. */
.m-s1 { --c: var(--m-serie-1); } .m-s2 { --c: var(--m-serie-2); }
.m-s3 { --c: var(--m-serie-3); } .m-s4 { --c: var(--m-serie-4); }
.m-s5 { --c: var(--m-serie-5); } .m-s6 { --c: var(--m-serie-6); }
.m-s7 { --c: var(--m-serie-7); } .m-s8 { --c: var(--m-serie-8); }
.m-e-ok { --c: var(--etat-ok-trait); }
.m-e-attention { --c: var(--etat-alerte-trait); }
.m-e-alerte { --c: var(--etat-erreur-trait); }
.m-e-neutre { --c: var(--m-gris-400); }  /* 400 et non 500 : le texte écrit dans la part se lit (audit du 10/11/2026) */
.m-e-inconnu { --c: var(--m-gris-300); }

.m-graph { margin: 0; }
/* Le graphique garde le pas de la colonne quand il suit un autre bloc (une
   phrase-chiffre, une intro) : `margin: 0` ci-dessus écrasait l'écart commun
   des sections, et la phrase touchait la barre (rendu du 11/11/2026). */
.m-section__corps > .m-graph:not(:first-child) { margin-top: var(--m-esp-4, 16px); }
/* La légende : au-dessus du tracé, dès deux séries. Le texte reste dans
   l'encre du texte, la pastille porte la couleur. */
.m-graph__legende {
  display: flex; flex-wrap: wrap; gap: var(--m-esp-2, 8px) var(--m-esp-4, 16px);
  list-style: none; padding: 0; margin: 0 0 var(--m-esp-4);
  font-size: var(--m-t-note); color: var(--m-texte-2);
}
.m-graph__legende li { display: inline-flex; align-items: center; gap: var(--m-esp-2, 8px); }
.m-graph__pastille { width: 12px; height: 12px; border-radius: 3px; background: var(--c); flex: none; }
.m-graph__pastille--trait { height: 0; border-radius: 0; background: none; border-top: 2px solid var(--c); }
.m-graph__pastille--tirets { border-top-style: dashed; }

.m-graph__corps { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--m-esp-2); }
.m-graph__axe-y { position: relative; height: var(--hauteur, 240px); min-width: 2.5rem; }
.m-graph__axe-y span {
  position: absolute; right: 0; bottom: calc(var(--y) * 1%); transform: translateY(50%);
  font-size: var(--m-t-legende); line-height: 1; color: var(--m-texte-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-graph__trace { position: relative; height: var(--hauteur, 240px); border-bottom: 1px solid var(--m-gris-400); }
.m-graph__grille { position: absolute; left: 0; right: 0; bottom: calc(var(--y) * 1%); border-top: 1px solid var(--m-gris-200); }
.m-graph__zero { position: absolute; left: 0; right: 0; bottom: calc(var(--y) * 1%); border-top: 1px solid var(--m-gris-500); }

/* Barres : bouts arrondis côté valeur, 2 px de fond entre deux segments
   empilés pour qu'on les compte. */
.m-graph__barre {
  position: absolute; left: calc(var(--x) * 1%); width: calc(var(--l) * 1%);
  bottom: calc(var(--y) * 1%); height: calc(var(--h) * 1%);
  background: var(--c); border-radius: 3px 3px 0 0; min-height: 1px;
}
.m-graph--empile .m-graph__barre { border-radius: 0; box-shadow: inset 0 2px 0 var(--marque-fond, #fff); }
.m-graph__valeur {
  position: absolute; left: calc((var(--x) + var(--l) / 2) * 1%); bottom: calc((var(--y) + var(--h)) * 1%);
  transform: translate(-50%, -4px);
  font-size: var(--m-t-legende); color: var(--m-texte-2); font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Courbes : un trait de 2 px qui ne s'épaissit pas quand le tracé s'étire ;
   une série de référence (promesse, objectif) en tirets. */
.m-graph__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.m-graph__ligne { fill: none; stroke: var(--c); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.m-graph__ligne--tirets { stroke-dasharray: 6 4; }
.m-graph__fin {
  position: absolute; left: calc(var(--x) * 1%); bottom: calc(var(--y) * 1%);
  width: 8px; height: 8px; margin: 0 0 calc(-1 * var(--m-esp-1, 4px)) calc(-1 * var(--m-esp-1, 4px)); border-radius: 50%;
  background: var(--c); box-shadow: 0 0 0 2px var(--marque-fond, #fff);
}

/* Les annotations. UNE forme par sorte, sur tous les graphiques :
   - repère daté : un trait vertical en tirets, son libellé en haut ;
   - bande : une période grisée, son libellé en haut à gauche ;
   - seuil : un trait horizontal en tirets, son libellé au-dessus, à droite ;
   - note : un point cerclé et sa phrase. */
.m-graph__repere { position: absolute; top: 0; bottom: 0; left: calc(var(--x) * 1%); border-left: 1px dashed var(--m-gris-600); }
.m-graph__bande { position: absolute; top: 0; bottom: 0; left: calc(var(--x) * 1%); width: calc(var(--l) * 1%); background: var(--m-gris-100); }
.m-graph__seuil { position: absolute; left: 0; right: 0; bottom: calc(var(--y) * 1%); border-top: 1px dashed var(--m-gris-600); }
.m-graph__repere--alerte { border-left-color: var(--etat-erreur-trait); }
.m-graph__repere--attention { border-left-color: var(--etat-alerte-trait); }
.m-graph__seuil--alerte { border-top-color: var(--etat-erreur-trait); }
.m-graph__seuil--attention { border-top-color: var(--etat-alerte-trait); }
.m-graph__annot {
  position: absolute; z-index: 1;
  font-size: var(--m-t-legende); line-height: 1.3; color: var(--m-texte);
  background: var(--marque-fond, #fff); padding: 1px var(--m-esp-1, 4px); white-space: nowrap;
}
.m-graph__repere .m-graph__annot { top: 0; left: 4px; }
.m-graph__repere--fin .m-graph__annot { left: auto; right: 4px; }
.m-graph__bande .m-graph__annot { top: 0; left: 0; background: none; color: var(--m-texte-2); }
.m-graph__seuil .m-graph__annot { right: 0; bottom: 2px; }
.m-graph__note {
  position: absolute; left: calc(var(--x) * 1%); bottom: calc(var(--y) * 1%);
  width: 10px; height: 10px; margin: 0 0 calc(-1 * var(--m-esp-1, 4px)) calc(-1 * var(--m-esp-1, 4px)); border-radius: 50%;
  border: 2px solid var(--m-texte); background: var(--marque-fond, #fff); z-index: 1;
}
.m-graph__note .m-graph__annot { left: 12px; bottom: 6px; white-space: normal; width: max-content; max-width: 14rem; }

.m-graph__axe-x { position: relative; height: 1.5rem; grid-column: 2; }
/* Des barres : chaque nom de catégorie tient dans la largeur de sa barre et
   passe à la ligne au lieu de chevaucher le voisin (mesuré à 390 px). */
.m-graph__axe-x--cat { height: 2.6rem; }
.m-graph__axe-x--cat span { width: calc(var(--l) * 1%); white-space: normal; text-align: center; line-height: 1.2; overflow: hidden; max-height: 2.4em; }
.m-graph__axe-x span {
  position: absolute; top: 6px; left: calc(var(--x) * 1%); transform: translateX(-50%);
  font-size: var(--m-t-legende); line-height: 1; color: var(--m-texte-2); white-space: nowrap;
}

/* La barre de 100 % : seulement pour les répartitions COMPARÉES
   (`repartitions()`). Une répartition seule est un camembert (plus bas). */
.m-repartition { display: flex; gap: 2px; height: 28px; }
.m-repartition__part { width: calc(var(--l) * 1%); background: var(--c); min-width: 2px; }
.m-repartition__part:first-child { border-radius: var(--m-rayon-petit) 0 0 var(--m-rayon-petit); }
.m-repartition__part:last-child { border-radius: 0 var(--m-rayon-petit) var(--m-rayon-petit) 0; }

.m-graph__note--fin .m-graph__annot { left: auto; right: 12px; text-align: right; }
/* Une note dans le haut du tracé : sous son point (`dessous`, calculé par le
   serveur), la rangée du haut restant aux ronds numérotés. */
.m-graph__note--dessous .m-graph__annot { bottom: auto; top: 8px; }
/* Sur téléphone, une note tient en deux lignes courtes au lieu d'une longue,
   qui passait sur les ronds voisins (mesuré à 390 px, 11/11/2026). */
@media (max-width: 640px) { .m-graph__note .m-graph__annot { max-width: 7.5rem; } }

/* Le classement : une barre horizontale par ligne, le nom à gauche, la
   valeur à droite. Une seule couleur ; une ligne mise en avant (le sujet de
   la fiche) la garde, les autres passent en gris. */
.m-classement { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--m-esp-2, 8px); }
.m-classement li {
  display: grid; grid-template-columns: minmax(7rem, 14rem) minmax(0, 1fr) 5.5rem;
  align-items: center; column-gap: var(--m-esp-3);
  font-size: var(--m-t-petit);
}
.m-classement__nom { line-height: 1.3; text-wrap: pretty; }
/* Le nom passe à la ligne, il n'est jamais coupé (11/11/2026, pages de
   chiffres : « Assurance vie et épargne retrai… » ne se lisait plus). */
.m-classement__piste { height: 14px; }
.m-classement__barre { display: block; height: 100%; width: calc(var(--l) * 1%); min-width: 2px; background: var(--c); border-radius: 0 3px 3px 0; }
.m-classement__valeur { text-align: right; font-variant-numeric: tabular-nums; color: var(--m-texte-2); }
.m-classement--avant .m-classement__nom, .m-classement--avant .m-classement__valeur { font-weight: 700; color: var(--m-texte); }

/* Avant / après : deux points reliés par un trait, sur une échelle commune. */
.m-halteres { display: grid; gap: var(--m-esp-3, 12px); }
.m-halteres__ligne, .m-halteres__axe {
  display: grid; grid-template-columns: minmax(7rem, 14rem) minmax(0, 1fr);
  align-items: center; column-gap: var(--m-esp-3); font-size: var(--m-t-petit);
}
.m-halteres__piste { position: relative; height: 16px; }
.m-halteres__axe .m-halteres__piste { height: 1rem; border-bottom: 1px solid var(--m-gris-200); }
.m-halteres__axe .m-halteres__piste span {
  position: absolute; left: calc(var(--x) * 1%); transform: translateX(-50%);
  font-size: var(--m-t-legende); color: var(--m-texte-2); white-space: nowrap;
}
.m-halteres__trait { position: absolute; top: 7px; height: 2px; left: calc(var(--a) * 1%); width: calc((var(--b) - var(--a)) * 1%); background: var(--m-gris-300); }
.m-halteres__point {
  position: absolute; top: 2px; left: calc(var(--x) * 1%); width: 12px; height: 12px; margin-left: calc(-1 * var(--m-esp-2, 8px));
  border-radius: 50%; background: var(--c); box-shadow: 0 0 0 2px var(--marque-fond, #fff);
}

/* Le nuage de points : un point de 10 px, cerclé du fond pour qu'on
   compte deux points qui se chevauchent ; le nom des points désignés. */
.m-graph__point {
  position: absolute; left: calc(var(--x) * 1%); bottom: calc(var(--y) * 1%);
  width: 10px; height: 10px; margin: 0 0 calc(-1 * var(--m-esp-1, 4px)) calc(-1 * var(--m-esp-1, 4px)); border-radius: 50%;
  background: var(--c); box-shadow: 0 0 0 2px var(--marque-fond, #fff);
}
.m-graph__point .m-graph__annot { left: 10px; bottom: 6px; background: var(--marque-fond, #fff); }
.m-graph__nom-axe { font-size: var(--m-t-legende); color: var(--m-texte-2); margin: 0 0 var(--m-esp-2); }
.m-graph__nom-axe--x { text-align: right; margin: var(--m-esp-1) 0 0; }

/* Les petits graphiques côte à côte, sur la même échelle (`courbes(...,
   bornes=...)`) : un titre de carte au-dessus de chacun. */
.m-multiples { display: grid; gap: var(--m-esp-6) var(--m-esp-5); grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

/* La petite courbe de tendance, dans le fil du texte. */
.m-tendance { display: inline-flex; align-items: center; gap: var(--m-esp-2, 8px); vertical-align: middle; white-space: nowrap; }
.m-tendance__trace { width: 64px; height: 18px; overflow: visible; }
.m-tendance__trace polyline { fill: none; stroke: var(--m-texte-2); stroke-width: 1.5; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.m-tendance__variation { font-size: var(--m-t-note); font-weight: 600; font-variant-numeric: tabular-nums; }
.m-tendance--ok { color: var(--etat-ok-texte); }
.m-tendance--alerte { color: var(--etat-erreur-texte); }
.m-tendance--neutre { color: var(--m-texte-2); }
@media (max-width: 640px) {
  .m-classement li, .m-halteres__ligne, .m-halteres__axe { grid-template-columns: minmax(5.5rem, 8rem) minmax(0, 1fr) auto; }
  .m-halteres__ligne, .m-halteres__axe { grid-template-columns: minmax(5.5rem, 8rem) minmax(0, 1fr); }
}

/* Les données du graphique, en tableau, sous lui : lisibles sans les
   couleurs, par un lecteur d'écran, et copiables. */
.m-graph__donnees { margin-top: var(--m-esp-3); font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-graph__donnees > summary { cursor: pointer; width: max-content; }
.m-graph__donnees > summary:hover { color: var(--m-lien); }
.m-graph__donnees .m-tableau { margin-top: var(--m-esp-3); font-size: var(--m-t-note); }

/* ── La grille ── Des cartes ou des encadrés côte à côte, à largeur égale,
   qui passent l'un sous l'autre quand la place manque. */
.m-grille {
  display: grid; gap: var(--m-esp-4, 16px);
  grid-template-columns: repeat(auto-fill, minmax(var(--m-grille-min, 280px), 1fr));
}
.m-grille > .m-encadre { max-width: none; }

/* ── La rangée de boutons ── */
.m-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--m-esp-3, 12px); }

/* ── Téléphone ── */
@media (max-width: 640px) {
  .m-page > * + *,
  .m-flux > * + * { margin-top: var(--m-page-rythme-mobile, var(--m-esp-6, 32px)); }
  .m-chiffres { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--m-esp-2, 8px); }
  /* Deux tuiles par ligne : un montant à sept chiffres (« 1 576 960 $ ») se
     coupait en deux lignes à la taille d'écran large (mesuré à 390 px). */
  .m-chiffres .m-stat { padding: var(--m-esp-4, 16px); }
  .m-chiffres .m-stat__num { font-size: var(--m-chiffres-taille-mobile, clamp(1.05rem, 5vw, 1.5rem)); white-space: nowrap; }
  .m-graph__trace, .m-graph__axe-y { height: min(var(--hauteur, 240px), 200px); }
}

/* ── Nuancier ── La planche montre chaque jeton de couleur : une case par
   degré, la couleur passée en variable (`--c`), son nom dessous. Réservé à
   la documentation (`/planche-graphique/`). */
.m-nuancier { display: grid; gap: var(--m-esp-2, 8px); grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); }
.m-nuancier__case { display: flex; flex-direction: column; gap: var(--m-esp-1, 4px); font-size: var(--m-t-legende); color: var(--m-texte-2, #666); }
.m-nuancier__case::before {
  content: ""; height: 44px; border-radius: var(--m-rayon-petit, 4px);
  background: var(--c); box-shadow: inset 0 0 0 1px var(--m-filet, #e3e3e3);
}
.m-nuancier__case b { color: var(--m-texte, #1a1a1a); font-weight: 600; }
.m-echelle { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: var(--m-esp-4, 16px) var(--m-esp-5, 24px); align-items: baseline; }
.m-echelle > dt { font-size: var(--m-t-legende); color: var(--m-texte-2, #666); }
.m-echelle > dd { margin: 0; }
.m-espace { display: flex; align-items: center; gap: var(--m-esp-3, 12px); font-size: var(--m-t-legende); color: var(--m-texte-2, #666); }
.m-espace::before { content: ""; width: var(--l); height: 12px; background: var(--m-marque-300, #ccc); border-radius: 2px; }
@media (max-width: 640px) { .m-echelle { grid-template-columns: minmax(0, 1fr); gap: var(--m-esp-1, 4px); } .m-echelle > dd { margin-bottom: var(--m-esp-4, 16px); } }

/* ══ Les blocs de contenu courants (10/11/2026, inventaire de toutes les
   apps) : chacun existait en 3 à 6 dessins différents. ══ */

/* ── Ligne de constat ── Un fait d'alerte en UNE ligne, son état en tête
   (pastille + mot), sans cadre : « une alerte tient en une ligne »
   (Benjamin, 09/11/2026). Plusieurs constats se suivent en liste. */
.m-constats { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--m-esp-2, 8px); }
.m-constat { display: flex; gap: var(--m-esp-3, 12px); align-items: baseline; font-size: var(--m-t-petit, 0.9375rem); line-height: 1.5; }
.m-constat::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--m-gris-500)); transform: translateY(-1px); }
.m-constat--ok { --c: var(--etat-ok-trait); }
.m-constat--attention { --c: var(--etat-alerte-trait); }
.m-constat--alerte { --c: var(--etat-erreur-trait); }
/* Un point de couleur DIT un état ; sans état, pas de point gris qui ne dit
   rien (audit du 11/11/2026, « En bref » d'une fiche). La place reste, pour
   que les lignes s'alignent. */
.m-constat:has(> .m-constat__etat):not(.m-constat--ok):not(.m-constat--attention):not(.m-constat--alerte)::before { visibility: hidden; }
.m-constat__etat { font-weight: 700; flex: none; }
.m-constat--ok .m-constat__etat { color: var(--etat-ok-texte); }
.m-constat--attention .m-constat__etat { color: var(--etat-alerte-texte); }
.m-constat--alerte .m-constat__etat { color: var(--etat-erreur-texte); }

/* ── Liste de faits « intitulé : valeur » ── L'intitulé en gris à gauche,
   la valeur à droite ; une ligne par fait, un filet entre deux. */
.m-faits { display: grid; grid-template-columns: minmax(8rem, 16rem) minmax(0, 1fr); margin: 0; font-size: var(--m-t-petit, 0.9375rem); }
/* UN TRAIT SÉPARE DEUX ÉLÉMENTS D'UNE LISTE, jamais le haut ni le bas d'un
   bloc (Benjamin, 11/11/2026 : « on dirait qu'il y a des lignes partout ») :
   vaut pour les faits, les lignes, le journal, les replis. Verrouillé par
   `test_socle_lisible.py` (deux traits sans texte entre eux). */
.m-faits > dt, .m-faits > dd { padding: var(--m-esp-2, 8px) 0; border-top: 1px solid var(--m-filet, #e3e3e3); margin: 0; }
.m-faits > dt:first-of-type, .m-faits > dd:first-of-type { border-top: 0; }
/* Dans une carte ou une grille, la colonne est trop étroite pour deux
   colonnes : le libellé passe AU-DESSUS de sa valeur (guide Tudigo du
   11/11/2026, un mot par ligne dans trois cartes côte à côte). */
:is(.m-carte, .m-grille) .m-faits { display: block; }
:is(.m-carte, .m-grille) .m-faits > dt { padding-bottom: 0; }
:is(.m-carte, .m-grille) .m-faits > dd { border-top: 0; padding-top: 2px; }
:is(.m-carte, .m-grille) .m-faits > dt:first-of-type { padding-top: 0; }
.m-faits > dt { color: var(--m-texte-2, #666); padding-right: var(--m-esp-4, 16px); }
.m-faits > dd { font-variant-numeric: tabular-nums; min-width: 0; }

/* ── Partie repliable ── Le complément qu'on ouvre si on veut : jamais le
   contenu principal (« un sujet, une page »). Un seul dessin : un filet, le
   titre en gras, un signe + / - à droite. */
.m-repli + .m-repli { border-top: 1px solid var(--m-filet, #e3e3e3); }
.m-repli > summary {
  list-style: none; cursor: pointer; padding: var(--m-esp-3, 12px) var(--m-esp-6, 32px) var(--m-esp-3, 12px) 0; position: relative;
  font-weight: 600; color: var(--m-texte, #1a1a1a);
}
.m-repli > summary::-webkit-details-marker { display: none; }
.m-repli > summary::after { content: "+"; position: absolute; right: 4px; top: 10px; font-size: var(--m-t-chapeau); color: var(--m-texte-2, #666); }
.m-repli[open] > summary::after { content: "−"; }
.m-repli > summary:hover { color: var(--m-lien); }
.m-repli__corps { padding: 0 0 var(--m-esp-4, 16px); }
.m-repli__resume { font-weight: 400; color: var(--m-texte-2, #666); margin-left: var(--m-esp-2, 8px); }

/* ── Étapes numérotées ── Une marche à suivre : le numéro dans un rond,
   le titre de l'étape, son texte. */
.m-etapes { list-style: none; counter-reset: etape; padding: 0; margin: 0; display: grid; gap: var(--m-esp-5, 24px); }
.m-etapes > li { counter-increment: etape; display: grid; grid-template-columns: 2rem minmax(0, 1fr); column-gap: var(--m-esp-4, 16px); }
.m-etapes > li::before {
  content: counter(etape); grid-row: span 2;
  width: 2rem; height: 2rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--m-marque-100); color: var(--m-marque-800); font-weight: 700; font-variant-numeric: tabular-nums;
}
.m-etapes > li > p { margin: 0; }
/* Tout ce qu'une étape contient (un modèle de lettre replié, un bloc de code)
   va dans la colonne du texte, jamais sous le numéro (guide Tudigo du
   11/11/2026 : « Modèle / de / lettre » écrit sur trois lignes). */
.m-etapes > li > * { grid-column: 2; }
.m-etapes > li > * + * { margin-top: var(--m-esp-2, 8px); }
.m-etapes > li > .m-etapes__titre { font-weight: 700; margin: var(--m-esp-1, 4px) 0; }

/* ── Citation ── Une phrase rapportée, sa source dessous. Dans la colonne
   de lecture, un filet de la couleur de marque à gauche. */
.m-citation { margin: 0; padding: 4px 0 4px var(--m-esp-5, 24px); border-left: 2px solid var(--m-marque-300); max-width: var(--m-lecture, 68ch); }
.m-citation > p { font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); line-height: 1.45; margin: 0; }
/* La source est un `<p>` de la citation : sans `.m-citation >` devant, la règle
   de la phrase (plus précise) lui donnait sa police et sa taille (constaté au
   rendu de « Ils nous citent », 10/11/2026). Ses liens prennent la couleur des
   liens du socle, jamais le bleu du navigateur. */
.m-citation > .m-citation__source { font-family: var(--font-body, inherit); font-size: var(--m-t-note, 0.8125rem); line-height: 1.5; color: var(--m-texte-2, #666); margin-top: var(--m-esp-2, 8px); }
.m-citation__source a { color: var(--m-lien, inherit); }

/* ── Le chiffre dans une phrase ── La réponse de la page en une phrase,
   son chiffre en grand : « 29,6 % des montants financés par Bricks sont en
   retard ou en défaut. » */
.m-phrase-chiffre { font-family: var(--font-heading, inherit); font-size: var(--m-t-phrase); line-height: 1.3; font-weight: 700; margin: 0; }
.m-phrase-chiffre b { font-size: var(--m-t-chiffre-grand); font-weight: 900; font-variant-numeric: tabular-nums; }

/* ── Source et méthode ── En bas de la page ou d'un bloc : d'où viennent
   les chiffres, de quand ils datent, comment ils sont calculés. Un filet au
   dessus, le texte en note. */
.m-source { font-size: var(--m-t-note, 0.8125rem); color: var(--m-texte-2, #666); }
.m-source p { margin: 0 0 var(--m-esp-2, 8px); }
.m-source b { color: var(--m-texte, #1a1a1a); font-weight: 600; }

/* ── Voir aussi ── Les liens vers les pages voisines, en pastilles. */
.m-voir-aussi { display: flex; flex-wrap: wrap; gap: var(--m-esp-2, 8px); align-items: center; }
.m-voir-aussi__titre { font-size: var(--m-t-note, 0.8125rem); color: var(--m-texte-2, #666); margin-right: var(--m-esp-1, 4px); }

/* ── État vide ── Une liste sans résultat : la phrase qui le dit et ce
   qu'on peut faire. Centré, comme tout bloc qui se suffit à lui-même. */
.m-vide { text-align: center; padding: var(--m-esp-7, 48px) var(--m-esp-4, 16px); border: 1px dashed var(--m-filet-fort, #ccc); border-radius: var(--m-rayon, 8px); color: var(--m-texte-2, #666); }
.m-vide__titre { font-weight: 700; color: var(--m-texte, #1a1a1a); margin: 0 0 var(--m-esp-2, 8px); }

/* ── Choix segmenté ── Deux à cinq options exclusives qui changent
   l'affichage (devise, période, unité) : des boutons collés, le choisi
   plein. Pas des onglets : rien n'est caché, seule l'unité change. */
.m-segments { display: inline-flex; border: 1px solid var(--m-filet-fort, #ccc); border-radius: var(--m-rayon-petit, 4px); overflow: hidden; }
.m-segments a, .m-segments button, .m-segments label {
  padding: var(--m-esp-2, 8px) var(--m-esp-3, 12px); font: inherit; font-size: var(--m-t-note, 0.8125rem); color: var(--m-texte, #1a1a1a);
  background: var(--m-surface, #fff); border: 0; text-decoration: none; cursor: pointer;
}
.m-segments > * + * { border-left: 1px solid var(--m-filet-fort, #ccc); }
/* Les liens d'un choix segmenté n'ont pas de classe : la règle des liens nus
   d'une page (`.m-page a:not([class])`, plus haut) les passait en couleur de
   lien, et le choix actif sortait violet sur noir (3,6 pour 1, 11/11/2026).
   Même force, déclarée après : le choix segmenté garde son dessin. */
.m-segments a[href] { color: var(--m-texte, #1a1a1a); text-decoration: none; }
.m-segments [aria-current], .m-segments [aria-pressed="true"], .m-segments a[aria-current] { background: var(--m-texte, #1a1a1a); color: var(--marque-fond, #fff); }
@media (max-width: 640px) { .m-faits { grid-template-columns: minmax(0, 1fr); } .m-faits > dt { border-bottom: 0; padding-bottom: 0; } }

/* ── Bloc de code ── Un extrait à copier (une clé, une commande, l'usage
   d'un bloc dans la charte) : police à chasse fixe, fond doux, défile de
   côté plutôt que de casser la page. */
.m-code {
  font-family: var(--m-label-police, ui-monospace, monospace); font-size: var(--m-t-note); line-height: 1.55;
  background: var(--m-surface-douce, #f3f3f3); border: 1px solid var(--m-filet, #e3e3e3);
  border-radius: var(--m-rayon-petit, 4px); padding: var(--m-esp-3, 12px) var(--m-esp-4, 16px);
  overflow-x: auto; white-space: pre; margin: var(--m-esp-3, 12px) 0 0; max-width: 100%;
}

/* ── Lien de chapitre ── Une carte entière cliquable qui mène à une page :
   son titre, une phrase. */
a.m-carte { display: block; color: inherit; text-decoration: none; transition: border-color 0.15s; }
a.m-carte:hover { border-color: var(--m-lien); }
a.m-carte:hover .m-intertitre { text-decoration: underline; }

/* ══ Repris des enquêtes ZB (10/11/2026) : lecture au doigt, nom au bout de
   la courbe, repères numérotés, n.p., échelle à deux sens, hachures, bande
   de tolérance, seuil d'un classement, répartitions comparées. Les PRINCIPES
   sont repris, pas les valeurs : couleurs et tailles restent celles de la
   charte (la palette des enquêtes ne tient pas en daltonisme). ══ */

/* L'échelle à deux sens et les hachures (second moyen de distinguer une part,
   sans la couleur). */
.m-div-pos { --c: var(--m-divergent-pos); }
.m-div-neg { --c: var(--m-divergent-neg); }
.m-motif { background-image: repeating-linear-gradient(45deg, color-mix(in srgb, var(--marque-fond, #fff) 55%, transparent) 0 2px, transparent 2px 6px); }
.m-graph__legende .m-motif .m-graph__pastille, .m-graph__legende li.m-motif .m-graph__pastille { background-image: repeating-linear-gradient(45deg, color-mix(in srgb, var(--marque-fond, #fff) 55%, transparent) 0 2px, transparent 2px 5px); }

/* Une valeur absente (« n.p. » : non publiée), écrite sur l'axe. */
.m-graph__absent {
  position: absolute; left: calc((var(--x) + var(--l) / 2) * 1%); bottom: calc(var(--y) * 1%);
  transform: translate(-50%, -4px); font-size: var(--m-t-legende); font-style: italic; color: var(--m-texte-2);
}

/* La bande de tolérance autour d'une courbe : la couleur de sa série, pâle. */
.m-graph__tolerance { fill: var(--c); fill-opacity: 0.14; stroke: none; }

/* Le nom de chaque courbe au bout de son trait, dans une marge à droite ; un
   halo du fond derrière le texte pour qu'il reste lisible sur la grille. */
.m-graph__corps--fin .m-graph__trace { margin-right: var(--m-graph-marge-fin, 10rem); }
.m-graph__corps--fin .m-graph__axe-x { margin-right: var(--m-graph-marge-fin, 10rem); }
.m-graph__etiquette {
  position: absolute; left: calc(100% + 10px); bottom: calc(var(--y) * 1%); transform: translateY(50%);
  font-size: var(--m-t-note); font-weight: 600; line-height: 1.2; width: 9.25rem; color: var(--m-texte);
  text-shadow: 0 0 3px var(--marque-fond, #fff), 0 0 3px var(--marque-fond, #fff);
  display: inline-flex; align-items: center; gap: var(--m-esp-2, 8px);
}
.m-graph__etiquette::before { content: ""; width: 10px; height: 2px; background: var(--c); flex: none; }

/* Les repères numérotés : un rond chiffré en haut du trait, la liste dessous. */
.m-graph__num {
  display: inline-grid; place-items: center; width: 1.25rem; height: 1.25rem; border-radius: 50%;
  font-size: var(--m-t-legende); font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--m-texte); color: var(--marque-fond, #fff); flex: none;
}
.m-graph__repere > .m-graph__num { position: absolute; top: -2px; left: 0; transform: translateX(-50%); }
/* Un rond trop près du précédent descend d'un cran (`cran`, calculé par le
   serveur) : deux repères voisins ne se lisent jamais comme un seul nombre. */
.m-graph__repere--cran > .m-graph__num { top: calc(1.25rem + 2px); }
/* Un rond passe toujours devant une note : son numéro reste lisible. */
.m-graph__repere > .m-graph__num { z-index: 2; }
.m-graph__num--alerte, .m-graph__repere--alerte > .m-graph__num { background: var(--etat-erreur-trait); color: var(--neutre-sur-aplat, #fff); }
.m-graph__reperes { list-style: none; padding: 0; margin: var(--m-esp-4) 0 0; display: grid; gap: var(--m-esp-2, 8px); font-size: var(--m-t-petit); }
.m-graph__reperes li { display: flex; gap: var(--m-esp-3, 12px); align-items: baseline; }

/* La lecture au doigt et à la souris : le trait guide et la boîte des
   valeurs de toutes les séries. Le tracé laisse défiler la page à la
   verticale (le doigt qui glisse de côté lit le graphique). */
.m-graph__trace[data-lecture] { touch-action: pan-y; cursor: crosshair; }
.m-graph__guide:not([hidden]) {
  position: absolute; top: 0; bottom: 0; left: calc(var(--x) * 1%); width: 0;
  border-left: 1px solid var(--m-gris-600); pointer-events: none; z-index: 2;
}
.m-graph__lecteur:not([hidden]) {
  position: fixed; z-index: 50; pointer-events: none;
  background: var(--m-surface); color: var(--m-texte); border: 1px solid var(--m-filet-fort); border-radius: var(--m-rayon-petit);
  padding: var(--m-esp-2, 8px) var(--m-esp-3, 12px); font-size: var(--m-t-note); line-height: 1.45; min-width: 8rem; max-width: min(18rem, calc(100vw - 16px));
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}
.m-graph__lecteur p { margin: 0; display: flex; align-items: center; gap: var(--m-esp-2, 8px); white-space: nowrap; }
.m-graph__lecteur b { font-variant-numeric: tabular-nums; }
.m-graph__lecteur p.m-graph__lecteur-titre { font-weight: 700; margin-bottom: var(--m-esp-1, 4px); }

/* Le seuil d'un classement : un trait vertical sur toutes les lignes, son
   libellé au-dessus. */
.m-classement__piste { position: relative; }
.m-classement__seuil { position: absolute; top: -4px; bottom: -4px; left: calc(var(--x) * 1%); border-left: 1px dashed var(--m-gris-600); }
.m-classement__seuil-titre {
  display: grid; grid-template-columns: minmax(7rem, 14rem) minmax(0, 1fr) 5.5rem; column-gap: var(--m-esp-3);
  margin: 0 0 var(--m-esp-1, 4px); font-size: var(--m-t-legende); color: var(--m-texte);
}
.m-classement__seuil-titre span { grid-column: 2; padding-left: calc(var(--x) * 1%); transform: translateX(-50%); white-space: nowrap; }

/* Le classement à deux sens (11/11/2026, pages de chiffres du Brief
   Patrimonial) : un solde, l'entrée à droite de l'axe, la sortie à gauche.
   `--axe` (sur la liste) : la position du zéro, de 0 à 100 ; `--g` et `--l`
   (sur la barre) : son départ et sa longueur. Les couleurs sont celles de
   l'échelle à deux sens (`m-div-pos`, `m-div-neg`). */
.m-classement--signe .m-classement__piste::after { content: ""; position: absolute; top: -4px; bottom: -4px; left: calc(var(--axe) * 1%); border-left: 1px solid var(--m-gris-600); }
.m-classement--signe .m-classement__barre { position: absolute; top: 0; left: calc(var(--g) * 1%); }
.m-classement__barre--neg { border-radius: 3px 0 0 3px; }

/* Les répartitions comparées : une barre de 100 % par ligne, la part
   écrite dans son segment quand il est assez large. */
.m-repartitions { display: grid; gap: var(--m-esp-3, 12px); }
.m-repartitions__ligne { display: grid; grid-template-columns: minmax(5rem, 10rem) minmax(0, 1fr); column-gap: var(--m-esp-3); align-items: center; font-size: var(--m-t-petit); }
.m-repartitions .m-repartition__part { display: flex; align-items: center; justify-content: center; overflow: hidden; }
.m-repartition__valeur { font-size: var(--m-t-legende); font-weight: 600; color: var(--neutre-sur-aplat, #fff); text-shadow: 0 0 2px rgba(0, 0, 0, 0.35); white-space: nowrap; }
.m-e-inconnu .m-repartition__valeur, .m-e-neutre .m-repartition__valeur { color: var(--m-texte); text-shadow: none; }

/* Les panneaux empilés : plusieurs graphiques l'un sous l'autre, sur la
   même échelle de temps (enquêtes ZB, Primopierre et Arkéa). */
.m-panneaux { display: grid; gap: var(--m-esp-5); }
.m-panneaux .m-intertitre { margin-bottom: var(--m-esp-2); }
@media (max-width: 640px) {
  .m-graph__corps--fin .m-graph__trace, .m-graph__corps--fin .m-graph__axe-x { margin-right: 5.5rem; }
  .m-graph__etiquette { width: 5.25rem; font-size: var(--m-t-legende); }
}

/* ── Frise verticale à états ── Une suite datée de faits, chacun avec son
   état (pastille + mot), reliés par un filet (repris des enquêtes ZB). */
.m-frise { list-style: none; margin: 0; padding: 0 0 0 var(--m-esp-5, 24px); border-left: 2px solid var(--m-filet); display: grid; gap: var(--m-esp-5); }
.m-frise > li { position: relative; }
.m-frise > li::before {
  content: ""; position: absolute; left: -29px; top: 6px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--c, var(--m-gris-500)); box-shadow: 0 0 0 3px var(--marque-fond, #fff);
}
.m-frise > li.m-constat--ok { --c: var(--etat-ok-trait); }
.m-frise > li.m-constat--attention { --c: var(--etat-alerte-trait); }
.m-frise > li.m-constat--alerte { --c: var(--etat-erreur-trait); }
.m-frise__date { display: block; font-size: var(--m-t-note); color: var(--m-texte-2); font-variant-numeric: tabular-nums; }
.m-frise__titre { font-weight: 700; margin: 2px 0 var(--m-esp-1, 4px); }
.m-frise p { margin: 0; }

/* ── Document cité ── Un extrait de pièce (jugement, contrat, courrier) :
   fond de papier, filet, source dessous ; un passage surligné (`mark`) et un
   passage masqué (`m-caviarde`, dit comme tel au lecteur d'écran). */
.m-document {
  margin: 0; background: var(--m-surface); border: var(--m-trait);
  border-radius: var(--m-rayon-petit); padding: var(--m-esp-4) var(--m-esp-5);
  font-family: var(--m-document-police, ui-serif, Georgia, serif); font-size: var(--m-t-petit); line-height: 1.7;
}
.m-document mark { background: color-mix(in srgb, var(--etat-alerte-trait) 22%, transparent); color: inherit; padding: 0 2px; }
.m-caviarde { background: var(--m-texte); color: transparent; border-radius: 2px; user-select: none; }
.m-document > figcaption { font-family: var(--font-body, inherit); font-size: var(--m-t-note); color: var(--m-texte-2); margin-top: var(--m-esp-3); }

/* ── Renvoi de source ── Un numéro en exposant dans le texte, qui ouvre la
   source dans une bulle (au doigt comme à la souris, par l'attribut popover
   du navigateur, sans script) ; la liste des sources en bas de page. */
.m-renvoi {
  display: inline-grid; place-items: center; min-width: 1.15rem; height: 1.15rem; padding: 0 3px;
  margin: 0 1px; vertical-align: super; font-size: var(--m-t-legende); font-weight: 700; line-height: 1;
  border: 1px solid var(--m-lien); border-radius: var(--m-rayon-pilule, 999px); background: transparent; color: var(--m-lien); cursor: pointer;
}
.m-renvoi:hover { background: var(--m-lien); color: var(--marque-fond, #fff); }
.m-sources { font-size: var(--m-t-note); color: var(--m-texte-2); padding-left: 1.5em; margin: 0; }
.m-sources li + li { margin-top: var(--m-esp-1, 4px); }

/* ── Fiche d'une personne ── Le portrait (ou ses initiales), le nom, ce
   qu'elle est dans l'affaire, une phrase. */
.m-personne { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); column-gap: var(--m-esp-4); align-items: start; }
.m-personne__portrait {
  width: 3.5rem; height: 3.5rem; border-radius: 50%; object-fit: cover;
  display: grid; place-items: center; background: var(--m-marque-100); color: var(--m-marque-800);
  font-weight: 700; font-size: var(--m-t-niveau-4);
}
.m-personne__nom { font-weight: 700; margin: 2px 0 0; }
.m-personne__role { font-size: var(--m-t-note); color: var(--m-texte-2); margin: 0 0 var(--m-esp-2, 8px); }
.m-personne p:last-child { margin: 0; font-size: var(--m-t-petit); }

/* ── La lecture, une seule pour tous les graphiques (10/11/2026) ──
   Les marques qu'on lit une à une (`data-bulle`) s'éclairent au survol, au
   toucher et au clavier ; la boîte est celle des barres et des courbes. */
.m-graph [data-bulle] { cursor: pointer; transition: opacity 0.12s, box-shadow 0.12s; }
.m-graph [data-bulle]:focus { outline: none; }
.m-graph [data-bulle]:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-graph__point.m-graph--actif { box-shadow: 0 0 0 2px var(--marque-fond, #fff), 0 0 0 4px var(--c); transform: scale(1.25); }
.m-repartition__part.m-graph--actif, .m-graph__barre.m-graph--actif { filter: brightness(0.88); }
.m-halteres__ligne.m-graph--actif, .m-classement li.m-graph--actif { background: var(--m-gris-100); }
/* Sous le doigt, une marque fine se touche quand même : la zone de contact
   déborde de 8 px autour du point. */
.m-graph__point::before { content: ""; position: absolute; inset: -8px; border-radius: 50%; }

/* Le premier et le dernier libellé de l'axe se calent vers l'intérieur au
   lieu de déborder (« 800M€ » coupé au bord, relevé à 390 px). */
.m-graph__axe-x span.m-graph__x-fin { transform: translateX(-100%); }
.m-graph__axe-x span.m-graph__x-debut { transform: none; }

/* ── Toucher : 24 px au moins sous le doigt (WCAG 2.2, audit du 10/11/2026) ──
   Les petites cibles gardent leur dessin ; leur zone de toucher déborde. */
.m-renvoi { position: relative; }
.m-renvoi::after { content: ""; position: absolute; inset: -6px; }
.m-fil a { padding-block: var(--m-esp-1, 4px); }

/* En sombre, les parts sont éclaircies : la valeur écrite dedans passe à
   l'encre du fond (noir), qui s'y lit à plus de 7 pour 1 ; le blanc tombait
   à 3,25 (audit du 10/11/2026). */
@media screen {
  html[data-mode="sombre"] .m-repartition__valeur { color: var(--marque-fond, #0d0d0d); text-shadow: none; }
  /* Les parts grises restent sombres en mode sombre : leur valeur s'écrit à
     l'encre claire du texte. */
  html[data-mode="sombre"] .m-e-neutre .m-repartition__valeur,
  html[data-mode="sombre"] .m-e-inconnu .m-repartition__valeur { color: var(--m-texte); }
}

/* ══ Lot 1 des modules à construire (11/11/2026) : contenu et chiffres.
   Chacun remplace de 3 à 6 dessins relevés le 10/11/2026 (catalogue de la
   charte). ══ */

/* ── Le corps d'un article ── Le texte d'une enquête, d'une actu, d'une
   méthode, tel que la rédaction l'écrit (balises nues) : la charte habille
   ses intertitres, listes, citations, images et tableaux. Toujours dans la
   colonne de lecture. */
.m-prose { max-width: var(--m-lecture, 68ch); font-size: var(--m-t-texte-long); line-height: 1.7; color: var(--m-texte); }
.m-prose > * { margin: 0; }
.m-prose > * + * { margin-top: var(--m-esp-4, 16px); }
.m-prose > h2 {
  font-family: var(--font-heading, inherit); font-size: var(--m-t-section); font-weight: var(--m-section-graisse, 700);
  line-height: 1.2; letter-spacing: var(--m-titre-espacement, -0.01em); margin-top: var(--m-esp-7, 48px);
}
.m-prose > h3 { font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 700; line-height: 1.25; margin-top: var(--m-esp-6, 32px); }
.m-prose > h4 { font-size: var(--m-t-niveau-4); font-weight: 700; line-height: 1.35; margin-top: var(--m-esp-5, 24px); }
.m-prose > h2 + *, .m-prose > h3 + *, .m-prose > h4 + * { margin-top: var(--m-esp-3, 12px); }
.m-prose a { color: var(--m-lien); text-decoration: underline; text-underline-offset: 0.15em; }
.m-prose ul, .m-prose ol { padding-left: 1.4em; }
.m-prose li + li { margin-top: var(--m-esp-2, 8px); }
.m-prose li::marker { color: var(--m-texte-2); }
.m-prose > blockquote { padding: 2px 0 2px var(--m-esp-5, 24px); border-left: 2px solid var(--m-marque-300); font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); line-height: 1.45; }
.m-prose img { display: block; max-width: 100%; height: auto; border-radius: var(--m-rayon-petit, 4px); }
.m-prose > figure, .m-prose > .m-figure, .m-prose > .m-graph, .m-prose > .m-defile { margin-top: var(--m-esp-6, 32px); margin-bottom: var(--m-esp-2, 8px); }
.m-prose > table { font-size: var(--m-t-petit); }
.m-prose strong, .m-prose b { font-weight: 700; }
.m-prose hr { border: 0; border-top: 1px solid var(--m-filet); margin-block: var(--m-esp-6, 32px); }

/* ── L'image et sa légende ── La légende sous l'image, en note ; le crédit
   à sa suite, plus pâle. Les coins : le petit rayon, partout. */
.m-figure { margin: 0; }
.m-figure img { display: block; width: 100%; height: auto; border-radius: var(--m-rayon-petit, 4px); background: var(--m-surface-douce, var(--m-gris-100)); }
.m-figure > figcaption { margin-top: var(--m-esp-2, 8px); font-size: var(--m-t-note); line-height: 1.45; color: var(--m-texte-2); }
.m-figure__credit { color: var(--m-texte-2); font-style: italic; }
.m-figure--une { max-width: none; }
/* ── Galerie de photos (`galerie()`, 11/11/2026) ── Des vignettes de MÊME
   taille (4/3, l'image recadrée au centre), leur légende dessous ; un clic
   ouvre la photo entière. Demandé sur la fiche RealT (Benjamin, 10/11/2026 :
   des photos de toutes les tailles, « faut trouver une autre manière »). */
.m-galerie { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr)); gap: var(--m-esp-4, 16px); margin: 0; padding: 0; list-style: none; }
.m-galerie .m-figure { max-width: none; }
.m-galerie img { aspect-ratio: 4 / 3; object-fit: cover; }
.m-galerie a { display: block; border-radius: var(--m-rayon-petit, 4px); }
.m-figure--une img { aspect-ratio: 16 / 9; object-fit: cover; }

/* ── Les lignes à filets ── Le nom à gauche, la valeur à droite en chiffres
   alignés, la précision dessous en gris ; un filet entre deux lignes. */
.m-lignes { list-style: none; margin: 0; padding: 0; font-size: var(--m-t-petit); }
.m-lignes > li { display: flex; align-items: baseline; justify-content: space-between; gap: var(--m-esp-4, 16px); padding: var(--m-esp-2, 8px) 0; }
.m-lignes > li + li { border-top: 1px solid var(--m-filet); }
.m-lignes__nom { min-width: 0; overflow-wrap: anywhere; }
.m-lignes a { color: var(--m-lien); text-decoration: none; }
.m-lignes a:hover { text-decoration: underline; }
.m-lignes__sous { display: block; font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-lignes__valeur { flex: none; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
/* Dans une carte étroite, le nom garde sa place : la valeur passe à la ligne
   au lieu de couper le nom lettre par lettre (« Airca / p / Agen / cy »). */
:is(.m-carte, .m-grille) .m-lignes > li { flex-wrap: wrap; }
:is(.m-carte, .m-grille) .m-lignes__nom { flex: 1 1 10rem; }
:is(.m-carte, .m-grille) .m-lignes__valeur { white-space: normal; }
.m-lignes--colonnes { max-width: none; columns: 14rem auto; column-gap: var(--m-esp-6, 32px); }
.m-lignes--colonnes > li { break-inside: avoid; border: 0; padding: var(--m-esp-1, 4px) 0; }
.m-lignes--colonnes > li:first-child { border: 0; }

/* ── Le journal daté ── La date dans sa colonne, le fait, la source en bout
   de ligne ; un filet entre deux faits. Sur téléphone, la date passe au-dessus. */
.m-journal { list-style: none; margin: 0; padding: 0; font-size: var(--m-t-petit); }
.m-journal > li {
  display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto; column-gap: var(--m-esp-4, 16px);
  align-items: baseline; padding: var(--m-esp-3, 12px) 0;
}
.m-journal > li + li { border-top: 1px solid var(--m-filet); }
.m-journal__date { font-size: var(--m-t-note); color: var(--m-texte-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.m-journal__fait { line-height: 1.5; }
.m-journal__fait > .m-etat { margin-right: var(--m-esp-1, 4px); }
.m-journal__nature { font-weight: 700; }
.m-journal__source { font-size: var(--m-t-note); white-space: nowrap; }
@media (max-width: 640px) {
  .m-journal > li { grid-template-columns: minmax(0, 1fr); row-gap: 2px; }
}

/* ── Le lien de source ── « Les Échos ↗ » : gris, souligné au survol. */
.m-lien-source { color: var(--m-texte-2); text-decoration: none; font-size: var(--m-t-note); }
.m-lien-source:hover { color: var(--m-lien); text-decoration: underline; }

/* ── Le lien de suite ── Sous le contenu d'une section, à gauche. */
.m-suite { margin: var(--m-esp-4, 16px) 0 0; font-weight: 600; }
.m-suite a { color: var(--m-lien); text-decoration: none; }
.m-suite a:hover { text-decoration: underline; }

/* ── La variation signée ── La flèche et le signe sont toujours écrits ; la
   couleur dit bonne (vert) ou mauvaise (rouge) nouvelle pour le lecteur. */
.m-variation { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.m-variation--ok { color: var(--etat-ok-texte); }
.m-variation--alerte { color: var(--etat-erreur-texte); }
.m-variation--neutre { color: var(--m-texte-2); }
.m-tableau td.m-bon .m-variation, .m-tableau td.m-mauvais .m-variation { color: inherit; }

/* ── La colonne que seul l'administrateur voit (`colonne_admin()` + classe
   `m-tableau__admin` sur ses cases) ── Le dessin d'`admin()` (fond gris,
   pointillé `--m-filet-fort`), posé sur les deux bords de la colonne. */
.m-tableau .m-tableau__admin { background: var(--m-gris-50); border-left: 1px dashed var(--m-filet-fort); border-right: 1px dashed var(--m-filet-fort); }
.m-tableau .m-tableau__admin + .m-tableau__admin { border-left: 0; }
.m-tableau thead .m-tableau__admin { color: var(--m-texte-2); }
.m-stat__variation { margin-top: var(--m-esp-1, 4px); font-size: var(--m-t-note); }
.m-tendance__variation.m-tendance--ok, .m-tendance__variation.m-tendance--alerte { font-weight: 600; }

/* ── La tuile principale ── LE chiffre de la rangée : deux colonnes, plus
   grand, en tête. */
.m-chiffres .m-stat--principal { grid-column: span 2; }
.m-chiffres .m-stat--principal .m-stat__num { font-size: var(--m-t-chiffre-grand); }

/* ── Le résultat d'un calcul ── En grand, sous les champs qui le
   produisent : ce qu'il mesure au-dessus, comment il est calculé dessous. */
.m-resultat { border-top: 2px solid var(--m-texte); padding-top: var(--m-esp-4, 16px); }
.m-resultat > p { margin: 0; }
.m-resultat__libelle { font-size: var(--m-t-petit); font-weight: 600; color: var(--m-texte-2); }
.m-resultat__valeur {
  font-family: var(--font-heading, inherit); font-size: var(--m-t-chiffre-grand); font-weight: 800;
  line-height: 1.15; font-variant-numeric: tabular-nums; margin-top: var(--m-esp-1, 4px);
}
.m-resultat__valeur .m-variation { font-family: var(--font-body, inherit); font-size: var(--m-t-petit); vertical-align: middle; }
.m-resultat__detail { font-size: var(--m-t-note); color: var(--m-texte-2); margin-top: var(--m-esp-2, 8px); }

/* ── Le compteur de résultats ── À gauche, avant la liste ; le nombre en gras. */
.m-compte { font-size: var(--m-t-note); color: var(--m-texte-2); margin: 0; }
.m-compte b { color: var(--m-texte); font-weight: 700; font-variant-numeric: tabular-nums; }
.m-tete .m-compte { margin-top: var(--m-esp-3, 12px); }

/* ── La jauge ── Une piste grise, la part remplie à la couleur de la série
   ou de l'état, les seuils en tirets avec leur nom, les bornes dessous. */
.m-jauge { max-width: 36rem; }
.m-jauge__tete { display: flex; align-items: baseline; justify-content: space-between; gap: var(--m-esp-3, 12px); margin: 0 0 var(--m-esp-2, 8px); }
.m-jauge__nom { font-size: var(--m-t-petit); color: var(--m-texte-2); }
.m-jauge__valeur { flex: none; white-space: nowrap; font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 800; font-variant-numeric: tabular-nums; }
.m-jauge__piste { position: relative; height: 12px; border-radius: var(--m-rayon-pilule, 999px); background: var(--m-gris-100); box-shadow: inset 0 0 0 1px var(--m-gris-200); }
.m-jauge__part { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--x) * 1%); min-width: 2px; border-radius: inherit; background: var(--c); }
.m-jauge__seuil { position: absolute; top: -6px; bottom: -6px; left: calc(var(--x) * 1%); border-left: 1px dashed var(--m-gris-600); }
.m-jauge__seuil--alerte { border-left-color: var(--etat-erreur-trait); }
.m-jauge__seuil--attention { border-left-color: var(--etat-alerte-trait); }
.m-jauge__seuil { top: calc(-6px - var(--rang, 0) * 1.4rem); }
.m-jauge__seuil .m-graph__annot { top: auto; bottom: calc(100% + 2px); left: 0; transform: translateX(-50%); white-space: nowrap; }
.m-jauge__bornes { display: flex; justify-content: space-between; margin: var(--m-esp-1, 4px) 0 0; font-size: var(--m-t-legende); color: var(--m-texte-2); font-variant-numeric: tabular-nums; }
.m-jauge:has(.m-jauge__seuil) .m-jauge__tete { margin-bottom: calc(var(--m-esp-5, 24px) + var(--rangs, 1) * 1.4rem - 1.4rem); }
/* Sous le doigt, la piste fine se touche sur 24 px (WCAG 2.2). */
.m-jauge__piste::before { content: ""; position: absolute; inset: -6px 0; }
.m-jauge__piste.m-graph--actif { box-shadow: inset 0 0 0 1px var(--m-gris-400); }

@media (max-width: 640px) {
  .m-chiffres .m-stat--principal { grid-column: 1 / -1; }
}

/* ══ Le camembert, et la source d'un graphique (11/11/2026) ══ */

/* ── Le camembert en anneau ── La part d'un tout : l'anneau, le total au
   centre, chaque part nommée à côté, dans l'ordre où elle tourne depuis midi
   (Benjamin, 11/11/2026). Survoler ou toucher une part met sa ligne en avant,
   et inversement (`static/js/graphiques.js`, `data-part`). */
.m-camembert { display: grid; grid-template-columns: minmax(9rem, 13rem) minmax(0, 1fr); gap: var(--m-esp-6, 32px); align-items: center; max-width: 52rem; }
.m-camembert__anneau { position: relative; aspect-ratio: 1; }
.m-camembert__anneau svg { display: block; width: 100%; height: 100%; overflow: visible; }
.m-camembert__fond { fill: none; stroke: var(--m-gris-100); stroke-width: 18; }
.m-camembert__part { fill: none; stroke: var(--c); stroke-width: 18; cursor: pointer; transition: stroke-width 0.12s; }
.m-camembert__part.m-graph--actif, .m-camembert__part:focus-visible { stroke-width: 23; }
/* Au clavier, la part prend aussi l'anneau de focus de la marque : l'épaisseur
   seule ne suffit pas comme repère (`test_focus_clavier_du_socle.py`). */
.m-camembert__part:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-camembert__centre {
  position: absolute; inset: 0; margin: 0; display: grid; place-content: center; text-align: center;
  pointer-events: none; line-height: 1.15;
}
/* Le total tient dans le trou de l'anneau (62 % de son diamètre) : la taille
   du niveau 4, et au besoin il passe à la ligne (« 24'645'740$ » touchait
   l'anneau à la taille d'un sous-titre, relevé le 11/11/2026). */
.m-camembert__centre { padding: 0 22%; }
.m-camembert__centre b { font-family: var(--font-heading, inherit); font-size: var(--m-t-niveau-4); font-weight: 800; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.m-camembert__centre span { font-size: var(--m-t-legende); color: var(--m-texte-2); margin-top: 2px; }
.m-camembert__parts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--m-esp-1, 4px); }
.m-camembert__parts > li {
  display: grid; grid-template-columns: 12px 3.75rem minmax(0, 1fr); column-gap: var(--m-esp-3, 12px); align-items: baseline;
  padding: var(--m-esp-2, 8px); border-radius: var(--m-rayon-petit, 4px); cursor: default; transition: background-color 0.12s;
}
.m-camembert__parts > li::before { content: ""; width: 12px; height: 12px; border-radius: 3px; background: var(--c); grid-row: 1 / span 2; align-self: center; }
.m-camembert__pct { font-family: var(--font-heading, inherit); font-weight: 800; font-size: var(--m-t-sous-titre); line-height: 1.1; font-variant-numeric: tabular-nums; grid-row: 1 / span 2; }
.m-camembert__nom { font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.m-camembert__detail { grid-column: 3; font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-camembert__parts > li.m-graph--actif { background: var(--m-gris-100); }
@media (max-width: 640px) {
  .m-camembert { grid-template-columns: minmax(0, 1fr); gap: var(--m-esp-4, 16px); }
  .m-camembert__anneau { width: min(13rem, 70vw); }
}

/* ── La source d'un graphique, d'un tableau, d'une image ── Un bouton
   « Source » sous le bloc, à droite, qui l'ouvre dans une bulle ; jamais une
   ligne de texte (Benjamin, 11/11/2026 : « un symbole comme le (?), mais une
   autre façon de le faire pour ne pas confondre source et information » ;
   « je veux pas supprimer, juste pas le faire en inline »).
   `graphique(g, source=...)` le pose dans la figure, `source(texte)`
   (`_page.html`) sous un autre bloc. Les `m-source` posés après un bloc par
   les pages pas encore passées sur la charte gardent le dessin discret
   ci-dessous, en attendant leur étape. */
.m-graph__source { display: flex; justify-content: flex-end; margin: var(--m-esp-2, 8px) 0 0; }
/* Le bouton « Source » : une étiquette rectangulaire, petite, grise, en
   capitales espacées ; ni le « ? » rond d'une définition, ni le numéro d'un
   renvoi. Sa bulle est celle des infobulles. */
.m-source-bouton {
  display: inline-flex; align-items: center; padding: var(--m-esp-1, 4px) var(--m-esp-2, 8px); border: 1px solid var(--m-filet, #e3e3e3);
  border-radius: var(--m-rayon-petit, 4px); background: transparent; color: var(--m-texte-2, #666); cursor: pointer;
  font: 600 var(--m-t-legende, 0.75rem)/1.4 var(--font-body, inherit); letter-spacing: 0.06em; text-transform: uppercase;
}
.m-source-bouton:hover, .m-source-bouton:focus-visible { color: var(--m-texte, #1a1a1a); border-color: currentColor; }
@media (pointer: coarse) {
  .m-source-bouton { position: relative; }
  .m-source-bouton::before { content: ""; position: absolute; inset: -12px -4px; }
}
:is(.m-graph, .m-defile, .m-tableau, .m-figure, .m-document, .m-grille, .m-classement) + .m-source {
  border-top: 0; padding-top: 0; margin-top: var(--m-esp-2, 8px); font-size: var(--m-t-legende); line-height: 1.45;
}
:is(.m-graph, .m-defile, .m-tableau, .m-figure, .m-document, .m-grille, .m-classement) + .m-source p { margin: 0; }
:is(.m-graph, .m-defile, .m-tableau, .m-figure, .m-document, .m-grille, .m-classement) + .m-source b { font-weight: 400; color: inherit; }

/* ══ Lot espace compte lecteur (11/11/2026) : la ligne de réglage, la fenêtre
   de confirmation. Construits pour `web.meelton.fr/account/` (Benjamin,
   11/11/2026 : refonte de l'espace compte, règle « copie de WordPress »
   levée), communs à toutes les pages qui en ont besoin. ══ */

/* ── La ligne de réglage ── Une chose qu'on reçoit ou qu'on suit (une
   newsletter, une entreprise) : son nom et une précision à gauche, son état à
   droite, ses réglages dessous (langue, édition), puis un lien discret pour
   l'arrêter. Un filet entre deux lignes. Le nom long passe à la ligne au lieu
   de pousser l'état hors de l'écran (mesuré sur téléphone le 11/11/2026). */
.m-reglages { list-style: none; margin: 0; padding: 0; }
.m-reglage { padding: var(--m-esp-4, 16px) 0; border-bottom: 1px solid var(--m-filet); }
.m-reglage:first-child { border-top: 1px solid var(--m-filet); }
.m-reglage__haut { display: flex; justify-content: space-between; align-items: baseline; gap: var(--m-esp-3, 12px); }
.m-reglage__haut > :last-child:not(.m-reglage__nom) { flex: none; }
.m-reglage__nom { min-width: 0; overflow-wrap: anywhere; font-weight: 700; color: var(--marque-encre, #1a1a1a); }
.m-reglage__nom a { color: inherit; }
.m-reglage__sous { display: block; font-weight: 400; font-size: var(--m-t-note); color: var(--m-texte-2); margin-top: 2px; }
.m-reglage--arret .m-reglage__nom { color: var(--m-texte-2); }
.m-reglage__champs { display: flex; flex-wrap: wrap; gap: var(--m-esp-3, 12px); margin-top: var(--m-esp-3, 12px); }
.m-reglage__champs > * { flex: 0 1 12rem; min-width: 0; }
/* Un bouton dans une ligne de réglage (« S'abonner ») garde sa largeur. */
.m-reglage__champs > .m-bouton { flex: none; }
.m-reglage__champs .m-champ { width: 100%; }
.m-reglage__pied { margin-top: var(--m-esp-2, 8px); font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-reglage__pied a, .m-reglage__pied button { color: var(--m-texte-2); text-decoration: underline; text-underline-offset: 0.15em; background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.m-reglage__pied [role="status"]:empty { display: none; }
@media (max-width: 560px) { .m-reglage__champs > * { flex: 1 1 9rem; } }

/* ── La fenêtre de confirmation ── Un `<dialog>` natif : le navigateur gère le
   focus, la touche Échap et le voile. Une question, deux boutons ; sur
   téléphone, les boutons passent l'un sous l'autre, le principal en haut.
   Remplace les boîtes du navigateur (`confirm()`), qu'une marque ne peut ni
   habiller ni traduire. */
.m-dialogue {
  border: 0; border-radius: var(--m-rayon, 8px); padding: var(--m-esp-6, 32px) var(--m-esp-5, 24px);
  max-width: min(28rem, calc(100vw - 32px)); width: 100%;
  color: var(--marque-encre, #1a1a1a); background: var(--neutre-surface, #fff);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
}
.m-dialogue::backdrop { background: rgba(15, 23, 42, 0.55); }
.m-dialogue__texte { margin: 0 0 var(--m-esp-5, 24px); line-height: 1.55; white-space: pre-line; }
/* Lot 8 (11/11/2026), la fenêtre qui envoie : une question en titre, le
   texte écrit par la page (sans le retour à la ligne forcé du texte rempli
   par script). */
.m-dialogue__titre { font-size: var(--m-t-sous-titre); font-weight: 700; line-height: 1.3; margin: 0 0 var(--m-esp-3, 12px); }
.m-dialogue__corps { margin: 0 0 var(--m-esp-5, 24px); line-height: 1.55; }
.m-dialogue__corps p { margin: 0; }
.m-dialogue__corps p + p { margin-top: var(--m-esp-2, 8px); }
.m-dialogue__actions { display: flex; gap: var(--m-esp-3, 12px); justify-content: flex-end; flex-wrap: wrap; }
@media (max-width: 480px) {
  .m-dialogue__actions { flex-direction: column-reverse; }
  .m-dialogue__actions .m-bouton { width: 100%; }
}

/* ══ Lot 3 des modules à construire (11/11/2026) : la mise en page d'un
   outil. Comportement : `static/js/outils.js`. Macros : `_page.html`. ══ */

/* ── Un champ d'outil ── Le libellé, le champ et son unité collée à droite,
   l'aide dessous en gris. */
.m-champ-outil { display: flex; flex-direction: column; gap: var(--m-esp-1, 4px); min-width: 0; }
.m-champ-outil .m-label { margin: 0; }
.m-champ-outil__ligne { position: relative; display: flex; }
.m-champ-outil__ligne--unite .m-champ { padding-right: 3.25rem; }
.m-champ-outil__unite {
  position: absolute; right: var(--m-esp-3, 12px); top: 50%; transform: translateY(-50%);
  color: var(--m-texte-2); font-size: var(--m-t-petit); pointer-events: none;
}
.m-champ-outil__aide { margin: 0; font-size: var(--m-t-note); color: var(--m-texte-2); line-height: 1.45; }
.m-champ-outil .m-champ { min-height: 2.75rem; }
.m-champ-outil .m-champ[type="number"] { font-variant-numeric: tabular-nums; }

/* ── Le compteur − / + ── Le nombre au milieu, deux boutons carrés collés. */
.m-compteur { display: inline-flex; align-items: stretch; width: max-content; }
.m-compteur .m-champ { width: 4.5rem; text-align: center; border-radius: 0; -moz-appearance: textfield; }
.m-compteur .m-champ::-webkit-outer-spin-button, .m-compteur .m-champ::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.m-compteur button {
  width: 2.75rem; border: 1px solid var(--m-filet-fort); background: var(--m-surface, #fff); color: var(--m-texte);
  font: inherit; font-size: var(--m-t-sous-titre); line-height: 1; cursor: pointer;
}
.m-compteur__moins { border-radius: var(--m-rayon-petit) 0 0 var(--m-rayon-petit); border-right: 0; }
.m-compteur__plus { border-radius: 0 var(--m-rayon-petit) var(--m-rayon-petit) 0; border-left: 0; }
.m-compteur button:hover { background: var(--m-gris-100); }
.m-compteur button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; position: relative; }

/* ── Le simulateur ── Les champs en deux colonnes sur grand écran, le bouton
   aligné à gauche, le résultat juste dessous. */
.m-simulateur { display: grid; gap: var(--m-esp-6, 32px); max-width: 52rem; }
.m-simulateur__champs { display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); gap: var(--m-esp-5, 24px) var(--m-esp-5, 24px); align-items: start; margin: 0; }
.m-simulateur__envoi { grid-column: 1 / -1; }

/* ── La page à encadré en marge ── Le contenu, et à droite un encadré qui
   reste en vue en défilant ; sur téléphone, l'encadré passe dessous. */
.m-avec-marge { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--m-esp-6, 32px); }
@media (min-width: 960px) {
  .m-avec-marge { grid-template-columns: minmax(0, 1fr) 21rem; gap: var(--m-esp-7, 48px); align-items: start; }
  .m-marge { position: sticky; top: var(--m-esp-5, 24px); }
}
.m-marge {
  border: 1px solid var(--m-filet); border-radius: var(--m-rayon, 8px); background: var(--m-surface, #fff);
  padding: var(--m-esp-5, 24px);
}
.m-marge__titre { margin: 0 0 var(--m-esp-3, 12px); font-weight: 700; font-size: var(--m-t-niveau-4); }
.m-marge > :last-child { margin-bottom: 0; }

/* ── Le choix en cartes ── Des cartes de même largeur et même hauteur, la
   choisie cerclée de la couleur de la marque ; la recommandée porte un
   badge. Le bouton radio reste là, pour le clavier et le lecteur d'écran. */
.m-choix { border: 0; margin: 0; padding: 0; min-width: 0; }
.m-choix > legend { padding: 0; margin-bottom: var(--m-esp-3, 12px); }
.m-choix__cartes { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); grid-auto-rows: 1fr; gap: var(--m-esp-3, 12px); align-items: stretch; }
/* `grid-auto-rows: 1fr` : la même hauteur sur TOUTES les rangées, pas
   seulement dans une rangée (six situations du guide Tudigo, 11/11/2026). */
.m-choix__carte {
  position: relative; display: flex; flex-direction: column; gap: var(--m-esp-2, 8px); cursor: pointer;
  padding: var(--m-esp-5, 24px) var(--m-esp-4, 16px) var(--m-esp-4, 16px);
  border: 1px solid var(--m-filet-fort); border-radius: var(--m-rayon, 8px); background: var(--m-surface, #fff);
  transition: border-color 0.12s, box-shadow 0.12s;
}
.m-choix__carte:hover { border-color: var(--m-gris-400); }
.m-choix__carte input { position: absolute; top: var(--m-esp-4, 16px); right: var(--m-esp-4, 16px); accent-color: var(--color-primary); width: 1.1rem; height: 1.1rem; margin: 0; }
.m-choix__carte:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); }
.m-choix__carte:has(input:focus-visible) { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-choix__titre { font-weight: 700; padding-right: var(--m-esp-6, 32px); }
.m-choix__chiffre { font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 800; font-variant-numeric: tabular-nums; }
.m-choix__texte { font-size: var(--m-t-petit); color: var(--m-texte-2); line-height: 1.45; }
.m-choix__badge {
  position: absolute; top: 0; left: var(--m-esp-4, 16px); transform: translateY(-50%);
  padding: 2px var(--m-esp-2, 8px); border-radius: var(--m-rayon-pilule, 999px);
  background: var(--color-primary); color: var(--neutre-sur-aplat, #fff); font-size: var(--m-t-legende); font-weight: 700;
}

/* ── Le questionnaire pas à pas ── La progression en haut (texte et barre),
   une question, la navigation en bas : « Précédent » à gauche, l'action à
   droite. */
.m-questionnaire { max-width: 40rem; display: grid; gap: var(--m-esp-5, 24px); }
.m-questionnaire__progression { display: grid; gap: var(--m-esp-2, 8px); }
.m-questionnaire__etape { margin: 0; font-size: var(--m-t-note); color: var(--m-texte-2); font-weight: 600; }
.m-questionnaire__barre { height: 6px; border-radius: var(--m-rayon-pilule, 999px); background: var(--m-gris-100); overflow: hidden; }
.m-questionnaire__barre > span { display: block; height: 100%; width: var(--avancement, 0%); background: var(--color-primary); transition: width 0.2s; }
.m-questionnaire__question { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--m-esp-4, 16px); }
.m-questionnaire__titre { padding: 0; font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 700; line-height: 1.3; }
.m-questionnaire__navigation { display: flex; gap: var(--m-esp-3, 12px); justify-content: space-between; flex-wrap: wrap; }
.m-questionnaire__navigation [data-suivant], .m-questionnaire__navigation [data-envoyer] { margin-left: auto; }
.m-questionnaire [hidden] { display: none; }

/* ── Le tiroir ── Un panneau à droite, sur toute la hauteur ; sur téléphone,
   une feuille qui monte du bas. Un seul voile, celui de la fenêtre. */
.m-tiroir {
  margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: min(28rem, 100vw); max-width: 100vw;
  border: 0; padding: 0; background: var(--neutre-surface, #fff); color: var(--marque-encre, #1a1a1a);
  box-shadow: -12px 0 40px rgba(0, 0, 0, 0.18);
}
.m-tiroir[open] { display: flex; flex-direction: column; }
.m-tiroir::backdrop { background: rgba(15, 23, 42, 0.55); }
.m-tiroir__tete {
  display: flex; align-items: center; justify-content: space-between; gap: var(--m-esp-3, 12px);
  padding: var(--m-esp-4, 16px) var(--m-esp-5, 24px); border-bottom: 1px solid var(--m-filet);
}
.m-tiroir__titre { margin: 0; font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 700; }
.m-tiroir__tete form { margin: 0; }
.m-tiroir__fermer {
  width: 2.5rem; height: 2.5rem; border: 0; border-radius: 50%; background: transparent; color: var(--m-texte-2);
  font-size: var(--m-t-section); line-height: 1; cursor: pointer;
}
.m-tiroir__fermer:hover { background: var(--m-gris-100); color: var(--m-texte); }
.m-tiroir__corps { padding: var(--m-esp-5, 24px); overflow-y: auto; flex: 1; }
@media (max-width: 640px) {
  .m-tiroir {
    margin: auto 0 0; width: 100vw; height: auto; max-height: 85dvh;
    border-radius: var(--m-rayon, 8px) var(--m-rayon, 8px) 0 0; box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.18);
  }
}

/* ══ Lot 7 des modules à construire (11/11/2026) : les formulaires.
   Comportement : `static/js/outils.js` (fin du fichier). Macros :
   `_page.html` (fin du fichier) et `_anti_robot.html`. ══ */

/* ── L'anti-robot ── Le piège est déjà invisible par son style EN LIGNE
   (`_anti_robot.html`) : cette règle le double, elle ne le porte jamais seule
   (un CSS en cache périmé l'a affiché le 25/08/2026). */
.m-anti-robot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.m-anti-robot__captcha { margin-top: var(--m-esp-2, 8px); }

/* ── Un champ facultatif le dit dans son libellé, en gris ; un message
   s'écrit sur plusieurs lignes et s'agrandit en hauteur seulement. */
.m-champ-outil__facultatif { font-weight: 400; color: var(--m-texte-2); }
.m-champ-outil__texte { min-height: 7.5rem; resize: vertical; line-height: 1.5; }

/* ── Le mot de passe ── Le bouton « Afficher » dans le champ, à droite ;
   enfoncé (le mot de passe en clair), il prend un fond. Sans script, il
   reste caché et le champ garde toute sa largeur. */
.m-mdp--actif .m-champ { padding-right: 6.5rem; }
.m-mdp__bouton {
  position: absolute; right: var(--m-esp-1, 4px); top: 50%; transform: translateY(-50%);
  min-height: 2.25rem; padding: 0 var(--m-esp-3, 12px); border: 0; border-radius: var(--m-rayon-petit, 4px);
  background: transparent; color: var(--m-texte-2); cursor: pointer;
  font: 600 var(--m-t-note)/1 var(--font-body, inherit);
}
.m-mdp__bouton:hover { color: var(--m-texte); background: var(--m-gris-100); }
.m-mdp__bouton[aria-pressed="true"] { color: var(--m-texte); background: var(--m-gris-100); }
.m-mdp__bouton:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.m-mdp__bouton[hidden] { display: none; }

/* ── Les lignes de saisie ── Une ligne par élément, son nom en titre, ses
   champs côte à côte sur grand écran, « Retirer » au bout ; un trait entre
   deux lignes, jamais au-dessus de la première ni sous la dernière. */
.m-repetable { border: 0; margin: var(--m-esp-4, 16px) 0 0; padding: 0; min-width: 0; }
.m-repetable > legend { padding: 0; margin-bottom: var(--m-esp-1, 4px); }
.m-repetable > .m-champ-outil__aide { margin-bottom: var(--m-esp-3, 12px); }
.m-repetable__lignes { display: grid; }
.m-repetable__ligne {
  padding: var(--m-esp-4, 16px) 0; min-width: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--m-esp-3, 12px) var(--m-esp-4, 16px); align-items: end;
}
.m-repetable__ligne + .m-repetable__ligne { border-top: 1px solid var(--m-filet); }
.m-repetable__ligne:first-child { padding-top: var(--m-esp-2, 8px); }
.m-repetable__titre { grid-column: 1 / -1; margin: 0; font-weight: 700; font-size: var(--m-t-petit); color: var(--m-texte); }
.m-repetable__champs { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: var(--m-esp-3, 12px) var(--m-esp-4, 16px); min-width: 0; }
.m-repetable__retirer {
  min-height: 2.75rem; padding: 0 var(--m-esp-2, 8px); border: 0; background: none; cursor: pointer;
  color: var(--m-texte-2); font: inherit; font-size: var(--m-t-note); text-decoration: underline; text-underline-offset: 0.15em;
}
.m-repetable__retirer:hover { color: var(--m-texte); }
.m-repetable__ajouter { margin: var(--m-esp-2, 8px) 0 0; }
.m-repetable [hidden] { display: none; }
@media (max-width: 560px) {
  .m-repetable__ligne { grid-template-columns: minmax(0, 1fr); }
  .m-repetable__retirer { justify-self: start; padding: 0; }
}

/* ── Le formulaire de contact, en carte ── Les champs courts côte à côte
   sur grand écran, le message sur toute la largeur, le bouton à gauche. */
.m-contact__titre { margin: 0 0 var(--m-esp-2, 8px); }
.m-contact__intro { margin: 0 0 var(--m-esp-5, 24px); color: var(--m-texte-2); line-height: 1.5; }
.m-contact__form { display: grid; gap: var(--m-esp-4, 16px); margin: 0; }
.m-contact__champs { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--m-esp-4, 16px); }
.m-contact__envoi { margin: var(--m-esp-2, 8px) 0 0; }

/* ══ Lot 4 (11/11/2026) : les hauts de page et les types de pages ══
   Macros : `tete(logo=, liens=, action=, bilan=)`, `selecteur()`,
   `suite_dossier()`, `texte_long()`, `message()` de `_page.html`, et
   `sous_menu(volets=, compteurs, sous-pages)` de `_navigation.html`. */

/* ── Haut de fiche : le visage de l'entité et ses liens sortants ── Le logo
   (ou les initiales) à gauche du titre, centré sur lui ; les liens vers
   d'autres sites en boutons discrets sous les états, trois au plus. */
.m-tete__identite { display: flex; align-items: center; gap: var(--m-esp-4, 16px); }
.m-tete__identite .m-tete__titre { min-width: 0; }
.m-tete__liens { display: flex; flex-wrap: wrap; gap: var(--m-esp-1, 4px) var(--m-esp-5, 24px); margin: var(--m-esp-3, 12px) 0 0; }
/* Discrets pour de bon : la police du texte, sans capitales espacées (une
   marque qui dessine ses boutons en capitales à chasse fixe, ZB, rendait
   trois liens sortants plus voyants que le titre), alignés à gauche quand
   un libellé passe à la ligne. */
.m-tete__liens .m-bouton--discret {
  padding-top: var(--m-esp-2, 8px); padding-bottom: var(--m-esp-2, 8px);
  font-family: inherit; font-size: var(--m-t-petit); text-transform: none; letter-spacing: normal; text-align: left;
}

/* ── En-tête d'outil : le titre de la vue à gauche, son contrôle à droite,
   alignés sur le bas du titre ; sur téléphone, le contrôle passe dessous. */
.m-tete__ligne { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--m-esp-4, 16px) var(--m-esp-6, 32px); }
.m-tete__vue { min-width: 0; flex: 1 1 20rem; }
.m-tete__action { flex: none; }
.m-selecteur { margin: 0; }
.m-selecteur .m-label { margin-bottom: var(--m-esp-1, 4px); }
.m-selecteur__ligne { display: flex; gap: var(--m-esp-2, 8px); align-items: stretch; }
.m-selecteur .m-champ { width: auto; min-width: 8rem; min-height: 2.75rem; box-sizing: border-box; }
.m-selecteur .m-bouton { min-height: 2.75rem; box-sizing: border-box; padding-top: 0; padding-bottom: 0; }

/* ── En-tête de dossier : pleine largeur, fond sombre ── Le titre, le
   chapeau et le BILAN, deux ou trois grands chiffres posés sur ce fond. Le
   chiffre se lit à son signe et à son libellé, jamais à sa couleur : la
   couleur de marque n'est pas une couleur de donnée (décision du
   24/10/2026). Les couleurs du bandeau sont des jetons, inversés en mode
   sombre : le bandeau y reste sombre (une surface à peine levée). Contraste
   mesuré au navigateur, clair et sombre (`test_socle_lisible.py`). */
:where(:root) {
  --m-dossier-fond: var(--marque-encre, #1a1a1a);
  --m-dossier-texte: var(--marque-fond, #fff);
  --m-dossier-texte-2: color-mix(in oklab, var(--marque-fond, #fff) 76%, var(--marque-encre, #1a1a1a));
  --m-dossier-filet: color-mix(in oklab, var(--marque-fond, #fff) 22%, var(--marque-encre, #1a1a1a));
}
@media screen {
  :where(html[data-mode="sombre"]) {
    --m-dossier-fond: var(--m-gris-100);
    --m-dossier-texte: var(--marque-encre, #f2f2f2);
    --m-dossier-texte-2: color-mix(in oklab, var(--marque-encre, #f2f2f2) 76%, var(--marque-fond, #0d0d0d));
    --m-dossier-filet: var(--m-gris-300);
  }
}
.m-tete--dossier {
  --m-texte: var(--m-dossier-texte); --m-texte-2: var(--m-dossier-texte-2);
  --marque-gris: var(--m-dossier-texte-2); --m-lien: var(--m-dossier-texte);
  --m-surtitre-couleur: var(--m-dossier-texte-2);
  background: var(--m-dossier-fond); color: var(--m-dossier-texte);
  padding: var(--m-esp-7, 48px) var(--m-esp-6, 32px);
  border-radius: var(--m-rayon, 8px);
}
/* Posé directement dans la page, le bandeau court d'un bord à l'autre de
   l'écran : le fond déborde à la peinture (ombre pleine rognée en haut et en
   bas), sans élargir la page ni créer de défilement de côté. */
.m-page > .m-tete--dossier {
  padding-left: 0; padding-right: 0; border-radius: 0;
  box-shadow: 0 0 0 100vmax var(--m-dossier-fond); clip-path: inset(0 -100vmax);
}
.m-tete--dossier .m-tete__titre, .m-tete--dossier .m-tete__chapeau, .m-tete--dossier .m-tete__signature { color: inherit; }
.m-tete--dossier .m-tete__signature { color: var(--m-dossier-texte-2); }
.m-tete__bilan {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--m-esp-5, 24px) var(--m-esp-6, 32px);
  margin: var(--m-esp-6, 32px) 0 0; padding: var(--m-esp-5, 24px) 0 0;
  border-top: 1px solid var(--m-dossier-filet);
}
.m-tete__bilan-chiffre { margin: 0; display: flex; flex-direction: column; gap: var(--m-esp-1, 4px); }
.m-tete__bilan-num {
  font-family: var(--font-heading, inherit); font-size: var(--m-t-chiffre-grand); font-weight: 800;
  line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--m-dossier-texte); white-space: nowrap;
}
.m-tete__bilan-libelle { font-size: var(--m-t-petit); line-height: 1.45; color: var(--m-dossier-texte-2); text-wrap: pretty; }
@media (max-width: 640px) {
  .m-tete--dossier { padding: var(--m-esp-6, 32px) var(--m-esp-4, 16px); }
  .m-page > .m-tete--dossier { padding-left: 0; padding-right: 0; }
}

/* ── Sous-menu : compteurs, second niveau, volets d'un dossier ── */
.m-sous-menu__compte {
  margin-left: var(--m-esp-2, 8px); font-size: var(--m-t-note); font-weight: 400;
  color: var(--m-texte-2); font-variant-numeric: tabular-nums;
}
/* Deux niveaux : la ligne des entrées (le dessin du sous-menu), puis celle
   des sous-pages de l'entrée active, en pastilles plus petites. */
.m-sous-menu--deux { display: block; border-bottom: 0; overflow: visible; }
.m-sous-menu__niveau {
  display: flex; gap: var(--m-esp-1, 4px) var(--m-esp-6, 32px); overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--m-filet);
}
@media (min-width: 900px) { .m-sous-menu__niveau { flex-wrap: wrap; overflow: visible; } }
.m-sous-menu__niveau a[aria-current] { color: var(--marque-encre, #1a1a1a); font-weight: 600; border-bottom-color: var(--color-primary); }
.m-sous-menu__sous { display: flex; gap: var(--m-esp-2, 8px); overflow-x: auto; scrollbar-width: none; padding: var(--m-esp-3, 12px) 0 0; }
@media (min-width: 900px) { .m-sous-menu__sous { flex-wrap: wrap; overflow: visible; } }
.m-sous-menu .m-sous-menu__sous a {
  padding: var(--m-esp-1, 4px) var(--m-esp-3, 12px); margin: 0; border: 0; border-radius: var(--m-rayon-pilule, 999px);
  font-size: var(--m-t-note); color: var(--m-texte-2);
}
.m-sous-menu .m-sous-menu__sous a:hover { color: var(--m-texte); background: var(--m-gris-100); }
.m-sous-menu .m-sous-menu__sous a[aria-current="page"] { color: var(--m-texte); background: var(--m-marque-100); font-weight: 600; }
/* Les volets d'un dossier : la position en tête, chaque volet numéroté. */
.m-sous-menu--volets { align-items: baseline; }
.m-sous-menu__position {
  flex: none; align-self: center; font-size: var(--m-t-note); font-weight: 700; color: var(--m-texte-2);
  font-variant-numeric: tabular-nums; padding-right: var(--m-esp-2, 8px);
}
.m-sous-menu__num {
  display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem; height: 1.5rem;
  margin-right: var(--m-esp-2, 8px); border-radius: var(--m-rayon-pilule, 999px);
  border: 1px solid var(--m-filet-fort); font-size: var(--m-t-legende); font-weight: 700; font-variant-numeric: tabular-nums;
}
.m-sous-menu a[aria-current="page"] .m-sous-menu__num { background: var(--marque-encre, #1a1a1a); border-color: var(--marque-encre, #1a1a1a); color: var(--marque-fond, #fff); }

/* ── L'appel « dossier suivant » ── En fin de dossier : un seul lien, sur
   toute la largeur, fond doux de la marque, le titre en grand. */
.m-suite-dossier__lien {
  display: flex; flex-direction: column; gap: var(--m-esp-1, 4px);
  padding: var(--m-esp-5, 24px) var(--m-esp-6, 32px); border-radius: var(--m-rayon, 8px);
  background: var(--m-marque-50); border: 1px solid var(--m-marque-200);
  color: var(--m-texte); text-decoration: none;
}
.m-suite-dossier__lien:hover { background: var(--m-marque-100); }
.m-suite-dossier__libelle {
  font-family: var(--m-label-police, inherit); font-size: var(--m-label-taille, 0.8rem);
  text-transform: var(--m-label-casse, uppercase); letter-spacing: var(--m-label-espacement, 0.08em);
  color: var(--m-texte-2);
}
.m-suite-dossier__titre { font-family: var(--font-heading, inherit); font-size: var(--m-t-section); font-weight: 700; line-height: 1.25; text-wrap: balance; }
.m-suite-dossier__lien:hover .m-suite-dossier__titre { text-decoration: underline; text-underline-offset: 0.15em; }
.m-suite-dossier__texte { font-size: var(--m-t-petit); color: var(--m-texte-2); text-wrap: pretty; }
@media (max-width: 640px) { .m-suite-dossier__lien { padding: var(--m-esp-4, 16px); } }

/* ── Le texte long (méthode, pages légales) ── Le sommaire à gauche, le
   texte dans la colonne de lecture. Les listes gardent leurs puces même sous
   une remise à zéro (Tailwind de ZB) ; le premier intertitre colle au haut. */
.m-prose ul { list-style: disc; }
.m-prose ol { list-style: decimal; }
.m-texte-page .m-prose > h2:first-child { margin-top: 0; }

/* ── La page de message ── Un bloc qui se suffit à lui-même : centré, dans
   la colonne étroite, l'état, le titre, une phrase, un lien. */
.m-message {
  max-width: var(--m-colonne-etroite, 680px); margin: 0 auto; text-align: center;
  padding: var(--m-esp-8, 64px) 0;
}
.m-message__etat { margin: 0 0 var(--m-esp-4, 16px); }
.m-message__titre {
  font-family: var(--font-heading, inherit); font-size: var(--m-t-section); font-weight: var(--m-section-graisse, 700);
  line-height: 1.2; color: var(--m-texte); margin: 0; text-wrap: balance;
}
.m-message__texte { font-size: var(--m-t-corps); line-height: 1.6; color: var(--m-texte-2); margin: var(--m-esp-3, 12px) 0 0; text-wrap: pretty; }
.m-message__lien { margin: var(--m-esp-5, 24px) 0 0; font-weight: 600; }
.m-message__lien a { color: var(--m-lien); text-underline-offset: 0.15em; }
/* Lot 8 (11/11/2026), les pages de service : ce que la page demande au
   lecteur, sous la phrase. Les champs et les listes s'alignent à gauche (on
   lit un libellé de gauche à droite), les boutons et les notes restent
   centrés comme le titre. Un écart régulier entre chaque morceau. */
.m-message__corps { margin: var(--m-esp-5, 24px) 0 0; text-align: left; }
.m-message__corps > * + *,
.m-message__corps form > * + * { margin-top: var(--m-esp-4, 16px); }
.m-message__corps .m-actions { justify-content: center; }
.m-message__corps .m-alerte { margin-bottom: 0; text-align: center; }
.m-message__corps .m-note { text-align: center; }
.m-message__corps .m-section { margin-top: var(--m-esp-6, 32px); }
/* Sous le titre du message, une section reste un cran plus bas que lui. */
.m-message__corps .m-section__titre { font-size: var(--m-t-sous-titre); }
/* L'adresse concernée par le geste : elle se relit avant de confirmer. */
.m-message__adresse {
  text-align: center; font-size: var(--m-t-petit); color: var(--m-texte-2);
  overflow-wrap: anywhere; margin: 0;
}
.m-message__adresse strong { color: var(--m-texte); font-weight: 600; }

/* ══ Lot 6 des modules à construire (11/11/2026) : boîtes, cartes et
   contenus. Macros : fin de `_page.html`. Chaque bloc remplace de 2 à 6
   dessins relevés le 10/11/2026 (catalogue de la charte). Règles tenues :
   une boîte isole un objet, un seul filet gris, aucune ombre, aucun trait de
   couleur à gauche (réservé aux encadrés), la couleur de marque aux liens et à
   ce qui est actif. ══ */

/* ── Le petit bouton, le bouton sur fond foncé ── Le petit : dans une ligne
   de tableau, une barre d'outils, à côté d'un bloc (« Copier »). Sur fond
   foncé : plein du fond de la page, ou en contour clair. */
.m-bouton--petit { padding: var(--m-esp-1) var(--m-esp-3); font-size: var(--m-t-note); border-radius: var(--m-rayon-petit, 4px); line-height: 1.5; white-space: nowrap; }
.m-bouton--discret.m-bouton--petit { padding-left: 0; padding-right: 0; }
.m-bouton--sur-fonce {
  background: var(--m-appel-texte, var(--marque-fond, var(--m-surface))); color: var(--m-appel-fond, var(--m-marque-900));
  border: 1px solid var(--m-appel-texte, var(--marque-fond, var(--m-surface)));
}
.m-bouton--sur-fonce:hover { background: var(--m-appel-texte, var(--marque-fond, var(--m-surface))); color: var(--m-appel-fond, var(--m-marque-900)); opacity: 0.88; transform: none; }
.m-bouton--contour.m-bouton--sur-fonce { background: transparent; color: var(--m-appel-texte, var(--marque-fond, var(--m-surface))); border: 1px solid var(--m-appel-texte, var(--marque-fond, var(--m-surface))); }
.m-bouton--contour.m-bouton--sur-fonce:hover { background: color-mix(in oklab, var(--m-appel-texte, var(--marque-fond, var(--m-surface))) 14%, transparent); color: var(--m-appel-texte, var(--marque-fond, var(--m-surface))); opacity: 1; }

/* ── La carte d'article (`carte_article()`) ── Remplace le dessin recopié du
   thème WordPress (`site-marque.css` jusqu'au 11/11/2026) : mêmes classes, que
   des pages et des tests lisent, mais les jetons de la charte. Plus aucune
   animation au survol (la carte montait de 4 px, l'image grossissait) : le
   titre se souligne. La date passe au gris de texte secondaire de la charte
   (4,5 pour 1 au moins, mesuré à chaque passage ; le gris pâle d'avant
   donnait 2,8), sans capitales. ⚠️ Ce gris pâle avait été REMIS par Benjamin
   le 28/09/2026 (« si le contraste doit monter, ça se tranche avec lui ») :
   le changement lui est soumis avec les captures du lot 6, avant fusion. */
.articles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); gap: var(--m-esp-6) var(--m-esp-5); }
.article-card { display: block; color: inherit; text-decoration: none; min-width: 0; }
.article-card:hover { text-decoration: none; }
.article-card:hover .article-card__title { color: var(--m-lien); text-decoration: underline; text-underline-offset: 0.15em; }
.article-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: var(--m-esp-1); border-radius: var(--m-rayon-petit, 4px); }
.article-card__image { aspect-ratio: 1 / 1; overflow: hidden; border-radius: var(--m-rayon, 8px); margin-bottom: var(--m-esp-3); background: var(--m-surface-douce); }
/* Le dégradé de marque en guise de vignette, quand d'autres cartes de la
   grille ont une image : il évite une grille de trous. */
.article-card__degrade { width: 100%; height: 100%; background: linear-gradient(135deg, var(--m-marque-100), var(--m-marque-400)); }
.article-card__image picture { display: block; width: 100%; height: 100%; }
.article-card__image img { display: block; width: 100%; height: 100%; object-fit: cover; }
.article-card__title {
  font-family: var(--font-heading, inherit); font-size: var(--m-t-niveau-4); font-weight: 700;
  line-height: 1.3; color: var(--m-texte); margin: 0 0 var(--m-esp-1); text-wrap: pretty;
}
.article-card__subtitle {
  font-size: var(--m-t-petit); line-height: 1.45; color: var(--m-texte-2); margin: 0 0 var(--m-esp-2);
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* L'accroche d'un dossier, écrite pour la vitrine : jamais coupée (25/10/2026). */
.article-card__subtitle--entier { display: block; -webkit-line-clamp: unset; line-clamp: none; overflow: visible; }
/* Le corps d'une fiche de nomination, sous le nom (24/09/2026). */
.article-card__texte { margin: var(--m-esp-2) 0 0; font-size: var(--m-t-petit); line-height: 1.55; color: var(--m-texte-2); }
.article-card__date { margin: 0; font-size: var(--m-t-note); line-height: 1.45; color: var(--m-texte-2); font-variant-numeric: tabular-nums; }
.article-card__date + .article-card__title { margin-top: var(--m-esp-1); }
.article-card__numero { margin: 0; font-size: var(--m-t-note); font-weight: 700; color: var(--m-lien); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* La une : grande image 16/9 à gauche, le texte à droite ; dessous sur
   téléphone. Elle prend toute la largeur de la grille. */
.articles-grid > .article-card--une { grid-column: 1 / -1; }
.article-card--une .article-card__image { aspect-ratio: 16 / 9; }
.article-card--une .article-card__title { font-size: var(--m-t-section); line-height: 1.2; letter-spacing: var(--m-titre-espacement, -0.01em); }
.article-card--une .article-card__subtitle { font-size: var(--m-t-corps); }
@media (min-width: 768px) {
  .article-card--une:has(> .article-card__image) { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); column-gap: var(--m-esp-6); align-content: start; }
  .article-card--une > .article-card__image { grid-row: 1 / span 6; margin: 0; }
  .article-card--une:has(> .article-card__image) > :not(.article-card__image) { grid-column: 2; }
}

/* La liste et les numéros : une ligne par article, un filet ENTRE deux. */
.articles-grid--liste, .articles-grid--numero { display: block; }
.articles-grid--liste > .article-card + .article-card,
.articles-grid--numero > .article-card + .article-card { border-top: 1px solid var(--m-filet); }
.article-card--liste { display: flex; align-items: baseline; justify-content: space-between; gap: var(--m-esp-4); padding: var(--m-esp-3) 0; }
.article-card--liste .article-card__title { font-family: var(--font-body, inherit); font-size: var(--m-t-corps); font-weight: 600; margin: 0; }
.article-card--liste .article-card__date { flex: none; white-space: nowrap; }
.article-card--numero {
  display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) auto; column-gap: var(--m-esp-4);
  grid-template-areas: "n t d" ". s s"; align-items: baseline; padding: var(--m-esp-3) 0;
}
.article-card--numero .article-card__numero { grid-area: n; }
.article-card--numero .article-card__title { grid-area: t; font-family: var(--font-body, inherit); font-size: var(--m-t-corps); font-weight: 600; margin: 0; }
.article-card--numero .article-card__subtitle { grid-area: s; margin: var(--m-esp-1) 0 0; }
.article-card--numero .article-card__date { grid-area: d; white-space: nowrap; }
.articles-grid--liste > .article-card:first-child, .articles-grid--numero > .article-card:first-child { padding-top: 0; }
@media (max-width: 640px) {
  .article-card--liste { flex-direction: column; gap: var(--m-esp-1); }
  .article-card--numero { grid-template-columns: minmax(0, 1fr); grid-template-areas: "n" "t" "s" "d"; row-gap: 2px; }
}

/* ── La brève (`breve()`) ── Le texte, sa source dessous en note ; un filet
   ENTRE deux brèves. Le mot en gras (la catégorie) à l'encre, en gras : la
   couleur de marque est réservée aux liens et à l'actif (10/08/2026). Le
   sélecteur `a.media-breve__source` passe devant `.media a` (même force,
   déclaré après) : plus besoin du `!important` d'avant. */
.media-breves { list-style: none; margin: 0; padding: 0; }
/* Dans une section de page, la liste garde l'écart de 16 px des blocs. */
.m-section__corps > .media-breves:not(:first-child) { margin-top: var(--m-esp-4, 16px); }
.media-breve { padding: var(--m-esp-2) 0; font-size: var(--m-t-petit); line-height: 1.5; }
.media-breve + .media-breve { border-top: 1px solid var(--m-filet); }
.media-breve:first-child { padding-top: 0; }
.media-breve strong, .media-breve b { font-weight: 700; color: var(--m-texte); }
/* La source posée en lien reste SOULIGNÉE : grise, sans soulignement, rien ne
   dit qu'on peut cliquer (constaté au rendu avant fusion, 11/11/2026). */
.media-breve__source, a.media-breve__source { display: block; margin-top: 2px; font-size: var(--m-t-note); color: var(--m-texte-2); text-decoration: none; }
a.media-breve__source { text-decoration: underline; text-underline-offset: 2px; }
a.media-breve__source:hover { color: var(--m-lien); }

/* ── Le rappel juridique (`rappel()`) ── Sous le contenu, en note grise, un
   filet au-dessus : on le trouve, il ne passe pas devant. */
.m-rappel { border-top: 1px solid var(--m-filet); padding-top: var(--m-esp-4); font-size: var(--m-t-note); line-height: 1.55; color: var(--m-texte-2); text-wrap: pretty; }
.m-rappel > p { margin: 0; }
.m-rappel > p + p { margin-top: var(--m-esp-2); }
.m-rappel__titre { font-weight: 700; color: var(--m-texte); }

/* ── La note sur 100 (`note_score()`) ── La note en grand, son maximum en
   gris, puis le tableau des critères (mini-barres communes). */
.m-note-score { display: grid; gap: var(--m-esp-4); }
.m-note-score__tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--m-esp-2) var(--m-esp-4); margin: 0; }
.m-note-score__valeur { font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); color: var(--m-texte-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.m-note-score__valeur b { font-size: var(--m-t-chiffre-grand); font-weight: 800; color: var(--m-texte); }
.m-note-score__libelle { font-size: var(--m-t-petit); color: var(--m-texte-2); }

/* ── La note sur 5 (`avis()`) ── Les étoiles à l'encre sur une piste grise,
   la part remplie au dixième ; la note écrite à côté, toujours. */
.m-avis { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--m-esp-1) var(--m-esp-2); margin-inline: 0; margin-bottom: 0; font-size: var(--m-t-petit); }
.m-avis__etoiles { position: relative; display: inline-block; color: var(--m-gris-500); font-size: var(--m-t-sous-titre); line-height: 1; letter-spacing: 0.08em; white-space: nowrap; }
.m-avis__plein { position: absolute; left: 0; top: 0; width: var(--part, 0%); overflow: hidden; color: var(--m-texte); }
.m-avis__note { font-weight: 700; font-variant-numeric: tabular-nums; }
.m-avis__nombre { color: var(--m-texte-2); }

/* ── Le modèle à copier (`modele()`) et le code à copier (`code(id=...)`) ──
   Le texte à part, dans une boîte au filet gris ; le bouton « Copier » en
   tête, à droite (il n'apparaît qu'avec le script, qui seul sait copier). */
.m-modele { margin-inline: 0; margin-bottom: 0; border: 1px solid var(--m-filet); border-radius: var(--m-rayon, 8px); background: var(--m-surface); }
.m-modele__tete { display: flex; align-items: center; justify-content: space-between; gap: var(--m-esp-3); padding: var(--m-esp-2) var(--m-esp-4); border-bottom: 1px solid var(--m-filet); }
.m-modele__titre { font-size: var(--m-t-note); font-weight: 600; color: var(--m-texte-2); }
.m-modele__texte { padding: var(--m-esp-4); font-size: var(--m-t-petit); line-height: 1.65; overflow-wrap: anywhere; }
.m-modele__texte > p { margin: 0; }
.m-modele__texte > p + p { margin-top: var(--m-esp-3); }
.m-code-copie { display: grid; }
.m-code-copie > .m-bouton { justify-self: end; }

/* ── L'index alphabétique (`index_alpha()`) ── Les 26 lettres, en carrés
   égaux ; une lettre vide en gris, sans cadre : elle dit qu'il n'y a rien. */
.m-index ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--m-esp-1); }
.m-index a, .m-index span { display: inline-grid; place-items: center; min-width: 1.75rem; min-height: 2rem; border-radius: var(--m-rayon-petit, 4px); font-size: var(--m-t-petit); font-weight: 600; text-decoration: none; font-variant-numeric: tabular-nums; }
.m-index a { color: var(--m-lien); border: 1px solid var(--m-filet); }
.m-index a:hover { border-color: var(--m-lien); }
.m-index a[aria-current] { background: var(--m-texte); border-color: var(--m-texte); color: var(--marque-fond, var(--m-surface)); }
.m-index span { color: var(--m-texte-2); font-weight: 400; }

/* ── Le glossaire (`glossaire()`) ── L'index en tête, puis une lettre par
   groupe ; un filet ENTRE deux termes. Une ancre visée garde de l'air
   au-dessus d'elle. */
.m-glossaire { display: grid; gap: var(--m-esp-6); }
.m-glossaire__groupe, .m-glossaire dt[id] { scroll-margin-top: var(--m-esp-8); }
.m-glossaire__lettre { font-family: var(--font-heading, inherit); font-size: var(--m-t-sous-titre); font-weight: 700; line-height: 1.25; color: var(--m-texte); margin: 0 0 var(--m-esp-2); }
.m-glossaire dl { margin: 0; }
.m-glossaire dt { font-weight: 700; color: var(--m-texte); }
.m-glossaire dd { margin: var(--m-esp-1) 0 0; padding-bottom: var(--m-esp-3); line-height: 1.6; text-wrap: pretty; }
.m-glossaire dd + dt { border-top: 1px solid var(--m-filet); padding-top: var(--m-esp-3); }

/* ── Ce que seul l'administrateur voit (`admin()`) ── Un cadre en pointillé
   gris, le libellé en tête : un seul dessin, jamais d'ambre (l'ambre dit
   « attention » au lecteur). */
.m-admin { border: 1px dashed var(--m-filet-fort); border-radius: var(--m-rayon, 8px); background: var(--m-gris-50); padding: var(--m-esp-4); font-size: var(--m-t-petit); }
.m-admin__libelle { margin: 0 0 var(--m-esp-2); font-size: var(--m-t-note); font-weight: 600; color: var(--m-texte-2); }
.m-admin__libelle b { color: var(--m-texte); }
.m-admin > :last-child { margin-bottom: 0; }

/* ── La mention de partenariat (`partenariat()`) ── Une ligne en note, le
   logo devant à hauteur fixe. */
.m-partenaire { display: flex; align-items: center; flex-wrap: wrap; gap: var(--m-esp-3); margin-inline: 0; margin-bottom: 0; font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-partenaire__logo { height: 2rem; width: auto; max-width: 8rem; object-fit: contain; }
.m-partenaire a { color: var(--m-lien); font-weight: 600; }
.m-partenaire b { color: var(--m-texte); font-weight: 600; }

/* ── L'appel à témoignage (`signaler()`) ── Le repli commun, son titre à la
   couleur des liens : c'est une invitation à ouvrir. */
.m-signaler > summary { color: var(--m-lien); }

/* ── Le bandeau d'appel final (`appel()`) ── Fond plein foncé de la marque
   (degré 900), le texte à la couleur du fond de page. En mode sombre, le
   degré 900 s'éclaircit avec l'encre : le bandeau prend alors le degré 100
   (foncé teinté) et l'encre, pour rester un aplat foncé sur une page noire
   (mesuré au rendu, 11/11/2026 : un aplat rose pâle sur la page noire). Ses
   boutons lisent les mêmes deux valeurs (`--m-appel-fond`, `--m-appel-texte`). */
.m-appel {
  --m-appel-fond: var(--m-marque-900); --m-appel-texte: var(--marque-fond, var(--m-surface));
  background: var(--m-appel-fond); color: var(--m-appel-texte); border-radius: var(--m-rayon, 8px); padding: var(--m-esp-7) var(--m-esp-6);
}
@media screen { :where(html[data-mode="sombre"]) .m-appel { --m-appel-fond: var(--m-marque-100); --m-appel-texte: var(--m-texte); } }
.m-appel__titre { font-family: var(--font-heading, inherit); font-size: var(--m-t-section); font-weight: 700; line-height: 1.2; letter-spacing: var(--m-titre-espacement, -0.01em); color: inherit; margin: 0; text-wrap: balance; }
.m-appel__texte { margin: var(--m-esp-3) 0 0; font-size: var(--m-t-corps); line-height: 1.55; text-wrap: pretty; }
.m-appel > .m-actions { margin-top: var(--m-esp-5); }
.m-appel a:not([class]) { color: inherit; }
@media (max-width: 640px) { .m-appel { padding: var(--m-esp-6) var(--m-esp-4); } }

/* ── La réponse en tête, en texte (`reponse()`) ── La phrase de la réponse
   sans chiffre : même police, un cran moins gras. */
.m-phrase-chiffre--texte { font-weight: 500; text-wrap: pretty; }
.m-phrase-chiffre + .m-phrase-chiffre { margin-top: var(--m-esp-4, 16px); }

/* ── La formule posée (`formule()`) ── L'opération dans sa colonne, ce
   qu'on prend, sa valeur à droite ; le résultat en gras sous un filet fort. */
.m-formule { margin-inline: 0; margin-bottom: 0; font-size: var(--m-t-petit); font-variant-numeric: tabular-nums; }
.m-formule__ligne { display: flex; align-items: baseline; justify-content: space-between; gap: var(--m-esp-4); padding: var(--m-esp-2) 0; }
.m-formule__ligne + .m-formule__ligne { border-top: 1px solid var(--m-filet); }
.m-formule dt, .m-formule dd { margin: 0; }
.m-formule dd { white-space: nowrap; text-align: right; }
.m-formule__op { display: inline-block; min-width: 1.5rem; font-weight: 700; color: var(--m-texte-2); }
.m-formule > .m-formule__ligne--resultat { border-top: 2px solid var(--m-texte); font-weight: 700; }

/* ── La règle citée (`regle()`) ── Le texte mot pour mot sur le fond doux,
   sa référence dessous en note. Ni guillemets décoratifs, ni trait à gauche. */
.m-regle { margin-inline: 0; margin-bottom: 0; background: var(--m-surface-douce); border-radius: var(--m-rayon, 8px); padding: var(--m-esp-4) var(--m-esp-5); }
.m-regle__texte { margin: 0; font-size: var(--m-t-petit); line-height: 1.65; text-wrap: pretty; }
.m-regle__texte > p { margin: 0; }
.m-regle__texte > p + p { margin-top: var(--m-esp-2); }
.m-regle__source { margin-top: var(--m-esp-2); font-size: var(--m-t-note); color: var(--m-texte-2); }

/* ── Les cartes du lot 6 (`carte_entite()`, `carte_avant()`,
   `carte_tache()`) ── La carte du socle, sans ombre (la charte n'en a
   aucune) ; le nom de la carte au troisième niveau, à l'encre. */
.m-carte--entite, .m-carte--avant, .m-carte--tache { box-shadow: none; padding: var(--m-esp-5); position: relative; display: flex; flex-direction: column; gap: var(--m-esp-3); }
.m-carte__nom { font-family: var(--font-heading, inherit); font-size: var(--m-t-niveau-4); font-weight: 700; line-height: 1.3; color: var(--m-texte); margin: 0; text-wrap: pretty; }
.m-carte__nom a { color: inherit; text-decoration: none; }
.m-carte__sous { margin: var(--m-esp-1) 0 0; font-size: var(--m-t-note); color: var(--m-texte-2); }
:is(.m-carte--entite, .m-carte--avant, .m-carte--tache) > p, .m-carte__texte > p { margin: 0; }
.m-carte__texte { font-size: var(--m-t-petit); line-height: 1.55; }
/* La fiche résumée : le visage et le nom, les états, une ligne de chiffres ;
   toute la carte se clique (le lien du nom la couvre). */
.m-carte__tete { display: flex; align-items: center; gap: var(--m-esp-3); min-width: 0; }
.m-carte--entite .m-carte__nom a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.m-carte--entite:has(.m-carte__nom a) { transition: border-color 0.15s; }
.m-carte--entite:has(.m-carte__nom a:hover) { border-color: var(--m-lien); }
.m-carte--entite:has(.m-carte__nom a:hover) .m-carte__nom { color: var(--m-lien); text-decoration: underline; }
.m-carte--entite:has(.m-carte__nom a:focus-visible) { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-carte__etats { display: flex; flex-wrap: wrap; gap: var(--m-esp-2); }
.m-carte__chiffres { display: flex; flex-wrap: wrap; gap: var(--m-esp-2) var(--m-esp-5); margin: 0; padding-top: var(--m-esp-3); border-top: 1px solid var(--m-filet); }
.m-carte__chiffres > div { display: flex; flex-direction: column-reverse; }
.m-carte__chiffres dt { font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-carte__chiffres dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* La carte mise en avant : le fond pâle de la marque et son badge, posé à
   cheval sur le bord du haut. */
.m-carte--avant { background: var(--m-marque-50); border-color: var(--m-marque-300); margin-top: var(--m-esp-3); }
.m-carte__badge {
  position: absolute; top: 0; left: var(--m-esp-5); transform: translateY(-50%);
  padding: 2px var(--m-esp-2); border-radius: var(--m-rayon-pilule, 999px);
  background: var(--color-primary); color: var(--neutre-sur-aplat, var(--m-surface)); font-size: var(--m-t-legende); font-weight: 700;
}
/* La carte de tâche : la date et l'état en tête. L'état se dit par sa
   pastille, jamais par un trait de couleur à gauche (catalogue, 10/11/2026). */
.m-carte__haut { display: flex; align-items: center; justify-content: space-between; gap: var(--m-esp-3); flex-wrap: wrap; }
.m-carte__date { font-size: var(--m-t-note); color: var(--m-texte-2); font-variant-numeric: tabular-nums; }

/* ══ Lot 5 des modules à construire (11/11/2026) : les graphiques lourds.
   Histogramme, carte par zone, frise horizontale, organigramme, flux,
   rubans de rang, entonnoir, contrôles d'un graphique. Calcul : fin de
   `apps/_shared/graphiques.py` ; dessin : `_graphiques.html` ; lecture :
   `static/js/graphiques.js`. Jetons seulement. ══ */

/* ── Le dégradé de la marque, par classe ── Une carte colore ses zones par
   classe de valeur : `m-dg-200` (peu) à `m-dg-900` (beaucoup). */
.m-dg-200 { --c: var(--m-marque-200); } .m-dg-300 { --c: var(--m-marque-300); }
.m-dg-400 { --c: var(--m-marque-400); } .m-dg-500 { --c: var(--m-marque-500); }
.m-dg-600 { --c: var(--m-marque-600); } .m-dg-700 { --c: var(--m-marque-700); }
.m-dg-800 { --c: var(--m-marque-800); } .m-dg-900 { --c: var(--m-marque-900); }

/* ── L'histogramme ── Les barres se touchent : les classes se suivent sans
   trou ; un liseré du fond sépare deux barres pour qu'on les compte. */
.m-graph--histogramme .m-graph__barre { border-radius: 0; box-shadow: inset -1px 0 0 var(--marque-fond, #fff); }

/* ── Les rubans de rang ── Un point à chaque période, un trait plus épais. */
.m-graph--rangs .m-graph__ligne { stroke-width: 3; }
.m-graph__jalon {
  position: absolute; left: calc(var(--x) * 1%); bottom: calc(var(--y) * 1%); width: 8px; height: 8px;
  transform: translate(-50%, 50%); border-radius: 50%; background: var(--c); box-shadow: 0 0 0 2px var(--marque-fond, #fff);
}
.m-graph--rangs .m-graph__fin { display: none; }

/* ── Les puces de séries ── La légende en pastilles qu'on éteint. Une série
   éteinte quitte le tracé ; sa puce reste, barrée et pâlie. */
.m-graph__puces { margin: 0 0 var(--m-esp-4); }
button.m-pastille { font: inherit; font-size: var(--m-t-note); cursor: pointer; }
.m-graph__puce[aria-pressed="false"] { color: var(--m-texte-2); text-decoration: line-through; }
.m-graph__puce[aria-pressed="false"] .m-graph__pastille { background: var(--m-gris-200); border-top-color: var(--m-gris-300); }
.m-graph__puce:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-graph--eteinte { visibility: hidden; }

/* ── Les contrôles d'un graphique ── Juste au-dessus de ce qu'ils commandent
   (comme le bloc de filtres) : le libellé, puis le choix segmenté ou le
   curseur. Une vue cachée l'est vraiment. */
.m-graph-controle { display: grid; gap: var(--m-esp-4, 16px); }
.m-graph__controles { display: flex; flex-wrap: wrap; align-items: center; gap: var(--m-esp-2, 8px) var(--m-esp-3, 12px); }
.m-graph__controles .m-label { margin: 0; }
.m-graph__controles--temps .m-curseur { flex: 1 1 18rem; }
.m-graph-controle__vue[hidden] { display: none; }
.m-segments button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }

/* ── La carte par zone ── La légende des classes collée au-dessus : une case
   de couleur par classe, la borne basse dessous, la borne haute au bout. */
.m-geo { max-width: 34rem; }
.m-geo--etendue { max-width: none; }
.m-geo__echelle { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--m-esp-2, 8px) var(--m-esp-5, 24px); margin: 0 0 var(--m-esp-3); }
/* Chaque borne est centrée sous la limite de deux classes (la première
   alignée à gauche) : elles ne se chevauchent pas tant qu'une case fait
   3rem (« 1'250 € » touchait « 1'000 € », rendu du 11/11/2026). */
.m-geo__classes { list-style: none; margin: 0; padding: 0 var(--m-esp-5, 24px) 0 0; display: grid; grid-template-columns: repeat(var(--n), minmax(3rem, 4.5rem)); }
.m-geo__classes li { position: relative; height: 2.25rem; font-size: var(--m-t-legende); color: var(--m-texte-2); font-variant-numeric: tabular-nums; cursor: default; }
.m-geo__case { display: block; height: 12px; background: var(--c); }
.m-geo__classes li + li .m-geo__case { box-shadow: inset 1px 0 0 var(--marque-fond, #fff); }
.m-geo__borne { position: absolute; left: 0; top: 1rem; transform: translateX(-50%); white-space: nowrap; }
.m-geo__borne--fin { left: 100%; }
.m-geo__classes li:first-child .m-geo__borne:not(.m-geo__borne--fin) { transform: none; }
.m-geo__classes li.m-graph--actif .m-geo__case { box-shadow: inset 0 0 0 2px var(--m-texte); }
.m-geo__vide-legende { height: 2.25rem; }
.m-geo__vide-legende { margin: 0; display: grid; gap: var(--m-esp-1, 4px); font-size: var(--m-t-legende); color: var(--m-texte-2); }
.m-geo__vide-legende .m-geo__case { width: 2.75rem; }
.m-geo__vide { --c: var(--m-gris-100); background-image: repeating-linear-gradient(45deg, var(--m-gris-300) 0 1px, transparent 1px 4px); }
.m-geo__fond { display: block; width: 100%; height: auto; overflow: visible; }
.m-geo__zone { fill: var(--c); stroke: var(--marque-fond, #fff); stroke-width: 0.75; stroke-linejoin: round; vector-effect: non-scaling-stroke; cursor: pointer; }
.m-geo__zone.m-geo__vide { fill: var(--hachure, var(--m-gris-100)); }
.m-geo__hachure-fond { fill: var(--m-gris-100); }
.m-geo__hachure { stroke: var(--m-gris-300); stroke-width: 1.5; }
.m-geo__zone--avant { stroke: var(--m-texte); stroke-width: 2.5; }
.m-geo__zone.m-graph--actif, .m-geo__zone:focus-visible { stroke: var(--m-texte); stroke-width: 1.6; }
.m-geo__zone:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ── La frise horizontale ── Les périodes en bandes pâles soulignées de leur
   couleur, le nom en encre ; une ligne par période qui en chevauche une
   autre. Les événements en ronds chiffrés sur l'axe. */
.m-frise-h__corps { position: relative; }
.m-frise-h__periodes { position: relative; height: calc(var(--rangs, 1) * 2.25rem); }
.m-frise-h__grille { position: absolute; top: 0; bottom: 0; left: calc(var(--x) * 1%); border-left: 1px solid var(--m-gris-200); }
.m-frise-h__periode {
  position: absolute; left: calc(var(--x) * 1%); width: calc(var(--l) * 1%); top: calc(var(--rang) * 2.25rem); height: 1.875rem;
  display: flex; align-items: center; padding: 0 var(--m-esp-2, 8px); overflow: hidden;
  background: color-mix(in oklab, var(--c) 22%, var(--marque-fond, #fff)); box-shadow: inset 0 -3px 0 var(--c);
  border-radius: var(--m-rayon-petit, 4px) var(--m-rayon-petit, 4px) 0 0; cursor: pointer;
}
.m-frise-h__periode--ouverte { border-top-right-radius: 0; background: linear-gradient(90deg, color-mix(in oklab, var(--c) 22%, var(--marque-fond, #fff)) 80%, transparent); }
.m-frise-h__nom { font-size: var(--m-t-note); font-weight: 600; color: var(--m-texte); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.m-frise-h__periode.m-graph--actif { background: color-mix(in oklab, var(--c) 38%, var(--marque-fond, #fff)); }
.m-frise-h__periode:focus-visible, .m-frise-h__point:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* L'axe : les ronds posés SUR la ligne du temps (une rangée de plus,
   au-dessus, quand deux se touchent), les années juste dessous. */
.m-frise-h__axe { position: relative; height: calc(var(--rangees, 1) * 1.5rem); border-bottom: 1px solid var(--m-gris-400); margin-bottom: var(--m-esp-2, 8px); }
.m-frise-h__point { position: absolute; left: calc(var(--x) * 1%); bottom: calc(var(--rang) * 1.5rem - 0.625rem); transform: translateX(-50%); cursor: pointer; box-shadow: 0 0 0 2px var(--marque-fond, #fff); }
.m-frise-h__point.m-graph--actif { transform: translateX(-50%) scale(1.2); }
.m-frise-h__point::before { content: ""; position: absolute; inset: -8px; border-radius: 50%; }
.m-frise-h__date { font-variant-numeric: tabular-nums; color: var(--m-texte-2); }
.m-frise-h .m-graph__axe-x { grid-column: auto; }

/* ── L'organigramme ── Un arbre en retrait : chaque niveau descend d'un cran,
   un trait relie chaque société à son détenteur, la part détenue écrite en
   tête de sa case. */
.m-organigramme__arbre, .m-organigramme__arbre ul { list-style: none; margin: 0; padding: 0; }
.m-organigramme__arbre ul { padding-left: var(--m-esp-6, 32px); }
.m-organigramme__noeud { position: relative; padding-top: var(--m-esp-2, 8px); }
.m-organigramme__arbre ul > .m-organigramme__noeud::before {
  content: ""; position: absolute; left: calc(-1 * var(--m-esp-5, 24px)); top: 0; height: 1.6rem; width: var(--m-esp-5, 24px);
  border-left: 1px solid var(--m-gris-400); border-bottom: 1px solid var(--m-gris-400);
}
.m-organigramme__arbre ul > .m-organigramme__noeud:not(:last-child)::after {
  content: ""; position: absolute; left: calc(-1 * var(--m-esp-5, 24px)); top: 0; bottom: 0; border-left: 1px solid var(--m-gris-400);
}
.m-organigramme__case {
  display: inline-grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--m-esp-2, 8px); align-items: baseline;
  max-width: 100%; padding: var(--m-esp-2, 8px) var(--m-esp-3, 12px); border: 1px solid var(--m-filet-fort); border-radius: var(--m-rayon-petit, 4px);
  background: var(--m-surface, #fff); cursor: default;
}
.m-organigramme__part { grid-row: 1 / span 2; font-weight: 800; font-variant-numeric: tabular-nums; font-size: var(--m-t-note); color: var(--m-texte-2); }
.m-organigramme__nom { font-weight: 700; overflow-wrap: anywhere; }
.m-organigramme__detail { grid-column: 2; font-size: var(--m-t-note); color: var(--m-texte-2); }
/* Un nœud sans part (la tête d'un arbre) : le détail SOUS le nom, jamais en
   colonne étroite à côté (mesuré à 390 px, dossiers ZB, 11/11/2026). */
.m-organigramme__case:not(:has(.m-organigramme__part)) { grid-template-columns: minmax(0, 1fr); }
.m-organigramme__case:not(:has(.m-organigramme__part)) .m-organigramme__detail { grid-column: 1; }
.m-organigramme__case[class*="m-e-"] .m-organigramme__nom::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--c); margin-right: var(--m-esp-2, 8px); vertical-align: middle; }
.m-organigramme__case.m-graph--actif { background: var(--m-gris-100); }
.m-organigramme__case:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
@media (max-width: 640px) { .m-organigramme__arbre ul { padding-left: var(--m-esp-5, 24px); } .m-organigramme__arbre ul > .m-organigramme__noeud::before, .m-organigramme__arbre ul > .m-organigramme__noeud:not(:last-child)::after { left: calc(-1 * var(--m-esp-4, 16px)); width: var(--m-esp-4, 16px); } }

/* ── Le réseau de détention (lot 8, 11/11/2026) ── Les liens en traits gris
   (plus épais pour un contrôle, plus de 50%), les sociétés en cases posées
   au centre de leur place, la part en étiquette sur le fond. Sous 640 px, le
   dessin cède la place à la liste. */
.m-reseau__trace { position: relative; height: var(--hauteur, 360px); }
.m-reseau__lien { fill: none; stroke: var(--m-gris-400); stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.m-reseau__lien--controle { stroke: var(--m-gris-600); stroke-width: 2.5; }
.m-reseau__noeud {
  position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); width: calc(var(--l) * 1%); transform: translate(-50%, -50%);
  box-sizing: border-box; display: grid; justify-items: center; gap: 2px; text-align: center;
  padding: var(--m-esp-2, 8px); border: 1px solid var(--m-filet-fort); border-radius: var(--m-rayon-petit, 4px);
  background: var(--m-surface, #fff); font-size: var(--m-t-note); line-height: 1.3; cursor: default;
}
.m-reseau__nom { font-weight: 700; color: var(--m-texte); overflow-wrap: anywhere; }
.m-reseau__detail { font-size: var(--m-t-legende); color: var(--m-texte-2); overflow-wrap: anywhere; }
.m-reseau__noeud[class*="m-e-"] .m-reseau__nom::before, .m-reseau__liste li[class*="m-e-"] .m-reseau__nom::before {
  content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--c); margin-right: var(--m-esp-1, 4px); vertical-align: middle;
}
.m-reseau__noeud.m-graph--actif { background: var(--m-gris-100); }
.m-reseau__part {
  position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); transform: translate(-50%, -50%);
  padding: 0 var(--m-esp-1, 4px); border-radius: var(--m-rayon-petit, 4px); background: var(--marque-fond, #fff);
  font-size: var(--m-t-legende); font-weight: 600; color: var(--m-texte-2); font-variant-numeric: tabular-nums; white-space: nowrap; cursor: default;
}
.m-reseau__part--controle { color: var(--m-texte); font-weight: 800; }
.m-reseau__part.m-graph--actif { background: var(--m-gris-100); color: var(--m-texte); }
.m-reseau__noeud:focus-visible, .m-reseau__part:focus-visible, .m-reseau__noeud a:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-reseau__liste { display: none; list-style: none; margin: 0; padding: 0; }
.m-reseau__liste li { display: grid; gap: 2px; padding: var(--m-esp-3, 12px) 0; font-size: var(--m-t-petit); }
.m-reseau__liste li + li { border-top: 1px solid var(--m-filet); }
.m-reseau__l-liens { color: var(--m-texte-2); font-variant-numeric: tabular-nums; }
.m-reseau__l-mot { color: var(--m-texte); font-weight: 600; }
@media (max-width: 640px) {
  .m-reseau__trace { display: none; }
  .m-reseau__liste { display: block; }
}

/* ── Le bouton de lecture d'un curseur de temps ── Un triangle pour
   « Lecture » et « Rejouer », deux barres pour « Pause », dessinés en CSS. */
.m-graph__lecture { display: inline-flex; align-items: center; gap: var(--m-esp-2, 8px); }
.m-graph__lecture[hidden] { display: none; }
.m-graph__lecture-signe { width: 0; height: 0; border-style: solid; border-width: 5px 0 5px 9px; border-color: transparent transparent transparent currentColor; }
.m-graph__lecture[data-etat="joue"] .m-graph__lecture-signe { width: 9px; height: 10px; border: 0; border-left: 3px solid currentColor; border-right: 3px solid currentColor; box-sizing: border-box; }

/* ── Le flux (Sankey) ── Les bandes en teinte pâle de leur couleur, les
   nœuds pleins, le nom et le montant de chaque nœud en HTML à côté de lui,
   sur un halo du fond pour rester lisible au-dessus des bandes. */
.m-flux__trace { position: relative; height: var(--hauteur, 360px); }
.m-flux__bande { fill: var(--c); fill-opacity: 0.32; stroke: none; cursor: pointer; transition: fill-opacity 0.12s; }
.m-flux__bande.m-graph--actif, .m-flux__bande:focus-visible { fill-opacity: 0.6; }
.m-flux__bande:focus-visible, .m-flux__noeud:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.m-flux__noeud { position: absolute; left: calc(var(--x) * 1%); width: calc(var(--l) * 1%); min-width: 4px; top: calc(var(--y) * 1%); height: calc(var(--h) * 1%); min-height: 2px; background: var(--c); cursor: pointer; }
.m-flux__noeud.m-e-neutre { --c: var(--m-gris-600); }
.m-flux__nom {
  position: absolute; left: calc((var(--x) + var(--l)) * 1%); top: calc(var(--y) * 1%); transform: translateY(-50%);
  padding-left: var(--m-esp-2, 8px); max-width: 40%; display: grid; line-height: 1.25; pointer-events: none;
  font-size: var(--m-t-note); color: var(--m-texte-2); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 3px var(--marque-fond, #fff), 0 0 3px var(--marque-fond, #fff), 0 0 3px var(--marque-fond, #fff);
}
.m-flux__nom b { color: var(--m-texte); font-weight: 700; }
.m-flux__nom--fin { left: auto; right: calc((100 - var(--x)) * 1%); padding: 0 var(--m-esp-2, 8px) 0 0; text-align: right; }
@media (max-width: 640px) {
  .m-flux__nom { max-width: 46%; font-size: var(--m-t-legende); }
  /* Sur téléphone, le nom d'un nœud du milieu passe AU-DESSUS de lui : à
     côté, il recouvrait celui de la dernière colonne (rendu du 11/11/2026). */
  .m-flux--milieu .m-flux__trace { margin-top: var(--m-esp-6, 32px); }
  .m-flux__nom--milieu {
    left: auto; right: calc((100 - var(--x) - var(--l)) * 1%); top: calc(var(--y0) * 1%); transform: translateY(-100%);
    display: block; max-width: none; white-space: nowrap; text-align: right; padding: 0 0 var(--m-esp-1, 4px);
  }
}

/* ── L'entonnoir ── Le nom à gauche, la barre centrée, la valeur et sa part
   du départ à droite ; la perte écrite entre deux étapes. */
.m-entonnoir__etapes { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--m-esp-1, 4px); }
.m-entonnoir__etape {
  display: grid; grid-template-columns: minmax(6rem, 12rem) minmax(0, 1fr) minmax(5.5rem, auto); column-gap: var(--m-esp-3, 12px);
  align-items: center; padding: var(--m-esp-1, 4px) 0; border-radius: var(--m-rayon-petit, 4px); cursor: default;
}
.m-entonnoir__perte { grid-column: 2; justify-self: center; font-size: var(--m-t-legende); color: var(--m-texte-2); font-variant-numeric: tabular-nums; margin-bottom: var(--m-esp-1, 4px); }
.m-entonnoir__nom { grid-column: 1; font-size: var(--m-t-petit); line-height: 1.3; }
.m-entonnoir__piste { grid-column: 2; display: flex; justify-content: center; height: 28px; }
.m-entonnoir__barre { display: block; width: calc(var(--l) * 1%); min-width: 2px; height: 100%; background: var(--c); border-radius: var(--m-rayon-petit, 4px); }
.m-entonnoir__valeur { grid-column: 3; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.m-entonnoir__valeur span { color: var(--m-texte-2); font-size: var(--m-t-note); }
.m-entonnoir__etape.m-graph--actif { background: var(--m-gris-100); }
.m-entonnoir__etape:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
@media (max-width: 560px) {
  .m-entonnoir__etape { grid-template-columns: minmax(0, 1fr) auto; }
  .m-entonnoir__nom { grid-column: 1; grid-row: 2; }
  .m-entonnoir__valeur { grid-column: 2; grid-row: 2; }
  .m-entonnoir__piste { grid-column: 1 / -1; grid-row: 3; justify-content: flex-start; height: 16px; }
  .m-entonnoir__perte { grid-column: 1 / -1; grid-row: 1; justify-self: start; }
}
