/*
Theme Name: IBA
Theme URI: https://ibaworld.group
Author: International Brand Alliance
Description: Thème sur mesure pour International Brand Alliance. Registre « instrument gravé » : bleu marine porté en aplat, or réservé au trait, typographie Caslon. Page unique bilingue pour le Programme International de Licences de Marques.
Version: 2.0.0
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: iba
Tags: block-theme, full-site-editing, corporate, one-column
*/

/* ==========================================================================
   1. JETONS
   Palette relevée de DESIGN.md, exprimée en OKLCH pour permettre les
   color-mix en espace oklab. theme.json porte les mêmes valeurs en
   hexadécimal pour l'éditeur de blocs.
   ========================================================================== */

:root {
  --navy-900: oklch(0.185 0.055 268);
  --navy-800: oklch(0.273 0.082 268);
  --navy-700: oklch(0.345 0.080 268);
  --navy-600: oklch(0.435 0.070 268);

  --gold: oklch(0.757 0.133 79);
  --gold-deep: oklch(0.620 0.108 79);

  --paper: oklch(0.975 0.006 85);
  --paper-2: oklch(0.945 0.009 85);
  --paper-3: oklch(0.915 0.011 85);

  --ink: oklch(0.245 0.030 268);
  --ink-soft: oklch(0.470 0.022 268);
  --sky: oklch(0.880 0.020 268);
  --sky-soft: oklch(0.740 0.028 268);

  /* Rôles contextuels. Redéfinis par .dark, ce qui évite de dupliquer
     chaque composant en variante sombre. */
  --bg: var(--paper);
  --bg-raised: oklch(1 0 0);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  /* Trois rôles pour l'or, séparés par le contraste exigé.
     L'or nominal sur papier ne passe pas 4,5:1 en petit texte : le texte
     descend, le filet reste clair. */
  --accent: oklch(0.455 0.100 79);      /* petit texte, étiquettes, chiffres */
  --accent-lg: oklch(0.560 0.115 79);   /* grand titre, figure monumentale */
  --accent-line: var(--gold-deep);      /* filets, bordures, décor */
  --rule: color-mix(in oklab, var(--ink) 14%, transparent);
  --rule-strong: color-mix(in oklab, var(--ink) 26%, transparent);
  --field: color-mix(in oklab, var(--ink) 4%, transparent);

  /* Typographie */
  --ff-display: "Libre Caslon Display", "Iowan Old Style", Georgia, serif;
  --ff-text: "Libre Caslon Text", Georgia, "Times New Roman", serif;
  --ff-ui: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --fs-mega: clamp(3.25rem, 1.2rem + 8.2vw, 9rem);
  --fs-hero: clamp(2.75rem, 1.4rem + 5.4vw, 6.5rem);
  --fs-h1: clamp(2.1rem, 1.3rem + 3.2vw, 4rem);
  --fs-h2: clamp(1.6rem, 1.15rem + 1.9vw, 2.75rem);
  --fs-h3: clamp(1.35rem, 1.1rem + 1vw, 1.9rem);   /* intertitre */
  --fs-h4: clamp(1.2rem, 1.05rem + 0.7vw, 1.6rem);  /* titre de carte */
  --fs-lead: clamp(1.15rem, 1.02rem + 0.55vw, 1.5rem);
  --fs-body: 1.0625rem;
  --fs-small: 0.9rem;
  --fs-label: 0.72rem;

  /* Approche des capitales : trois crans, pas davantage. */
  --ls-caps: 0.14em;
  --ls-ui: 0.11em;
  --ls-button: 0.06em;
  --fs-figure: clamp(1.9rem, 1.2rem + 2.6vw, 3.4rem);

  /* Trame */
  --shell: 78rem;
  --shell-wide: 92rem;
  --gutter: clamp(1.25rem, 0.6rem + 3vw, 4.5rem);
  --pace: clamp(4.5rem, 2.5rem + 8vw, 9.5rem);
  --pace-tight: clamp(3rem, 2rem + 4vw, 5.5rem);

  --sp-1: 0.375rem;
  --sp-2: 0.75rem;
  --sp-3: 1.25rem;
  --sp-4: 2rem;
  --sp-5: clamp(2.5rem, 1.6rem + 3vw, 4rem);
  --sp-6: clamp(3.5rem, 2rem + 5vw, 6rem);

  /* Mouvement. Une seule courbe, une sortie exponentielle. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --t-fast: 180ms;
  --t-mid: 350ms;
  --t-slow: 620ms;

  --masthead-real: 5.5rem;

  /* Colorway du header, basculé par .is-stuck et par .has-hero. */
  --mh-link: var(--ink);
  --mh-link-strong: var(--navy-900);
  --mh-accent: var(--gold-deep);
  --mh-rule: color-mix(in oklab, var(--ink) 12%, transparent);
}

/* Sections sombres : on ne repeint pas les composants, on repeint les rôles.
   Un seul bleu pour toutes les sections sombres : la même valeur que
   l'ancien .dark--deep (navy-900), désormais suffixe sans effet conservé
   dans le HTML existant mais superflu pour un nouveau bloc. */
.dark {
  --bg: var(--navy-900);
  --bg-raised: color-mix(in oklab, var(--navy-800) 70%, var(--navy-900));
  --fg: var(--sky);
  --fg-soft: color-mix(in oklab, var(--sky) 72%, var(--navy-800));
  --accent: var(--gold);
  --accent-lg: var(--gold);
  --accent-line: var(--gold);
  --rule: color-mix(in oklab, var(--sky) 20%, transparent);
  --rule-strong: color-mix(in oklab, var(--sky) 36%, transparent);
  --field: color-mix(in oklab, var(--sky) 8%, transparent);
}

/* ==========================================================================
   2. SOCLE
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  /* Le header est collant : sans ce décalage, une ancre place le titre
     de section derrière la plaque. */
  scroll-padding-top: calc(var(--masthead-real) + 1.5rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ff-ui);
  font-size: var(--fs-body);
  line-height: 1.62;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Le thème pose lui-même le rythme vertical, section par section : on
   neutralise l'empilement que WordPress applique entre blocs de premier
   niveau. Sa règle de mise en page « flow » pose 1,5 rem entre chaque
   enfant du contenu, ce qui laissait passer une bande de papier entre deux
   sections d'aplats différents. Le sélecteur porte une classe, donc il
   l'emporte sur le :where() du cœur, qui a une spécificité nulle. */
body .wp-site-blocks > * + * { margin-block-start: 0; }

.wp-block-post-content > *,
.wp-block-post-content > * + * {
  margin-block-start: 0;
  margin-block-end: 0;
}

img,
svg,
canvas,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

a { color: inherit; }

::selection {
  background: color-mix(in oklab, var(--gold) 38%, transparent);
  color: var(--navy-900);
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
}

.skip-link:focus {
  left: var(--gutter);
  top: 0.75rem;
  z-index: 200;
  padding: 0.7rem 1.1rem;
  background: var(--navy-900);
  color: var(--paper);
  font: 600 var(--fs-label) / 1 var(--ff-ui);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  text-decoration: none;
}

/* ==========================================================================
   3. TYPOGRAPHIE
   ========================================================================== */

h1, h2, h3, h4 {
  font-family: var(--ff-display);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.012em;
  text-wrap: balance;
  margin: 0;
  color: var(--fg);
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); line-height: 1.15; }
h4 { font-size: var(--fs-h4); line-height: 1.15; }

/* Titre de carte : tout h3 ou h4 posé dans un composant de section. La
   taille suit le rôle, pas la balise ; seul l'intertitre, enfant direct
   de la section, garde --fs-h3. */
.section > * :is(h3, h4) { font-size: var(--fs-h4); line-height: 1.15; }

/* Le Display n'a pas de cut italique : l'accentuation passe par le Text. */
:is(h1, h2, h3, h4) em {
  font-family: var(--ff-text);
  font-style: italic;
  color: var(--accent-lg);
}

p { margin: 0; }
p + p { margin-top: 0.9em; }

.label {
  display: block;
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

.lead {
  font-family: var(--ff-text);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--fg);
}

.text-soft { color: var(--fg-soft); }

.note {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--fg-soft);
}

.measure { max-width: 68ch; }
.measure--tight { max-width: 54ch; }

/* Filet or qui précède l'étiquette d'ouverture d'une section. */
.section > .label,
.section > * > .label--rule {
  position: relative;
  padding-left: 3.25rem;
}

.section > .label::before,
.section > * > .label--rule::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 2.25rem;
  height: 1px;
  background: var(--accent-line);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--t-slow) var(--ease) 120ms;
}

.section.is-in > .label::before,
.reveal.is-in.label--rule::before,
.is-in > .label::before { transform: scaleX(1); }

/* ==========================================================================
   4. TRAME
   ========================================================================== */

.shell {
  width: min(100% - var(--gutter) * 2, var(--shell));
  margin-inline: auto;
}

.shell--wide { width: min(100% - var(--gutter) * 2, var(--shell-wide)); }

.section {
  position: relative;
  padding-block: var(--pace);
  background: var(--bg);
  color: var(--fg);
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
}

.section--tight { padding-block: var(--pace-tight); }

.section > * {
  width: min(100% - var(--gutter) * 2, var(--shell));
  margin-left: max(var(--gutter), calc(50% - var(--shell) / 2));
  margin-right: auto;
}

.section > .alignwide,
.section > .is-wide {
  width: min(100% - var(--gutter) * 2, var(--shell-wide));
  margin-left: max(var(--gutter), calc(50% - var(--shell-wide) / 2));
}

.section > * + * { margin-top: var(--sp-4); }
.section > .label + * { margin-top: var(--sp-3); }
.section > :is(h2, .section__title) + * { margin-top: var(--sp-3); }

.dark { background: var(--bg); color: var(--fg); }
.dark :is(h1, h2, h3, h4) { color: var(--sky); }
.dark p { color: var(--fg-soft); }
.dark .lead { color: var(--sky); }

/* Variante claire secondaire. Deux sections claires qui se suivent ont
   besoin d'un écart de valeur, sinon le chapitre se perd. */
.section--alt {
  --bg: var(--paper-2);
  --bg-raised: var(--paper);
  --rule: color-mix(in oklab, var(--ink) 16%, transparent);
}

/* Filet de couture entre deux sections claires successives : sans lui, le
   passage de paper à paper-2 se lit comme un accident d'impression. */
.section--seam::before {
  content: "";
  position: absolute;
  inset-inline: var(--gutter);
  top: 0;
  height: 1px;
  background: var(--rule);
}

/* Grain discret sur les aplats navy. Le bleu plein sur grand écran
   « banding » sinon, surtout en dégradé. */
.dark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.035;
  background-image: radial-gradient(circle at 1px 1px, var(--sky) 1px, transparent 0);
  background-size: 4px 4px;
}

/* ==========================================================================
   5. EN-TÊTE
   Collant, en surimpression sur le hero, puis plaque papier au défilement.
   La hauteur réelle est mesurée en JavaScript et exposée en --masthead-real.
   ========================================================================== */

.wp-block-template-part { margin-block: 0; }

.masthead {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid var(--mh-rule);
  transition:
    background var(--t-mid) var(--ease),
    border-color var(--t-mid) var(--ease),
    box-shadow var(--t-mid) var(--ease);
}

.masthead__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 0.4rem + 2vw, 2.5rem);
  min-height: 5.5rem;
  padding-block: 0.75rem;
  /* Pleine largeur : contrairement au contenu des sections, l'en-tête n'est
     pas borné à --shell. Le gutter suffit à tenir le logo et le menu loin
     du bord. */
  padding-inline: var(--gutter);
}

/* Sur la page unique, le hero passe sous le header.

   Safari iOS ne recompose un élément fixed qu'à des points d'arrêt du
   défilement plutôt qu'image par image : pendant un geste rapide, le
   header reste peint à une ancienne position et semble flotter au milieu
   du contenu avant de se recaler d'un coup à l'arrêt. Le flou du
   backdrop-filter posé par .is-stuck (plus bas) aggrave le phénomène, plus
   coûteux à recomposer qu'un aplat. Promouvoir le header sur son propre
   calque, avant même qu'il ne soit collé, force Safari à le recomposer en
   continu au lieu d'attendre. */
.has-hero .masthead--overlay {
  position: fixed;
  inset-inline: 0;
  top: 0;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  background: transparent;
  border-bottom-color: transparent;
  --mh-link: color-mix(in oklab, var(--ink) 78%, transparent);
  --mh-link-strong: var(--navy-900);
  --mh-rule: transparent;
}

.has-hero .masthead--overlay.is-stuck {
  background: color-mix(in oklab, var(--paper) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom-color: var(--rule);
  box-shadow: 0 1px 0 color-mix(in oklab, var(--ink) 6%, transparent),
              0 18px 40px -32px color-mix(in oklab, var(--navy-900) 55%, transparent);
}

.admin-bar .masthead { top: 32px; }

/* Le tiroir des cartes du Parcours (.journey__stops div) reste collant à
   toutes les largeurs, contrairement au chapô à deux colonnes : sa
   compensation de barre d'admin reste donc valable partout, elle. */
.admin-bar .journey__stops div { top: calc(var(--masthead-real) + 3.5rem + 32px); }

@media (max-width: 782px) {
  .admin-bar .masthead { top: 46px; }
  .admin-bar .journey__stops div { top: calc(var(--masthead-real) + 3.5rem + 46px); }
}

/* Jauge de lecture. Un seul trait or, calé sur le bas du header. */
.masthead__gauge {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 100%;
  transform: scaleX(var(--read, 0));
  transform-origin: left;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold));
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
  pointer-events: none;
}

.masthead.is-stuck .masthead__gauge { opacity: 1; }

/* --- marque ------------------------------------------------------------ */

.brand {
  position: relative;
  display: block;
  flex: 0 0 auto;
  line-height: 0;
}

/* Les deux calques (mark/alt) n'ont plus forcément le même ratio : mark
   porte désormais le repère compact du pied de page, alt garde le lockup
   complet. Les ancrer avec inset:0 forçait celui du dessus à se déformer
   pour remplir la boîte dimensionnée par l'autre — un seul point d'ancrage
   (haut-gauche) laisse chacun garder sa largeur intrinsèque. */
.brand img {
  position: absolute;
  top: 0;
  left: 0;
  width: auto;
  height: 100%;
  transition: opacity var(--t-mid) var(--ease);
}

/* .brand n'a donc plus d'image en flux normal pour lui donner sa taille :
   sans largeur propre, un enfant absolu en width:auto se retrouve calculé
   contre une boîte de largeur nulle et disparaît. Le ratio du lockup
   complet (celui visible ici) la lui rend, en plus de la hauteur ; le
   fichier empile IBA, « International » et « Brand Alliance » sur trois
   niveaux, et en dessous de ~3rem les deux lignes de légende deviennent
   illisibles alors que la marque elle-même reste nette. */
.masthead .brand {
  height: clamp(3rem, 2.4rem + 2vw, 4.25rem);
  aspect-ratio: 2345 / 1101;
}

/* Le logo blanc ne sert que sur fond sombre : ici le header est clair ou
   transparent sur hero clair, donc la version couleur reste visible. */
.brand__mark { opacity: 0; }
.brand__alt { opacity: 1; }

/* --- navigation -------------------------------------------------------- */

.masthead__nav {
  display: none;
  align-items: center;
  gap: clamp(1rem, 0.3rem + 2vw, 2.25rem);
  margin-left: auto;
}

.iba-nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 0.2rem + 1.8vw, 2rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.iba-nav a {
  position: relative;
  display: inline-block;
  padding-block: 0.35rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--mh-link);
  transition: color var(--t-fast) var(--ease);
  white-space: nowrap;
}

.iba-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--mh-accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--t-mid) var(--ease);
}

.iba-nav a:hover { color: var(--mh-link-strong); }

.iba-nav a:hover::after,
.iba-nav a.is-current::after {
  transform: scaleX(1);
  transform-origin: left;
}

.iba-nav a.is-current { color: var(--mh-link-strong); }

/* --- sélecteur de langue ----------------------------------------------- */

.lang-switch {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
}

.lang-switch li + li::before {
  content: "/";
  margin-right: 0.4rem;
  color: var(--mh-rule);
  color: color-mix(in oklab, var(--mh-link) 45%, transparent);
}

.lang-switch a {
  text-decoration: none;
  color: color-mix(in oklab, var(--mh-link) 65%, transparent);
  transition: color var(--t-fast) var(--ease);
}

.lang-switch a:hover { color: var(--mh-link-strong); }
.lang-switch .current-lang { color: var(--mh-link-strong); }
.lang-switch .current-lang a { color: inherit; cursor: default; }

/* --- appel à l'action du header ---------------------------------------- */

.masthead__cta {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  padding: 0.72rem 1.35rem;
  border: 1px solid var(--gold-deep);
  border-radius: 2px;
  background: transparent;
  color: var(--mh-link-strong);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  text-decoration: none;
  transition: color var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease);
}

/* Remplissage or qui monte depuis le bas plutôt qu'un simple changement
   de fond : le bouton se « charge », il ne clignote pas. */
.masthead__cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--gold);
  transform: translateY(101%);
  transition: transform var(--t-mid) var(--ease);
}

.masthead__cta:hover {
  color: var(--navy-900);
  border-color: var(--gold);
}

.masthead__cta:hover::before { transform: translateY(0); }

/* --- bouton du tiroir --------------------------------------------------- */

.burger {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-left: auto;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.burger span,
.burger span::before,
.burger span::after {
  display: block;
  width: 1.1rem;
  height: 1px;
  background: var(--mh-link-strong);
  transition: transform var(--t-mid) var(--ease), opacity var(--t-fast) var(--ease);
}

.burger span { position: relative; }

.burger span::before,
.burger span::after {
  content: "";
  position: absolute;
  left: 0;
}

.burger span::before { top: -5px; }
.burger span::after { top: 5px; }

.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span::after { transform: translateY(-5px) rotate(-45deg); }

/* --- tiroir mobile ------------------------------------------------------ */

/* Le tiroir est un enfant du header en flux normal, pas un panneau fixed
   calé sur --masthead-real : ce jeton, mesuré en JavaScript, pouvait se
   désynchroniser de quelques dizaines de pixels de la hauteur réelle sur
   certains téléphones et laissait un vide entre le header et le tiroir.
   En flux, le tiroir colle toujours pile sous la marque et la navigation,
   quelle que soit leur hauteur ; c'est le header lui-même (fixed ou
   sticky) qui grandit et reste collé en haut quand le tiroir s'ouvre. */
.drawer {
  /* Le header est en layout-flow WordPress : sans ce reset, le tiroir
     hérite du même 1,5rem que le cœur ajoute entre deux enfants de
     premier niveau (voir plus haut, .wp-site-blocks > * + *), et se
     retrouve décollé du bas de la barre au lieu d'y coller. */
  margin-block-start: 0;
  display: grid;
  grid-template-rows: 0fr;
  background: var(--navy-900);
  color: var(--sky);
  transition: grid-template-rows var(--t-slow) var(--ease);
  /* Le tiroir ouvert prend la hauteur de son contenu (cinq ancres + le
     sélecteur de langue) : sur un téléphone en paysage ou un petit écran,
     cette hauteur dépasse celle qui reste sous le header, et le bas du
     tiroir sortait de l'écran sans aucun moyen d'y faire défiler. */
  max-height: calc(100vh - var(--masthead-real));
  overflow-y: auto;
}

@supports (height: 100dvh) {
  .drawer { max-height: calc(100dvh - var(--masthead-real)); }
}

.drawer[data-open="true"] { grid-template-rows: 1fr; }

.drawer__inner {
  overflow: hidden;
  min-height: 0;
}

.drawer .shell { padding-block: 1.5rem 2.25rem; }

.drawer .iba-nav__list {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
}

.drawer .iba-nav__list li { border-bottom: 1px solid color-mix(in oklab, var(--sky) 14%, transparent); }
.drawer .iba-nav__list li:last-child { border-bottom: 0; }

.drawer .iba-nav a {
  display: block;
  padding-block: 1rem;
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  font-weight: 400;
  letter-spacing: -0.012em;
  text-transform: none;
  color: var(--sky);
}

.drawer .iba-nav a::after { display: none; }
.drawer .iba-nav a:hover { color: var(--gold); }

.drawer .lang-switch {
  margin-top: 1.75rem;
  --mh-link: var(--sky);
  --mh-link-strong: var(--gold);
}

.masthead p:empty { display: none; }

@media (min-width: 60rem) {
  .masthead__nav { display: flex; }
  .burger { display: none; }
  .drawer { display: none; }
}

/* ==========================================================================
   6. BOUTONS
   ========================================================================== */

.wp-block-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 1rem;
}

.wp-block-button__link,
.btn {
  position: relative;
  z-index: 0;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1rem 1.7rem;
  border: 1px solid var(--gold);
  border-radius: 2px;
  background: var(--gold);
  color: var(--navy-900);
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  text-decoration: none;
  transition: color var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease);
}

.wp-block-button__link::before,
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--navy-900);
  transform: translateY(101%);
  transition: transform var(--t-mid) var(--ease);
}

.wp-block-button__link:hover,
.btn:hover { color: var(--gold); border-color: var(--navy-900); }

.wp-block-button__link:hover::before,
.btn:hover::before { transform: translateY(0); }

.dark .wp-block-button__link:hover,
.dark .btn:hover { border-color: var(--gold); }

.wp-block-button__link:active,
.btn:active { transform: translateY(1px); }

/* La flèche avance d'un cran au survol, sans déplacer le libellé. */
.btn__arrow,
.wp-block-button__link .arr {
  display: inline-block;
  transition: transform var(--t-mid) var(--ease);
}

.wp-block-button__link:hover .arr,
.btn:hover .btn__arrow { transform: translateX(4px); }

.is-style-ghost .wp-block-button__link,
.btn--ghost {
  background: transparent;
  border-color: color-mix(in oklab, var(--sky) 45%, transparent);
  color: var(--sky);
}

.is-style-ghost .wp-block-button__link::before,
.btn--ghost::before { background: var(--sky); }

.is-style-ghost .wp-block-button__link:hover,
.btn--ghost:hover { color: var(--navy-900); border-color: var(--sky); }

.is-style-ink .wp-block-button__link {
  background: transparent;
  border-color: color-mix(in oklab, var(--ink) 35%, transparent);
  color: var(--ink);
}

.is-style-ink .wp-block-button__link::before { background: var(--navy-900); }
.is-style-ink .wp-block-button__link:hover { color: var(--paper); border-color: var(--navy-900); }

/* Lien souligné qui se dessine de gauche à droite. */
.link-underline {
  position: relative;
  display: inline-block;
  font-weight: 600;
  font-size: var(--fs-label);
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--accent);
  padding-bottom: 0.3rem;
}

.link-underline::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform-origin: right;
  transform: scaleX(1);
  transition: transform var(--t-mid) var(--ease);
}

.link-underline:hover::after {
  transform: scaleX(0);
  transform-origin: right;
}

/* ==========================================================================
   7. HERO
   Pleine hauteur, fond blanc franc, rupture délibérée avec le papier du
   reste de la page.
   ========================================================================== */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  padding-top: calc(var(--masthead-real) + clamp(2rem, 1rem + 4vw, 5rem)) !important;
  padding-bottom: clamp(2.5rem, 1.5rem + 4vw, 5rem) !important;
  background: oklch(1 0 0);
  overflow: hidden;
  isolation: isolate;
}

/* La marge gauche reproduit le bord de la colonne centrée, au lieu de le
   déduire d'un `auto`. Sans cela, tout enfant borné par un `max-width`
   plus étroit que la colonne se recentrait dans la page : le chapô du hero
   partait au milieu alors que le titre restait à gauche. */
.hero > * {
  position: relative;
  z-index: 1;
  width: min(100% - var(--gutter) * 2, var(--shell));
  margin-left: max(var(--gutter), calc(50% - var(--shell) / 2));
  margin-right: auto;
}

.hero__eyebrow {
  position: relative;
  padding-left: 3.25rem;
  color: var(--gold-deep);
}

.hero__eyebrow::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 2.25rem;
  height: 1px;
  background: var(--accent-line);
  transform-origin: left;
  transform: scaleX(0);
  animation: rule-in 900ms var(--ease) 220ms forwards;
}

@keyframes rule-in { to { transform: scaleX(1); } }

/* Sur écran tactile, 100vh passe sous la barre d'adresse : le bas du hero,
   et donc l'invite à défiler, se retrouvent hors champ. La hauteur
   « petite » borne le hero à ce qui est réellement visible. */
@media (pointer: coarse) {
  @supports (min-height: 100svh) {
    .hero { min-height: 100svh; }
  }
}

.hero__title {
  margin-top: clamp(1.25rem, 0.8rem + 1.6vw, 2rem);
  font-size: var(--fs-hero);
  line-height: 1.02;
  letter-spacing: -0.022em;
  max-width: 19ch;
}

.hero__title em { color: var(--accent-lg); }

/* Chaque mot du titre monte d'un cran, décalé. Le découpage est fait en
   JavaScript ; sans JavaScript le titre s'affiche tel quel.

   La fenêtre de recadrage prend la hauteur de la boîte de ligne, réglée à
   1,02 pour l'interlignage serré du titre : plus étroite que les vrais
   hors-texte de la police (empattements arrondis des capitales, hampes
   descendantes, italique du mot accentué), elle rognait ces lettres. Un
   padding, compensé par une marge négative de même valeur, élargit la
   fenêtre sans toucher à l'interlignage : le padding reste dans la boîte
   que `overflow: hidden` laisse visible, la marge négative annule
   l'espace qu'il ajouterait sinon dans la ligne. */
.hero__title .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding: 0.18em 0.08em;
  margin: -0.18em -0.08em;
}

.hero__title .w > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 900ms var(--ease);
  transition-delay: calc(var(--i, 0) * 55ms + 120ms);
}

.hero.is-lit .hero__title .w > span { transform: translateY(0); }

.hero__lead {
  margin-top: clamp(1.5rem, 0.9rem + 1.8vw, 2.25rem);
  max-width: 46ch;
  font-family: var(--ff-text);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ink-soft);
}

.hero__actions,
.hero .wp-block-buttons { margin-top: clamp(2rem, 1.2rem + 2.2vw, 3rem); }

/* Bandeau défilant des cinq piliers. Il ne vit plus dans le hero : c'est
   une bande à part entière, posée entre le hero blanc et le premier
   chapitre sur papier. Le navy plein en fait la césure.

   La boucle repose sur deux pistes identiques qui glissent chacune de
   100 % de leur propre largeur : sans couture, sans calcul en JavaScript.
   L'animation ne démarre qu'une fois la seconde piste clonée, si bien que
   sans JavaScript le bandeau reste une simple rangée lisible. */
.marquee {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  padding-block: clamp(1.15rem, 0.9rem + 0.8vw, 1.6rem);
  background: var(--navy-900);
  color: var(--sky);
  overflow: hidden;
  /* Les extrémités s'effacent au lieu d'être tranchées net par le bord. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  --marquee-gap: clamp(2rem, 1rem + 3vw, 4rem);
}

/* Grain, comme sur les autres aplats navy : le bleu plein « bande » sinon
   sur grand écran. */
.marquee::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.04;
  background-image: radial-gradient(circle at 1px 1px, var(--sky) 1px, transparent 0);
  background-size: 4px 4px;
}

.marquee__track {
  position: relative;
  z-index: 1;
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--marquee-gap);
  margin: 0;
  padding: 0 var(--marquee-gap) 0 0;
  list-style: none;
  min-width: max-content;
}

.marquee.is-running .marquee__track { animation: marquee 44s linear infinite; }

@keyframes marquee {
  to { transform: translateX(-100%); }
}

/* Le bandeau ne porte plus ni arrêt au survol ni commande visible. Le seul
   arrêt restant est `prefers-reduced-motion`, traité plus bas. */

.marquee__track > li {
  display: inline-flex;
  align-items: center;
  gap: var(--marquee-gap);
  white-space: nowrap;
  /* Les capitales demandent de l'approche, sans quoi elles se collent. */
  font-size: clamp(0.76rem, 0.72rem + 0.14vw, 0.85rem);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: color-mix(in oklab, var(--sky) 88%, var(--navy-900));
}

/* Losange or entre deux piliers : le trait de l'identité, pas une puce. */
.marquee__track > li::after {
  content: "";
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  rotate: 45deg;
  background: var(--gold);
}

/* Invite à défiler, discrète, qui s'efface dès le premier geste. */
.scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 1.5rem;
  z-index: 2;
  transform: translateX(-50%);
  /* .hero > * cale ses enfants sur la colonne de texte, gouttière comprise :
     l'invite à défiler héritait donc de cette largeur et de cette marge,
     ce qui la décalait du vrai centre du hero. Elle doit se centrer sur le
     hero entier, pas sur la colonne. */
  width: auto;
  margin: 0;
  display: flex;
  /* Le trait est le premier enfant du HTML (repli sans mot-clé le rendrait
     seul lisible sans style) ; column-reverse place donc le texte au-dessus
     sans toucher au balisage. */
  flex-direction: column-reverse;
  align-items: center;
  gap: 0.6rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: color-mix(in oklab, var(--ink) 45%, transparent);
  transition: opacity var(--t-mid) var(--ease);
}

.is-scrolled .scroll-hint { opacity: 0; }

.scroll-hint i {
  display: block;
  width: 1px;
  height: 2.25rem;
  background: linear-gradient(var(--gold-deep), transparent);
  animation: hint 2.4s var(--ease-soft) infinite;
}

@keyframes hint {
  0%, 100% { transform: scaleY(0.4); transform-origin: top; opacity: 0.4; }
  50% { transform: scaleY(1); transform-origin: top; opacity: 1; }
}

/* --- tracé gravé -------------------------------------------------------- */

.graticule {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  aspect-ratio: 1;
  width: clamp(24rem, 58vw, 62rem);
  right: -14%;
  top: 50%;
  translate: 0 calc(-50% + var(--par, 0px));
  background: url("assets/img/graticule.svg") center / contain no-repeat;
  opacity: 0.5;
}

.dark .graticule { opacity: 0.22; filter: invert(1) brightness(1.6); }

.graticule--spin { animation: spin 90s linear infinite; }

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Deuxième tracé, plus petit et contrarotatif, pour donner de la
   profondeur sans ajouter d'image. */
.graticule--twin {
  width: clamp(13rem, 30vw, 32rem);
  right: auto;
  left: -6%;
  top: 22%;
  opacity: 0.28;
  animation: spin 140s linear infinite reverse;
}

/* --- globe du hero ------------------------------------------------------

   Il remplace les deux tracés gravés : même place, à droite, mais une vraie
   carte plutôt qu'un décor. Rendu par cobe en WebGL, livré avec le thème.
   Sans WebGL, le module ne monte rien et le hero reste sur son fond blanc. */

.hero__globe {
  position: absolute;
  z-index: 0;
  /* Ancré dans l'angle inférieur droit et débordant des deux côtés : on ne
     voit qu'un quart de sphère, ce qui suggère une échelle bien plus grande
     que celle du hero. Le débordement est coupé par l'overflow du hero. */
  right: -16vw;
  bottom: -22vw;
  width: clamp(30rem, 68vw, 68rem);
  aspect-ratio: 1;
  margin: 0;
  pointer-events: none;
  /* Le flanc gauche se dissout avant d'atteindre la colonne de texte : la
     sphère est blanche, mais les terres, elles, se verraient derrière les
     appels à l'action. */
  -webkit-mask-image: linear-gradient(100deg, transparent 0, rgba(0, 0, 0, 0.4) 16%, #000 42%);
  mask-image: linear-gradient(100deg, transparent 0, rgba(0, 0, 0, 0.4) 16%, #000 42%);
}

/* La prise en main n'est activée que sur pointeur fin, par le module. */
.hero__globe.is-grabbable .globe__canvas { pointer-events: auto; }

.globe__canvas {
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 900ms var(--ease);
}

.globe__canvas.is-ready { opacity: 1; }

/* Sous 60rem, le titre occupe toute la largeur : le globe recule au second
   plan, plus petit et plus effacé, plutôt que de passer derrière le texte. */
@media (max-width: 60rem) {
  .hero__globe {
    right: -34vw;
    bottom: -30vw;
    width: clamp(24rem, 115vw, 40rem);
    opacity: 0.75;
  }
}

/* ==========================================================================
   8. BLOCS DE SECTION
   Onze traitements distincts. Chaque chapitre porte sa propre mécanique
   visuelle : la répétition d'une grille de cartes est l'échec à éviter.
   ========================================================================== */

/* --- 8.1 en-tête de chapitre ------------------------------------------- */

/* Titre puis chapô, en colonne. La numérotation des chapitres a été retirée :
   sur une page unique de onze sections, elle donnait un compte à rebours que
   personne ne suit, et elle volait la place du titre. */
.chapter { display: block; }

.chapter h2 { max-width: 22ch; }

/* Le chapô se lit comme la suite du titre, pas comme une colonne voisine :
   même famille que les autres chapôs du site, mesure de lecture bornée. */
.chapter__side {
  margin-top: clamp(1.1rem, 0.8rem + 1vw, 1.75rem);
  max-width: 62ch;
}

.chapter__side > * + * { margin-top: 1rem; }

.chapter__side p {
  font-family: var(--ff-text);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--fg-soft);
}

.dark .chapter__side p { color: var(--fg-soft); }

/* --- 8.2 manifeste : citation monumentale + triptyque d'acteurs -------- */

.manifesto { display: grid; gap: var(--sp-5); }

@media (min-width: 62rem) {
  .manifesto { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(3rem, 1rem + 6vw, 7rem); }
}

.manifesto__quote {
  font-family: var(--ff-display);
  font-size: var(--fs-h1);
  line-height: 1.08;
  letter-spacing: -0.012em;
  text-wrap: balance;
  color: var(--fg);
  margin-bottom: 1.75rem;
}

.manifesto__quote em { font-family: var(--ff-text); font-style: italic; color: var(--accent-lg); }

.roles {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--rule);
}

.roles li {
  position: relative;
  padding: 1.4rem 0 1.4rem 0;
  border-bottom: 1px solid var(--rule);
  transition: padding-left var(--t-mid) var(--ease);
}

.roles li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.4rem;
  width: 0;
  height: 1px;
  background: var(--accent-line);
  transition: width var(--t-mid) var(--ease);
}

.roles li:hover { padding-left: 2rem; }
.roles li:hover::before { width: 1.25rem; }

.roles b {
  display: block;
  margin-bottom: 0.4rem;
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
}

.roles p { color: var(--fg-soft); font-size: var(--fs-body); }

/* --- 8.3 chaînes de valeur comparées ------------------------------------ */

.chain-set {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}

.chain-block {
  position: relative;
  padding: clamp(1.5rem, 1rem + 1.6vw, 2.5rem);
  border: 1px solid var(--rule);
  background: color-mix(in oklab, var(--bg-raised) 55%, transparent);
  transition: border-color var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}

.chain-block:hover { border-color: var(--rule-strong); }

.chain-block--licence { border-color: color-mix(in oklab, var(--accent) 45%, transparent); }

.chain-block__stamp {
  position: absolute;
  top: clamp(1.5rem, 1rem + 1.6vw, 2.5rem);
  right: clamp(1.5rem, 1rem + 1.6vw, 2.5rem);
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  line-height: 1;
  color: color-mix(in oklab, var(--fg) 22%, transparent);
  font-variant-numeric: tabular-nums;
}

.chain-block--licence .chain-block__stamp { color: var(--accent); }

.chain-block__label {
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--fg-soft);
  margin-bottom: 1.5rem;
}

.chain-block--licence .chain-block__label { color: var(--accent); }

.chain-flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.35rem;
  margin-bottom: 1.5rem;
}

.chain-flow span {
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  font-size: var(--fs-small);
  color: var(--fg);
  background: var(--bg);
  transition: border-color var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

.chain-block--licence .chain-flow span { border-color: color-mix(in oklab, var(--accent) 55%, transparent); }
.chain-block:hover .chain-flow span { border-color: var(--fg-soft); }
.chain-block--licence:hover .chain-flow span { border-color: var(--accent); }

/* Le connecteur se dessine quand le bloc entre à l'écran : le flux est
   le sujet, il doit se lire comme un mouvement. */
.chain-flow i {
  position: relative;
  display: block;
  width: 1.5rem;
  height: 1px;
  background: var(--rule-strong);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 420ms var(--ease);
  transition-delay: calc(var(--i, 0) * 130ms + 200ms);
}

.is-in .chain-flow i { transform: scaleX(1); }

.chain-block--licence .chain-flow i { background: var(--accent-line); }

.chain-block--licence .chain-flow i::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-top: 1px solid var(--accent-line);
  border-right: 1px solid var(--accent-line);
  transform: translateY(-50%) rotate(45deg);
}

.chain-block__note { font-size: var(--fs-body); color: var(--fg-soft); }

/* --- 8.4 bento : huit raisons, tailles inégales ------------------------- */

/* Le filet est porté par chaque case, pas par le fond de la grille : une
   rangée incomplète laisserait sinon apparaître des blocs de couleur à la
   place des cases manquantes. */
.bento {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

@media (min-width: 62rem) {
  .bento { grid-template-columns: repeat(4, 1fr); }
  /* Huit raisons sur douze unités : deux doubles en haut, quatre simples
     au milieu, deux doubles en bas. Le compte tombe juste, donc aucune
     case vide ne laisse apparaître le fond de la grille. */
  .bento > *:nth-child(1),
  .bento > *:nth-child(2),
  .bento > *:nth-child(7),
  .bento > *:nth-child(8) { grid-column: span 2; }
}

.bento > * {
  position: relative;
  overflow: hidden;
  padding: clamp(1.4rem, 1rem + 1.2vw, 2.15rem);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--rule);
  transition: background var(--t-mid) var(--ease);
}

.bento > *::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 2px;
  background: var(--accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease);
}

.bento > *:hover { background: var(--bg-raised); }
.bento > *:hover::before { transform: scaleX(1); }

.bento .num {
  display: block;
  margin-bottom: 0.9rem;
  font-family: var(--ff-display);
  font-size: 1rem;
  color: color-mix(in oklab, var(--accent) 75%, transparent);
  font-variant-numeric: tabular-nums;
}

.bento h3 { margin-bottom: 0.55rem; }
.bento p { font-size: var(--fs-body); color: var(--fg-soft); }


/* --- 8.5 planche d'échange ---------------------------------------------- */

.exchange {
  display: grid;
  gap: 0;
  border: 1px solid var(--rule);
}

@media (min-width: 58rem) {
  .exchange { grid-template-columns: 1fr 1fr; }
}

.exchange__party { padding: clamp(1.75rem, 1.2rem + 1.8vw, 3rem); }

.exchange__party + .exchange__party { border-top: 1px solid var(--rule); }

@media (min-width: 58rem) {
  .exchange__party + .exchange__party { border-top: 0; border-left: 1px solid var(--rule); }
}

.exchange__role {
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

.exchange__stance {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  line-height: 1.15;
  margin-bottom: 1.35rem;
  color: var(--fg);
}

.exchange__list { margin: 0; padding: 0; list-style: none; }

.exchange__list li {
  position: relative;
  padding: 0.7rem 0 0.7rem 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: var(--fs-body);
  color: var(--fg-soft);
}

.exchange__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.32rem;
  width: 0.6rem;
  height: 1px;
  background: var(--accent-line);
}

.exchange__flows {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--rule);
  grid-column: 1 / -1;
}

@media (min-width: 58rem) {
  .exchange__flows { grid-template-columns: 1fr 1fr; }
}

.exchange__flow {
  position: relative;
  padding: 1.4rem clamp(1.75rem, 1.2rem + 1.8vw, 3rem) 1.4rem calc(clamp(1.75rem, 1.2rem + 1.8vw, 3rem) + 1.75rem);
  font-size: var(--fs-body);
  color: var(--fg-soft);
}

.exchange__flow + .exchange__flow { border-top: 1px solid var(--rule); }

@media (min-width: 58rem) {
  .exchange__flow + .exchange__flow { border-top: 0; border-left: 1px solid var(--rule); }
}

.exchange__flow b {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--fg);
}

/* Flèches opposées : ce qui descend vers le licencié, ce qui remonte
   vers le propriétaire. */
.exchange__flow::before {
  content: "→";
  position: absolute;
  left: clamp(1.75rem, 1.2rem + 1.8vw, 3rem);
  top: 1.35rem;
  color: var(--accent);
  font-size: 1rem;
}

.exchange__flow:last-child::before { content: "←"; }

.exchange__frame {
  grid-column: 1 / -1;
  padding: 1.5rem clamp(1.75rem, 1.2rem + 1.8vw, 3rem);
  border-top: 1px solid var(--rule);
  background: color-mix(in oklab, var(--accent) 7%, transparent);
  font-size: var(--fs-body);
  color: var(--fg-soft);
}

.exchange__frame b { color: var(--fg); font-weight: 600; }

/* --- 8.6 cartes de flux de revenus ------------------------------------- */

/* Cinq cartes, une par flux, seule grille de cartes du site. Toutes de
   même taille : colonnes égales, rangées en 1fr. Pas de numéro, les flux
   se cumulent, ils ne se suivent pas. */

.flows {
  list-style: none;
  padding: 0;
  display: grid;
  grid-auto-rows: 1fr;
  gap: 0.75rem;
}

.flow {
  /* Fond opaque : la plaque de la serrure le reprend pour masquer la clé. */
  --flow-ground: color-mix(in oklab, var(--bg-raised) 55%, var(--bg));
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: 0.25rem 1.1rem;
  align-content: start;
  margin: 0;
  padding: 1.35rem 1.25rem 1.2rem;
  background: var(--flow-ground);
  border: 1px solid var(--rule);
  border-radius: 2px;
  transition: background var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease);
}

.flow > * { margin: 0; }

/* Filet or qui se tend au survol, comme celui des étiquettes. */
.flow::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto;
  height: 2px;
  background: var(--accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-slow) var(--ease);
}

.flow:hover { --flow-ground: var(--bg-raised); border-color: var(--rule-strong); }
.flow:hover::before { transform: scaleX(1); }

.flow p { font-size: var(--fs-body); color: var(--fg-soft); }

.flow .flow__when {
  margin-top: 0.6rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.5rem;
  align-items: baseline;
  font-size: var(--fs-small);
  line-height: 1.5;
}

.flow__when b {
  font: 600 var(--fs-label)/1.2 var(--ff-ui);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  color: var(--accent);
}

@media (min-width: 40rem) {
  .flows { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .flow { display: flex; flex-direction: column; gap: 0.5rem; }
  .flow .flow__ico { margin-bottom: 1.1rem; }
  .flow .flow__when { margin-top: auto; }
}

@media (min-width: 75rem) {
  .flows { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.9rem; }
  .flow { padding: 1.6rem 1.35rem 1.3rem; }
  .flow .flow__ico { width: 4rem; height: 4rem; }
}

/* Icônes gravées. Or au trait, encre atténuée pour le secondaire, aucune
   pastille. Écrites en SVG dans le contenu, animées ici. */
.flow__ico {
  grid-row: 1 / span 3;
  width: 3.5rem;
  height: 3.5rem;
  overflow: visible;
  color: var(--accent-line);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.flow__ico * { transform-box: fill-box; }
.flow__ico .soft { stroke: var(--fg-soft); }
.flow__ico .gold { fill: var(--accent-line); stroke: none; }
.flow__ico .plate { fill: var(--flow-ground); transition: fill var(--t-mid) var(--ease); }

/* Tracé à l'entrée : la liste reçoit .is-in, chaque carte est décalée par
   --i, chaque trait par --k. */
.flow__ico .ln {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1100ms var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms + var(--k, 0) * 140ms + 200ms);
}

.flow__ico .pop {
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms + 900ms);
}

.flows:not(.is-in) .flow__ico .ln { stroke-dashoffset: 1; transition: none; }
.flows:not(.is-in) .flow__ico .pop { opacity: 0; transform: scale(0.6); transition: none; }

.flow__key,
.flow__cycle,
.flow__drop,
.flow__needle { transform-origin: center; }
.flow__keyhole { opacity: 0; }
.flow__bar { transform-origin: bottom; }
.flow__floor { stroke-dasharray: 2.5 3; }

@keyframes flow-key { 0%, 15% { transform: translateX(-4px); } 45%, 80% { transform: translateX(9px); } 100% { transform: translateX(-4px); } }
@keyframes flow-keyhole { 0%, 40% { opacity: 0; } 50%, 78% { opacity: 1; } 95%, 100% { opacity: 0; } }
@keyframes flow-spin { to { transform: rotate(360deg); } }
@keyframes flow-bar-1 { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(0.62); } }
@keyframes flow-bar-2 { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(1.3); } }
@keyframes flow-bar-3 { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(0.45); } }
@keyframes flow-bar-4 { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(0.75); } }
@keyframes flow-floor { 0%, 100% { stroke-width: 1.4; } 50% { stroke-width: 2.4; } }
@keyframes flow-drop { 0% { transform: translateY(-6px); opacity: 0; } 20% { opacity: 1; } 70% { transform: translateY(15px); opacity: 1; } 85%, 100% { transform: translateY(19px); opacity: 0; } }
@keyframes flow-needle { 0% { transform: rotate(0); } 25% { transform: rotate(-38deg); } 50% { transform: rotate(24deg); } 70% { transform: rotate(-9deg); } 85%, 100% { transform: rotate(0); } }

/* Boucles au survol seulement : au repos, la section se lit sans mouvement. */
.flow:hover .flow__key { animation: flow-key 2.2s var(--ease) infinite; }
.flow:hover .flow__keyhole { animation: flow-keyhole 2.2s var(--ease) infinite; }
.flow:hover .flow__cycle { animation: flow-spin 5s linear infinite; }
.flow:hover .flow__bar:nth-of-type(1) { animation: flow-bar-1 2.4s var(--ease) infinite; }
.flow:hover .flow__bar:nth-of-type(2) { animation: flow-bar-2 2.4s var(--ease) 0.2s infinite; }
.flow:hover .flow__bar:nth-of-type(3) { animation: flow-bar-3 2.4s var(--ease) 0.4s infinite; }
.flow:hover .flow__bar:nth-of-type(4) { animation: flow-bar-4 2.4s var(--ease) 0.6s infinite; }
.flow:hover .flow__floor { animation: flow-floor 2.4s var(--ease) 0.4s infinite; }
.flow:hover .flow__drop { animation: flow-drop 1.9s var(--ease) infinite; }
.flow:hover .flow__needle { animation: flow-needle 2.6s var(--ease) infinite; }

/* Écrans tactiles : une seule lecture de la boucle, après le tracé. */
@media (hover: none) {
  .flows.is-in .flow__key { animation: flow-key 2.2s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
  .flows.is-in .flow__keyhole { animation: flow-keyhole 2.2s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
  .flows.is-in .flow__cycle { animation: flow-spin 2.4s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
  .flows.is-in .flow__bar { animation: flow-bar-3 2.4s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
  .flows.is-in .flow__drop { animation: flow-drop 1.9s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
  .flows.is-in .flow__needle { animation: flow-needle 2.6s var(--ease) calc(var(--i, 0) * 110ms + 1.3s) 1; }
}

@media (prefers-reduced-motion: reduce) {
  .flow__ico * { animation: none !important; }
}

/* --- 8.7 mécanique en trois temps --------------------------------------- */

/* Trois temps, donc trois colonnes ou une seule. Une grille auto-fit
   placerait le troisième bloc seul sur une rangée, avec un filet de
   séparation orienté dans le mauvais sens. */
.steps {
  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  border: 1px solid var(--rule);
}

@media (min-width: 52rem) {
  .steps { grid-template-columns: repeat(3, 1fr); }
}

.steps > div {
  position: relative;
  padding: clamp(1.5rem, 1.1rem + 1.4vw, 2.4rem);
}

.steps > div + div { border-top: 1px solid var(--rule); }

@media (min-width: 52rem) {
  .steps > div + div { border-top: 0; border-left: 1px solid var(--rule); }
}

.steps .tag {
  display: inline-block;
  margin-bottom: 1rem;
  padding: 0.32rem 0.6rem;
  border: 1px solid color-mix(in oklab, var(--accent) 45%, transparent);
  border-radius: 2px;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
}

.steps :is(h3, h4) { margin-bottom: 0.9rem; }

.steps ul { margin: 0 0 1.25rem; padding: 0; list-style: none; }

.steps li {
  position: relative;
  padding: 0.4rem 0 0.4rem 1.15rem;
  font-size: var(--fs-body);
  color: var(--fg-soft);
}

.steps li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.02rem;
  width: 0.55rem;
  height: 1px;
  background: var(--accent-line);
}

.steps .out {
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  font-family: var(--ff-text);
  font-style: italic;
  font-size: var(--fs-body);
  color: var(--fg);
}

/* --- 8.8 grille de contrôle --------------------------------------------- */

.control {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.control > div {
  position: relative;
  padding: clamp(1.35rem, 1rem + 1.1vw, 2rem);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--rule);
  transition: background var(--t-mid) var(--ease);
}

.control > div:hover { background: var(--bg-raised); }

.control :is(h3, h4) {
  margin-bottom: 0.5rem;
  color: var(--accent);
}

.control p { font-size: var(--fs-body); color: var(--fg-soft); }

/* --- 8.9 tableaux tenus par des filets ---------------------------------- */

.ledger { overflow-x: auto; }

.ledger table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-body);
  min-width: 34rem;
}

.ledger :is(th, td) {
  padding: 0.95rem 1.1rem 0.95rem 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
  color: var(--fg-soft);
}

.ledger thead th {
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--rule-strong);
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}

.ledger tbody td:first-child,
.ledger tbody th:first-child {
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
}

.ledger tbody tr { transition: background var(--t-fast) var(--ease); }
.ledger tbody tr:hover { background: color-mix(in oklab, var(--accent) 6%, transparent); }
.ledger tbody tr:last-child :is(th, td) { border-bottom: 0; }

.ledger .num-cell { font-variant-numeric: tabular-nums; white-space: nowrap; }

.ledger caption,
.ledger .wp-element-caption {
  caption-side: bottom;
  margin-top: 1rem;
  text-align: left;
  font-size: var(--fs-small);
  color: var(--fg-soft);
}

/* --- 8.10 scénarios chiffrés -------------------------------------------- */

.scenarios {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.scenario {
  padding: clamp(1.4rem, 1rem + 1.3vw, 2.2rem);
  border: 1px solid var(--rule);
  transition: border-color var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}

.scenario:hover { border-color: var(--rule-strong); transform: translateY(-3px); }

.scenario--key {
  border-color: color-mix(in oklab, var(--accent) 55%, transparent);
  background: color-mix(in oklab, var(--accent) 6%, transparent);
}

.scenario h3 {
  margin-bottom: 1.25rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--rule);
}

.scenario dl { margin: 0; }

.scenario .row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  font-size: 0.9rem;
  color: var(--fg-soft);
}

.scenario .row b {
  font-family: var(--ff-display);
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

.scenario__figure {
  display: block;
  margin: 1.1rem 0 0.4rem;
  font-family: var(--ff-display);
  font-size: var(--fs-figure);
  line-height: 1;
  color: var(--accent-lg);
  font-variant-numeric: tabular-nums;
}

.scenario__note {
  margin-top: 0.75rem;
  font-family: var(--ff-text);
  font-style: italic;
  font-size: 0.95rem;
  color: var(--fg-soft);
}

/* --- 8.11 frise du parcours --------------------------------------------- */

.journey { position: relative; }

/* .section coupe l'overflow pour border les décors de fond (graticules,
   marquee) : sur une section qui empile des cartes collantes, cette même
   coupe empêche le navigateur de les accrocher au viewport. */
.section:has(.journey__stops) { overflow: visible; }

/* Le chapô à gauche, la pile de cartes à droite. Étendu à #parcours plutôt
   qu'à .chapter en général : les autres chapitres (éligibilité, objections)
   gardent leur intro pleine largeur au-dessus de leur grille. */
@media (min-width: 62rem) {
  #parcours {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    /* La pile de cartes dépasse de loin la hauteur du chapô : même en
       min-content, une rangée dont la taille reste intrinsèque continue de
       recevoir sa part de ce surplus (seule une taille fixe y échappe), et
       la rangée du label gonflait d'autant, ouvrant un vide au-dessus du
       titre. Une hauteur fixe pour le label force tout le surplus vers la
       seconde rangée, invisible sous un chapô aligné en haut. */
    grid-template-rows: 1.8rem 1fr;
    column-gap: clamp(2rem, 1rem + 4vw, 5rem);
    align-items: start;
    padding-inline: max(var(--gutter), calc(50% - var(--shell) / 2));
    /* .section pose un grand pace au-dessus du contenu : le chapô devait
       défiler tout ce pace avant d'atteindre son propre décalage collant,
       ce qui se voyait comme un temps mort avant l'accroche. Ramené à la
       hauteur du header, la rangée du haut naît déjà à son point de
       fixation — elle est collante dès la première image, pas après coup. */
    padding-top: calc(var(--masthead-real) + 1rem);
    padding-bottom: var(--pace);
  }

  #parcours > * { width: auto; margin-left: 0; }

  #parcours > .label {
    grid-column: 1;
    grid-row: 1;
    position: sticky;
    top: calc(var(--masthead-real) + 1rem);
  }

  /* La pile à droite défile bien plus longtemps que le chapô n'est haut :
     sans ça, le texte quitte l'écran avant la fin de la pile. Le figer
     laisse le lecteur garder l'intro sous les yeux jusqu'à la dernière
     carte, où la rangée se termine et le défilement normal reprend. Le
     décalage reprend exactement la hauteur de la rangée du label
     au-dessus (1.8rem, sans espace entre les deux) pour que les deux
     s'immobilisent ensemble, sans à-coup. */
  #parcours > .chapter {
    grid-column: 1;
    grid-row: 2;
    position: sticky;
    top: calc(var(--masthead-real) + 1rem + 1.8rem);
  }

  /* La marge du haut, posée en style inline dans le contenu pour l'empilement
     vertical d'origine, décalerait la colonne de droite sous celle de
     gauche : elle n'a plus lieu d'être une fois les deux colonnes côte à
     côte. */
  #parcours > .journey {
    grid-column: 2;
    grid-row: 1 / 3;
    margin-top: 0 !important;
  }

  /* Barre d'admin de WordPress : elle s'intercale au-dessus du header sans
     être comptée dans --masthead-real. Sans ce correctif, la
     prévisualisation connectée montre un chapô qui s'accroche 32px trop
     haut, caché derrière la barre. Ce chapô à deux colonnes n'existe qu'à
     partir de cette largeur : la même compensation, posée hors media query,
     s'appliquait aussi en dessous, où .label garde le position:relative
     générique de .section > .label — elle atterrissait donc décalée en
     plein milieu du texte plutôt qu'au-dessus du titre. */
  .admin-bar #parcours { padding-top: calc(var(--masthead-real) + 1rem + 32px); }
  .admin-bar #parcours > .label { top: calc(var(--masthead-real) + 1rem + 32px); }
  .admin-bar #parcours > .chapter { top: calc(var(--masthead-real) + 1rem + 1.8rem + 32px); }
}

.journey__rail { display: none; }

.journey__rail i {
  position: absolute;
  inset: 0;
  background: var(--accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1600ms var(--ease) 120ms;
}

.journey.is-in .journey__rail i { transform: scaleX(1); }

/* Chaque étape se fige sous le filet doré, à la même cote que la
   suivante : plus de décalage en escalier, la pile ne montre qu'une carte
   à la fois. Ce qui les distingue, c'est --exit (posé image par image par
   iba.js) : le temps que la carte suivante approche de son propre point de
   fixation, la précédente se réduit et se dissipe vers le filet, comme
   rangée, plutôt que de rester peinte sous celle qui la recouvre. */
.journey__stops {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  max-width: 42rem;
}

.journey__stops div {
  position: sticky;
  top: calc(var(--masthead-real) + 3.5rem);
  z-index: calc(var(--i, 0) + 1);
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  column-gap: 1.5rem;
  padding: clamp(1.75rem, 1.4rem + 1.5vw, 2.5rem) clamp(1.5rem, 1.1rem + 1.5vw, 2.5rem);
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--bg-raised);
  box-shadow: 0 16px 24px -20px color-mix(in oklab, var(--navy-900) 80%, transparent);
  transform: translateY(calc(var(--exit, 0) * -2.5rem)) scale(calc(1 - var(--exit, 0) * 0.14));
  opacity: calc(1 - var(--exit, 0));
  transform-origin: 50% 0%;
}

.journey__stops b {
  grid-column: 1;
  grid-row: 1 / 3;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--accent-line);
  border-radius: 50%;
  font-family: var(--ff-display);
  font-size: 1rem;
  font-weight: 400;
  color: var(--accent);
  background: var(--bg);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 420ms var(--ease), transform 420ms var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms + 260ms);
  font-variant-numeric: tabular-nums;
}

.journey.is-in .journey__stops b { opacity: 1; transform: scale(1); }

.journey__stops h3 { margin-bottom: 0.5rem; }
.journey__stops span { display: block; font-size: var(--fs-body); color: var(--fg-soft); }

/* --- 8.12 grille d'éligibilité ------------------------------------------ */

/* Chaque case porte son propre filet haut : sur une grille qui passe à la
   ligne, une bordure posée sur le conteneur se décale d'une rangée à
   l'autre. */
.facets {
  display: grid;
  column-gap: clamp(1.5rem, 0.8rem + 2vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.facets > div {
  position: relative;
  padding: 1.6rem 0;
  border-top: 1px solid var(--rule);
  transition: padding-left var(--t-mid) var(--ease);
}

.facets > div:hover { padding-left: 1.5rem; }

.facets > div::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2.35rem;
  width: 0;
  height: 1px;
  background: var(--accent-line);
  transition: width var(--t-mid) var(--ease);
}

.facets > div:hover::before { width: 1rem; }

.facets .num {
  display: block;
  margin-bottom: 0.6rem;
  font-family: var(--ff-display);
  font-size: 1rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.facets :is(h3, h4) { margin-bottom: 0.4rem; }
.facets p { font-size: var(--fs-body); color: var(--fg-soft); }

/* --- 8.13 accordéon des objections -------------------------------------- */

.acc { border-top: 1px solid var(--rule); }

.acc details { border-bottom: 1px solid var(--rule); }

.acc summary {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 1.4rem 3rem 1.4rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  line-height: 1.15;
  color: var(--fg);
  transition: color var(--t-fast) var(--ease);
}

.acc summary::-webkit-details-marker { display: none; }
.acc summary::marker { content: ""; }
.acc summary:hover { color: var(--accent); }

.acc summary::after {
  content: "";
  position: absolute;
  right: 0.4rem;
  /* Centré sur la hauteur du résumé plutôt que calé à une cote fixe : une
     question qui passe sur deux lignes sur mobile désaligne sinon le
     chevron, resté à la hauteur d'une ligne unique. */
  top: 50%;
  width: 0.65rem;
  height: 0.65rem;
  border-right: 1px solid var(--accent-line);
  border-bottom: 1px solid var(--accent-line);
  transform: translateY(-50%) rotate(45deg);
  transform-origin: center;
  transition: transform var(--t-mid) var(--ease);
}

.acc details[open] summary::after { transform: translateY(-50%) rotate(-135deg); }

.acc .ans {
  overflow: hidden;
  padding: 0 0 1.6rem;
  max-width: 68ch;
  color: var(--fg-soft);
  animation: unfold var(--t-slow) var(--ease);
}

@keyframes unfold {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- 8.14 deux portes --------------------------------------------------- */

.doors {
  display: grid;
  gap: 0;
  border: 1px solid var(--rule);
}

@media (min-width: 58rem) {
  .doors { grid-template-columns: 1fr 1fr; }
}

.doors__door {
  position: relative;
  overflow: hidden;
  padding: clamp(1.75rem, 1.2rem + 1.9vw, 3.25rem);
  transition: background var(--t-mid) var(--ease);
}

.doors__door + .doors__door { border-top: 1px solid var(--rule); }

@media (min-width: 58rem) {
  .doors__door + .doors__door { border-top: 0; border-left: 1px solid var(--rule); }
}

.doors__door:hover { background: color-mix(in oklab, var(--accent) 6%, transparent); }

.doors__who {
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.85rem;
}

.doors__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  line-height: 1.15;
  margin-bottom: 1.4rem;
  color: var(--fg);
}

.steps-list { margin: 0 0 1.75rem; padding: 0; list-style: none; }

.steps-list li {
  position: relative;
  padding: 0.55rem 0 0.55rem 1.4rem;
  font-size: var(--fs-body);
  color: var(--fg-soft);
  border-top: 1px solid var(--rule);
}

.steps-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.28rem;
  width: 0.7rem;
  height: 1px;
  background: var(--accent-line);
}

.doors__link {
  position: relative;
  display: inline-block;
  padding-bottom: 0.35rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--accent);
}

.doors__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease);
}

.doors__link:hover::after { transform: scaleX(0.35); }

/* --- 8.15 citation ------------------------------------------------------ */

.quote {
  /* margin-block seulement : un margin: 0 écrasait la marge gauche posée
     par .section > *, et la citation partait au bord de la page. */
  margin-block: 0;
  padding-left: clamp(1.25rem, 0.5rem + 2vw, 2.5rem);
  border-left: 1px solid var(--accent-line);
}

.quote p {
  font-family: var(--ff-text);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--fg);
}

.quote cite,
.quote .wp-block-quote__citation {
  display: block;
  margin-top: 1rem;
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-style: normal;
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent);
}

/* --- 8.16 filets -------------------------------------------------------- */

.rule,
.wp-block-separator.rule {
  height: 1px;
  border: 0;
  background: var(--rule);
  opacity: 1;
  margin-block: var(--sp-5);
}

.rule--partial { width: 4rem; background: var(--accent-line); }

/* --- 8.17 clôture ------------------------------------------------------- */

.closing { position: relative; overflow: hidden; }

.closing__title {
  font-size: var(--fs-h2);
  max-width: 18ch;
  margin-bottom: 1.5rem;
}

.closing__lead { max-width: 54ch; color: var(--fg-soft); font-size: var(--fs-lead); font-family: var(--ff-text); }

.closing__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
  margin-top: var(--sp-4);
}

.closing__grid { display: grid; gap: var(--sp-5); }

@media (min-width: 64rem) {
  .closing__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2.5rem, 1rem + 5vw, 6rem); }
}

/* ==========================================================================
   9. FORMULAIRE
   ========================================================================== */

.iba-form {
  /* Cases blanches cernées d'or : sur le papier et sous le tracé gravé de
     la clôture, un simple filet bas se perdait. Le blanc reste teinté vers
     le papier, jamais pur. L'or profond passe 3:1 sur ce fond, seuil d'un
     contour de composant. */
  --field-bg: oklch(0.995 0.003 85);
  --field-line: var(--accent-line);
  --field-line-hover: color-mix(in oklab, var(--accent-line), var(--ink) 22%);
  --field-error: oklch(0.58 0.19 27);

  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.dark .iba-form {
  --field-bg: var(--bg-raised);
  --field-line-hover: color-mix(in oklab, var(--accent-line), var(--sky) 30%);
  --field-error: oklch(0.76 0.15 27);
}

.iba-form .field { display: flex; flex-direction: column; gap: 0.5rem; }
.iba-form .field--full { grid-column: 1 / -1; }

.iba-form :is(label, legend) {
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  color: var(--fg-soft);
}

.iba-form .req { color: var(--accent); }

/* --- champs à étiquette flottante ---------------------------------------

   Adapté du « Floating Label » de 21st.dev, sans React ni motion.
   La case entière est le champ : fond blanc, filet or. L'étiquette repose à
   la hauteur de la saisie tant que le champ est vide et monte, au focus ou
   dès qu'il est rempli, dans une réserve ménagée en haut de la case : elle
   ne disparaît jamais et rien ne bouge autour d'elle. */

.iba-form .field__control {
  position: relative;
  padding-top: 1.55rem;
  border: 1px solid var(--field-line);
  border-radius: 2px;
  /* Fond opaque : le tracé gravé de la clôture passe derrière le
     formulaire, et une case transparente le laisserait traverser la saisie. */
  background: var(--field-bg);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-mid) var(--ease);
}

.iba-form .field__control:hover { border-color: var(--field-line-hover); }

.iba-form .field__control:focus-within {
  border-color: var(--field-line);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent-line) 16%, transparent);
}

.iba-form .field__control > :is(input, textarea) {
  display: block;
  width: 100%;
  padding: 0.15rem 1rem 0.7rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--fg);
  font-family: var(--ff-ui);
  font-size: var(--fs-body);
  line-height: 1.4;
}

.iba-form .field__control textarea { min-height: 8.5rem; resize: vertical; }

.iba-form .field__control > :is(input, textarea):focus { outline: none; }

/* Le remplissage automatique peint son propre fond bleuté : on le recouvre
   du blanc de la case. Règle séparée, un sélecteur inconnu invaliderait la
   liste. */
.iba-form .field__control > :-webkit-autofill {
  -webkit-box-shadow: 0 0 0 100px var(--field-bg) inset;
  -webkit-text-fill-color: var(--fg);
}

.iba-form .field__control > label {
  position: absolute;
  left: 1rem;
  top: 0.7rem;
  max-width: calc(86% - 1rem);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  pointer-events: none;
  transform-origin: left top;
  transform: translateY(0.8rem) scale(1.16);
  transition: transform var(--t-mid) var(--ease), color var(--t-fast) var(--ease);
}

.iba-form .field__control > :focus + label,
.iba-form .field__control > :not(:placeholder-shown) + label { transform: none; }

/* Règle séparée : un sélecteur inconnu invaliderait toute la liste. */
.iba-form .field__control > :-webkit-autofill + label { transform: none; }

.iba-form .field__control > :focus + label { color: var(--accent); }

.iba-form .field__control ::placeholder {
  color: transparent;
  transition: color var(--t-fast) var(--ease);
}

.iba-form .field__control :focus::placeholder {
  color: color-mix(in oklab, var(--fg-soft) 70%, transparent);
}

/* Filet or qui se dessine de gauche à droite sur le bord bas de la case
   active, le même trait que sous le profil coché. */
.iba-form .field__control::after {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  bottom: -1px;
  height: 2px;
  background: var(--accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease);
  pointer-events: none;
}

.iba-form .field__control:focus-within::after { transform: scaleX(1); }

.iba-form .field__control:has([aria-invalid="true"]),
.iba-form .field__control:has([aria-invalid="true"]):hover { border-color: var(--field-error); }
.iba-form .field__control:has([aria-invalid="true"])::after { background: var(--field-error); }
.iba-form .field__control:has([aria-invalid="true"]):focus-within {
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--field-error) 14%, transparent);
}
.iba-form [aria-invalid="true"] + label { color: var(--field-error); }

/* --- liste déroulante du profil -----------------------------------------

   Un <select> natif, un seul profil, obligatoire : le clavier, le mobile
   et la validation viennent sans code. Même case que les autres champs,
   chevron or. Là où le navigateur le permet (appearance: base-select), la
   liste ouverte prend aussi le blanc et le filet or ; ailleurs, elle reste
   celle du système. */

.iba-form .field__control > select {
  display: flex;
  align-items: center;
  width: 100%;
  /* Hauteur d'un champ texte, même vide : sans valeur affichée, le select
     de base-select s'écraserait sur son rembourrage. */
  min-height: calc(2.4rem + var(--fs-body) * 1.4);
  /* La zone cliquable couvre aussi la réserve de l'étiquette. */
  margin: -1.55rem 0 0;
  padding: 1.7rem 2.75rem 0.7rem 1rem;
  border: 0;
  border-radius: 0;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23a97b26' stroke-width='1.3'/%3E%3C/svg%3E") no-repeat right 1.1rem center / 0.75rem auto;
  color: var(--fg);
  font-family: var(--ff-ui);
  font-size: var(--fs-body);
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

.dark .iba-form .field__control > select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23dda53f' stroke-width='1.3'/%3E%3C/svg%3E");
}

.iba-form .field__control > select:focus { outline: none; }

/* Tant que l'option vide est choisie, le champ est :invalid : l'étiquette
   reste au repos. Un select n'a pas de :placeholder-shown. */
.iba-form .field__control > select:invalid:not(:focus) + label { transform: translateY(0.8rem) scale(1.16); }

/* Liste ouverte sans focus (clic depuis un autre onglet, par exemple) :
   l'étiquette monte quand même. Règle séparée, :open est encore inconnu de
   certains navigateurs et invaliderait la précédente. */
.iba-form .field__control > select:open:invalid + label { transform: none; }

@supports (appearance: base-select) {
  .iba-form .field__control > select,
  .iba-form .field__control > select::picker(select) { appearance: base-select; }

  .iba-form .field__control > select::picker-icon { display: none; }

  .iba-form .field__control > select::picker(select) {
    margin-top: 0.4rem;
    padding: 0.35rem 0;
    border: 1px solid var(--field-line);
    border-radius: 2px;
    background: var(--field-bg);
    box-shadow: 0 1rem 2rem -1.25rem color-mix(in oklab, var(--navy-900) 40%, transparent);
  }

  .iba-form .field__control > select option {
    padding: 0.7rem 1rem;
    color: var(--fg);
    font-size: var(--fs-body);
    transition: background var(--t-fast) var(--ease);
  }

  .iba-form .field__control > select option:is(:hover, :focus-visible) {
    outline: none;
    background: color-mix(in oklab, var(--accent) 7%, var(--field-bg));
  }

  .iba-form .field__control > select option::checkmark { color: var(--accent-line); }
}

@media (prefers-reduced-motion: reduce) {
  .iba-form .field__control > label,
  .iba-form .field__control::after { transition: none !important; }
}

.iba-form .field__error:empty { display: none; }

.iba-form .field__error {
  font-size: var(--fs-small);
  color: var(--field-error);
}

.iba-form .consent {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  font-family: var(--ff-ui);
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.5;
  color: var(--fg-soft);
  cursor: pointer;
}

/* Case à cocher redessinée pour porter le même filet or que les champs :
   la case native, grise et arrondie, détonnait à côté. */
.iba-form .consent input {
  flex: 0 0 auto;
  display: grid;
  place-content: center;
  width: 1.15rem;
  height: 1.15rem;
  margin: 0.15rem 0 0;
  border: 1px solid var(--field-line);
  border-radius: 2px;
  background: var(--field-bg);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}

.iba-form .consent input::after {
  content: "";
  width: 0.62rem;
  height: 0.34rem;
  margin-top: -0.12rem;
  border-left: 2px solid var(--field-bg);
  border-bottom: 2px solid var(--field-bg);
  transform: rotate(-45deg) scale(0);
  transition: transform var(--t-fast) var(--ease);
}

.iba-form .consent:hover input { border-color: var(--field-line-hover); }

.iba-form .consent input:checked {
  border-color: var(--accent-line);
  background: var(--accent-line);
}

.iba-form .consent input:checked::after { transform: rotate(-45deg) scale(1); }

.dark .iba-form .consent input::after { border-color: var(--navy-900); }

.iba-form .consent input:focus-visible {
  outline: 2px solid var(--accent-line);
  outline-offset: 2px;
}

.iba-form .consent input[aria-invalid="true"] { border-color: var(--field-error); }

.iba-form .hp {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.iba-form button[type="submit"] {
  position: relative;
  z-index: 0;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1rem 1.9rem;
  border: 1px solid var(--gold);
  border-radius: 2px;
  background: var(--gold);
  color: var(--navy-900);
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease);
}

.iba-form button[type="submit"]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--navy-900);
  transform: translateY(101%);
  transition: transform var(--t-mid) var(--ease);
}

.iba-form button[type="submit"]:hover { color: var(--gold); }
.iba-form button[type="submit"]:hover::before { transform: translateY(0); }
.iba-form button[type="submit"][disabled] { opacity: 0.55; cursor: progress; }
.iba-form button[type="submit"][disabled]::before { transform: translateY(101%); }

.iba-form .form__status {
  grid-column: 1 / -1;
  padding: 0.9rem 1.1rem;
  border-left: 1px solid var(--accent-line);
  background: color-mix(in oklab, var(--accent) 8%, transparent);
  font-size: var(--fs-body);
  color: var(--fg);
}

.iba-form .form__status:empty { display: none; }

.iba-form .form__status[data-state="error"] {
  border-left-color: oklch(0.58 0.19 27);
  background: color-mix(in oklab, oklch(0.58 0.19 27) 9%, transparent);
}

/* ==========================================================================
   10. PIED DE PAGE
   ========================================================================== */

.footer {
  background: var(--navy-900);
  color: var(--sky);
  padding-block: clamp(3.5rem, 2rem + 5vw, 6rem) 2rem;
  --rule: color-mix(in oklab, var(--sky) 16%, transparent);
}

.footer__inner {
  display: grid;
  gap: clamp(2rem, 1rem + 3vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

@media (min-width: 68rem) {
  .footer__inner { grid-template-columns: minmax(0, 1.7fr) repeat(3, minmax(0, 1fr)); }
}

.footer__brand img { height: clamp(2.75rem, 2.4rem + 1vw, 3.5rem); width: auto; }
.footer__brand .brand { position: static; }
.footer__brand .brand__mark { position: static; opacity: 1; }
.footer__brand .brand__alt { display: none; }

.footer__brand p {
  margin-top: 1.25rem;
  max-width: 36ch;
  font-size: var(--fs-small);
  color: color-mix(in oklab, var(--sky) 72%, var(--navy-900));
}

.footer__brand em { font-family: var(--ff-text); font-style: italic; color: var(--gold); }

.footer h2 {
  margin-bottom: 1.1rem;
  font-family: var(--ff-ui);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--gold);
}

.footer ul { margin: 0; padding: 0; list-style: none; }
.footer li + li { margin-top: 0.6rem; }

.footer a {
  font-size: var(--fs-small);
  text-decoration: none;
  color: color-mix(in oklab, var(--sky) 80%, var(--navy-900));
  transition: color var(--t-fast) var(--ease);
}

.footer a:hover { color: var(--gold); }

.footer .iba-nav a { padding-block: 0; font-size: var(--fs-small); font-weight: 400; letter-spacing: 0; text-transform: none; }
.footer .iba-nav a::after { display: none; }
.footer .iba-nav__list { flex-direction: column; align-items: flex-start; gap: 0.6rem; }

.footer .lang-switch {
  margin-top: 1.1rem;
  --mh-link: var(--sky);
  --mh-link-strong: var(--gold);
}

/* .footer li + li vise les listes empilées (nav, propriétaires) : sur cette
   liste-ci, affichée en ligne, elle poussait « EN » sous la ligne de base de
   « FR » au lieu de l'aligner à côté. */
.footer .lang-switch li + li { margin-top: 0; }

/* .footer a impose 0.92rem à tout lien, y compris la langue non courante :
   sans cette règle, elle se retrouve plus grande que la langue courante
   (un <span>, non concerné par ce sélecteur), qui hérite de --fs-label. */
.footer .lang-switch a,
.footer .lang-switch .current-lang {
  font-size: var(--fs-label);
}

.footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  margin-top: clamp(2.5rem, 1.5rem + 3vw, 4rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.footer__base p {
  font-size: var(--fs-small);
  color: color-mix(in oklab, var(--sky) 58%, var(--navy-900));
}

/* ==========================================================================
   11. MOUVEMENT
   Une courbe unique, des révélations décalées, aucune animation de
   propriété de mise en page.
   ========================================================================== */

.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity var(--t-slow) var(--ease),
    transform var(--t-slow) var(--ease);
  transition-delay: var(--delay, 0ms);
  will-change: opacity, transform;
}

.reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Variante latérale, réservée aux blocs qui se lisent de gauche à droite
   (les chaînes de flux, la planche d'échange). */
.reveal--side { transform: translateX(-20px); }
.reveal--side.is-in { transform: none; }

/* Chiffre qui se compose. La valeur finale reste dans le DOM pour les
   lecteurs d'écran et pour l'indexation ; seul l'affichage est animé. */
[data-count] { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   11b. FINITIONS
   Trois grilles qui laissaient une case orpheline sur grand écran, et les
   intertitres de sous-chapitre qui se lisaient plus petits que le chapô
   qui les suit.
   ========================================================================== */

/* Six domaines de contrôle : auto-fit en posait cinq puis un seul. Deux
   rangées de trois tiennent la grille. */
@media (min-width: 62rem) {
  .control:has(> :nth-child(6)) { grid-template-columns: repeat(3, 1fr); }
  /* La grille de profil n'en compte que quatre : une seule rangée. */
  .control:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, 1fr); }
}

/* Intertitre de sous-chapitre : un h3 posé directement dans la section,
   qui ouvre un tableau, une grille ou une phrase de chapô. Un filet or
   court au-dessus et un écart plus large le séparent du bloc précédent. */
.section > h3 {
  position: relative;
  margin-top: var(--sp-6);
  padding-top: 1.25rem;
  max-width: 30ch;
  font-size: var(--fs-h3);
  line-height: 1.15;
}

.section > h3::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 2.25rem;
  height: 1px;
  background: var(--accent-line);
}

.section > h3 + .lead { margin-top: var(--sp-2); }
.section > h3 + :is(.ledger, .control, .steps, .scenarios, .facets, .journey, .exchange) { margin-top: var(--sp-3); }

/* Note qui suit un intertitre (« Exemple pédagogique… ») : elle colle au
   titre, le bloc chiffré vient ensuite. */
.section > h3 + .note { margin-top: var(--sp-2); max-width: 60ch; }
.section > .note + :is(.scenarios, .ledger, .steps) { margin-top: var(--sp-4); }

/* ==========================================================================
   12. RÉGLAGES D'ACCESSIBILITÉ ET D'IMPRESSION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .reveal,
  .hero__title .w > span,
  .journey__stops b { opacity: 1 !important; transform: none !important; }

  .journey__rail i,
  .chain-flow i,
  .hero__eyebrow::after,
  .section > .label::before { transform: scaleX(1) !important; }

  .graticule--spin,
  .graticule--twin,
  .scroll-hint i { animation: none !important; }

  .graticule { translate: 0 -50% !important; }

  /* Le bandeau garde son aplat mais cesse de défiler : la piste passe à la
     ligne dans la colonne de texte. Le JavaScript ne clone rien dans ce
     cas, donc aucun texte n'est répété. */
  .marquee { overflow: visible; -webkit-mask-image: none; mask-image: none; }

  .marquee__track {
    flex-wrap: wrap;
    row-gap: 0.6rem;
    width: min(100% - var(--gutter) * 2, var(--shell));
    min-width: 0;
    margin-inline: auto;
    padding-right: 0;
    animation: none !important;
  }
  .marquee__track > li:last-child::after { display: none; }
}

@media print {
  .masthead,
  .drawer,
  .scroll-hint,
  .graticule,
  .iba-form { display: none !important; }

  .section { padding-block: 1.5rem; background: #fff !important; color: #000 !important; }
  .dark, .dark--deep { background: #fff !important; color: #000 !important; }
  .dark :is(h1, h2, h3, h4), .dark p { color: #000 !important; }
  .acc .ans { display: block !important; }
  .flows .ln { stroke-dashoffset: 0 !important; }
  .flows .pop { opacity: 1 !important; transform: none !important; }
  a::after { content: " (" attr(href) ")"; font-size: 0.8em; }
}

/* ==========================================================================
   13. ÉDITEUR
   Le contenu vit en base : l'éditeur doit rendre les mêmes composants,
   sans le header collant ni les révélations qui masqueraient les blocs.
   ========================================================================== */

.editor-styles-wrapper .reveal { opacity: 1; transform: none; }
.editor-styles-wrapper .flows .ln { stroke-dashoffset: 0; }
.editor-styles-wrapper .flows .pop { opacity: 1; transform: none; }
.editor-styles-wrapper .hero { min-height: 0; padding-top: 4rem !important; }
.editor-styles-wrapper .graticule { display: none; }
.editor-styles-wrapper .journey__rail i,
.editor-styles-wrapper .chain-flow i { transform: scaleX(1); }
.editor-styles-wrapper .journey__stops b { opacity: 1; transform: none; }
.editor-styles-wrapper .hero__title .w > span { transform: none; }
.editor-styles-wrapper .marquee { overflow: visible; -webkit-mask-image: none; mask-image: none; }
.editor-styles-wrapper .marquee__track { flex-wrap: wrap; row-gap: 0.6rem; min-width: 0; animation: none; }

/* ==========================================================================
   14. GARDE-FOUS
   Les décorations en position absolue sont posées dans le flux par le
   contenu de la page : elles ne doivent ni prendre la largeur de la
   colonne ni décaler ce qui les suit.
   ========================================================================== */

.section > .graticule,
.hero > .graticule {
  width: clamp(24rem, 58vw, 62rem);
  margin: 0;
}

.section > .graticule--twin,
.hero > .graticule--twin { width: clamp(13rem, 30vw, 32rem); }

.section > .graticule + * { margin-top: 0; }

/* Les blocs de groupe imbriqués par WordPress ne doivent pas re-borner
   la largeur : la section s'en charge déjà. */
.section > .wp-block-group > .wp-block-group { width: 100%; }

/* Le contenu de page est rendu en flux, donc déjà pleine largeur : aucune
   compensation en 100vw, qui déborderait de la largeur de la barre de
   défilement. */
.wp-block-post-content > .alignfull { width: 100%; max-width: 100%; }

main.wp-block-group { overflow-x: clip; }

/* ==========================================================================
   15. PAGE SIMPLE
   Mentions légales et toute page de texte long : un bandeau navy court,
   puis une colonne de lecture unique.
   ========================================================================== */

/* Sur une page simple le header reste dans le flux, en plaque papier :
   inutile de compenser sa hauteur, elle est déjà prise. */
.page-band {
  padding-block: clamp(2.5rem, 1.5rem + 3.5vw, 4.5rem);
}

.page-band h1 { max-width: 20ch; }

.prose > * + * { margin-top: 1.5rem; }

.prose p {
  color: var(--fg-soft);
}

.prose h2 {
  margin-top: var(--sp-5);
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: var(--fs-h4);
  line-height: 1.15;
}

.prose h2 + p { margin-top: 0.75rem; }

.prose a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: var(--accent-line);
  text-underline-offset: 0.2em;
  transition: color var(--t-fast) var(--ease);
}

.prose a:hover { color: var(--accent); }

/* La gouttière globale de theme.json s'ajouterait à celle des sections :
   deux marges au lieu d'une, et une colonne de texte trop étroite. */
.section.has-global-padding,
.section > .has-global-padding,
.wp-block-post-content.has-global-padding { padding-inline: 0; }

.closing__grid > .wp-block-group { width: 100%; margin-inline: 0; }

/* Page intérieure sans hero : les mentions légales gardent la mise en
   page du thème, mais sur un fond papier et une mesure de lecture bornée. */
.page-template-page-plain .section > .wp-block-post-title {
  margin-bottom: clamp(2rem, 1.2rem + 2vw, 3rem);
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}

.page-template-page-plain .entry-content > * + * { margin-top: 1.75rem; }
/* Rubriques en h2 au cran des titres de carte ; la première colle au
   filet du titre de page, sans second filet. */
.page-template-page-plain .entry-content h2 { margin-top: var(--sp-5); padding-top: 1.5rem; border-top: 1px solid var(--rule); font-size: var(--fs-h4); line-height: 1.15; }
.page-template-page-plain .entry-content h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.page-template-page-plain .entry-content h2 + p { margin-top: 0.75rem; }
.page-template-page-plain .entry-content p { color: var(--fg-soft); }
.page-template-page-plain .entry-content a { color: var(--accent); }

/* Cible tactile du sélecteur de langue dans le tiroir : le header en cache
   la version compacte sous 60rem, celle du tiroir doit se toucher. */
.drawer .lang-switch { gap: 0.75rem; font-size: var(--fs-small); }

.drawer .lang-switch li,
.drawer .lang-switch a,
.drawer .lang-switch .current-lang {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.35rem;
}

.drawer .lang-switch li + li::before { align-self: center; }
