/* ═══════════════════════════════════════════════════════════════════════════
   LES COMPOSANTS — et rien d'autre. structure.md §16 à §52.

   Une seule implémentation : ce que porte la vitrine est exactement ce que
   portent les 44 écrans. Aucune valeur brute (§127) — tout remonte à tokens.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════ BOUTON — §16 ══════════ */

.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
  height: var(--h-controle); padding: 0 var(--e-4);
  border: 0; border-radius: var(--r-puce);
  font: inherit; font-size: var(--t-corps); font-weight: var(--g-moyen);
  line-height: 1; white-space: nowrap; text-decoration: none;
  cursor: pointer;
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe),
              box-shadow var(--duree) var(--courbe), transform var(--duree) var(--courbe);
}
/* La cible reste 44 px même quand le bouton est plus court. §116 / loi D-7 */
.btn::after {
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%);
  height: max(var(--cible), 100%);
}
.btn:active:not(.est-desactive) { transform: translateY(1px); }

.btn--primaire { background: var(--accent); color: var(--sur-accent); }
.btn--primaire:hover, .btn--primaire.est-survol { background: var(--accent-fort); }

/* `second` etait `--surface` : blanc sur blanc, donc invisible des qu'il tombe dans
   une carte — c'est-a-dire presque partout. Il porte maintenant un LAVIS neutre, ce
   qui le rend lisible sur les deux fonds du systeme sans lui donner de couleur. */
.btn--second {
  background: var(--lavis-neutre); color: var(--encre);
  box-shadow: inset 0 0 0 1px var(--bord-controle);
}
.btn--second:hover, .btn--second.est-survol { background: var(--ligne); }

/* `discret` etait transparent : sur une carte blanche, rien ne disait qu'il y avait
   un bouton. Il prend un filet a `--ligne`. C'est exactement le dernier recours que
   la regle de bordure prevoit : on ne cerne pas les CONTENEURS, mais un controle a
   besoin d'un bord pour se donner a voir. Pas de fond, donc il reste le plus leger. */
.btn--discret {
  background: transparent; color: var(--encre-douce);
  box-shadow: inset 0 0 0 1px var(--bord-controle);
}
.btn--discret:hover, .btn--discret.est-survol {
  background: var(--creuse); color: var(--encre);
  box-shadow: inset 0 0 0 1px var(--encre-douce);
}

.btn--danger { background: var(--danger-plein); color: var(--sur-danger); }

/* Le libelle d'un bouton prend TOUJOURS l'encre du bouton.
   `.bandeau span` — une balise nue dans un selecteur descendant — repeignait le
   <span> du libelle de tout bouton pose dans un bandeau. L'icone restait blanche
   (elle suit `currentColor` du bouton), le texte passait en encre sombre : un
   bouton destructif ecrit en noir sur rouge, a 2,5:1.
   La specificite (0,2,0) est deliberee : elle bat toute regle `.X span` (0,1,1),
   quel que soit l'ordre des feuilles. Voir structure.md §141.3.15. */
.btn .btn__lib { color: inherit; }
.btn--danger:hover, .btn--danger.est-survol { filter: brightness(0.92); }

.btn--fantome { background: var(--lavis-accent); color: var(--accent-fort); }
.btn--fantome:hover { background: var(--accent-doux); }

.btn--sm { height: calc(var(--h-controle) - 0.375rem); padding: 0 var(--e-3); font-size: var(--t-menu); }
.btn--lg { height: calc(var(--h-controle) + 0.5rem); padding: 0 var(--e-5); font-size: var(--t-sous); }
.btn--plein { width: 100%; }

.btn--icone { width: var(--h-controle); padding: 0; }
.btn--icone.btn--sm { width: calc(var(--h-controle) - 0.375rem); }
.btn--icone.btn--lg { width: calc(var(--h-controle) + 0.5rem); }

.btn.est-focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.est-desactive, .btn:disabled {
  opacity: 0.45; cursor: not-allowed; box-shadow: none; transform: none;
}
.btn.est-chargement { pointer-events: none; }

.rouet {
  width: 0.875rem; height: 0.875rem; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: tourne 0.7s linear infinite;
}
@keyframes tourne { to { transform: rotate(360deg); } }

.groupe-btn { display: inline-flex; background: var(--creuse); border-radius: var(--r-puce); padding: 3px; }
.groupe-btn__b {
  height: calc(var(--h-controle) - 0.375rem); padding: 0 var(--e-3);
  border: 0; border-radius: var(--r-puce); background: none;
  font: inherit; font-size: var(--t-menu); font-weight: var(--g-moyen);
  color: var(--encre-douce); cursor: pointer;
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
.groupe-btn__b:hover { color: var(--encre); }
.groupe-btn__b.est-actif { background: var(--surface); color: var(--encre); box-shadow: var(--ombre-1); }

/* ════════════════════════════════════ BADGE · TAG · PUCE — §35–36 ═════ */

.badge {
  display: inline-flex; align-items: center; gap: var(--e-1);
  padding: 0.2rem var(--e-2); border-radius: var(--r-puce);
  font-size: var(--t-menu); font-weight: var(--g-moyen); line-height: 1.45;
  white-space: nowrap;
}
/* La couleur LAVE le fond ; l'encre reste lisible. Jamais du blanc sur pastel. */
.badge--neutre { background: var(--lavis-neutre); color: var(--encre-douce); }
.badge--accent { background: var(--lavis-accent); color: var(--accent-fort); }
.badge--ok     { background: var(--lavis-ok);     color: var(--ok); }
.badge--alerte { background: var(--lavis-alerte); color: var(--alerte); }
.badge--danger { background: var(--lavis-danger); color: var(--danger); }
.badge--info   { background: var(--lavis-info);   color: var(--info); }

.tag {
  display: inline-flex; align-items: center; gap: var(--e-1);
  height: 1.75rem; padding: 0 var(--e-1) 0 var(--e-3);
  background: var(--creuse); border-radius: var(--r-puce);
  font-size: var(--t-menu); color: var(--encre);
}
.tag__x {
  width: 1.25rem; height: 1.25rem; flex: none;
  display: grid; place-items: center;
  padding: 0; border: 0; border-radius: 50%; background: none;
  color: var(--encre-faible); cursor: pointer;
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
.tag__x:hover { background: var(--ligne); color: var(--encre); }

/* L'échelle de température : la valeur se lit à la CHALEUR du fond.
   Le chiffre reste écrit à l'encre. La couleur lave, elle n'écrit pas. */
.puce {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5rem; padding: 0.2rem var(--e-2);
  border-radius: var(--r-puce);
  font-family: var(--police-chiffre); font-variant-numeric: tabular-nums;
  font-size: var(--t-menu); font-weight: var(--g-fort); color: var(--encre);
}
.puce--t5 { background: var(--lavis-temp-5); }
.puce--t4 { background: var(--lavis-temp-4); }
.puce--t3 { background: var(--lavis-temp-3); }
.puce--t2 { background: var(--lavis-temp-2); }
.puce--t1 { background: var(--lavis-temp-1); }

.pastille { width: 0.625rem; height: 0.625rem; border-radius: 50%; flex: none; display: inline-block; }
.pastille--accent { background: var(--accent); }
.pastille--ok     { background: var(--ok); }
.pastille--alerte { background: var(--alerte); }
.pastille--danger { background: var(--danger); }
.pastille--info   { background: var(--info); }
.pastille--neutre { background: var(--encre-faible); }

/* ═════════════════════════════════════════════ AVATAR — §37 ═══════════ */

.avatar {
  width: 2.25rem; height: 2.25rem; flex: none;
  display: inline-grid; place-items: center; border-radius: var(--r-puce);
  background: var(--lavis-accent); color: var(--accent-fort);
  font-size: var(--t-menu); font-weight: var(--g-fort); letter-spacing: var(--chasse-menu);
}
.avatar--sm { width: 1.75rem; height: 1.75rem; font-size: 0.6875rem; }
.avatar--lg { width: 3rem; height: 3rem; font-size: var(--t-corps); }
.avatar--ok     { background: var(--lavis-ok);     color: var(--ok); }
.avatar--info   { background: var(--lavis-info);   color: var(--info); }
.avatar--alerte { background: var(--lavis-alerte); color: var(--alerte); }
.avatar--reste  { background: var(--creuse); color: var(--encre-douce); }
.avatars { display: inline-flex; }
.avatars .avatar + .avatar { margin-left: -0.5rem; box-shadow: 0 0 0 2px var(--surface); }

/* ══════════════════════════════════════════ INFOBULLE — §38 ═══════════ */

.infobulle { position: relative; display: inline-flex; }
.infobulle::after {
  content: attr(data-infobulle);
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  background: var(--encre); color: var(--fond);
  padding: var(--e-1) var(--e-2); border-radius: var(--r-controle);
  font-size: var(--t-menu); white-space: nowrap; z-index: 30;
  opacity: 0; pointer-events: none;
  transition: opacity var(--duree) var(--courbe);
}
.infobulle:hover::after, .infobulle:focus-visible::after { opacity: 1; }

/* ══════════════════════════════════════ CARTE · MÉTRIQUE — §33–34 ═════ */

.carte {
  background: var(--surface); border-radius: var(--r-carte);
  box-shadow: var(--ombre-1); overflow: hidden;
}
.carte__tete {
  display: flex; align-items: center; gap: var(--e-3);
  padding: var(--e-4) var(--p-carte) 0;
}
.carte__tete h3 { margin: 0; font-family: var(--police-titre); font-size: var(--t-sous); font-weight: var(--g-moyen); flex: 1; }
.carte__corps { padding: var(--p-carte); }
.carte--lavis { background: var(--lavis-accent); box-shadow: none; }
.carte--creuse { background: var(--creuse); box-shadow: none; }
.carte--dense .carte__corps { padding: var(--e-3) var(--e-4); }
.carte--dense .carte__tete { padding: var(--e-3) var(--e-4) 0; }

.carte__pied {
  display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap;
  padding: var(--e-3) var(--p-carte);
  background: var(--creuse); font-size: var(--t-menu); color: var(--encre-douce);
}
.carte--dense .carte__pied { padding: var(--e-2) var(--e-4); }

/* Le ruban de statut : un liseré en haut, 3 px. C'est le SEUL endroit du
   système où une couleur borde quelque chose, et c'est assumé — sur une grille
   dense, un lavis de fond se confond d'une carte à l'autre, un liseré non. */
.carte--ruban { position: relative; }
.carte--ruban::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px; z-index: 1;
}
.carte--ruban-accent::before { background: var(--accent); }
.carte--ruban-ok::before     { background: var(--ok); }
.carte--ruban-alerte::before { background: var(--alerte); }
.carte--ruban-danger::before { background: var(--danger); }
.carte--ruban-info::before   { background: var(--info); }

/* ═══════════════════════════════════════════════════════════════════════════
   LA MOSAIQUE — douze colonnes, remplissage DENSE.

   `grid-auto-flow: dense` remonte une carte etroite dans un trou laisse plus
   haut par une carte large. Sans lui, une grille de cartes de tailles melangees
   laisse des escaliers de vide sur le flanc droit — et ce vide n'est pas du
   rythme, c'est un defaut de rangement.

   Les hauteurs se disent en RANGEES (`--r`), pas en pixels : une carte occupe
   deux rangees et suit donc la densite comme tout le reste.
   ═══════════════════════════════════════════════════════════════════════════ */
.mosaique {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: minmax(5.5rem, auto);
  grid-auto-flow: dense;
  gap: var(--e-3);
  align-items: stretch;
}
.mosaique > * { min-width: 0; }
.m-3  { grid-column: span 3; }
.m-4  { grid-column: span 4; }
.m-5  { grid-column: span 5; }
.m-6  { grid-column: span 6; }
.m-7  { grid-column: span 7; }
.m-8  { grid-column: span 8; }
.m-9  { grid-column: span 9; }
.m-12 { grid-column: span 12; }
.h-2  { grid-row: span 2; }
.h-3  { grid-row: span 3; }

/* La carte remplit sa case : sans ca, deux cartes cote a cote de contenus
   inegaux laissent un decrochage sous la plus courte. */
.mosaique .carte { display: flex; flex-direction: column; height: 100%; }
.mosaique .carte__corps { flex: 1; }

@media (max-width: 68rem) {
  .m-3, .m-4, .m-5 { grid-column: span 6; }
  .m-7, .m-8, .m-9 { grid-column: span 12; }
}
@media (max-width: 44rem) {
  .mosaique { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .m-3, .m-4, .m-5, .m-6 { grid-column: span 1; }
  .m-7, .m-8, .m-9, .m-12 { grid-column: span 2; }
  .h-2, .h-3 { grid-row: span 1; }
}

/* ── les pieces qui vivent DANS une carte ─────────────────────────────── */

/* Deux a quatre chiffres serres dans une seule carte : quatre cartes de KPI
   cote a cote gaspillent quatre bordures et quatre paddings pour quatre nombres. */
.stat-groupe { display: grid; grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr)); gap: var(--e-3); }
.stat-groupe > div { display: flex; flex-direction: column; gap: 2px; }
.stat-groupe span { font-size: var(--t-menu); color: var(--encre-douce); }
.stat-groupe strong {
  font-family: var(--police-chiffre); font-variant-numeric: tabular-nums;
  font-size: var(--t-sous); font-weight: var(--g-fort); letter-spacing: -0.02em;
}
.stat-groupe > div + div { padding-left: var(--e-3); border-left: 1px solid var(--ligne); }

/* Une bande visuelle en tete de carte, sans image : le lavis fait le travail. */
.carte__bande {
  height: 4.5rem; margin: calc(var(--p-carte) * -1) calc(var(--p-carte) * -1) var(--e-3);
  background: linear-gradient(135deg, var(--lavis-accent), var(--lavis-alerte) 55%, var(--lavis-danger));
  display: flex; align-items: flex-end; padding: var(--e-3);
}
.carte--dense .carte__bande { margin: calc(var(--e-3) * -1) calc(var(--e-4) * -1) var(--e-3); }

/* Lignes compactes dans une carte — la ou un tableau serait trop lourd. */
.mini-liste { display: flex; flex-direction: column; }
.mini-liste > div {
  display: flex; align-items: center; gap: var(--e-2);
  padding: var(--e-2) 0; font-size: var(--t-corps);
}
.mini-liste > div + div { border-top: 1px solid var(--ligne); }
.mini-liste .mini-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-liste .mini-val { font-family: var(--police-chiffre); font-variant-numeric: tabular-nums; color: var(--encre-douce); }

/* Un rang de barres minuscules — la tendance sans le poids d'un graphe. */
.barres-mini { display: flex; align-items: flex-end; gap: 3px; height: 2.5rem; }
.barres-mini span { flex: 1; background: var(--lavis-accent); border-radius: 3px 3px 1px 1px; min-height: 3px; }
.barres-mini span.est-haute { background: var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   UN RANG DE METRIQUES EST UNE GRILLE, jamais un `.rang` en flex.

   Un flex `align-items: center` centre verticalement des cartes de hauteurs
   inegales : une metrique avec icone, une avec delta et une sans ne tombent
   alors sur AUCUNE ligne commune — c'est l'escalier. La grille donne des
   colonnes egales, et les emplacements reserves donnent des lignes communes.
   Voir structure.md §144.2.
   ═══════════════════════════════════════════════════════════════════════════ */
.metriques {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: var(--e-3) var(--e-5);
  align-items: start;
}
/* Les emplacements vides ne sont reserves QUE dans un rang : une metrique
   seule ne traine pas un blanc sous son chiffre. */
.metriques .metrique__delta.est-vide,
.metriques .metrique__note.est-vide { display: block; visibility: hidden; }

.metrique { display: flex; flex-direction: column; gap: var(--e-1); }
.metrique__delta.est-vide,
.metrique__note.est-vide { display: none; }

/* Hauteurs FIXES, pas planchers. Un plancher ne suffit pas : une tete qui porte
   une icone mesurait 21,69 px contre 20 px sans — la boite de ligne du SVG
   depassait le plancher — et ces 1,69 px descendaient sur la valeur puis sur le
   delta. Mesure, pas estimation : c'est ce qui separe un rang aligne d'un rang
   qui a l'air aligne. */
.metriques .metrique__tete  { height: 1.25rem; }
.metriques .metrique__val   { min-height: 2.25rem; display: flex; align-items: flex-end; }
.metriques .metrique__delta { height: 1.5rem; box-sizing: border-box; }

.metrique__tete { display: flex; align-items: center; gap: var(--e-2); }

/* L'emplacement d'icone est une boite, pas une ligne de texte : en `inline` sa
   hauteur suivait la boite de ligne de la police et variait avec la presence du
   SVG. En flex a hauteur fixe, plein ou vide, il mesure toujours pareil. */
.metrique__ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1rem; height: 1.25rem; flex: none;
}
.metrique__delta { align-items: center; box-sizing: border-box; }
.metrique__lib { flex: 1; font-size: var(--t-menu); color: var(--encre-douce); }
.metrique__ic { color: var(--encre-faible); }
.metrique__val {
  font-family: var(--police-chiffre); font-variant-numeric: tabular-nums;
  font-size: var(--t-titre); font-weight: var(--g-fort);
  line-height: var(--i-serre); letter-spacing: -0.03em;
}
.metrique__delta {
  display: inline-flex; align-items: center; gap: var(--e-1); align-self: flex-start;
  padding: 0.15rem var(--e-2); border-radius: var(--r-puce);
  font-size: var(--t-menu); font-weight: var(--g-moyen);
}
/* Le delta dit son SENS, pas son signe : une baisse de coût est bonne. */
.delta--bon    { background: var(--lavis-ok);     color: var(--ok); }
.delta--mauvais{ background: var(--lavis-danger); color: var(--danger); }
.delta--neutre { background: var(--lavis-neutre); color: var(--encre-douce); }
.delta--bas svg { transform: rotate(0); }
.metrique__note { margin: var(--e-1) 0 0; font-size: var(--t-menu); color: var(--encre-faible); }

/* ════════════════════════════════════════════ SAISIE — §17–27 ═════════ */

.champ { display: flex; flex-direction: column; gap: var(--e-2); min-width: 0; }
.champ__label { font-size: var(--t-menu); font-weight: var(--g-moyen); color: var(--encre-douce); }
.champ__requis { color: var(--danger); margin-left: 2px; }

.champ__boite {
  display: flex; align-items: center; gap: var(--e-2);
  background: var(--surface); border-radius: var(--r-controle);
  padding: 0 var(--e-3); min-height: var(--h-controle);
  /* --bord-controle, pas --ligne : le bord d un controle doit tenir 3:1 (§141.3.1). */
  box-shadow: inset 0 0 0 1px var(--bord-controle);
  transition: box-shadow var(--duree) var(--courbe), background var(--duree) var(--courbe);
}
.champ__boite:hover { box-shadow: inset 0 0 0 1px var(--encre-douce); }
.champ__boite:focus-within { box-shadow: inset 0 0 0 2px var(--accent); }
.champ__ic { color: var(--encre-faible); display: inline-flex; }
.champ__suffixe { color: var(--encre-faible); font-size: var(--t-menu); white-space: nowrap; }

.champ input, .champ textarea, .champ select {
  flex: 1; min-width: 0; border: 0; outline: none; background: none;
  font: inherit; font-size: var(--t-corps); color: var(--encre);
  padding: var(--e-2) 0;
}
.champ textarea { resize: vertical; line-height: var(--i-texte); }
.champ input::placeholder, .champ textarea::placeholder { color: var(--encre-faible); }

.champ__boite--select { position: relative; padding-right: var(--e-2); }
.champ select { appearance: none; cursor: pointer; padding-right: var(--e-5); }
.champ__fleche { position: absolute; right: var(--e-3); pointer-events: none; color: var(--encre-faible); }

.champ__aide { margin: 0; font-size: var(--t-menu); color: var(--encre-faible); }
.champ__err {
  display: flex; align-items: center; gap: var(--e-1);
  margin: 0; font-size: var(--t-menu); color: var(--danger);
}
.champ.est-erreur .champ__boite { box-shadow: inset 0 0 0 1.5px var(--danger); background: var(--lavis-danger); }
.champ.est-desactive { opacity: 0.55; }
.champ.est-desactive .champ__boite { background: var(--creuse); cursor: not-allowed; }
.champ.est-lecture .champ__boite { background: var(--creuse); box-shadow: none; }
.champ.est-focus .champ__boite { box-shadow: inset 0 0 0 2px var(--accent); }
.champ.est-succes .champ__boite { box-shadow: inset 0 0 0 1.5px var(--ok); }

/* Case, radio — la coche est dessinée, jamais native. */
.coche { display: inline-flex; align-items: flex-start; gap: var(--e-3); cursor: pointer; min-height: var(--cible); padding: var(--e-1) 0; }
.coche input { position: absolute; opacity: 0; width: 0; height: 0; }
.coche__boite {
  width: 1.25rem; height: 1.25rem; flex: none; margin-top: 0.15rem;
  display: grid; place-items: center;
  background: var(--surface); border-radius: 6px;
  box-shadow: inset 0 0 0 1.5px var(--encre-faible);
  color: transparent;
  transition: background var(--duree) var(--courbe), box-shadow var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
.coche input[type="radio"] + .coche__boite { border-radius: 50%; }
.coche:hover .coche__boite { box-shadow: inset 0 0 0 1.5px var(--encre-douce); }
.coche input:checked + .coche__boite { background: var(--accent); box-shadow: inset 0 0 0 1.5px var(--accent); color: var(--sur-accent); }
.coche input:focus-visible + .coche__boite { outline: 2px solid var(--accent); outline-offset: 2px; }
.coche input:disabled + .coche__boite { opacity: 0.4; }
.coche.est-desactive { opacity: 0.55; cursor: not-allowed; }
.coche__texte { display: flex; flex-direction: column; gap: 2px; font-size: var(--t-corps); }
.coche__aide { font-size: var(--t-menu); color: var(--encre-faible); }

/* Interrupteur — §24 */
.bascule { display: inline-flex; align-items: flex-start; gap: var(--e-3); cursor: pointer; min-height: var(--cible); padding: var(--e-1) 0; }
.bascule input { position: absolute; opacity: 0; width: 0; height: 0; }
.bascule__rail {
  width: 2.5rem; height: 1.5rem; flex: none; margin-top: 0.1rem;
  background: var(--encre-faible); border-radius: var(--r-puce);
  display: flex; align-items: center; padding: 3px;
  transition: background var(--duree) var(--courbe);
}
.bascule__pouce {
  width: 1.125rem; height: 1.125rem; background: var(--pouce-bascule); border-radius: 50%;
  box-shadow: var(--ombre-1);
  transition: transform var(--duree) var(--courbe);
}
.bascule input:checked + .bascule__rail { background: var(--accent); }
.bascule input:checked + .bascule__rail .bascule__pouce { transform: translateX(1rem); }
.bascule input:focus-visible + .bascule__rail { outline: 2px solid var(--accent); outline-offset: 2px; }
.bascule.est-desactive { opacity: 0.55; cursor: not-allowed; }
.bascule__texte { display: flex; flex-direction: column; gap: 2px; font-size: var(--t-corps); }

/* Curseur — §25 */
.curseur { display: flex; flex-direction: column; gap: var(--e-2); }
.curseur__tete { display: flex; align-items: center; justify-content: space-between; font-size: var(--t-menu); color: var(--encre-douce); }
.curseur output { font-family: var(--police-chiffre); font-weight: var(--g-moyen); color: var(--encre); }
/* Deux mesures, une seule fois : tout le centrage en decoule. Un `margin-top`
   ecrit en dur (-6px) redevient faux des qu'on touche a l'une des deux. */
.curseur { --rail-h: 6px; --pouce: 1.125rem; }
.curseur input[type="range"] {
  appearance: none; -webkit-appearance: none;
  width: 100%; height: 1.5rem; background: none; cursor: pointer;
}
.curseur input[type="range"]::-webkit-slider-runnable-track {
  height: var(--rail-h); border-radius: var(--r-puce); background: var(--creuse);
}
.curseur input[type="range"]::-moz-range-track {
  height: var(--rail-h); border-radius: var(--r-puce); background: var(--creuse);
}
.curseur input[type="range"]::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none; box-sizing: border-box;
  width: var(--pouce); height: var(--pouce); border-radius: 50%;
  /* WebKit pose le pouce sur le HAUT du rail : on le remonte de la moitie de
     leur difference pour que les deux centres coincident. */
  margin-top: calc((var(--rail-h) - var(--pouce)) / 2);
  background: var(--accent); border: 3px solid var(--surface); box-shadow: var(--ombre-1);
}
.curseur input[type="range"]::-moz-range-thumb {
  box-sizing: border-box; width: var(--pouce); height: var(--pouce); border-radius: 50%;
  background: var(--accent); border: 3px solid var(--surface);
}

/* ═══════════════════════════════════════════ ONGLETS — §28 ════════════ */

.onglets { border-bottom: 1px solid var(--ligne); margin-bottom: var(--e-4); }
.onglets__zone { position: relative; display: flex; align-items: center; }

.onglets__rail {
  display: flex; gap: var(--e-1); overflow-x: auto; scroll-behavior: auto;
  scrollbar-width: none; flex: 1; min-width: 0;
}
.onglets__rail::-webkit-scrollbar { display: none; }

/* Un degrade sur le bord qui deborde : il DIT qu'il reste quelque chose, sans
   prendre de place ni couper un libelle. Le degrade seul ne suffit pas — les
   fleches restent la pour la souris et le clavier. */
.onglets__zone.deborde-avant  .onglets__rail { mask-image: linear-gradient(90deg, transparent, #000 3rem); }
.onglets__zone.deborde-apres  .onglets__rail { mask-image: linear-gradient(90deg, #000 calc(100% - 3rem), transparent); }
.onglets__zone.deborde-avant.deborde-apres .onglets__rail {
  mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
}

.onglets__fleche {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 2rem; height: 2rem; flex: none;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-puce);
  background: var(--surface); color: var(--encre-douce);
  box-shadow: var(--ombre-2); cursor: pointer;
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
.onglets__fleche:hover { background: var(--creuse); color: var(--encre); }
.onglets__fleche[hidden] { display: none; }
.onglets__fleche--avant { left: 0; }
.onglets__fleche--avant svg { transform: rotate(180deg); }
.onglets__fleche--apres { right: 0; }
.onglet {
  position: relative; border: 0; background: none;
  min-height: var(--cible); padding: 0 var(--e-3);
  font: inherit; font-size: var(--t-corps); color: var(--encre-douce);
  cursor: pointer; white-space: nowrap;
  transition: color var(--duree) var(--courbe);
}
.onglet:hover { color: var(--encre); }
.onglet.est-actif { color: var(--encre); font-weight: var(--g-moyen); }
.onglet.est-actif::after {
  content: ''; position: absolute; left: var(--e-2); right: var(--e-2); bottom: -1px;
  height: 2px; background: var(--accent); border-radius: var(--r-puce);
}

/* ════════════════════════════════════════ PAGINATION — §32 ════════════ */

.pagination { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; padding-top: var(--e-3); }
.pagination__info { font-size: var(--t-menu); color: var(--encre-faible); flex: 1; }
.pagination__boutons { display: flex; align-items: center; gap: var(--e-1); }
.pagination__n {
  min-width: 2rem; height: 2rem; padding: 0 var(--e-2);
  border: 0; border-radius: var(--r-puce); background: none;
  font: inherit; font-size: var(--t-menu); color: var(--encre-douce); cursor: pointer;
}
.pagination__n:hover { background: var(--creuse); color: var(--encre); }
.pagination__n.est-actif { background: var(--lavis-accent); color: var(--accent-fort); font-weight: var(--g-fort); }
.pagination__ell { color: var(--encre-faible); padding: 0 var(--e-1); }

/* ═════════════════════════════════════════════ TABLEAU — §39 ══════════ */

.tbl-boite { background: var(--surface); border-radius: var(--r-carte); box-shadow: var(--ombre-1); overflow: hidden; }
.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-corps); }
.tbl th, .tbl td { padding: var(--p-cellule); text-align: left; }
.tbl thead th {
  font-size: var(--t-menu); font-weight: var(--g-moyen); color: var(--encre-douce);
  background: var(--creuse); white-space: nowrap;
}
.tbl th.est-triable { cursor: pointer; user-select: none; }
.tbl th.est-triable:hover { color: var(--encre); }
.tbl__tri { opacity: 0.4; margin-left: var(--e-1); vertical-align: -2px; }
.tbl th[aria-sort="ascending"] .tbl__tri,
.tbl th[aria-sort="descending"] .tbl__tri { opacity: 1; color: var(--accent); }
.tbl th[aria-sort="descending"] .tbl__tri { transform: scaleY(-1); }
.tbl tbody tr { height: var(--h-ligne); }
/* On sépare par un filet, jamais par une bordure sur chaque cellule. */
.tbl tbody tr + tr td { border-top: 1px solid var(--ligne); }
.tbl tbody tr:hover td { background: var(--lavis-neutre); }
.tbl__sel { width: 3rem; }
.tbl__sel .coche { min-height: 0; }
.al-d { text-align: right; font-family: var(--police-chiffre); font-variant-numeric: tabular-nums; }
.al-c { text-align: center; }
.tbl__princ { font-weight: var(--g-moyen); }
.tbl__second { display: block; font-size: var(--t-menu); color: var(--encre-faible); }

/* Sous 48 rem le tableau devient des CARTES ÉTIQUETÉES — jamais un scroll
   horizontal muet où l'on perd la colonne qu'on lisait. §39 Responsive */
@media (max-width: 48rem) {
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; width: 100%; }
  .tbl thead { display: none; }
  .tbl tbody tr {
    height: auto; background: var(--surface);
    border-radius: var(--r-controle); padding: var(--e-2);
    margin-bottom: var(--e-2); box-shadow: var(--ombre-1);
  }
  .tbl tbody tr + tr td { border-top: 0; }
  .tbl td {
    display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
    padding: var(--e-2); text-align: right;
  }
  .tbl td::before {
    content: attr(data-l);
    font-size: var(--t-menu); color: var(--encre-faible); text-align: left; flex: none;
  }
  .tbl-boite { background: none; box-shadow: none; overflow: visible; }
}

/* ═══════════════════════════════════════ ALERTE · BANDEAU — §42–43 ════ */

.alerte {
  display: flex; align-items: flex-start; gap: var(--e-3);
  padding: var(--e-4); border-radius: var(--r-carte);
}
.alerte__corps { flex: 1; min-width: 0; }
.alerte__corps strong { display: block; font-weight: var(--g-moyen); }
.alerte__corps p { margin: var(--e-1) 0 0; color: var(--encre-douce); font-size: var(--t-corps); }
.alerte__corps > .btn, .alerte__corps > .rang { margin-top: var(--e-3); }
.alerte--ok     { background: var(--lavis-ok); }
.alerte--info   { background: var(--lavis-info); }
.alerte--alerte { background: var(--lavis-alerte); }
.alerte--danger { background: var(--lavis-danger); }
.alerte--ok     .alerte__ic { color: var(--ok); }
.alerte--info   .alerte__ic { color: var(--info); }
.alerte--alerte .alerte__ic { color: var(--alerte); }
.alerte--danger .alerte__ic { color: var(--danger); }

.bandeau {
  display: flex; align-items: center; gap: var(--e-3);
  padding: var(--e-3) var(--e-4); border-radius: var(--r-controle);
  font-size: var(--t-corps);
}
.bandeau--alerte { background: var(--lavis-alerte); color: var(--alerte); }
.bandeau--danger { background: var(--lavis-danger); color: var(--danger); }
.bandeau--info   { background: var(--lavis-info);   color: var(--info); }
/* `>` et non un descendant : le message du bandeau est son enfant direct, alors
   que le libelle d'un bouton d'action est un petit-enfant. Sans le combinateur,
   la regle traversait le bouton. §141.3.15 */
.bandeau > span { flex: 1; color: var(--encre); }

/* ═══════════════════════════════ PROGRESSION · JAUGE — §45 ════════════ */

.prog { display: flex; flex-direction: column; gap: var(--e-2); }
.prog__tete { display: flex; justify-content: space-between; font-size: var(--t-menu); color: var(--encre-douce); }
.prog__val { font-family: var(--police-chiffre); font-weight: var(--g-moyen); color: var(--encre); }
.prog__rail { height: 0.5rem; background: var(--creuse); border-radius: var(--r-puce); overflow: hidden; }
.prog__rail--seg { display: flex; }
.prog__jauge { display: block; height: 100%; border-radius: var(--r-puce); transition: width var(--duree-long) var(--courbe); }
.prog__seg { height: 100%; }
.prog__jauge--accent { background: var(--accent); }
.prog__jauge--ok     { background: var(--ok); }
.prog__jauge--alerte { background: var(--alerte); }
.prog__jauge--danger { background: var(--danger); }
.prog__jauge--info   { background: var(--info); }
.prog__jauge--neutre { background: var(--encre-faible); }
.prog__legende { display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-4); margin: var(--e-2) 0 0; padding: 0; list-style: none; font-size: var(--t-menu); color: var(--encre-douce); }
.prog__legende li { display: flex; align-items: center; gap: var(--e-2); }
.prog__legende b { font-family: var(--police-chiffre); color: var(--encre); }

.jauge { position: relative; width: var(--jauge-t); height: var(--jauge-t); flex: none; }
.jauge svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.jauge circle { fill: none; stroke-width: 10; stroke-linecap: round; }
.jauge__fond { stroke: var(--creuse); }
.jauge__arc  { transition: stroke-dashoffset var(--duree-long) var(--courbe); }
.jauge__arc--accent { stroke: var(--accent); }
.jauge__arc--ok     { stroke: var(--ok); }
.jauge__arc--alerte { stroke: var(--alerte); }
.jauge__arc--danger { stroke: var(--danger); }
.jauge__centre {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
}
.jauge__centre strong {
  font-family: var(--police-chiffre); font-size: var(--t-titre);
  font-weight: var(--g-fort); line-height: 1; letter-spacing: -0.03em;
}
.jauge__centre span { font-size: var(--t-menu); color: var(--encre-douce); }

/* ══════════════════════════════════════════ SQUELETTE — §46 ═══════════ */

.squel-groupe { display: flex; flex-direction: column; gap: var(--e-2); width: 100%; }
.squel {
  display: block; background: var(--creuse); border-radius: var(--r-controle);
  background-image: linear-gradient(90deg, transparent, var(--lavis-neutre), transparent);
  background-size: 200% 100%; background-repeat: no-repeat;
  animation: chatoie 1.4s ease-in-out infinite;
}
@keyframes chatoie { from { background-position: -100% 0; } to { background-position: 200% 0; } }
.squel--ligne  { height: 0.75rem; }
.squel--titre  { height: 1.25rem; width: 45%; }
.squel--court  { height: 0.75rem; width: 65%; }
.squel--bloc   { height: 6rem; border-radius: var(--r-carte); }
.squel--rond   { height: 2.25rem; width: 2.25rem; border-radius: 50%; }

/* ════════════════════════════════════════ ÉTAT VIDE — §47 ═════════════ */

.vide {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--e-2); padding: var(--e-7) var(--e-4);
  background: var(--surface); border-radius: var(--r-carte);
}
.vide__ic {
  width: 3.5rem; height: 3.5rem; display: grid; place-items: center;
  background: var(--lavis-accent); color: var(--accent); border-radius: var(--r-puce);
  margin-bottom: var(--e-2);
}
.vide h3 { margin: 0; font-family: var(--police-titre); font-size: var(--t-sous); font-weight: var(--g-moyen); }
.vide p { margin: 0; max-width: 32rem; color: var(--encre-douce); }
.vide__act { margin-top: var(--e-3); display: flex; gap: var(--e-2); flex-wrap: wrap; justify-content: center; }

/* ═════════════════════════════════ MODALE · TIROIR — §49–50 ═══════════ */

.modale { position: fixed; inset: 0; z-index: 130; display: grid; place-items: center; padding: var(--e-4); }
.modale__voile { position: absolute; inset: 0; background: rgb(0 0 0 / 0.45); }
.modale__boite {
  position: relative; width: min(34rem, 100%); max-height: 86vh;
  display: flex; flex-direction: column;
  background: var(--surface); border-radius: var(--r-carte);
  box-shadow: var(--ombre-3); overflow: hidden;
  animation: monte var(--duree) var(--courbe);
}
/* Cinq largeurs. Trop large sur un contenu court, on cherche le bouton a
   l'autre bout de l'ecran ; trop etroite sur un formulaire, on defile pour
   rien. La taille suit le CONTENU, pas l'habitude. */
.modale--sm .modale__boite    { width: min(24rem, 100%); }
.modale--lg .modale__boite    { width: min(52rem, 100%); }
.modale--xl .modale__boite    { width: min(68rem, 100%); }
.modale--plein .modale__boite { width: calc(100vw - var(--e-6)); height: calc(100vh - var(--e-6)); max-height: none; }

.modale__chapeau { margin: 0 0 var(--e-4); color: var(--encre-douce); }
.modale__tete { display: flex; align-items: center; gap: var(--e-3); padding: var(--e-4) var(--e-5); }
.modale__tete h2 { margin: 0; font-family: var(--police-titre); font-size: var(--t-sous); font-weight: var(--g-moyen); flex: 1; }
.modale__corps { padding: 0 var(--e-5) var(--e-4); overflow-y: auto; flex: 1; }
/* Le pied : l'action tierce a GAUCHE, les deux vraies a droite. Cote a cote,
   « Ne plus afficher » se ferait cliquer a la place d'« Annuler ». */
.modale__pied { display: flex; align-items: center; gap: var(--e-2); justify-content: space-between;
                padding: var(--e-4) var(--e-5); background: var(--creuse); flex-wrap: wrap; }
.modale__tierce  { margin-right: auto; }
.modale__actions { display: flex; gap: var(--e-2); flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 30rem) {
  .modale__pied { flex-direction: column-reverse; align-items: stretch; }
  .modale__actions { flex-direction: column-reverse; }
  .modale__actions .btn { width: 100%; }
  .modale__tierce { margin: var(--e-2) 0 0; text-align: center; }
}
/* La confirmation destructive se signale par le LAVIS, pas par un fond rouge plein. §106 */
.modale__boite--danger .modale__tete { background: var(--lavis-danger); }
.modale__boite--danger .modale__tete h2 { color: var(--danger); }

.tiroir { position: fixed; inset: 0; z-index: 130; }
.tiroir__voile { position: absolute; inset: 0; background: rgb(0 0 0 / 0.45); }
.tiroir__boite {
  position: absolute; inset: 0 0 0 auto; width: min(28rem, 100%);
  display: flex; flex-direction: column; background: var(--surface);
  box-shadow: var(--ombre-3); animation: entre var(--duree) var(--courbe);
}
@keyframes entre { from { transform: translateX(100%); } }
.tiroir__tete { display: flex; align-items: center; gap: var(--e-3); padding: var(--e-4) var(--e-5); }
.tiroir__tete h2 { margin: 0; font-family: var(--police-titre); font-size: var(--t-sous); font-weight: var(--g-moyen); flex: 1; }
.tiroir__corps { padding: 0 var(--e-5) var(--e-4); overflow-y: auto; flex: 1; }
.tiroir__pied { display: flex; gap: var(--e-2); justify-content: flex-end; padding: var(--e-4) var(--e-5); background: var(--creuse); }
@media (max-width: 48rem) {
  /* Sur mobile la modale monte du bas — le pouce est en bas. §115 */
  .modale { place-items: end center; padding: 0; }
  .modale__boite { width: 100%; border-radius: var(--r-carte) var(--r-carte) 0 0; max-height: 92vh; }
  @keyframes monte { from { opacity: 0; transform: translateY(16px); } }
}

/* ═══════════════════════════════════ VISUALISATION — §52 ══════════════ */

.graphe { position: relative; }
.graphe--barres { display: flex; flex-direction: column; }
.graphe__grille {
  position: absolute; inset: 0 0 1.75rem 2.75rem;
  display: flex; flex-direction: column; justify-content: space-between; pointer-events: none;
}
.graphe__grille span { position: relative; border-top: 1px solid var(--ligne); }
.graphe__grille i {
  position: absolute; right: calc(100% + var(--e-2)); top: -0.55em;
  font-style: normal; font-size: var(--t-menu); color: var(--encre-faible);
  font-family: var(--police-chiffre);
}
.graphe__barres {
  display: flex; align-items: flex-end; gap: 2px;
  height: var(--gh); margin-left: 2.75rem; position: relative;
}
.graphe__col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; }
.graphe__b {
  position: relative; width: 62%; min-height: 3px;
  border-radius: var(--r-controle) var(--r-controle) 3px 3px;
  transition: height var(--duree-long) var(--courbe), filter var(--duree) var(--courbe);
}
.graphe__b--accent { background: var(--accent); }
.graphe__b--ok     { background: var(--ok); }
.graphe__b--info   { background: var(--info); }
.graphe__col:hover .graphe__b { filter: brightness(1.12); }
.graphe__b b {
  position: absolute; bottom: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  font-family: var(--police-chiffre); font-size: var(--t-menu); color: var(--encre);
  white-space: nowrap; opacity: 0; transition: opacity var(--duree) var(--courbe);
}
.graphe__col:hover .graphe__b b { opacity: 1; }
.graphe__x { margin-top: var(--e-2); font-size: var(--t-menu); color: var(--encre-faible); white-space: nowrap; }
.graphe__axe { display: flex; justify-content: space-between; margin-top: var(--e-2); font-size: var(--t-menu); color: var(--encre-faible); }

.graphe--courbe svg { width: 100%; height: var(--gh); display: block; overflow: visible; }
.courbe__aire  { fill: var(--lavis-accent); }
.courbe__trait { fill: none; stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }

.donut { display: flex; align-items: center; gap: var(--e-5); flex-wrap: wrap; }
.donut svg { width: var(--donut-t); height: var(--donut-t); transform: rotate(-90deg); flex: none; }
.donut circle { fill: none; stroke-width: 16; }
.donut__arc--accent { stroke: var(--accent); }
.donut__arc--ok     { stroke: var(--ok); }
.donut__arc--alerte { stroke: var(--alerte); }
.donut__arc--danger { stroke: var(--danger); }
.donut__arc--info   { stroke: var(--info); }
.donut__arc--neutre { stroke: var(--creuse); }
.donut { position: relative; }
.donut__centre {
  position: absolute; left: calc(var(--donut-t) / 2); top: 50%;
  transform: translate(-50%, -50%); text-align: center; pointer-events: none;
}
.donut__legende { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-2); font-size: var(--t-menu); }
.donut__legende li { display: flex; align-items: center; gap: var(--e-2); color: var(--encre-douce); }
.donut__legende b { margin-left: auto; font-family: var(--police-chiffre); color: var(--encre); }

.etincelle { width: 100%; height: 2rem; margin-top: var(--e-2); overflow: visible; }
.etincelle polyline { fill: none; stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.etincelle--accent polyline { stroke: var(--accent); }
.etincelle--ok polyline     { stroke: var(--ok); }
.etincelle--danger polyline { stroke: var(--danger); }

/* ════════════════════════════════════════════ CODE — §123 ═════════════ */

.copier { position: relative; }
.copier pre {
  margin: 0; background: var(--encre); color: var(--fond);
  border-radius: var(--r-carte); padding: var(--e-4);
  overflow-x: auto; font-size: var(--t-menu); line-height: 1.75;
  font-family: var(--police-chiffre);
}
.copier [data-copier] { position: absolute; top: var(--e-3); right: var(--e-3); z-index: 2; background: var(--surface); box-shadow: var(--ombre-1); }

/* ═════════════════════════════════════════════ JETON ═════════════════ */

.jeton { display: flex; align-items: center; gap: var(--e-3); min-width: 0; }
.jeton__apercu { flex: none; }
.jeton__txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.jeton__txt code { font-size: var(--t-menu); font-family: var(--police-chiffre); }
.jeton__val { font-size: var(--t-menu); color: var(--encre-faible); font-family: var(--police-chiffre); }
.jeton__note { font-size: var(--t-menu); color: var(--encre-douce); }
.pastille-couleur { width: 2.75rem; height: 2.75rem; border-radius: var(--r-controle); box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.06); }

/* Même raison que dans coquille.css : ces surfaces déclarent un display, donc
   elles doivent réaffirmer hidden pour ne pas s'ouvrir toutes seules. */
.modale[hidden], .tiroir[hidden] { display: none; }


/* ═══════════════════════════════════════════════════════════════════════════
   APERCU D'ACCORD TYPOGRAPHIQUE — inc/typo.php

   Un mini tableau de bord rendu dans une paire de voix. Il montre l'accord sur
   du contenu REEL : un titre, trois chiffres, deux lignes de liste. Un accord
   juge sur un pangramme se comporte autrement une fois pose sur des donnees.
   ═══════════════════════════════════════════════════════════════════════════ */

.ac-carte {
  background: var(--surface); border-radius: var(--r-carte);
  padding: var(--p-carte); box-shadow: var(--ombre-1);
  display: flex; flex-direction: column; gap: var(--e-2);
}
.ac-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--e-2); margin-bottom: var(--e-2); }
.ac-nom {
  font-size: var(--t-menu); text-transform: uppercase;
  letter-spacing: var(--chasse-caps); color: var(--encre-faible);
}
.ac-h1 {
  margin: 0; font-family: var(--ac-titre); font-size: var(--t-titre);
  line-height: var(--i-serre); letter-spacing: var(--chasse-titre); color: var(--encre);
}
.ac-h2 {
  margin: var(--e-3) 0 var(--e-1); font-family: var(--ac-titre);
  font-size: var(--t-sous); color: var(--encre);
}
.ac-kpi { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e-2); margin-top: var(--e-2); }
.ac-kpi > div { background: var(--creuse); border-radius: var(--r-controle); padding: var(--e-2) var(--e-3); }
.ac-lib { display: block; font-family: var(--ac-texte); font-size: var(--t-menu); color: var(--encre-douce); }
.ac-val {
  display: block; font-family: var(--police-chiffre); font-variant-numeric: tabular-nums;
  font-size: var(--t-sous); font-weight: var(--g-fort); color: var(--encre);
}
.ac-ligne {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-2);
  font-family: var(--ac-texte); font-size: var(--t-corps); color: var(--encre);
  padding: var(--e-2) 0;
}
.ac-ligne + .ac-ligne { border-top: 1px solid var(--ligne); }
.ac-etat {
  font-size: var(--t-menu); font-weight: var(--g-moyen);
  background: var(--lavis-ok); color: var(--ok);
  padding: 0.15rem var(--e-2); border-radius: var(--r-puce); white-space: nowrap;
}
.ac-ligne:last-of-type .ac-etat { background: var(--lavis-alerte); color: var(--alerte); }
.ac-note {
  margin: var(--e-3) 0 0; padding-top: var(--e-3); border-top: 1px solid var(--ligne);
  font-family: var(--ac-texte); font-size: var(--t-menu);
  color: var(--encre-douce); line-height: var(--i-texte);
}

/* ═══════════ LA CIBLE — §141.6.1 ═══════════════════════════════════════
   La boîte VISIBLE peut faire la taille que le dessin demande ; la SURFACE
   CLIQUABLE ne descend jamais sous --cible. Ce sont deux rectangles, et il
   faut pouvoir rétrécir l'un sans rétrécir l'autre.
   Le calque ne peint rien : rien ne bouge à l'œil. */
/* Le calque ne vaut que pour un contrôle ISOLÉ. Empilés — les lignes d'un menu —
   deux calques de 44 px se chevauchent de 21 px et se volent les clics : pire
   qu'une petite cible. Une liste s'agrandit pour de vrai. */
.menu__i { min-height: var(--cible); }
.fil__racine, .fil a { position: relative; }
.fil__racine::after, .fil a::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: max(100%, var(--cible)); height: max(100%, var(--cible));
  transform: translate(-50%, -50%);
}
