/* ─────────────────────────────────────────────────────────────────────────
   STELLAR REBIRTH : la direction artistique du livre, portée sur une page.

   Rien n'est inventé ici. La palette vient de `lib/core/design/sr_palette.dart`,
   l'échelle typographique et les écarts de `sr_type.dart`, les motifs de
   `sr_motifs.dart`, et les quatre thèmes sont ceux de l'application.

   Trois règles tiennent le reste :

   * Deux encres, pas trois. Aucun codage par la couleur : toute la hiérarchie
     repose sur l'opacité de l'encre, et c'est la seule échelle disponible.
   * On trace, on n'empile pas. Pas de carte, pas d'ombre portée, pas
     d'élévation. Une surface se distingue par un filet et, au plus, un voile
     d'encre à quatre pour cent.
   * Deux fontes à empattements, aucune sans. Le mot « sans-serif » n'apparaît
     nulle part dans ce fichier, et `tools/site/verify.py` le vérifie.
   ───────────────────────────────────────────────────────────────────────── */

/* ─── Les fontes ─────────────────────────────────────────────────────────
   Instrument Serif pour l'affichage, la fonte de la couverture.
   Literata pour le récit, et pour lui seul.                              */

@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/InstrumentSerif-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/InstrumentSerif-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("assets/fonts/Literata-Variable.woff2") format("woff2-variations");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("assets/fonts/Literata-Italic-Variable.woff2") format("woff2-variations");
  font-weight: 200 900;
  font-style: italic;
  font-display: swap;
}

/* ─── La palette ─────────────────────────────────────────────────────────
   Deux encres, relevées au pixel sur la couverture du roman : un outremer
   profond et une crème chaude. « Nuit » est la couverture, « papier » la
   retourne pour lire au soleil. Retourner la page n'ajoute pas une couleur,
   c'est la même paire dans l'autre sens.                                 */

:root {
  --ground: #002EB8;
  --ink: #FFF9EF;
  --hollow: #001E86;
  --raised: #0A3ED0;
  --glint: #93A9EE;
  --scrim: #001B78EE;

  /* L'échelle d'encre, celle de `SRPalette`. Toute la hiérarchie tient ici :
     un mélange improvisé désaccorde immédiatement une section de ses
     voisines.

     Une seule règle s'ajoute, et elle est propre à la page : **aucun texte
     n'est peint sous `--ink-soft`.** Le troisième rang de l'application
     (46 %) tient 3,1 pour 1 sur l'outremer et 2,7 sur le crème ; sur un
     téléphone tenu à bout de bras, dans une application qu'on a choisi
     d'ouvrir, cela passe ; sur une page publique lue une fois, non. La
     hiérarchie se fait donc à la taille et à la casse, ce que la direction
     artistique demande de toute façon : une section ne se reconnaît pas à sa
     teinte. `--ink-faint` reste pour ce qui n'est pas du texte : filets
     inactifs, traits de séparation. `tools/site/verify.py` mesure les deux
     rapports et refuse le troisième rang sous un `color`. */
  --ink-soft: color-mix(in srgb, var(--ink) 72%, transparent);
  --ink-faint: color-mix(in srgb, var(--ink) 46%, transparent);
  --rule: color-mix(in srgb, var(--ink) 34%, transparent);
  --rule-faint: color-mix(in srgb, var(--ink) 16%, transparent);
  --fill: color-mix(in srgb, var(--ink) 7%, transparent);
  --fill-faint: color-mix(in srgb, var(--ink) 4%, transparent);

  /* Deux épaisseurs de trait suffisent, et la seconde ne sert qu'à ce qui
     est actif. */
  --hair: 1px;
  --bold: 1.6px;

  /* Tout écart de la page sort de cette liste. */
  --xs: 4px;
  --sm: 8px;
  --md: 14px;
  --lg: 22px;
  --xl: 34px;
  --xxl: 56px;
  --xxxl: 96px;

  --r-frame: 4px;
  --r-card: 10px;
  --r-sheet: 20px;
  --r-pill: 999px;

  /* Rien ne rebondit. Le mouvement glisse et se pose. */
  --t-tap: 110ms;
  --t-quick: 240ms;
  --t-base: 420ms;
  --t-slow: 900ms;
  --ease: cubic-bezier(0.215, 0.61, 0.355, 1);

  --display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --prose: "Literata", Georgia, "Times New Roman", serif;

  color-scheme: dark;
}

[data-theme="papier"] {
  --ground: #FFF9EF;
  --ink: #002EB8;
  --hollow: #F0E5D2;
  --raised: #FFFDF8;
  --glint: #3D5BC7;
  --scrim: #E8DCC6EE;
  color-scheme: light;
}

/* ─── Le socle ───────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.42;
  transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease);
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
svg { display: block; }
.filters { position: absolute; width: 0; height: 0; overflow: hidden; }

a { color: inherit; text-decoration: none; }
code {
  font-family: var(--prose);
  font-size: 0.88em;
  letter-spacing: 0.01em;
  color: var(--ink-soft);
}
abbr { text-decoration: none; border-bottom: var(--hair) dotted var(--rule); }
em { font-style: italic; }

::selection { background: var(--ink); color: var(--ground); }

:focus-visible {
  outline: var(--bold) solid var(--ink);
  outline-offset: 3px;
  border-radius: var(--r-frame);
}

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

.skip {
  position: absolute;
  left: var(--md); top: calc(-1 * var(--xxl));
  z-index: 40;
  padding: var(--sm) var(--md);
  background: var(--ground);
  border: var(--hair) solid var(--ink);
  border-radius: var(--r-frame);
  font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase;
  transition: top var(--t-quick) var(--ease);
}
.skip:focus { top: var(--md); }

.wrap {
  width: min(1120px, calc(100% - 2 * var(--xl)));
  margin-inline: auto;
}
.wrap--narrow { width: min(660px, calc(100% - 2 * var(--xl))); }

/* ─── La voix de l'interface ─────────────────────────────────────────────
   Des capitales espacées, comme sur la couverture. L'interlettrage large
   n'est pas décoratif : sans lui, une capitale à fort contraste devient
   illisible.                                                             */

.part__name, .themes__label, .button, .tally span, .beat__line {
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

.sc { text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.92em; }

/* ─── Le sélecteur de thème ────────────────────────────────────────────── */

/* Un reglage n'est pas une barre de titre.

   Le selecteur reste a portee, mais il se retire des qu'on descend : sur un
   ecran large il passait sur la colonne de droite, et l'application n'a pas
   de barre en travers de la page -- elle n'en a nulle part. Il revient des
   qu'on remonte, ou qu'on revient en haut. */
.themes {
  position: fixed;
  z-index: 30;
  top: var(--md); right: var(--md);
  transition: opacity var(--t-quick) var(--ease),
              transform var(--t-quick) var(--ease),
              visibility var(--t-quick) var(--ease);
  display: flex; align-items: center; gap: var(--md);
  padding: var(--sm) var(--md);
  background: var(--ground);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
}
.themes__label {
  font-size: 11px;
  color: var(--ink-soft);
}
.themes__set { display: flex; gap: var(--xs); }
.themes button {
  appearance: none;
  padding: var(--xs) var(--md);
  background: none;
  border: var(--hair) solid transparent;
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: color var(--t-tap) var(--ease), border-color var(--t-tap) var(--ease);
}
.themes button:hover { color: var(--ink); }
.themes button[aria-checked="true"] {
  color: var(--ink);
  border-color: var(--ink);
  border-width: var(--bold);
}

.themes[data-away] {
  opacity: 0;
  visibility: hidden;
  transform: translateY(calc(-100% - var(--lg)));
}

@media (max-width: 720px) {
  .themes { top: auto; bottom: var(--md); right: 50%; transform: translateX(50%); }
  .themes[data-away] { transform: translateX(50%) translateY(calc(100% + var(--lg))); }
  .themes__label { display: none; }
}

/* ─── L'ouverture ────────────────────────────────────────────────────────
   Le logo n'est pas composé, il est dessiné : c'est une image, stockée en
   blanc sur transparence, et recolorée avec l'encre du thème courant,
   exactement comme les dessins des fiches. Un masque CSS fait ici ce que
   `SRWordmark` fait dans l'application.                                  */

/* La spirale est une rangée, pas un fond.

   Deux jets s'y sont cassé les dents. Le premier la posait en fond derrière un
   bloc de titre centré : les boutons tombaient sur la crête. Le second lui
   réservait sa hauteur en marge basse et centrait le titre dans ce qui
   restait, ce qui marche tant que le reste est plus grand que le titre. Sur un
   écran de portable il ne l'est pas, et les boutons revenaient se poser sur la
   crête, à zéro pixel.

   Elle occupe maintenant une rangée de la grille, sous celle du titre, avec un
   écart minimum qui lui appartient. Le chevauchement n'est plus une question
   de calcul : la grille ne peut pas empiler deux rangées. */
.opening {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: var(--xxxl) 0 0;
  overflow: hidden;
}

.opening__stars,
.opening__vortex {
  position: absolute;
  left: 0; right: 0;
  pointer-events: none;
}
.opening__stars { top: 0; height: 100%; width: 100%; }
/* La spirale deborde par le bas, comme sur la couverture -- mais la couverture
   s'arrete la, et la page continue. On l'efface au degrade plutot que de la
   trancher : un anneau coupe net au milieu d'une page se lit comme un defaut,
   un anneau qui s'eteint se lit comme un horizon. */
.opening__vortex {
  position: relative;
  width: 100%;
  height: var(--vortex-h, 300px);
  /* L'air sous les boutons, et il ne se négocie pas. */
  margin-top: var(--xxl);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, black 0%, black 62%, transparent 100%);
}

.opening__plate {
  position: relative;
  z-index: 2;
  align-self: center;
  width: min(760px, calc(100% - 2 * var(--xl)));
  margin-inline: auto;
  text-align: center;
}

.wordmark { margin: 0; }
.wordmark__art {
  display: block;
  width: min(560px, 78vw);
  aspect-ratio: 1800 / 469;
  margin-inline: auto;
  background-color: var(--ink);
  -webkit-mask: url("assets/wordmark.png") no-repeat center / contain;
  mask: url("assets/wordmark.png") no-repeat center / contain;
  transition: background-color var(--t-base) var(--ease);
}
.wordmark__art--small { width: 180px; }

.signature {
  margin: var(--lg) 0 0;
  font-family: var(--display);
  font-size: 19px;
  font-style: italic;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}

.opening__line {
  margin: var(--xl) 0 0;
  font-family: var(--display);
  font-size: clamp(15px, 1.6vw, 19px);
  text-transform: uppercase;
  letter-spacing: 0.3em;
  color: var(--ink-soft);
}
.opening__line--long {
  margin-top: var(--md);
  font-size: clamp(12px, 1.25vw, 15px);
  letter-spacing: 0.26em;
  color: var(--ink-soft);
}

.opening__acts {
  margin-top: var(--xxl);
  display: flex; gap: var(--md);
  justify-content: center; flex-wrap: wrap;
}

.button {
  display: inline-block;
  /* Un bouton et un lien composés pareil doivent faire la même hauteur : le
     premier ne tient pas l'interligne du corps, le second si. */
  line-height: 1.2;
  padding: var(--md) var(--xl);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
  font-size: 13px;
  color: var(--ink-soft);
  background: none;
  cursor: pointer;
  transition: color var(--t-tap) var(--ease),
              border-color var(--t-tap) var(--ease),
              background-color var(--t-tap) var(--ease);
}
.button:hover { color: var(--ink); border-color: var(--ink); background: var(--fill-faint); }
.button--bold { border-width: var(--bold); border-color: var(--ink); color: var(--ink); }

/* ─── Les sections ─────────────────────────────────────────────────────── */

.section { padding: var(--xxxl) 0; }
.section--thesis { padding-top: var(--xxl); }
.section--absent { padding-bottom: var(--xxxl); }

/* Le filet titré : un filet, un mot en capitales espacées, un filet. C'est
   la seule manière dont l'application nomme ses sections. */
.rule {
  display: flex;
  align-items: center;
  gap: var(--lg);
  margin: 0 0 var(--xl);
  font-weight: 400;
}
.rule::before, .rule::after {
  content: "";
  flex: 1;
  height: var(--hair);
  background: var(--rule);
}
.rule > span {
  font-family: var(--display);
  font-size: clamp(15px, 1.8vw, 17px);
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--ink);
  white-space: nowrap;
}

.lede {
  margin: 0 0 var(--xl);
  font-family: var(--display);
  font-size: clamp(28px, 4.6vw, 46px);
  line-height: 1.14;
  letter-spacing: -0.02em;
  text-align: center;
}

.prose {
  margin: 0 0 var(--lg);
  font-family: var(--prose);
  font-variation-settings: "wght" 430;
  font-size: 17px;
  line-height: 1.76;
  color: var(--ink-soft);
}
.prose--wide { max-width: 62ch; }

/* La dernière ligne de la quatrième de couverture. Elle pose une question au
   lecteur : elle n'est plus du texte de présentation, et elle ne se compose
   pas comme lui. */
.ask {
  margin: var(--xl) 0 0;
  font-family: var(--display);
  font-size: clamp(21px, 2.6vw, 28px);
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
}
.prose:last-child { margin-bottom: 0; }

.note {
  margin: var(--xl) 0 0;
  font-family: var(--prose);
  font-variation-settings: "wght" 430;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--ink-soft);
  border-left: var(--hair) solid var(--rule-faint);
  padding-left: var(--lg);
  max-width: 74ch;
}
.note--tight { margin-top: var(--lg); }

/* ─── Le relevé ─────────────────────────────────────────────────────────
   Une grille est une grille : chaque cellule fait le même bloc, et le
   libellé est une ligne réservée.                                        */

.tally {
  list-style: none;
  margin: var(--xxl) 0 0;
  padding: 0;
  display: grid;
  /* Trois relevés, trois colonnes, une rangée pleine. Le premier jet laissait
     la grille se répartir toute seule, ce qui donnait une case orpheline au
     milieu de son filet. Une grille est une grille. */
  grid-template-columns: repeat(3, 1fr);
  border-top: var(--hair) solid var(--rule-faint);
  border-left: var(--hair) solid var(--rule-faint);
}
.tally li {
  padding: var(--lg) var(--md);
  border-right: var(--hair) solid var(--rule-faint);
  border-bottom: var(--hair) solid var(--rule-faint);
  text-align: center;
}
.tally b {
  display: block;
  font-family: var(--display);
  font-size: 42px;
  line-height: 0.94;
  letter-spacing: -0.03em;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.tally span {
  display: block;
  margin-top: var(--sm);
  font-size: 11px;
  color: var(--ink-soft);
}

/* ─── Le récit ─────────────────────────────────────────────────────────── */

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

.beat {
  display: grid;
  gap: var(--lg);
  padding: var(--xl) 0;
  width: min(1120px, calc(100% - 2 * var(--xl)));
  margin-inline: auto;
}
.beat--bare { padding: var(--xxl) 0; }

/* Le double filet de la couverture : un cadre extérieur, un blanc, un cadre
   intérieur. C'est ce qui transforme une page en objet imprimé, et c'est
   aussi la raison pour laquelle il n'y a pas de cartes ici. */
.plate {
  margin: 0 auto;
  width: min(880px, 100%);
  padding: var(--sm);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-frame);
}
.plate img,
.plate .scene {
  display: block;
  width: 100%;
  border: var(--hair) solid var(--rule-faint);
  border-radius: 2px;
}
/* La boîte des scènes garde le rapport 1,42 de l'`AspectRatio` de
   l'application : le ciel y a été composé pour cette forme, et les cinq
   galaxies s'y placent en fractions de la boîte. */
.plate .scene { aspect-ratio: 1.42; background: var(--fill-faint); }

.beat__line {
  margin: 0;
  text-align: center;
  font-size: clamp(14px, 1.7vw, 19px);
  letter-spacing: 0.24em;
  color: var(--ink);
  text-wrap: balance;
}
.beat__line--after {
  margin-top: var(--md);
  font-size: clamp(12px, 1.4vw, 15px);
  color: var(--ink-soft);
}
.beat__redaction {
  width: min(360px, 60%);
  height: 14px;
  margin: var(--lg) auto 0;
  background: var(--ink);
  border-radius: 2px;
}

/* ─── La bande-annonce ─────────────────────────────────────────────────────
   Une feuille par-dessus la page, posée sur le voile de `SRTheme.scrim`. Le
   film garde son propre cadre : un double filet, comme les plans du récit,
   parce que c'est ainsi que ce livre délimite au lieu d'empiler.          */

.reel__end {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--md);
  flex-wrap: wrap;
  /* Le bouton ferme le récit, il ne prolonge pas son dernier plan : collé à
     la réplique, il se lisait comme une septième phrase. */
  margin: var(--xxl) 0 0;
}
.reel__meta {
  font-family: var(--prose);
  font-variation-settings: "wght" 430;
  font-size: 14px;
  color: var(--ink-soft);
}

.viewer {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: var(--lg);
}
/* `display: grid` sur une classe l'emporte sur le `[hidden]` du navigateur, et
   le lecteur restait ouvert par-dessus la page au chargement. */
.viewer[hidden] { display: none; }
.viewer__scrim {
  position: absolute;
  inset: 0;
  /* Les couleurs de `SRTheme.scrim`, posées un cran plus opaques. Une feuille
     modale sur un téléphone couvre presque tout l'écran ; sur une page de
     bureau, il reste de la place autour, et le logo qui transparaissait
     derrière le film se lisait comme un défaut d'empilement. */
  background: var(--scrim);
}
.viewer__frame {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Le bouton ferme le film, il n'en fait pas partie. À quatorze pixels, sa
     pilule touchait presque le cadre de la vidéo et se lisait comme une
     commande du lecteur. */
  gap: var(--xl);
  max-width: 100%;
  max-height: 100%;
}
.viewer__video {
  display: block;
  width: auto;
  height: auto;
  max-width: min(1080px, 92vw);
  max-height: 76vh;
  background: var(--hollow);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-frame);
}
.viewer__close {
  padding: var(--sm) var(--lg);
  background: none;
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--t-tap) var(--ease), border-color var(--t-tap) var(--ease);
}
.viewer__close:hover { color: var(--ink); border-color: var(--ink); }

/* ─── La carte des chapitres ───────────────────────────────────────────── */

.part { margin-top: var(--xl); }
.part__name {
  margin: 0 0 var(--md);
  font-size: 12px;
  color: var(--ink-soft);
}
.map {
  list-style: none;
  margin: 0; padding: 0;
  border-top: var(--hair) solid var(--rule-faint);
}
.map li {
  display: flex;
  align-items: center;
  gap: var(--md);
  padding: var(--md) var(--xs);
  border-bottom: var(--hair) solid var(--rule-faint);
}
.map li span {
  font-family: var(--display);
  font-size: 13px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  min-width: 2ch;
}
.map li b {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 400;
}
.map--sealed li { padding-left: calc(30px + var(--md)); }
.sealed {
  color: var(--ink-soft);
  font-style: italic;
  font-size: 17px !important;
}

/* ─── La langue zrok ───────────────────────────────────────────────────────
   Une bande d'archive qui décroche, et l'écriture des Zrok qui passe dedans.

   Le film fait le même geste dans sa demi-seconde de perte de signal, et la
   page en porte la table : les fragments, leurs places, leurs tailles et leur
   rythme viennent de `ZROK_FLASH`. Les battements sont écrits en `@keyframes`
   par le script, depuis cette table, pour qu'il n'y en ait qu'une.

   Le tour dure six secondes et compte quatre apparitions, soit deux tiers de
   battement par seconde. Une page qui clignote plus de trois fois par seconde
   met des gens en danger, et il n'y avait aucune raison d'aller vite.       */

.zrok-band {
  position: relative;
  margin-top: var(--xl);
  aspect-ratio: 16 / 5;
  overflow: hidden;
  background: var(--hollow);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-frame);
}
.zrok-band__snow,
.zrok-band__flashes {
  position: absolute;
  inset: 0;
}
.zrok-band__snow { width: 100%; height: 100%; }

/* Les lignes du tube, et la bande qui glisse : deux voiles d'encre, rien de
   plus. On trace, on n'empile pas, même quand on abîme. */
.zrok-band::before,
.zrok-band::after {
  content: "";
  position: absolute;
  pointer-events: none;
}
.zrok-band::before {
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    var(--rule-faint) 0 1px,
    transparent 1px 3px
  );
}
.zrok-band::after {
  left: 0;
  right: 0;
  height: 18px;
  background: linear-gradient(to bottom, transparent, var(--fill), transparent);
  animation: sr-zrok-bande 7s linear infinite;
}
@keyframes sr-zrok-bande {
  from { top: -18px; }
  to { top: 100%; }
}

.zrok-flash {
  position: absolute;
  display: block;
  opacity: 0;
  transform: translate(-50%, -50%);
  will-change: opacity, transform;
}
.zrok-flash svg { height: 100%; width: auto; }
.zrok-stroke { fill: none; stroke: var(--ink); stroke-linecap: round; stroke-linejoin: round; }
.zrok-fill { fill: var(--ink); }

@media (max-width: 720px) {
  .zrok-band { aspect-ratio: 4 / 3; }
}

/* ─── Le livre ─────────────────────────────────────────────────────────────
   La couverture est l'objet, pas une illustration : elle a droit à sa place
   entière, au double filet qui l'encadre comme les plans du récit, et à rien
   par-dessus.                                                              */

.book {
  display: grid;
  grid-template-columns: minmax(240px, 340px) 1fr;
  gap: var(--xxl);
  align-items: start;
  margin-top: var(--xl);
}
.book__cover {
  margin: 0;
  padding: var(--sm);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-frame);
}
.book__cover img {
  width: 100%;
  border: var(--hair) solid var(--rule-faint);
  border-radius: 2px;
}
.book__side { padding-top: var(--sm); }
.book__side .prose b { font-weight: 400; font-style: italic; }

.soon {
  margin: var(--xl) 0 var(--md);
  font-family: var(--display);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--ink-soft);
}
.stores { list-style: none; margin: 0; padding: 0; }
.stores li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--md);
  padding: var(--md) 0;
  border-bottom: var(--hair) solid var(--rule-faint);
}
.stores li:first-child { border-top: var(--hair) solid var(--rule-faint); }
.stores b {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 400;
}
.stores span {
  font-family: var(--display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-soft);
  white-space: nowrap;
}

@media (max-width: 720px) {
  .book { grid-template-columns: 1fr; gap: var(--xl); }
  .book__cover { width: min(300px, 100%); margin-inline: auto; }
}

/* ─── Le pied ──────────────────────────────────────────────────────────── */

.foot {
  padding: var(--xxl) 0 var(--xxxl);
  border-top: var(--hair) solid var(--rule-faint);
  text-align: center;
}
.foot__mark { display: flex; justify-content: center; }
.signature--foot { margin-top: var(--md); font-size: 16px; }
.foot__links {
  list-style: none;
  margin: var(--xl) 0 0;
  padding: 0;
  display: flex; gap: var(--lg);
  justify-content: center; flex-wrap: wrap;
}
.foot__links a {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: var(--hair) solid transparent;
  transition: color var(--t-tap) var(--ease), border-color var(--t-tap) var(--ease);
}
.foot__links a:hover { color: var(--ink); border-color: var(--rule); }
.foot__legal {
  margin: var(--xl) 0 0;
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
}
.foot__legal a {
  border-bottom: var(--hair) solid var(--rule);
  transition: color var(--t-tap) var(--ease), border-color var(--t-tap) var(--ease);
}
.foot__legal a:hover { color: var(--ink); border-color: var(--ink); }

.foot__fine {
  margin: var(--md) auto 0;
  max-width: 60ch;
  font-family: var(--prose);
  font-variation-settings: "wght" 430;
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* ─── Le mouvement ───────────────────────────────────────────────────────
   Une page qu'on tourne, une encre qui apparaît. Rien ne rebondit, et
   `reduceMotion` fige tout, le ciel comme les apparitions.               */

[data-reveal] {
  opacity: 0;
  transform: translateY(var(--md));
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
[data-reveal].is-in { opacity: 1; transform: none; }

@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;
  }
  [data-reveal] { opacity: 1; transform: none; }
  /* La bande se fige sur un seul fragment. Les quatre ont été placés pour se
     succéder ; montrés ensemble, ils se chevauchent en une tache. */
  .zrok-flash { opacity: 0; animation: none !important; }
  .zrok-flash[data-repos] { opacity: 0.72; }
  .zrok-band::after { display: none; }
}

/* ─── Les petits écrans ────────────────────────────────────────────────── */

@media (max-width: 720px) {
  .wrap, .wrap--narrow, .beat { width: calc(100% - 2 * var(--lg)); }
  .section { padding: var(--xxl) 0; }
  .rule { gap: var(--md); }
  .rule > span { font-size: 13px; letter-spacing: 0.2em; white-space: normal; }
  .opening { padding-top: var(--xxl); }
  .beat__line { letter-spacing: 0.18em; }
  .tally b { font-size: 34px; }
  .foot { padding-bottom: var(--xxxl); }
}
