/* =========================================================
   Cœur Alchimique — feuille de style unique
   Bleu = l'émotion. Or = sa transmutation.
   ========================================================= */

/* ---------- 0. La police des titres ----------

   Cormorant Garamond, hébergée ici même. Jamais chez Google : une
   police distante fait partir l'adresse IP du visiteur vers un tiers,
   ce que la CNIL sanctionne et ce qui obligerait à un bandeau de
   consentement. Servie depuis le domaine, la question ne se pose pas.

   Version variable (une graisse continue de 300 à 700 dans un seul
   fichier) : le site utilise 400 et 600, en romain et en italique.
   Deux fichiers au lieu de quatre.

   Sous-ensemble latin uniquement. Le sous-ensemble latin-ext a été
   essayé et retiré : Chromium le télécharge quand même, parce que les
   deux plages se chevauchent sur trois signes combinants — 68 Ko pour
   rien à chaque visite. Si un jour un nom polonais ou roumain apparaît
   dans un témoignage, ces lettres-là s'afficheront en Georgia. Une
   lettre au mauvais dessin, pas un carré vide.

   Les chemins sont relatifs à CETTE feuille, pas à la page : ils
   fonctionnent donc depuis la racine comme depuis /pages/.
   ---------- */

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin-italic.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. Jetons ---------- */
:root {
  /* Échelle du fond : uniquement des bleus, du plus profond au plus
     ouvert. Toutes ces valeurs portent du texte crème — il n'y a plus
     aucune zone claire, donc plus aucune bascule de lisibilité.

     Le rythme d'une page se fait par une respiration : on descend vers
     g4 au milieu, puis on remonte vers le profond en bas. Pas une pente
     monotone du haut vers le bas. */
  --g0: #070d18;
  --g1: #0c1a2c;
  --g2: #0f2036;
  --g3: #142943;
  --g4: #1a3558;
  --g5: #21426b;   /* le plus ouvert — réservé aux moments qui respirent */

  --g-footer: #050a12;

  /* Réservés à la future section « méthode » : la seule zone du site où
     le bleu bascule vers l'or, pour montrer la transmutation. */
  --or-bascule-1: #3f74b0;
  --or-bascule-2: #a8cbef;
  --or-bascule-3: #e7cf8f;
  --or-bascule-4: #9c7a26;

  /* Couleurs de marque */
  --bleu-nuit: #05090f;
  --bleu-profond: #0c1b33;
  --bleu-vif: #2f6bb5;
  --bleu-pale: #9dc0e8;
  --or: #c9a227;
  --or-clair: #e3c879;
  --or-pale: #f0e0b8;
  --creme: #f6f1e6;
  --encre: #14243d;
  --encre-douce: #46536b;

  /* Rôles */
  --texte-sombre-fond: #f2f5f9;
  --texte-sombre-fond-attenue: #a9bdd6;
  --texte-clair-fond: var(--encre);
  --texte-clair-fond-attenue: var(--encre-douce);

  /* Typographie */
  --font-titre: "Cormorant Garamond", Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  --font-texte: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --pas: 1rem;

  /* Trois largeurs, et il faut les distinguer :
     - --largeur-max  : le cadre de la page. 1800 px, parce qu'un écran
       moderne fait au moins 1920 et qu'une grille de cartes gagne à
       respirer.
     - --largeur-lecture : un bloc de texte suivi. Plafonné à 50rem
       (~800 px) parce qu'au-delà de 75 caractères par ligne, l'œil
       perd la ligne suivante en revenant à la marge. Élargir la page
       n'élargit JAMAIS un paragraphe.
     - --largeur-texte : les chapôs et en-têtes de section, plus court
       encore pour qu'un titre ne parte pas en bandeau. */
  --largeur-max: 112.5rem;
  --largeur-lecture: 50rem;
  --largeur-texte: 38rem;
  --rayon: 14px;
  --rayon-s: 8px;
  --ombre: 0 18px 50px -20px rgba(0, 0, 0, 0.55);
  --transition: 220ms cubic-bezier(0.4, 0, 0.2, 1);
  /* Pour les déplacements de fond, pas les survols : le miroir d'eau. */
  --transition-lente: 650ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- 2. Base ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font-texte);
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--texte-sombre-fond);
  background: var(--bleu-nuit);

  /* clip, PAS hidden. overflow-x: hidden force overflow-y à « auto »,
     ce qui fait de <body> une boîte de défilement — et un enfant en
     position: sticky ne colle plus à rien, parce qu'il colle à cette
     boîte-là et non à la fenêtre. L'en-tête partait au défilement.
     overflow-x: clip masque exactement pareil sans créer de boîte. */
  overflow-x: clip;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--font-titre);
  font-weight: 600;
  line-height: 1.15;
  margin: 0 0 0.6em;
  letter-spacing: 0.01em;
}

h1 { font-size: clamp(2.3rem, 6vw, 4rem); }
h2 { font-size: clamp(1.85rem, 4.2vw, 2.9rem); }
h3 { font-size: clamp(1.25rem, 2.4vw, 1.6rem); }
h4 { font-size: 1.1rem; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

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

.lien-evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--or);
  color: var(--bleu-nuit);
  padding: 0.75rem 1.25rem;
  z-index: 200;
  font-weight: 600;
}
.lien-evitement:focus { left: 0.5rem; top: 0.5rem; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- 3. Mise en page ---------- */
.contenu {
  width: min(100% - clamp(2.5rem, 5vw, 5rem), var(--largeur-max));
  margin-inline: auto;
}

.contenu--etroit {
  width: min(100% - 2.5rem, var(--largeur-lecture));
  margin-inline: auto;
}

section {
  padding-block: clamp(3.5rem, 9vw, 7rem);
  position: relative;
}

/* Chaque section porte sa couleur de départ (--de) et d'arrivée (--vers),
   toutes deux prises dans l'échelle bleue. Comme il n'y a plus de zone
   claire, aucune section ne peut devenir illisible en cours de route.

   Interpolation en OKLAB : la clarté y est perceptuellement linéaire,
   donc les fondus entre bleus proches sont plus réguliers qu'en sRGB.
   La première déclaration sert de repli aux navigateurs anciens. */
.fondu {
  background-image: linear-gradient(180deg, var(--de), var(--vers));
  background-image:
    var(--halo, linear-gradient(transparent, transparent)),
    linear-gradient(180deg in oklab, var(--de), var(--vers));
}

.bande-transition {
  height: clamp(90px, 14vw, 160px);
  background-image: linear-gradient(180deg, var(--de), var(--vers));
  background-image: linear-gradient(180deg in oklab, var(--de), var(--vers));
}

/* RÉSERVÉ — la bascule bleu → or n'est plus utilisée sur les pages.
   Le fond du site est uniformément bleu, l'or n'est qu'un accent.
   Ces classes sont conservées pour la future section « explication de
   la méthode », où la transmutation sera montrée localement.
   Elles ont besoin des jetons --or-bascule-* ci-dessous. */
.bande-transition--or {
  height: clamp(180px, 26vw, 340px);
  background-image: linear-gradient(180deg, var(--de) 0%, var(--or-bascule-1) 28%, var(--or-bascule-2) 56%, var(--vers) 100%);
  background-image: linear-gradient(
    180deg in oklab,
    var(--de) 0%,
    var(--or-bascule-1) 28%,
    var(--or-bascule-2) 56%,
    var(--vers) 100%
  );
}

/* RÉSERVÉ — idem, pour la future section « méthode ». */
.bande-vers-pied {
  height: clamp(110px, 16vw, 190px);
  background-image: linear-gradient(180deg in oklab, var(--or-bascule-3) 0%, var(--or-bascule-4) 58%, var(--g-footer) 100%);
}

[data-theme="sombre"] { color: var(--texte-sombre-fond); }
[data-theme="sombre"] .attenue { color: var(--texte-sombre-fond-attenue); }
[data-theme="clair"] { color: var(--texte-clair-fond); }
[data-theme="clair"] .attenue { color: var(--texte-clair-fond-attenue); }

.chapo {
  font-size: clamp(1.1rem, 2vw, 1.3rem);
  max-width: var(--largeur-texte);
  line-height: 1.65;
}

.surtitre {
  font-family: var(--font-texte);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--or-clair);
  margin-bottom: 0.9rem;
  display: block;
}
[data-theme="clair"] .surtitre { color: #8a6b1c; }

.entete-section { max-width: var(--largeur-texte); margin-bottom: clamp(2rem, 4vw, 3rem); }

/* En-tête pleine largeur, à deux colonnes.

   `--largeur-texte` (38rem) est la bonne mesure pour LIRE un paragraphe.
   Ce n'est pas une largeur d'EN-TÊTE : à 1800px, le contenu fait 1720px
   et l'en-tête 608px, soit 35 %. Un titre aligné à gauche dans ce format
   ressemble à un timbre posé sur une rangée qui ne lui appartient pas.

   Ici le titre garde sa mesure de lecture, le chapô aussi, mais les deux
   se partagent la largeur du contenu : la bande annonce la largeur de ce
   qui suit au lieu de la contredire. Réservé aux en-têtes alignés à
   gauche — les en-têtes centrés sont déjà symétriques, ils ne souffrent
   pas du même défaut. */
@media (min-width: 75rem) {
  .entete-section--bande {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: end;
  }
  .entete-section--bande > :first-child { max-width: 30rem; }
  .entete-section--bande .chapo { margin: 0 0 0.35rem; max-width: 34rem; }
}
.entete-section.centre { margin-inline: auto; text-align: center; }

/* Le retour au rayon.

   Livres et E-learnings ne sont plus dans la navigation : ce sont deux
   rayons de la Médiathèque, qui y mène. Une page qu'on atteint par un
   lien ou par un moteur de recherche doit dire d'où elle vient, sinon
   le visiteur n'a aucun moyen de remonter à l'ensemble. */
.retour-rayon {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  color: var(--bleu-pale);
  text-decoration: none;
}
.retour-rayon svg { width: 1em; height: 1em; flex: none; }
.retour-rayon:hover { color: var(--or-clair); }


/* Filet décoratif */
.filet {
  width: 64px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--or), transparent);
  margin: 1.5rem 0;
  border: 0;
}
.entete-section.centre .filet { margin-inline: auto; }

/* ---------- 4. Boutons ---------- */
.bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-texte);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 0.9rem 1.7rem;
  border-radius: 999px;
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--transition), background var(--transition),
              border-color var(--transition), box-shadow var(--transition);
}
.bouton:hover { transform: translateY(-2px); }

.bouton--or {
  background: linear-gradient(135deg, var(--or-clair), var(--or));
  color: #2a2008;
  box-shadow: 0 10px 30px -12px rgba(201, 162, 39, 0.8);
}
.bouton--or:hover { box-shadow: 0 16px 38px -12px rgba(201, 162, 39, 0.95); }

.bouton--contour {
  border-color: rgba(227, 200, 121, 0.55);
  color: var(--or-clair);
  background: rgba(227, 200, 121, 0.06);
}
.bouton--contour:hover { border-color: var(--or-clair); background: rgba(227, 200, 121, 0.14); }

[data-theme="clair"] .bouton--contour {
  border-color: rgba(20, 36, 61, 0.3);
  color: var(--encre);
  background: rgba(20, 36, 61, 0.04);
}
[data-theme="clair"] .bouton--contour:hover { border-color: var(--encre); background: rgba(20, 36, 61, 0.09); }

.groupe-boutons { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 1.8rem; }

/* ---------- 5. En-tête ---------- */

/* Les fragments sont injectés DANS leur hôte, qui reste dans le DOM.
   Pour l'en-tête et le pied, cet hôte doit disparaître de la mise en
   page : un élément sticky ne peut coller qu'à l'intérieur de la boîte
   de son parent, et cet hôte fait exactement la hauteur de l'en-tête.
   Résultat, l'en-tête avait 0 px de course et repartait au défilement
   comme s'il n'était pas collant du tout. display: contents supprime
   la boîte de l'hôte sans toucher à son contenu.

   Ne PAS généraliser à tous les [data-partial] : l'hôte du sceau, lui,
   porte ses propres styles et a besoin de sa boîte. */
[data-partial="entete"],
[data-partial="pied"] { display: contents; }

/* L'en-tête s'efface quand on descend et revient dès qu'on remonte.

   Le principe : descendre, c'est lire — on rend l'écran au texte.
   Remonter, c'est chercher — on rend la navigation, tout de suite,
   sans attendre d'être arrivé en haut.

   La translation plutôt que `display` ou la hauteur : rien ne bouge
   dans le flux, donc rien ne saute, et le sommaire de page qui se colle
   dessous n'a pas à être recalculé. */
.entete {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(5, 9, 15, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(227, 200, 121, 0.16);
  transition: transform 280ms ease;
}
.entete[data-cachee="true"] { transform: translateY(-100%); }

/* Le sommaire de page suit : sans ça il resterait à sa place et
   laisserait une bande vide là où était l'en-tête. */
.sommaire { transition: top 280ms ease; }
body[data-entete-cachee="true"] .sommaire { top: 0; }

@media (prefers-reduced-motion: reduce) {
  .entete, .sommaire { transition: none; }
}

.entete__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 72px;
}

.marque { display: flex; align-items: center; gap: 0.75rem; text-decoration: none; color: var(--creme); }
.marque__sceau { width: 38px; height: 38px; flex: none; }
.marque__texte { display: flex; flex-direction: column; line-height: 1.1; }
.marque__nom {
  font-family: var(--font-titre);
  font-size: 1.22rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.marque__baseline {
  font-size: 0.66rem;
  letter-spacing: 0.07em;
  color: var(--bleu-pale);
  font-style: italic;
}
@media (max-width: 560px) { .marque__baseline { display: none; } }

.nav-principale ul {
  list-style: none;
  display: flex;
  gap: 0.35rem;
  margin: 0; padding: 0;
}
.nav-principale a {
  display: block;
  padding: 0.55rem 0.85rem;
  font-size: 0.93rem;
  text-decoration: none;
  color: var(--texte-sombre-fond-attenue);
  border-radius: var(--rayon-s);
  transition: color var(--transition), background var(--transition);
}
.nav-principale a:hover { color: var(--creme); background: rgba(157, 192, 232, 0.1); }
.nav-principale a[aria-current] { color: var(--or-clair); }

.bascule-menu {
  display: none;
  background: none;
  border: 1px solid rgba(227, 200, 121, 0.35);
  border-radius: var(--rayon-s);
  color: var(--creme);
  width: 44px; height: 44px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.bascule-menu svg { width: 22px; height: 22px; }
.bascule-menu .icone-fermer { display: none; }
.bascule-menu[aria-expanded="true"] .icone-ouvrir { display: none; }
.bascule-menu[aria-expanded="true"] .icone-fermer { display: block; }

@media (max-width: 860px) {
  .bascule-menu { display: inline-flex; }
  /* Fond OPAQUE, et surtout pas de backdrop-filter ici. Le panneau est
     un enfant de .entete, qui en porte déjà un : Chromium compose alors
     les deux et la page transparaît à travers le menu, malgré un fond
     à 98 %. On voyait le titre du hero derrière les entrées. Un aplat
     opaque règle la question — et il n'y a rien à flouter derrière un
     fond opaque de toute façon. */
  .nav-principale {
    position: absolute;
    inset: 100% 0 auto 0;
    background: #070d18;
    border-bottom: 1px solid rgba(227, 200, 121, 0.2);
    box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.8);
    display: none;
  }
  .nav-principale[data-ouvert="true"] { display: block; }
  .nav-principale ul { flex-direction: column; padding: 0.75rem 1.25rem 1.5rem; gap: 0; }
  .nav-principale a { padding: 0.9rem 0.25rem; font-size: 1.05rem; border-bottom: 1px solid rgba(157, 192, 232, 0.1); }
}

/* ---------- 6. Hero ---------- */
.hero { padding-block: clamp(4rem, 12vw, 8.5rem); }
.hero__grille {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 900px) {
  .hero__grille { grid-template-columns: 1fr; }
  .hero__visuel { order: -1; }
}

.hero__titre { margin-bottom: 0.35em; }
.hero__baseline {
  font-family: var(--font-titre);
  font-style: italic;
  font-size: clamp(1.25rem, 2.8vw, 1.75rem);
  color: var(--or-clair);
  margin-bottom: 1.2rem;
  line-height: 1.35;
}
.hero__texte { max-width: 34rem; color: var(--texte-sombre-fond-attenue); }

.hero__visuel { position: relative; }
.hero__visuel img {
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  border: 1px solid rgba(227, 200, 121, 0.18);
}

/* Halos — profondeur du fond.

   Ils étaient auparavant des <span> floutés en position absolue. Mauvaise
   idée : un élément flouté déborde de sa section, ce qui crée une barre de
   défilement horizontale, et le rogner avec overflow:hidden coupe le flou
   au couteau — on voyait une arête nette en bord de section.

   Un dégradé radial en fond n'a aucun de ces deux défauts : il ne déborde
   jamais et il s'éteint en douceur. On pose une classe sur la section. */

/* Les rayons sont exprimés en POURCENTAGE de la section, et le halo
   s'éteint (transparent) bien avant les bords. C'est ce qui évite une
   ligne visible à la jointure entre deux sections : au bord, le halo
   vaut exactement zéro des deux côtés. */

.halo-haut-droite {
  --halo: radial-gradient(42% 46% at 86% 40%, rgba(76, 140, 210, 0.22), transparent 72%);
}
.halo-haut-gauche {
  --halo: radial-gradient(42% 46% at 14% 38%, rgba(76, 140, 210, 0.22), transparent 72%);
}
.halo-bas-gauche {
  --halo: radial-gradient(40% 44% at 12% 62%, rgba(47, 107, 181, 0.20), transparent 72%);
}
.halo-or {
  --halo: radial-gradient(30% 34% at 88% 46%, rgba(201, 162, 39, 0.12), transparent 70%);
}
/* Le hero : un halo bleu côté titre, une pointe dorée côté visuel. */
.halo-hero {
  --halo:
    radial-gradient(46% 52% at 16% 34%, rgba(47, 107, 181, 0.28), transparent 70%),
    radial-gradient(30% 34% at 88% 72%, rgba(201, 162, 39, 0.16), transparent 70%);
}

/* ---------- 7. Cartes ---------- */
.grille {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}
.grille--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }

.carte {
  background: rgba(157, 192, 232, 0.06);
  border: 1px solid rgba(157, 192, 232, 0.16);
  border-radius: var(--rayon);
  padding: 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transition: transform var(--transition), border-color var(--transition), background var(--transition);
}
.carte:hover { transform: translateY(-4px); border-color: rgba(227, 200, 121, 0.4); }
[data-theme="clair"] .carte {
  background: rgba(255, 255, 255, 0.55);
  border-color: rgba(20, 36, 61, 0.12);
}
[data-theme="clair"] .carte:hover { border-color: rgba(154, 122, 40, 0.5); background: rgba(255, 255, 255, 0.8); }

.carte h3 { margin: 0; }
.carte__pied { margin-top: auto; padding-top: 0.5rem; }

/* Le pied des cartes de soin.

   Prix, duree et bouton s'empilaient sur trois lignes : beaucoup de
   hauteur pour trois informations courtes, et une carte qui n'en
   finissait pas apres un protocole deja long. Une seule rangee — le
   tarif d'un cote, l'action de l'autre — et la duree collee au prix,
   puisqu'elle le qualifie : « 100 € pour environ 1h30 » se lit d'un
   trait, alors que deux lignes separees demandent de recoller.

   La classe est un modificateur et pas une reecriture de
   .carte__pied : ce pied-la sert dans huit rendus differents, dont des
   cartes sans prix ni bouton. `margin-top: auto` est conserve, c'est
   lui qui colle le pied en bas quand les deux cartes n'ont pas la
   meme hauteur. */
.carte__pied--tarif {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid rgba(201, 162, 39, 0.22);
}
.carte__tarif { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.45rem; }
.carte__tarif .prix { margin: 0; }
.carte__duree { margin: 0; font-size: 0.88rem; }
.carte__pied--tarif .bouton { margin: 0; flex: none; }

/* Sous 420 px les deux blocs ne tiennent plus cote a cote : le bouton
   passe dessous et prend toute la largeur, ce qui en fait une cible
   franche au pouce plutot qu'un bouton perdu a droite. */
@media (max-width: 420px) {
  .carte__pied--tarif { justify-content: flex-start; }
  .carte__pied--tarif .bouton { width: 100%; justify-content: center; }
}

.carte__media {
  margin: -1.6rem -1.6rem 0.4rem;
  border-radius: var(--rayon) var(--rayon) 0 0;
  overflow: hidden;
  aspect-ratio: 16 / 10;
}
.carte__media img { width: 100%; height: 100%; object-fit: cover; }

/* Média en portrait — les couvertures de livres.

   object-fit: contain et non cover : chaque couverture porte son titre
   jusqu'aux bords, et chacune a sa propre couleur de fond (violet, vert,
   magenta, blanc). Rogner couperait le texte ; « contain » les montre
   entières, sur un fond neutre qui tient lieu de passe-partout.

   Le rapport 0.68 est la moyenne des sept couvertures : le cadrage est
   donc quasi plein pour toutes, avec un filet de marge selon les cas. */
.carte__media--portrait {
  aspect-ratio: 0.68;
  background: rgba(7, 13, 24, 0.55);
  margin-bottom: 1rem;
}
.carte__media--portrait img { object-fit: contain; }

.livre__ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
}
.livre__format { font-size: 0.85rem; color: var(--texte-sombre-fond-attenue); }

/* Une grille de couvertures n'a pas besoin de colonnes aussi larges
   qu'une grille de cartes de texte. */
.grille--livres { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }

/* align-self : la carte est un conteneur flex en colonne, dont les
   enfants s'étirent sur toute la largeur par défaut. Une pastille qui
   s'étire n'est plus une pastille — ça se voyait peu à 350 px de
   carte, ça saute aux yeux à 560. */
.etiquette {
  display: inline-block;
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: rgba(227, 200, 121, 0.14);
  color: var(--or-clair);
  border: 1px solid rgba(227, 200, 121, 0.3);
}
[data-theme="clair"] .etiquette { background: rgba(154, 122, 40, 0.12); color: #7d6119; border-color: rgba(154, 122, 40, 0.3); }

.prix {
  font-family: var(--font-titre);
  font-size: 1.85rem;
  font-weight: 600;
  color: var(--or-clair);
  line-height: 1;
}
[data-theme="clair"] .prix { color: #8a6b1c; }

.liste-puces { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.liste-puces li { position: relative; padding-left: 1.4rem; font-size: 0.95rem; }
/* Les cartes pliables de « Vous n'êtes pas venu·e ici par hasard ».

   Sur mobile, quatre cartes pleines forment une colonne de texte qu'on
   fait défiler sans rien y chercher : le visiteur devrait lire les
   quatre descriptions pour trouver celle qui le concerne. Repliées, les
   quatre phrases tiennent dans un écran et il n'ouvre que la sienne.

   Au-dessus de 45rem elles sont ouvertes et le résumé n'est plus
   cliquable : rien à déplier quand tout tient côte à côte. C'est
   socle.js qui pose et retire l'attribut `open` selon la largeur — CSS
   ne peut pas forcer l'ouverture d'un <details>. */
.carte--pliable { }
.carte--pliable > summary {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  cursor: pointer;
  list-style: none;
}
.carte--pliable > summary::-webkit-details-marker { display: none; }
.carte--pliable > summary > h3 { margin: 0; flex: 1; }
.carte--pliable > summary::after {
  content: "";
  flex: none;
  width: 0.62rem; height: 0.62rem;
  border-right: 1.5px solid var(--or);
  border-bottom: 1.5px solid var(--or);
  transform: translateY(-0.18rem) rotate(45deg);
  transition: transform 220ms ease;
}
.carte--pliable[open] > summary::after { transform: translateY(0.12rem) rotate(-135deg); }
.carte--pliable > p { margin: 0.9rem 0 0; }
.carte--pliable > summary:focus-visible { outline: 2px solid var(--or); outline-offset: 4px; }

@media (min-width: 45rem) {
  .carte--pliable > summary { cursor: default; pointer-events: none; }
  .carte--pliable > summary::after { display: none; }
}

.liste-puces li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.62em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--or);
}

/* ---------- 8. La bibliothèque intérieure ---------- */
.etapes { display: grid; gap: 1.4rem; counter-reset: etape; }
.etape { display: grid; grid-template-columns: auto 1fr; gap: 1.1rem; align-items: start; }
.etape__num {
  font-family: var(--font-titre);
  font-size: 1.5rem;
  color: var(--or);
  line-height: 1;
  padding-top: 0.15rem;
  min-width: 2.2rem;
}
.etape h3 { margin-bottom: 0.3rem; font-size: 1.2rem; }
.etape p { font-size: 0.97rem; margin: 0; }

/* L'étagère : chaque trait est un livre, chaque livre une émotion. */
.etagere {
  background: linear-gradient(160deg, rgba(10, 22, 40, 0.9), rgba(6, 12, 24, 0.95));
  border: 1px solid rgba(157, 192, 232, 0.2);
  border-radius: var(--rayon);
  padding: 1.5rem;
  box-shadow: var(--ombre);
  position: relative;
  overflow: hidden;
}
.etagere__rayon {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 78px;
  padding-bottom: 6px;
  border-bottom: 2px solid rgba(157, 192, 232, 0.22);
  margin-bottom: 14px;
}
.etagere__rayon:last-of-type { margin-bottom: 0; }

.livre {
  flex: 1;
  border-radius: 2px 2px 0 0;
  background: var(--teinte-livre, #1d3a63);
  background-image: linear-gradient(100deg, rgba(255, 255, 255, 0.16) 0 18%, transparent 18% 82%, rgba(0, 0, 0, 0.28) 82% 100%);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.08);
  transition: background-color 700ms ease, opacity 700ms ease;
}

/* Le cœur, au centre de l'étagère */
.coeur-support {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.coeur-svg {
  width: 118px;
  height: 118px;
  filter: drop-shadow(0 0 18px var(--halo-coeur, rgba(47, 107, 181, 0.8)))
          drop-shadow(0 0 44px var(--halo-coeur, rgba(47, 107, 181, 0.5)));
  transition: filter 700ms ease;
}

/* Le moteur : l'étagère et ce qui la commande, ensemble.

   Trois enfants — les étapes, la scène, les états — et non deux blocs,
   parce que l'ordre de lecture n'est pas le même selon la largeur :

     mobile   étapes, PUIS l'étagère, PUIS les trois états. L'étagère
              est ainsi juste au-dessus des cartes qui la repeignent.
     ≥ 60rem  l'étagère à gauche sur les deux rangées, collante ; les
              étapes puis les états à droite.

   Trois éléments frères permettent les deux mises en page sans `order`,
   donc sans décaler l'ordre du clavier.

   `align-self: start` est obligatoire sur un élément collant en grille :
   sans lui il est étiré sur toute la hauteur de sa rangée et n'a plus
   aucune marge pour coller. C'est la première cause de « sticky qui ne
   colle pas ».
   ========================================================= */
/* En flux normal sous 60rem, et non en grille : en grille à une seule
   colonne, chaque enfant occupe sa propre rangée, le bloc de
   positionnement d'un élément collant est donc sa rangée — de sa
   hauteur exacte — et il ne lui reste pas un pixel pour coller. En
   flux, le bloc est `.moteur` tout entier : l'étagère reste sous les
   yeux pendant qu'on fait défiler ce qui la commande. */
.moteur { display: block; }
.moteur > * + * { margin-top: clamp(2rem, 5vw, 3.5rem); }
.moteur__etats { display: grid; gap: clamp(1.5rem, 3vw, 2rem); align-content: start; }
.moteur__legende { font-size: 0.88rem; margin-top: 1.1rem; }
.moteur__bascule h3 { font-size: clamp(1.5rem, 2.6vw, 2rem); margin: 0.2rem 0 0.6rem; }
.moteur__bascule p { max-width: 42rem; margin: 0; }

/* Sur mobile l'étagère colle aussi, mais raccourcie : à hauteur pleine
   elle mangeait la moitié de l'écran et il ne restait plus la place
   d'afficher une carte ouverte en dessous. */
/* Sous 60rem, l'étagère ne s'affiche pas du tout.

   Elle a d'abord été épinglée puis raccourcie, pour rester sous les yeux
   au moment où on choisit un état. Mais épinglée, elle passe forcément
   par-dessus le texte qui défile dessous, et son fond dégradé ne le
   masque qu'à moitié : on lit à travers une étagère.

   Rien n'est perdu. L'étape 02 dit déjà que chaque émotion y est rangée,
   l'étape 03 que le cœur en est le moteur, et chaque carte d'état porte
   son propre cœur et décrit la bibliothèque en toutes lettres — fermée
   et sombre, ouverte, habitée. Le dessin illustrait ; il ne portait
   aucune information à lui seul. */
@media (max-width: 59.99rem) {
  .moteur__scene { display: none; }
}

@media (min-width: 60rem) {
  .moteur {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    column-gap: clamp(2rem, 5vw, 4rem);
    row-gap: clamp(2rem, 4vw, 3rem);
    align-items: start;
  }
  .moteur > * + * { margin-top: 0; }
  .moteur__scene  { grid-column: 1; grid-row: 1 / 3; position: sticky;
                    top: calc(var(--h-entete, 5rem) + 1.5rem); align-self: start; }
  .moteur__etapes { grid-column: 2; grid-row: 1; }
  .moteur__etats  { grid-column: 2; grid-row: 2; }
}

/* ---------- 9. Les trois états du cœur ----------

   Les cartes sont le sélecteur. Un seul DOM, deux mises en page :

     < 48rem   accordéon — le panneau s'ouvre sous sa propre carte,
               ce qui évite d'aller chercher le détail en haut de
               l'écran quand les cartes sont empilées ;
     ≥ 48rem   les trois cartes sur une rangée, le panneau ouvert en
               dessous sur toute la largeur.

   La bascule est du placement de grille, pas un déplacement de nœud :
   l'ordre du DOM (carte, panneau, carte, panneau…) est déjà celui du
   mobile, et le desktop ne fait que le replacer.
   ---------- */

.etats {
  display: grid;
  gap: 0.6rem;
  margin-top: 2.5rem;
}

/* Une planche de symboles ne doit jamais occuper une cellule. */
.planche { position: absolute; width: 0; height: 0; }

.carte-etat {
  display: grid;
  /* Les trois accroches n'ont pas la même longueur : si l'une passe à
     trois lignes, les autres restent centrées dans leur carte au lieu
     de coller en haut. */
  align-content: center;
  gap: 0.3rem;
  padding: 1.15rem 1.3rem;
  text-align: center;
  border: 1px solid;
  border-radius: var(--rayon);
  font-family: var(--font-texte);
  color: inherit;
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition),
              transform var(--transition), box-shadow var(--transition);
}
/* Le cœur de l'état. Trois dessins de la même famille : un contour
   commun, et la lumière qui change. Le débordement des rayons du
   créateur sort du carré — d'où overflow visible. */
.carte-etat__coeur {
  width: clamp(3.25rem, 6vw, 4.25rem);
  aspect-ratio: 1;
  margin: 0 auto 0.35rem;
  display: block;
  transition: opacity var(--transition), transform var(--transition);
  opacity: 0.72;
}
.carte-etat__coeur svg { width: 100%; height: 100%; display: block; overflow: visible; }
.carte-etat:hover .carte-etat__coeur { opacity: 0.9; }
.carte-etat[aria-expanded="true"] .carte-etat__coeur { opacity: 1; transform: scale(1.06); }

.carte-etat__titre { font-family: var(--font-titre); font-size: 1.2rem; line-height: 1.2; }
.carte-etat__accroche { font-size: 0.88rem; line-height: 1.45; opacity: 0.8; }

/* Les trois teintes : le bleu qui se ferme, le passage, l'or. */
.carte-etat--blesse { border-color: rgba(47, 107, 181, 0.5); background: rgba(28, 58, 97, 0.35); }
.carte-etat--alchimique {
  border-color: rgba(120, 110, 90, 0.6);
  background: linear-gradient(135deg, rgba(28, 58, 97, 0.35), rgba(201, 162, 39, 0.22));
}
.carte-etat--createur { border-color: rgba(227, 200, 121, 0.55); background: rgba(201, 162, 39, 0.16); }

.carte-etat:hover { transform: translateY(-2px); }
.carte-etat:hover .carte-etat__accroche { opacity: 1; }

.carte-etat[aria-expanded="true"] {
  border-color: var(--or);
  box-shadow: 0 0 0 1px var(--or), 0 14px 34px -18px rgba(201, 162, 39, 0.8);
}
.carte-etat[aria-expanded="true"] .carte-etat__titre { color: var(--or-pale); }
.carte-etat[aria-expanded="true"] .carte-etat__accroche { opacity: 1; }

.etat-panneau { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.etat-panneau[hidden] { display: none; }
.etat-panneau .liste-puces { margin: 0; }

/* Mobile : le panneau prolonge sa carte. On soude les deux en fermant
   les coins qui se touchent — sinon on lit deux blocs sans rapport. */
@media (max-width: 47.99rem) {
  .carte-etat[aria-expanded="true"] {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    box-shadow: none;
    border-bottom-color: transparent;
  }
  .etat-panneau {
    margin-top: -0.6rem;
    padding: 0.25rem 1.3rem 1.4rem;
    border: 1px solid var(--or);
    border-top: none;
    border-radius: 0 0 var(--rayon) var(--rayon);
  }
}

@media (min-width: 48rem) {
  .etats {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem clamp(1rem, 2vw, 1.5rem);
  }
  /* On compte les boutons entre eux, pas les enfants dans l'ordre :
     la planche de symboles est aussi un enfant, et compter par position
     décalait tout d'une case. `nth-of-type` ne voit que les boutons.
     Les panneaux fermés sont en display:none et ne prennent pas de
     place — un seul occupe donc la rangée 2. */
  .etats > button:nth-of-type(1) { grid-column: 1; grid-row: 1; }
  .etats > button:nth-of-type(2) { grid-column: 2; grid-row: 1; }
  .etats > button:nth-of-type(3) { grid-column: 3; grid-row: 1; }
  .etats > .etat-panneau { grid-column: 1 / -1; grid-row: 2; }
  .etat-panneau { padding-top: 1.5rem; }
}

@media (min-width: 60rem) {
  .etat-panneau { grid-template-columns: 1fr 1fr; }
}

.etat__resume {
  font-family: var(--font-titre);
  font-style: italic;
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  color: var(--or-clair);
  margin-bottom: 1rem;
}

/* La flèche de transmutation */
.transmutation {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 3rem;
  font-family: var(--font-titre);
  font-size: clamp(1.05rem, 2.2vw, 1.4rem);
}
.transmutation__etape { opacity: 0.9; }
.transmutation__fleche {
  flex: 1 1 5rem;
  max-width: 10rem;
  height: 2px;
  background: linear-gradient(90deg, var(--bleu-vif), var(--or));
  border-radius: 2px;
  min-width: 3rem;
}
.transmutation__de { color: var(--bleu-pale); }
.transmutation__vers { color: var(--or-clair); }

/* ---------- 9 bis. Le corps d'un article ----------

   Le seul endroit du site où il y a vraiment du texte suivi. Tout se
   joue sur le rythme vertical : un intertitre doit appartenir
   visiblement au paragraphe qui le suit, donc l'espace au-dessus est
   nettement plus grand que celui du dessous. */
.prose > * + * { margin-top: 1.15rem; }
.prose h2 {
  margin-top: clamp(2.2rem, 5vw, 3rem);
  margin-bottom: 0.2rem;
  font-size: clamp(1.35rem, 3vw, 1.7rem);
  color: var(--or-pale);
}
.prose h2 + p { margin-top: 0.6rem; }
.prose + .cadre { margin-top: clamp(2.5rem, 6vw, 4rem); }

/* ---- La pratique guidée ----

   Ce n'est plus un texte qu'on lit, c'est une voix qu'on suit les yeux
   fermés. Elle change donc d'allure : un bloc à part, sur un fond à
   peine plus clair, des paragraphes plus aérés et plus courts. Les
   points de suspension sont de Sophie — ce sont les respirations, on
   n'y touche pas.

   Pas de justification ici : une consigne se lit ligne à ligne, et le
   drapeau à droite donne à chaque ligne sa longueur propre. */
.pratique-guidee {
  margin: clamp(2.5rem, 6vw, 3.5rem) 0;
  padding: clamp(1.6rem, 4vw, 2.4rem);
  border-radius: var(--rayon);
  border: 1px solid rgba(227, 200, 121, 0.22);
  background: rgba(157, 192, 232, 0.05);
}
.pratique-guidee h2 {
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  margin: 0;
  color: var(--or-pale);
}
.pratique-guidee__note {
  font-size: 0.9rem;
  color: var(--texte-sombre-fond-attenue);
  margin: 0.4rem 0 1.8rem;
}
.pratique-guidee p {
  margin: 0 0 1.1rem;
  line-height: 1.85;
  max-width: 38rem;
}
.pratique-guidee p:last-child { margin-bottom: 0; }
.pratique-guidee strong { color: var(--or-pale); font-weight: 600; }
.pratique-guidee__retour {
  margin: 1.4rem 0 0;
  padding-left: 1.4rem;
  display: grid;
  gap: 0.7rem;
  line-height: 1.7;
  max-width: 38rem;
}
.pratique-guidee__retour::marker { color: var(--or); }
[data-theme="clair"] .pratique-guidee { background: rgba(20, 36, 61, 0.04); }
[data-theme="clair"] .pratique-guidee h2,
[data-theme="clair"] .pratique-guidee strong { color: #7d6119; }
[data-theme="clair"] .pratique-guidee__note { color: var(--texte-clair-fond-attenue); }

/* ---------- 10. Le cadre (complément médical) ---------- */
.cadre {
  border: 1px solid rgba(20, 36, 61, 0.18);
  border-left: 4px solid var(--or);
  border-radius: var(--rayon-s);
  padding: 1.5rem 1.7rem;
  background: rgba(255, 255, 255, 0.6);
}
[data-theme="sombre"] .cadre {
  background: rgba(157, 192, 232, 0.07);
  border-color: rgba(157, 192, 232, 0.2);
  border-left-color: var(--or);
}
.cadre h3 { margin-bottom: 0.5rem; font-size: 1.2rem; }
.cadre p { font-size: 0.97rem; margin: 0; }

/* ---------- 11. Citation ---------- */
.citation {
  font-family: var(--font-titre);
  font-size: clamp(1.3rem, 3vw, 1.9rem);
  font-style: italic;
  line-height: 1.45;
  max-width: 44rem;
  margin: 0 auto;
  text-align: center;
  position: relative;
  padding-top: 2rem;
}
.citation::before {
  content: "”";
  position: absolute;
  top: -0.4rem; left: 50%;
  transform: translateX(-50%);
  font-size: 4rem;
  color: var(--or);
  opacity: 0.55;
  line-height: 1;
}
.citation cite { display: block; font-size: 0.85rem; font-style: normal; letter-spacing: 0.16em; text-transform: uppercase; margin-top: 1.5rem; opacity: 0.75; font-family: var(--font-texte); }

/* ---------- 12. Frise ---------- */
.frise { list-style: none; margin: 0; padding: 0; position: relative; }
.frise::before {
  content: "";
  position: absolute;
  left: 18px; top: 22px; bottom: 22px;
  width: 2px;
  background: linear-gradient(180deg, var(--bleu-vif), var(--or));
}
.frise__item { position: relative; padding-left: 3.6rem; padding-bottom: 2.4rem; min-height: 37px; }
.frise__item:last-child { padding-bottom: 0; }
/* Le medaillon remplace le point. Le cercle est ici, le dessin vient
   de EMBLEMES_FRISE : une seule declaration pour la taille, la couleur
   et le fond, quel que soit le symbole. Le fond est opaque expres —
   c'est lui qui interrompt le rail vertical derriere chaque etape. */
.frise__embleme {
  position: absolute;
  left: 0; top: 0.1rem;
  width: 37px; height: 37px;
  border-radius: 50%;
  background: var(--g9);
  border: 1px solid var(--or);
  color: var(--or);
  display: grid;
  place-items: center;
}
[data-theme="sombre"] .frise__embleme { background: var(--bleu-profond); color: var(--or-clair); }
.frise__embleme svg { width: 25px; height: 25px; display: block; }
.frise__periode {
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8a6b1c;
  display: block;
  margin-bottom: 0.2rem;
}
[data-theme="sombre"] .frise__periode { color: var(--or-clair); }
.frise__item h3 { font-size: 1.22rem; margin-bottom: 0.35rem; }
.frise__item p { font-size: 0.97rem; margin: 0; }

.a-renseigner {
  display: inline-block;
  align-self: flex-start;
  margin-top: 0.5rem;
  font-size: 0.78rem;
  padding: 0.25rem 0.6rem;
  border-radius: var(--rayon-s);
  background: rgba(201, 162, 39, 0.16);
  border: 1px dashed rgba(201, 162, 39, 0.6);
  color: #7d6119;
}
[data-theme="sombre"] .a-renseigner { color: var(--or-clair); }

/* La frise et la carte du fil conducteur se suivaient sans rien entre
   les deux : le bas de la derniere etape touchait le haut de la carte.
   La classe .biblio existait dans sophie.html mais n'avait aucune
   regle — elle en a une maintenant. */
.biblio { display: flex; flex-direction: column; gap: 3rem; }

/* ---------- Protocoles et jalons ----------

   Les deux protocoles de soin, et la genealogie de la pratique.
   Numerotation en chiffres dores : `counter` plutot que le marqueur
   natif de <ol>, parce qu'on veut pouvoir le colorer et le caler sans
   dependre de ::marker, dont le support reste inegal. */
.carte--protocole { align-self: stretch; }
.protocole__canal {
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--or-clair);
  margin-bottom: 0.9rem;
}
.protocole { list-style: none; counter-reset: etape; margin: 1.4rem 0 0; padding: 0; }
.protocole > li {
  counter-increment: etape;
  position: relative;
  padding-left: 2.2rem;
  padding-bottom: 1.1rem;
}
.protocole > li:last-child { padding-bottom: 0; }
.protocole > li::before {
  content: counter(etape, decimal-leading-zero);
  position: absolute;
  left: 0; top: 0.15em;
  font-family: var(--font-titre);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  color: var(--or);
  opacity: 0.85;
}
.protocole > li > p { margin: 0; font-size: 0.97rem; }
.protocole__fin {
  margin-top: 1.5rem;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(201, 162, 39, 0.28);
  font-size: 0.92rem;
  font-style: italic;
}

.jalons { list-style: none; margin: 1.3rem 0 0; padding: 0; }
.jalons__item { display: flex; gap: 1.2rem; padding-bottom: 1.2rem; }
.jalons__item:last-child { padding-bottom: 0; }
.jalons__annee {
  flex: none;
  width: 6.5rem;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--or-clair);
  padding-top: 0.18em;
}
.jalons__corps { flex: 1 1 auto; min-width: 0; }
.jalons__corps p { margin: 0; font-size: 0.97rem; }
.miroir__origine { margin-top: 2rem; }

/* Sous 640 px la colonne d'annees mange la largeur du texte :
   on repasse l'item en pile. */
@media (max-width: 640px) {
  .jalons__item { display: block; }
  .jalons__annee { width: auto; display: block; margin-bottom: 0.25rem; padding-top: 0; }
}

/* ---------- 13. Chaîne (émotions → créativité) ---------- */
.chaine { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; justify-content: center; margin-top: 1.5rem; }
.chaine__maillon {
  font-family: var(--font-titre);
  font-size: clamp(1rem, 2vw, 1.3rem);
  padding: 0.4rem 1.1rem 0.4rem 0.8rem;
  border-radius: 999px;
  border: 1px solid currentColor;
  opacity: 0.85;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
/* L'emblème hérite de `currentColor` : il prend la couleur du maillon
   et suit donc le thème de la section sans avoir à être redéclaré. */
.chaine__embleme {
  width: 1.35em;
  height: 1.35em;
  flex: none;
  display: block;
}
.chaine__embleme svg { width: 100%; height: 100%; display: block; }
.chaine__lien { opacity: 0.5; }

/* ---------- 14. Accordéon (FAQ) ---------- */
.accordeon { border-top: 1px solid rgba(20, 36, 61, 0.14); }
[data-theme="sombre"] .accordeon { border-top-color: rgba(157, 192, 232, 0.18); }
.accordeon details { border-bottom: 1px solid rgba(20, 36, 61, 0.14); }
[data-theme="sombre"] .accordeon details { border-bottom-color: rgba(157, 192, 232, 0.18); }
.accordeon summary {
  cursor: pointer;
  padding: 1.1rem 2.5rem 1.1rem 0;
  font-family: var(--font-titre);
  font-size: 1.2rem;
  position: relative;
  list-style: none;
}
.accordeon summary::-webkit-details-marker { display: none; }
.accordeon summary::after {
  content: "+";
  position: absolute;
  right: 0.4rem; top: 50%;
  transform: translateY(-50%);
  font-size: 1.5rem;
  color: var(--or);
  transition: transform var(--transition);
}
.accordeon details[open] summary::after { content: "–"; }
.accordeon details > p { padding: 0 0 1.3rem; max-width: var(--largeur-texte); font-size: 0.99rem; }

/* ---------- 15. Formulaire ---------- */
.formulaire { display: grid; gap: 1.1rem; max-width: 34rem; }
.champ { display: grid; gap: 0.4rem; }
.champ label { font-size: 0.9rem; font-weight: 600; }
.champ input, .champ textarea, .champ select {
  font: inherit;
  font-size: 1rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--rayon-s);
  border: 1px solid rgba(20, 36, 61, 0.22);
  background: rgba(255, 255, 255, 0.8);
  color: var(--encre);
}
[data-theme="sombre"] .champ input,
[data-theme="sombre"] .champ textarea,
[data-theme="sombre"] .champ select {
  background: rgba(157, 192, 232, 0.08);
  border-color: rgba(157, 192, 232, 0.28);
  color: var(--creme);
}
.champ textarea { min-height: 9rem; resize: vertical; }
.champ--case { grid-template-columns: auto 1fr; align-items: start; gap: 0.7rem; }
.champ--case input { width: 1.15rem; height: 1.15rem; margin-top: 0.3rem; padding: 0; }
.champ--case label { font-weight: 400; font-size: 0.9rem; }
.obligatoire { color: var(--or); }
.champ__aide { font-size: 0.85rem; }

/* Livre d'or : le piège à robots sort de l'écran et de l'arbre d'accessibilité. */
.pot-de-miel { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.formulaire button[type="submit"]:disabled { opacity: 0.6; cursor: wait; transform: none; }
.statut-formulaire:empty { display: none; }
.statut-formulaire {
  padding: 0.9rem 1.1rem;
  border-radius: var(--rayon-s);
  border: 1px solid rgba(157, 192, 232, 0.28);
  font-size: 0.95rem;
}
.statut-formulaire--succes { border-color: rgba(227, 200, 121, 0.6); background: rgba(227, 200, 121, 0.1); color: var(--or-pale); }
.statut-formulaire--erreur { border-color: rgba(230, 140, 120, 0.7); background: rgba(230, 140, 120, 0.1); }

/* Un masquage `hidden` ne doit jamais être écrasé par un display de section. */
[data-livre-dor-mur][hidden], [data-livre-dor-accueil][hidden] { display: none !important; }

.temoignages { display: grid; gap: 1.5rem; max-width: var(--largeur-lecture); margin-inline: auto; }
.temoignage {
  background: rgba(157, 192, 232, 0.06);
  border: 1px solid rgba(157, 192, 232, 0.16);
  border-left: 3px solid var(--or);
  border-radius: var(--rayon);
  padding: 1.5rem 1.6rem;
}
.temoignage__texte { margin: 0; }
.temoignage__texte p {
  margin: 0;
  font-family: var(--font-titre);
  font-size: clamp(1.15rem, 2.2vw, 1.35rem);
  font-style: italic;
  line-height: 1.5;
  white-space: pre-line; /* respecte les retours à la ligne du message */
}
/* Message long : replié sur 5 lignes tant qu'on n'a pas cliqué « Lire la suite ». */
.temoignage--replie .temoignage__texte p {
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.temoignage__suite {
  margin-top: 0.6rem;
  padding: 0.2rem 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 0.9rem;
  color: var(--or-clair);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.temoignage__suite:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
.temoignage__signature { margin: 1rem 0 0; font-size: 0.9rem; color: var(--or-clair); }
.temoignage__signature cite { font-style: normal; font-weight: 600; }

/* Accueil : des citations, pas des cartes — la page en compte déjà beaucoup. */
.avis-accueil { display: grid; gap: clamp(1.75rem, 4vw, 2.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.avis-accueil__item { margin: 0; text-align: center; }
.avis-accueil__item blockquote { margin: 0; }
.avis-accueil__item p {
  margin: 0;
  font-family: var(--font-titre);
  font-size: clamp(1.2rem, 2.4vw, 1.5rem);
  font-style: italic;
  line-height: 1.5;
  white-space: pre-line;
}
.avis-accueil__item figcaption { margin-top: 1rem; font-size: 0.9rem; font-weight: 600; letter-spacing: 0.04em; color: var(--or-clair); }

/* Le formulaire du livre d'or, replié par défaut. */
.depot-message > summary {
  cursor: pointer;
  font-family: var(--font-titre);
  font-size: clamp(1.2rem, 2.4vw, 1.5rem);
  color: var(--or-clair);
  list-style: none;
}
.depot-message > summary::-webkit-details-marker { display: none; }
.depot-message > summary::after { content: " +"; }
.depot-message[open] > summary::after { content: " –"; }
.depot-message > summary:focus-visible { outline: 2px solid var(--or); outline-offset: 4px; }

/* ---------- 16. Pied de page ----------

   Le pied prolonge le bleu, un cran plus profond que la fin de page.
   Un filet doré marque la limite sans rupture de couleur.

   Il NE prend PAS les 1800 px de la page. Deux blocs collés aux deux
   bords d'un écran large ne forment pas une composition, ils forment
   deux îlots séparés par un désert — c'était le défaut de la version
   précédente. Le pied se cale donc sur 78rem, centrés.
   ---------- */

.pied {
  position: relative;
  isolation: isolate;
  background: var(--g-footer);
  color: var(--texte-sombre-fond-attenue);
  border-top: 1px solid rgba(227, 200, 121, 0.28);
  padding-block: clamp(3rem, 7vw, 5rem) 2rem;
  font-size: 0.93rem;
}

/* Une lueur très basse, pour que le pied ne soit pas le seul aplat noir
   d'un site qui module sa profondeur partout ailleurs. */
.pied::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(60% 120% at 22% 0%, rgba(47, 107, 181, 0.16), transparent 68%);
}

.pied__conteneur {
  width: min(100% - clamp(2.5rem, 5vw, 5rem), 78rem);
  margin-inline: auto;
}

.pied__grille {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.2fr) max-content;
  gap: clamp(2rem, 5vw, 3.5rem);
  padding-bottom: 2.5rem;
  border-bottom: 1px solid rgba(169, 189, 214, 0.18);
}
@media (max-width: 940px) {
  .pied__grille { grid-template-columns: 1fr 1fr; }
  .pied__identite { grid-column: 1 / -1; }
}
@media (max-width: 620px) {
  .pied__grille { grid-template-columns: 1fr; gap: 2.25rem; }
}

/* ---- L'identité ---- */
.pied__marque {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.pied__sceau { width: 56px; height: 56px; flex: none; }
.pied__nom {
  font-family: var(--font-titre);
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--creme);
  margin: 0;
  line-height: 1.1;
}
.pied__baseline {
  font-family: var(--font-titre);
  font-style: italic;
  font-size: 1rem;
  color: var(--or-pale);
  margin: 0.25rem 0 0;
  line-height: 1.35;
}
.pied__mail {
  display: inline-block;
  margin-top: 1.4rem;
  font-size: 1rem;
  border-bottom: 1px solid rgba(227, 200, 121, 0.35);
  padding-bottom: 2px;
}

/* ---- Le cadre légal ---- */
.pied__cadre {
  border-left: 2px solid rgba(227, 200, 121, 0.35);
  padding-left: clamp(1rem, 2vw, 1.5rem);
}
.pied__cadre p { margin: 0; line-height: 1.65; }
.pied__cadre strong { color: var(--or-pale); font-weight: 600; }

/* ---- Les liens ---- */
.pied h4 {
  font-family: var(--font-texte);
  font-size: 0.76rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--or-clair);
  margin: 0 0 1rem;
}
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.pied a { color: var(--texte-sombre-fond-attenue); text-decoration: none; transition: color var(--transition); }
.pied a:hover { color: var(--or-clair); }

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.5rem;
  font-size: 0.83rem;
  opacity: 0.72;
}

.reseaux { display: flex; gap: 0.6rem; margin-top: 1.2rem; }
.reseaux a {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 1px solid rgba(169, 189, 214, 0.3);
  border-radius: 50%;
  transition: all var(--transition);
}
.reseaux a:hover { border-color: var(--or-clair); background: rgba(227, 200, 121, 0.12); }
.reseaux svg { width: 18px; height: 18px; }

/* ---------- 17. Bandeau de chantier ---------- */
.chantier {
  background: repeating-linear-gradient(45deg, rgba(201,162,39,.14) 0 10px, rgba(201,162,39,.06) 10px 20px);
  border: 1px dashed rgba(201, 162, 39, 0.6);
  border-radius: var(--rayon-s);
  padding: 1rem 1.2rem;
  font-size: 0.92rem;
}
.chantier strong { color: var(--or-clair); }
[data-theme="clair"] .chantier strong { color: #7d6119; }

/* ---------- 18. Divers ---------- */
/* La ligne qui referme une rangée de cartes et passe le relais.
   Centrée, à la mesure de lecture, détachée par un filet léger. */
.grille__conclusion {
  max-width: var(--largeur-lecture);
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid rgba(227, 200, 121, 0.22);
  text-align: center;
  font-family: var(--font-titre);
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  font-style: italic;
  color: var(--or-clair);
}

.centre { text-align: center; }
.mt-l { margin-top: 2.5rem; }
.mt-m { margin-top: 1.5rem; }


/* Section de bascule : la phrase à laquelle Sophie tient, lue de haut en bas,
   du bleu de l'émotion à l'or de sa transmutation. */
.section-transmutation {
  /* Fond bleu comme le reste. C'est le TEXTE qui bascule : la première
     phrase reste bleue, la seconde est en or. L'or n'apparaît qu'ici. */
  padding-block: clamp(4rem, 9vw, 7rem);
}
.section-transmutation .phrase-depart { color: var(--bleu-pale); }
.section-transmutation .phrase-arrivee { color: var(--or-clair); }
.section-transmutation p {
  font-family: var(--font-titre);
  font-size: clamp(1.3rem, 3.6vw, 2.2rem);
  line-height: 1.3;
  margin: 0;
}
.section-transmutation .fleche {
  width: 2px;
  height: clamp(54px, 10vw, 96px);
  margin: 1.4rem auto;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--bleu-vif), var(--or));
}

/* =========================================================
   19. Le hero illustré de l'accueil

   Une photographie de bibliothèque en fond, un sceau doré qui tourne
   par-dessus et fait respirer une lumière sur l'image.

   Contraintes tenues :
   - on n'anime que transform et opacity, les deux seules propriétés
     que le navigateur compose sans recalculer la mise en page ;
   - rotations très lentes (90 à 180 s) : au-delà, ça devient une roue
     de chargement et ça agite au lieu d'apaiser ;
   - tout s'arrête si la personne a demandé moins d'animations.
   ========================================================= */

/* NB : .hero--illustre ne porte pas .fondu — son fond, c'est la photo.
   La section ne déclare donc que --vers, que le voile utilise pour se
   raccorder à la section suivante. Pas de --de ici, il serait mort. */
.hero--illustre {
  isolation: isolate;
  padding-block: clamp(4.5rem, 13vw, 9rem);
}

.hero__photo {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.hero__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 58%;
}

/* Le voile : assez dense à gauche pour que le titre tienne, plus léger
   à droite pour laisser voir la bibliothèque. Il finit sur --vers pour
   se raccorder à la section suivante sans couture. */
.hero__voile {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(95deg,
      rgba(7, 13, 24, 0.92) 0%,
      rgba(7, 13, 24, 0.82) 34%,
      rgba(7, 13, 24, 0.34) 64%,
      rgba(7, 13, 24, 0.55) 100%),
    linear-gradient(180deg,
      rgba(7, 13, 24, 0.60) 0%,
      rgba(10, 20, 36, 0.26) 42%,
      var(--vers) 100%);
}

/* Le voile bleu — pour un hero à texte aligné à gauche.

   Trois couches, de la plus haute à la plus basse :

   1. le fondu du bas. C'est lui qui fait que la photo n'a pas de bord :
      elle se dissout dans la couleur de la section suivante. Sans lui,
      l'image s'arrête net sur une ligne droite et le raccord se voit.
   2. la lisibilité à gauche, où se trouve le texte. À droite le voile
      s'allège : on veut voir la bibliothèque.
   3. le filtre bleu, qui ramène la photo dans l'échelle du site. Une
      image, même bien choisie, n'a jamais exactement nos bleus.

   `transparent` est proscrit dans un dégradé : c'est rgba(0,0,0,0), et
   l'interpolation vers une couleur opaque passe par du gris. On écrit
   donc la même couleur avec une alpha nulle. */
.hero--voile-bleu .hero__voile {
  background-image:
    linear-gradient(180deg,
      rgb(from var(--g0) r g b / 0.45) 0%,
      rgb(from var(--g0) r g b / 0) 26%,
      rgb(from var(--vers) r g b / 0) 52%,
      rgb(from var(--vers) r g b / 0.72) 86%,
      var(--vers) 100%),
    linear-gradient(100deg,
      rgb(from var(--g0) r g b / 0.9) 0%,
      rgb(from var(--g0) r g b / 0.72) 32%,
      rgb(from var(--g0) r g b / 0.28) 66%,
      rgb(from var(--g0) r g b / 0.42) 100%),
    linear-gradient(0deg,
      rgb(from var(--bleu-vif) r g b / 0.3),
      rgb(from var(--bleu-vif) r g b / 0.3));
}

/* Variante sans le filtre bleu — pour une illustration déjà dans nos
   couleurs.

   Le troisième calque ci-dessus existe pour ramener une photo dans
   l'échelle du site : une image trouvée n'a jamais exactement nos
   bleus. Appliqué à un dessin qui les a déjà, il ne corrige rien et
   coûte cher — il éteint l'or. Sur le hero d'accompagnement, la lueur
   que la femme tient dans ses mains virait au gris.

   On garde les deux calques qui servent à quelque chose : le fondu du
   bas, qui dissout l'image dans la section suivante, et l'assombrissement
   de gauche, qui tient la lisibilité du titre. Et on allège la droite,
   puisqu'il n'y a rien à y masquer. */
.hero--voile-bleu.hero--sans-teinte .hero__voile {
  background-image:
    linear-gradient(180deg,
      rgb(from var(--g0) r g b / 0.45) 0%,
      rgb(from var(--g0) r g b / 0) 26%,
      rgb(from var(--vers) r g b / 0) 52%,
      rgb(from var(--vers) r g b / 0.72) 86%,
      var(--vers) 100%),
    linear-gradient(100deg,
      rgb(from var(--g0) r g b / 0.72) 0%,
      rgb(from var(--g0) r g b / 0.5) 32%,
      rgb(from var(--g0) r g b / 0.12) 66%,
      rgb(from var(--g0) r g b / 0.2) 100%);
}

/* ---- La note de lecture des articles ----

   Un encadré discret en tête d'article : il dit d'où parle le texte
   avant qu'on le lise, pas après. Filet doré à gauche plutôt qu'un
   cadre complet — c'est une note, pas un avertissement. */
.note-lecture {
  border-left: 2px solid var(--or);
  padding: 0.1rem 0 0.1rem 1.1rem;
  margin: 0 0 2.2rem;
  max-width: 44rem;
}
.note-lecture__titre {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--or-clair);
  margin-bottom: 0.35rem;
}
.note-lecture p {
  margin: 0;
  font-size: 0.93rem;
  line-height: 1.65;
  color: var(--texte-sombre-fond-attenue);
}
[data-theme="clair"] .note-lecture__titre { color: #7d6119; }
[data-theme="clair"] .note-lecture p { color: var(--texte-clair-fond-attenue); }

/* ---- Les passages à trancher ----

   Marquage de travail, pas de design : il sert à montrer un texte à
   Sophie et à décider ensemble. Tout porte la classe `a-trancher`, donc
   le jour où c'est réglé, un seul mot à chercher pour tout retirer —
   le marquage et son motif.

   Ambre et non rouge : ce ne sont pas des erreurs, ce sont des
   questions. */
mark.a-trancher {
  background: rgba(227, 160, 60, 0.22);
  color: inherit;
  box-shadow: 0 0 0 2px rgba(227, 160, 60, 0.22);
  border-radius: 2px;
}
.a-trancher__motif {
  margin: 0.7rem 0 1.3rem;
  padding: 0.7rem 0.95rem;
  border-left: 3px solid rgba(227, 160, 60, 0.75);
  background: rgba(227, 160, 60, 0.08);
  border-radius: 0 4px 4px 0;
  font-size: 0.87rem;
  line-height: 1.6;
  color: var(--texte-sombre-fond-attenue);
}
.a-trancher__motif strong {
  color: #e8a83c;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.74rem;
}
/* Le bandeau « en construction » du pied. */
.pied__chantier {
  margin: 0 0 1.1rem;
  padding: 0.55rem 0.9rem;
  border: 1px dashed rgba(227, 160, 60, 0.45);
  border-radius: 4px;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--texte-sombre-fond-attenue);
}
.pied__chantier strong { color: #e8a83c; }

/* ---- Le sceau ---- */
.sceau-bloc {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  width: min(100%, 30rem);
  margin-inline: auto;
}

/* La lumière que le sceau diffuse sur la bibliothèque. */
.sceau-bloc::before {
  content: "";
  position: absolute;
  inset: -6%;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(227, 200, 121, 0.34) 0%,
    rgba(201, 162, 39, 0.20) 34%,
    rgba(201, 162, 39, 0.08) 56%,
    transparent 72%);
  animation: sceau-respire 11s ease-in-out infinite;
}

.sceau { width: 100%; height: auto; display: block; position: relative; }

/* En SVG, il faut dire explicitement autour de quel point on tourne :
   transform-box: view-box cale l'origine sur le repère du viewBox. */
.sceau > g {
  transform-box: view-box;
  transform-origin: 200px 200px;
}
.sceau__graduations { animation: sceau-tourne 150s linear infinite; }
.sceau__etapes      { animation: sceau-tourne 100s linear infinite reverse; }
.sceau__interieur   { animation: sceau-tourne 200s linear infinite; }
.sceau__coeur       { animation: sceau-pulse 11s ease-in-out infinite; }

@keyframes sceau-tourne { to { transform: rotate(360deg); } }
@keyframes sceau-respire {
  0%, 100% { opacity: 0.5; transform: scale(0.97); }
  50%      { opacity: 1;   transform: scale(1.05); }
}
@keyframes sceau-pulse {
  0%, 100% { opacity: 0.86; }
  50%      { opacity: 1; }
}

/* Repos complet pour qui a demandé moins d'animations. */
@media (prefers-reduced-motion: reduce) {
  .sceau > g,
  .sceau-bloc::before { animation: none !important; }
  .sceau-bloc::before { opacity: 0.8; transform: none; }
}

@media (max-width: 900px) {
  .sceau-bloc { width: min(78%, 22rem); }
  .hero__voile {
    background-image:
      linear-gradient(180deg,
        rgba(7, 13, 24, 0.62) 0%,
        rgba(7, 13, 24, 0.90) 42%,
        var(--vers) 100%);
  }

  /* Sur un écran étroit, le texte ne passe plus à côté de l'image : il
     passe dessus. Le voile doit donc changer de sens — un dégradé
     horizontal ne protège plus rien quand la colonne de texte fait
     toute la largeur.

     La règle générique juste au-dessus fait exactement cela, mais elle
     ne s'applique pas ici : `.hero--voile-bleu.hero--sans-teinte` la
     bat en spécificité. Il faut donc la redire. Un peu plus douce,
     parce qu'on veut garder la lueur visible sous le texte. */
  .hero--voile-bleu.hero--sans-teinte .hero__voile {
    background-image:
      linear-gradient(180deg,
        rgb(from var(--g0) r g b / 0.58) 0%,
        rgb(from var(--g0) r g b / 0.82) 46%,
        rgb(from var(--g0) r g b / 0.78) 70%,
        var(--vers) 100%);
  }
}

/* ---- La composition centrée du hero de l'accueil ----

   Deux autres compositions ont été essayées et écartées le 16/09 :
   le sceau à gauche avec le texte à droite (le sceau gagnait, l'image
   perdait), et l'image retournée en miroir (le livre ouvert se
   retrouvait dans le coin le plus sombre). Voir le README. */

/* Le sceau est le pivot : trois lignes au-dessus, le texte et les boutons
   en dessous. Tout doit tenir dans une hauteur d'écran, d'où le padding
   haut réduit et un sceau plus petit qu'ailleurs. */
/* La flèche de descente. Ce n'est pas un bouton : elle ne promet rien,
   elle signale qu'il y a une suite. */
.hero__descente {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: clamp(1.75rem, 4vw, 2.75rem) auto 0;
  border-radius: 50%;
  color: var(--or-clair);
  border: 1px solid rgba(227, 200, 121, 0.3);
  transition: border-color var(--transition), transform var(--transition),
              background var(--transition);
  animation: descente-respire 3.2s ease-in-out infinite;
}
.hero__descente svg { width: 1.4rem; height: 1.4rem; }
.hero__descente:hover {
  border-color: var(--or);
  background: rgba(201, 162, 39, 0.12);
}
@keyframes descente-respire {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__descente { animation: none; }
}

.hero--centre { padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(3rem, 6vw, 5rem); }
.hero__pile { text-align: center; }
.hero__pile .hero__titre { margin-bottom: 0.25em; }
.hero__pile .hero__baseline { margin-bottom: 0; }
.hero__pile .hero__texte,
.hero__pile .hero__baseline { margin-inline: auto; max-width: 42rem; }
.hero__pile .groupe-boutons { justify-content: center; }
.hero__pile .sceau-bloc { width: min(72vw, 19rem); margin-block: clamp(0.5rem, 2vw, 1.5rem); }
.hero--centre .hero__voile {
  /* Le voile est fait de --g0 à différentes opacités. Écrire
     rgba(7,13,24,…) en dur, c'était recopier --g0 cinq fois : le jour
     où on retouche l'échelle bleue, le voile ne suit pas.
     rgb(from …) lit le jeton et n'en change que l'alpha. La première
     déclaration reste en repli pour les navigateurs d'avant 2023. */
  background-image:
    linear-gradient(180deg,
      rgba(7, 13, 24, 0.88) 0%,
      rgba(7, 13, 24, 0.40) 34%,
      rgba(7, 13, 24, 0.55) 62%,
      var(--vers) 100%);
  background-image:
    linear-gradient(180deg,
      rgb(from var(--g0) r g b / 0.88) 0%,
      rgb(from var(--g0) r g b / 0.40) 34%,
      rgb(from var(--g0) r g b / 0.55) 62%,
      var(--vers) 100%);
}


/* =========================================================
   20. Le sommaire de page (nav de niveau 2)

   Une barre d'ancres qui se colle sous l'en-tête et suit la lecture.
   Posée sur les pages longues à sections nommées — Accompagnement et
   sa FAQ, pour commencer.

   Elle se construit toute seule depuis le DOM : toute <section> qui
   porte un id et un data-sommaire="Libellé court" y apparaît. Rien à
   maintenir en double, donc rien qui puisse se désynchroniser.

   Le top du sticky vaut --h-entete, mesurée en JS : la hauteur de
   l'en-tête change avec la largeur (la baseline disparaît sous 560 px)
   et une valeur en dur laisserait un trou ou un recouvrement.
   ========================================================= */

/* Tant que le JS n'a rien construit, l'hôte est vide : on ne montre
   pas une barre dorée qui ne contient rien. */
.sommaire:empty { display: none; }

.sommaire {
  position: sticky;
  top: var(--h-entete, 72px);
  z-index: 90;
  background: rgba(7, 13, 24, 0.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(157, 192, 232, 0.14);
}
.sommaire ol {
  display: flex;
  gap: 0.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
  /* Sur petit écran la barre défile au doigt plutôt que de passer à la
     ligne : une barre d'ancres sur trois lignes mange l'écran. */
  overflow-x: auto;
  scrollbar-width: none;
}
.sommaire ol::-webkit-scrollbar { display: none; }

.sommaire a {
  display: block;
  white-space: nowrap;
  padding: 0.85rem 0.9rem;
  font-size: 0.88rem;
  text-decoration: none;
  color: var(--texte-sombre-fond-attenue);
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.sommaire a:hover { color: var(--creme); }
.sommaire a[aria-current="true"] {
  color: var(--or-clair);
  border-bottom-color: var(--or);
}

/* Une ancre visée par le sommaire ne doit pas se caler sous les deux
   barres collantes : on réserve leur hauteur au-dessus de chaque cible. */
[data-sommaire] { scroll-margin-top: calc(var(--h-entete, 72px) + 3.5rem); }

/* Toute section qu'on peut viser par une ancre doit s'arrêter SOUS
   l'en-tête collante, sinon son titre se gare derrière. */
section[id] { scroll-margin-top: calc(var(--h-entete, 72px) + 1rem); }

/* =========================================================
   21. La bande défilante

   Une grille `auto-fit` fait ce qu'on lui demande : quand les cartes ne
   tiennent plus sur une ligne, elle les replie sur la suivante. À
   1000 px, un rayon de quatre cartes devient donc deux rangées de deux,
   et à 700 px quatre cartes empilées — quatre écrans de défilement pour
   un seul rayon, sans que rien n'indique que les autres existent.

   Ici les cartes restent sur une ligne, quoi qu'il arrive, et la ligne
   défile. La largeur est fixe (`flex-basis`), donc dès qu'une carte de
   plus qu'il n'en tient est présente, la suivante dépasse du bord : ce
   fragment est toute l'information dont on a besoin pour comprendre
   qu'on peut pousser vers la droite. Un bouton « suivant » ou des
   points de pagination diraient la même chose en prenant de la place.

   Quand tout tient — quatre cartes sur un grand écran — il n'y a pas
   de débordement, donc pas de défilement, et la bande ne se distingue
   pas d'une grille ordinaire.

   `overflow-x: auto` impose `overflow-y: auto` : le survol qui soulève
   la carte de 4 px serait rogné en haut. D'où le rembourrage vertical.
   ========================================================= */

.grille--defilante {
  display: flex;
  gap: 1.5rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-block: 0.5rem 1.25rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(227, 200, 121, 0.45) transparent;
  /* Pas de débord jusqu'aux bords de l'écran : un margin négatif en vw
     rouvrirait la barre de défilement horizontale de la page. */
}
.grille--defilante > * {
  flex: 0 0 min(85%, 21rem);
  scroll-snap-align: start;
}
.grille--defilante::-webkit-scrollbar { height: 6px; }
.grille--defilante::-webkit-scrollbar-thumb {
  background: rgba(227, 200, 121, 0.45);
  border-radius: 999px;
}
.grille--defilante::-webkit-scrollbar-track { background: transparent; }

/* =========================================================
   22. Cartes cliquables et cartes d'action

   Deux façons de se passer d'un bouton.

   .carte--lien : toute la carte est cliquable. Le lien reste posé sur
   le titre — donc annoncé correctement par un lecteur d'écran et par
   la navigation au clavier — mais son ::after s'étire sur la carte
   entière, qui devient la zone de clic. Pas de bouton en pied de
   carte, pas de deuxième cible pour la même destination.

   .carte-action : une carte large, à la place d'un bouton centré seul
   en fin de section. Elle peut porter une phrase, ce qu'un bouton ne
   peut pas faire.
   ========================================================= */

.carte--lien { position: relative; }
.carte--lien h3 a,
.carte--lien h4 a { text-decoration: none; }
.carte--lien h3 a::after,
.carte--lien h4 a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
/* L'anneau de focus doit entourer la carte, pas seulement le titre. */
.carte--lien:focus-within {
  outline: 2px solid var(--or-clair);
  outline-offset: 3px;
}
.carte--lien:focus-within h3 a:focus-visible,
.carte--lien:focus-within h4 a:focus-visible { outline: none; }

.carte__suite {
  margin-top: auto;
  align-self: flex-start;
  padding-top: 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--or-clair);
}
.carte__suite::after {
  content: "→";
  transition: transform var(--transition);
}
.carte--lien:hover .carte__suite::after { transform: translateX(4px); }

.carte-action {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
  position: relative;
  padding: clamp(1.4rem, 3vw, 2rem);
  border-radius: var(--rayon);
  border: 1px solid rgba(227, 200, 121, 0.3);
  background:
    linear-gradient(120deg, rgba(201, 162, 39, 0.10), rgba(157, 192, 232, 0.05));
  text-decoration: none;
  transition: transform var(--transition), border-color var(--transition),
              background var(--transition);
}
.carte-action:hover {
  transform: translateY(-3px);
  border-color: rgba(227, 200, 121, 0.6);
}
/* Variante avec emblème : trois colonnes au lieu de deux. Sans cette
   règle, le troisième enfant passerait à la ligne — la grille n'en
   déclare que deux. */
.carte-action--embleme { grid-template-columns: auto 1fr auto; }
.carte-action__embleme {
  width: clamp(2.75rem, 7vw, 3.75rem);
  aspect-ratio: 1;
  flex: none;
}
.carte-action__embleme svg { width: 100%; height: 100%; display: block; overflow: visible; }
/* Sur un écran étroit, l'emblème passe au-dessus du texte plutôt que de
   lui prendre la moitié de la largeur. */
@media (max-width: 34rem) {
  .carte-action--embleme { grid-template-columns: 1fr auto; }
  .carte-action__embleme { grid-column: 1 / -1; }
}

.carte-action h3 { margin: 0 0 0.25rem; color: var(--or-pale); }
.carte-action p { margin: 0; color: var(--texte-sombre-fond-attenue); font-size: 0.97rem; }
.carte-action__fleche {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(227, 200, 121, 0.45);
  color: var(--or-clair);
  font-size: 1.1rem;
  flex: none;
  transition: transform var(--transition), background var(--transition);
}
.carte-action:hover .carte-action__fleche {
  transform: translateX(4px);
  background: rgba(201, 162, 39, 0.16);
}
@media (max-width: 560px) {
  .carte-action { grid-template-columns: 1fr; gap: 1rem; }
  .carte-action__fleche { justify-self: start; }
}

/* =========================================================
   23. Sans JavaScript

   L'en-tête, le pied et une partie du contenu sont injectés en JS.
   Sans script, la page perd sa navigation : il faut au minimum que
   les liens restent atteignables. Ce bloc n'existe que pour ça.
   ========================================================= */

.avertissement-js {
  background: rgba(201, 162, 39, 0.14);
  border-bottom: 1px solid rgba(227, 200, 121, 0.5);
  color: var(--texte-sombre-fond);
  padding: 1rem clamp(1.25rem, 4vw, 2.5rem);
  font-size: 0.95rem;
  line-height: 1.7;
}
.avertissement-js strong { color: var(--or-clair); }
.avertissement-js a { color: var(--or-clair); }

/* =========================================================
   24. La Médiathèque

   Trois rayons — Lire, Écouter, Pratiquer. Rangés par geste, parce
   que ranger par prix serait commercial et ranger par format ne dit
   rien de ce qu'on vient chercher.

   Le filtre « accès libre » se fait en CSS, par un attribut sur la
   section : rien n'est retiré du DOM, donc rien à reconstruire, et
   l'état du bouton (aria-pressed) suffit à l'annoncer.
   ========================================================= */

.filtres { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.75rem; }

.filtre {
  font-family: var(--font-texte);
  font-size: 0.88rem;
  font-weight: 600;
  padding: 0.6rem 1.15rem;
  border-radius: 999px;
  border: 1px solid rgba(227, 200, 121, 0.35);
  background: transparent;
  color: var(--texte-sombre-fond-attenue);
  cursor: pointer;
  transition: color var(--transition), background var(--transition),
              border-color var(--transition);
}
.filtre:hover { color: var(--creme); border-color: rgba(227, 200, 121, 0.6); }
.filtre[aria-pressed="true"] {
  background: rgba(201, 162, 39, 0.18);
  border-color: var(--or);
  color: var(--or-pale);
}

.rayon[data-filtre="libre"] .carte[data-acces="payant"] { display: none; }

/* Une carte qui ouvre une fiche plutôt que d'emmener ailleurs.

   C'est un <button> et non un lien : il n'y a pas de destination, il y
   a une fiche qui s'ouvre sur place. Un lecteur d'écran a besoin de la
   différence, et le clavier aussi — un lien répond à Entrée, un bouton
   à Entrée et à Espace.

   Un bouton n'hérite ni de la police, ni de la couleur, ni de
   l'alignement du texte : tout est à remettre. */
.carte--ouvrante {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  width: 100%;
}
.carte--ouvrante .carte__titre {
  font-family: var(--font-titre);
  font-size: 1.3rem;
  line-height: 1.25;
  color: var(--creme);
}
.carte--ouvrante:hover .carte__titre { color: var(--or-pale); }
.carte--ouvrante:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
/* La couverture est un objet posé sur la carte, pas une image dans un
   cadre.

   Le cadre pleine largeur a été essayé : une couverture est en portrait,
   une carte est large, et il restait de chaque côté deux bandes vides
   qu'il fallait ensuite remplir — zoom flouté, teinte dominante, voile.
   Chaque remplissage crée son propre problème : sur les trois couvertures
   des Éditions du Net, qui sont blanches, un fond flouté vire au gris et
   rend la carte plus terne qu'un aplat bleu nuit.

   Sans cadre, il n'y a plus de bandes à remplir. La couverture a sa
   propre largeur, une ombre portée la décolle du fond, et la carte
   garde son bleu : les couleurs à l'écran appartiennent aux livres et
   non à l'interface. C'est aussi moins de code.

   `max-width: 100%` pour les visuels en paysage — les repères des
   parcours font 960 × 600 et déborderaient de la carte. */
.carte__visuel {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.1rem;
}
/* La couverture cède un peu de place à l'étiquette plutôt que de passer
   dessous — mais pas toute : sous 5,5rem une couverture n'est plus
   lisible. Au-delà, c'est à l'étiquette de se replier sur deux lignes.
   Le vocabulaire des genres est court pour que ça n'arrive presque
   jamais. */
.carte__visuel .carte__media { flex: 0 1 auto; min-width: 5.5rem; }
.carte__visuel .etiquette {
  flex: 0 1 auto;
  text-align: center;
  white-space: normal;
}

.carte__visuel .carte__media {
  display: flex;
  aspect-ratio: auto;
  height: auto;
  margin: 0;
  background: transparent;
  border-radius: 0;
  overflow: visible;
}
/* La boîte épouse l'image, elle ne l'encadre pas : à hauteur fixe, un
   visuel en paysage était centré dans une boîte de 180 px et l'ombre
   portée dessinait un rectangle vide autour de lui. */
.carte__visuel .carte__media img {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 180px;
  border-radius: 2px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.4);
}

/* =========================================================
   Les étagères décoratives

   Un filet doré, une rangée de tranches de livres posées dessus. Le
   décor est dans le flux de la section, à l'intérieur : posé entre
   deux sections il aurait son propre fond et couperait le dégradé qui
   les raccorde.

   `overflow: hidden` sur la rangée : le nombre de tranches est fixe,
   donc sur un écran étroit les dernières sortent — elles sont coupées
   proprement au lieu d'élargir la page.
   ========================================================= */

.etagere-deco {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  opacity: 0.75;
}
.etagere-deco__rangee {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 46px;
  overflow: hidden;
  /* Les tranches s'éteignent aux deux bouts, comme le filet en dessous :
     sinon la rangée se termine par une coupe franche au milieu de nulle
     part, là où la largeur de l'écran est tombée. */
  mask-image: linear-gradient(90deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
}
.etagere-deco__vide { flex: 0 0 var(--l, 10px); }
.etagere-deco__livre {
  flex: 0 0 var(--l, 12px);
  height: var(--h, 70%);
  border-radius: 2px 2px 0 0;
  background: rgb(from var(--bleu-pale) r g b / var(--o, 0.4));
  background-image: linear-gradient(100deg,
    rgba(255, 255, 255, 0.16) 0 18%,
    transparent 18% 82%,
    rgba(0, 0, 0, 0.28) 82% 100%);
}
.etagere-deco__livre--or { background-color: rgb(from var(--or) r g b / var(--o, 0.4)); }
.etagere-deco__filet {
  height: 1px;
  background: linear-gradient(90deg,
    rgb(from var(--or) r g b / 0) 0%,
    rgb(from var(--or) r g b / 0.55) 12%,
    rgb(from var(--or) r g b / 0.55) 88%,
    rgb(from var(--or) r g b / 0) 100%);
  box-shadow: 0 1px 10px rgb(from var(--or) r g b / 0.2);
}

/* =========================================================
   Le vocabulaire

   Les cartes ne portent que le mot. C'est une planche de contact et
   non une page de dictionnaire : on balaie, on s'arrête sur celui
   qu'on ne connaît pas, on l'ouvre. Mettre un extrait de définition
   sous chaque mot rendrait la planche illisible et ferait double
   emploi avec la fiche.

   Ce sont des <button> et non des cartes cliquables : ils n'emmènent
   nulle part, ils ouvrent quelque chose sur place. Le clavier et les
   lecteurs d'écran ont besoin de cette distinction.
   ========================================================= */

.mots { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.mot {
  font-family: var(--font-titre);
  font-size: 1.12rem;
  padding: 0.7rem 1.3rem;
  border-radius: 999px;
  border: 1px solid rgba(157, 192, 232, 0.22);
  background: rgba(157, 192, 232, 0.06);
  color: var(--creme);
  cursor: pointer;
  text-align: left;
  transition: color var(--transition), background var(--transition),
              border-color var(--transition), transform var(--transition);
}
.mot:hover {
  transform: translateY(-2px);
  border-color: rgba(227, 200, 121, 0.55);
  color: var(--or-pale);
}
.mot:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }

/* La fiche de définition.

   <dialog> apporte le piège au clavier, la fermeture par Échap, le
   fond inerte et le fond assombri. Reste à l'habiller — et à ne pas
   oublier que ::backdrop est un pseudo-élément à part, qui n'hérite
   de rien. */
.fiche {
  width: min(36rem, calc(100vw - 2.5rem));
  max-height: min(88vh, 54rem);
  padding: 0;
  border: 1px solid rgba(227, 200, 121, 0.28);
  border-radius: var(--rayon);
  background: #0e1c31;
  color: var(--creme);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
  overflow: visible;
}
.fiche::backdrop { background: rgba(4, 8, 16, 0.72); }
.fiche__corps {
  padding: 2.1rem 2.1rem 2.3rem;
  overflow-y: auto;
  max-height: inherit;
  /* La barre de défilement par défaut est claire : sur un fond bleu
     nuit, c'est un ruban blanc collé au bord de la fiche. On la reprend
     dans les couleurs de la maison, fine, sans rail. */
  scrollbar-width: thin;
  scrollbar-color: rgba(227, 200, 121, 0.38) transparent;
}
.fiche__corps::-webkit-scrollbar { width: 8px; }
.fiche__corps::-webkit-scrollbar-track { background: transparent; }
.fiche__corps::-webkit-scrollbar-thumb {
  background: rgba(227, 200, 121, 0.38);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
.fiche__corps:hover::-webkit-scrollbar-thumb { background: rgba(227, 200, 121, 0.6); background-clip: content-box; }

/* La fiche d'une œuvre : plus large, et en deux colonnes dès qu'il y a
   la place. La couverture à gauche, le texte à droite — ce qui raccourcit
   la colonne de texte d'autant, et supprime le défilement dans la
   plupart des cas au lieu de l'habiller. */
/* La mention de pied quand elle telecharge vraiment.

   `position: relative` la sort du plan du ::after qui rend toute la
   carte cliquable : sans ca, le clic serait capte par le titre et
   ouvrirait l'apercu au lieu de telecharger. C'est la seule facon de
   faire cohabiter une carte entierement cliquable et une action a
   part dedans. */
.carte__suite--action {
  position: relative;
  z-index: 2;
  align-self: flex-start;
  text-decoration: none;
  border-bottom: 1px solid rgba(227, 200, 121, 0.35);
  transition: color var(--transition), border-color var(--transition);
}
.carte__suite--action:hover,
.carte__suite--action:focus-visible {
  color: var(--or-pale);
  border-bottom-color: var(--or-clair);
}

.fiche--large { width: min(52rem, calc(100vw - 3rem)); }

.fiche__colonnes { display: grid; gap: 1.6rem; }
@media (min-width: 46rem) {
  .fiche__colonnes {
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: 2.2rem;
    align-items: start;
  }
}
/* Le rythme de la colonne de texte, écrit élément par élément plutôt
   qu'avec un espacement unique : l'étiquette, le titre et le sous-titre
   forment un seul bloc — ils se répondent — et le corps du texte se
   détache. Un `* + *` uniforme les mettait tous à la même distance, ce
   qui revient à dire qu'ils ont tous le même lien entre eux. */
.fiche__texte > * { margin: 0; }
.fiche__texte > * + * { margin-top: 1rem; }
.fiche__texte > .etiquette + h3 { margin-top: 0.8rem; }
.fiche__texte > h3 + .fiche__sous-titre { margin-top: 0.25rem; }
.fiche__texte .etiquette { align-self: start; }
.fiche__corps h3 {
  margin: 0 0 1rem;
  font-size: clamp(1.45rem, 3.4vw, 1.9rem);
  line-height: 1.15;
  color: var(--or-pale);
  padding-right: 2.5rem;
}
.fiche__corps h3:focus { outline: none; }
.fiche__corps p { margin: 0; color: var(--texte-sombre-fond); }

.fiche__fermer-forme { margin: 0; }
.fiche__fermer {
  position: absolute;
  top: 0.9rem; right: 0.9rem;
  width: 2.2rem; height: 2.2rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(157, 192, 232, 0.22);
  border-radius: 50%;
  background: transparent;
  color: var(--texte-sombre-fond-attenue);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}
.fiche__fermer:hover { color: var(--or-pale); border-color: rgba(227, 200, 121, 0.55); }
.fiche__fermer svg { width: 1rem; height: 1rem; }

.fiche__media { display: flex; justify-content: flex-start; }
.fiche__media img {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 17rem;
  border-radius: 2px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.6), 0 2px 8px rgba(0, 0, 0, 0.45);
}
@media (max-width: 45.99rem) {
  .fiche__media img { max-height: 12rem; }
}

.fiche__sous-titre {
  font-style: italic;
  color: var(--texte-sombre-fond-attenue);
}
/* Les faits sont d'une autre nature que la description : un filet les
   sépare au lieu d'un simple blanc, qui les aurait fait lire comme la
   suite du paragraphe. */
.fiche__texte .fiche__faits {
  margin-top: 1.4rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(157, 192, 232, 0.14);
}
/* La barre d'action colle en bas du corps qui défile.

   Une fiche de livre dépasse souvent la hauteur disponible : sans ça,
   le prix et le bouton se trouvent sous la ligne de flottaison de la
   fiche, et rien ne dit qu'ils existent. Collés, ils sont toujours là,
   et le texte défile derrière. */
.fiche__actions {
  position: sticky;
  bottom: -2.3rem;
  margin: 1.7rem -2.1rem -2.3rem;
  padding: 1.1rem 2.1rem 1.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.2rem;
  background: linear-gradient(180deg, rgb(14 28 49 / 0) 0%, #0e1c31 42%);
  border-radius: 0 0 var(--rayon) var(--rayon);
}
.fiche__lien-discret {
  display: inline-block;
  margin-top: 1.2rem;
  font-size: 0.88rem;
  color: var(--texte-sombre-fond-attenue);
}
.fiche__lien-discret:hover { color: var(--or-pale); }

/* Sur un écran étroit, le bouton prend toute la largeur restante :
   « Commander chez l'éditeur » se cassait en deux lignes et la barre
   collante finissait par occuper le tiers de la fiche. */
@media (max-width: 30rem) {
  .fiche__actions { gap: 0.8rem; }
  .fiche__actions .bouton { flex: 1 1 auto; text-align: center; padding-inline: 1rem; }
}

.fiche__voir-aussi { margin-top: 1.6rem; padding-top: 1.1rem; border-top: 1px solid rgba(157, 192, 232, 0.16); }
.fiche__voir-aussi ul { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.fiche__renvoi {
  font-family: var(--font-texte);
  font-size: 0.88rem;
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  border: 1px solid rgba(157, 192, 232, 0.22);
  background: transparent;
  color: var(--bleu-pale);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}
.fiche__renvoi:hover { color: var(--or-pale); border-color: rgba(227, 200, 121, 0.55); }

/* Le lecteur audio.

   Le contrôle natif, pas un lecteur maison : il apporte le clavier, le
   défilement, la vitesse de lecture, l'affichage sur l'écran verrouillé
   du téléphone et la reprise après un appel. Tout ça est déjà écrit et
   mieux écrit qu'on ne le referait.

   On ne peut pas le repeindre — chaque navigateur dessine le sien dans
   un DOM fantôme fermé. Le seul levier propre est `color-scheme: dark` :
   le navigateur rend alors sa propre variante sombre du contrôle, au
   lieu du gris clair par défaut qui tranchait sur le bleu nuit. C'est
   mieux qu'un `filter: invert`, qui retourne aussi les couleurs et ment
   sur l'état des icônes. */
.carte--audio .lecteur {
  display: block;
  width: 100%;
  height: 40px;
  margin-bottom: 0.9rem;
  color-scheme: dark;
}

/* Le téléchargement est un service, pas une invitation : il se tient au
   bout de la ligne d'informations, discret, et ne concurrence pas le
   bouton de lecture. */
.media__telecharger {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--texte-sombre-fond-attenue);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.media__telecharger:hover { color: var(--or-pale); }

/* Pastille d'accès : dorée quand c'est libre — sur ce site, l'or
   marque ce qui compte, et le gratuit est la porte d'entrée. */
.pastille-acces {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  white-space: nowrap;
}
.pastille-acces--libre {
  background: rgba(201, 162, 39, 0.18);
  border: 1px solid rgba(227, 200, 121, 0.45);
  color: var(--or-pale);
}
.pastille-acces--payant {
  background: rgba(157, 192, 232, 0.12);
  border: 1px solid rgba(157, 192, 232, 0.3);
  color: var(--texte-sombre-fond-attenue);
}

.media__ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
.media__detail { font-size: 0.85rem; color: var(--texte-sombre-fond-attenue); }
/* Le prix est un détail comme les autres par la taille, mais il se
   lit en premier dans la ligne : c'est la seule information qu'on
   vient y chercher sans l'avoir cherchée. */
.media__prix { color: var(--or-pale); font-weight: 600; }
.media__sous-titre {
  font-family: var(--font-titre);
  font-style: italic;
  color: var(--or-pale);
  margin-bottom: 0.4rem;
}

/* =========================================================
   25. Le miroir d'eau

   Trois parts, une surface. Au-dessus ce qui s'exprime, au-dessous ce
   qui se tait — et l'état final est le reflet exact de l'état initial
   autour de la ligne d'eau.

   Cinq rangs, la surface au 3. Une figure ne change que de rang ; sa
   position vient d'ici. C'est ce qui rend l'animation gratuite : il n'y
   aura rien à reconstruire, juste un `top` qui glisse.

       rang 1  ░░  l'air, tout en haut
       rang 2  ░░  l'air, juste au-dessus
       rang 3  ──  LA SURFACE — le seuil, l'axe du reflet
       rang 4  ▓▓  sous l'eau
       rang 5  ▓▓  le fond

   La ligne d'eau est un élément CSS et pas un <line> SVG : un trait
   sans épaisseur a une boîte englobante plate, donc un dégradé en
   objectBoundingBox y est dégénéré et n'est jamais peint. C'est le bug
   qui rendait l'ancienne ligne de flottaison invisible.
   ========================================================= */

/* Trois enfants : la scène, les commandes, le panneau de texte.
   Sur mobile, l'ordre du DOM suffit — scène, commandes, texte.
   Au-dessus de 900px, la grille remet le texte au-dessus des
   commandes dans la colonne de droite. */
.miroir {
  display: grid;
  gap: 1.25rem;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  /* Le repli si le JavaScript ne tourne pas — assez pour deux lignes.
     Il est déclaré ici et non sur la scène : posé sur la scène, il
     écrasait par héritage la valeur mesurée que le JS pose sur
     `.miroir`, et la scène restait à 4rem quoi qu'il arrive. */
  --pas: 4rem;
}
/* Sur grand écran, la colonne de droite se cale sur la ligne d'eau.

   La ligne d'eau est à 2,5 pas du haut de la scène — c'est la
   définition même de la scène, cinq rangs de part et d'autre du
   troisième. On donne donc cette hauteur exacte à la première rangée
   de la grille : le texte s'aligne sur son bas, les jalons et les
   boutons commencent sur son haut. Les trois tirets se retrouvent
   pile à la hauteur de l'horizon, ce qui est tout l'intérêt — ils
   disent la même chose que la scène, au même niveau.

   `minmax(…, auto)` et non une hauteur figée : si un jour le texte du
   panneau s'allonge, la rangée grandit au lieu de déborder par le
   haut. L'alignement se décale un peu, la page ne casse pas. */
@media (min-width: 56.25rem) {
  .miroir {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(calc(var(--pas, 4rem) * 2.5), auto) auto;
    column-gap: clamp(2rem, 5vw, 4rem);
    row-gap: 0;
    align-items: start;
  }
  .miroir__scene     { grid-column: 1; grid-row: 1 / 3; }
  .miroir__panneau   { grid-column: 2; grid-row: 1; align-self: end; }
  .miroir__commandes { grid-column: 2; grid-row: 2; align-self: start; }

  /* Le texte et les commandes partagent le même bloc centré : centrer
     les boutons dans la colonne les décalerait du texte, qui est plus
     étroit qu'elle. */
  .miroir__panneau,
  .miroir__commandes { width: 100%; max-width: 34rem; margin-inline: auto; }
  /* Le tiret fait 2 px : on le remonte d'un pixel pour qu'il soit
     centré SUR la ligne d'eau et non posé dessous. */
  .miroir__jalons { margin-top: -1px; }
  .miroir__panneau   { padding-bottom: 0.7rem; }
}

/* L'en-tête de la section se cale sur la grille du miroir.

   La bande d'en-tête a sa propre géométrie (1,05fr / 1fr) et le miroir
   la sienne (1fr / 1fr, plus un bloc de 34rem centré dans la colonne de
   droite). Résultat : le chapô commençait 135 px à gauche du texte qui
   se trouve juste en dessous, ce qui se voit d'autant plus qu'ils sont
   l'un au-dessus de l'autre et qu'ils se ressemblent.

   On lui redonne exactement les mêmes colonnes, le même écart et le
   même bloc centré : les deux paragraphes partagent enfin une marge.

   Au seuil de la bande (75rem) et non à celui du miroir (56,25rem) :
   entre les deux, l'en-tête n'est pas une grille, et un bloc centré
   dans un en-tête empilé donne un décalage de 32 px qui ressemble à
   une faute. Dans cette plage, le chapô reste sous le titre — il se
   lit comme un en-tête, pas comme une colonne. */
@media (min-width: 75rem) {
  .entete-section--miroir {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
  }
  .entete-section--miroir > :first-child { max-width: none; }
  .entete-section--miroir .chapo {
    width: 100%;
    max-width: 34rem;
    margin: 0 auto;
  }
}

/* ---- La scène ---- */

/* La scène n'a plus de hauteur fixe : elle vaut cinq fois le pas, et
   le pas est mesuré en JavaScript sur la figure la plus haute. Une
   hauteur figée obligeait à choisir entre deux défauts — trop courte,
   les libellés qui passent sur deux lignes se chevauchent ; assez
   longue pour le pire cas, on gagne 340px de vide sur téléphone. Et
   comme les textes viennent d'un JSON qu'on édite, le pire cas n'est
   pas connu à l'avance.

   Repli si le JavaScript ne tourne pas : 4rem, assez pour deux lignes. */
.miroir__scene {
  position: relative;
  height: calc(var(--pas) * 5);
}

/* La masse d'eau. Bord franc en haut — c'est la surface, elle doit être
   nette — et fondu partout ailleurs, sinon l'aplat dessine une boîte
   sur le fond de la section. */
.miroir__scene::after {
  content: "";
  position: absolute;
  inset: 50% 0 0;
  background: linear-gradient(180deg, rgba(47, 107, 181, 0.17), transparent 88%);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  pointer-events: none;
}

.miroir__eau {
  position: absolute;
  inset-inline: 0;
  top: 50%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent, var(--or-clair) 16%, var(--or-clair) 84%, transparent);
}
.miroir__eau::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: -3px;
  height: 7px;
  background: inherit;
  opacity: 0.18;
}

/* ---- Une part ---- */

.miroir__fig {
  position: absolute;
  inset-inline: 0;
  top: calc(var(--pas) * 2.5);
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  transform: translateY(-50%);
  transition: top var(--transition-lente, 0.65s cubic-bezier(0.4, 0, 0.2, 1)),
              opacity 0.45s ease;
}
/* Le rang N est centré au milieu de sa tranche : (N − 0,5) pas. */
.miroir__fig[data-rang="1"] { top: calc(var(--pas) * 0.5); }
.miroir__fig[data-rang="2"] { top: calc(var(--pas) * 1.5); }
.miroir__fig[data-rang="3"] { top: calc(var(--pas) * 2.5); }
.miroir__fig[data-rang="4"] { top: calc(var(--pas) * 3.5); }
.miroir__fig[data-rang="5"] { top: calc(var(--pas) * 4.5); }

/* Sous l'eau, on s'efface. Jamais complètement : rien n'a disparu,
   c'est tout le propos. */
.miroir__fig[data-zone="eau"] { opacity: 0.42; }
.miroir__fig[data-zone="air"] { opacity: 1; }
.miroir__fig[data-zone="seuil"] { opacity: 1; }

.miroir__symbole {
  flex: 0 0 auto;
  width: clamp(3rem, 7vw, 4rem);
  aspect-ratio: 1;
  display: block;
}
.miroir__symbole svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* L'auréole ne s'allume qu'au seuil — le seul moment où une part est
   exactement au partage. */
.miroir__auréole { opacity: 0; transition: opacity 0.45s ease; }
.miroir__fig[data-zone="seuil"] .miroir__auréole { opacity: 1; }

.miroir__texte { display: grid; gap: 0.15rem; min-width: 0; transition: gap var(--transition-lente); }

/* Au seuil, la ligne d'eau passerait en plein milieu du libellé et le
   barrerait. Le bloc de texte étant centré sur la ligne, il suffit
   d'écarter ses deux lignes : la fenêtre s'ouvre pile sur la surface,
   quelle que soit la longueur du texte. Le nom au-dessus, le détail
   en dessous — le libellé enjambe la surface, ce qui tombe bien. */
.miroir__fig[data-zone="seuil"] .miroir__texte { gap: 1.15rem; }
.miroir__texte strong { font-size: clamp(0.95rem, 1.6vw, 1.05rem); line-height: 1.25; }
.miroir__detail {
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--texte-sombre-fond-attenue);
}
.miroir__fig[data-zone="seuil"] .miroir__detail { color: var(--or-clair); }

/* ---- Le panneau ---- */

/* Jalons et boutons sont centrés à toutes les largeurs. La scène est
   une figure symétrique — une surface, autant de rangs au-dessus qu'en
   dessous — et ce qui la commande doit l'être aussi. */
.miroir__jalons {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 0 100%;
}
.miroir__jalons li {
  width: 2.25rem;
  height: 2px;
  border-radius: 999px;
  background: rgba(157, 192, 232, 0.25);
  transition: background var(--transition);
}
.miroir__jalons li[data-etat="passe"] { background: rgba(201, 162, 39, 0.5); }
.miroir__jalons li[data-etat="courant"] { background: var(--or); }

.miroir__panneau h3 { color: var(--or-pale); margin-bottom: 0.6rem; }
.miroir__panneau p { max-width: 34rem; }

.miroir__commandes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
}
.miroir__commandes button[disabled] { opacity: 0.35; cursor: default; }

.miroir__note { font-size: 0.9rem; margin-top: clamp(1.25rem, 3vw, 2rem); font-style: italic; }

/* Un déplacement de 20 % de la scène, c'est exactement le genre de
   mouvement qui gêne. On garde le changement, on retire le glissement. */
@media (prefers-reduced-motion: reduce) {
  .miroir__fig,
  .miroir__auréole,
  .miroir__jalons li { transition: none; }
}

/* =========================================================
   26. Les deux chemins

   Deux cartes larges sur l'accueil, à la place de l'ancienne rangée
   suivie d'un aperçu de trois parcours et d'un lien vers les sept.
   Elles ne vendent pas : elles expliquent ce qu'est chaque chemin.

   Elles ne réutilisent pas `.carte` — une carte du site est faite pour
   vivre à trois ou quatre par rangée, avec un texte court. Ici il n'y
   en a que deux et elles portent un paragraphe entier ; elles ont donc
   leur propre respiration. Elles gardent en revanche `.carte--lien`,
   pour que toute la surface soit cliquable.
   ========================================================= */

.chemins {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  margin-top: 2.5rem;
}
@media (min-width: 48rem) { .chemins { grid-template-columns: 1fr 1fr; } }

.chemin {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  border-radius: var(--rayon);
  border: 1px solid rgba(157, 192, 232, 0.16);
  background: rgba(157, 192, 232, 0.06);
  transition: transform var(--transition), border-color var(--transition),
              background var(--transition);
}
.chemin:hover {
  transform: translateY(-4px);
  border-color: rgba(227, 200, 121, 0.4);
  background: rgba(157, 192, 232, 0.09);
}
.chemin h3 { margin: 0; font-size: clamp(1.5rem, 2.6vw, 1.9rem); }
.chemin > p { margin: 0; }

/* L'emblème et la pastille sur une seule rangée — le même parti que
   `.carte__visuel` sur les cartes de la Médiathèque. La pastille ne
   peut pas être posée en absolu : elle se replie sur deux lignes quand
   le libellé est long, et elle passerait alors sur l'emblème. */
.chemin__visuel {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}
.chemin__visuel .etiquette { flex: 0 1 auto; text-align: center; white-space: normal; }

/* L'emblème. Deux dessins tracés sur la même grille, même épaisseur,
   même dégradé : ils doivent se lire comme une paire, pas comme deux
   illustrations trouvées séparément. */
.chemin__embleme {
  width: clamp(4.5rem, 9vw, 6rem);
  aspect-ratio: 1;
  flex: 0 0 auto;
}
.chemin__embleme svg { width: 100%; height: 100%; display: block; overflow: visible; }
.chemin:hover .chemin__embleme { opacity: 1; }

/* Les faits : ce qu'on veut savoir avant de cliquer. Pas des puces
   décoratives — un filet doré discret suffit à les séparer. */
.chemin__faits {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
  font-size: 0.92rem;
  color: var(--texte-sombre-fond-attenue);
  border-top: 1px solid rgba(227, 200, 121, 0.22);
  padding-top: 1rem;
}
/* La puce est posée en absolu, pas en élément de flex. Avec
   `display:flex` sur le <li>, chaque nœud de texte devient un élément
   de flex à part entière : un <span data-chiffre> au milieu d'une
   phrase se retrouvait séparé du reste par le `gap`, et « Deux
   formules, à partir de 100 € » s'affichait avec un trou au milieu.
   Même famille de piège que la carte-action glissée dans un <p>. */
.chemin__faits li { position: relative; padding-left: 0.95rem; }
.chemin__faits li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--or);
}

.chemin .carte__suite { margin-top: auto; padding-top: 1.1rem; align-self: flex-start; }
