/* ===========================================================================
   despontsalaplacedesmurs.com — feuille de style de production
   Valeurs reprises du paquet de design (design/site.css + ds/tokens-*.css).
   Le design est fixé sur un cadre de 1920 × 1080 : ici tout est fluidifié,
   mais les valeurs de référence sont conservées comme bornes hautes.
   =========================================================================== */

/* ---- Polices, hébergées localement -------------------------------------
   Pas d'import Google Fonts : le site doit être autonome, et l'appel au CDN
   transmettrait l'IP des visiteurs à un tiers. Oswald est une police
   variable — un seul fichier couvre les graisses 600 et 700.            */
@font-face {
  font-family: 'Oswald';
  src: url('../assets/fonts/oswald-var-latin.woff2') format('woff2-variations');
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Source Sans 3';
  src: url('../assets/fonts/sourcesans3-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/ibmplexmono-500-latin.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---- Jetons ------------------------------------------------------------ */
:root {
  /* Base monochrome froide — ne change jamais */
  --ink: #0D1518;
  --charcoal: #1C2A30;
  --slate: #495F6F;
  --mist: #ABBDC8;
  --paper: #F2F5F5;
  --line: rgba(171, 189, 200, .16);

  /* Couleurs signatures — mesurées puis calées pour le fond sombre */
  --oe-rose-raw:#9B2D4C;   --oe-rose:#E0637F;
  --oe-orange-raw:#73341D; --oe-orange:#DF6A38;
  --oe-vert-raw:#284021;   --oe-vert:#56A643;
  --oe-rouge-raw:#69241F;  --oe-rouge:#E4574A;
  --oe-or-raw:#976A25;     --oe-or:#D89F42;
  --oe-violet-raw:#6A1374; --oe-violet:#B172E8;

  /* Courbe unique du site. Aucun rebond nulle part. */
  --ease: cubic-bezier(.22,.61,.36,1);

  /* ---- Réglage du voile -------------------------------------------------
     Le design calait le dégradé latéral pour mourir à 82 % et le scrim haut
     à 250 px. À la demande d'OD (V1), le voile est décalé vers la gauche et
     vers le haut pour moins empiéter sur l'image. Ces deux valeurs sont les
     seules à toucher pour l'ajuster encore.
     ATTENTION : le design avait mesuré ses valeurs pour garantir ≥ 13:1 sur
     le texte. En réduisant le voile on réduit cette marge — elle reste
     confortable ici, mais ne pas aller beaucoup plus loin.               */
  --veil-end: 68%;        /* était 82% */
  --topscrim-h: 190px;    /* était 250px */

  /* Géométrie — bornes hautes = valeurs du design à 1920 */
  --marge: clamp(22px, 6.25vw, 120px);
  /* 800 px sur le cadre de 1920 du design = 41,7 vw. Garder 800 px en dur
     ferait déborder la plaque sur le repère « Défilez », centré, dès qu'on
     descend sous 1900 px de large — le design lui-même ne dégage que 5 px. */
  --plaque-w: min(800px, 41.7vw);
  --plaque-bottom: clamp(96px, 13.7vh, 148px);
  --edgescrim-w: clamp(180px, 17.7vw, 340px);
}

[data-oe="rose"]   { --oe: var(--oe-rose);   --oe-raw: var(--oe-rose-raw); }
[data-oe="orange"] { --oe: var(--oe-orange); --oe-raw: var(--oe-orange-raw); }
[data-oe="vert"]   { --oe: var(--oe-vert);   --oe-raw: var(--oe-vert-raw); }
[data-oe="rouge"]  { --oe: var(--oe-rouge);  --oe-raw: var(--oe-rouge-raw); }
[data-oe="or"]     { --oe: var(--oe-or);     --oe-raw: var(--oe-or-raw); }
[data-oe="violet"] { --oe: var(--oe-violet); --oe-raw: var(--oe-violet-raw); }

/* ---- Base -------------------------------------------------------------- */
* { box-sizing: border-box; }

html { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: 'Source Sans 3', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; }

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

/* =========================================================================
   LE DÉFILEUR — vidéo fixe, paliers qui s'inscrivent par-dessus
   ========================================================================= */
.scroller { position: relative; }

.stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: var(--ink);
}

.stage__media { position: absolute; inset: 0; }
.stage__media img,
.stage__media video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* L'affiche reste visible tant que la vidéo n'a pas peint sa première image. */
.stage__media video { opacity: 0; transition: opacity .3s linear; }
.stage.is-video .stage__media video { opacity: 1; }

/* ---- Le voile : cinq couches, dans cet ordre exact --------------------- */
.floor     { position: absolute; inset: 0; background: rgba(7,12,14,.30); }
/* Les paliers du dégradé sont exprimés en fraction de --veil-end : décaler
   cette seule variable décale tout le voile, sans casser sa progression. */
.veil      { position: absolute; inset: 0;
             background: linear-gradient(90deg,
               rgba(7,12,14,.96) 0%,
               rgba(7,12,14,.90) calc(var(--veil-end) * .244),
               rgba(7,12,14,.66) calc(var(--veil-end) * .512),
               rgba(7,12,14,.24) calc(var(--veil-end) * .780),
               rgba(7,12,14,0)   var(--veil-end)); }
/* Le dégradé latéral meurt à 82 % : le scrim de rive couvre l'angle droit
   que ni lui ni le scrim haut n'atteignent, sous le rail de progression. */
.edgescrim { position: absolute; right: 0; top: 0; bottom: 0;
             width: var(--edgescrim-w);
             background: linear-gradient(270deg,
               rgba(7,12,14,.88) 0%, rgba(7,12,14,.62) 44%,
               rgba(7,12,14,0) 100%); }
.topscrim  { position: absolute; left: 0; right: 0; top: 0;
             height: var(--topscrim-h);
             background: linear-gradient(180deg,
               rgba(7,12,14,.92) 0%, rgba(7,12,14,.58) 46%,
               rgba(7,12,14,0) 100%); }
.grain     { position: absolute; inset: 0; opacity: .075;
             mix-blend-mode: overlay; pointer-events: none;
             background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>"); }

/* Production : plancher renforcé */
[data-floor="42"] .floor { background: rgba(7,12,14,.42); }

/* =========================================================================
   PAGE CLAIRE — Libérez la création. Même géométrie, valeurs inversées.
   ========================================================================= */
.clair { background: var(--paper); color: var(--ink); }
.clair .floor     { background: rgba(255,255,255,.34); }
.clair .veil      { background: linear-gradient(90deg,
                      rgba(255,255,255,.97) 0%,
                      rgba(255,255,255,.93) calc(var(--veil-end) * .244),
                      rgba(255,255,255,.72) calc(var(--veil-end) * .512),
                      rgba(255,255,255,.28) calc(var(--veil-end) * .780),
                      rgba(255,255,255,0)   var(--veil-end)); }
.clair .edgescrim { background: linear-gradient(270deg,
                      rgba(255,255,255,.94) 0%, rgba(255,255,255,.68) 44%,
                      rgba(255,255,255,0) 100%); }
.clair .topscrim  { background: linear-gradient(180deg,
                      rgba(255,255,255,.95) 0%, rgba(255,255,255,.64) 46%,
                      rgba(255,255,255,0) 100%); }
.clair .grain     { mix-blend-mode: multiply; opacity: .055; }
/* Sur la page claire le chrome est en couleur PLEINE, jamais en alpha :
   l'encre transparente ne se densifie pas et tombe sous le seuil. */
.clair .forte     { color: var(--ink); }
.clair .prolong   { color: rgba(13,21,24,.76); }
.clair .rail em   { color: #39474E; }
.clair .rail i    { background: #7C8990; }
.clair .rail i.on { background: var(--oe-raw); }
.clair .cue span  { color: rgba(13,21,24,.6); }
.clair .cue i     { background: linear-gradient(rgba(13,21,24,.6), rgba(13,21,24,0)); }
.clair .brand img { filter: invert(1) brightness(.10); }
/* La signature bascule sur sa valeur mesurée : l'or calé est illisible sur blanc. */
.clair .etq span  { color: var(--oe-raw); }
.clair .etq i     { background: var(--oe-raw); }
.clair .foot      { border-top-color: rgba(13,21,24,.14); }
.clair .foot .k   { color: #39474E; }
.clair .foot .ro  { color: rgba(13,21,24,.66); }
.clair .foot .ln a{ color: var(--ink); border-bottom-color: var(--oe-raw); }
.clair .card      { background: rgba(13,21,24,.06); }
.clair .card p    { color: rgba(13,21,24,.66); }
.clair .btn       { border-color: var(--oe-raw); color: var(--oe-raw); }
.clair .btn.solid { background: var(--oe-raw); color: var(--paper); }

/* =========================================================================
   LES PALIERS
   ========================================================================= */
.plaques { position: absolute; inset: 0; pointer-events: none; }

.plaque {
  position: absolute;
  left: var(--marge);
  bottom: var(--plaque-bottom);
  width: var(--plaque-w);
  margin: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.plaque.is-on { visibility: visible; opacity: 1; pointer-events: auto; }

/* Apparition 560 ms — opacité + translateY(18px→0), en trois temps décalés.
   Sortie 340 ms — opacité seule, sans déplacement. */
.plaque > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .34s var(--ease), transform 0s linear .34s;
}
.plaque.is-on > * {
  opacity: 1;
  transform: none;
  transition: opacity .56s var(--ease), transform .56s var(--ease);
}
.plaque.is-on > .forte,
.plaque.is-on > .themes   { transition-delay: .09s; }
.plaque.is-on > .prolong  { transition-delay: .17s; }

.etq { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.etq span {
  font: 500 clamp(12px, .73vw, 14px)/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .24em; text-transform: uppercase; color: var(--oe, var(--mist));
}
.etq i { display: block; width: 54px; height: 2px; background: var(--oe, var(--mist)); }

/* Interligne : le design posait 70/70, soit 1. En capitales accentuées —
   THÉÂTRE, L'EXPÉRIENCE, DÉCONSTRUIRE — les accents de la ligne du bas
   viennent toucher les jambages de celle du dessus. 1.09 dégage un filet
   d'air constant sans changer la densité du bloc. Écart assumé au design. */
.forte {
  font: 700 clamp(32px, 3.65vw, 70px)/1.09 'Oswald', system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .006em;
  margin: 28px 0 0; color: var(--paper); text-wrap: pretty;
}
.forte.sm { font-size: clamp(28px, 3.02vw, 58px); }
.forte.xs { font-size: clamp(26px, 2.5vw, 48px); line-height: 1.12; }

.prolong {
  font: 400 clamp(17px, 1.15vw, 22px)/1.55 'Source Sans 3', system-ui, sans-serif;
  color: rgba(242,245,245,.80); margin: 24px 0 0;
  max-width: 640px; text-wrap: pretty;
}

/* Palier 03 de l'accueil : la liste de six thèmes remplace la phrase forte. */
.themes { list-style: none; margin: 34px 0 0; padding: 0; display: grid; gap: 15px; max-width: 760px; }
.themes li {
  font: 600 clamp(19px, 1.41vw, 27px)/1.24 'Oswald', system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .10em;
  color: rgba(242,245,245,.94); display: flex; gap: 20px; align-items: baseline;
}
.themes li b {
  font: 400 13px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .16em; color: var(--oe); flex: 0 0 30px;
}

/* =========================================================================
   CHROME — logo, rail, repère « Défilez »
   ========================================================================= */
.brand { position: absolute; left: var(--marge); top: clamp(24px, 5.5vh, 60px); z-index: 40; }
.brand img { display: block; width: clamp(132px, 10.7vw, 206px); height: auto; }

.rail {
  position: absolute; right: clamp(20px, 3.4vw, 66px); top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: flex-end; gap: 14px;
  z-index: 30;
}
.rail em {
  font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace; font-style: normal;
  letter-spacing: .18em; color: rgba(171,189,200,.75); margin-bottom: 6px;
}
.rail i {
  display: block; width: 2px; height: clamp(22px, 3.5vh, 38px);
  background: rgba(171,189,200,.56);
  transition: background .34s var(--ease);
}
.rail i.on { background: var(--oe, var(--paper)); }

.cue {
  position: absolute; left: 50%; bottom: 52px; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 13px;
  opacity: 1; transition: opacity .34s var(--ease); z-index: 30;
}
.cue.is-off { opacity: 0; pointer-events: none; }
.cue span {
  font: 500 11px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .3em; text-transform: uppercase; color: rgba(171,189,200,.66);
}
.cue i { display: block; width: 1px; height: clamp(30px, 7.8vh, 56px);
         background: linear-gradient(rgba(171,189,200,.7), rgba(171,189,200,0)); }
/* Le repère est centré sur la largeur, comme dans le design. Cette position
   ne tient que sur un cadre large : à 1920 le design ne dégage que 5 px entre
   la plaque et lui. En dessous de 1500 px il tomberait dans le texte, donc on
   l'efface plutôt que de le déplacer — c'est un indice, pas une information.
   Écart assumé par rapport au design, signalé dans le README. */
@media (max-width: 1499px), (max-height: 620px) { .cue { display: none; } }

/* Lien discret vers la grille de l'accueil, pages œuvres uniquement. */
.backlink {
  position: absolute; right: var(--marge); top: clamp(26px, 6vh, 72px);
  font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .2em; text-transform: uppercase;
  color: rgba(242,245,245,.68); text-decoration: none; z-index: 40;
  padding-bottom: 6px; border-bottom: 1px solid transparent;
}
.backlink:hover, .backlink:focus-visible {
  color: var(--paper); border-bottom-color: var(--oe);
}
.clair .backlink { color: #39474E; }
.clair .backlink:hover { color: var(--ink); border-bottom-color: var(--oe-raw); }

/* =========================================================================
   ALLER PLUS LOIN — dossier + teaser
   ========================================================================= */
.further { padding: clamp(56px, 9vh, 150px) var(--marge) clamp(40px, 6vh, 90px); }
.further > h2 {
  font: 700 clamp(30px, 3.23vw, 62px)/1.08 'Oswald', system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .02em; margin: 0;
}
.dlrow { display: flex; gap: 30px; align-items: stretch; margin-top: 40px; flex-wrap: wrap; }

.card {
  background: var(--charcoal); padding: 38px 40px; flex: 1 1 320px;
  display: flex; flex-direction: column; justify-content: space-between; min-height: 250px;
}
.card h3 {
  font: 700 clamp(24px, 1.67vw, 32px)/1.16 'Oswald', system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .02em; margin: 0; color: var(--paper);
}
.card p { font: 400 17px/1.5 'Source Sans 3', system-ui, sans-serif;
          color: rgba(242,245,245,.66); margin: 14px 0 0; }

.btn {
  display: inline-flex; align-items: center; gap: 14px;
  border: 1px solid var(--oe); color: var(--oe);
  padding: 15px 26px; text-decoration: none;
  font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .2em; text-transform: uppercase;
  margin-top: 30px; align-self: flex-start;
  transition: background .3s var(--ease), color .3s var(--ease);
}
.btn:hover, .btn:focus-visible { background: var(--oe); color: var(--ink); }
.btn.solid { background: var(--oe); color: var(--ink); }
.btn.solid:hover { filter: brightness(1.12); }
/* Production : le violet signature est clair, le libellé passe en noir franc
   pour détacher davantage (demande OD, V1). */
[data-oe="violet"] .btn.solid { color: #000; }

/* Teaser : vignette d'abord. L'iframe n'est injectée qu'au clic, sinon
   YouTube dépose ses traceurs sur chaque visite. */
.tzr { flex: 1.25 1 380px; position: relative; background: #1a262c;
       min-height: 250px; overflow: hidden; border: 0; padding: 0;
       cursor: pointer; display: block; width: 100%; }
.tzr img { position: absolute; inset: 0; width: 100%; height: 100%;
           object-fit: cover; opacity: .5; transition: opacity .42s var(--ease); }
.tzr:hover img, .tzr:focus-visible img { opacity: .66; }
.tzr .play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 76px; height: 76px; border: 1px solid var(--paper); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.tzr .play::after {
  content: ""; border-left: 16px solid var(--paper);
  border-top: 10px solid transparent; border-bottom: 10px solid transparent;
  margin-left: 5px;
}
.tzr .lb {
  position: absolute; left: 26px; bottom: 22px;
  font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .2em; text-transform: uppercase; color: rgba(242,245,245,.8);
}
.tzr iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* =========================================================================
   LA GRILLE DES ŒUVRES — deuxième zone de l'accueil
   ========================================================================= */
.oeuvres { padding: clamp(56px, 9vh, 150px) var(--marge) clamp(40px, 6vh, 90px); }
.oeuvres > h2 {
  font: 700 clamp(30px, 3.23vw, 62px)/1.08 'Oswald', system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .02em; margin: 0 0 40px;
}

/* minmax(0,1fr) et non 1fr : 1fr vaut minmax(auto,1fr) et laisse le contenu
   le plus large gonfler sa piste, ce qui casse l'égalité des colonnes.
   3 colonnes jusqu'à six œuvres, 4 dès la septième — rien d'autre à changer. */
.grid6 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px 26px; }
@media (min-width: 1200px) { .grid6.is-seven-plus { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.tile { position: relative; min-width: 0; }
.tile a { display: block; text-decoration: none; color: inherit; }
.sq { position: relative; aspect-ratio: 1; overflow: hidden; background: #101a1e; }
.sq img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: opacity .42s var(--ease), transform .52s var(--ease);
}
/* Croisement d'opacité de deux images — surtout pas un filtre CSS :
   les versions colorisées ont un travail de lumière qu'un grayscale()
   ne reproduirait pas. */
.sq .cl { opacity: 0; }
.tile:hover .cl, .tile:focus-within .cl, .tile.is-tapped .cl { opacity: 1; }
.tile:hover .sq img, .tile:focus-within .sq img, .tile.is-tapped .sq img { transform: scale(1.028); }

.sq .edge {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--oe); transform: scaleX(0); transform-origin: left;
  transition: transform .42s var(--ease);
}
.tile:hover .edge, .tile:focus-within .edge, .tile.is-tapped .edge { transform: scaleX(1); }

.sq .num {
  position: absolute; left: 20px; top: 18px;
  font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .18em; color: var(--oe); opacity: 0; transition: opacity .3s var(--ease);
}
.tile:hover .num, .tile:focus-within .num, .tile.is-tapped .num { opacity: 1; }

/* Retour au repos 25 % plus rapide, même courbe. */
.tile .sq img, .tile .edge, .tile .num { transition-duration: .315s, .39s; }
.tile:hover .sq img, .tile:hover .edge, .tile:hover .num,
.tile.is-tapped .sq img, .tile.is-tapped .edge, .tile.is-tapped .num {
  transition-duration: .42s, .52s;
}

/* La légende est hors du carré : les titres sont déjà composés dans les
   images, à des hauteurs variables — toute légende posée dessus en
   recouvrirait certains. */
.cap { padding: 17px 2px 0; }
/* Discipline : certaines images la portent déjà, d'autres non — la mention
   lève l'ambiguïté. Volontairement discrète, en retrait de la couleur
   signature qui reste au thème. */
.cap .kind {
  font: 500 10px/1.3 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .22em; text-transform: uppercase;
  color: rgba(171,189,200,.72); margin: 0 0 7px;
}
.clair .cap .kind { color: #5C6C74; }
.cap .disc {
  font: 500 11px/1.35 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .2em; text-transform: uppercase; color: var(--oe);
}
.cap .acc {
  font: 400 17px/1.38 'Source Sans 3', system-ui, sans-serif;
  color: rgba(242,245,245,.84); margin-top: 9px; text-wrap: pretty;
}
.tile:hover .cap .acc, .tile:focus-within .cap .acc { color: var(--paper); }

.tap {
  position: absolute; right: 14px; top: 12px;
  font: 500 11px/1 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .16em; text-transform: uppercase;
  color: rgba(242,245,245,.75); border: 1px solid rgba(242,245,245,.4);
  padding: 7px 11px; display: none;
}

@media (max-width: 860px) {
  .grid6 { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  /* Pas de survol au doigt : le premier appui colorise, le second ouvre. */
  .tap { display: block; }
  .sq { outline: 1px solid transparent; }
  .tile.is-tapped .sq { outline-color: var(--oe); }
}

/* =========================================================================
   COMPTEUR D'ANNÉES — accueil, une seule fois par session
   ========================================================================= */
.load {
  position: fixed; inset: 0; z-index: 100; background: var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  transition: opacity .7s var(--ease);
}
.load.is-out { opacity: 0; pointer-events: none; }
.load[hidden] { display: none; }
.year {
  font: 700 clamp(96px, 15.2vw, 292px)/.82 'Oswald', system-ui, sans-serif;
  letter-spacing: -.01em; color: var(--paper); font-variant-numeric: tabular-nums;
}
.year.blur { color: rgba(242,245,245,.30); letter-spacing: .01em; }
.evt {
  font: 500 clamp(13px, 1.1vw, 21px)/1.5 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .16em; text-transform: uppercase; color: var(--mist);
  margin-top: 26px; text-align: center; max-width: 800px;
  padding: 0 var(--marge); min-height: 2.6em;
}
.rule-y { position: absolute; left: var(--marge); right: var(--marge); bottom: clamp(60px, 11vh, 120px); }
.rule-y .bar { height: 1px; background: rgba(171,189,200,.22); position: relative; }
/* Pas de transition CSS ici : la largeur est animée image par image par le
   compteur, en même temps que le chiffre. Les deux entreraient en conflit. */
.rule-y .bar b { position: absolute; top: 0; left: 0; height: 1px; background: var(--paper); }
.rule-y .tk { position: absolute; top: -7px; width: 1px; height: 15px; background: rgba(171,189,200,.4); }
.rule-y .tk.on { background: var(--paper); height: 23px; top: -11px; }
.rule-y .ends { display: flex; justify-content: space-between; margin-top: 20px;
                font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
                letter-spacing: .2em; color: rgba(171,189,200,.6); }

/* =========================================================================
   PIED DE PAGE CONTACT
   ========================================================================= */
.foot { padding: clamp(48px, 7vh, 74px) var(--marge) clamp(44px, 6vh, 62px);
        border-top: 1px solid var(--line); }
.foot .k { font: 500 12px/1 'IBM Plex Mono', ui-monospace, monospace;
           letter-spacing: .28em; text-transform: uppercase; color: var(--mist); }
/* Deux contacts côte à côte quand il y en a deux, l'un sous l'autre sinon. */
.pers-row { display: flex; flex-wrap: wrap; gap: clamp(28px, 5vw, 96px); }
.pers { flex: 0 1 auto; min-width: 0; }
.pers .nm { margin-top: 22px; }
@media (max-width: 860px) { .pers-row { gap: 34px; } }
.foot .nm { font: 700 clamp(28px, 2.3vw, 44px)/1.16 'Oswald', system-ui, sans-serif;
            text-transform: uppercase; letter-spacing: .02em; margin: 22px 0 0; }
.foot .ro { font: 400 18px/1.5 'Source Sans 3', system-ui, sans-serif;
            color: rgba(242,245,245,.66); margin: 8px 0 0; }
.foot .ln { font: 400 clamp(18px, 1.15vw, 22px)/1.6 'Source Sans 3', system-ui, sans-serif;
            margin: 26px 0 0; }
.foot .ln a { color: var(--paper); text-decoration: none;
              border-bottom: 1px solid var(--oe, var(--slate)); }
.foot .ln a:hover { color: var(--oe); }

/* =========================================================================
   MOBILE — le voile bascule vers le bas, le texte devient un bandeau
   ========================================================================= */
@media (max-width: 860px) {
  :root { --topscrim-h: clamp(260px, 40vh, 480px); }

  .veil { background: linear-gradient(0deg,
            rgba(7,12,14,.96) 0%, rgba(7,12,14,.88) 22%,
            rgba(7,12,14,.42) 48%, rgba(7,12,14,0) 72%); }
  .clair .veil { background: linear-gradient(0deg,
            rgba(255,255,255,.97) 0%, rgba(255,255,255,.90) 22%,
            rgba(255,255,255,.46) 48%, rgba(255,255,255,0) 72%); }
  .edgescrim { display: none; }

  .plaque {
    left: var(--marge); right: var(--marge); width: auto;
    bottom: calc(clamp(90px, 14vh, 210px) + env(safe-area-inset-bottom));
  }
  .prolong { max-width: none; }

  /* Le rail vertical devient une série de filets horizontaux sous le texte. */
  .rail {
    right: auto; left: var(--marge); top: auto;
    bottom: calc(clamp(44px, 7vh, 96px) + env(safe-area-inset-bottom));
    transform: none; flex-direction: row; align-items: center; gap: 10px;
  }
  .rail em { margin: 0 8px 0 0; }
  .rail i { width: 40px; height: 2px; }

  .cue { bottom: calc(20px + env(safe-area-inset-bottom)); }
  .cue i { height: 34px; }

  .dlrow { flex-direction: column; }
  .card { padding: 30px 26px; }
}

/* =========================================================================
   MOUVEMENT RÉDUIT — pas de vidéo, pas de transition. Le voile fonctionne
   à l'identique sur l'image fixe, les paliers restent lisibles.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .stage__media video { display: none; }
  .plaque > *, .plaque.is-on > * { transition: none; transform: none; }
  .rail i, .cue, .sq img, .btn { transition: none; }
}
