/* Livre ouvert, feuille de base v3 de l'accueil FR.
   Jetons : styles/tokens.css (copié en public/styles/tokens.css) et
   public/styles/largeurs.fr.css (généré par outils/largeurs.py).

   Valeurs nouvelles, hors jetons, et leur raison :
   - 3.375rem (54px), 1.72 et 3.345 : formule de corps du nom (spec 05,
     E2) ; la réserve de la fonction est en rem pour suivre le zoom texte.
   - 0.86 et 0.88 : interlignage serré du nom et des titres, faits de
     capitales sans jambage.
   - 118deg, 1300px, 185svh, 62svh, 84%, 50% 22% : ouverture de la
     couverture, plage de la première page, trame et volets (spec 05).
   - 3px, 7px, 2px, 58px, 3.5rem : rail, rangée secondaire et écart de la
     planche, monogramme, entrées du sommaire (spec 05).
   - 8.25rem, 15.625rem et 7.05 : borne du corps du courriel sur la
     quatrième (132px et 250px au corps par défaut, en rem pour suivre le
     zoom texte). 8.25rem est la largeur laissée à la suite à côté des
     deux lignes ; 15.625rem la réserve pour le h2, les retraits et le pied ; 7.05 la
     longueur en em de la ligne la plus longue à sa largeur
     (nicolassardain.com à 62 %, 6,997 em, plus la marge). Le bloc tient
     ainsi dans 100svh moins la barre.
   - 24% : filet des réseaux sur la couverture (spec 05).
   - Tailles, interlignages, graisses et largeurs des styles de texte
     (corps, chapo, affirmation, petit, fonction, chiffre, annee, source,
     sommaire, titre-bloc) : provisoires, la maquette de référence
     n'étant pas dans le dépôt ; à aligner sur le design system v3.
   - oklch(0 0 0 / 0.45) : voile sous le sommaire, identique dans les
     deux thèmes.
   - Opacités 0.16 et 0.09 des grains (spec 05).
   - Survol des liens : 3px et 2px (épaisseur du trait qui se déroule),
     oklch(0.72 0.11 255) (le bleu du soulignage sur couv en thème clair,
     la valeur de --accent du thème sombre).
   - Double page à partir de 768px (spec 05, abaissé de 1024px le
     11 octobre 2026 pour que l'iPad en portrait l'ait) : 768px (le
     seuil « livre »), 40px (gouttière large), 640px (colonne de lecture),
     1900px et -180deg (pivot sur le dos central), 1.625rem (nom du
     verso), 3.25rem (entrées du sommaire du verso).
   - Accessibilité (spec 08) : 160ms (survol), 3px et 25 % (filet de la
     section courante), 100 % (garde-fou des lignes justifiées). Les media queries ne
     lisent pas les propriétés personnalisées : le seuil est écrit en dur. */

@layer socle, composants, adaptations, mouvement;

/* Hors couche : @property ne se déclare pas dans @layer. */
@supports (animation-timeline: view()) and (timeline-scope: --a) {
  @property --ouv { syntax: "<number>"; inherits: true; initial-value: 0; }
  @property --res { syntax: "<number>"; inherits: true; initial-value: 0; }
}

@layer socle {
  :root {
    --col: min(100vw, var(--colonne));
    --in: calc(var(--col) - 2 * var(--gouttiere));
    --grain-sombre: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.16'/%3E%3C/svg%3E");
    /* Rôles de couleur qui changent avec le thème (valeurs claires ici,
       sombres en fin de feuille). En sombre le livre s'inverse : la
       couverture est une toile claire, le papier est nuit, la quatrième
       reste nuit (papier de fin) et porte le laiton. */
    --grain-couv: var(--grain-clair);
    --q-fond: var(--couv);
    --q-texte: var(--sur-couv);
    --q-filet: color-mix(in oklch, var(--sur-couv) 24%, transparent);
    --q-filet-fort: var(--sur-couv);
    --q-grain: var(--grain-clair);
    --contact-fond: transparent;
    --focus-couv: var(--metal);
    --aplat-fond: var(--metal);
    --aplat-texte: var(--sur-metal);
    --contact-texte: var(--metal);
    --avancement: var(--metal);
    --verso-fond: var(--fond-2);
    --verso-texte: var(--titre);
    --verso-filet: var(--filet);
    /* La toile : les surfaces intérieures qui portent la couleur de la
       couverture le jour (barre, sommaire, bandeau, table des carnets,
       loupe, aplats). Le jour elle vaut couv ; la nuit, lampe de lecture,
       elle devient papier nuit (bloc Nuit) : seules la couverture et le
       verso gardent la toile claire. toile-2 est la surface posée sur le
       papier (sommaire, table, aplats), fond-2 la nuit. */
    --toile: var(--couv);
    --grain-toile: var(--grain-couv);
    --toile-2: var(--couv);
    --sur-toile: var(--sur-couv);
    --toile-titre: var(--sur-couv);
    --toile-filet: color-mix(in oklch, var(--sur-couv) 24%, transparent);
    --toile-bord: var(--sur-couv);
    --toile-bord-doux: color-mix(in oklch, var(--sur-couv) 24%, transparent);
    --toile-ligne: transparent;
    --barre-bas: var(--trait-fort) solid var(--metal);
    --focus-toile: var(--focus-couv);
    --aplat-toile-fond: var(--aplat-fond);
    --aplat-toile-texte: var(--aplat-texte);
    /* Le point de la gouttière : soleil le jour (disque plein) ; la
       nuit, lune en croissant, cernée pour se lire sur la toile claire de
       la couverture, où le laiton seul ne se voit pas. */
    --astre-cerne: none;
    --astre-masque: none;
    --monogramme-lune: none;
    --fleche-carnets: var(--metal);
    /* Le disque « cité » du relevé, sur la page de gauche : l'accent, sauf
       la nuit, où la page de gauche est une toile claire (bloc Nuit). */
    --verso-accent: var(--accent);
    --maison: color-mix(in oklch, var(--sur-couv) 72%, transparent);
    --sv-couv-texte: var(--metal);
    --sv-couv-trait: oklch(0.72 0.11 255);
    --sv-toile-texte: var(--sv-couv-texte);
    --sv-toile-trait: var(--sv-couv-trait);
    --sv-verso-texte: var(--accent-vif);
    --sv-verso-trait: var(--metal);
    --sv-q-texte: var(--metal);
    --sv-q-trait: oklch(0.72 0.11 255);
    --grain-clair: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.09'/%3E%3C/svg%3E");
  }

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

  /* Le fond du document est celui de la couverture et de la quatrième,
     qui ouvrent et ferment chaque page : quand le défilement rebondit au
     bout de la page, sur téléphone, c'est lui qui se montre, et il
     prolonge la quatrième au lieu d'ouvrir une bande claire. Le corps
     garde son fond, qui couvre toute la page. */
  html {
    -webkit-text-size-adjust: 100%;
    background: var(--toile);
  }

  body {
    margin: 0;
    background: var(--dehors);
    color: var(--corps);
    font-family: var(--famille);
    font-size: 1rem;
    line-height: 1.5;
    overflow-x: clip;
  }

  h1, h2, h3, p, ul, ol, figure { margin: 0; }
  ul, ol { padding: 0; list-style: none; }
  img, canvas, svg { display: block; max-width: 100%; }
  a { color: inherit; }
  button { font: inherit; color: inherit; }

  :focus-visible {
    outline: var(--trait-focus) solid var(--accent);
    outline-offset: 2px;
  }
}

@layer composants {
  /* ---- Styles de texte ---- */
  .corps { font-size: 1rem; line-height: 1.5; font-weight: 400; font-stretch: 100%; }
  .chapo { font-size: 1.125rem; line-height: 1.4; font-weight: 600; font-stretch: 90%; color: var(--encre); }
  .affirmation, .titre-phrase {
    font-size: 1.625rem; line-height: 1.1; font-weight: 800; font-stretch: 72%;
    color: var(--titre); text-wrap: balance;
  }
  .petit, .pied { font-size: 0.8125rem; line-height: 1.45; }
  .fonction {
    font-size: 0.8125rem; line-height: 1.3; font-weight: 600; font-stretch: 100%;
  }
  .chiffre { font-stretch: 116%; font-variant-numeric: tabular-nums; }
  .annee {
    font-size: 0.6875rem; font-weight: 600; font-stretch: 116%;
    font-variant-numeric: tabular-nums; color: var(--faible);
  }
  .source, .portes, summary {
    font-size: 0.8125rem; line-height: 1.3; font-weight: 700; font-stretch: 100%;
    color: var(--faible);
  }
  .titre-bloc {
    font-size: 1.25rem; line-height: 1.15; font-weight: 800; font-stretch: 82%;
    color: var(--titre); text-wrap: balance;
  }
  #sommaire a { font-size: 1.25rem; line-height: 1.1; font-weight: 800; font-stretch: 80%; }

  .lien {
    color: var(--accent);
    text-decoration-color: var(--filet-fort);
    text-underline-offset: 0.2em;
  }

  /* ---- Titrage justifié ---- */
  h2 {
    font-size: calc(var(--in) * var(--k-titre));
    line-height: 0.88;
    font-weight: 900;
    color: var(--titre);
    margin-block-end: var(--e-5);
  }
  /* Les capitales : les h2 de section de l'accueil et toute ligne de titre
     justifiée, mesurée en capitales par outils/largeurs.py, et le nom en
     dos de livre. Aucune autre capitale ni interlettrage dans le livre. */
  [data-groupe="titre"] { text-transform: uppercase; }
  /* Les lignes justifiées sont calées sur la colonne en px : le zoom texte
     ne les grossit pas. Garde-fou : jamais plus larges que leur bloc. */
  .ligne {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    font-stretch: var(--w, 100%);
    font-size: calc(1em * var(--f, 1));
  }
  .trio { margin-block: var(--e-5); }
  .trio .ligne {
    font-size: calc(var(--in) * var(--k-trio) * var(--f, 1));
    line-height: 0.95; font-weight: 200; text-transform: uppercase; color: var(--titre);
  }
  /* La source de la parution vedette : un titre de bloc, sous le titre de
     section et au-dessus du titre de l'article. */
  .source-vedette {
    font-size: 1.25rem; line-height: 1.15; font-weight: 800; font-stretch: 82%;
    color: var(--titre);
  }

  /* ---- Lien d'évitement ----
     Premier élément focalisable de chaque page, caché jusqu'au focus. */
  .evitement {
    position: fixed;
    inset-block-start: var(--e-2);
    inset-inline-start: var(--e-2);
    z-index: 10;
    display: inline-flex;
    align-items: center;
    min-height: var(--cible);
    padding-inline: var(--e-4);
    background: var(--toile-2);
    color: var(--sur-toile);
    font-size: 0.8125rem;
    font-weight: 700;
    translate: 0 calc(-100% - var(--e-4));
  }
  .evitement:focus { translate: 0 0; outline-color: var(--focus-toile); }

  /* ---- Colonne ---- */
  .scene, .pages, .quatrieme, .barre, #sommaire {
    width: var(--col);
    margin-inline: auto;
  }
  .pages {
    position: relative;
    z-index: 1;
    background: var(--grain-sombre), var(--fond);
    padding-block-end: var(--e-8);
  }

  /* ---- Couverture ---- */
  .scene { position: relative; z-index: 2; }
  .volume { position: relative; transform-origin: 0 50%; transform-style: preserve-3d; }
  .couverture, .verso { backface-visibility: hidden; }
  .couverture {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    padding: calc(var(--gouttiere) + var(--e-5)) var(--gouttiere) calc(var(--barre) + 2 * var(--gouttiere));
    background: var(--grain-couv), var(--couv);
    color: var(--sur-couv);
  }
  .dos {
    flex: 1;
    min-height: 0;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
  }
  .nom {
    font-size: min(calc((var(--in) - 3.375rem) / 1.72), calc((100svh - var(--barre) - 3 * var(--gouttiere) - var(--e-5)) / 3.345));
    line-height: 0.86;
    font-weight: 900;
    text-transform: uppercase;
  }
  .nom-ligne { display: block; white-space: nowrap; font-stretch: var(--wl); }
  /* Le nom en lignes justifiées du paysage court, caché ailleurs ; le h1
     reste la seule lecture du nom. */
  .nom-paysage { display: none; }
  .nom-a { --wl: var(--wa, 62%); }
  .nom-b { --wl: var(--wb, 62%); }
  .fonction { margin-block-start: var(--e-3); }
  .fonction span { display: block; }
  .fonction span + span { color: var(--maison); }
  .verso {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    transform: rotateY(180deg);
    background: var(--grain-sombre), var(--verso-fond);
    color: var(--verso-texte);
    --survol-texte: var(--sv-verso-texte);
    --survol-trait: var(--sv-verso-trait);
  }
  /* Le monogramme du verso mène en haut de page : en double page, c'est
     le premier lien de la page de gauche. */
  .verso > .marque { display: block; width: 40%; color: inherit; }
  .verso > .marque .monogramme { width: 100%; }
  /* Le verso ne porte son texte et son sommaire qu'en double page. */
  .verso-texte, .verso-sommaire { display: none; }
  .monogramme text { font-family: var(--famille); font-size: 60px; font-weight: 900; font-stretch: 75%; fill: currentColor; }
  /* Le point du monogramme : un disque le jour, une lune en croissant la
     nuit (--monogramme-lune, bloc Nuit), cernée comme le point de la
     gouttière. */
  .monogramme circle {
    fill: var(--metal);
    clip-path: var(--monogramme-lune);
    filter: var(--astre-cerne);
  }

  /* ---- Première page ---- */
  .premiere {
    display: flex;
    flex-direction: column;
    gap: var(--e-5);
    padding: var(--gouttiere);
    background: var(--grain-sombre), var(--fond);
  }
  .trame {
    position: relative;
    width: calc(100% + 2 * var(--gouttiere));
    height: min(calc(var(--col) * 1.25), 62svh);
    margin-inline: calc(-1 * var(--gouttiere));
    margin-block-start: calc(-1 * var(--gouttiere));
    overflow: hidden;
  }
  .trame canvas, .trame img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 22%;
  }
  .trame canvas { display: none; }
  .portes { display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-5); }
  .portes a, .pied a, summary {
    display: inline-flex;
    align-items: center;
    min-height: var(--cible);
  }
  .introduction { display: grid; gap: var(--e-4); padding: var(--e-7) var(--gouttiere) 0; }

  /* ---- Sections ---- */
  .section { display: grid; gap: var(--e-4); padding: var(--e-8) var(--gouttiere) 0; }
  .section > h2 { margin-block-end: var(--e-2); }
  /* Bande sur papier-2 : la section commerciale des accueils EN et DE. */
  .bande {
    margin-block-start: var(--e-7);
    padding-block: var(--e-7);
    background: var(--grain-sombre), var(--fond-2);
  }

  /* Volets */
  .rail { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--e-1); }
  .rail span { height: 3px; background: var(--filet); }
  .curseur { display: none; position: absolute; inset-block-start: 0; inset-inline-start: 0; width: 25%; height: 3px; background: var(--accent); }
  .volets {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 84%;
    gap: var(--e-3);
    margin-inline: calc(-1 * var(--gouttiere));
    padding-inline: var(--gouttiere);
    scroll-padding-inline: var(--gouttiere);
    overflow-x: auto;
    scroll-snap-type: inline mandatory;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
  }
  .volets::-webkit-scrollbar { display: none; }
  .volets article {
    display: grid;
    align-content: start;
    gap: var(--e-3);
    scroll-snap-align: start;
    padding-block-start: var(--e-4);
    border-block-start: var(--trait-fort) solid var(--titre);
  }

  /* Planche d'années */
  .planche {
    position: sticky;
    inset-block-start: env(safe-area-inset-top, 0px);
    z-index: 1;
    display: grid;
    gap: 2px;
    padding-block: var(--e-3);
    background: var(--grain-sombre), var(--fond);
  }
  .cases, .cases-2, .graduations { display: grid; grid-template-columns: repeat(23, 1fr); gap: 2px; }
  .cases span, .cases-2 span { display: flex; flex-direction: column; background: var(--filet); }
  .cases span { height: var(--case); }
  .cases-2 span { height: 7px; }
  .cases-2 span:first-child { grid-column-start: 17; }
  .cases i, .cases-2 i { flex: 1; background: var(--titre); }
  .graduations { padding-block-start: var(--e-1); }
  .graduations span { white-space: nowrap; }
  .g2004 { grid-column: 1; }
  .g2010 { grid-column: 7; justify-self: center; }
  .g2020 { grid-column: 17; justify-self: center; }
  .g2026 { grid-column: 23; justify-self: end; }
  .k0 { --k: 0; } .k1 { --k: 1; } .k2 { --k: 2; } .k3 { --k: 3; } .k4 { --k: 4; }
  .k5 { --k: 5; } .k6 { --k: 6; } .k7 { --k: 7; } .k8 { --k: 8; } .k9 { --k: 9; } .k10 { --k: 10; }
  .etape, .international { display: grid; gap: var(--e-3); padding-block-start: var(--e-5); }

  /* Parutions */
  .parutions { display: grid; gap: var(--e-6); }
  .parutions li { display: grid; gap: var(--e-2); }
  .source span + span::before, .source span + time::before { content: "· "; }
  details { border-block-start: var(--trait) solid var(--filet); }
  /* Le résumé se lit comme un lien qu'on déplie : en accent, avec un signe
     plus qui devient moins à l'ouverture, le triangle natif ne s'affichant
     plus en display flex. */
  summary { cursor: pointer; gap: var(--e-2); color: var(--accent); list-style: none; }
  summary::-webkit-details-marker { display: none; }
  summary::after { content: "+"; font-size: 1rem; line-height: 1; }
  details[open] summary::after { content: "\2212"; }
  summary:hover { color: var(--accent-vif); }
  details[open] summary { margin-block-end: var(--e-5); }

  /* ---- Quatrième de couverture ---- */
  .cran { display: block; }
  /* Dans l'ordre : le titre, le courriel (l'action principale, rien ne le
     précède), les réseaux, « Poursuivre » (les carnets, ou le billet
     voisin), la ligne légale. En colonne, le courriel est en dos de livre
     à gauche, les réseaux puis la suite s'alignent en bas à droite. */
  .quatrieme {
    position: relative;
    z-index: 0;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto 1fr auto auto;
    grid-template-areas: "titre titre" "mail reseaux" "mail suite" "pied pied";
    gap: var(--e-5) var(--e-4);
    min-height: 100svh;
    padding: var(--e-7) var(--gouttiere) calc(var(--barre) + env(safe-area-inset-bottom, 0px) + var(--e-3));
    background: var(--q-grain), var(--q-fond);
    color: var(--q-texte);
  }
  .quatrieme h2 { grid-area: titre; color: var(--q-texte); margin: 0; }
  .quatrieme :focus-visible { outline-color: var(--metal); }
  .couverture :focus-visible { outline-color: var(--focus-couv); }
  .barre :focus-visible, #sommaire :focus-visible { outline-color: var(--focus-toile); }
  .courriel {
    grid-area: mail;
    align-self: end;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: min(calc((var(--in) - 8.25rem) / 2), calc((100svh - var(--barre) - 15.625rem) / 7.05));
    line-height: 0.95;
    font-weight: 900;
  }
  .courriel a { display: block; color: var(--metal); text-decoration: none; }
  .poursuivre {
    grid-area: suite;
    align-self: end;
    min-width: 0;
    padding-block-start: var(--e-3);
    border-block-start: var(--trait-fort) solid var(--q-filet-fort);
    font-size: 0.8125rem; line-height: 1.3; font-weight: 700;
  }
  .poursuivre a { display: inline-flex; align-items: center; min-height: var(--cible); color: var(--q-texte); }
  .poursuivre .poursuivre-billet { display: grid; gap: var(--e-1); text-decoration: none; }
  .poursuivre .dates {
    font-size: 0.6875rem; font-weight: 600; font-stretch: 116%; font-variant-numeric: tabular-nums;
    color: color-mix(in oklch, var(--q-texte) 72%, transparent);
  }
  .poursuivre-titre { font-size: 1.625rem; line-height: 1.05; font-weight: 800; font-stretch: 62%; }
  /* L'aperçu du dernier billet (accueils) : la photo de couverture au-dessus
     de la date et du titre. */
  .poursuivre-apercu picture, .poursuivre-apercu img {
    display: block;
    inline-size: 100%;
    max-inline-size: 20em;
    block-size: auto;
  }
  .poursuivre-apercu picture { margin-block-end: var(--e-2); }
  .poursuivre .poursuivre-billet:hover .poursuivre-titre { color: var(--survol-texte); }
  .reseaux {
    grid-area: reseaux;
    align-self: end;
    display: flex;
    flex-wrap: wrap;
    gap: 0 var(--e-4);
    min-width: 0;
    font-size: 0.8125rem;
    font-weight: 600;
  }
  .reseaux a { display: inline-flex; align-items: center; min-height: var(--cible); color: var(--q-texte); }
  .pied { grid-area: pied; display: flex; flex-wrap: wrap; gap: 0 var(--e-4); align-items: center; }
  .pied span { text-decoration: none; }

  /* ---- Barre du pouce ---- */
  .barre {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 3;
    display: grid;
    grid-template-columns: 1fr 58px 1fr;
    align-items: center;
    height: calc(var(--barre) + env(safe-area-inset-bottom, 0px));
    padding-block-end: env(safe-area-inset-bottom, 0px);
    background: var(--grain-toile), var(--toile);
    color: var(--sur-toile);
    box-shadow: inset 0 var(--trait) 0 var(--toile-ligne);
  }
  .barre button, .barre a {
    display: flex;
    align-items: center;
    min-height: var(--cible);
    padding-inline: var(--gouttiere);
    background: none;
    border: 0;
    font-size: 0.8125rem;
    line-height: 1.45;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
  }
  .barre .marque { justify-content: center; padding: 0; width: 58px; }
  .barre .marque svg { width: 40px; }
  /* La flèche du monogramme (accueils) : cachée, elle ne paraît que le
     temps du signal de la couche mouvement. */
  .barre .marque svg { overflow: visible; }
  .barre .fleche {
    fill: none;
    stroke: var(--metal);
    stroke-width: 7;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0;
  }
  .barre .contact { justify-self: end; color: var(--contact-texte); background: var(--contact-fond); }
  .avancement {
    display: none;
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: 2px;
    background: var(--avancement);
    transform-origin: 0 50%;
  }

  /* ---- Sommaire ---- */
  #sommaire {
    position: fixed;
    inset: auto 0 0;
    margin-block: 0;
    max-height: 90svh;
    overflow-y: auto;
    padding: var(--gouttiere) var(--gouttiere) calc(var(--gouttiere) + env(safe-area-inset-bottom, 0px));
    border: 0;
    background: var(--grain-toile), var(--toile-2);
    color: var(--sur-toile);
  }
  /* La bascule Midi / Minuit (scripts/bascule.js), cachée sans script. */
  .bascule[hidden] { display: none; }
  .bascule { cursor: pointer; font: inherit; display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2); }
  .bascule-icone { width: 1.15em; height: 1.15em; flex: none; }
  /* Les trois choix côte à côte ; le choix en cours est marqué
     (aria-pressed), en aplat dans le sommaire, souligné ailleurs. */
  .bascule-choix { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--e-4); }
  .bascule[aria-pressed="true"] { cursor: default; }
  #sommaire .bascule-choix {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
    margin-block-end: var(--e-3);
  }
  #sommaire .bascule {
    border-color: var(--toile-bord-doux);
    color: var(--sv-toile-texte);
  }
  #sommaire .bascule + .bascule { border-inline-start: 0; }
  #sommaire .bascule[aria-pressed="true"] {
    background: var(--sur-toile);
    border-color: var(--sur-toile);
    color: var(--toile-2);
  }
  #sommaire::backdrop { background: oklch(0 0 0 / 0.45); }
  #sommaire li a {
    display: flex;
    align-items: center;
    min-height: 3.5rem;
    text-decoration: none;
    border-block-end: var(--trait) solid var(--toile-filet);
  }
  /* Les intertitres du sommaire : « Sur cette page » sépare les sections
     de la page des autres pages du site (« Sur le site »), « Dans ce
     billet » la découpe d'un billet. */
  .sommaire-intertitre {
    margin-block: var(--e-5) var(--e-1);
    font-size: 0.6875rem; line-height: 1.45; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--metal);
  }
  #sommaire > .sommaire-intertitre:first-child { margin-block-start: 0; }
  /* Le second groupe se détache : un filet fort et de l'air au-dessus,
     des entrées d'un cran plus petites, une flèche en bout de ligne,
     puisqu'elles mènent à une autre page. */
  #sommaire .sommaire-intertitre ~ .sommaire-intertitre {
    margin-block-start: var(--e-6);
    padding-block-start: var(--e-4);
    border-block-start: var(--trait-fort) solid var(--toile-bord);
  }
  #sommaire ol:has(+ .sommaire-intertitre ~ .sommaire-intertitre) li:last-child a,
  #sommaire .sommaire-intertitre + ol:has(+ .sommaire-intertitre) li:last-child a { border-block-end: 0; }
  #sommaire .sommaire-intertitre ~ .sommaire-intertitre + ol a {
    justify-content: space-between;
    min-height: 3rem;
    font-size: 1.0625rem;
  }
  #sommaire .sommaire-intertitre ~ .sommaire-intertitre + ol a::after {
    content: "\2192";
    content: "\2192" / "";
    color: var(--metal);
  }
  #sommaire .langues { display: flex; gap: var(--e-5); margin-block: var(--e-4); }
  #sommaire .langues a { display: inline-flex; align-items: center; min-height: var(--cible); font-size: 0.75rem; font-weight: 700; }
  #sommaire button {
    width: 100%;
    min-height: var(--cible);
    background: var(--toile-2);
    color: var(--sur-toile);
    border: var(--trait) solid var(--toile-bord);
    font-weight: 700;
    cursor: pointer;
  }
}

@layer composants {
  /* ---- Deux familles de liens (accueils) ----
     Le lien de suite (« Lire l'article », « Lire les carnets ») se lit,
     l'appel de fin de section engage. Le premier : couleur du texte, sans
     soulignement, précédé d'un filet court en métal qui s'allonge au
     survol et au focus. Le second : un objet typographique sur la largeur
     de la section, entre deux filets de titre, numéro de section à gauche,
     libellé en capitales espacées, flèche métal à droite, seule à bouger. */
  .lien-suite {
    display: inline-flex;
    align-items: center;
    gap: var(--e-3);
    min-height: var(--cible);
    color: var(--corps);
    font-weight: 600;
    text-decoration: none;
  }
  .lien-suite::before {
    content: "";
    flex: none;
    inline-size: var(--e-5);
    block-size: var(--trait-fort);
    background: var(--metal);
    transform-origin: 0 50%;
  }

  .cta-section {
    display: flex;
    align-items: center;
    gap: var(--e-4);
    inline-size: 100%;
    min-height: var(--cible-liste);
    padding-inline-end: var(--e-2);
    border-block: var(--trait) solid var(--titre);
    color: var(--titre);
    text-decoration: none;
  }
  .cta-num {
    flex: none;
    font-size: 0.6875rem; font-weight: 600; font-stretch: 116%;
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--interlettrage);
    color: var(--faible);
  }
  .cta-libelle {
    flex: 1;
    font-size: 0.8125rem; line-height: 1.3; font-weight: 700;
    letter-spacing: var(--interlettrage);
  }
  .cta-fleche {
    flex: none;
    font-size: 1.25rem; line-height: 1; font-weight: 700;
    color: var(--metal);
  }
  /* L'appel vers les carnets, a la fin de « En dehors de mes fonctions ».
     Pas de numero : il ne renvoie pas a une section du livre mais a une
     autre rubrique. Le libelle s'ecrit en casse normale et s'affiche en
     capitales. La fleche est le ↓ d'Archivo tourne vers la droite :
     Archivo n'a pas de →, et un telephone en empruntait une maigre. */
  /* L'aplat : la couleur et le grain de la couverture, comme une petite
     couverture posee dans la page, bleu nuit le jour, toile claire la
     nuit. Sans filets, l'aplat les remplace. La fleche est en metal sur
     le bleu, en sur-couv sur la toile claire (bloc Nuit). */
  .cta-carnets {
    margin-block-start: var(--e-5);
    min-height: calc(var(--cible-liste) * 1.4);
    padding-inline: var(--e-5);
    border: 0;
    background: var(--grain-couv), var(--couv);
    color: var(--sur-couv);
  }
  .cta-carnets .cta-fleche { color: var(--fleche-carnets); }
  .cta-carnets:focus-visible { outline-offset: 3px; }
  .cta-carnets .cta-libelle { font-size: 1.0625rem; text-transform: uppercase; }
  .cta-carnets .cta-fleche { inline-size: 1em; text-align: center; font-size: 1.75rem; transform: rotate(-90deg); }

  /* ---- La parution vedette, cliquable en entier ----
     Le lien de suite étend sa zone au bloc par un ::after ; le DOM ne
     bouge pas, le volet « Trois autres parutions » reste hors du bloc. Un
     carré à filet de titre, flèche ↗ non lue, marque le bloc ; il se
     remplit au survol et au focus du lien. */
  .parutions .vedette { position: relative; padding-inline-end: calc(var(--cible) + var(--e-4)); }
  .vedette .lien-suite::after { content: ""; position: absolute; inset: 0; }
  .vedette::after {
    /* \FE0E demande la forme texte : sans lui, iOS dessinait l'emoji. */
    content: "\2197\FE0E" / "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-end: 0;
    display: grid;
    place-items: center;
    inline-size: var(--cible);
    block-size: var(--cible);
    border: var(--trait) solid var(--titre);
    color: var(--titre);
    font-size: 1.25rem; line-height: 1;
    pointer-events: none;
  }
  .vedette:has(.lien-suite:hover, .lien-suite:focus-visible)::after {
    background: var(--titre);
    color: var(--fond);
  }
}

@layer composants {
  /* ---- Survol des liens, sur tout le site ----
     Au survol, un trait se déroule sous le lien. Sur fond sombre (couv,
     quatrième, barre, sommaire, page de titre, loupe, et tout le thème
     sombre), le texte passe en jaune métal sur un trait bleu. Sur le papier
     clair, le jaune ne se lirait pas : le texte reste bleu et c'est le trait
     qui est jaune. Les entrées en liste (sommaires, plan, réseaux) changent
     seulement de couleur ; les aplats (Contact) et les images ne bougent
     pas. */
  :root {
    --survol-texte: var(--accent-vif);
    --survol-trait: var(--metal);
    --survol-epaisseur: 3px;
  }
  .couverture {
    --survol-texte: var(--sv-couv-texte);
    --survol-trait: var(--sv-couv-trait);
    --survol-epaisseur: 2px;
  }
  .barre, #sommaire, .bandeau, .loupe {
    --survol-texte: var(--sv-toile-texte);
    --survol-trait: var(--sv-toile-trait);
    --survol-epaisseur: 2px;
  }
  .quatrieme {
    --survol-texte: var(--sv-q-texte);
    --survol-trait: var(--sv-q-trait);
    --survol-epaisseur: 2px;
  }
  .lien, .portes a, .pied a, #sommaire .langues a, .verso-langues a:not(.verso-contact),
  .prose a:not(.bil-loupe), .legal a, .fil a, .retour a, .entree .titre-bloc a,
  .pied-page a:not(.contact-metal), .verso-sommaire li a, .verso-langues .bascule,
  .pied-page .bascule, .reseaux a, .poursuivre a:not(.poursuivre-billet) {
    background-image: linear-gradient(var(--survol-trait), var(--survol-trait));
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% var(--survol-epaisseur);
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
  }
  /* Les liens à cible tactile (44px, texte centré) : le trait se pose
     sous la ligne de texte, pas au bas de la cible. */
  .portes a, .pied a, #sommaire .langues a, .verso-langues a:not(.verso-contact),
  .fil a, .retour a, .pied-page a:not(.contact-metal), .verso-sommaire li a,
  .verso-langues .bascule, .pied-page .bascule, .reseaux a, .poursuivre a:not(.poursuivre-billet) {
    background-position: 0 calc(50% + 0.8em);
  }
  /* Les entrées du sommaire du verso : le trait suit le texte, pas la
     ligne entière. */
  .verso-sommaire li a { width: fit-content; }
  .lien:hover, .portes a:hover, .pied a:hover, #sommaire .langues a:hover,
  .verso-langues a:not(.verso-contact):hover, .prose a:not(.bil-loupe):hover,
  .legal a:hover, .fil a:hover, .retour a:hover, .entree .titre-bloc a:hover,
  .pied-page a:not(.contact-metal):hover, .verso-sommaire li a:hover,
  .verso-langues .bascule:hover, .pied-page .bascule:hover, .reseaux a:hover,
  .poursuivre a:not(.poursuivre-billet):hover,
  .verso-langues .bascule[aria-pressed="true"], .pied-page .bascule[aria-pressed="true"] {
    color: var(--survol-texte);
    text-decoration-color: transparent;
    background-size: 100% var(--survol-epaisseur);
  }
  #sommaire li a:hover, .plan a:hover {
    color: var(--survol-texte);
  }
}

@layer composants {
  /* ---- Le point de la gouttière (accueils) ----
     La hauteur du soleil en Charente : haut quand le soleil est haut, bas
     quand il est bas. La nuit, le même point est la lune. Décoratif
     (aria-hidden), hors du focus, et absent sans script : --soleil vient
     de /scripts/lumiere.js. Sur téléphone, il longe le dos de la
     couverture, plus petit ; en double page, il se pose dans le pli, sur
     la hauteur de la première double page, et part avec elle au
     défilement. */
  .astre { display: none; }
  :root[data-lumiere] .astre {
    --astre: 8px;
    --marge-astre: var(--e-7);
    display: block;
    position: absolute;
    z-index: 3;
    inset-inline-start: var(--e-1);
    top: calc(var(--marge-astre) + (1 - var(--soleil, 0)) / 2 * (100svh - 2 * var(--marge-astre) - var(--astre)));
    inline-size: var(--astre);
    block-size: var(--astre);
    pointer-events: none;
    filter: var(--astre-cerne);
  }
  /* Le soleil le jour : un disque plein. La lune la nuit : le même
     disque, échancré en croissant, cerné de bleu nuit pour se lire sur la
     toile claire de la couverture (bloc Nuit). */
  .astre::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--metal);
    -webkit-mask: var(--astre-masque);
    mask: var(--astre-masque);
  }
}

@layer composants {
  /* Texte pour le seul lecteur d'écran : hors de la vue, pas hors de
     l'arbre d'accessibilité. */
  .masque {
    position: absolute;
    inline-size: 1px; block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* ---- Le relevé « Cité par » (accueils) ----
     Quels assistants IA citent le site, et à quelle date : un colophon,
     lisible en trois secondes. Écrit par outils/releve_ia.py d'après
     data/releve-ia.json. Disque plein dans l'accent si cité, cercle vide
     au filet sinon ; le mot est dit au lecteur d'écran. Deux exemplaires :
     .releve-flux, le seul lu, sous la couverture sur téléphone et fixé dans
     la page de gauche du premier écran en double page ; .releve-verso, sa
     copie décorative dans la page de gauche du sommaire, qui le recouvre à
     l'ouverture. Les couleurs passent par --releve-*, posées par
     emplacement. */
  .releve {
    --releve-texte: var(--titre);
    --releve-faible: var(--faible);
    --releve-accent: var(--accent);
    --releve-filet: var(--filet);
    display: grid;
    gap: var(--e-3);
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--releve-faible);
  }
  .releve-flux { padding: var(--e-7) var(--gouttiere) 0; }
  .releve-verso { display: none; }
  .releve .releve-titre {
    margin: 0;
    font-size: 0.6875rem; line-height: 1.2; font-weight: 700; font-stretch: 116%;
    letter-spacing: var(--interlettrage);
    text-transform: uppercase;
    color: var(--releve-texte);
  }
  .releve-liste { margin: 0; padding: 0; list-style: none; border-block-start: var(--trait) solid var(--releve-filet); }
  .releve-liste li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--e-3);
    padding-block: var(--e-2);
    border-block-end: var(--trait) solid var(--releve-filet);
  }
  .releve-nom { font-weight: 600; color: var(--releve-texte); }
  .releve-marque {
    inline-size: 0.625rem; block-size: 0.625rem;
    border-radius: 50%;
    border: var(--trait) solid var(--releve-texte);
  }
  .releve-oui { background: var(--releve-accent); border-color: var(--releve-accent); }
  .releve-date { font-variant-numeric: tabular-nums; }
  .releve-pied { margin: 0; }
}

/* ---- Découpe de la page de gauche (décision du 10 octobre 2026) ----
   En double page, livre fermé, la phrase « Mesurer avant de généraliser. » évidée
   dans la moitié gauche, là où la couverture se pose au premier geste.
   Ornement (aria-hidden), pas du contenu. Les lettres laissent voir la
   couverture, sa couleur et son grain, dans les deux thèmes. Fixée sous
   la scène (z-index 1, comme le relevé), elle est recouverte par la
   couverture qui pivote, puis par le verso au repos ; sans mouvement, le
   livre est posé ouvert et le verso la cache d'emblée. Aucune animation
   propre. Lignes de titre ordinaires : largeurs.py les mesure. Elles
   remplissent la largeur de la page, ou la hauteur si elle manque :
   4.701 est la hauteur du bloc en corps, soit la somme des --f des
   quatre lignes (interligne 1 : les accents de GÉNÉRA ne touchent pas
   la ligne du dessus). Absente tant que la page porte le relevé (Staging) :
   le relevé la remplacera. Bloc unique, à supprimer en entier avec les
   quatre lignes des accueils. */
@layer composants {
  .decoupe { display: none; }
  @media (min-width: 768px) and (min-height: 501px) {
    .decoupe {
      position: fixed;
      z-index: 1;
      inset-block: 40px;
      inset-inline-start: 40px;
      inline-size: calc(var(--gauche) - 80px);
      display: grid;
      align-content: center;
      overflow: hidden;
      container-type: size;
      color: transparent;
      background: var(--grain-couv), var(--couv);
      -webkit-background-clip: text;
      background-clip: text;
      pointer-events: none;
    }
    body:has(.releve-flux) .decoupe { display: none; }
    .decoupe .ligne {
      font-size: calc(min(100cqw * var(--k-titre), 100cqh / 4.701) * var(--f, 1));
      line-height: 1;
      font-weight: 900;
    }
    @supports not ((background-clip: text) or (-webkit-background-clip: text)) {
      .decoupe { color: var(--couv); background: none; }
    }
    @media (forced-colors: active) {
      .decoupe { display: none; }
    }
  }
}

/* ---- Nuit : le livre inversé, devenu lampe de lecture ----
   Seules les variables de rôle changent, sous l'état de lumière nuit
   (/scripts/lumiere.js, data-lumiere). La couverture de l'accueil et son
   verso restent une toile claire (couv, grain sombre) ; tout le reste,
   barre, sommaire, bandeau, table des carnets, aplats et quatrième, est
   papier nuit : fond, fond-2 pour ce qui se pose dessus, encre, filets,
   laiton pour Contact. Le crépuscule garde les rôles du jour. */
:root[data-lumiere="nuit"] {
  --grain-couv: var(--grain-sombre);
  --q-fond: var(--fond); --q-texte: var(--encre); --q-filet: var(--filet);
  --q-filet-fort: var(--encre); --q-grain: var(--grain-sombre);
  --contact-fond: var(--metal); --contact-texte: var(--sur-metal);
  --aplat-fond: var(--sur-couv); --aplat-texte: var(--couv); --focus-couv: var(--sur-couv);
  --verso-fond: var(--couv); --verso-texte: var(--sur-couv);
  --verso-filet: color-mix(in oklch, var(--sur-couv) 24%, transparent);
  --verso-accent: var(--sur-couv);
  --toile: var(--fond); --toile-2: var(--fond-2);
  --sur-toile: var(--encre); --toile-titre: var(--titre);
  --toile-filet: var(--filet); --toile-bord: var(--filet-fort); --toile-bord-doux: var(--filet-fort);
  --toile-ligne: var(--filet); --barre-bas: var(--trait) solid var(--filet);
  --focus-toile: var(--metal);
  --aplat-toile-fond: var(--metal); --aplat-toile-texte: var(--sur-metal);
  --astre-cerne: drop-shadow(0 0 1px var(--sur-couv)) drop-shadow(0 0 1px var(--sur-couv));
  --monogramme-lune: path(evenodd, "M-2 -2 H14 V14 H-2 Z M5 3.5 a4.8 4.8 0 1 0 9.6 0 a4.8 4.8 0 1 0 -9.6 0 Z");
  --astre-masque: radial-gradient(circle at 72% 30%, transparent 46%, #000 48%);
  --fleche-carnets: var(--sur-couv);
  --survol-texte: var(--metal); --survol-trait: var(--accent);
  --sv-couv-texte: var(--sur-couv); --sv-couv-trait: var(--metal-vif);
  --sv-toile-texte: var(--metal); --sv-toile-trait: var(--accent);
  --sv-verso-texte: var(--sur-couv); --sv-verso-trait: var(--metal-vif);
  --sv-q-texte: var(--metal); --sv-q-trait: var(--accent);
}

@layer adaptations {
  /* Ouverture : posée par scripts/couverture.js hors réduction de mouvement. */
  .ouvre .scene {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    height: 100svh; height: 100dvh;
    pointer-events: none;
    perspective: 1300px;
    perspective-origin: 0 50%;
  }
  /* Les pages fixes (scène du livre, table des carnets, page de titre des
     pages légales) prennent 100dvh après 100svh : sur iPad, quand la barre
     de Safari se replie, la fenêtre grandit, et une hauteur en svh
     laissait sous elles une bande du fond. La couverture suit la scène
     (100 % du volume) : en 100svh, elle laissait cette même bande sous
     elle, livre fermé. */
  .ouvre .volume {
    height: 100%;
    pointer-events: auto;
    transform: rotateY(calc(var(--ouv, 0) * -118deg));
  }
  .ouvre .couverture { height: 100%; }
  .ouvre.ouvert .scene { visibility: hidden; }
  .ouvre .cadre::after { content: ""; display: block; height: 185svh; }
  .ouvre .premiere { position: sticky; inset-block-start: 0; }
  .ouvre .trame canvas { display: block; opacity: calc(1 - var(--res, 0)); }
  .ouvre .trame img { opacity: var(--res, 0); }

  /* ---- Double page, à partir de 768px ----
     Le livre est posé ouvert à plat : la page de droite porte la
     couverture puis les pages, la page de gauche le verso. Barre et
     sommaire en popover disparaissent, le verso les remplace. */
  @media (min-width: 768px) and (min-height: 501px) {
    /* Le pli n'est pas au milieu : la page de gauche, qui porte le
       sommaire, prend 44 % de la largeur, et la page de droite, qui porte
       le texte, le reste. Tout ce qui se pose sur l'une ou l'autre page lit
       --gauche, jamais une moitié écrite en dur. */
    :root {
      --gauche: 44vw;
      --col: calc(100vw - var(--gauche));
      --gouttiere: max(40px, calc((var(--col) - 720px) / 2));
      --barre: 0px;
    }
    .pages, .quatrieme { margin-inline: var(--gauche) 0; }
    :root[data-lumiere] .astre { --astre: 14px; inset-inline-start: calc(var(--gauche) - var(--astre) / 2); }
    /* Le relevé dans la page de gauche : fixé au premier écran, sous la
       scène (z-index 2), que le verso recouvre à l'ouverture ; sa copie
       prend place dans le verso, entre la fonction et le sommaire. */
    .releve-flux {
      position: fixed;
      z-index: 1;
      inset-block-start: 50%;
      inset-inline-start: 40px;
      inline-size: min(calc(var(--gauche) - 80px), 22rem);
      padding: 0;
      translate: 0 -50%;
    }
    .releve-verso {
      --releve-texte: var(--verso-texte);
      /* Pleine encre : le gris à 72 % de la fonction tombait à 3:1. */
      --releve-faible: var(--verso-texte);
      --releve-accent: var(--verso-accent);
      --releve-filet: var(--verso-filet);
      display: grid;
      inline-size: min(100%, 22rem);
      margin-block-start: var(--e-7);
    }
    .barre, #sommaire { display: none; }

    /* Le verso : page de gauche, filet à droite. Papier-2 en clair, toile
       claire (couv) en sombre. */
    .verso {
      display: flex;
      flex-direction: column;
      gap: var(--e-5);
      place-items: stretch;
      padding: 40px;
      border-inline-end: var(--trait) solid var(--verso-filet);
    }
    .ouvre .verso { padding-inline-start: calc(40px + var(--col) - var(--gauche)); }
    /* Le nom et la fonction, couchés en dos de livre, se centrent dans la
       largeur de la couverture : calés sur sa hauteur, ils n'en prennent
       qu'une partie, et restaient collés à gauche. */
    .dos { align-content: center; }
    .verso > .marque { width: 96px; }
    .verso-texte { display: grid; gap: var(--e-2); }
    .verso-nom {
      font-size: 1.625rem; line-height: 1.1; font-weight: 800; font-stretch: 62%;
      color: var(--verso-texte);
    }
    .verso .fonction { color: var(--verso-texte); }
    .verso .fonction span + span { color: color-mix(in oklch, var(--verso-texte) 72%, transparent); }
    .verso-sommaire { display: block; margin-block-start: auto; }
    .verso-sommaire ol { border-block-start: var(--trait-fort) solid var(--verso-texte); }
    .verso-sommaire li { border-block-end: var(--trait) solid var(--verso-filet); }
    .verso-sommaire a { color: var(--verso-texte); text-decoration: none; }
    .verso-sommaire li a {
      position: relative;
      display: flex;
      align-items: center;
      min-height: 3.25rem;
      font-size: 0.875rem; font-weight: 700;
    }
    .verso-langues {
      display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2) var(--e-5);
      margin-block-start: var(--e-5);
      font-size: 0.8125rem; font-weight: 700;
    }
    .verso-langues a { display: inline-flex; align-items: center; min-height: var(--cible); }
    .verso-langues .bascule {
      display: inline-flex; align-items: center; min-height: var(--cible);
      padding: 0; background-color: transparent; border: 0; color: var(--verso-texte);
      font-size: 0.8125rem; font-weight: 700;
    }
    /* Le survol commun (couche composants) : la couleur d'ici le masquerait. */
    .verso-sommaire li a:hover, .verso-langues .bascule:hover { color: var(--survol-texte); }
    /* La section visible (scripts/couverture.js) : un filet métal de 3px à
       gauche de son entrée. */
    .verso-sommaire a[aria-current="true"]::before {
      content: "";
      position: absolute;
      inset-block: 25%;
      inset-inline-start: calc(-1 * var(--e-3));
      width: 3px;
      background: var(--metal);
    }
    .verso-langues .verso-contact {
      margin-inline-start: auto;
      padding-inline: var(--e-4);
      background: var(--aplat-fond);
      color: var(--aplat-texte);
    }
    .verso-langues .verso-contact:hover { background: var(--metal-vif); color: var(--sur-metal); }

    /* Quatrième : le courriel à l'horizontale sur deux lignes justifiées
       à la colonne de lecture ; dessous, chacun sous son filet, les
       réseaux à gauche, en liste à la taille du titre du billet pour ne
       pas faire note de bas de page, et la suite à droite, sa photo
       réduite pour ne pas prendre le pas sur le titre. */
    .quatrieme {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
      grid-template-rows: auto auto auto 1fr;
      grid-template-areas: "titre titre" "mail mail" "reseaux suite" "pied pied";
      column-gap: var(--e-6);
    }
    .courriel {
      align-self: start;
      writing-mode: horizontal-tb;
      transform: none;
      font-size: calc(var(--in) * var(--k-courriel));
    }
    .poursuivre, .reseaux { align-self: stretch; }
    .poursuivre-apercu picture, .poursuivre-apercu img { max-inline-size: 11em; }
    .reseaux {
      flex-direction: column;
      flex-wrap: nowrap;
      align-items: flex-start;
      gap: 0;
      margin: 0;
      padding-block-start: var(--e-3);
      border-block-start: var(--trait-fort) solid var(--q-filet-fort);
      font-size: 1.625rem;
      line-height: 1.05;
      font-weight: 800;
      font-stretch: 62%;
    }
    .pied { align-self: end; }

    /* Volets : deux colonnes, sans défilement ni rail. */
    .rail { display: none; }
    .volets {
      grid-auto-flow: row;
      grid-template-columns: 1fr 1fr;
      grid-auto-columns: auto;
      gap: var(--e-6) var(--e-5);
      margin-inline: 0;
      padding-inline: 0;
      overflow: visible;
    }

    /* Sans mouvement : le livre est posé ouvert, verso fixe à gauche, pas
       de couverture. */
    :root:not(.ouvre) .scene {
      position: fixed;
      inset-block-start: 0;
      inset-inline-start: 0;
      width: var(--gauche);
      height: 100svh; height: 100dvh;
    }
    :root:not(.ouvre) .volume { height: 100%; }
    :root:not(.ouvre) .couverture { display: none; }
    :root:not(.ouvre) .verso { position: absolute; inset: 0; transform: none; backface-visibility: visible; }

    /* Avec mouvement : la couverture couvre la page de droite et pivote
       sur le pli pour se poser à gauche, verso visible. Elle a la largeur
       de la page de droite, plus large que celle de gauche : retournée, elle
       déborde de l'écran à gauche, de la différence entre les deux pages,
       et le verso décale son contenu d'autant. */
    .ouvre .scene {
      inset-inline: var(--gauche) 0;
      width: var(--col);
      margin: 0;
      perspective: 1900px;
    }
    .ouvre .volume { transform: rotateY(calc(var(--ouv, 0) * -180deg)); }
    .ouvre.ouvert .scene { visibility: visible; }
  }
  /* ---- Paysage court, 500px de haut au plus ----
     Prime sur la colonne et sur la double page. Le livre est posé ouvert
     (couverture.js ne pose pas .ouvre) : une colonne de 720px au plus, la
     barre en ligne fine collée en haut, la couverture et la quatrième à la
     hauteur de leur contenu, nom et courriel à l'horizontale. */
  @media (max-height: 500px) {
    :root {
      --gouttiere: 40px;
      --col: min(100vw, 720px);
      --barre: 2.5rem;
    }
    .barre {
      position: sticky;
      inset-block: 0 auto;
      height: var(--barre);
      padding-block-end: 0;
      border-block-end: var(--barre-bas);
    }
    .barre button, .barre a { min-height: var(--barre); }
    .barre .marque svg { width: 30px; }
    #sommaire { inset: 0 0 auto; max-height: 100svh; }
    .couverture {
      min-height: auto;
      height: auto;
      padding: var(--e-6) var(--gouttiere);
    }
    .dos { flex: none; writing-mode: horizontal-tb; transform: none; }
    .nom {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
    .nom-paysage {
      display: block;
      font-size: calc(var(--in) * var(--k-titre));
      line-height: 0.88;
      font-weight: 900;
    }
    .premiere { padding-block-end: var(--gouttiere); }
    .planche { position: static; }
    .quatrieme {
      min-height: auto;
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: none;
      grid-template-areas: "titre" "mail" "reseaux" "suite" "pied";
      padding-block-end: var(--e-6);
    }
    .courriel {
      align-self: start;
      writing-mode: horizontal-tb;
      transform: none;
      font-size: calc(var(--in) * var(--k-courriel));
    }
    .reseaux { flex-wrap: nowrap; }
  }
}

@layer mouvement {
  /* Les deux familles de liens : le filet s'allonge, la flèche avance,
     le marqueur se remplit ; rien ne bouge sans mouvement. */
  @media (prefers-reduced-motion: no-preference) {
    .lien-suite::before, .cta-fleche { transition: transform var(--d-courte) var(--courbe); }
    .lien-suite:hover::before, .lien-suite:focus-visible::before { transform: scaleX(2); }
    .cta-section:hover .cta-fleche, .cta-section:focus-visible .cta-fleche { transform: translateX(var(--e-2)); }
    .cta-carnets:hover .cta-fleche, .cta-carnets:focus-visible .cta-fleche { transform: translateX(var(--e-2)) rotate(-90deg); }
    .vedette::after { transition: background-color var(--d-courte) var(--courbe), color var(--d-courte) var(--courbe); }
    /* Un état de lumière qui change pendant la visite passe en fondu.
       lumiere.js pose .lumiere-passe le temps du passage seulement : posée
       à demeure, la transition ralentirait tous les survols. Le point de
       la gouttière glisse au même pas. Sans mouvement, rien de tout cela :
       l'état commute d'un coup. */
    .lumiere-passe, .lumiere-passe *, .lumiere-passe *::before, .lumiere-passe *::after {
      transition: color var(--duree-lumiere) linear, background-color var(--duree-lumiere) linear,
        border-color var(--duree-lumiere) linear, outline-color var(--duree-lumiere) linear,
        text-decoration-color var(--duree-lumiere) linear, fill var(--duree-lumiere) linear,
        stroke var(--duree-lumiere) linear, top var(--duree-lumiere) var(--courbe);
    }
  }

  /* L'accueil, à chaque arrivée : après le nom, le point du monogramme de
     la barre devient une flèche, fait trois fois signe vers le bas, puis
     redevient le point. Une seule fois par visite de l'accueil (.ouvre n'y
     existe que là) ; jamais sans mouvement. Dix durées de transition en
     tout, après quatre d'attente. */
  @media (prefers-reduced-motion: no-preference) {
    .ouvre .barre .marque circle {
      animation: point-efface calc(10 * var(--d-transition)) var(--courbe) calc(4 * var(--d-transition)) both;
    }
    .ouvre .barre .fleche {
      animation: fleche-signe calc(10 * var(--d-transition)) var(--courbe) calc(4 * var(--d-transition)) both;
    }
  }
  @keyframes point-efface {
    0%, 100% { opacity: 1; }
    8%, 92% { opacity: 0; }
  }
  @keyframes fleche-signe {
    0%, 100% { opacity: 0; translate: 0 0; }
    8% { opacity: 1; translate: 0 0; }
    22% { translate: 0 10px; }
    36% { translate: 0 0; }
    50% { translate: 0 10px; }
    64% { translate: 0 0; }
    78% { translate: 0 10px; }
    92% { opacity: 1; translate: 0 0; }
  }

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

    #sommaire {
      translate: 0 100%;
      transition: translate var(--d-transition) var(--courbe),
        display var(--d-transition) allow-discrete,
        overlay var(--d-transition) allow-discrete;
    }
    #sommaire:popover-open { translate: 0 0; }
    @starting-style {
      #sommaire:popover-open { translate: 0 100%; }
    }
    /* En paysage court, la barre est en haut : le sommaire en descend. */
    @media (max-height: 500px) {
      #sommaire { translate: 0 -100%; }
      #sommaire:popover-open { translate: 0 0; }
      @starting-style {
        #sommaire:popover-open { translate: 0 -100%; }
      }
    }

    a, .bascule { transition: color 160ms var(--courbe), background-color 160ms var(--courbe), background-size 160ms var(--courbe), text-decoration-color 160ms var(--courbe); }
    .lettre { animation: lettre 900ms var(--courbe) both; animation-delay: calc(var(--i) * 55ms); }
    /* Retour arrière ou page rendue par le cache : le nom ne se rejoue pas. */
    .arrivee-sautee .lettre { animation: none; }
    .i0 { --i: 0; } .i1 { --i: 1; } .i2 { --i: 2; } .i3 { --i: 3; }
    .i4 { --i: 4; } .i5 { --i: 5; } .i6 { --i: 6; }
  }

  /* Collée en bas seulement quand l'écran la contient : sous 620px de
     haut, elle défile normalement et rien n'est inaccessible. */
  @media (prefers-reduced-motion: no-preference) and (min-height: 620px) {
    .quatrieme { position: sticky; inset-block-end: 0; }
  }

  @keyframes lettre { from { font-weight: 100; font-stretch: 62%; } }
  @keyframes ouvrir { from { --ouv: 0; } to { --ouv: 1; } }
  @keyframes resoudre { from { --res: 0; } to { --res: 1; } }
  @keyframes encre { from { font-weight: 200; font-stretch: 62%; } }
  @keyframes rail { from { translate: 0; } to { translate: 300%; } }
  @keyframes avance { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @keyframes titre-etape {
    0%, 26% { color: var(--titre); }
    33%, 66% { color: var(--accent); }
    73%, 100% { color: var(--titre); }
  }
  @keyframes case {
    0%, 26% { opacity: 0; background: var(--accent); }
    33% { opacity: 1; background: var(--accent); }
    66% { opacity: 1; background: var(--accent); }
    73%, 100% { opacity: 1; background: var(--titre); }
  }

  @supports (animation-timeline: view()) and (timeline-scope: --a) {
    @media (prefers-reduced-motion: no-preference) {
      .ouvre {
        animation: ouvrir linear both, resoudre linear both;
        animation-timeline: scroll(root block), scroll(root block);
        animation-range: 0 100svh, 100svh 185svh;
      }

      h2 .ligne {
        animation: encre linear both;
        animation-timeline: view();
        animation-range: entry 0% cover 36%;
      }

      #s-auj { timeline-scope: --volets; }
      .volets { scroll-timeline: --volets inline; }
      .curseur {
        display: block;
        animation: rail steps(4, jump-none) both;
        animation-timeline: --volets;
      }

      #s-par { timeline-scope: --e1, --e2, --e3, --e4; }
      .e1 { view-timeline: --e1; }
      .e2 { view-timeline: --e2; }
      .e3 { view-timeline: --e3; }
      .e4 { view-timeline: --e4; }
      .cases i, .cases-2 i {
        animation: case linear both;
        animation-range: cover calc(var(--k) * 1%) cover 100%;
      }
      .planche .b1 { animation-timeline: --e1; }
      .planche .b2 { animation-timeline: --e2; }
      .planche .b3 { animation-timeline: --e3; }
      .planche .b4 { animation-timeline: --e4; }
      /* Le titre de chaque étape passe en accent avec ses cases, puis
         revient au titre : la frise et le texte disent la même chose. */
      .etape .titre-bloc {
        animation: titre-etape linear both;
        animation-range: cover 0% cover 100%;
      }
      .e1 .titre-bloc { animation-timeline: --e1; }
      .e2 .titre-bloc { animation-timeline: --e2; }
      .e3 .titre-bloc { animation-timeline: --e3; }
      .e4 .titre-bloc { animation-timeline: --e4; }
      /* En double page, l'écran est haut et les étapes courtes : sur la
         plage cover, plusieurs étapes étaient à mi-course en même temps et
         toute la frise s'allumait d'un coup. Sur la plage contain, une
         étape s'allume quand elle monte dans le haut de la page, une seule
         à la fois ; les précédentes restent pleines, les suivantes vides. */
      @media (min-width: 768px) and (min-height: 501px) {
        .cases i, .cases-2 i { animation-range: contain calc(30% + var(--k) * 1%) contain 70%; }
        .etape .titre-bloc { animation-range: contain 30% contain 70%; }
      }

      .avancement {
        display: block;
        animation: avance linear both;
        animation-timeline: scroll(root);
      }
    }
  }
}
