/* ==========================================================================
   base.css — fontes, echelle typographique, mise en page, accessibilite
   ========================================================================== */

/* Auto-hebergees : aucune requete tierce, donc rien a declarer au RGPD
   (CHARTE §4). Sous-ensemble latin — il couvre le francais integralement,
   « œ » compris (U+0152-0153). */

/* Inter en fonte VARIABLE : un seul fichier pour 400..700. CHARTE §4 demande
   quatre graisses (400/600/650/700), CHARTE §8 en plafonne deux par fonte.
   La variable tient les deux : une seule requete, un seul fichier, et l'echelle
   est respectee a la lettre. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/inter-latin-var-260c81a4759baf163c025001c4f27872.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* JetBrains Mono : une seule graisse suffit. Le code est en 400, les numeros de
   version aussi. Une graisse non utilisee est un fichier telecharge pour rien. */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-400-latin-caf0dfde4e448468f09b7bed230206a4.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* 🔴 LE PIED EST ANCRE EN BAS DE LA FENETRE, ET AUCUNE PAGE LONGUE NE LE SENT.
   Sur une page courte — une 404, un « c'est confirme », le journal des versions
   avant le premier artefact — le pied s'arretait la ou le contenu s'arretait :
   133 px de fond nu sous son filet, dans une fenetre de 655. Le defaut ne se
   voyait sur aucune des douze pages ouvertes jusqu'ici parce qu'aucune n'etait
   assez courte. Mesure sur /fr/ : hauteur, largeurs de section et hero
   strictement inchanges. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  font-synthesis-weight: none;
}

/* 🔴 `width: 100%` N'EST PAS DECORATIF, IL REPARE CE QUE LES DEUX LIGNES
   AU-DESSUS CASSENT. `.page` porte `margin: 0 auto` ; dans un conteneur flex, des
   marges automatiques absorbent l'espace libre et l'element se replie sur sa
   largeur de contenu au lieu de s'etirer. `main.page` tombait de 1152 px a 643 :
   toute page bornee se recentrait sur son texte, colonne de prose comprise.
   ⚠️ Invisible sur l'accueil — qui est en pleine largeur, donc sans `.page` sur
   `main`, et c'est la seule page ou l'ancrage du pied avait ete essaye. */
body > main { flex: 1 0 auto; width: 100%; }

/* --------------------------------------------------------------------------
   Echelle typographique — ratio ~1,25, ancree a 16 px (CHARTE §4)
   -------------------------------------------------------------------------- */

/* ⚠️ `overflow-wrap: break-word` : un mot francais long ne fait plus defiler la
   page. « telechargement » mesure 347 px a 44 px, dans une colonne qui en fait
   299 a 360 px de fenetre — le titre de /telecharger/merci poussait la page
   entiere de 2 px, depuis le W5-c. La regle ne se declenche que lorsque le mot
   ne PEUT pas tenir : elle ne coupe rien ailleurs. Le plancher de 360 px du
   W12-d avait ete pose sans que cette page soit ouverte. */
h1, h2, h3, h4 { margin: 0 0 calc(var(--space) * 2); text-wrap: balance; overflow-wrap: break-word; }

/* 🔴 ECHELLE REMONTEE — amendement du CHARTE §4, 12 aout 2026 (W12-a)

   Le §4 donnait Hero 56 / H1 40 / H2 30. Ces valeurs ne sont pas fausses, elles
   sont TIMIDES : le contraste entre le titre et le corps est ce qui se lit comme
   « soigne », et a 56 px contre 17 px il n'y a pas d'evenement typographique sur
   la page. Le registre vise — grandes dalles sombres, titres lourds — demande le
   cran au-dessus, et l'interlettrage se resserre a mesure que le corps grandit
   (a 76 px, -0,02 em parait encore lache).

   ⚠️ Le plancher mobile monte de 36 a 40 px : c'est deja la taille a laquelle un
   titre de hero tient en trois lignes sur 360 px, verifie sur la chaine la plus
   longue des deux langues. */
.hero-title {
  font-size: clamp(40px, 7vw, 76px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

h1 { font-size: 44px; font-weight: 700; line-height: 1.1;  letter-spacing: -0.025em; }
h2 { font-size: 34px; font-weight: 650; line-height: 1.18; letter-spacing: -0.02em; }
h3 { font-size: 22px; font-weight: 600; line-height: 1.3; }

p { margin: 0 0 calc(var(--space) * 2); }

small, .meta { font-size: 14px; line-height: 1.5; color: var(--fg-muted); }

/* 🔴 LE CHAPO « PLAT » — la deuxieme ligne d'une page interieure (CHARTE §13).

   « Plat » veut dire : la couleur et le corps d'un chapo, SANS la mise en page
   de `.chapo` (components.css), qui centre et borne a 42 rem. Sur ces pages le
   chapo est suivi d'une barre de rubriques, d'une grille ou d'une prose alignees
   a gauche : les centrer aurait echange un defaut de contraste contre un defaut
   d'alignement. Les metriques sont donc celles de l'ancien `.meta-large`, au
   pixel pres — ce lot ne deplace rien, il ne change qu'une couleur.

   ⚠️ ELLE REMPLACE `.meta-large`, ET LE TOKEN --fg-meta-large AVEC ELLE. Ce
   dernier plafonnait a 3,47:1 sur le fond sombre : le grand texte de WCAG
   commence a 18,66 px EN GRAS ou 24 px en normal, donc a 18 px en graisse
   normale le seuil reste 4,5. C'etait le SEUL echec AA du depot
   (E2E_PLAYBOOKS PW-15.7, releve par Lighthouse au W12-b et jamais ferme).

   Le token n'avait qu'UN emploi reel dans tout le CSS — la couleur de cette
   classe. Le corriger revenait donc a le supprimer, ce que le commentaire qu'il
   portait avait lui-meme prevu : « remonter --fg-meta-large revient a supprimer
   le token (il deviendrait --fg-muted) ». C'est exactement ce qui s'est passe. */
.chapo-plat { font-size: 18px; line-height: 1.5; color: var(--fg-muted); }

code, kbd, samp, pre { font-family: var(--font-mono); font-size: 14.5px; line-height: 1.55; }

/* 🔴 UN <pre> NU FAISAIT DEFILER LA PAGE DE 1169 px — W12-h.

   `overflow-x` vivait sur `.code pre`, jamais sur `pre`. Le seul <pre> du depot
   pose hors d'un `.code` est la ligne `issue` de /admin/commandes/{id} : 2392 px
   de contenu dans une boite de 1152, en `overflow: visible`. La page entiere
   defilait horizontalement — sur l'ecran dont la raison d'etre est de copier
   cette ligne, et d'autant plus que la fenetre etait etroite : +1169 px a 1280,
   +2040 a 375.

   Ce <pre>-la est desormais dans un `.code`, comme partout ailleurs. La regle
   ci-dessous est le plancher qui evite que le prochain oubli coute la meme
   chose : `white-space: pre` ne se replie jamais, donc un <pre> sans
   `overflow-x` deborde TOUJOURS des qu'il depasse sa boite. */
pre { overflow-x: auto; }

a { color: var(--accent-text); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

hr { border: 0; border-top: 1px solid var(--border); margin: calc(var(--space) * 4) 0; }

/* --------------------------------------------------------------------------
   Mise en page
   -------------------------------------------------------------------------- */

.page { max-width: var(--maxw-page); margin: 0 auto; padding: 0 calc(var(--space) * 3); }

/* 🔴 CHARTE §4 : la longueur de ligne du texte suivi. C'est la regle la plus
   souvent perdue au moment d'ajouter une page — elle doit donc valoir pour le
   blog ET pour le manuel, pas seulement le blog (PLAN W2, pieges).

   ⚠️ Ce commentaire disait « 68 caracteres » et se trompait, du W2 au W12-e :
   la colonne en tenait 92 a 99. La correction est dans --maxw-prose, pas ici —
   c'est la valeur du jeton qui etait fausse, pas la regle. Le nombre n'est plus
   recopie a cet endroit : deux endroits qui l'ecrivent, c'est un endroit qui
   finira par mentir. */
.prose { max-width: var(--maxw-prose); }
.prose img, .prose video { max-width: 100%; height: auto; }

/* 🔴 LA PROSE DE DOCUMENTATION — W12-f.

   Un h2 de 34 px est le barème d'une PAGE, calibre sur une section marketing
   qui en porte une, deux, trois. Les pages d'aide en portent neuf ou dix a la
   suite : ce n'est plus une hierarchie, c'est dix titres. Meme defaut qu'au
   W12-e pour le titre de carte du blog — un barème de page employe dans un role
   qui n'est pas celui d'une page.

   ⚠️ ET LE W12-f L'A RENDU OBLIGATOIRE. En ramenant --maxw-prose de 772 a
   620 px, le meme h2 de 34 px passe a deux lignes bien plus souvent : la
   correction de la longueur de ligne ne pouvait pas etre livree seule.

   ⚠️ h3 n'est PAS touche. A 26 / 22 / 17 px avec 650 / 600 / 400 en graisse, les
   trois degres se distinguent ; descendre h3 en meme temps les aurait ecrases
   l'un sur l'autre pour ne rien gagner. Ce que la taille cesse de porter, la
   graisse le porte. */
.prose--doc h2 { font-size: 26px; line-height: 1.25; letter-spacing: -0.015em; }

/* 🔴 LE CHEMIN DE FICHIER FAISAIT DEFILER LA PAGE — defaut du W9-b, trouve au
   W12-f en verifiant autre chose.

   `%USERPROFILE%\.debugxmltool\logs\debugxmltool.log` fait 436 px en mono et ne
   contient AUCUNE occasion de retour a la ligne : ni espace, ni trait d'union.
   A 361 px de fenetre il depassait de 99 px et faisait defiler la page ENTIERE
   horizontalement — la barre du bas, le titre, tout. Mesure sur les quatre
   pages d'aide : 460 px de large pour 361 disponibles sur /signaler-un-probleme,
   373 pour 361 sur les trois autres.

   ⚠️ Le defaut ne se voyait pas en large — il n'apparait qu'en dessous de
   ~640 px, et toute la relecture de ce depot se fait autour de 1280. Quatrieme
   axe apres le theme (W12-c), la largeur (W12-d) et la langue (W12-e).

   ⚠️ Sans effet dans un `.code pre` : `white-space: pre` y neutralise
   `overflow-wrap`, et un bloc de code continue donc de defiler dans sa boite
   plutot que de se replier. C'est ce qu'on veut des deux cotes. */
.prose--doc code { overflow-wrap: anywhere; }

/* 🔴 LA BANDE SAIGNE, LE CONTENU RESTE BORNE — corrige au W12-a.

   Jusqu'ici `<main>` portait `.page`, donc toutes les sections etaient DANS une
   boite de 1200 px : le fond de `.section--subtle` s'arretait a 1152 px et l'on
   voyait un rectangle plus clair flotter, avec du --bg de chaque cote. Sur un
   ecran de 1440 px cela fait 144 px de bordure involontaire a gauche et a
   droite — le detail qui signe une page non finie.

   Les pages qui alternent des bandes declarent donc `pleineLargeur` (SiteLayout)
   et posent `.page` elles-memes, section par section. Partout ailleurs le
   gabarit continue de borner `<main>` et une page n'a rien a declarer. */
.section { padding: var(--section-pad) 0; }
.section--subtle { background: var(--bg-subtle); border-block: 1px solid var(--border-muted); }

/* Deux densites, pour que neuf sections d'affilee ne se suivent pas au meme
   rythme (CHARTE §2.3 : la densite est assumee, pas l'uniformite). */
.section--tight { --section-pad: calc(var(--space) * 7); }
.section--loose { --section-pad: calc(var(--space) * 16); }

/* 🔴 L'OUVERTURE D'UNE PAGE INTERIEURE — W12-f.

   Le titre et son chapo ne sont pas une section de contenu : ils sont l'en-tete
   de la page. Ecrits comme une `.section` ordinaire ils empilaient leur retrait
   bas sur le retrait haut de la section suivante — 96 + 96 + les marges, soit
   208 px de vide mesures entre le chapo et le premier titre sur les quatre
   pages d'aide. Un lecteur qui arrive sur /fr/aide/faq voit un ecran et demi
   avant la premiere question.

   ⚠️ Le retrait bas est a ZERO, et pas simplement reduit : l'espace sous le
   chapo doit etre celui de la section suivante et d'elle seule, sinon on
   remplace un empilement par un autre, plus petit, qu'il faudra reregler a
   chaque changement de densite en dessous. */
.section--titre { padding: calc(var(--space) * 8) 0 0; }

/* 🔴 UN OUTIL N'EST PAS UNE PAGE D'ATTERRISSAGE — W12-h.

   Les douze ecrans de l'admin ouvraient sur 96 px de vide sous la barre : le
   retrait d'une `.section` ordinaire, calibre pour une page qui accueille. On
   ne vient pas se faire accueillir dans une file d'emission — on vient voir qui
   attend. Mesure identique sur les quatorze etats releves : `vide: 96`.

   ⚠️ Pose sur `<main>` par layout/admin, PAS sur les douze gabarits. Une regle
   de rythme recopiee douze fois est une regle que le treizieme ecran oubliera —
   et c'est trait pour trait ce qui vient d'arriver a `.nav__end`. */
.page--outil .section { --section-pad: calc(var(--space) * 4); }

/* --------------------------------------------------------------------------
   LA DALLE — W12-c

   🔴 UNE SEULE PAR PAGE. C'est la regle qui la rend efficace : deux bandes
   inversees dans une meme page ne sont plus une rupture, ce sont des rayures,
   et l'accent revient a zero. Un test compte les occurrences dans les gabarits.

   ⚠️ Elle redefinit --fg et --fg-muted POUR SA DESCENDANCE plutot que de poser
   `color` sur chaque enfant. Tout ce qui vit dessous — `.meta`, `.prose`, un
   titre, un composant qui n'existe pas encore — suit alors sans une regle de
   plus. C'est la seule facon de ne pas avoir a rattraper chaque classe une par
   une le jour ou l'on y glisse un bloc.

   ⚠️ Le --border local va avec : sans lui, tout filet pose dans la bande garde
   la bordure claire de la page et dessine un liset blanc.

   ⚠️ Aucune bordure haute ni basse : la dalle se separe par son fond, un filet
   par-dessus ferait « encadre ». C'est la difference avec --subtle.

   ⚠️ --bg-code n'est PAS remappe, deliberement. Le remapper poserait les six
   jetons de coloration — calibres sur --bg-code — sur une surface qu'ils n'ont
   jamais vue, et --tok-comment tomberait sous AA en theme clair. Un bloc de code
   pose dans la bande garde donc son fond de code, et son filet suffit a l'y
   detacher. Aucun gabarit n'en met, mais la regle doit survivre a celui qui le
   fera. */
.section--dalle {
  background: var(--bg-dalle);
  color: var(--fg-dalle);
  --fg:           var(--fg-dalle);
  --fg-muted:     var(--fg-dalle-muted);
  --border:       var(--border-dalle);
  --border-muted: var(--border-dalle);
  --accent-text:  var(--accent-dalle);
  --bg-subtle:    var(--bg-dalle-relief);
  --bg-elevated:  var(--bg-dalle-relief);
  --section-pad: calc(var(--space) * 14);
}

/* --------------------------------------------------------------------------
   LE HERO TIENT LA PREMIERE FENETRE — W12-b

   `svh` et pas `vh` : sur mobile, `100vh` compte la hauteur AVANT que la barre
   d'adresse ne se retracte, donc le hero deborde toujours d'une centaine de
   pixels et le bouton passe sous la ligne de flottaison. `svh` prend la plus
   petite hauteur possible du viewport — la seule qui garantisse que tout est vu.

   ⚠️ `min-height` et jamais `height` : en 360 px de large, le titre passe a trois
   lignes et le cadre de debogueur s'empile dessous. La section doit pouvoir
   grandir, sinon le contenu sort par le bas.

   ⚠️ Le halo est un pseudo-element en position absolue, hors du flux et sans
   dimension propre : il ne peut donc rien decaler, et le CLS reste a zero. */
.section--hero {
  position: relative;
  isolation: isolate;
  min-height: calc(100svh - var(--nav-height));
  display: flex;
  align-items: center;
  --section-pad: calc(var(--space) * 8);
}

.section--hero::before {
  content: "";
  position: absolute;
  inset: calc(var(--nav-height) * -1) 0 auto 0;
  height: 70%;
  background: var(--halo);
  z-index: -1;
  pointer-events: none;
}

.section--hero > .page { width: 100%; }

.stack > * + * { margin-top: calc(var(--space) * 2); }
.grid { display: grid; gap: calc(var(--space) * 3); grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* --------------------------------------------------------------------------
   Accessibilite (CHARTE §7) — le minimum non negociable
   -------------------------------------------------------------------------- */

/* Ne JAMAIS supprimer l'anneau de focus : la cible est un public au clavier. */
:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.skip-link {
  position: absolute;
  left: calc(var(--space) * 2);
  top: calc(var(--space) * -12);
  z-index: 100;
  padding: calc(var(--space) * 1.5) calc(var(--space) * 2);
  background: var(--accent-solid);
  color: var(--on-accent);
  border-radius: var(--radius);
  text-decoration: none;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: calc(var(--space) * 2); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

img, video { max-width: 100%; }
