/*
  Site public de Louh.

  Palette reprise telle quelle de l'app (src/constants/brand.ts), et Karla en
  texte courant comme dans l'app (src/lib/fonts.ts).

  Titrage en Amiri, comme l'app (src/lib/fonts.ts). C'est le latin de la famille
  dont vient la police coranique affichée dans les captures : titrer dans la même
  écriture fait tenir la page ensemble, là où une troisième famille l'aurait
  éparpillée entre Karla, Amiri Quran et elle.

  Thème CLAIR verrouillé, conformément à la direction validée. L'app a un mode
  sombre ; la page d'accueil n'en a pas, pour que la première impression soit
  toujours celle du mushaf, papier clair et encre verte.
*/

:root {
  color-scheme: light;

  /* Identité, identique à Brand dans src/constants/brand.ts */
  --pine: #102e2c;
  --gold: #c09540;
  --parchment: #e9d5a9;
  --cream: #f3e7cf;
  --paper: #fbf7ee;
  --line: #e8e1d1;
  --wood: #8a6544;
  --wood-soft: #f6edde;
  --card: #ffffff;

  /* Neutres tirés vers le chaud, jamais un gris pur */
  --ink: var(--pine);
  --ink-soft: #55605c;
  --ink-faint: #8a938f;

  /* Largeur de lecture. 34 rem donnaient une colonne trop étroite pour la
     page : le texte s'arrêtait aux deux tiers et laissait un vide qui se
     lisait comme un défaut de mise en page. 42 rem font environ 75 signes,
     la limite haute de ce qui reste confortable à lire. */
/* L'ombre des captures, sortie en variable parce qu'elle était recopiée à
     l'identique à quatre endroits. Ce n'est pas un effet décoratif : elle dit
     « ceci est un objet posé sur le papier », par opposition au texte qui EST
     le papier. D'où sa portée, volontairement étroite : les captures et les
     cartes de prix, et rien d'autre. Posée sur un bloc de texte elle ne
     signifierait plus rien, et n'ajouterait qu'un flou gris.

     Teinte pin plutôt que noire, et étalement négatif : l'ombre reste sous
     l'objet au lieu de baver autour, et se lit sur le papier crème comme une
     ombre portée, pas comme un halo. */
  --lift: 0 1.5rem 3rem -1.5rem rgba(16, 46, 44, 0.28);
  --lift-high: 0 2rem 4rem -1.75rem rgba(16, 46, 44, 0.34);

  /* Les trois fonds des cartes de prix, en ÉCHELLE et non en exception.

     Les formules sont ordonnées : essai libre, mois, année. Leur fond suit cet
     ordre, du parchemin le plus dilué au parchemin plein. Le lecteur n'a rien à
     décoder ; il voit que quelque chose s'approfondit en allant vers la droite,
     et c'est vrai.

     LES TROIS VALEURS SONT UNE SEULE COULEUR, à trois doses. Trois teintes
     choisies séparément se seraient lues comme trois décisions ; une même
     couleur diluée à 10, 45 et 100 % se lit comme une progression. C'est aussi
     ce qui garde l'échelle juste si `--cream` change un jour.

     Le blanc pur n'y figure pas : c'était la seule valeur froide de la page,
     dans une palette dont l'en-tête de ce fichier dit qu'aucun neutre ne doit
     être gris. La première marche se lit blanche sans l'être. */
  --leaf-1: color-mix(in srgb, var(--cream) 10%, #fff);
  --leaf-2: color-mix(in srgb, var(--cream) 45%, #fff);
  --leaf-3: var(--cream);

  /* L'or de la marque ne passe pas le contraste en petit corps : 2,7:1 sur
     blanc. Cette version assombrie sert aux mentions de petite taille ; --gold
     reste pour les aplats et le grand corps.

     La valeur est calée sur le PARCHEMIN, pas sur le blanc. Le fond de la carte
     marquée est plus sombre que celui des deux autres, et un or réglé sur blanc
     y retombait à 3,91:1, sous le seuil. Mesuré à 5:1 sur parchemin. */
  --gold-ink: #7a5c20;

  --measure: 42rem;
  --rail: 4.5rem;

  --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.12rem);
  --step-1: clamp(1.2rem, 1.1rem + 0.5vw, 1.45rem);
  --step-2: clamp(1.6rem, 1.35rem + 1.1vw, 2.3rem);
  --step-3: clamp(2.2rem, 1.6rem + 2.6vw, 4rem);
}

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

/* La coupe doit porter sur `html` AUSSI : posée sur `body` seul, le
   débordement du héros continuait d'élargir le document et ouvrait une barre
   de défilement horizontale sur du vide. */
html {
  overflow-x: clip;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Une ancre atterrissait pile contre le bord haut de la fenêtre, sans air. */
:target {
  scroll-margin-top: 2.5rem;
}

body {
  margin: 0;
  /* Le halo et le motif du héros débordent volontairement de la colonne
     (`inset: … -50vw …`) pour aller au bord de l'écran. Sans cette coupe, ce
     débordement ouvrait un défilement horizontal sur une zone vide.
     `clip` plutôt que `hidden` : il n'introduit pas de conteneur de
     défilement, et n'empêche donc pas `position: sticky` ailleurs. */
  overflow-x: clip;
  background: var(--paper);
  color: var(--ink);
  font-family: Karla, ui-sans-serif, system-ui, sans-serif;
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: Amiri, Georgia, "Times New Roman", serif;
  font-weight: 400;
  line-height: 1.12;
  text-wrap: balance;
  margin: 0;
}

p {
  margin: 0;
  max-width: var(--measure);
}

/* Les marges sont mises à zéro plus haut et l'espacement confié aux
   conteneurs. Reste le flux normal d'une section, où un titre était collé au
   paragraphe qui le suit : on le rétablit ici, explicitement. */
h1 + p,
h2 + p,
h3 + p {
  margin-top: 0.9rem;
}

/* Deux paragraphes qui se suivent ont besoin d'un blanc entre eux.

   `p { margin: 0 }` oblige chaque endroit à poser la sienne, et l'oubli ne se
   voit pas au balisage : les trois derniers paragraphes de « Pourquoi Louh
   existe ? » étaient bien trois `<p>` distincts, mais se lisaient comme un seul
   pavé. La règle vaut donc par défaut, et non plus au cas par cas.

   Portée aux enfants DIRECTS d'une section : les paragraphes des cartes de prix
   ont un espacement dessiné, qu'une marge générale défferait. Et à spécificité
   supérieure, un style en ligne ou une classe (`.pivot`, `.lede`) garde la
   sienne : seuls les paragraphes sans habillage propre sont touchés. */
section > p + p {
  margin-top: 1.1rem;
}

a {
  color: inherit;
}

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

/* `height: auto` est indispensable : les images portent des attributs
   width/height (qui réservent la place et évitent les sauts de mise en page),
   et sans lui la hauteur reste figée à l'attribut pendant que la largeur
   s'adapte. L'image est alors étirée. */
img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* ── Le rail : colonne vertébrale, reprise de l'écran Parcours ────────────
   Un filet vertical qui traverse la page, ponctué de rosaces là où une
   section commence. La page est un chemin, comme l'app en est un. */

.page {
  --pad: clamp(1.25rem, 5vw, 3rem);
  max-width: 68rem;
  margin: 0 auto;
  padding-inline: var(--pad);
  position: relative;
}

@media (min-width: 60rem) {
  .page {
    padding-left: calc(var(--pad) + var(--rail));
  }

  /* Le fil à parcourir, en creux. */
  .page::before,
  .page::after {
    content: "";
    position: absolute;
    top: 0;
    left: calc(var(--pad) + var(--rail) / 2 - 1px);
    width: 2px;
    pointer-events: none;
  }

  .page::before {
    bottom: 0;
    background: linear-gradient(
      to bottom,
      transparent,
      var(--line) 6rem,
      var(--line) calc(100% - 10rem),
      transparent
    );
  }

  /* Et le fil parcouru, en or. Sa hauteur suit le défilement : la page se
     remonte comme le parcours de l'app se remplit. */
  /* Hauteur pilotée par le script, en pourcentage du chemin réellement
     parcourable : arrivé en bas de page, le fil est plein. */
  .page::after {
    height: var(--travelled, 0%);
    background: linear-gradient(to bottom, transparent, var(--gold) 6rem, var(--gold));
    opacity: 0.85;
  }
}

@media (prefers-reduced-motion: reduce) {
  .page::after {
    display: none;
  }
}

section {
  position: relative;
  /* Resserré : à 9vw, deux sections voisines laissaient jusqu'à 14 rem de vide
     entre elles sur grand écran, et la page se lisait par blocs isolés plutôt
     que comme un propos suivi. */
  padding-block: clamp(2rem, 3.8vw, 3.25rem);
}

/* Les titres de section n'avaient pas de taille propre et retombaient sur celle
   du navigateur : ils passaient inaperçus à côté de leur chapô. */
section > h2 {
  font-size: var(--step-2);
  /* 26ch bridaient le titre à 494 px sur 920 disponibles, et coupaient en deux
     des phrases qui tenaient sur une ligne : « On apprend par l'oreille, comme
     on l'a toujours fait. » en réclame 740, « Quinze sourates, sans payer ni
     créer de compte. » 677.

     48 rem sont mesurés sur le plus long des cinq, pas choisis au hasard. Le
     chapô en dessous s'arrête à 46 rem, ce qui aurait été le réglage naturel :
     il manquait quatre pixels. */
  max-width: 48rem;
}

section + section {
  border-top: 1px solid var(--line);
}

/* Rosace, marqueur de section.

   Le tracé et les DEUX ÉTATS sont ceux de `src/components/rosace.tsx` :
   l'étoile à seize branches et son disque central. Éteinte, elle a l'aspect
   d'une sourate encore à faire (étoile claire cerclée de bois, cœur bois
   clair) ; allumée, celui d'une sourate mémorisée (étoile or, cœur encre pin).

   Un masque monochrome ne pouvait pas rendre ce cercle : il faut deux formes
   et deux couleurs, donc du vrai SVG dans la page.  */
.node {
  display: none;
}

@media (min-width: 60rem) {
  .node {
    display: block;
    position: absolute;
    top: clamp(3.5rem, 9vw, 7rem);
    left: calc(-1 * var(--rail) / 2 - 1.05rem);
    width: 2.1rem;
    height: 2.1rem;
  }

  .rosace {
    width: 100%;
    height: 100%;
    display: block;
    overflow: visible;
  }

  /* À faire */
  .star {
    fill: var(--card);
    stroke: var(--wood);
    stroke-width: 28;
    stroke-linejoin: round;
    transition: fill 0.5s ease, stroke 0.5s ease;
  }
  .disc {
    fill: var(--wood-soft);
    stroke: var(--wood);
    stroke-width: 20;
    transition: fill 0.5s ease, stroke 0.5s ease;
  }

  /* Mémorisée */
  .node.lit .star {
    fill: var(--gold);
    stroke: var(--gold);
  }
  .node.lit .disc {
    fill: var(--pine);
    stroke: var(--gold);
  }
}

@media (prefers-reduced-motion: reduce) {
  .star {
    fill: var(--gold);
    stroke: var(--gold);
  }
  .disc {
    fill: var(--pine);
    stroke: var(--gold);
  }
}

/* ── Repères ─────────────────────────────────────────────────────────── */

.eyebrow {
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wood);
  margin: 0 0 1rem;
}

.lede {
  font-size: var(--step-1);
  color: var(--ink-soft);
  line-height: 1.5;
  /* Plus grand que le corps, donc moins de signes par ligne à largeur égale :
     il peut aller plus loin sans devenir pénible. */
  max-width: 46rem;
}

.small {
  font-size: var(--step--1);
  color: var(--ink-faint);
}

/* ── En-tête ─────────────────────────────────────────────────────────── */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.5rem;
  flex-wrap: wrap;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: Amiri, Georgia, serif;
  font-size: var(--step-1);
  text-decoration: none;
}

.wordmark img {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 22%;
}

.nav {
  display: flex;
  gap: 1.5rem;
  font-size: var(--step--1);
}

.nav a {
  color: var(--ink-soft);
  text-decoration: none;
  padding-block: 0.25rem;
  border-bottom: 1px solid transparent;
}

.nav a:hover {
  color: var(--ink);
  border-bottom-color: var(--gold);
}

/* ── Menu compact ─────────────────────────────────────────────────────────
   En dessous du point de bascule, les six liens ne tiennent plus sur une ligne :
   ils repassaient au-dessous du logotype, collés au bord, et n'étaient de toute
   façon accessibles qu'en haut de page. Ils se replient donc dans un panneau,
   et l'en-tête se fixe pour qu'on puisse changer de section de n'importe où.

   AMÉLIORATION PROGRESSIVE. Le bouton n'est montré que sous la classe
   « js-nav », posée par le script. Sans script il n'apparaît pas, le panneau
   n'est jamais masqué, et la barre reste celle d'avant : on peut toujours
   naviguer. Le repli ne dépend d'aucun script.

   MÊME POINT DE BASCULE QUE LES CARTES DE PRIX (46 rem). Deux seuils voisins
   mais différents feraient basculer la page en deux temps, ce qui se lit comme
   un défaut. */

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.85rem 0.5rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  font: inherit;
  font-size: var(--step--1);
  cursor: pointer;
}

.nav-toggle:hover {
  color: var(--ink);
  border-color: var(--gold);
}

/* Le trait de focus doit rester visible : c'est le seul repère au clavier. */
.nav-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.nav-burger {
  position: relative;
  display: block;
  width: 1.05rem;
  height: 1.5px;
  border-radius: 1px;
  background: currentColor;
}

.nav-burger::before,
.nav-burger::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: currentColor;
}

.nav-burger::before {
  top: -5px;
}

.nav-burger::after {
  top: 5px;
}

/* Ouvert, le bouton devient une croix : le geste pour fermer est le même que
   celui pour ouvrir, au même endroit. */
.nav-toggle[aria-expanded="true"] .nav-burger {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-burger::before {
  top: 0;
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-burger::after {
  top: 0;
  transform: rotate(-45deg);
}

@media (prefers-reduced-motion: no-preference) {
  .nav-burger,
  .nav-burger::before,
  .nav-burger::after {
    transition: transform 0.18s ease, top 0.18s ease, background-color 0.18s ease;
  }
}

@media (max-width: 45.999rem) {
  /* L'en-tête se fixe en haut. Le fond n'est posé qu'une fois la page défilée :
     au repos, le halo du héros passe derrière l'en-tête, et un aplat opaque y
     dessinerait une bande visible en travers du dégradé.

     ⚠️ PORTÉE « js-nav », ET C'EST INDISPENSABLE. Les quatre pages légales
     partagent cette feuille, n'ont pas de script et n'ont que deux liens. Sans
     cette portée elles héritaient d'un en-tête fixe dont personne ne pose
     jamais le fond, et leur texte défilait au travers, illisible. La barre s'y
     fixe donc seulement là où il y a un menu à atteindre de n'importe où. */
  .js-nav .masthead {
    position: sticky;
    top: 0;
    z-index: 30;
    padding-block: 0.9rem;
    margin-inline: calc(var(--pad) * -1);
    padding-inline: var(--pad);
  }

  .js-nav .masthead.posee {
    background: var(--paper);
    box-shadow: 0 1px 0 var(--line);
  }

  @media (prefers-reduced-motion: no-preference) {
    .js-nav .masthead {
      transition: background-color 0.2s ease, box-shadow 0.2s ease;
    }
  }

  /* Une ancre atterrissait sous l'en-tête fixe, donc sur le corps de la section
     au lieu de son titre. La marge de défilement doit couvrir sa hauteur. */
  .js-nav :target {
    scroll-margin-top: 5.25rem;
  }

  .js-nav .nav-toggle {
    display: inline-flex;
  }

  .js-nav .nav {
    position: absolute;
    top: calc(100% - 0.25rem);
    right: var(--pad);
    left: var(--pad);
    z-index: 5;
    display: none;
    flex-direction: column;
    gap: 0;
    padding: 0.35rem;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 0.9rem;
    box-shadow: var(--lift-high);
  }

  .js-nav .nav[data-ouvert] {
    display: flex;
  }

  /* Cible tactile d'au moins 44 px, et le soulignement or de la barre laisse
     place à un aplat : dans une liste, c'est la ligne entière qu'on vise. */
  .js-nav .nav a {
    padding: 0.7rem 0.85rem;
    border-radius: 0.6rem;
    border-bottom: 0;
  }

  .js-nav .nav a:hover,
  .js-nav .nav a:focus-visible {
    color: var(--ink);
    background: var(--wood-soft);
  }
}

/* ── Héro ────────────────────────────────────────────────────────────── */

.hero {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  align-items: start;
  padding-top: clamp(1.75rem, 4vw, 2.75rem);
}

@media (min-width: 60rem) {
  .hero {
    grid-template-columns: minmax(0, 1fr) 17rem;
  }
}

.hero h1 {
  font-size: var(--step-3);
  margin-bottom: 1.25rem;
}

/* `line-height: 1` ne laisse pas la place aux signes portés : la damma monte
   au-dessus de la ligne et la queue du ḥāʾ descend en dessous, si bien que le
   mot chevauchait le titre. L'arabe vocalisé demande nettement plus d'interligne
   que le latin. */
.arabic {
  font-family: "Amiri Quran", Amiri, serif;
  color: var(--gold);
  direction: rtl;
  line-height: 1.55;
}

.hero .arabic {
  font-size: clamp(2.6rem, 6vw, 3.6rem);
  margin-bottom: 0.75rem;
}

/* `direction: rtl` pousse le texte contre le bord droit du bloc. En
   inline-block le mot ne fait que sa largeur et suit l'alignement de la
   colonne, tout en gardant son sens de lecture. */
.hero .arabic {
  display: inline-block;
}

/* La capture n'est pas encadrée d'un faux téléphone : l'écran suffit, et un
   cadre dessiné vieillit mal. */
.shot {
  border-radius: 1.4rem;
  border: 1px solid var(--line);
  box-shadow: var(--lift);
  background: var(--card);
}

.shot-row {
  display: grid;
  gap: clamp(1rem, 3vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin-top: 3rem;
  max-width: 34rem;
}

/* ── Boutons ─────────────────────────────────────────────────────────── */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.8rem 1.4rem;
  border-radius: 999px;
  text-decoration: none;
  font-size: var(--step--1);
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  transition: transform 0.15s ease, background-color 0.15s ease;
}

.btn-primary {
  background: var(--gold);
  color: var(--pine);
  font-weight: 700;
}

.btn-primary:hover {
  background: #ab8438;
}

.btn-ghost {
  border-color: var(--line);
  color: var(--ink-soft);
}

.btn-ghost:hover {
  border-color: var(--gold);
  color: var(--ink);
}

.btn[aria-disabled="true"] {
  opacity: 0.55;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .btn:hover {
    transform: translateY(-1px);
  }
}

/* Badges de boutique : l'app n'est pas encore publiée, il n'y a donc rien à
   ouvrir. Un bouton grisé donne l'air d'une page cassée ; un repère assumé dit
   la même chose sans affaiblir le haut de page. */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--pine);
  border-radius: 999px;
  font-size: var(--step--1);
  letter-spacing: 0.02em;
  font-weight: 700;
}

.badge-note {
  display: inline-flex;
  align-items: center;
  font-size: var(--step--1);
  color: var(--wood);
}

/* ── Listes de contenu ───────────────────────────────────────────────── */

.grid {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  margin-top: 2.5rem;
}

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

.grid h3 {
  font-size: var(--step-1);
  margin-bottom: 0.5rem;
}

.grid p {
  color: var(--ink-soft);
  font-size: var(--step--1);
  line-height: 1.6;
}

/* Les trois gestes sont une SÉQUENCE : la numérotation dit quelque chose de
   vrai, elle ne décore pas. */
.steps {
  counter-reset: step;
}

.steps > div::before {
  counter-increment: step;
  content: counter(step);
  display: block;
  font-family: Amiri, Georgia, serif;
  font-size: var(--step-1);
  color: var(--gold);
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.6rem;
  margin-bottom: 0.9rem;
}

/* ── Tarifs ──────────────────────────────────────────────────────────── */

/* ── Le prix ─────────────────────────────────────────────────────────────
   Trois cartouches posés sur le papier, pas trois cases de comparateur.

   CE QUI FAIT LE DESSIN ICI, C'EST L'ALIGNEMENT. Trois cartes dont les prix ne
   tombent pas sur la même ligne d'œil se lisent comme un brouillon, quelle que
   soit la qualité du reste. `subgrid` accroche les quatre lignes (intitulé,
   prix, périodicité, détail) sur les rails de la grille parente : les prix
   s'alignent même quand les intitulés au-dessus n'ont pas la même hauteur, et
   les filets aussi.

   Repli sans `subgrid` : la carte redevient une colonne flex et le détail est
   poussé en bas par `margin-top: auto`. L'alignement se fait alors par le bas
   au lieu des rails. Rien ne casse, c'est simplement moins juste. */

.plans {
  display: grid;
  gap: clamp(0.85rem, 2vw, 1.25rem);
  margin-top: 2.5rem;
}

.plan {
  display: flex;
  flex-direction: column;
  position: relative;
  isolation: isolate;
  border: 1px solid var(--line);
  border-radius: 1.1rem;
  padding: 1.5rem 1.4rem 1.6rem;
  background: var(--leaf-1);
  box-shadow: var(--lift);
}

/* Trois colonnes déclarées, jamais `auto-fit`.

   `auto-fit` décidait seul du nombre de colonnes, et pouvait en poser deux : la
   troisième carte passait alors sur une seconde bande de pistes que `row-gap: 0`
   collait à la première. Le nombre de colonnes est donc fixé, et l'empilement
   n'a lieu que sous le point de bascule, là où la grille reprend son écart
   normal et où l'alignement par rails n'a plus de sens de toute façon. */
@media (min-width: 46rem) {
  .plans {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  @supports (grid-template-rows: subgrid) {
    .plans {
      grid-template-rows: auto auto auto;
      /* Les pistes appartenant aux cartes, tout écart de ligne s'ouvrirait à
         l'intérieur d'elles. L'espacement interne est donc porté par les marges
         des blocs, qui elles participent à la hauteur des pistes. */
      row-gap: 0;
    }
    .plan {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      /* Sans ancrage explicite, un contenu plus court que sa piste se replace
         selon l'étirement par défaut et le filet redescend : c'est précisément
         l'alignement qu'on venait chercher qui se perdait. */
      align-items: start;
    }
  }
}

.plan-name {
  margin: 0;
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-soft);
}

.plan .price {
  display: block;
  margin: 0.6rem 0 1.1rem;
  font-family: Amiri, Georgia, serif;
  font-size: var(--step-2);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* Le symbole monétaire n'a pas à peser autant que le nombre : c'est le chiffre
   qu'on compare d'une carte à l'autre. En `span` plutôt que précédé d'une
   espace insécable, l'écart est réglé au dessin et ne peut pas se couper en
   fin de ligne. */
.plan .price .cur {
  font-size: 0.55em;
  margin-left: 0.34em;
  color: var(--ink-soft);
}

/* L'unité se lit SUR la ligne du prix, jamais sous elle.

   Une première version lui donnait son propre bloc, sous une ligne qui nommait
   déjà la périodicité (« AU MOIS » en haut, « par mois » en bas). Deux lignes
   pour la même information : l'une des deux flottait forcément, isolée sous le
   prix sans rien à quoi se rattacher. Une unité appartient à son nombre.

   La ligne du haut porte donc autre chose, ce que la périodicité ne dit pas :
   « Sans compte », « Sans engagement », et sur la carte annuelle l'écart de
   tarif, seul marqueur en couleur de la rangée. */
.plan .price .per {
  font-family: Karla, ui-sans-serif, system-ui, sans-serif;
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin-left: 0.15em;
  /* La périodicité ne se coupe pas en « par / mois » sur colonne étroite. */
  white-space: nowrap;
}

.plan-detail {
  margin: 0;
  padding-top: 1.05rem;
  border-top: 1px solid var(--line);
  font-size: var(--step--1);
  line-height: 1.65;
  color: var(--ink-soft);
}

/* Le repli seul pousse le détail en bas de carte. Avec `subgrid`, la ligne est
   déjà tenue par les rails : une marge automatique en plus ferait redescendre le
   filet des cartes au texte court sous celui des autres, c'est-à-dire qu'elle
   défairait exactement l'alignement qu'on cherche.

   La règle vit donc ici, dans le repli, et non dans la base suivie d'un
   correctif : à spécificité égale c'est la dernière déclaration qui gagne, et
   l'annulation posée plus haut dans la feuille était sans effet. */
@supports not (grid-template-rows: subgrid) {
  .plan-detail {
    margin-top: auto;
  }
}

/* Les marches de l'échelle. `nth-child` plutôt que des classes : ce qui décide
   du fond, c'est bien le RANG de la carte dans la rangée, et rien d'autre. Si
   l'ordre des formules change un jour, l'échelle suit sans qu'on y pense. */
.plans > .plan:nth-child(2) {
  background: var(--leaf-2);
}

.plans > .plan:nth-child(3) {
  background: var(--leaf-3);
}

/* La formule à l'année est la feuille pleine, et se tient un cran plus haut.

   LE PARCHEMIN PLUTÔT QU'UN FILET D'OR. Un liseré doré en haut d'une carte est
   le marqueur de n'importe quel comparateur de prix ; il ne disait rien de
   Louh. La matière dit la même chose sans ornement rapporté.

   L'élévation est permanente plutôt qu'au survol : la carte est recommandée
   tout le temps, pas seulement quand la souris passe. Et une carte qui se
   soulève sous le curseur sans être cliquable promet un geste qui n'existe
   pas. */
.plan-best {
  border-color: var(--parchment);
  box-shadow: var(--lift-high);
}

.plan-best .plan-detail {
  border-top-color: color-mix(in srgb, var(--wood) 24%, transparent);
}

.plan-tag {
  display: inline-block;
  margin-left: 0.45rem;
  padding: 0.08em 0.5em;
  border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
  border-radius: 999px;
  font-size: 0.78em;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--gold-ink);
  font-variant-numeric: tabular-nums;
  vertical-align: 0.1em;
}

/* ── Pages de texte (légal, support) ─────────────────────────────────── */

.prose {
  padding-block: clamp(2rem, 4vw, 3rem);
}

.prose h1 {
  font-size: var(--step-2);
  margin-bottom: 0.75rem;
}

.prose h2 {
  font-size: var(--step-1);
  margin: 2.75rem 0 0.75rem;
}

.prose h3 {
  font-size: var(--step-0);
  font-family: Karla, sans-serif;
  font-weight: 700;
  margin: 1.75rem 0 0.4rem;
}

.prose p,
.prose li {
  color: var(--ink-soft);
  max-width: var(--measure);
}

.prose ul {
  margin: 0.75rem 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.4rem;
}

.prose a {
  color: var(--wood);
  text-underline-offset: 3px;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0;
  font-size: var(--step--1);
}

.prose th,
.prose td {
  text-align: left;
  padding: 0.6rem 0.8rem 0.6rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.prose th {
  font-weight: 700;
  color: var(--ink);
}

.table-wrap {
  overflow-x: auto;
}

/* Bloc à compléter avant mise en ligne : voyant, pas discret. */
.todo {
  border: 1px dashed var(--wood);
  background: color-mix(in srgb, var(--cream) 60%, transparent);
  border-radius: 0.6rem;
  padding: 1rem 1.2rem;
  margin: 1rem 0;
  font-size: var(--step--1);
  color: var(--wood);
}

.todo strong {
  color: var(--pine);
}

/* ── Pied de page ────────────────────────────────────────────────────── */

.site-footer {
  border-top: 1px solid var(--line);
  padding-block: 2.5rem 3.5rem;
  display: grid;
  gap: 1.25rem;
}

.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  font-size: var(--step--1);
}

.site-footer a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

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

/* ── Apparition au défilement ──────────────────────────────────────────
   Tout est VISIBLE par défaut. C'est le script qui masque, après s'être
   annoncé par la classe `js` sur la racine. Masquer d'abord et révéler
   ensuite laisse une page blanche dès que le script tarde, échoue ou ne
   s'exécute pas : un contenu ne doit jamais dépendre d'une animation pour
   être lu. */

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s ease, transform 0.6s ease;
  }
  .js .reveal.seen {
    opacity: 1;
    transform: none;
  }
}

/* ── Profondeur ──────────────────────────────────────────────────────────
   Une page d'un seul ton reste plate quelle que soit la typographie. La
   profondeur vient d'écarts de valeur entre les plans, pas d'ombres portées
   sur tout. Trois plans : le papier, la crème, et le parchemin de la marque. */

.hero {
  isolation: isolate;
}

/* Halo de parchemin derrière le héros : le regard se pose là avant de lire. */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* ⚠️ SANS CECI, LE HALO AVALE LES CLICS DE L'EN-TÊTE. Il déborde de six rem
     vers le haut, donc par-dessus le menu. Son `z-index: -1` le place derrière
     le contenu du héros, mais `isolation: isolate` l'enferme dans le héros, qui
     est peint APRÈS l'en-tête : il se retrouve donc au-dessus des liens pour la
     souris. Le curseur ne changeait plus et les liens paraissaient être du
     texte. `.motif`, juste en dessous, portait déjà cette règle. */
  pointer-events: none;
  inset: -6rem -50vw -4rem -50vw;
  background:
    radial-gradient(58% 70% at 68% 34%, color-mix(in srgb, var(--parchment) 62%, transparent), transparent 70%),
    radial-gradient(46% 60% at 8% 8%, color-mix(in srgb, var(--cream) 78%, transparent), transparent 72%);
}

/* Motif rub el hizb, très en retrait. C'est la géométrie du louh et de la
   rosace de l'icône, pas un ornement générique.

   Un `<svg>` sans dimensions retombe sur 300 × 150 : il faut les donner, sinon
   le motif forme une vignette au coin du héros au lieu de le tapisser. Le
   masque le fait mourir avant d'atteindre le texte, pour qu'il reste une
   texture et jamais un élément qu'on remarque. */
.motif {
  position: absolute;
  z-index: -1;
  inset: -4rem -50vw auto -50vw;
  width: auto;
  height: 34rem;
  opacity: 0.055;
  pointer-events: none;
  color: var(--pine);
  mask-image: radial-gradient(58% 62% at 72% 42%, #000 15%, transparent 72%);
}

.band {
  background: var(--cream);
  border-block: 1px solid var(--parchment);
}

/* Bande de chiffres : elle rythme la page et donne les faits d'un coup d'œil. */
.figures {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  /* Padding sur les quatre côtés : sans l'horizontal, les chiffres touchaient
     le bord de la bande. */
  padding: clamp(1.5rem, 3.5vw, 2.25rem) clamp(1.5rem, 4vw, 2.5rem);
  align-items: start;
}

.figure {
  text-align: center;
}

.figure b {
  display: block;
  font-family: Amiri, Georgia, serif;
  font-weight: 400;
  font-size: var(--step-2);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin-bottom: 0.4rem;
}

.figure span {
  font-size: var(--step--1);
  color: var(--ink-soft);
  display: block;
  max-width: 12rem;
  /* Le libellé est borné en largeur : sans marges automatiques il resterait
     calé à gauche de sa colonne pendant que le chiffre, lui, serait centré. */
  margin-inline: auto;
}

/* ── Captures en profondeur ──────────────────────────────────────────────
   Deux écrans décalés en marche d'escalier. Une première version les
   superposait : la seconde capture recouvrait les versets de la première,
   c'est-à-dire exactement ce que la section donne à voir. La profondeur ne
   doit jamais coûter le contenu. */

.stack-shots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 3vw, 2rem);
  align-items: start;
  margin-top: 3.5rem;
  max-width: 32rem;
}

.stack-shots img {
  border-radius: 1.2rem;
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--lift);
}

.stack-shots img:last-child {
  margin-top: clamp(1.5rem, 5vw, 3rem);
}

/* Décalage en cascade des révélations : les trois gestes arrivent dans
   l'ordre où on les accomplit. */
@media (prefers-reduced-motion: no-preference) {
  .js .steps > div {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.55s ease, transform 0.55s ease;
  }
  .js .steps.seen > div {
    opacity: 1;
    transform: none;
  }
  .js .steps.seen > div:nth-child(2) { transition-delay: 0.12s; }
  .js .steps.seen > div:nth-child(3) { transition-delay: 0.24s; }
}

/* ══ Mise en valeur du produit ═══════════════════════════════════════════
   Une page d'application doit MONTRER l'application. La première version la
   racontait : captures de 272 px enfermées dans une colonne de lecture, texte
   qui décrivait des fonctions. Ici les écrans occupent la place, et les
   sections sortent de la colonne quand le sujet le demande. */

/* Sortie de colonne : la section reprend toute la largeur utile. */
.bleed {
  margin-left: calc(-1 * var(--rail));
}

@media (max-width: 59.99rem) {
  .bleed {
    margin-left: 0;
  }
}

/* ── Héro élargi ─────────────────────────────────────────────────────── */

.hero {
  grid-template-columns: 1fr;
  padding-bottom: clamp(2rem, 4vw, 3rem);
}

@media (min-width: 60rem) {
  .hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: center;
  }
}

.hero h1 {
  font-size: clamp(2.4rem, 5.6vw, 4.6rem);
  letter-spacing: -0.015em;
  margin-bottom: 1.1rem;
}

/* Deux écrans côte à côte, décalés : on voit tout de suite qu'il s'agit d'une
   application, et non d'une brochure avec une image. */
.duo {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 2vw, 1.4rem);
  align-items: start;
}

.duo img {
  border-radius: clamp(1rem, 2vw, 1.6rem);
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--lift-high);
}

.duo img:last-child {
  margin-top: clamp(2rem, 6vw, 4.5rem);
}

/* ── Le constat, en grand ────────────────────────────────────────────── */

.tension {
  padding-block: clamp(1.75rem, 3.2vw, 2.75rem);
}

/*
  ⚠️ Viser `.tension p` touchait AUSSI le chapô qui suit, alors qu'il a sa
  propre largeur : `.tension p` (deux classes) l'emportait sur `.lede` (une
  seule), et le paragraphe se retrouvait bridé à vingt-quatre signes. La règle
  ne porte donc plus que sur le constat lui-même.
*/
.tension > p:first-of-type {
  font-family: Amiri, Georgia, serif;
  font-size: clamp(1.5rem, 3.4vw, 2.6rem);
  line-height: 1.3;
  max-width: 46ch;
  /* La coupe était décidée par un `<br>` dans le balisage. Il tombait juste à
     une largeur, et à une seule : en colonne étroite il coupait après « sur
     laquelle » et laissait une ligne de 21 % suivie d'un « ans. » de 10 %, la
     phrase se lisant en escalier au lieu d'occuper la mesure. Il a été retiré.

     PAS DE `text-wrap` ICI, ET C'EST MESURÉ. En flux libre les lignes occupent
     98 % et 99 % de la mesure ; `balance` les ramenait à 74 % et 77 %, soit un
     quart de largeur perdu pour égaliser un pavé de trois lignes qui n'en avait
     pas besoin. `pretty` ne changeait rien. La dernière ligne courte est celle
     de n'importe quel paragraphe, pas un défaut. */
  color: var(--ink);
}

.tension b {
  font-weight: 400;
  color: var(--gold);
}

.tension .lede {
  max-width: 46rem;
}

/* ── Section encre ───────────────────────────────────────────────────────
   Le seul bloc sombre de la page. Il ne sert pas à décorer : c'est là que se
   trouve l'argument qu'aucun concurrent francophone ne peut copier, et le
   contraste lui donne le poids qu'un aplat clair de plus lui refuserait.
   L'or et l'arabe n'y sont jamais aussi justes que sur l'encre. */

/*
  Le bloc reste DANS la colonne, il ne déborde pas jusqu'au rail.

  Sorti en pleine largeur, son bord gauche tombait pile sur le fil de
  progression, qui semblait alors le traverser. Le rail est la colonne
  vertébrale de la page : rien ne doit s'asseoir dessus.
*/
.ink {
  position: relative;
  background: var(--pine);
  color: var(--cream);
  border-radius: clamp(1rem, 2.5vw, 2rem);
  padding: clamp(2.5rem, 6vw, 5rem);
  margin-top: clamp(3rem, 8vw, 6rem);
  overflow: hidden;
}

.ink h2,
.ink h3 {
  color: var(--cream);
}

.ink p {
  color: color-mix(in srgb, var(--cream) 78%, transparent);
}

.ink .eyebrow {
  color: var(--gold);
}

/* `.small` est un gris moyen, calculé pour le fond papier. Sur l'encre il
   tombait juste au-dessus du seuil de lisibilité. */
.ink .small {
  color: color-mix(in srgb, var(--cream) 62%, transparent);
}

.ink .arabic {
  color: var(--gold);
}

/* Comparaison des deux orthographes : deux bandes du même verset, côte à côte.
   C'est le seul endroit de la page où la démonstration remplace l'argument. */
/* Comparaison des deux orthographes : deux bandes du même verset, côte à côte.
   C'est le seul endroit de la page où la démonstration remplace l'argument. */
.compare {
  display: grid;
  gap: clamp(1rem, 3vw, 2rem);
  margin-top: clamp(2rem, 5vw, 3rem);
}

@media (min-width: 46rem) {
  .compare {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.compare figure {
  margin: 0;
}

.compare img {
  border-radius: 0.9rem;
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
  box-shadow: 0 1.25rem 2.5rem -1.25rem rgba(0, 0, 0, 0.5);
}

.compare figcaption {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 0.9rem;
  font-size: var(--step--1);
  color: var(--gold);
}

.compare figcaption .arabic {
  font-size: 1.5rem;
  line-height: 1.4;
}

.compare .small {
  margin-top: 0.35rem;
}

.pair {
  display: grid;
  gap: 1.75rem;
  margin-top: 2.5rem;
}

@media (min-width: 40rem) {
  .pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.pair h3 {
  font-size: var(--step-1);
}

/* Comme dans le héros : en inline-block, le mot ne fait que sa largeur et suit
   l'alignement de la colonne, tout en gardant son sens de lecture. En block, le
   `direction: rtl` le collait au bord droit du bloc. */
.pair .arabic {
  font-size: 1.9rem;
  line-height: 1.5;
  display: inline-block;
  margin-bottom: 0.45rem;
}

/* ── Vitrine à écran fixe ────────────────────────────────────────────────
   La bande défilante précédente coupait le dernier écran au bord du cadre,
   n'annonçait nulle part qu'elle défilait, et traitait sept captures de la
   même façon. Elle donnait une pellicule, pas une démonstration.

   Ici le téléphone reste en place pendant que le texte défile à côté, et
   l'écran change à chaque étape. Le mouvement suit la lecture au lieu de s'y
   ajouter, et chaque capture obtient toute la place et une seconde d'attention.

   Repli : sans script ou sur écran étroit, les captures s'enchaînent
   simplement sous leur texte. Rien ne dépend du dispositif. */

.showcase {
  display: grid;
  gap: clamp(2rem, 5vw, 3rem);
  margin-top: clamp(2.5rem, 6vw, 4rem);
}

.moment + .moment {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
}

.moment h3 {
  font-size: var(--step-1);
}

.moment .index {
  display: block;
  font-family: Amiri, Georgia, serif;
  font-size: var(--step--1);
  letter-spacing: 0.1em;
  color: var(--gold);
  margin-bottom: 0.5rem;
}

.stage {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  justify-items: center;
}

.stage img {
  border-radius: 1.3rem;
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--lift-high);
  max-width: 17rem;
}

@media (min-width: 62rem) {
  .showcase {
    grid-template-columns: minmax(0, 1fr) 19rem;
    gap: clamp(3rem, 7vw, 6rem);
    align-items: start;
  }

  /* Le téléphone tient la position pendant que le texte défile à côté. */
  .stage {
    position: sticky;
    top: 14vh;
    height: 38rem;
    display: block;
  }

  .stage img {
    position: absolute;
    inset: 0;
    margin: auto;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    /* Fondu court : chaque capture tient environ 400 px de défilement, soit
       une à deux secondes. Un fondu long y mangerait un tiers du temps et
       ferait se chevaucher deux écrans pendant qu'on descend vite. */
    transition: opacity 0.32s ease, transform 0.32s ease;
  }

  /* Sans script, la première capture reste affichée : jamais de cadre vide. */
  .js .stage img {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }

  .js .stage img.on {
    opacity: 1;
    transform: none;
  }

  /* Chaque moment occupe assez de hauteur pour qu'on ait le temps de le lire
     avant que l'écran ne change. */
  .moment {
    min-height: 22rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .moment + .moment {
    margin-top: 0;
  }

  /* Course restante après le dernier moment.

     Sans elle, la quatrième capture s'affichait au moment précis où le bloc
     fixe atteignait le bas de son conteneur et se décollait : elle
     apparaissait un instant puis repartait vers le haut. Il faut du défilement
     APRÈS le déclenchement pour qu'on ait le temps de la voir. */
  /* Réserve de défilement AVANT le premier moment et APRÈS le dernier.

     Sans celle du haut, la première capture cédait la place dès que le second
     texte franchissait le seuil, c'est-à-dire alors que le bloc fixe finissait
     à peine d'entrer dans l'écran. Sans celle du bas, la dernière apparaissait
     au moment où le bloc se décollait. Les deux extrémités ont besoin de
     course, pas seulement la fin. */
  .showcase-steps {
    padding-top: clamp(10rem, 34vh, 20rem);
    padding-bottom: clamp(20rem, 62vh, 38rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .stage {
    position: static;
    height: auto;
    display: grid;
  }
  .stage img {
    position: static;
    opacity: 1;
    transform: none;
    max-width: 17rem;
  }
}


/* ─────────────────────────────────────────────────────────────
   Le titre en deux temps
   ─────────────────────────────────────────────────────────────
   Un louh est la tablette de bois sur laquelle on écrit, on efface et on
   réécrit. Le titre le rejoue : la première phrase est encrée, la seconde a
   commencé à partir. C’est de la typographie, pas une animation : rien ne
   bouge devant le lecteur, et rien ne distrait (§3 du cahier des charges). */
/* L’argument sous le titre : plus grand que le chapô, bien plus petit que le
   titre. Il porte le raisonnement, pas la promesse. */
.hero .claim {
  font-family: Amiri, Georgia, serif;
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  line-height: 1.35;
  color: var(--ink);
  margin: 1.15rem 0 1.1rem;
  /* Les deux mouvements tiennent chacun sur sa ligne, d’où le retour explicite
     dans le HTML : c’est l’opposition qui porte l’argument, et une coupure au
     milieu de la première phrase l’efface.

     `balance` ne combat PAS ce retour, contrairement à ce qui était noté ici :
     il équilibre chaque segment de part et d’autre du `<br>`. Sans lui, la
     première phrase se coupait en « … prend une » puis « semaine. », seule sur
     un cinquième de la largeur. */
  text-wrap: balance;
  max-width: 34ch;
}
/* Ce qui s’efface s’écrit dans le ton du bois.

   L’opacité a été retirée : à la taille d’un titre elle passait pour un effet
   voulu, mais à celle-ci le bois affaibli se lisait comme du texte délavé. Le
   ton pleine force se lit comme un second ton choisi, ce qu’il est. */
.hero .claim .fade { color: var(--wood); }


/* La phrase pivot de « Pourquoi Louh existe ». Trois mots après deux paragraphes
   de constat : ils portent le basculement, et une taille de corps ordinaire les
   ferait passer pour une ligne de plus. */
.pivot {
  font-family: Amiri, Georgia, serif;
  font-size: clamp(1.3rem, 2.2vw, 1.6rem);
  color: var(--ink);
  margin: 1.6rem 0;
}


/* Ce qui se perd s'écrit dans le ton du bois, ici comme dans le titre.

   La couleur n'appuie pas, elle SIGNIFIE : l'or nomme (« louh », les chiffres),
   le bois dit ce qui s'efface (« La perdre prend un mois », « perdues »). Un
   lecteur apprend ce code en deux sections sans y penser, et il ne tient que
   tant qu'on ne colore pas pour insister. */
.perdu {
  color: var(--wood);
}
