/* ============================================================================
   COMPOSANTS — le vocabulaire visuel de la page.
   Chaque composant porte TOUS ses états : repos, survol, focus, actif,
   désactivé. Le premium se joue là, pas dans la décoration.
   ========================================================================== */

/* ── Barre de navigation ─────────────────────────────────────────────────── */
.nav {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
  block-size: var(--h-nav);
  background: oklch(0.155 0.002 40 / 0.82);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-block-end: 1px solid var(--bordure);
}
/* Sans support du flou, le fond translucide laisserait le texte de la page
   défiler derrière les liens et les rendrait illisibles : on repasse opaque. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav { background: var(--bg); }
}
.nav__inner {
  block-size: 100%;
  display: flex;
  align-items: center;
  gap: var(--e5);
}
/* La hauteur minimale ne vient pas du sigle (21 px) mais de la cible tactile : le lien mesurait
   131×28, donc conforme au plancher WCAG 2.2 AA de 24 px (SC 2.5.8) mais sous l'exigence de
   44 px posée par FRONTEND.md. C'est la zone à toucher qui grandit, pas le dessin. */
/* `flex: none` n'est pas une précaution, c'est une réparation. Sans lui, le logo se comprimait
   comme n'importe quel élément flexible : sur un écran de 375 px, la pastille « de A à Z » se
   retrouvait à ~14 px de large et son texte s'empilait sur QUATRE lignes, ce qui faisait sortir
   la barre de sa hauteur fixe et poussait les liens hors de l'écran. Le point important est
   ailleurs : aucun contrôle mécanique ne pouvait voir ce défaut. La page ne débordait pas
   (`.nav__liens` défile), les contrastes restaient bons, les cibles tactiles aussi, et le texte
   était toujours là dans l'arbre d'accessibilité. Il n'a été trouvé qu'en REGARDANT une capture.
   C'est la limite exacte de l'audit automatique, et elle mérite d'être écrite ici. */
.nav__logo { display: flex; flex: none; align-items: center; gap: var(--e3); min-block-size: 44px; color: var(--texte); text-decoration: none; }
.nav__logo svg { block-size: 21px; inline-size: auto; color: var(--texte); }
.nav__logo .puce { white-space: nowrap; }
/* Sous 640 px, la place ne suffit pas pour le sigle ET la pastille ET les liens. On retire la
   pastille : l'information « de A à Z » reste portée par le nom accessible du lien
   (`aria-label="The 5ers, de A à Z — haut de page"`), par le titre de l'onglet et par le hero.
   Rien n'est perdu — seule la redondance visuelle disparaît là où elle coûte. */
@media (max-width: 639px) {
  .nav__logo .puce { display: none; }
  /* Retirer la pastille a fait tomber la cible du lien à 36 px de large — celle du sigle seul.
     La zone à toucher doit rester à 44 px quoi qu'il arrive : c'est le dessin qui mesure 36,
     pas la surface cliquable. Correction faite après coup, l'audit ayant attrapé la régression
     que la correction précédente venait d'introduire. */
  .nav__logo { min-inline-size: 44px; }
}
/* `min-inline-size: 0` lève le minimum automatique du flex : c'est cette liste-là qui doit
   absorber le manque de place et défiler, jamais le logo. */
.nav__liens { display: flex; gap: var(--e2); margin-inline-start: auto; min-inline-size: 0; overflow-x: auto; scrollbar-width: none; }
.nav__liens::-webkit-scrollbar { display: none; }
.nav__lien {
  --taille-min: 44px;
  display: inline-flex;
  align-items: center;
  min-block-size: var(--taille-min);
  padding-inline: var(--e3);
  color: var(--texte-attenue);
  font-size: var(--fs-petit);
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--r-petit);
  transition: color var(--t-court) var(--ease-doux), background var(--t-court) var(--ease-doux);
}
.nav__lien:hover { color: var(--texte); background: var(--surface); }
.nav__lien[aria-current='true'] { color: var(--lime); }

/* ── Cartes ───────────────────────────────────────────────────────────────── */
.carte {
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--r-carte);
  padding: var(--e5);
  box-shadow: var(--ombre-1);
  transition: border-color var(--t) var(--ease-doux), box-shadow var(--t) var(--ease-doux),
              transform var(--t) var(--ease-sortie);
}
.carte--survol:hover { border-color: var(--bordure-forte); box-shadow: var(--ombre-2); transform: translateY(-2px); }

/* ── Marqueurs de fiabilité ───────────────────────────────────────────────
   Quatre niveaux, et chacun porte une FORME propre en plus de sa couleur.
   Sans la forme, le marqueur serait indéchiffrable en contraste forcé (où les
   couleurs sont remplacées par celles du système) et pour un daltonien. */
/* Soude un marqueur de fiabilité à la ponctuation qui le suit. Le conteneur est posé
   mécaniquement par scripts/assembler.mjs, jamais à la main : un marqueur est un `inline-flex`,
   donc une boîte, et le navigateur a le droit de passer à la ligne juste après — la virgule se
   retrouvait alors seule en tête de ligne. Un liant de mots (U+2060) ne suffit pas : il agit
   entre deux caractères, pas de part et d'autre d'une boîte. Seul `nowrap` sur un parent commun
   interdit vraiment cette coupure. */
.soude { white-space: nowrap; }

.lvl {
  display: inline-flex;
  align-items: center;
  gap: 0.42em;
  padding: 0.2em 0.62em 0.2em 0.5em;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: var(--r-puce);
  border: 1px solid currentColor;
  white-space: nowrap;
}
.lvl::before { content: ''; inline-size: 0.62em; block-size: 0.62em; background: currentColor; flex: none; }
.lvl--officiel   { color: var(--lvl-officiel); }
.lvl--officiel::before   { border-radius: 50%; }                                  /* disque */
.lvl--recoupe    { color: var(--lvl-recoupe); }
.lvl--recoupe::before    { clip-path: polygon(50% 0, 100% 100%, 0 100%); }         /* triangle */
.lvl--temoignage { color: var(--lvl-temoignage); }
.lvl--temoignage::before { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); } /* losange */
.lvl--contredit  { color: var(--lvl-contredit); }
.lvl--contredit::before  { clip-path: polygon(20% 0,50% 30%,80% 0,100% 20%,70% 50%,100% 80%,80% 100%,50% 70%,20% 100%,0 80%,30% 50%,0 20%); } /* croix */

/* ── Une règle ────────────────────────────────────────────────────────────
   Le liseré de gauche encode la gravité. C'est le seul endroit de la page où
   la couleur porte l'information seule — le titre de la règle la redit toujours
   en toutes lettres, et un liseré épais reste perceptible en contraste forcé. */
.regle {
  background: linear-gradient(180deg, var(--surface), var(--bg-eleve));
  border: 1px solid var(--bordure);
  border-inline-start: 3px solid var(--bordure-forte);
  border-radius: var(--r-carte);
  padding: var(--e5);
  margin-block-end: var(--e4);
}
.regle--danger { border-inline-start-color: var(--danger); }
.regle--alerte { border-inline-start-color: var(--alerte); }
.regle--info   { border-inline-start-color: var(--info); }
.regle__entete { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--e3); margin-block-end: var(--e3); }
.regle__num {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--texte-discret);
  letter-spacing: 0.08em;
}
.regle__titre { font-family: var(--font-corps); font-size: var(--fs-h4); font-weight: 650; }
.regle__clair {
  margin-block-start: var(--e4);
  padding-block-start: var(--e4);
  border-block-start: 1px dashed var(--bordure);
  color: var(--texte-attenue);
}
.regle__clair::before {
  content: 'En clair';
  display: block;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lime);
  margin-block-end: var(--e2);
}

/* ── Vis-à-vis d'une contradiction ────────────────────────────────────────
   Deux sources officielles qui se contredisent sont montrées CÔTE À CÔTE.
   Les cacher, ou n'en montrer qu'une, désarme le lecteur : il tombera sur
   l'autre version ailleurs et croira que c'est nous qui nous trompons. */
.versus {
  border: 1px solid var(--lvl-contredit);
  border-radius: var(--r-carte);
  background: oklch(0.705 0.185 25 / 0.07);
  padding: var(--e5);
  margin-block-end: var(--e5);
}
.versus__grille { display: grid; gap: var(--e4); }
@media (min-width: 860px) { .versus__grille { grid-template-columns: 1fr 1fr; } }
.versus__cote { background: var(--bg); border: 1px solid var(--bordure); border-radius: var(--r-petit); padding: var(--e4); }
.versus__cote h4 { color: var(--texte-attenue); margin-block-end: var(--e2); }
.versus__date { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--texte-discret); }
.versus__verdict {
  margin-block-start: var(--e4);
  padding: var(--e4);
  background: var(--surface-2);
  border-radius: var(--r-petit);
  border-inline-start: 3px solid var(--lime);
}

/* ── Encadré ──────────────────────────────────────────────────────────────── */
.encadre {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e4);
  align-items: start;
  padding: var(--e5);
  border-radius: var(--r-carte);
  border: 1px solid var(--bordure);
  background: var(--bg-eleve);
  margin-block: var(--e5);
}
.encadre__icone { inline-size: 24px; block-size: 24px; flex: none; color: var(--info); }
.encadre > :last-child > :last-child { margin-block-end: 0; }
.encadre--danger { border-color: oklch(0.705 0.185 25 / 0.5); background: oklch(0.705 0.185 25 / 0.08); }
.encadre--danger .encadre__icone { color: var(--danger); }
.encadre--alerte { border-color: oklch(0.805 0.145 75 / 0.5); background: oklch(0.805 0.145 75 / 0.08); }
.encadre--alerte .encadre__icone { color: var(--alerte); }

/* ── Citation d'une source ────────────────────────────────────────────────── */
.citation {
  margin: var(--e4) 0;
  padding: var(--e4) var(--e5);
  background: var(--bg);
  border-radius: var(--r-petit);
  border-inline-start: 2px solid var(--bordure-forte);
  font-style: italic;
  color: var(--texte-attenue);
}
.citation cite {
  display: block;
  margin-block-start: var(--e2);
  font-style: normal;
  font-size: var(--fs-micro);
  color: var(--texte-discret);
}

/* ── Boutons ──────────────────────────────────────────────────────────────── */
.btn {
  --taille-min: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-block-size: var(--taille-min);
  padding-inline: var(--e5);
  font: inherit;
  font-weight: 600;
  border-radius: var(--r-pilule);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--t) var(--ease-doux), border-color var(--t) var(--ease-doux),
              box-shadow var(--t) var(--ease-doux), transform var(--t-court) var(--ease-sortie);
}
.btn--principal { background: var(--lime); color: var(--bg); box-shadow: var(--halo-lime); }
.btn--principal:hover { transform: translateY(-1px); }
.btn--fantome { background: transparent; color: var(--texte); border-color: var(--bordure-forte); }
.btn--fantome:hover { background: var(--surface-2); border-color: var(--lime); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* ── Tableaux ─────────────────────────────────────────────────────────────
   L'enrobage défile horizontalement quand la place manque. Il porte
   `tabindex="0"` et un rôle de groupe : sans cela, un tableau plus large que
   l'écran est atteignable à la souris mais INACCESSIBLE au clavier. */
.tableau-enrobage {
  overflow-x: auto;
  border: 1px solid var(--bordure);
  border-radius: var(--r-carte);
  margin-block: var(--e5);
}
.tableau-enrobage:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
table { inline-size: 100%; border-collapse: collapse; min-inline-size: 560px; font-size: var(--fs-petit); }
caption { text-align: start; padding: var(--e4) var(--e5); color: var(--texte-attenue); font-size: var(--fs-petit); }
th, td { padding: var(--e3) var(--e4); text-align: start; border-block-end: 1px solid var(--bordure); vertical-align: top; }
thead th {
  position: sticky;
  inset-block-start: 0;
  background: var(--surface-2);
  color: var(--texte);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 650;
}
tbody tr:last-child td { border-block-end: none; }
tbody tr:hover { background: var(--surface); }
th[scope='row'] { color: var(--texte); font-weight: 600; }

/* ── Schémas ──────────────────────────────────────────────────────────────── */
.schema {
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--r-panneau);
  padding: var(--e5);
  margin-block: var(--e6);
}
.schema svg { inline-size: 100%; block-size: auto; }

/* ── Les schémas sur écran étroit ──────────────────────────────────────────
   Un schéma est dessiné sur 800 unités de large. Réduit à la largeur d'un
   téléphone, ses libellés de 13 unités tombent sous 5 px réels : le dessin
   reste « visible » mais devient indéchiffrable — le pire des deux mondes,
   puisqu'il occupe la place sans rendre le service.
   On applique donc au schéma le traitement déjà retenu pour les tableaux
   larges : il garde une taille où il se lit, et c'est la zone qui défile.
   La largeur retenue est 800 px, c'est-à-dire EXACTEMENT celle du viewBox.
   Une première version rendait à 760 px : le rapport 760/800 = 0,95 mettait
   discrètement tous les libellés à l'échelle, et un texte écrit « 13 » se
   dessinait à 12,35 px. Ça passait de justesse, mais la marge se mangeait
   d'elle-même, et rien ne le signalait. À l'échelle 1:1, une unité écrite
   dans le dessin vaut un pixel à l'écran — ce qui rend le plancher de 13
   contrôlable mécaniquement par scripts/assembler.mjs, et non plus « à peu
   près respecté ». */
@media (max-width: 819px) {
  .schema {
    padding: var(--e4);
    overflow-x: auto;
    overscroll-behavior-inline: contain; /* le geste ne déclenche pas la navigation arrière */
  }
  .schema svg { inline-size: 800px; max-inline-size: none; }
  /* L'indice est posé AVANT le dessin, pas après, et la nuance change tout à l'usage.
     Écrit en `::after`, il se retrouvait sous un schéma haut de 600 à 800 px : on voyait
     donc les libellés coupés à droite pendant plusieurs écrans de défilement vertical avant
     d'atteindre la phrase qui les explique. L'indice arrivait après le moment où il servait.
     En `::before`, il se lit en même temps que le haut du dessin.
     `position: sticky` le maintient visible pendant le défilement horizontal, sans quoi il
     sortirait de l'écran au premier geste — c'est-à-dire exactement quand on s'en sert. */
  .schema::before {
    content: 'défilez pour voir tout le schéma →';
    display: block;
    margin-block-end: var(--e3);
    font-size: var(--fs-micro);
    color: var(--texte-discret);
    position: sticky;
    inset-inline-start: 0;
  }
}
/* La zone défilante doit être atteignable au clavier, sinon son contenu est
   inaccessible à qui n'utilise pas de souris (WCAG 2.1.1). L'attribut est posé
   par scripts/assembler.mjs sur chaque figure, pas laissé à la main du rédacteur. */
.schema:focus-visible { outline: 2px solid var(--lime); outline-offset: 3px; }
.schema figcaption {
  margin-block-start: var(--e4);
  padding-block-start: var(--e4);
  border-block-start: 1px solid var(--bordure);
  font-size: var(--fs-petit);
  color: var(--texte-attenue);
}

/* ── Outils interactifs ───────────────────────────────────────────────────── */
.outil { background: var(--bg-eleve); border: 1px solid var(--bordure-forte); border-radius: var(--r-panneau); padding: var(--e5); }
.outil__grille { display: grid; gap: var(--e4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }
.champ { display: flex; flex-direction: column; gap: var(--e2); }
.champ label { font-size: var(--fs-petit); font-weight: 600; color: var(--texte-attenue); }
.champ input, .champ select {
  min-block-size: 44px;
  padding: var(--e2) var(--e3);
  font: inherit;
  color: var(--texte);
  background: var(--bg);
  border: 1px solid var(--bordure-forte);
  border-radius: var(--r-petit);
}
.champ input:focus-visible, .champ select:focus-visible { border-color: var(--lime); }
.champ__aide { font-size: var(--fs-micro); color: var(--texte-discret); }
.outil__sortie {
  margin-block-start: var(--e5);
  padding: var(--e5);
  background: var(--surface);
  border-radius: var(--r-carte);
  border: 1px solid var(--bordure);
}

/* ── Frise ────────────────────────────────────────────────────────────────── */
.frise { list-style: none; padding: 0; margin: 0; }
.frise li { position: relative; padding-inline-start: var(--e6); padding-block-end: var(--e5); border-inline-start: 1px solid var(--bordure); }
.frise li:last-child { border-inline-start-color: transparent; padding-block-end: 0; }
.frise li::before {
  content: '';
  position: absolute;
  inset-inline-start: -5px;
  inset-block-start: 6px;
  inline-size: 9px; block-size: 9px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 0 3px var(--bg);
}
.frise li[data-etat='risque']::before { background: var(--danger); }
.frise__quand { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--texte-discret); letter-spacing: 0.06em; }
.frise__quoi { font-weight: 650; margin-block: var(--e1) var(--e2); }

/* ── Puces ────────────────────────────────────────────────────────────────── */
.puce {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.22em 0.7em;
  font-size: var(--fs-micro);
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
  border-radius: var(--r-pilule);
  border: 1px solid var(--bordure-forte);
  color: var(--texte-attenue);
}
.puce--lime { color: var(--lime); border-color: oklch(0.945 0.185 122 / 0.4); }

/* ── Jauge de couloir ──────────────────────────────────────────────────────
   Représente l'espace entre le solde courant et les deux limites qui ferment
   un compte. Le choix de la rendre en HTML plutôt qu'en SVG est délibéré : les
   valeurs doivent rester lisibles par un lecteur d'écran comme du texte, et un
   SVG mis à jour dynamiquement oblige à maintenir en parallèle une description
   accessible qui se désynchronise à la première modification. */
.jauge { margin-block: var(--e5) var(--e4); }
.jauge__piste {
  position: relative;
  block-size: 46px;
  background: var(--bg);
  border: 1px solid var(--bordure);
  border-radius: var(--r-petit);
  overflow: hidden;
}
.jauge__zone {
  position: absolute;
  inset-block: 0;
  background: color-mix(in oklch, var(--lime) 16%, transparent);
  border-inline: 1px solid color-mix(in oklch, var(--lime) 55%, transparent);
  transition: inset-inline-start var(--t) var(--ease-sortie), inline-size var(--t) var(--ease-sortie);
}
/* Le curseur et son repère triangulaire vivent À L'INTÉRIEUR de la piste, et c'est une
   correction, pas un choix esthétique. Ils étaient posés en débord (`inset-block: -4px` pour
   le trait, `-5px` de plus pour le triangle) — sauf que `.jauge__piste` porte `overflow: hidden`.
   Mesuré : le triangle occupait 77614→77624 quand la piste commençait à 77622. Huit de ses dix
   pixels étaient donc découpés, et comme il pointe vers le bas, ce qui restait visible était sa
   pointe la plus fine : un repère de 2 px pour marquer la position sur une jauge de 46 px de
   haut. Le défaut ne se voyait sur aucun contrôle — la page ne débordait pas, rien n'était
   masqué au sens de l'accessibilité, l'élément existait bien dans l'arbre. Il ne se voyait
   qu'en regardant. */
.jauge__curseur {
  position: absolute;
  inset-block: 0;
  inline-size: 2px;
  background: var(--texte);
  transition: inset-inline-start var(--t) var(--ease-sortie);
}
.jauge__curseur::after {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: -4px;
  inline-size: 10px; block-size: 10px;
  background: var(--texte);
  clip-path: polygon(50% 100%, 0 0, 100% 0);
}
.jauge__bornes {
  display: flex;
  justify-content: space-between;
  gap: var(--e3);
  margin-block-start: var(--e2);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--texte-discret);
}
.jauge__bornes b { color: var(--danger); font-weight: 600; }

/* Le résultat chiffré d'un calculateur : le nombre doit primer visuellement sur
   son étiquette, sinon l'œil lit l'étiquette et saute la valeur. */
.resultat { display: grid; gap: var(--e4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); }
/* Les trois parties d'un résultat sont des `<span>`, donc EN LIGNE par nature — et c'est ce qui
   cassait la mise en page. Sur un élément en ligne, `margin-block-start` n'a aucun effet : les
   trois parties se suivaient donc sur la même ligne et passaient à la ligne suivante seulement
   quand la place manquait. Résultat mesuré : avec un libellé court (« Plancher de perte »), la
   valeur restait à côté et se dessinait 16 px PLUS HAUT que son propre libellé ; avec un libellé
   long (« Marge avant le plancher »), elle passait dessous. Quatre blocs identiques par le code,
   deux mises en page différentes à l'écran, selon la longueur du texte. On force donc la
   structure au lieu de la laisser dépendre du contenu. */
.resultat > p { margin: 0; }
.resultat__cle, .resultat__val, .resultat__note { display: block; }
.resultat__cle { font-size: var(--fs-petit); color: var(--texte-attenue); }
/* `min-block-size: 2lh` réserve deux lignes au libellé : sans cette réserve, les valeurs des
   quatre blocs se désalignent dès qu'un seul libellé passe sur deux lignes — ce qui arrive à
   « Marge avant la limite du jour » en dessous de 1200 px. On paie une ligne vide sur les
   libellés courts pour que les quatre chiffres restent sur la même horizontale, ce qui est
   précisément ce qui permet de les comparer d'un coup d'œil. */
.resultat__cle { min-block-size: 2lh; }
.resultat__val { font-family: var(--font-mono); font-size: var(--fs-h3); font-weight: 600; line-height: 1.1; margin-block-start: var(--e1); }
.resultat__val[data-ton='danger'] { color: var(--danger); }
.resultat__val[data-ton='alerte'] { color: var(--alerte); }
.resultat__note { font-size: var(--fs-micro); color: var(--texte-discret); margin-block-start: var(--e1); }

/* ── Liste de faits ────────────────────────────────────────────────────────
   Cette classe comble un manque du design system, et ce manque avait un coût
   réel : faute de classe de liste, la rédaction a détourné `.puce` — qui est une
   pilule `inline-flex` conçue pour un mot unique. Appliquée à un `<ul>`, elle
   empêchait tout retour à la ligne et faisait déborder la page de 93 px à
   1440 px de large. Nommer une classe « puce » quand elle désigne une pilule
   invitait la confusion : en français, une puce est d'abord une puce de liste. */
.liste { list-style: none; padding: 0; margin-block: var(--e4); display: grid; gap: var(--e3); }
.liste > li {
  position: relative;
  padding-inline-start: var(--e5);
  max-inline-size: 74ch;
}
.liste > li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.62em;
  inline-size: 7px;
  block-size: 7px;
  border-radius: 2px;
  background: var(--bordure-forte);
}
.liste--lime > li::before { background: var(--lime); }
