@charset "utf-8";
/* ==========================================================================
   struk.tech — « La salle »
   Monde visuel : showroom cinématographique. Voir DESIGN.md et GRILLE.md.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
img, svg, video, canvas { display: block; max-width: 100%; }
img, video { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }

/* --------------------------------------------------------------------------
   2. Jetons
   -------------------------------------------------------------------------- */
:root {
  /* Fonds */
  --paper:    #F2F1ED;
  --paper-2:  #E9E7E1;
  --press:    #0B0A09;
  --press-2:  #16150F;

  /* Encre sur papier */
  --ink:      #1D1C19;
  --ink-2:    #56534B;
  --ink-3:    #6E6A60;

  /* Encre sur noir */
  --lume:     #F2F1ED;
  --lume-2:   #A8A49A;
  --lume-3:   #858177;

  /* Sol courant — redéfini par [data-ground] */
  --bg:       var(--paper);
  --bg-2:     var(--paper-2);
  --fg:       var(--ink);
  --fg-2:     var(--ink-2);
  --fg-3:     var(--ink-3);
  --hair:     rgb(29 28 25 / .16);
  --hair-2:   rgb(29 28 25 / .30);

  /* Le cadre, construit sur le nombre d'or.
     Mesuré sur le viewport et jamais sur le contenu : en `vw`/`svh` et non en
     `%`, un pourcentage se résolvant sur le bloc parent, ce qui décalait le
     texte des filets dès que la largeur changeait.

       0    → fx1 : φ⁻⁵ = 9,017 %   marge, le rail et la marque y vivent
       fx1  → fx2 : φ⁻⁴ = 14,590 %  bande interne
       fx2  → fx3 : φ⁻¹ = 61,803 %  la colonne de texte, section dorée exacte
       fx3  → 100 : φ⁻⁴ = 14,590 %  bande droite, miroir de la bande interne

     Verticalement, fy1 = φ⁻⁵ également : le filet du haut est la hauteur de
     l'en-tête, qu'il encadre au lieu de le traverser. La bande de contenu
     mesure 2 × φ⁻². */
  --fx1: 9.017vw;
  --fx2: 23.607vw;
  --fx3: 85.410vw;

  /* La colonne se subdivise elle aussi en φ : le texte occupe φ⁻¹ de sa
     largeur, la figure géométrique exactement le reste. Les deux ne peuvent
     donc pas se chevaucher, quelle que soit la longueur du titre. */
  /* L'échelle φ, en fractions du conteneur. Toute piste de grille qui porte
     du texte est prise ici, jamais en rem ni en px : une piste fixe ne peut
     pas tomber sur un filet, puisque le filet est proportionnel.
     Les sommes se referment : g5+g4 = g3, g4+g3 = g2, g3+g2 = g1, g2+g1 = 100. */
  --g5: 9.017%;    /* φ⁻⁵ */
  --g4: 14.590%;   /* φ⁻⁴ */
  --g3: 23.607%;   /* φ⁻³ */
  --g2: 38.197%;   /* φ⁻² */
  --g1: 61.803%;   /* φ⁻¹ */

  --col-w:  calc(var(--fx3) - var(--fx2));
  --text-w: calc((var(--fx3) - var(--fx2)) * 0.618034);
  --fy1: clamp(62px, 9.017svh, 104px);
  --fy2: 85.410svh;
  --frame: rgb(242 241 237 / .22);
  --frame-mark: rgb(242 241 237 / .5);

  /* Anneau de focus — seule couleur saturée autorisée dans l'interface */
  --focus: #006DEC;
  /* Couleur de signature : réservée aux démonstrations, jamais à l'interface.
     Une démonstration est du contenu ; l'interface, elle, reste monochrome. */
  --sig: #006DEC;

  /* Familles */
  --serif: "Source Serif 4", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans:  "Public Sans", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --mono:  "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Corps */
  --d1: clamp(2.5rem, 5.3vw, 5.4rem);
  --d2: clamp(1.85rem, 3.6vw, 3.4rem);
  --d3: clamp(1.35rem, 2.2vw, 2.05rem);
  --t-17: 1.0625rem;
  --t-16: 1rem;
  --t-15: .9375rem;
  --t-13: .8125rem;
  --t-11: .6875rem;
  --t-10: .625rem;

  /* Rythme */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px;
  --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px; --s-11: 176px;

  --gutter: 22px;
  --measure: 54ch;
  /* La largeur de contenu vient du cadre lui-même (fx3 − fx2), plus d'un
     plafond arbitraire. */

  /* Mouvement — la courbe de la référence */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --d-micro: 220ms;

  color-scheme: dark light;
}

@media (min-width: 768px)  { :root { --gutter: 40px; } }
@media (min-width: 1200px) { :root { --gutter: 64px; } }

/* Sols. Un composant est écrit une fois et fonctionne sur les deux. */
[data-ground="paper"] {
  --bg: var(--paper); --bg-2: var(--paper-2);
  --fg: var(--ink); --fg-2: var(--ink-2); --fg-3: var(--ink-3);
  --hair: rgb(29 28 25 / .16); --hair-2: rgb(29 28 25 / .30);
  background: var(--bg); color: var(--fg);
}
[data-ground="press"] {
  --bg: var(--press); --bg-2: var(--press-2);
  --fg: var(--lume); --fg-2: var(--lume-2); --fg-3: var(--lume-3);
  --hair: rgb(242 241 237 / .18); --hair-2: rgb(242 241 237 / .34);
  background: var(--bg); color: var(--fg);
}

/* Couleur du cadre, déclarée par la page et commutée par scène sur l'accueil */
[data-frame="dark"]  { --frame: rgb(29 28 25 / .34);   --frame-mark: rgb(29 28 25 / .62); }
[data-frame="light"] { --frame: rgb(242 241 237 / .22); --frame-mark: rgb(242 241 237 / .5); }

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--t-16);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background-color 700ms var(--ease), color 700ms var(--ease);
}

:where(h1, h2, h3, h4) {
  font-family: var(--serif);
  font-weight: 300;
  font-variation-settings: "opsz" 60;
  line-height: 1.02;
  letter-spacing: -.015em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

::selection { background: var(--fg); color: var(--bg); }

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

.skip {
  position: fixed; left: var(--gutter); top: 14px; z-index: 200;
  transform: translateY(-250%);
  background: var(--fg); color: var(--bg);
  padding: 11px 18px; border-radius: 999px;
  font-family: var(--mono); font-size: var(--t-10);
  text-transform: uppercase; letter-spacing: .18em;
  transition: transform var(--d-micro) var(--ease);
}
.skip:focus { transform: translateY(0); }

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

/* --------------------------------------------------------------------------
   4. Le cadre — la signature de ce monde
   -------------------------------------------------------------------------- */
.frame { position: fixed; inset: 0; z-index: 60; pointer-events: none; }
.frame i {
  position: absolute; display: block; background: var(--frame);
  transition: background-color 700ms var(--ease);
}
.frame i.v { top: 0; bottom: 0; width: 1px; }
.frame i.h { left: 0; right: 0; height: 1px; }
.frame i.v1 { left: var(--fx1); }
.frame i.v2 { left: var(--fx2); }
.frame i.v3 { left: var(--fx3); }
.frame i.h1 { top: var(--fy1); }
.frame i.h2 { top: var(--fy2); }

/* Losanges aux intersections */
.frame b {
  /* Centré sur l'axe peint du filet (son bord plus un demi-pixel), pas sur son
     bord : sinon chaque losange est décalé d'un demi-pixel sur sa ligne. */
  position: absolute; width: 5px; height: 5px; margin: -2px 0 0 -2px;
  background: var(--frame-mark); transform: rotate(45deg);
  transition: background-color 700ms var(--ease);
}
.frame b.m11 { left: var(--fx1); top: var(--fy1); }
.frame b.m21 { left: var(--fx2); top: var(--fy1); }
.frame b.m31 { left: var(--fx3); top: var(--fy1); }
.frame b.m12 { left: var(--fx1); top: var(--fy2); }
.frame b.m22 { left: var(--fx2); top: var(--fy2); }
.frame b.m32 { left: var(--fx3); top: var(--fy2); }

/* Sous 860px la colonne dorée ne laisse plus de mesure lisible : on retire la
   verticale interne et on referme le cadre en symétrie, toujours sur φ⁻⁵. */
@media (max-width: 860px) {
  :root {
    --fx3: 90.983vw;
    /* La colonne dorée n'existe plus : sa subdivision non plus. Sans cela, le
       texte serait plafonné à la part réservée au titre sur grand écran. */
    --text-w: 100%;
    /* Le texte s'appuie sur les deux filets qui restent : il part de v1 et
       s'arrête sur v3. La gouttière vaut donc exactement la marge du cadre,
       sans quoi le filet de droite traverserait le texte au lieu de l'encadrer. */
    --gutter: 9.017vw;
  }
  .frame i.v2, .frame b.m21, .frame b.m22 { display: none; }
}

/* --------------------------------------------------------------------------
   5. Mise en page
   -------------------------------------------------------------------------- */
.wrap { position: relative; z-index: 2; width: 100%; padding-inline: var(--gutter); }
/* Conservé pour compatibilité : le conteneur ne recentre plus rien, sans quoi
   le contenu et les filets cesseraient d'être dans le même repère. */
.wrap--max { max-width: none; }

/* Colonne alignée sur la seconde verticale du cadre */
/* La colonne occupe exactement la section dorée : elle commence sur fx2 et
   s'arrête sur fx3. Le filet de droite est une contrainte, pas un décor. */
.col { padding-left: 0; }
@media (min-width: 861px) {
  .col {
    margin-left: calc(var(--fx2) - var(--gutter));
    max-width: calc(var(--fx3) - var(--fx2));
  }
}

.section { padding-block: var(--s-9); }
@media (min-width: 768px) { .section { padding-block: var(--s-11); } }

/* --------------------------------------------------------------------------
   6. Typographie
   -------------------------------------------------------------------------- */
.d1 { font-size: var(--d1); }
@media (min-width: 861px) {
  .d1, .opening__content .lede { max-width: var(--text-w); }
}
.d2 { font-size: var(--d2); }
.d3 { font-size: var(--d3); line-height: 1.12; }

.lede {
  font-size: var(--t-17); line-height: 1.6; color: var(--fg-2);
  max-width: 46ch;
}
.body { font-size: var(--t-16); line-height: 1.65; color: var(--fg-2); max-width: var(--measure); }
.body > * + * { margin-top: var(--s-4); }
.body strong { color: var(--fg); font-weight: 600; }
.small { font-size: var(--t-15); line-height: 1.6; color: var(--fg-2); max-width: 48ch; }

.mono {
  font-family: var(--mono); font-size: var(--t-10); font-weight: 400;
  text-transform: uppercase; letter-spacing: .18em; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}
.mono--fg { color: var(--fg); }

.link {
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: 5px; text-decoration-color: var(--hair-2);
  transition: text-decoration-color var(--d-micro) var(--ease);
}
.link:hover { text-decoration-color: currentColor; }

/* --------------------------------------------------------------------------
   7. Pastilles — le seul bouton du site
   -------------------------------------------------------------------------- */
.pil {
  display: inline-flex; align-items: center; gap: 14px;
  min-height: 46px; padding: 5px 6px 5px 20px;
  border-radius: 999px; border: 1px solid transparent;
  background: var(--fg); color: var(--bg);
  font-family: var(--mono); font-size: var(--t-10); font-weight: 500;
  text-transform: uppercase; letter-spacing: .18em; white-space: nowrap;
  transition: transform var(--d-micro) var(--ease), opacity var(--d-micro) var(--ease);
}
.pil__arrow {
  width: 34px; height: 34px; flex: none; border-radius: 50%;
  background: var(--bg); color: var(--fg);
  display: grid; place-items: center;
  transition: transform var(--d-micro) var(--ease);
}
.pil:hover { transform: translateY(-1px); }
.pil:hover .pil__arrow { transform: translateX(3px); }
.pil:active { transform: translateY(0); }

.pil--ghost {
  background: transparent; color: var(--fg); border-color: var(--hair-2);
}
.pil--ghost .pil__arrow { background: transparent; border: 1px solid var(--hair-2); color: var(--fg); }
.pil--ghost:hover { border-color: var(--fg); }

.pil[aria-disabled="true"] {
  background: transparent; color: var(--fg-3);
  border-color: var(--hair); border-style: dashed;
  cursor: not-allowed; pointer-events: none;
}

/* Étiquette — signale une catégorie, jamais une action */
.tag {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--bg-2); color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-10); font-weight: 400;
  text-transform: uppercase; letter-spacing: .18em; white-space: nowrap;
}
[data-ground="press"] .tag { background: rgb(242 241 237 / .1); color: var(--fg-2); }

/* --------------------------------------------------------------------------
   8. Scène — un plein écran, son image, son texte
   -------------------------------------------------------------------------- */
.scene {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: end;
  overflow: clip;
  isolation: isolate;
}
.scene__media { position: absolute; inset: 0; z-index: -2; }
.scene__media img {
  width: 100%; height: 100%; object-fit: cover;
  object-position: var(--focal, 50% 50%);
}
.scene__veil {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to top, rgb(11 10 9 / .88) 0%, rgb(11 10 9 / .55) 34%, rgb(11 10 9 / .12) 68%, rgb(11 10 9 / .3) 100%);
}
.scene__veil--paper {
  background:
    linear-gradient(to top, rgb(242 241 237 / .92) 0%, rgb(242 241 237 / .6) 36%, rgb(242 241 237 / .1) 72%, transparent 100%);
}
.scene__body { position: relative; z-index: 1; padding-bottom: calc(100svh - var(--fy2)); }
.scene__body > * + * { margin-top: var(--s-5); }

/* --------------------------------------------------------------------------
   9. En-tête
   -------------------------------------------------------------------------- */
/* L'en-tête EST la bande du haut : sa hauteur vaut le premier filet, qui
   l'encadre au lieu de le couper. Et ses colonnes sont celles du cadre : chaque
   élément occupe une cellule, aucun ne chevauche un filet.

     cellule 1   0   → fx1   la marque
     cellule 2   fx1 → fx2   vide, la respiration du cadre
     cellule 3   fx2 → fx3   la navigation, puis la bascule de langue
     cellule 4   fx3 → 100   l'appel à écrire, centré */
.mast {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  height: var(--fy1);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding-inline: var(--gutter);
  pointer-events: none;
}
@media (min-width: 861px) {
  .mast {
    /* `gap: 0` est indispensable : la valeur du mode flex serait héritée par la
       grille et décalerait chaque piste par rapport à son filet. */
    display: grid; padding-inline: 0; gap: 0;
    grid-template-columns:
      var(--fx1)
      calc(var(--fx2) - var(--fx1))
      calc(var(--fx3) - var(--fx2))
      calc(100vw - var(--fx3));
    align-items: center;
  }
  .mast .mark     { grid-column: 1; }
  .mast__mid      { grid-column: 3; }
  .mast__cta      { grid-column: 4; }
}
.mast > * { pointer-events: auto; position: relative; z-index: 1; }
/* Voile d'en-tête : sans lui, une nav de 10 px passe sur un ciel clair et
   disparaît. Il suit le sol courant, donc il ne se voit sur aucun des deux. */
.mast::before {
  content: ""; position: absolute; inset: -1px 0 auto 0; height: calc(var(--fy1) * 2.2);
  pointer-events: none; z-index: 0;
  background: linear-gradient(to bottom, var(--mast-scrim, rgb(11 10 9 / .62)) 0%,
              transparent 100%);
  transition: background 700ms var(--ease);
}
[data-ground="paper"] { --mast-scrim: rgb(242 241 237 / .82); }
[data-ground="press"] { --mast-scrim: rgb(11 10 9 / .7); }

.mark {
  display: inline-flex; align-items: center;
  font-family: var(--serif); font-weight: 400; font-size: 1.2rem;
  font-variation-settings: "opsz" 28; letter-spacing: -.012em; line-height: 1;
  color: var(--fg); white-space: nowrap;
}
@media (min-width: 861px) {
  /* Le corps suit la cellule : la marque y tient à toutes les largeurs plutôt
     que de déborder sur le premier filet. */
  .mark {
    font-size: min(1.1rem, calc(var(--fx1) * 0.132));
    padding-left: clamp(12px, 1.5vw, 30px);
  }
}

.mast__mid { display: flex; align-items: center; justify-content: space-between;
              gap: var(--s-4); min-width: 0; }
.mast__cta { display: flex; align-items: center; justify-content: center; gap: 10px; }

.nav { display: none; }
.nav ul { display: flex; align-items: center; gap: clamp(16px, 1.9vw, 30px); }
@media (min-width: 1060px) {
  .nav { display: flex; align-items: center; }
}
.nav a {
  font-family: var(--mono); font-size: var(--t-10); font-weight: 500;
  text-transform: uppercase; letter-spacing: .16em; color: var(--fg);
  opacity: .72;
  padding: 8px 0; position: relative;
  transition: color var(--d-micro) var(--ease);
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 2px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-micro) var(--ease);
}
.nav a:hover { opacity: 1; }
.nav a[aria-current="page"] { opacity: 1; }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--fg); }

.icon-btn {
  width: 46px; height: 46px; border-radius: 50%;
  border: 1px solid var(--hair-2); color: var(--fg);
  display: grid; place-items: center;
  transition: border-color var(--d-micro) var(--ease), background-color var(--d-micro) var(--ease);
}
.icon-btn:hover { border-color: var(--fg); }
.icon-btn[aria-pressed="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }

.lang {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: var(--t-10); letter-spacing: .12em;
  width: auto; min-width: 76px; height: 46px; padding-inline: 15px;
  border-radius: 999px; white-space: nowrap;
}
.lang b { font-weight: 500; }
.lang [aria-current="true"] { color: var(--fg); }
.lang [aria-current="false"] { color: var(--fg-3); }

.burger { display: grid; }
@media (min-width: 1060px) { .burger { display: none; } }
/* La pastille ne s'affiche que si la cellule de droite peut la contenir
   centrée. En dessous, le tiroir porte le contact. */
.mast__cta > .pil { display: none; }
@media (min-width: 1060px) { .mast__cta > .pil { display: inline-flex; } }

/* Tiroir */
.drawer {
  position: fixed; inset: 0; z-index: 150;
  background: var(--bg); color: var(--fg);
  display: grid; align-content: center;
  padding: var(--s-8) var(--gutter);
  opacity: 0; visibility: hidden;
  transition: opacity 420ms var(--ease), visibility 420ms;
}
.drawer[data-open="true"] { opacity: 1; visibility: visible; }
.drawer__close { position: absolute; top: 18px; right: var(--gutter); }
.drawer nav ul { display: grid; gap: 2px; }
.drawer nav a {
  display: flex; align-items: baseline; gap: var(--s-4);
  padding: 14px 0; border-bottom: 1px solid var(--hair);
  font-family: var(--serif); font-weight: 300; font-variation-settings: "opsz" 40;
  font-size: clamp(1.7rem, 7vw, 2.6rem); line-height: 1.05; letter-spacing: -.02em;
}
.drawer nav a span { font-family: var(--mono); font-size: var(--t-10);
                     letter-spacing: .18em; color: var(--fg-3); }
.drawer nav a[aria-current="page"] { color: var(--fg); }
.drawer nav a[aria-current="page"] span { color: var(--fg); }
.drawer__contact { margin-top: var(--s-7); display: flex; flex-wrap: wrap; gap: 12px; }

/* --------------------------------------------------------------------------
   10. Rail — repère de progression entre les scènes
   -------------------------------------------------------------------------- */
.rail {
  position: fixed; left: var(--gutter); top: 50%; transform: translateY(-50%);
  z-index: 90; display: none; gap: 10px; flex-direction: column;
}
@media (min-width: 1060px) { .rail { display: flex; } }
.rail a { display: flex; align-items: center; gap: 12px; }
/* Le trait s'allonge par `transform`, pas par `width` : animer une largeur
   force un recalcul de mise en page à chaque image. */
.rail i {
  display: block; width: 34px; height: 1px; background: var(--frame-mark);
  transform: scaleX(.53); transform-origin: left center;
  transition: transform var(--d-micro) var(--ease), background-color var(--d-micro) var(--ease);
}
.rail span {
  font-family: var(--mono); font-size: var(--t-10); text-transform: uppercase;
  letter-spacing: .18em; color: var(--fg-3);
  opacity: 0; transform: translateX(-4px);
  transition: opacity var(--d-micro) var(--ease), transform var(--d-micro) var(--ease);
}
.rail a:hover i, .rail a[aria-current="true"] i { transform: scaleX(1); background: var(--fg); }
.rail a:hover span, .rail a[aria-current="true"] span { opacity: 1; transform: translateX(0); }

/* --------------------------------------------------------------------------
   11. Fiche clé/valeur
   -------------------------------------------------------------------------- */
.spec { display: grid; border-top: 1px solid var(--hair); }
.spec > div {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 18px; padding: 11px 0; border-bottom: 1px solid var(--hair);
}
.spec dt { font-family: var(--mono); font-size: var(--t-10); text-transform: uppercase;
           letter-spacing: .18em; color: var(--fg-3); }
.spec dd { margin: 0; font-size: var(--t-15); color: var(--fg); text-align: right;
           min-width: 0; font-variant-numeric: tabular-nums;
           /* `break-word` et non `anywhere` : la valeur passe d'abord à la ligne
              entière, et ne se coupe en plein mot qu'en dernier recours. */
           overflow-wrap: break-word; }

/* Liste réglée */
.ruled { display: grid; border-top: 1px solid var(--hair); }
.ruled > li { padding-block: var(--s-5); border-bottom: 1px solid var(--hair); }

/* --------------------------------------------------------------------------
   12. Colophon
   -------------------------------------------------------------------------- */
.colophon { position: relative; z-index: 2; padding-block: var(--s-9) var(--s-6); }
.colophon__grid { display: grid; gap: var(--s-7); }
@media (min-width: 900px) {
  .colophon__grid { grid-template-columns: var(--g2) var(--g3) minmax(0,1fr);
                    column-gap: 0; }
  .colophon__grid > * + * { padding-left: var(--s-6); }
}
.colophon h2 { font-size: var(--d3); margin-bottom: var(--s-4); }
.colophon ul { display: grid; gap: 11px; }
.colophon a { color: var(--fg-2); font-size: var(--t-15);
              transition: color var(--d-micro) var(--ease); }
.colophon a:hover { color: var(--fg); }
.colophon__base {
  display: flex; flex-wrap: wrap; gap: var(--s-4); justify-content: space-between;
  align-items: center; padding-top: var(--s-6); margin-top: var(--s-7);
  border-top: 1px solid var(--hair);
}
.colophon__base p, .colophon__base a {
  font-family: var(--mono); font-size: var(--t-10); color: var(--fg-3);
  text-transform: uppercase; letter-spacing: .18em;
}
.social { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--s-5); }
.social a {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--hair);
  display: grid; place-items: center; color: var(--fg-2);
  transition: border-color var(--d-micro) var(--ease), color var(--d-micro) var(--ease),
              transform var(--d-micro) var(--ease);
}
.social a:hover { border-color: var(--fg); color: var(--fg); transform: translateY(-2px); }

/* --------------------------------------------------------------------------
   13. Mouvement
   -------------------------------------------------------------------------- */
.js:not(.motion-off) [data-reveal] { opacity: 0; transform: translateY(18px); }
.js:not(.motion-off) [data-rise] { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal], .js [data-rise], .motion-off [data-reveal], .motion-off [data-rise] {
    opacity: 1 !important; transform: none !important;
  }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
.motion-off [data-reveal], .motion-off [data-rise] {
  opacity: 1 !important; transform: none !important;
}

/* --------------------------------------------------------------------------
   14. Impression
   -------------------------------------------------------------------------- */
@media print {
  .frame, .rail, .mast, .drawer, .skip, .scene__media, .scene__veil { display: none !important; }
  [data-ground="press"] { background: #fff !important; color: #000 !important;
                          --fg: #000; --fg-2: #222; --fg-3: #444; --hair: #bbb; }
  .scene { min-height: 0; }
  .scene__body { padding-bottom: 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; color: #555; }
}

/* --------------------------------------------------------------------------
   15. Relevé du cadre — touche G
   -------------------------------------------------------------------------- */
.cadre-on .frame i { background: var(--focus); opacity: .55; }
.cadre-on .frame b { background: var(--focus); width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; }
.cadre-on .frame::after {
  content: ""; position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(to bottom, rgb(0 109 236 / .16) 0 1px, transparent 1px 8px);
}

.cadre-hud {
  position: fixed; left: var(--gutter); bottom: 18px; z-index: 200;
  display: flex; flex-wrap: wrap;
  background: var(--bg); border: 1px solid var(--hair-2); border-radius: 8px;
  box-shadow: 0 2px 0 rgb(0 0 0 / .06), 0 24px 48px -28px rgb(0 0 0 / .5);
  max-width: calc(100% - var(--gutter) * 2);
}
.cadre-hud[hidden] { display: none; }
.cadre-hud > * {
  padding: 9px 13px; border-right: 1px solid var(--hair);
  font-family: var(--mono); font-size: var(--t-10); color: var(--fg-3);
  text-transform: uppercase; letter-spacing: .1em; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.cadre-hud > *:last-child { border-right: 0; }
.cadre-hud b { color: var(--fg); font-weight: 500; }
.cadre-hud button { color: var(--focus); min-height: 34px; }
@media print { .cadre-hud { display: none !important; } }

/* --------------------------------------------------------------------------
   16. Pages calmes — en-tête de pièce et sections
   -------------------------------------------------------------------------- */
/* `isolation` est indispensable : sans contexte d'empilement propre, un enfant
   en z-index négatif passe derrière le fond opaque du bloc et disparaît. */
/* `minmax(0, 1fr)` n'est pas décoratif : une piste `auto` se dimensionne sur
   le contenu, et un mot long la poussait au-delà du viewport. `overflow: clip`
   masquait le débordement, si bien que le texte franchissait le filet de
   droite sans que la page paraisse défiler. */
.opening { position: relative; min-height: 100svh; display: grid; align-items: end;
           grid-template-columns: minmax(0, 1fr);
           overflow: clip; isolation: isolate; }

/* Le bloc de texte d'une ouverture se pose exactement sur la seconde
   horizontale du cadre, comme les scènes de l'accueil. */
.opening__inner { position: relative; z-index: 1; padding-block: 26svh 8svh; }
@media (min-width: 861px) {
  .opening__inner {
    position: absolute; left: 0; right: 0; bottom: calc(100svh - var(--fy2));
    padding-block: 0;
  }
}
.opening__content > * + * { margin-top: var(--s-5); }
.opening__content .lede { max-width: 40ch; }
.opening__act { display: flex; flex-wrap: wrap; gap: 12px; }

/* La figure géométrique se cale sur le cadre : son bord droit tombe sur fx3,
   son centre sur le milieu de la bande de contenu. Elle en est le prolongement,
   pas une illustration posée par-dessus. */
.geo {
  position: absolute; z-index: -1; pointer-events: none;
  right: calc(100vw - var(--fx3));
  top: calc(var(--fy1) + (var(--fy2) - var(--fy1)) / 2);
  width: calc(var(--col-w) - var(--text-w)); aspect-ratio: 1;
  transform: translateY(-50%);
  color: var(--fg);
}
.geo svg { width: 100%; height: 100%; overflow: visible; }
[data-ground="press"] .geo { opacity: .42; }
[data-ground="paper"] .geo { opacity: .5; }
@media (max-width: 860px) {
  /* Sur mobile le texte prend toute la largeur : la figure se replie dans la
     bande libre entre l'en-tête et le contenu, au lieu de passer dessous. */
  .geo { right: calc(100vw - var(--fx3)); top: calc(var(--fy1) + 2svh);
         width: min(38vw, 19svh); transform: none; }
  /* Sur un écran court il n'y a pas de bande libre : la figure devient
     franchement une texture de fond, jamais un élément qui concurrence. */
  [data-ground="press"] .geo { opacity: .24; }
  [data-ground="paper"] .geo { opacity: .3; }
}

.lead-in { display: grid; gap: var(--s-4); margin-bottom: var(--s-7); }
/* Le titre de section reste un <h2>, c'est le plan du document, mais il a pris
   la forme d'un libellé : le grand titre qui le doublait disait deux fois la
   même chose. */
.lead-in h2 { font-family: var(--mono); font-weight: 400; font-size: var(--t-10);
              text-transform: uppercase; letter-spacing: .18em; line-height: 1.5;
              /* Le titre porte la couleur de la page, ce qui le détache du
                 texte courant. Chaque ton est calculé pour tenir 4,5:1 sur son
                 sol : à 10 px, un accent qui ne se lit pas n'est pas un accent.
                 À défaut de couleur déclarée, une encre de plus que l'ordinal
                 d'une ligne de registre. */
              color: var(--titre, var(--fg-2)); max-width: none; }
/* Le chapeau porte désormais seul le poids de la section : il monte d'un cran
   et passe à l'encre pleine, sans quoi la page n'aurait plus aucun relief. */
.lead-in p { max-width: 46ch; color: var(--fg); line-height: 1.5; letter-spacing: -.01em;
             font-size: clamp(1.2rem, 1.75vw, 1.6rem); }
@media (min-width: 1000px) {
  /* Le chapeau se cale sur la colonne de texte des registres qui le suivent
     (`.defs dd`, valeur de `.figure`), sinon il flotte à un filet auquel rien
     ne répond plus bas. */
  .lead-in--split { grid-template-columns: var(--g3) minmax(0,1fr);
                    column-gap: 0; align-items: baseline; }
  .lead-in--split > h2 { padding-right: var(--s-5); }
}

/* Registre de figures. Une figure par ligne pleine largeur : la colonne de
   quatre cartes plaçait ses coupures au quart, à la moitié, aux trois quarts,
   c'est-à-dire nulle part sur le cadre. En ligne, chaque coupure est un filet. */
.figures, .claims, .marks { display: grid; gap: 0; border-top: 1px solid var(--hair-2); }
.figure { padding-block: var(--s-5); border-bottom: 1px solid var(--hair);
          display: grid; gap: 10px; }
/* La valeur n'est pas toujours un chiffre : « Pendant l'enregistrement » est
   une réponse, pas une mesure. Un `white-space: nowrap` la faisait passer
   par-dessus la note au lieu de se replier. Le compteur étant redevenu inline,
   « 730+ » ne se coupe plus de lui-même : la contrainte n'a plus lieu d'être. */
.figure b { display: block; font-family: var(--serif); font-weight: 300;
            font-variation-settings: "opsz" 40; font-size: clamp(1.25rem, 2.1vw, 1.85rem);
            line-height: 1.14; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
            text-wrap: balance; }
/* Le compteur vit DANS le <b>. Un sélecteur `.figure span` l'attrapait aussi et
   le rendait en bloc à la taille d'une note : le chiffre sortait à 15 px et son
   suffixe tombait à la ligne suivante. La note est le span de <dd>, pas celui-ci. */
.figure b > span { display: inline; font: inherit; color: inherit; letter-spacing: inherit; }
.figure dd > span { display: block; font-size: var(--t-15); color: var(--fg-2); }
.figure dd { margin: 0; display: grid; gap: 10px; }
@media (min-width: 840px) {
  /* Trois colonnes franches — étiquette, valeur, note — au lieu d'une
     subdivision imbriquée qui étranglait la valeur. g3 + g2 = g1 : les deux
     coupures tombent sur l'échelle. `display: contents` fait des enfants du
     <dd> des cellules de ce même rang, sans toucher au balisage. */
  .figure { grid-template-columns: var(--g3) var(--g2) minmax(0,1fr);
            column-gap: 0; gap: 0; align-items: center; }
  .figure dd { display: contents; }
  .figure > .mono, .figure b { padding-right: var(--s-5); }
}

/* Liste de définitions large */
.defs { display: grid; border-top: 1px solid var(--hair); }
.defs > div { display: grid; gap: 8px; padding-block: var(--s-5); border-bottom: 1px solid var(--hair); }
@media (min-width: 840px) {
  .defs > div { grid-template-columns: var(--g3) minmax(0,1fr); column-gap: 0; align-items: baseline; }
  .defs dt { padding-right: var(--s-5); }
}
.defs dt { font-family: var(--serif); font-weight: 400; font-variation-settings: "opsz" 24;
           font-size: var(--t-17); letter-spacing: -.01em; }
.defs dd { margin: 0; color: var(--fg-2); font-size: var(--t-15); max-width: 60ch; }

/* Étapes numérotées, en registre réglé. */
.steps, .method { display: grid; gap: 0; border-top: 1px solid var(--hair-2); }
.steps > li, .method > li { padding-block: var(--s-5); border-bottom: 1px solid var(--hair);
                            display: grid; gap: var(--s-3); }
.steps h3, .method h3 { font-size: var(--d3); margin: 0; }
.steps p, .method p { color: var(--fg-2); font-size: var(--t-15); }
@media (min-width: 860px) {
  .steps > li, .method > li {
    grid-template-columns: var(--g4) var(--g3) minmax(0,1fr);
    column-gap: 0; align-items: baseline; gap: 0;
  }
  .steps > li > :not(:last-child), .method > li > :not(:last-child) { padding-right: var(--s-5); }
}

/* Encadré franc */
.note { border: 1px solid var(--hair-2); border-radius: 3px; padding: var(--s-5); }
@media (min-width: 760px) { .note { padding: var(--s-6); } }
.note h3 { font-size: var(--d3); margin-block: var(--s-3) var(--s-3); }
.note p { color: var(--fg-2); font-size: var(--t-15); max-width: 62ch; }

/* Bande d'appel */
.callout { border-top: 1px solid var(--hair-2); padding-top: var(--s-7);
           display: grid; gap: var(--s-5); }
@media (min-width: 860px) { .callout { grid-template-columns: var(--g1) minmax(0,1fr);
                                       align-items: center; column-gap: 0; }
                            .callout > :first-child { padding-right: var(--s-7); }
                            .callout > :last-child { justify-self: start; } }
.callout h2 { font-size: var(--d2); max-width: 22ch; }
.callout p { color: var(--fg-2); margin-top: var(--s-3); max-width: 46ch; }

/* Article numéroté (pages documentaires) */
.article { display: grid; gap: var(--s-3); padding-block: var(--s-7); border-top: 1px solid var(--hair); }
.article__no { font-family: var(--mono); font-size: var(--t-10); text-transform: uppercase;
               letter-spacing: .18em; color: var(--fg-3); }
.article h2 { font-size: var(--t-17); font-family: var(--serif); font-weight: 400;
              font-variation-settings: "opsz" 24; letter-spacing: -.01em;
              scroll-margin-top: 110px; }
.article__body { font-size: var(--t-16); line-height: 1.68; color: var(--fg-2); max-width: 62ch; }
.article__body > * + * { margin-top: var(--s-4); }
.article__body strong { color: var(--fg); font-weight: 600; }
.article__body a { color: var(--fg); text-decoration: underline;
                   text-decoration-thickness: 1px; text-underline-offset: 4px; }
.article__body ul { display: grid; gap: 10px; }
.article__body li { padding-left: 22px; position: relative; }
.article__body li::before { content: ""; position: absolute; left: 2px; top: .68em;
                            width: 9px; height: 1px; background: var(--fg-3); }
.article__body code { font-family: var(--mono); font-size: .9em; }
@media (min-width: 940px) {
  /* Le titre tient la colonne de gauche et se lit en descendant le long du
     filet ; le corps part de g3, comme tout texte du site. L'ordinal « Art. 01 »
     empilé au-dessus du titre a disparu : le sommaire numérote déjà. */
  .article { grid-template-columns: var(--g3) minmax(0,1fr); column-gap: 0;
             align-items: start; }
  .article h2 { grid-column: 1; grid-row: 1; padding-right: var(--s-5); }
  .article__body { grid-column: 2; grid-row: 1; }
}

.tofill { background: #B4532A; color: #F2F1ED; padding: 1px 8px; border-radius: 3px;
          font-family: var(--mono); font-size: .85em; }
