/* ===== Reset & base ===== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: auto; }
body {
  margin: 0;
  background: var(--papier-creme);
  font-family: var(--font-texte);
  color: var(--encre);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: var(--petrole); text-decoration: none; }
a:hover { color: var(--petrole-fonce); }
h1, h2, h3, h4, p { margin: 0; }
button { font-family: inherit; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--petrole);
  outline-offset: 2px;
}

.site {
  position: relative;
  max-width: 1440px;
  margin: 0 auto;
  background: var(--papier-creme);
  overflow: hidden;
}

.container {
  padding-inline: clamp(24px, 5.6vw, 80px);
}

/* Grain statique, jamais animé */
.grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 40;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22160%22 height=%22160%22%3E%3Cfilter id=%22g%22%3E%3CfeTurbulence type=%22fractalNoise%22 baseFrequency=%220.9%22 numOctaves=%223%22 stitchTiles=%22stitch%22/%3E%3C/filter%3E%3Crect width=%22160%22 height=%22160%22 filter=%22url%28%23g%29%22 opacity=%220.5%22/%3E%3C/svg%3E');
}

/* Trait d'encre décoratif */
.trait { display: block; width: 100%; }
.trait path { stroke: var(--encre); }

/* ===== Typo utilitaires ===== */
.surtitre {
  margin: 0 0 8px 0;
  font-size: var(--taille-surtitre);
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--encre-3);
}
.surtitre--petrole { color: var(--petrole); }
.h-display {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144;
  font-weight: 600;
  font-size: var(--taille-display);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--encre);
}
.h1 {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144;
  font-weight: 600;
  font-size: var(--taille-h1);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--encre);
}
.h2 {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144;
  font-weight: 600;
  font-size: var(--taille-h2);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--petrole-fonce);
}
.h3 {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 96;
  font-weight: 600;
  font-size: var(--taille-h3);
  line-height: 1.25;
  color: var(--encre);
}
.h4 {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 48;
  font-weight: 600;
  font-size: 21px;
  line-height: 1.3;
  color: var(--encre);
}
.corps-l { font-size: var(--taille-corps-l); line-height: 1.65; color: var(--encre-2); }
.corps { font-size: var(--taille-corps); line-height: 1.7; color: var(--encre-2); }
.petit { font-size: var(--taille-petit); line-height: 1.6; color: var(--encre-2); }
.accent-manuscrit { font-family: var(--font-accent); font-weight: 500; color: var(--orange); display: inline-block; transform: rotate(-4deg); }

/* ===== Boutons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 0 24px;
  border-radius: var(--rayon);
  font-size: 17px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}
.btn--primaire { background: var(--petrole); color: var(--papier-clair); }
.btn--primaire:hover { background: var(--petrole-fonce); color: var(--papier-clair); }
.btn--secondaire { background: transparent; border: 1.5px solid var(--petrole); color: var(--petrole); }
.btn--secondaire:hover { background: var(--hover-petrole); border-color: var(--petrole-fonce); color: var(--petrole-fonce); }
.btn--accent { background: var(--orange); color: var(--encre); }
.btn--accent:hover { background: var(--hover-orange); color: var(--encre); }
.btn--telecharger { border: 1.5px solid var(--orange); color: var(--encre); background: transparent; }
.btn--telecharger:hover { background: var(--vignette); color: var(--encre); }
.btn svg { flex: none; }

/* ===== Puces de filtre ===== */
.puce {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 16px;
  border-radius: var(--rayon);
  border: 1px solid var(--encre);
  color: var(--encre);
  font-size: 15px;
  background: transparent;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}
.puce[aria-pressed="true"] {
  background: var(--petrole);
  border-color: var(--petrole);
  color: var(--papier-clair);
  font-weight: 500;
}
.puce:hover:not([aria-pressed="true"]) { background: var(--hover-petrole); }

/* ===== Badges ===== */
.badge {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 8px;
  border-radius: var(--rayon);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  align-self: flex-start;
}
.badge--modele { background: var(--axe-modele); color: var(--papier-clair); }
.badge--bien-commun { background: var(--axe-bien-commun); color: var(--papier-clair); }
.badge--justice { background: var(--axe-justice); color: var(--papier-clair); }
.badge--valorisation { background: var(--axe-valorisation); color: var(--encre); }
.badge--cadre { background: var(--axe-cadre); color: var(--papier-clair); }
.badge--bientot { border: 1px dashed var(--encre); color: var(--encre); }

/* ===== Vocabulaire de plis =====================================================

   PROBLÈME RÉSOLU ICI (revue du 2026-09-04)
   -----------------------------------------
   La v1 n'avait qu'une seule forme de bloc : `.corne`, un rectangle dont le
   coin supérieur droit est coupé en diagonale. Elle était appliquée aux
   4 axes du modèle, aux 3 portes d'entrée, aux 12 cartes de livret et à
   chaque couverture — soit une vingtaine d'occurrences identiques sur deux
   pages. Le reproche : « à chaque fois c'est un carré avec l'angle en haut à
   droite coupé, c'est répétitif ». Le diagnostic est juste : une seule
   silhouette répétée annule l'effet « papier plié » qu'elle cherchait à
   produire, parce que du vrai papier ne se plie jamais deux fois pareil.

   SOLUTION : un vocabulaire, pas une forme
   ----------------------------------------
   Cinq découpes, toutes dérivées du même geste (on plie une feuille), qu'on
   distribue de sorte que deux blocs voisins n'aient jamais la même :

     .pli--corne     coin replié en HAUT À DROITE   (la découpe d'origine)
     .pli--corne-bg  coin replié en BAS À GAUCHE    (le geste miroir)
     .pli--onglet    languette d'intercalaire en haut à gauche
     .pli--dechire   bord inférieur déchiré à la main
     .pli--croquis   coins arrondis irréguliers, tracés « au crayon »

   La page Accueil promettait déjà ce vocabulaire dans sa légende — « Quatre
   axes, quatre plis » — alors que les quatre axes portaient le MÊME pli.
   Depuis cette version, la promesse est tenue : chaque axe a son pli.

   L'OREILLE DE PAPIER (le gain principal)
   ---------------------------------------
   Couper un coin ne dit pas « plié », ça dit « rogné ». Un vrai pli laisse
   voir la SOUS-FACE de la feuille. C'est ce que rend `.oreille` :

     - le bloc est découpé par clip-path : le triangle du coin devient
       réellement transparent, on voit la page à travers ;
     - le pseudo-élément ::after remplit EXACTEMENT le triangle restant du
       carré de coin — la surface où le rabat vient se poser après le pli ;
     - il est peint dans la couleur de l'envers du papier, avec une ombre
       portée sur ses deux bords libres et un pli de lumière sur l'arête.

   Géométrie : le carré de coin fait --coin de côté. La ligne de pliage va de
   (100% - coin, 0) à (100%, coin). Le coin de la feuille, en (100%, 0), bascule
   par-dessus cette ligne et atterrit en (100% - coin, coin). Le rabat couvre
   donc le triangle « inférieur gauche » du carré de coin, ce que traduit
   `polygon(0 0, 0 100%, 100% 100%)` en coordonnées locales du pseudo-élément.

   ANIMATION : le pli s'ouvre
   --------------------------
   --coin est déclaré via @property, donc INTERPOLABLE : un simple `transition`
   suffit à faire grandir la découpe et l'oreille ensemble au survol. Sans
   @property (Safari < 16.4, Firefox < 128) la valeur saute d'un coup — la
   forme reste juste, seule la transition manque. Aucun repli n'est nécessaire.

   COMPATIBILITÉ ASCENDANTE
   ------------------------
   `.corne` reste défini et se comporte comme `.pli .pli--corne` : tout
   balisage qui n'aurait pas été migré garde exactement l'aspect v1.
   ============================================================================ */

@property --coin {
  syntax: '<length>';
  inherits: true;
  initial-value: 30px;
}

.pli {
  position: relative;
  --coin: var(--pli);
}
@media (max-width: 899px) {
  .pli { --coin: var(--pli-mobile); }
}

/* ---- 1. Coin replié en haut à droite ---- */
.pli--corne {
  clip-path: polygon(0 0, calc(100% - var(--coin)) 0, 100% var(--coin), 100% 100%, 0 100%);
}

/* ---- 2. Coin replié en bas à gauche : le geste miroir ----
   Utilisé en alternance avec le précédent dans les grilles de cartes. À
   silhouette égale, l'œil lit deux objets différents simplement parce que le
   poids visuel bascule d'un angle à l'autre. */
.pli--corne-bg {
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--coin) 100%, 0 calc(100% - var(--coin)));
}

/* ---- 3. Languette d'intercalaire ----
   Le bord supérieur n'est pas droit : le premier tiers reste haut, le reste
   descend d'un cran. C'est la silhouette d'un intercalaire de classeur — un
   objet d'école, cohérent avec la DA, et une forme que rien d'autre sur la
   page ne porte. La marche fait 18px (12px en mobile) : au-delà elle mange le
   padding supérieur des cartes et le badge s'y cogne. */
.pli--onglet {
  --marche: 18px;
  clip-path: polygon(
    0 0,
    36% 0,
    calc(36% + 14px) var(--marche),
    100% var(--marche),
    100% 100%,
    0 100%
  );
}
@media (max-width: 899px) { .pli--onglet { --marche: 12px; } }

/* ---- 4. Bord inférieur déchiré ----
   Dix-sept points irréguliers le long du bord bas. Les décalages ne suivent
   aucune régularité (2, 15, 6, 13, 3, 16, 5, 12, 7, 14, 4, 13, 6, 15, 4, 14) :
   toute périodicité se voit immédiatement et retombe dans le motif décoratif,
   alors qu'on cherche l'accident. Réservé aux BANDES pleine largeur, jamais
   aux cartes : sur 300px de large la déchirure devient un zigzag graphique. */
.pli--dechire {
  /* --dent : profondeur maximale de la déchirure. Paramétrée parce que la
     bande « Le Modèle » ne fait que 120px de haut : à 16px, la déchirure y
     mordait le bas de l'origami. Elle y descend à 9px (voir .axe--modele). */
  --dent: 16px;
  clip-path: polygon(
    0% 0%, 100% 0%,
    100% calc(100% - var(--dent) * 0.88),
    93.7% calc(100% - var(--dent) * 0.25),
    87.4% calc(100% - var(--dent) * 0.94),
    81.1% calc(100% - var(--dent) * 0.38),
    74.8% calc(100% - var(--dent) * 0.81),
    68.5% calc(100% - var(--dent) * 0.13),
    62.2% calc(100% - var(--dent) * 0.75),
    55.9% calc(100% - var(--dent) * 0.31),
    49.6% calc(100% - var(--dent) * 1.00),
    43.3% calc(100% - var(--dent) * 0.44),
    37.0% calc(100% - var(--dent) * 0.81),
    30.7% calc(100% - var(--dent) * 0.19),
    24.4% calc(100% - var(--dent) * 0.88),
    18.1% calc(100% - var(--dent) * 0.38),
    11.8% calc(100% - var(--dent) * 0.75),
    5.5% calc(100% - var(--dent) * 0.25),
    0% calc(100% - var(--dent) * 0.94)
  );
}

/* ---- 5. Coins arrondis irréguliers ----
   Huit rayons différents (syntaxe horizontal / vertical de border-radius) :
   aucun coin n'a le même profil, et aucun n'est un quart de cercle. C'est le
   contour qu'on obtient en traçant un rectangle à main levée. Pas de
   clip-path ici : border-radius laisse vivre la bordure ET l'ombre portée,
   qu'un clip-path aurait toutes deux rognées. */
.pli.pli--croquis {
  /* Classe doublee VOLONTAIREMENT (.pli.pli--croquis, specificite 0,2,0) : le
     vocabulaire de plis est declare avant les composants qui le consomment, et
     .axe comme .carte remettent `border-radius: 0` pour neutraliser le style
     natif du <button>. A specificite egale la derniere regle du fichier gagne,
     et l'arrondi disparaissait. Les quatre autres variantes n'ont pas ce
     probleme : elles passent par clip-path, qu'aucun composant ne redefinit. */
  border-radius: var(--rondeur, 18px 46px 22px 40px / 40px 20px 44px 22px);
}

/* ---- L'oreille de papier ----
   Voir l'explication géométrique en tête de section. Deux règles seulement
   changent d'une variante à l'autre : la position du carré de coin et
   l'orientation du triangle.

   --envers : couleur de la sous-face. Redéfinie par chaque contexte — crème
   sur du papier, teinte assombrie de l'aplat sur les axes colorés. */
.oreille { position: relative; }
.oreille::after {
  content: "";
  position: absolute;
  z-index: 3;
  width: var(--coin);
  height: var(--coin);
  background: var(--envers, var(--papier-envers));
  /* Le pli de lumière : la feuille est plus claire à la pointe libre (elle
     capte la lumière rasante) et plus dense près de l'arête de pliage. */
  background-image: linear-gradient(225deg,
    rgba(20, 33, 31, 0.14) 0%,
    rgba(20, 33, 31, 0.04) 42%,
    rgba(255, 255, 255, 0.22) 100%);
  /* L'ombre tombe sur les DEUX BORDS LIBRES du rabat, jamais sur l'arête :
     une ombre sur l'arête ferait lire un objet posé, pas une feuille pliée. */
  filter: drop-shadow(-2px 2px 3px var(--pli-ombre));
  pointer-events: none;
  transition: width 0.4s cubic-bezier(0.19, 1, 0.22, 1),
              height 0.4s cubic-bezier(0.19, 1, 0.22, 1);
}
.pli--corne.oreille::after {
  top: 0; right: 0;
  clip-path: polygon(0 0, 0 100%, 100% 100%);
}
.pli--corne-bg.oreille::after {
  bottom: 0; left: 0;
  clip-path: polygon(100% 0, 0 0, 100% 100%);
  filter: drop-shadow(2px -2px 3px var(--pli-ombre));
  background-image: linear-gradient(45deg,
    rgba(20, 33, 31, 0.14) 0%,
    rgba(20, 33, 31, 0.04) 42%,
    rgba(255, 255, 255, 0.22) 100%);
}
/* Les trois autres plis n'ont pas de rabat : une languette et une déchirure
   ne replient rien, elles enlèvent de la matière. Leur ::after reste inerte. */
.pli--onglet.oreille::after,
.pli--dechire.oreille::after,
.pli--croquis.oreille::after { content: none; }

/* ---- Le pli s'ouvre au survol ----
   Une seule variable pilote la découpe ET l'oreille : elles ne peuvent pas se
   désynchroniser. `transition` sur --coin exige @property, déclaré plus haut. */
.pli--interactif {
  transition: --coin 0.4s cubic-bezier(0.19, 1, 0.22, 1);
}
.pli--interactif:hover,
.pli--interactif:focus-visible,
a:hover > .pli--interactif,
a:focus-visible > .pli--interactif {
  --coin: var(--pli-ouvert);
}
@media (max-width: 899px) {
  /* Pas d'ouverture au survol en mobile : il n'y a pas de survol, et le
     :hover résiduel du tactile laissait le pli ouvert après le tap. */
  .pli--interactif:hover { --coin: var(--pli-mobile); }
}

/* ---- Bande de scotch ----
   Un morceau d'adhésif translucide en travers d'un coin. Sert à signaler les
   blocs « en chantier » : c'est le geste qu'on fait sur une feuille qu'on
   punaise en salle des profs, et il dit « provisoire » sans écrire le mot. */
.scotch { position: relative; }
.scotch::before {
  content: "";
  position: absolute;
  top: -9px;
  left: 26px;
  width: 88px;
  height: 24px;
  background: rgba(233, 160, 59, 0.28);
  border-left: 1px solid rgba(233, 160, 59, 0.45);
  border-right: 1px solid rgba(233, 160, 59, 0.45);
  transform: rotate(-6deg);
  pointer-events: none;
  z-index: 4;
}

/* ---- Compatibilité v1 ----
   `.corne` seule continue de produire exactement la découpe d'origine. */
.corne {
  position: relative;
  --coin: var(--pli);
  clip-path: polygon(0 0, calc(100% - var(--coin)) 0, 100% var(--coin), 100% 100%, 0 100%);
}
@media (max-width: 899px) { .corne { --coin: var(--pli-mobile); } }

@media (prefers-reduced-motion: reduce) {
  .pli--interactif, .oreille::after { transition: none; }
}

/* ===== En-tête ===== */
.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: transparent;
  padding: 24px clamp(24px, 5.6vw, 80px);
  transition: background-color 0.3s, border-color 0.3s, transform 0.3s;
  border-bottom: 1px solid transparent;
}
.entete.entete--pleine {
  background: var(--papier-creme);
  border-bottom-color: var(--bord);
}
.entete__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.entete__logo { width: 168px; height: auto; }
.entete__nav { display: flex; align-items: center; gap: 32px; }
.entete__lien {
  position: relative;
  font-size: 17px;
  color: var(--encre);
  padding-bottom: 2px;
}
.entete__lien::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1.4px;
  background: var(--encre);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease-out;
}
.entete__lien:hover { color: var(--petrole); }
.entete__lien:hover::after { transform: scaleX(1); }
.entete__lien--actif { color: var(--petrole); font-weight: 600; }
.entete__burger { display: none; }

@media (max-width: 899px) {
  .entete { padding: 16px 24px; }
  .entete__logo { width: 128px; }
  .entete__nav { display: none; }
  .entete__burger {
    display: block;
    background: none;
    border: none;
    padding: 4px;
  }
}

.entete__mobile-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 24px 24px;
  background: var(--papier-creme);
  border-bottom: 1px solid var(--bord);
}
.entete__mobile-nav[hidden] { display: none; }
.entete__mobile-nav a {
  padding: 12px 0;
  font-size: 17px;
  color: var(--encre);
  border-bottom: 1px solid var(--bord);
}
.entete__mobile-nav a:last-child { border-bottom: none; }
.entete__mobile-nav .btn { margin-top: 8px; }
@media (min-width: 900px) {
  .entete__mobile-nav { display: none !important; }
}

/* ===== Hero Accueil ===== */
.hero {
  position: relative;
  padding: 96px clamp(24px, 5.6vw, 80px) 160px;
}
.hero__grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 24px;
  align-items: center;
}
.hero__texte { grid-column: 1 / span 6; }
.hero__slogan { margin-top: 48px; display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.hero__ligne { position: relative; }
.hero__ligne:nth-child(2) { margin-left: 56px; }
.hero__ligne:nth-child(3) { margin-left: 112px; }
.hero__ligne-texte {
  margin: 0 0 4px 0;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144;
  font-weight: 600;
  font-size: var(--taille-h2);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--petrole);
}
.hero__trait { display: block; }
.hero__trait path { stroke: var(--orange); }
.hero__visuel { grid-column: 8 / span 5; position: relative; height: 460px; overflow: hidden; }
/* Le SVG epouse exactement le conteneur : main.js lui donne un viewBox en
   pixels, une unite du trace vaut donc un pixel a l'ecran. C'est ce qui
   permet a la trainee de se terminer sur la queue de l'avion quelle que
   soit la largeur, l'avion et le SVG n'ayant pas la meme echelle. */
.hero__trajectoire { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.hero__avion {
  position: absolute; right: 0; top: 40px;
  width: 420px; height: auto;
  transform: rotate(-14deg);
  filter: drop-shadow(0 12px 32px rgba(20, 33, 31, 0.10));
}

@media (max-width: 899px) {
  .hero { padding: 40px 24px 88px; }
  .hero__grid { display: block; }
  .hero__texte { grid-column: auto; }
  .hero__slogan { gap: 16px; }
  .hero__ligne:nth-child(2), .hero__ligne:nth-child(3) { margin-left: 0; }
  .hero__ligne-texte { font-size: var(--taille-h2-mobile); }
  .hero__visuel { grid-column: auto; position: relative; margin-top: 40px; height: 200px; }
  .hero__avion { width: 232px; }
}

/* ===== Manifeste ===== */
.manifeste {
  position: relative;
  background: var(--papier-clair);
  padding: 128px clamp(24px, 5.6vw, 80px) 96px;
}
.manifeste__grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; }
.manifeste__texte { grid-column: 1 / span 6; }
.manifeste__titre { margin: 0 0 32px 0; max-width: 20ch; }
.manifeste__corps { max-width: 64ch; text-wrap: pretty; }
/* La colonne droite portait la liste des enjeux ; celle-ci est devenue le
   bandeau défilant de la section suivante (voir index.html). La boîte à
   outils, qui flottait sous le texte en position absolue avec un débord de
   -56px à gauche, la remplace : elle a maintenant sa propre colonne, à
   l'échelle, et le manifeste retrouve une composition à deux colonnes
   franches au lieu d'un pavé de texte suivi d'une image en équilibre. */
.manifeste__visuel {
  grid-column: 8 / span 5;
  display: flex;
  align-items: center;
  justify-content: center;
}
.manifeste__boite { width: 100%; max-width: 380px; height: auto; }

@media (max-width: 899px) {
  .manifeste { padding: 64px 24px; }
  .manifeste__grid { display: block; }
  .manifeste__texte, .manifeste__visuel { grid-column: auto; margin-top: 0; }
  /* En colonne unique, la boîte à outils desktop ferait doublon avec la
     version mobile déjà présente dans le flux du texte. */
  .manifeste__visuel { display: none; }
  .manifeste__titre { margin-bottom: 24px; font-size: var(--taille-h2-mobile); }
  .manifeste__corps { margin-bottom: 32px; max-width: none; }
  .manifeste__boite--mobile { display: block; width: 232px; margin: 32px 0 0 -24px; }
}
.manifeste__boite--mobile { display: none; }

/* ===== Slogan en trois temps ===== */
.slogan { position: relative; padding: 160px clamp(24px, 5.6vw, 80px); }
.slogan__inner { max-width: 1280px; margin: 0 auto; }
.slogan__bloc {
  display: grid;
  grid-template-columns: 160px 1fr 240px;
  gap: 24px;
  align-items: center;
  padding: 48px 0;
}
.slogan__bloc:first-child { padding-top: 0; padding-bottom: 48px; }
.slogan__bloc:nth-child(3) { margin-left: 64px; }
.slogan__bloc:nth-child(5) { margin-left: 128px; padding-bottom: 0; }
.slogan__chiffre {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 144;
  font-weight: 600;
  font-size: 96px;
  line-height: 1;
  color: var(--filigrane);
  will-change: transform;
}
.slogan__titre { margin: 0 0 16px 0; }
.slogan__image { justify-self: end; }

@media (max-width: 899px) {
  .slogan { padding: 88px 24px; }
  .slogan__bloc {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    padding: 32px 0;
  }
  .slogan__bloc:first-child { padding-top: 0; }
  .slogan__bloc:nth-child(3), .slogan__bloc:nth-child(5) { margin-left: 0; }
  .slogan__bloc:nth-child(5) { padding-bottom: 0; }
  .slogan__chiffre { flex-basis: 100%; font-size: 56px; margin-bottom: 0; }
  .slogan__bloc > div { flex: 1; min-width: 0; }
  .slogan__titre { font-size: var(--taille-h2-mobile); margin-bottom: 8px; }
  .slogan__image { width: 88px; flex: none; }
}

/* ===== Le modèle ===== */
.modele {
  position: relative;
  background: var(--papier-profond);
  padding: 128px clamp(24px, 5.6vw, 80px);
}
.modele__inner { display: flex; flex-direction: column; align-items: center; }
.modele__surtitre { text-align: center; }
.modele__titre { margin-bottom: 64px; text-align: center; max-width: 24ch; }
.modele__legende { margin-top: 32px; text-align: center; color: var(--encre-3); }
.modele__cta { margin-top: 32px; }

@media (max-width: 899px) {
  .modele { padding: 64px 24px; }
  .modele__titre { margin-bottom: 32px; font-size: var(--taille-h2-mobile); }
  .modele__cta { width: 100%; }
}

/* ===== Sélecteur à quatre axes =====
   Quatre aplats de couleur, un origami par aplat, qui s'ouvrent SUR PLACE
   (pas de modale). Remplace la cocotte SVG interactive supprimée.

   Le panneau ouvert n'est PAS une vitrine décorative : c'est le branchement
   vers les livrets téléchargeables. Chaque livret y est une carte cliquable
   qui réutilise le composant .couverture de la bibliothèque (défini plus bas
   dans ce fichier, section « Couverture ») — même balisage, même typographie.
   Seuls le fond et la couleur de texte sont revoilés ici, parce que la carte
   est posée sur un aplat saturé et non sur du papier crème.

   Géométrie fermée (desktop) : grille 2 colonnes, gap 24px, max 1040px.
   Géométrie ouverte (desktop) : grille 3 colonnes ; l'axe ouvert occupe
   toute la rangée 1, les trois autres la rangée 2 (132px).
   Le panneau de contenu partage exactement la même cellule que l'axe ouvert
   (mêmes grid-column et grid-row) : il se superpose à l'aplat sans position
   absolue, donc la rangée prend la hauteur du contenu. Pas de hauteur fixe :
   min-height 420px, et le panneau grandit avec ses cartes. */

.axes {
  /* position: relative est indispensable : Flip.from({absolute: true})
     sort momentanément les panneaux du flux et les positionne par rapport
     au premier ancêtre positionné. */
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--espace-m);
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
}

/* --axe-echelle : facteur de normalisation OPTIQUE des origami.
   Les quatre illustrations n'ont ni le même format ni la même densité
   d'encre : à hauteur de boîte égale, le bateau (700x515, 25 % de pixels
   opaques) paraissait riquiqui et le moulin (272x258, 35 % opaques) énorme.
   Le facteur égalise la SURFACE D'ENCRE APPARENTE, mesurée en intégrant le
   canal alpha de chaque .webp puis en la ramenant à la moyenne géométrique
   des quatre. Il multiplie la BOÎTE (.axe__pli), pas l'image : object-fit
   contain garde donc l'illustration entièrement dans sa boîte, sans
   débordement à gérer. Écart de surface apparente : 152 % avant, 1,1 % après. */
.axe--bien-commun  { --axe-couleur: var(--axe-bien-commun);  --axe-texte: var(--papier-clair); --axe-echelle: 1.05; }
.axe--valorisation { --axe-couleur: var(--axe-valorisation); --axe-texte: var(--encre);        --axe-echelle: 0.96; }
.axe--justice      { --axe-couleur: var(--axe-justice);      --axe-texte: var(--papier-clair); --axe-echelle: 0.79; }
.axe--cadre        { --axe-couleur: var(--axe-cadre);        --axe-texte: var(--papier-clair); --axe-echelle: 1.26; }
/* La cocotte est de loin la plus dense des cinq (42 % de pixels opaques) :
   son facteur la ramene au meme poids visuel que les quatre origami. */
.axe--modele       { --axe-couleur: var(--axe-modele);       --axe-texte: var(--encre);        --axe-echelle: 0.70; }

/* Le panneau de contenu est un FRÈRE des boutons, pas un descendant :
   il ne peut pas hériter des variables ci-dessus, on les lui redonne. */
.axe__contenu--bien-commun  { --axe-couleur: var(--axe-bien-commun);  --axe-texte: var(--papier-clair); }
.axe__contenu--valorisation { --axe-couleur: var(--axe-valorisation); --axe-texte: var(--encre); }
.axe__contenu--justice      { --axe-couleur: var(--axe-justice);      --axe-texte: var(--papier-clair); }
.axe__contenu--cadre        { --axe-couleur: var(--axe-cadre);        --axe-texte: var(--papier-clair); }
.axe__contenu--modele       { --axe-couleur: var(--axe-modele);       --axe-texte: var(--encre); }

.axe {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--espace-s);
  aspect-ratio: 5 / 4;
  /* Pas de padding vertical : « origami à 55 % du panneau » se mesure sur la
     hauteur pleine, or un pourcentage se résout sur la boîte de contenu. */
  padding: 0 var(--espace-m);
  border: 0;
  border-radius: 0;
  background: var(--axe-couleur);
  color: var(--axe-texte);
  /* La DÉCOUPE n'est plus définie ici : chaque axe porte sa propre variante du
     vocabulaire de plis (.pli--corne, --corne-bg, --onglet, --croquis), posée
     dans le HTML. La légende de la section — « Quatre axes, quatre plis » —
     décrit enfin ce qu'on voit : en v1 les quatre boutons partageaient la même
     découpe, ce qui rendait la phrase fausse et la grille monotone.
     --coin reste piloté ici parce que l'état RÉDUIT le rabaisse à 16px : 30px
     de pli sur 132px de haut mangeaient un quart du panneau.
     clip-path rogne aussi le contour de focus, d'où l'outline en offset
     négatif plus bas. */
  /* Les axes sont les plus GRANDS blocs du site (480 × 384 en 1440). Un pli
     de 30px, qui suffit sur une carte de livret, s'y lit comme une écornure
     accidentelle. On le passe à 44px, la marche de la languette à 26px et
     l'arrondi du croquis à des rayons deux fois plus larges : sur un objet
     deux fois plus grand, une forme ne se lit qu'à la même proportion. */
  --coin: 44px;
  --pli-ouvert: 64px;
  --marche: 26px;
  --rondeur: 34px 84px 40px 72px / 72px 36px 80px 40px;
  /* Sous-face du rabat sur un aplat saturé : le crème du papier y ferait une
     tache claire sans rapport avec l'axe. On assombrit la couleur de l'axe
     elle-même — c'est la même feuille, vue de dos. 76 % et non 68 : à 68 le
     triangle virait au presque-noir sur le pétrole et le rouge, et lisait
     comme un trou dans la page plutôt que comme du papier retourné. */
  --envers: color-mix(in srgb, var(--axe-couleur) 76%, #14211F);
  text-align: center;
  cursor: pointer;
  /* Jamais de transition sur transform : GSAP (survol) et Flip (ouverture)
     en sont les seuls propriétaires. */
}

/* Le contour de focus doit rester À L'INTÉRIEUR : le clip-path du biseau
   rogne tout ce qui déborde, un outline-offset positif serait invisible.
   currentColor suit --axe-texte, donc contraste sur chacun des quatre aplats. */
.axe:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: -10px;
}

.axe__numero {
  position: absolute;
  top: var(--espace-m);
  left: var(--espace-m);
  font-family: var(--font-texte);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.5;
  transition: opacity 0.3s ease;
}

/* .axe__pli est la BOÎTE de l'origami : c'est elle que Flip anime, et c'est
   elle que --axe-echelle redimensionne. Aucun calque de décalage
   risographie : les .webp portent déjà leur propre ombre portée dessinée,
   les deux se superposaient et salissaient l'illustration. */
.axe__pli {
  position: relative;
  display: block;
  flex: none;
  width: 100%;
  height: calc(55% * var(--axe-echelle));
  pointer-events: none;
}

.axe__origami {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.axe__nom {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 34px;
  line-height: 1.15;
  transition: font-size 0.35s ease, opacity 0.3s ease;
}

/* ---- État ouvert ---- */
.axes--ouvert { grid-template-columns: repeat(3, 1fr); }

/* L'axe ouvert et le panneau occupent la MÊME cellule : ils se superposent,
   et la rangée prend la hauteur du plus grand des deux. */
.axes--ouvert .axe--ouvert,
.axes--ouvert .axe__contenu {
  grid-column: 1 / -1;
  grid-row: 1;
}
.axes--ouvert .axe--ouvert {
  order: 0;
  aspect-ratio: auto;
  height: auto;
  min-height: 420px;
  cursor: default;
}
/* Le rabat disparaît sur l'axe OUVERT : son triangle occupe le coin
   supérieur droit, où se trouve déjà la croix de fermeture (16 → 60px). Les
   deux se chevauchaient sur 3px et la croix perdait son contraste. Un panneau
   ouvert n'a de toute façon plus à se lire comme une feuille pliée : il est
   déplié, c'est tout le propos du geste. */
.axes--ouvert .axe--ouvert.oreille::after { content: none; }
/* Le nom repasse dans le panneau (en 40px) : on efface celui du bouton et
   son numéro pour ne pas les afficher deux fois. */
.axes--ouvert .axe--ouvert .axe__nom,
.axes--ouvert .axe--ouvert .axe__numero { opacity: 0; }

/* Le voyage de l'origami : du centre vers le haut à droite. Il vit dans le
   bouton (z-index 1), le panneau est au-dessus (z-index 2) : il est donc
   toujours DERRIÈRE les cartes et derrière la croix, jamais par-dessus.
   right: 8px place en plus l'illustration à droite de la dernière carte, pour
   qu'il n'y ait pas non plus de recouvrement géométrique en 1440 : avec trois
   cartes de 150px et 20px de gouttière, la zone libre à droite ne fait que
   155px, et la boîte du cadre éducatif (la plus haute, ×1,26) en occupe 151. */
.axes--ouvert .axe--ouvert .axe__pli {
  position: absolute;
  /* 64px : juste sous la croix de fermeture, qui occupe 16 → 60px. En le
     posant plus haut, l'origami passait derrière elle et le geste de
     fermeture se lisait mal. */
  top: 64px;
  right: 8px;
  width: calc(120px * var(--axe-echelle));
  height: calc(120px * var(--axe-echelle));
  opacity: 0.9;
}

/* Les panneaux réduits gardent leur couleur PLEINE : à 55 % d'opacité ils
   avaient l'air désactivés alors qu'ils sont cliquables. Ils ne se
   distinguent plus que par la taille. La bande « Le Modèle » est exclue :
   même réduite elle reste une bande, elle ne devient pas une vignette. */
.axes--ouvert .axe--reduit:not(.axe--modele) {
  order: 1;
  aspect-ratio: auto;
  height: 132px;
  gap: var(--espace-xs);
  /* Le pli suit la taille du panneau, comme partout ailleurs. Il ne suffit pas
     de réduire --coin : la languette et l'arrondi ont leurs propres variables,
     et à 26px de marche sur 132px de haut la languette mangeait un cinquième
     du panneau, tandis que l'arrondi de 84px transformait le quatrième axe en
     gélule. Les trois descendent ensemble. */
  --coin: 16px;
  --marche: 13px;
  --rondeur: 16px 38px 18px 32px / 32px 17px 36px 18px;
}
.axes--ouvert .axe--reduit .axe__pli { height: calc(60px * var(--axe-echelle)); }
.axes--ouvert .axe--reduit .axe__nom { font-size: 19px; }
.axes--ouvert .axe--reduit .axe__numero { top: 12px; left: 14px; }

/* ---- Les deux dispositions ouvertes ----
   a) un AXE est ouvert : 3 colonnes, l'axe en rangée 1, les trois autres en
      rangée 2, la bande « Le Modèle » inchangée en rangée 3 ;
   b) la BANDE est ouverte : 4 colonnes, les quatre axes réduits en rangée 1,
      et la bande — déjà pleine largeur — se déplie verticalement en rangée 2. */
.axes--ouvert:not(.axes--modele-ouvert) .axe--reduit:not(.axe--modele) { grid-row: 2; }
.axes--ouvert:not(.axes--modele-ouvert) .axe--modele { grid-row: 3; }

.axes--modele-ouvert { grid-template-columns: repeat(4, 1fr); }
.axes--modele-ouvert .axe--reduit { grid-row: 1; }
.axes--modele-ouvert .axe--ouvert,
.axes--modele-ouvert .axe__contenu { grid-row: 2; }

/* ---- La bande « Le Modèle » ----
   Cinquième élément de la grille, et non plus un bouton isolé après elle :
   elle passe ainsi par exactement la même mécanique d'ouverture (mêmes
   classes, même Flip, même panneau) que les quatre axes. */
.axes .axe--modele {
  grid-column: 1 / -1;
  /* Coins carrés en toutes circonstances : c'est son identité, elle n'a
     jamais eu le biseau des couvertures. Son pli à elle est ailleurs — sur le
     bord inférieur, déchiré (classe .pli--dechire posée dans le HTML). C'est
     la seule forme du vocabulaire qui demande de la largeur : sur une bande
     pleine largeur la déchirure lit comme un arrachage, sur une carte de
     300px elle retomberait en zigzag décoratif. */
  --coin: 0px;
  /* 9px et non 16 : la bande fermée ne fait que 120px de haut et l'origami y
     est centré avec 15px de marge basse. À 16px, la déchirure lui mordait le
     bord inférieur. */
  --dent: 9px;
}
/* Dépliée, la bande devient un panneau de 400px+ : la déchirure peut y
   reprendre son amplitude pleine sans rien toucher. */
.axes .axe--modele.axe--ouvert { --dent: 16px; }
/* Au repos, et aussi quand un AUTRE axe est ouvert : forme de bande. */
.axe--modele:not(.axe--ouvert) {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  aspect-ratio: auto;
  height: 120px;
  padding: 0 var(--espace-l);
  text-align: left;
}
.axe--modele:not(.axe--ouvert) .axe__nom { font-size: 28px; }
.axe--modele:not(.axe--ouvert) .axe__pli {
  width: calc(128px * var(--axe-echelle));
  height: calc(128px * var(--axe-echelle));
}

/* ---- Panneau de contenu ----
   pointer-events: none sur le conteneur : les clics traversent jusqu'à
   l'aplat, seuls les enfants (colonnes, croix) les captent. */
.axe__contenu {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 38% 62%;
  color: var(--axe-texte);
  pointer-events: none;
}
.axe__contenu[hidden] { display: none; }
.axe__contenu > * { pointer-events: auto; }
.axe__contenu:focus-visible { outline: 3px solid currentColor; outline-offset: -10px; }

.axe__colonne--texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 40px;
}
.axe__colonne--cartes {
  padding: 40px 40px 40px 0;
  /* Sans min-width: 0, un enfant en overflow-x ne peut pas rétrécir sous sa
     taille de contenu dans une grille : le défilement mobile ne partirait
     pas et la page déborderait à l'horizontale. */
  min-width: 0;
}

.axe__contenu-nom {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 40px;
  line-height: 1.1;
}
.axe__intro {
  margin: 16px 0 0 0;
  font-size: var(--taille-corps-l);
  line-height: 1.6;
  max-width: 42ch;
  opacity: 0.85;
}
/* « collé en bas de la colonne » : margin-top auto dans une colonne flex qui
   s'étire sur toute la hauteur de la cellule (align-items: stretch par
   défaut sur .axe__contenu). Souligné en currentColor et non en
   var(--encre) : sur le vert, le pétrole et le rouge, de l'encre sur
   l'aplat tomberait à 1,3:1 — illisible. */
.axe__lien-outils {
  margin-top: auto;
  padding-top: var(--espace-m);
  color: inherit;
  font-size: 17px;
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.axe__lien-outils:hover { color: inherit; text-decoration-thickness: 2px; }

/* ---- Les cartes de livret ---- */
.axe__cartes {
  display: flex;
  gap: 20px;
  align-items: flex-start;
}
.axe__carte {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 150px;
  flex: none;
  color: inherit;
  text-decoration: none;
}
/* La carte est un <a> : sans ces deux règles, le `a:hover { color: petrole }`
   du reste de la feuille reprend la main au survol et le titre vire au
   pétrole sur l'aplat de l'axe — illisible sur le vert et le rouge. Même
   raison pour le contour de focus, qui doit suivre la couleur du panneau. */
.axe__carte:hover,
.axe__carte:focus-visible { color: inherit; }
.axe__carte:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }

.axe__carte-couv {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  /* min-height: 0 est indispensable : en tant qu'élément de flex, la boîte
     hérite de min-height: auto, qui l'empêche de descendre sous la hauteur de
     son contenu — la couverture s'étirait alors au lieu de tenir son 3/4, et
     les cartes d'une même rangée n'avaient plus la même hauteur. */
  min-height: 0;
  flex: none;
}

/* Le composant .couverture est importé tel quel (voir section « Couverture »).
   Deux revoilages seulement, imposés par le contexte : la carte est posée sur
   l'aplat de l'axe, il faut donc l'éclaircir pour qu'elle s'en détache, et
   inverser sa couleur de texte qui est claire par défaut.
   Le fond = var(--papier-clair) à 92 % (#FFFDF9) posé sur la couleur de l'axe :
   il en reste une teinte, la carte reste de la famille de l'axe. */
.axe__carte .couverture {
  background-color: var(--axe-couleur);
  background-image: linear-gradient(rgba(255, 253, 249, 0.92), rgba(255, 253, 249, 0.92));
  color: var(--encre);
}

/* Le composant est calibré pour les couvertures de la bibliothèque, larges de
   190 à 220px. Ici elles font 150px (132 en mobile) : à typographie
   inchangée, le bas de la couverture — sous-titre et logo — sortait du cadre
   et se faisait rogner par son overflow: hidden. On redescend donc les trois
   tailles de texte et on rééquilibre les trois zones, sans toucher au
   composant lui-même. Les titres longs se terminent en ellipse plutôt qu'en
   coupe nette ; le titre complet est de toute façon répété sous la carte. */
/* min-height: 0 pour la même raison que sur .axe__carte-couv : sans lui, les
   trois zones ne peuvent pas descendre sous la hauteur de leur contenu (la
   vignette fait 120px d'intrinsèque), leur flex-basis en pourcentage est
   ignoré, et le bas de la couverture est repoussé hors du cadre. */
.axe__carte .couverture__titre-zone,
.axe__carte .couverture__fenetre,
.axe__carte .couverture__bas { min-height: 0; }
.axe__carte .couverture__titre-zone { flex: 0 0 34%; padding: 8px 10px; }
.axe__carte .couverture__titre {
  font-size: 12px;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}
.axe__carte .couverture__fenetre { flex: 0 0 40%; margin: 0 12px; }
.axe__carte .couverture__image { padding: 4px; }
.axe__carte .couverture__bas { padding: 4px 10px 8px; gap: 3px; }
.axe__carte .couverture__soustitre {
  font-size: 9px;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.axe__carte .couverture__logo { font-size: 10px; }

.axe__carte-titre {
  margin: 0;
  font-size: 15px;
  line-height: 1.3;
  font-weight: 500;
  /* 2 lignes maximum, ellipse au-delà. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.axe__carte-action {
  font-size: 13px;
  line-height: 1.2;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* « en construction » : la carte existe, elle montre à quoi ressemblera le
   livret, mais elle ne mène nulle part. Rendue en <span> et non en <a> :
   pas de href, donc ni focusable ni activable, aucun lien mort dans l'onglet. */
.axe__carte--construction {
  opacity: 0.55;
  cursor: default;
}

.axes__fermer {
  position: absolute;
  top: 16px;
  right: 16px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.axes__fermer:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }

@media (max-width: 899px) {
  .axes { grid-template-columns: 1fr; gap: var(--espace-s); }
  /* En une seule colonne, l'axe fait 327px de large : il redescend à l'échelle
     d'une carte, donc à la profondeur de pli d'une carte. Sans cette reprise,
     les 44px du desktop mangeaient un huitième de la largeur du panneau. */
  .axe {
    --coin: var(--pli-mobile);
    --pli-ouvert: var(--pli-mobile);
    --marche: 14px;
    --rondeur: 16px 40px 20px 34px / 34px 18px 38px 20px;
  }
  .axe { --coin: var(--biseau-mobile); }
  .axe__pli { height: calc(50% * var(--axe-echelle)); }
  .axe__nom { font-size: 27px; }

  .axes--ouvert { grid-template-columns: 1fr; }
  .axes--ouvert .axe--ouvert { min-height: 420px; }
  /* Les trois autres restent empilés SOUS l'axe ouvert : rangée auto. */
  .axes--ouvert .axe--reduit:not(.axe--modele) { height: 96px; }
  .axes--ouvert .axe--reduit .axe__pli { height: calc(44px * var(--axe-echelle)); }
  .axes--ouvert .axe--reduit .axe__nom { font-size: 17px; }
  .axes--ouvert .axe--ouvert .axe__pli {
    /* Même règle qu'en desktop : la croix occupe 12 → 56px, l'origami
       commence dessous. */
    top: 60px; right: 12px;
    width: calc(96px * var(--axe-echelle));
    height: calc(96px * var(--axe-echelle));
  }

  /* Les colonnes s'empilent. padding-top 64px : le texte commence sous la
     croix ; padding-right 132px : il ne passe pas sous l'origami. */
  .axe__contenu { grid-template-columns: 1fr; }
  .axe__colonne--texte { padding: 64px 132px 0 20px; min-height: 168px; }
  .axe__contenu-nom { font-size: 27px; }
  .axe__intro { font-size: var(--taille-corps-mobile); }
  .axe__lien-outils { padding-top: var(--espace-s); }

  /* Les cartes passent en défilement horizontal avec accroche. Le
     padding-inline fait respirer la première et la dernière ; il est posé sur
     le conteneur défilant lui-même pour qu'il défile avec les cartes. */
  .axe__colonne--cartes { padding: 24px 0; }
  .axe__cartes {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    padding-inline: 20px;
    /* Sans scroll-padding, l'accroche « mandatory » colle immédiatement la
       première carte au bord du conteneur et annule le padding-inline : le
       point d'accroche se cale sur la boîte de padding. On rentre donc le
       snapport de la même valeur pour que la respiration soit conservée. */
    scroll-padding-inline: 20px;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .axe__cartes::-webkit-scrollbar { display: none; }
  .axe__carte { width: 132px; scroll-snap-align: start; }
  /* À 132px de large la couverture ne fait plus que 176px de haut : le bas ne
     tient plus deux lignes de sous-titre sans manger le logo. */
  .axe__carte .couverture__soustitre { -webkit-line-clamp: 1; line-clamp: 1; }

  .axes__fermer { top: 12px; right: 12px; }

  /* La bande reste pleine largeur, elle ne fait que rétrécir. */
  .axe--modele:not(.axe--ouvert) { height: 88px; padding: 0 var(--espace-m); }
  .axe--modele:not(.axe--ouvert) .axe__nom { font-size: 22px; }
  .axe--modele:not(.axe--ouvert) .axe__pli {
    width: calc(90px * var(--axe-echelle));
    height: calc(90px * var(--axe-echelle));
  }

  /* Une seule colonne : les rangées explicites suffisent à garder la bande
     en dernier, et le panneau collé à l'élément qu'il complète. */
  .axes--modele-ouvert { grid-template-columns: 1fr; }
  .axes--ouvert:not(.axes--modele-ouvert) .axe--reduit:not(.axe--modele) { grid-row: auto; }
  .axes--ouvert:not(.axes--modele-ouvert) .axe--modele { grid-row: 5; }
  .axes--modele-ouvert .axe--reduit { grid-row: auto; }
  .axes--modele-ouvert .axe--ouvert,
  .axes--modele-ouvert .axe__contenu { grid-row: 5; }
}

/* ===== Arrivée sur un groupe de la bibliothèque via une ancre =====
   Un lien « Voir les N outils de cet axe » amène sur outils.html#axe-… :
   à l'arrivée, le groupe visé se signale par un liseré de 2px dans sa
   couleur, une seule fois, qui s'efface en 1,2s. La couleur est posée par
   main.js dans --liseret. Le liseré est un ::after (donc hors du flux et
   sans effet sur la mise en page) et la classe est retirée à la fin. */
.groupe--cible { position: relative; }
.groupe--cible::after {
  content: '';
  position: absolute;
  inset: -16px;
  border: 2px solid var(--liseret, var(--petrole));
  pointer-events: none;
  animation: liseret-groupe 1.2s ease-out forwards;
}
@keyframes liseret-groupe {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  100% { opacity: 0; }
}

/* prefers-reduced-motion : aucun déplacement, aucun fondu, aucun Flip.
   main.js bascule les classes sans timeline et ne pose jamais .groupe--cible ;
   ici on coupe les transitions CSS restantes pour que le changement d'état
   soit strictement instantané. */
@media (prefers-reduced-motion: reduce) {
  .axe,
  .axe__nom,
  .axe__numero { transition: none; }
  .groupe--cible::after { animation: none; opacity: 0; }
}

/* ===== Accrochage / trois portes d'entrée ===== */
.portes {
  position: relative;
  padding: 160px clamp(24px, 5.6vw, 80px);
}
.portes__titre { margin-bottom: 64px; }
.portes__grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 24px;
  align-items: start;
}
.porte {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 48px;
  box-shadow: var(--ombre-repos), var(--ombre-survol);
  transition: transform 0.35s cubic-bezier(0.19, 1, 0.22, 1), box-shadow 0.35s ease;
}
/* Même geste que les cartes de livret : on soulève une feuille (voir le
   commentaire de .carte pour le rôle du demi-degré de bascule). */
.porte:hover {
  transform: translateY(-6px) rotate(-0.3deg);
  box-shadow: 0 20px 44px rgba(20, 33, 31, 0.12);
}
@media (prefers-reduced-motion: reduce) { .porte:hover { transform: none; } }
.porte--principale {
  grid-column: 1 / span 6;
  grid-row: 1 / span 2;
  min-height: 528px;
  background: var(--petrole);
  color: var(--papier-clair);
}
.porte--principale:hover { background: var(--petrole-fonce); }
/* Sous-face du rabat : la teinte de la porte assombrie, jamais le crème du
   papier — sur un aplat saturé, un triangle crème lit comme un trou.
   Les profondeurs de pli suivent la taille du bloc, comme sur les axes : la
   grande porte (660 × 528) porte 48px, les deux petites (550 × ~200) 34px. */
.porte--principale {
  --envers: color-mix(in srgb, var(--petrole) 72%, #14211F);
  --coin: 48px;
  --pli-ouvert: 72px;
}
.porte--ambassadeurs {
  --envers: color-mix(in srgb, var(--magenta) 72%, #14211F);
  --coin: 34px;
  --pli-ouvert: 52px;
}
.porte--accrochage { --rondeur: 22px 58px 26px 48px / 48px 24px 54px 26px; }
@media (max-width: 899px) {
  .porte--principale, .porte--ambassadeurs {
    --coin: var(--pli-mobile);
    --pli-ouvert: var(--pli-mobile);
  }
  .porte--accrochage { --rondeur: 16px 38px 18px 32px / 32px 17px 36px 18px; }
}
.porte__numero { margin-bottom: 24px; font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--papier-clair); opacity: 0.7; }
.porte--principale .h3, .porte--principale .h1 { color: var(--papier-clair); }
.porte__desc { color: var(--papier-clair); opacity: 0.85; max-width: 30ch; }
.porte__image { align-self: flex-end; }
.porte--accrochage {
  grid-column: 8 / span 5;
  position: relative;
  display: flex;
  gap: 24px;
  padding: 40px 40px 40px 48px;
  background: var(--papier-creme);
  border: 1.5px solid var(--encre);
  box-shadow: none;
  /* Cette porte porte le pli .pli--croquis (coins arrondis irréguliers). Sans
     overflow: hidden, la barre orange ::before — posée à left:0, top:0,
     bottom:0 — dépasserait des coins arrondis et rendrait l'arrondi faux. */
  overflow: hidden;
}
.porte--accrochage::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 8px;
  background: var(--orange);
}
.porte--accrochage .porte__numero { color: var(--encre-3); opacity: 1; }
.porte--ambassadeurs {
  grid-column: 8 / span 5;
  margin-top: 48px;
  display: flex;
  gap: 24px;
  padding: 40px;
  background: var(--magenta);
  color: var(--papier-clair);
}

@media (max-width: 899px) {
  .portes { padding: 88px 24px; }
  .portes__titre { margin-bottom: 32px; font-size: var(--taille-h2-mobile); }
  .portes__grid { display: flex; flex-direction: column; gap: 16px; }
  .porte, .porte--principale, .porte--accrochage, .porte--ambassadeurs {
    grid-column: auto; grid-row: auto; margin-top: 0; min-height: 0; padding: 32px;
  }
  .porte--accrochage { padding: 24px 24px 24px 32px; }
}

/* ===== Territoires ===== */
.territoires {
  position: relative;
  background: var(--papier-clair);
  padding: 96px clamp(24px, 5.6vw, 80px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.territoires__titre { margin: 16px 0; max-width: 30ch; }
.territoires__image { width: 136px; }

@media (max-width: 899px) {
  .territoires { display: block; padding: 64px 24px; }
  .territoires__titre { font-size: var(--taille-h3-mobile); }
  .territoires__image { width: 96px; margin: 24px 0 0 auto; }
}

/* ===== Contact / CTA ===== */
.cta {
  position: relative;
  background: var(--petrole);
  padding: 128px clamp(24px, 5.6vw, 80px);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 48px;
}
.cta__titre { color: var(--papier-clair); max-width: 24ch; margin-bottom: 16px; }
.cta__corps { color: var(--papier-clair); opacity: 0.8; max-width: 62ch; }

@media (max-width: 899px) {
  .cta { display: block; padding: 64px 24px; }
  .cta__titre { font-size: var(--taille-h2-mobile); }
  .cta .btn { width: 100%; margin-top: 32px; }
}

/* ===== Pied de page ===== */
.pied {
  position: relative;
  background: var(--papier-profond);
  padding: 0 clamp(24px, 5.6vw, 80px) 64px;
}
.pied__trait { margin-bottom: 64px; }
.pied__grid {
  display: grid;
  grid-template-columns: 4fr 4fr 4fr;
  gap: 24px;
  align-items: start;
}
/* height: auto est indispensable : sans lui l'image prend la hauteur de
   son attribut HTML et le logo se retrouve ecrase. */
.pied__logo { width: 200px; height: auto; margin-bottom: 16px; }
.pied__baseline { max-width: 34ch; }
.pied__contact p { margin: 0 0 8px 0; }
.pied__nav { display: flex; flex-direction: column; gap: 8px; font-size: 15px; justify-self: end; text-align: right; }

@media (max-width: 899px) {
  .pied { padding: 0 24px 40px; }
  .pied__trait { margin-bottom: 40px; }
  .pied__grid { display: block; }
  .pied__logo { width: 168px; }
  .pied__contact { margin: 24px 0; }
  .pied__nav { flex-direction: row; flex-wrap: wrap; gap: 8px 24px; justify-self: start; text-align: left; }
}

/* ===== Page Outils : hero ===== */
.hero-outils {
  position: relative;
  padding: 80px clamp(24px, 5.6vw, 80px) 96px;
}
.hero-outils__grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; align-items: end; }
.hero-outils__texte { grid-column: 1 / span 7; }
.hero-outils__titre { margin-bottom: 32px; max-width: 22ch; }
.hero-outils__image-wrap { grid-column: 9 / span 4; display: flex; justify-content: flex-end; }
.hero-outils__image { width: 300px; }

@media (max-width: 899px) {
  .hero-outils { padding: 40px 24px 64px; }
  .hero-outils__grid { display: block; }
  .hero-outils__texte, .hero-outils__image-wrap { grid-column: auto; }
  .hero-outils__titre { font-size: var(--taille-h1-mobile); margin-bottom: 24px; }
  .hero-outils__image-wrap { justify-content: flex-end; margin-top: 24px; }
  .hero-outils__image { width: 208px; }
}

/* ===== Bibliothèque : filtres ===== */
.filtres-section { position: relative; padding: 96px clamp(24px, 5.6vw, 80px) 0; }
.filtres {
  background: var(--papier-clair);
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  padding: 24px 32px;
  display: flex;
  align-items: center;
  gap: 48px;
  flex-wrap: wrap;
}
.filtres__groupe { display: flex; align-items: center; gap: 16px; }
.filtres__label { margin: 0; font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--encre-3); }
.filtres__puces { display: flex; gap: 8px; flex-wrap: wrap; }
.filtres__separateur { width: 1px; height: 40px; background: var(--bord); }
.filtres__reset {
  margin-left: auto;
  background: none;
  border: none;
  font-size: 15px;
  color: var(--petrole);
  text-decoration: underline;
}
.filtres__reset:hover { color: var(--petrole-fonce); }

@media (max-width: 899px) {
  .filtres-section { padding: 40px 24px 0; }
  .filtres { display: block; padding: 24px; }
  .filtres__groupe { display: block; margin-bottom: 24px; }
  .filtres__groupe:last-child { margin-bottom: 0; }
  .filtres__label { display: block; margin-bottom: 12px; }
  .filtres__separateur { display: none; }
  .filtres__puces .puce { height: 44px; }
  .filtres__reset { margin: 16px 0 0; display: block; }
}

/* ===== Bibliothèque : groupes et cartes ===== */
.bibliotheque { position: relative; padding: 96px clamp(24px, 5.6vw, 80px) 160px; }
.groupe { margin-bottom: 96px; }
.groupe:last-child { margin-bottom: 0; }
.groupe__barre { display: block; height: 4px; width: 100%; margin-bottom: 24px; }
.groupe__barre--modele { background: var(--axe-modele); }
.groupe__barre--cadre { background: var(--axe-cadre); }
.groupe__barre--justice { background: var(--axe-justice); }
.groupe__barre--valorisation { background: var(--axe-valorisation); }
.groupe__barre--bien-commun { background: var(--axe-bien-commun); }
.groupe__entete { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; margin-bottom: 40px; }
.groupe__compte { font-size: 15px; color: var(--encre-3); white-space: nowrap; }
.groupe__grille { display: grid; gap: 24px; align-items: start; }

@media (max-width: 899px) {
  .bibliotheque { padding: 64px 24px 88px; }
  .groupe { margin-bottom: 64px; }
  .groupe__entete { display: block; margin-bottom: 24px; }
  .groupe__compte { display: block; margin-top: 8px; }
  .groupe__grille { display: flex; flex-direction: column; gap: 16px; }
}

/* La carte se SOULÈVE comme une feuille, elle ne glisse pas comme un bouton.
   Trois quantités, dosées ensemble : 6px de montée, 0.35° de bascule, et une
   ombre qui s'écarte. Le demi-degré est le paramètre qui fait tout le travail
   — sans lui, une carte qui monte lit comme un rectangle qui translate ; avec
   lui, elle lit comme une feuille qu'on décolle d'une pile. Au-delà de 0.5°
   l'inclinaison devient visible EN TANT QUE rotation et le geste se casse.
   L'angle alterne de signe une carte sur deux (voir .groupe__grille plus bas)
   pour que deux voisines ne se penchent jamais du même côté. */
/* AU REPOS, les cartes sont légèrement de travers ; AU SURVOL, elles se
   redressent en se soulevant. C'est l'inverse de la convention web (repos
   droit, survol animé) et c'est fait exprès : une pile de feuilles posées sur
   une table n'est jamais alignée au degré près, et prendre une feuille en main
   est précisément le geste qui la redresse. La grille de la bibliothèque
   perdait toute sa raideur pour 0,5° et zéro coût.

   Les valeurs : entre 0,35° et 0,6°, jamais plus. Au-delà de 0,8° sur une
   carte de 350px l'inclinaison devient lisible EN TANT QUE rotation, et
   l'ensemble a l'air cassé plutôt que posé. Les angles sont distribués par
   nth-child avec un cycle de 5 — un cycle plus court (2 ou 3) redevient un
   motif que l'œil repère à la troisième carte, et l'aléatoire revient.
   Le déplacement de 6px et le retour à 0° partagent la même transition : la
   feuille se redresse en montant, elle ne fait pas deux gestes. */
.carte {
  background: var(--papier-clair);
  border: 1px solid var(--bord);
  --repos: -0.45deg;
  transform: rotate(var(--repos));
  transition: transform 0.35s cubic-bezier(0.19, 1, 0.22, 1),
              box-shadow 0.35s ease,
              opacity 0.25s;
}
.carte:nth-child(5n+2) { --repos: 0.5deg; }
.carte:nth-child(5n+3) { --repos: -0.3deg; }
.carte:nth-child(5n+4) { --repos: 0.6deg; }
.carte:nth-child(5n+5) { --repos: -0.55deg; }
.carte:hover {
  transform: translateY(-6px) rotate(0deg);
  box-shadow: 0 18px 40px rgba(20, 33, 31, 0.10);
}

@media (prefers-reduced-motion: reduce) {
  .carte, .carte:hover { transform: none; }
}
.carte--vedette { box-shadow: var(--ombre-repos), var(--ombre-survol); }
.carte__couverture { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
/* La languette rabaisse le bord supérieur de 18px sur les deux tiers droits
   de la carte. Le badge, posé à 16px du haut, y perdait ses 2 premiers pixels
   sur sa partie droite. On le repousse sous la marche. */
.pli--onglet .carte__couverture { padding-top: 26px; }
.carte__contenu { padding: 32px; }
.carte__titre { margin: 0 0 8px 0; }
.carte__soustitre { margin: 0 0 24px 0; max-width: 62ch; }

.carte--large { display: grid; grid-template-columns: 5fr 7fr; }
.carte--large .carte__couverture { padding: 24px; align-items: center; gap: 12px; }
.carte--large .carte__contenu { display: flex; flex-direction: column; justify-content: center; padding: 40px; }
.carte--large .btn { align-self: flex-start; }

.carte--mini { display: flex; gap: 16px; align-items: center; background: var(--papier-creme); border: 1.5px dashed var(--encre); padding: 20px; border-radius: var(--rayon); box-shadow: none; }
.carte--mini:hover { transform: none; box-shadow: none; }
.carte--mini__couverture { position: relative; width: 96px; flex: none; aspect-ratio: 3 / 4; }
.carte--mini__titre { margin: 12px 0 0 0; font-family: var(--font-display); font-variation-settings: 'opsz' 48; font-weight: 600; font-size: 17px; line-height: 1.3; color: var(--encre-2); }

.chantier-carte {
  background: var(--papier-creme);
  border: 1.5px dashed var(--encre);
  border-radius: var(--rayon);
  padding: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

@media (max-width: 899px) {
  .carte--large { display: block; }
  .carte--large .carte__couverture { padding: 24px 24px 0; display: flex; justify-content: center; }
  .carte--large .carte__contenu { padding: 24px; text-align: center; }
  .carte--large .btn { align-self: stretch; width: 100%; }
  .carte__contenu { text-align: center; }
  .carte--mini { padding: 16px; }
  .carte--mini__couverture { width: 72px; }
  .chantier-carte { display: block; }
}

/* ===== Section En construction ===== */
.chantier { position: relative; background: var(--papier-clair); padding: 128px clamp(24px, 5.6vw, 80px); }
.chantier__grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; }
.chantier__texte { grid-column: 1 / span 4; }
.chantier__liste { grid-column: 6 / span 7; display: flex; flex-direction: column; gap: 16px; }
.chantier__liste .chantier-carte:nth-child(2) { margin-left: 32px; }
.chantier__liste .chantier-carte:nth-child(3) { margin-left: 64px; }

@media (max-width: 899px) {
  .chantier { padding: 64px 24px; }
  .chantier__grid { display: block; }
  .chantier__texte, .chantier__liste { grid-column: auto; }
  .chantier__liste { margin-top: 24px; gap: 12px; }
  .chantier__liste .chantier-carte:nth-child(2), .chantier__liste .chantier-carte:nth-child(3) { margin-left: 0; }
  .chantier-carte { flex-direction: column; align-items: flex-start; }
}

/* ===== Couverture ===== */
/* La couverture porte le MÊME pli que la carte qui la contient. Elle hérite
   la variante par sélecteur descendant plutôt que par une classe posée dans le
   HTML : le livret et sa carte sont un seul objet, il ne faut pas pouvoir les
   désaccorder par oubli. --coin y est plus petit (18px) que sur la carte : la
   couverture ne fait qu'un tiers de sa largeur, un pli à l'échelle de la carte
   y aurait mangé le titre. */
.couverture {
  position: relative;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: 1.5px solid var(--encre);
  --coin: 18px;
  --envers: color-mix(in srgb, currentColor 22%, var(--papier-envers));
  /* La couverture est une MAQUETTE de livret : elle doit se comporter comme
     une photo du livre, c'est-à-dire garder ses proportions internes à toutes
     les tailles. Or elle est rendue entre 96px (vignette « bientôt ») et 479px
     (carte vedette) de large, avec une typographie fixe : à 168px, un titre de
     huit mots occupait 126px là où sa zone en fait 63, poussait la fenêtre et
     la bande basse hors du cadre, et la couverture dépassait son ratio 3/4 de
     56 %. Toute la bibliothèque était en dents de scie, sans que la cause soit
     visible autrement qu'en mesurant les boîtes.
     `container-type: inline-size` fait de la couverture son propre contexte de
     mesure : ses corps de texte sont exprimés en cqw (pourcentage de SA
     largeur) plus bas, et elle se comporte enfin comme une maquette à
     l'échelle. Les bornes des clamp() sont calées sur la couverture de
     référence (325px de large, corps 17) : 5,2cqw y redonne exactement 17px. */
  container-type: inline-size;
  clip-path: polygon(0 0, calc(100% - var(--coin)) 0, 100% var(--coin), 100% 100%, 0 100%);
  display: flex;
  flex-direction: column;
  font-family: var(--font-texte);
  overflow: hidden;
  color: var(--papier-clair);
}
.couverture--valorisation { color: var(--encre); }
.couverture--construction { border-style: dashed; }

/* ---- Accord du pli entre la carte et sa couverture ---- */
.pli--corne-bg .couverture {
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--coin) 100%, 0 calc(100% - var(--coin)));
}
.pli--onglet .couverture {
  clip-path: polygon(0 0, 36% 0, calc(36% + 10px) 12px, 100% 12px, 100% 100%, 0 100%);
}
.pli--croquis .couverture {
  clip-path: none;
  border-radius: 12px 26px 14px 22px / 22px 13px 25px 14px;
}
/* Le rabat de la couverture : même géométrie que celui des cartes, à l'échelle
   de --coin: 18px. Il ne s'ouvre pas au survol — deux plis qui bougent en même
   temps sur le même objet, c'est un objet qui tremble. */
.couverture::after {
  content: "";
  position: absolute;
  top: 0; right: 0;
  z-index: 3;
  width: var(--coin);
  height: var(--coin);
  background: var(--envers);
  background-image: linear-gradient(225deg,
    rgba(20, 33, 31, 0.16) 0%,
    rgba(20, 33, 31, 0.05) 42%,
    rgba(255, 255, 255, 0.24) 100%);
  clip-path: polygon(0 0, 0 100%, 100% 100%);
  filter: drop-shadow(-1px 1px 2px var(--pli-ombre));
  pointer-events: none;
}
.pli--corne-bg .couverture::after {
  top: auto; right: auto; bottom: 0; left: 0;
  clip-path: polygon(100% 0, 0 0, 100% 100%);
  filter: drop-shadow(1px -1px 2px var(--pli-ombre));
  background-image: linear-gradient(45deg,
    rgba(20, 33, 31, 0.16) 0%,
    rgba(20, 33, 31, 0.05) 42%,
    rgba(255, 255, 255, 0.24) 100%);
}
.pli--onglet .couverture::after,
.pli--croquis .couverture::after { content: none; }
/* min-height: 0 — même cause que sur .couverture__fenetre : sans lui, la
   taille minimale automatique d'un enfant flexible est le contenu, et
   `flex: 0 0 28%` n'était qu'un vœu pieux. overflow: hidden est la ceinture :
   si un titre reste trop long malgré la mise à l'échelle, il est rogné dans sa
   zone et NE POUSSE PAS le reste de la couverture. */
.couverture__titre-zone { flex: 0 0 28%; min-height: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; padding: 4cqw 4.3cqw; }
.couverture__titre {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 48;
  font-weight: 600;
  font-size: clamp(8px, 5.2cqw, 26px);
  line-height: 1.22;
  text-align: center;
  color: inherit;
  /* Quatre lignes au maximum. Un titre de livret n'en demande jamais plus une
     fois mis à l'échelle ; la limite n'existe que pour qu'un futur titre
     exceptionnellement long ne casse pas la maquette silencieusement. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}
/* min-height: 0 est INDISPENSABLE, et son absence était un bug de mise en page
   visible sur la moitié des livrets. `flex: 0 0 44%` fixe la BASE à 44 % de la
   couverture, mais la taille minimale automatique d'un enfant flexible est
   `auto` : le navigateur refuse alors de descendre sous la hauteur intrinsèque
   du contenu. L'illustration est en `width: 100%`, donc sa hauteur
   intrinsèque vaut sa largeur multipliée par son rapport de forme. Pour les
   .webp carrés (page-blanche, loupe, cocotte…) cela faisait 291px au lieu des
   191px demandés : la fenêtre débordait sur la bande du bas, le sous-titre se
   retrouvait imprimé sur le blanc de l'image et la mention « Dycie »
   disparaissait sous le bord. Les illustrations au format paysage (bateau,
   112 × 88) passaient, elles — d'où un défaut qui ne touchait qu'une carte
   sur deux et pouvait se lire comme une intention.
   `object-fit: contain` sur l'image fait le reste : elle se contente de la
   place accordée sans se déformer. */
.couverture__fenetre { position: relative; flex: 0 0 44%; min-height: 0; margin: 0 4.9cqw; background: var(--papier-clair); display: flex; align-items: center; justify-content: center; padding: 3cqw; }
.couverture__image { width: 100%; height: 100%; object-fit: contain; padding: 3cqw; }
.couverture__tag {
  position: absolute; left: -6px; bottom: 6px;
  display: inline-flex; align-items: center;
  height: 6.8cqw; min-height: 12px; padding: 0 3cqw;
  background: var(--magenta); color: var(--papier-clair);
  font-weight: 600; font-size: clamp(6px, 3.4cqw, 15px); letter-spacing: 0.06em; text-transform: uppercase;
  transform: rotate(-4deg);
  white-space: nowrap;
}
.couverture__bas { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.8cqw; padding: 1.8cqw 4.3cqw 3.7cqw; }
.couverture__soustitre { margin: 0; font-size: clamp(7px, 3.7cqw, 18px); line-height: 1.3; text-align: center; color: inherit; }
.couverture__logo { margin: 0; font-family: var(--font-display); font-variation-settings: 'opsz' 30; font-weight: 600; font-size: clamp(7px, 4cqw, 20px); color: inherit; }

/* ===== Utilitaires d'animation (états posés par JS) ===== */
.js-fade-up, .js-fade-left, .js-fade-right { opacity: 1; }
.no-js-hide-nothing { display: block; }

/* ===== Révélation ligne par ligne (masque) =====
   Structure posée par revelationLignes() dans main.js :
     <h2 data-lignes>
       <span class="ligne-masque"><span class="ligne-glisse">…mots…</span></span>
       …une paire par ligne mesurée…
     </h2>

   Le masque est la boîte qui coupe ; le translateur est ce qui glisse dedans.
   Les deux sont indispensables : animer directement la ligne sans masque
   ferait passer le texte PAR-DESSUS la ligne d'à côté. */
.ligne-masque {
  display: block;
  overflow: hidden;
  /* Le couple padding/marge est la seule façon de laisser vivre les jambages
     sous un overflow: hidden. Fraunces descend bas (« p », « g », « q », « ç ») :
     sans ces 0,18 em, chaque « g » de chaque titre était coupé net. La marge
     négative annule exactement le padding pour que l'interligne visuelle du
     titre reste celle du CSS. */
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
}
.ligne-glisse {
  display: block;
  will-change: transform;
}
/* Sans JS, ou avant que la découpe n'ait lieu, le titre reste un titre
   ordinaire : aucune règle ne dépend de la structure de masques pour
   l'affichage au repos. */
.ligne-mot { display: inline; }

@media (prefers-reduced-motion: reduce) {
  .ligne-masque { overflow: visible; padding-bottom: 0; margin-bottom: 0; }
  .ligne-glisse { transform: none !important; }
}

/* ===== Bandeau défilant des enjeux =====
   Remplace la liste statique qui vivait dans la colonne droite du manifeste.
   Les enjeux sont la matière la plus dense de la page — dix formulations
   longues — et ils étaient posés en petit corps dans une colonne de 5/12.
   Personne ne lit ça. En bandeau pleine largeur, en Fraunces, ils deviennent
   la respiration entre le manifeste et les trois temps du slogan.

   Aucun enjeu n'a été retiré : la liste est reprise mot pour mot, seule sa
   mise en forme change. */
.bandeau {
  position: relative;
  overflow: hidden;
  background: var(--vignette);
  /* 58px en bas contre 40 en haut : la déchirure mange jusqu'à 14px du bord
     inférieur, et la rangée du bas se retrouvait à 30px du vide. */
  padding: 40px 0 58px;
  /* Bord inférieur déchiré : c'est une BANDE, le seul format sur lequel la
     déchirure du vocabulaire de plis se lit vraiment (voir .pli--dechire). */
  --dent: 14px;
}
.bandeau__titre {
  margin: 0 0 20px;
  text-align: center;
  color: var(--encre-3);
}
.bandeau__piste {
  display: flex;
  width: max-content;
  /* Le défilement est une translation de -50 % de la piste, et la piste
     contient exactement deux copies de la file : quand la première a fini de
     sortir, la seconde est exactement là où la première a commencé. Le retour
     à zéro est donc invisible, quelle que soit la longueur du texte.
     --duree-piste est calculée en JS depuis la largeur réelle, pour que la
     vitesse soit la même (en px/s) sur toutes les tailles d'écran. */
  animation: defile var(--duree-piste, 40s) linear infinite;
}
.bandeau__piste--inverse {
  animation-direction: reverse;
  margin-top: 14px;
}
@keyframes defile {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
/* Le survol ralentit au lieu d'arrêter : un bandeau qui se fige lit comme un
   bug, un bandeau qui ralentit lit comme une invitation à lire. */
.bandeau:hover .bandeau__piste { animation-duration: calc(var(--duree-piste, 40s) * 3.2); }

.bandeau__file {
  display: flex;
  align-items: center;
  flex: none;
  gap: 0;
  white-space: nowrap;
}
.bandeau__file span {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 96;
  font-weight: 600;
  font-size: 30px;
  line-height: 1.25;
  color: var(--encre);
  padding: 0 4px;
}
.bandeau__piste--inverse .bandeau__file span {
  font-size: 26px;
  color: var(--encre-2);
}
/* Le séparateur : une astérisque manuscrite orange, penchée. C'est le même
   rôle que la virgule orange de la liste d'origine (.manifeste__virgule), qui
   disparaît avec elle — on ne perd pas le signe, il change de forme. */
.bandeau__sep {
  font-family: var(--font-accent) !important;
  font-size: 34px !important;
  color: var(--orange) !important;
  padding: 0 22px !important;
  display: inline-block;
  transform: translateY(-2px) rotate(-8deg);
}

/* Les bords se fondent dans le fond : sans ce masque, les mots sont tranchés
   net par le bord de l'écran et le bandeau lit comme une zone qui déborde
   plutôt que comme un ruban qui passe. */
.bandeau::before,
.bandeau::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: clamp(48px, 8vw, 120px);
  z-index: 2;
  pointer-events: none;
}
.bandeau::before { left: 0; background: linear-gradient(90deg, var(--vignette), transparent); }
.bandeau::after { right: 0; background: linear-gradient(270deg, var(--vignette), transparent); }

@media (max-width: 899px) {
  .bandeau { padding: 28px 0 32px; --dent: 10px; }
  .bandeau__file span { font-size: 21px; }
  .bandeau__piste--inverse .bandeau__file span { font-size: 19px; }
  .bandeau__sep { font-size: 25px !important; padding: 0 14px !important; }
}
@media (prefers-reduced-motion: reduce) {
  /* Aucun défilement : la piste est figée sur son premier écran. Les enjeux
     restent lisibles, ils ne bougent simplement plus. */
  .bandeau__piste { animation: none; }
}

/* ===== Soulignement d'encre voyageur (menu) =====
   Un seul trait pour tout le menu ; main.js le déplace de lien en lien et le
   redessine à chaque saut. Voir souligneNav() pour la mécanique. */
.entete__nav { position: relative; }
.nav-trait {
  position: absolute;
  top: 0;
  left: 0;
  height: 8px;
  opacity: 0;
  pointer-events: none;
  overflow: visible;
}
.nav-trait path { stroke: var(--petrole); }
/* La barre droite de la v1 disparaît : deux soulignements sur le même lien,
   l'un droit l'autre tracé, se superposaient et faisaient un trait double. */
.entete__lien::after { content: none; }

/* ===== Couverture en vignette (cartes « bientôt disponible ») =====
   La mise à l'échelle en cqw (voir .couverture) gère désormais la typographie
   des vignettes de 96px sans réglage manuel. Restent deux exceptions, qui ne
   sont pas des questions de taille mais de sens :

   - la pastille « En construction » débordait de 6px à gauche pour donner
     l'impression d'une étiquette collée après coup. Sur 96px de large, ce
     débord ne produisait qu'une troncature par overflow: hidden ;
   - le rabat de papier couvrirait un cinquième d'une couverture de cette
     taille : à cette échelle, la couverture n'est plus un objet qu'on manipule,
     c'est un repère. */
.carte--mini__couverture .couverture__tag { left: 0; }
.carte--mini__couverture .couverture::after { content: none; }
