/* Page d'attente « Seuil ». Une scène plein écran, l'interface posée dessus.
   La scène est une boîte 16:9 qui couvre l'écran (comme object-fit: cover) :
   --W/--H sa taille, --L/--T son décalage. Le texte se place par rapport à
   elle, pour tomber sur les mêmes zones sombres de l'image à toutes les
   tailles (ciel au-dessus du moniteur, pied du moniteur, bureau).
   Mission 2 (06/10) : titre Archivo étendu 900 (choix de Théo), une phrase,
   le compte, une pilule de verre au centre bas, trois icônes, le folio. */

/* Archivo étendu (wdth 125, graisse 100 à 900 dans un seul fichier, latin). */
@font-face { font-family: "Archivo Etendu"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(/assets/fonts/archivo-expanded-latin.woff2) format("woff2"); }
@font-face { font-family: "Martian Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/assets/fonts/martian-mono-latin.woff2) format("woff2"); }
/* Replis à la même chasse que Martian Mono (0,7 em) : la bascule change le
   dessin des lettres, pas leur place. Menlo (Mac, iOS) et Courier New (Windows)
   chassent à 0,6 em. */
@font-face { font-family: "Repli Menlo"; src: local("Menlo"), local("Menlo-Regular"); size-adjust: 116.3%; }
@font-face { font-family: "Repli Courier"; src: local("Courier New"), local("CourierNewPSMT"); size-adjust: 116.6%; }

:root {
  --blanc: #F4F1EA;
  --nuit: #06080b;
  --g: 32px;                                   /* bord */
  --e: 32px;                                   /* bord gauche du folio */
  --px: .3; --py: .5;                          /* point d'ancrage du recadrage */
  --W: max(100vw, 177.78svh);
  --H: calc(var(--W) * .5625);
  --L: calc((100vw - var(--W)) * var(--px));
  --T: calc((100svh - var(--H)) * var(--py));
  --mono: "Martian Mono", "Repli Menlo", "Repli Courier", monospace;
  --large: "Archivo Etendu", "Arial Black", sans-serif;
  --m: clamp(10px, min(.62vw, 1.3vh), 14px);  /* corps du registre */
  /* Le titre : une ligne d'Archivo étendu 900 en capitales, calée sur la
     largeur du cadre. --titre-l : avance du titre en em (mesurée), --titre-h :
     hauteur de l'encre en em. Changer de police tient en ces variables. */
  --police-titre: var(--large);
  --titre-l: 13.9; --titre-l2: 7.47; --titre-h: .7;
  /* Le bouton : la seule couleur de la page. Elle suit le fond affiché
     (décision de Théo, DECISION-teinte-par-fond.md) : une teinte par démo, tirée
     de son accent mesuré, toutes à la même clarté (OKLCH L 0,78). Sans script
     et en mouvement réduit : celle du premier fond, ECLIPSE. */
  --teinte: #F69F72; --teinte-t: #21120A;
  --sortie: cubic-bezier(.16, 1, .3, 1);       /* la courbe du dépliage, mesurée sur la référence */
  /* Pilule et bouton réduits d'un cinquième (Théo, 06/10 : « trop gros sur PC ») :
     pilule 56 → 46 px, bouton 48 → 38 px, dépliée 420 → 340 px. */
  --hp: 46px;                                  /* hauteur de la pilule */
  --lf: min(340px, calc(100vw - 40px));        /* largeur dépliée */
}

/* INERTE depuis le 06/10 (DECISION-mobile-video.md) : le bouton n'a plus de
   teinte, plus rien ne lit --teinte. Ce bloc, le gel de attente-forme.js et
   data-fond restent jusqu'à la validation de Théo (liste dans RAPPORT-2.md). */
/* Propriétés enregistrées : le changement de teinte est un vrai fondu de
   couleur (1,2 s, lancé avec le balayage des volets), pas un saut. */
@property --teinte { syntax: "<color>"; inherits: true; initial-value: #F69F72; }
@property --teinte-t { syntax: "<color>"; inherits: true; initial-value: #21120A; }
html { transition: --teinte 1.2s cubic-bezier(.4, 0, .2, 1), --teinte-t 1.2s cubic-bezier(.4, 0, .2, 1); }
html[data-fond="eclipse"] { --teinte: #F69F72; --teinte-t: #21120A; }  /* cuivre : les verres d'ECLIPSE */
html[data-fond="circa"]   { --teinte: #F2A04A; --teinte-t: #120B03; }  /* sodium (Théo : « le orange va avec CIRCA ») */
html[data-fond="raster"]  { --teinte: #89BEEB; --teinte-t: #0A1723; }  /* acier : le cuir marine de RASTER */
html[data-fond="offset"]  { --teinte: #FF918E; --teinte-t: #221010; }  /* corail : le rouge du logo d'OFFSET */
/* Figée (saisie, survol du bouton, envoi, succès), la pilule garde sa
   teinte en propre ; dégelée, elle rejoint celle de la page en 1,2 s. */
.inscription.degel { transition: --teinte 1.2s cubic-bezier(.4, 0, .2, 1), --teinte-t 1.2s cubic-bezier(.4, 0, .2, 1); }

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; overflow: hidden; }
body {
  background: var(--nuit); color: var(--blanc);
  font: 400 var(--m)/1.55 var(--mono);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
a { color: inherit; text-underline-offset: .25em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--blanc); outline-offset: 4px; }
.lu { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ── La scène ──────────────────────────────────────────────────────────── */
.scene {
  position: fixed; left: var(--L); top: var(--T);
  width: var(--W); height: var(--H); overflow: hidden;
}
.scene-img { display: block; width: 100%; height: 100%; }
.volets { position: absolute; inset: 0; visibility: hidden; }
.scene.vif .volets { visibility: visible; }
/* Pendant le geste de souris, l'image fixe s'efface : les fentes entre volets
   montrent le noir, et chaque volet s'assombrit avec son angle. Pendant le
   balayage, elle reste dessous et bouche les jointures des volets. */
.scene { background: #000; }
.scene.geste .scene-img { visibility: hidden; }
.volets b::after { content: ""; position: absolute; inset: 0; background: #000; opacity: var(--o, 0); }
.volets i {
  position: absolute; top: 0; bottom: 0;
  left: calc(var(--i) * var(--cw)); width: calc(var(--cw) + 1px);
  transform-style: preserve-3d;
}
.volets b {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background: #000; transform: rotateY(calc(var(--k) * 120deg)) translateZ(var(--r));
}
/* L'image d'une face (--im, posée par le script). Une image chargée par
   url() sur une colonne de 80×900 px devenait, au premier balayage, le
   « plus grand affichage » de Chromium : LCP mesuré à 7,2 s au lieu du
   titre à 40 ms. Une image GÉNÉRÉE (le fondu de l'image sur elle-même, à
   100 %, identique à l'œil) n'est pas suivie par le LCP : mesuré, le titre
   reste le plus grand affichage sur 16 s, balayages compris. Firefox n'a pas
   cette fonction : il garde l'image directe. */
.volets b::before {
  content: ""; position: absolute; inset: 0;
  background: #000 no-repeat var(--im, none); background-size: var(--sw) 100%;
  background-position: calc(var(--i) * var(--cw) * -1) 0;
}
@supports (background-image: -webkit-cross-fade(url(a.png), url(a.png), 100%)) {
  .volets b::before { background-image: -webkit-cross-fade(var(--im), var(--im), 100%); }
}
/* Le voile : 18 % de noir sur le tiers bas, rien ailleurs, aucune teinte. */
.voile {
  position: fixed; left: 0; right: 0; bottom: 0; height: 34svh; pointer-events: none;
  background: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,.18) 28%);
}


/* ── L'en-tête : titre, promesse, symbole, centrés au-dessus des écrans ─
   Décision de Théo (DECISION-3b.md). Tout se dimensionne sur --A, la
   hauteur de ciel au-dessus du bord du moniteur au centre de l'écran (19 %
   de la scène) : le titre en prend un tiers, la promesse un sixième, le
   symbole un peu plus d'un tiers ; il se pose sur le cadre noir du
   moniteur, jamais sur son écran. */
.tete {
  position: fixed; left: 0; right: 0; top: var(--g);
  display: flex; flex-direction: column; align-items: center; text-align: center;
  --A: calc(var(--T) + .19 * var(--H) - var(--g));
}
.titre {
  font: 900 var(--f)/.74 var(--police-titre); font-stretch: 125%;
  text-transform: uppercase; letter-spacing: -.02em; white-space: nowrap;
  --f: min(calc(.34 * var(--A) / var(--titre-h)), calc(70vw / var(--titre-l)));
}
/* La promesse : le deuxième niveau de lecture, après le titre. */
.promesse {
  margin-top: calc(.09 * var(--A)); text-wrap: balance;
  font: 500 max(22px, calc(.18 * var(--A)))/1.15 var(--large); font-stretch: 125%; letter-spacing: -.01em;
}
.symbole { display: block; margin-top: calc(.08 * var(--A)); height: max(48px, calc(.35 * var(--A))); width: auto; fill: var(--blanc); }

/* ── Le centre bas : la pilule et les icônes ───────────────────────────── */
/* La pilule se pose sur le pied du moniteur (76 % de la scène), jamais
   plus bas que ce qu'il faut pour laisser les icônes et le folio. Le compte
   à rebours qui la précédait (74 px) est retiré (Théo, 06/10) : la pilule
   garde sa place, l'air libéré reste vide. */
.centre {
  position: fixed; left: 0; right: 0;
  top: min(calc(var(--T) + .76 * var(--H) - 14px), calc(100svh - var(--g) - 202px));
  display: flex; flex-direction: column; align-items: center; pointer-events: none;
}
.centre > * { pointer-events: auto; }

/* ── La pilule de verre ────────────────────────────────────────────────── */
/* Verre neutre (blanc à 10 %) : flou et saturation de ce qui est derrière,
   un filet plus clair en haut (le reflet), une ombre longue et douce. Le
   reflet qui suit la souris est un dégradé radial (--gx/--gy), sans image. */
.inscription { position: relative; display: flex; flex-direction: column; align-items: center; width: var(--lf); }
.verre {
  position: relative; display: flex; align-items: center; gap: 0;
  width: var(--lv, var(--lf)); height: var(--hp); padding: 4px; border-radius: 999px;
  background: rgb(255 255 255 / .1);
  -webkit-backdrop-filter: blur(20px) saturate(170%); backdrop-filter: blur(20px) saturate(170%);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .34), inset 0 -1px 0 rgb(255 255 255 / .06),
              0 32px 64px -24px rgb(0 0 0 / .7), 0 12px 24px -12px rgb(0 0 0 / .45),
              0 0 24px -12px rgb(255 255 255 / .16);
  transition: width .52s var(--sortie);
}
.verre::before, .verre::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; }
/* Le bord : plus clair en haut, presque éteint sur les flancs. */
.verre::before {
  padding: 1px;
  background: linear-gradient(rgb(255 255 255 / .55), rgb(255 255 255 / .1) 45%, rgb(255 255 255 / .18));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* Le reflet sous la souris (bureau seulement : le script ne pose --gl qu'au pointeur fin). */
.verre::after {
  background: radial-gradient(180px circle at var(--gx, 50%) var(--gy, -20%), rgb(255 255 255 / .16), transparent 70%);
  opacity: var(--gl, 0); transition: opacity .3s;
}
/* Repli : sans backdrop-filter, ou si le visiteur demande moins de
   transparence, le verre devient un aplat sombre à 62 %, sans flou. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .verre, .carte { background: rgb(8 10 14 / .62); }
}
@media (prefers-reduced-transparency: reduce) {
  .verre, .carte { background: rgb(8 10 14 / .62); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
html.sans-verre .verre, html.sans-verre .carte { background: rgb(8 10 14 / .62); -webkit-backdrop-filter: none; backdrop-filter: none; }

.verre input[type="email"] {
  /* Les 4 px entre le champ et le bouton sont une marge du champ, pas un
     gap du verre : au repos le champ est à largeur nulle, et un gap y
     poussait le bouton de 4 px vers la droite (8 / 0 au lieu de 4 / 4,
     vu par Théo le 06/10). */
  flex: 1; min-width: 0; height: 100%; margin-right: 4px; padding: 0 0 0 18px; border: 0; border-radius: 999px; background: transparent;
  color: var(--blanc); font: 400 max(14px, var(--m))/1 var(--mono); letter-spacing: .02em; outline: none;
  transition: opacity .25s .12s;
}
.verre input::placeholder { color: var(--blanc); opacity: .66; }
/* Le focus du champ : l'anneau entoure la pilule entière. */
.verre:has(input:focus-visible) { outline: 2px solid rgb(244 241 234 / .8); outline-offset: 3px; }
.inscription[data-souris] .verre:has(input:focus-visible) { outline: none; }
.joindre {
  /* Verre blanc translucide, le même partout (Théo, 06/10, DECISION-mobile-video.md) :
     22 % de blanc en moyenne, un filet clair en haut, texte blanc (4,6:1 au
     bureau, 5,9:1 au téléphone, mesurés). Plus aucune teinte. Pas de flou propre :
     dans la pilule, qui floute déjà, il ne floutait qu'elle (mesuré, sans gain). */
  position: relative; flex: none; display: inline-flex; align-items: center; gap: 10px;
  height: 100%; padding: 0 14px 0 17px; border: 0; border-radius: 999px; cursor: pointer; white-space: nowrap;
  background: linear-gradient(rgb(255 255 255 / .28), rgb(255 255 255 / .16));
  color: var(--blanc); font: 600 12.5px/1 var(--large); font-stretch: 125%; letter-spacing: .005em;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .62), inset 0 0 0 1px rgb(255 255 255 / .16), 0 6px 16px -8px rgb(0 0 0 / .55);
  transition: opacity .2s, transform .45s var(--sortie), background .2s;
}
/* Au doigt, pas de survol qui reste collé après l'appui, ni de surbrillance
   d'appui du navigateur (bleue en Chromium, grise sur iOS) : l'appui a son
   propre retour (:active, la pilule qui se déplie). */
@media (hover: hover) { .joindre:hover { background: linear-gradient(rgb(255 255 255 / .34), rgb(255 255 255 / .2)); } }
.joindre, .net-a, .carte-a, .legaux a, .pause { -webkit-tap-highlight-color: transparent; }
.joindre:active { transform: scale(.98); }
.plus { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; transition: transform .45s var(--sortie); }
.inscription[data-etat="ouvert"] .plus { transform: rotate(90deg); }
.coche { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: var(--blanc); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; opacity: 0; pointer-events: none; }
.coche .anneau { stroke: var(--blanc); stroke-width: 1.4; opacity: 0; }

/* Les états, avec script. Repos : la pilule épouse le bouton (--lb, mesuré
   par le script), le champ est replié. */
.js .inscription[data-etat="repos"] .verre { --lv: var(--lb, 214px); }
.js .inscription[data-etat="repos"] input[type="email"] { opacity: 0; padding: 0; margin: 0; transition: none; }
/* Envoi : le bouton s'efface à moitié, une lueur traverse le verre. */
.inscription[data-etat="envoi"] .joindre { opacity: .7; cursor: progress; }
.inscription[data-etat="envoi"] .joindre::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(100deg, transparent 30%, rgb(255 255 255 / .45) 50%, transparent 70%) 0 0 / 250% 100%;
  animation: lueur 1s linear infinite;
}
@keyframes lueur { from { background-position: 125% 0; } to { background-position: -125% 0; } }
/* Fait : la pilule se resserre en cercle, le bouton et le champ s'effacent,
   la coche est là. Le tracé, l'anneau et l'écriture ne se jouent qu'au
   moment de l'inscription (.anime, posé par le script) ; au rechargement sur
   ?inscrit=1, l'état est posé d'emblée. */
.inscription[data-etat="fait"] .verre { --lv: var(--hp); transition-duration: .6s; }
.inscription[data-etat="fait"] input[type="email"],
.inscription[data-etat="fait"] .joindre { opacity: 0; pointer-events: none; transition: opacity .18s; }
.inscription[data-etat="fait"] .joindre { transform: scale(.7); }
.inscription[data-etat="fait"] .coche { opacity: 1; filter: drop-shadow(0 0 5px rgb(255 255 255 / .3)); }
.inscription[data-etat="fait"] .coche path { stroke-dasharray: 28; stroke-dashoffset: 0; }
.anime[data-etat="fait"] .coche path { animation: trace .5s .42s var(--sortie) backwards; }
.anime[data-etat="fait"] .coche .anneau { animation: anneau 1.1s .5s cubic-bezier(.45, 0, .2, 1) backwards; }
.anime[data-etat="fait"] .etat { animation: ecrit .7s .7s var(--sortie) backwards; }
@keyframes trace { from { stroke-dashoffset: 28; } }
@keyframes anneau {
  0% { opacity: 1; stroke-dasharray: 22 200; stroke-dashoffset: 0; }
  85% { opacity: 1; }
  100% { opacity: 0; stroke-dasharray: 22 200; stroke-dashoffset: -172; }
}
@keyframes ecrit { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* La date d'ouverture : seulement une fois inscrit. Avec le script, à la fin
   de l'animation (la phrase finit de s'écrire à 1,4 s) ; sans script ou au
   rechargement sur ?inscrit=1, d'emblée. */
.ouverture { display: none; margin-top: 8px; text-align: center; letter-spacing: .04em; color: var(--blanc); }
.inscription[data-etat="fait"] .ouverture { display: block; }
.anime[data-etat="fait"] .ouverture { animation: fondu-monte .6s 1.5s var(--sortie) backwards; }
@keyframes fondu-monte { from { opacity: 0; transform: translateY(6px); } }
/* L'information RGPD n'apparaît qu'au moment de la collecte (champ ouvert) ;
   sa place est gardée (rien ne bouge quand elle arrive). */
.js .inscription:is([data-etat="repos"], [data-etat="fait"]) .info { visibility: hidden; }
/* Le texte sous le verre : succès (role=status) ou erreur (role=alert). */
.etat { max-width: var(--lf); margin-top: 12px; text-align: center; line-height: 1.6; }
.etat:empty { display: none; }
.etat a { white-space: nowrap; }
.secoue .verre { animation: secoue .32s linear; }
@keyframes secoue { 20%, 60% { transform: translateX(-2px); } 40%, 80% { transform: translateX(2px); } }
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ── Les trois icônes et leur carte (mécanique du pied de page du site) ── */
/* Une seule carte pour les trois icônes. Elle s'ouvre en 160 ms à sa place
   et à sa taille (jamais depuis l'icône précédente) ; d'une icône à l'autre,
   elle glisse en 200 ms sans se fermer : l'ancien volet s'efface d'abord
   (70 ms), le nouveau n'apparaît que quand la carte a presque sa taille,
   pour qu'aucun texte ne soit coupé ni superposé (RETOURS-IPHONE.md, mesuré).
   Ici elle s'ouvre vers le HAUT, au-dessus de la rangée. data-open (posé par
   attente-forme.js) gouverne ; sans script, le survol et le focus servent de filet. */
.reseaux { position: relative; display: flex; align-items: center; margin-top: 18px; }
.net-a {
  display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  color: rgb(244 241 234 / .72); transition: color .2s;
}
.net-a svg { display: block; }
.net:hover .net-a, .net-a:focus-visible, .reseaux[data-open] .net-a[aria-expanded="true"] { color: var(--blanc); }
.net-a:focus-visible { outline-offset: -2px; border-radius: 12px; }
.carte {
  --ci: 1; --cw: 340px; --ch: 112px; --fermee: cubic-bezier(.4, 0, 1, 1); --forme: cubic-bezier(.3, 0, 0, 1);
  position: absolute; bottom: calc(100% + 8px); z-index: 5;
  left: var(--cl, calc(var(--ci) * 44px + 22px - var(--cw) / 2));
  width: var(--cw); height: var(--ch); overflow: hidden; padding: 14px 16px; border-radius: 18px;
  background: rgb(12 14 18 / .86);
  -webkit-backdrop-filter: blur(22px) saturate(160%); backdrop-filter: blur(22px) saturate(160%);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), inset 0 0 0 1px rgb(255 255 255 / .1), 0 24px 48px -16px rgb(0 0 0 / .7);
  display: none; opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity .16s var(--fermee), transform .16s var(--fermee), display .16s allow-discrete,
    left 0s .16s, width 0s .16s, height 0s .16s;
}
.reseaux[data-open] .carte, .reseaux:not([data-open]):focus-within .carte {
  display: grid; opacity: 1; transform: none; pointer-events: auto;
  transition: opacity .16s cubic-bezier(0, 0, .2, 1), transform .16s cubic-bezier(0, 0, .2, 1), display 0s allow-discrete,
    left .2s var(--forme), width .2s var(--forme), height .2s var(--forme);
}
@media (hover: hover) {
  .reseaux:not([data-open]):hover .carte {
    display: grid; opacity: 1; transform: none; pointer-events: auto;
    transition: opacity .16s cubic-bezier(0, 0, .2, 1), transform .16s cubic-bezier(0, 0, .2, 1), display 0s allow-discrete,
      left .2s var(--forme), width .2s var(--forme), height .2s var(--forme);
  }
}
/* À l'ouverture (la carte était fermée ou en train de se fermer), le script
   pose .pose une image : la carte prend sa place et sa taille sans glisser. */
.reseaux .carte.pose { transition: opacity .16s cubic-bezier(0, 0, .2, 1), transform .16s cubic-bezier(0, 0, .2, 1), display 0s allow-discrete !important; }
@starting-style {
  .reseaux[data-open] .carte, .reseaux:not([data-open]):focus-within .carte { opacity: 0; transform: translateY(6px); }
}
@media (hover: hover) { @starting-style { .reseaux:not([data-open]):hover .carte { opacity: 0; transform: translateY(6px); } } }
/* Les géométries : le courriel (icône 1), X (2), Instagram (3). Ce sont
   les valeurs sans script ; le script les remplace par la taille mesurée du
   volet, à la police près. */
.reseaux:is([data-open="1"], :not([data-open]):has(> .net:nth-child(1):is(:hover, :focus-within), #carte-mail:focus-within)) .carte { --ci: 0; --cw: 272px; --ch: 74px; }
.reseaux:is([data-open="2"], :not([data-open]):has(> .net:nth-child(2):is(:hover, :focus-within), #carte-x:focus-within)) .carte { --ci: 1; }
.reseaux:is([data-open="3"], :not([data-open]):has(> .net:nth-child(3):is(:hover, :focus-within), #carte-instagram:focus-within)) .carte { --ci: 2; }
/* Chaque volet garde SA taille (align-self: start) : étirés sur la cellule
   commune, les trois mesuraient la hauteur du plus grand et la carte du
   courriel avait 44 px de vide (mesuré : 112 px pour 68). Pas de flou : un
   filtre sur du texte qui se fond faisait une bouillie de deux textes. */
.volet {
  grid-area: 1 / 1; align-self: start; justify-self: start; width: max-content; opacity: 0; visibility: hidden;
  transition: opacity .07s linear, visibility 0s linear .07s;
}
.reseaux:is([data-open="1"], :not([data-open]):has(> .net:nth-child(1):is(:hover, :focus-within), #carte-mail:focus-within)) #carte-mail,
.reseaux:is([data-open="2"], :not([data-open]):has(> .net:nth-child(2):is(:hover, :focus-within), #carte-x:focus-within)) #carte-x,
.reseaux:is([data-open="3"], :not([data-open]):has(> .net:nth-child(3):is(:hover, :focus-within), #carte-instagram:focus-within)) #carte-instagram {
  opacity: 1; visibility: visible;
  transition: opacity .13s cubic-bezier(0, 0, .2, 1) .1s, visibility 0s;
}
.reseaux .carte.pose .volet { transition-delay: 0s; }
.reseaux .carte.retrecit .volet { transition-duration: 0s; transition-delay: 0s; }
/* Un seul lien par carte, qui la couvre entière. */
.carte-a { display: grid; gap: 4px; color: inherit; text-decoration: none; outline: none; }
.carte-a::after { content: ""; position: absolute; inset: 0; }
.carte:has(.carte-a:focus-visible) { outline: 2px solid var(--blanc); outline-offset: -4px; }
.carte-t { display: flex; align-items: center; gap: 6px; font: 700 12.5px/1.3 var(--large); font-stretch: 125%; white-space: nowrap; }
.carte-h { color: rgb(244 241 234 / .7); white-space: nowrap; }
.carte-t svg { flex: none; }
.carte-tete { display: grid; grid-template-columns: 40px 1fr auto; column-gap: 12px; align-items: center; }
.avatar { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: #000;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .22); }
.avatar svg { height: 18px; fill: var(--blanc); }
.carte-qui { display: grid; gap: 2px; min-width: 0; }
.carte-coche { width: 15px; height: 15px; }
.carte-coche circle { fill: #1D9BF0; }
#carte-instagram .carte-coche circle { fill: #0095F6; }
.carte-coche path { fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.carte-act { align-self: start; padding: 4px 10px; border-radius: 999px; background: var(--blanc); color: #0b0b0c;
  font: 700 11px/1.2 var(--large); font-stretch: 125%; }
.carte-voir { display: inline-flex; align-items: center; gap: 5px; margin-top: 10px; color: rgb(244 241 234 / .7); }
.carte-a:hover .carte-voir, .carte-a:focus-visible .carte-voir { color: var(--blanc); }

/* ── Le folio ──────────────────────────────────────────────────────────── */
.folio {
  position: fixed; left: var(--e); right: var(--g); bottom: var(--g);
  display: flex; align-items: center; gap: 2.6em; text-transform: uppercase; letter-spacing: .14em;
}
.registre { white-space: pre; min-width: calc(16ch + 2.3em); } /* « 01 / 04  ECLIPSE », le plus long : le nom qui change ne pousse rien */
.pause {
  min-height: 44px; min-width: 44px; margin: -14px 0; padding: 0 .9em; border: 1px solid transparent;
  background: transparent; color: var(--blanc); font: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer;
}
.pause:hover { border-color: var(--blanc); }
.pause[aria-pressed="true"] { background: var(--blanc); color: var(--nuit); }
/* Les deux pages légales, à droite du folio (à la place de la bascule de
   langue : la page n'existe qu'en anglais). */
.legaux { margin-left: auto; display: flex; gap: 1.6em; }
.legaux a { display: inline-flex; align-items: center; min-height: 44px; margin-block: -14px; }
/* La ligne d'information sous la pilule (RGPD, art. 13). */
.info { margin-top: 10px; text-align: center; font-size: max(10px, calc(var(--m) * .9)); letter-spacing: .02em; color: rgb(244 241 234 / .78); }
.info a { color: var(--blanc); }

/* ── Très large (21:9 et au-delà) : le ciel au-dessus du moniteur est rogné.
   On remonte le cadrage (--py) pour garder une bande de ciel au titre ; la
   pilule reste sous le pied du moniteur. ─────────────────────────────────── */
@media (min-aspect-ratio: 2/1) {
  :root { --py: .3; }
}

/* ── Portrait (téléphone, tablette) : la scène entière, écrans compris, entre
   le titre et le formulaire. Les dix volets de Louver, sans survol. ──────── */
@media (max-aspect-ratio: 1/1), (max-height: 560px) {
  :root { --g: 24px; --e: 24px; --W: 110vw; --hp: 52px; }  /* bouton de 44 px : la cible tactile */
  /* Si le contenu ne tient pas (petit téléphone, téléphone couché), la page
     défile plutôt que de couper le formulaire. Aux tailles prévues, elle tient. */
  html, body { height: auto; overflow-x: hidden; overflow-y: auto; }
  body { display: flex; flex-direction: column; min-height: 100svh; padding: var(--g) 0; }
  .page { display: contents; }
  .tete { order: 1; } .scene { order: 2; } .centre { order: 3; } .folio { order: 4; }
  .tete { position: static; padding: 8px var(--g) 0; flex: none; }
  .titre span { display: block; }
  .titre { --f: min(calc((100vw - 2 * var(--g)) / var(--titre-l2)), 132px); line-height: .9; }
  .promesse { margin-top: 14px; font-size: max(17px, 4.6vw); }
  .symbole { position: relative; z-index: 1; margin-top: 16px; height: 44px; }
  /* La scène au téléphone (RETOURS-IPHONE.md, sujet 3) : à 162vw on ne voyait
     que 62 % de l'image, les deux écrans en gros plan sous un bandeau noir.
     À 110vw, 91 % de la largeur : le moniteur, le portable entier (clavier
     compris) et de la ville des deux côtés. L'image ne peut pas reculer
     davantage : les écrans en occupent 70 % de la largeur. Elle monte sous le
     symbole, et son haut se fond dans le noir sur un long dégradé, sans bord. */
  .scene {
    position: relative; left: auto; top: auto; flex: none; margin: -28px 0 -18px calc(var(--W) * -.09);
    -webkit-mask-image: linear-gradient(transparent, rgb(0 0 0 / .35) 12%, rgb(0 0 0 / .8) 22%, #000 32%, #000 88%, transparent);
            mask-image: linear-gradient(transparent, rgb(0 0 0 / .35) 12%, rgb(0 0 0 / .8) 22%, #000 32%, #000 88%, transparent);
  }
  .voile { display: none; }
  .centre { position: relative; top: auto; flex: none; padding: 0 20px; margin-block: auto; }
  .reseaux { margin-top: 12px; }
  .folio { position: relative; left: auto; right: auto; bottom: auto; padding: 12px var(--g) 0; flex: none; gap: 1.4em; }
}
@media (max-aspect-ratio: 1/1) and (max-width: 599px) and (max-height: 760px) {
  .symbole { height: 36px; margin-top: 12px; }
  .titre { --f: min(calc((100vw - 2 * var(--g)) / var(--titre-l2)), 9svh); }
}
@media (max-aspect-ratio: 1/1) and (min-width: 600px), (max-height: 560px) and (min-width: 600px) {
  :root { --g: 40px; --e: 40px; --W: 100vw; --m: 12px; }
  .titre { --f: min(calc((100vw - 2 * var(--g)) / var(--titre-l)), 10.5svh); }
  .titre span { display: inline; }
  .promesse { font-size: 24px; }
  .scene { margin-left: 0; }
}

/* ── Le téléphone en portrait (rapport ≤ 2:3) : la vidéo CIRCA ─────────────
   Décision de Théo (DECISION-mobile-video.md). Trois zones, de haut en bas,
   sans chevauchement : symbole, titre, promesse ; la vidéo, rien par-dessus ;
   la pilule. Au pied : les icônes à gauche, Pause / Privacy / Legal à droite.
   La vidéo (9:16) a du noir pur en haut et en bas, et son contenu (moniteur,
   portable) tient entre 5 % et 75 % de sa hauteur : on la dimensionne pour que
   ce contenu remplisse exactement la zone du milieu (unités cqh de la scène),
   ses marges noires passant sous le titre et sous la pilule. Ses flancs sont
   gris (le mur) : un fondu latéral quand elle est plus étroite que l'écran.
   Tablette en portrait (3:4) et téléphone couché gardent la scène du bureau. */
@media (max-aspect-ratio: 2/3) {
  :root { --g: 20px; --e: 20px; }
  html, body { height: 100%; overflow: hidden; }
  /* Le noir de la vidéo est #000 : la page le prend, sinon son rectangle se voyait. */
  body {
    background: #000;
    display: grid; grid-template-rows: auto minmax(0, 1fr) auto; row-gap: 1.5svh; min-height: 0; height: 100svh;
    padding: max(env(safe-area-inset-top), 4.5svh) 0 calc(max(env(safe-area-inset-bottom), 10px) + 52px);
  }
  .tete { grid-row: 1; padding: 0 var(--g); position: relative; top: auto; z-index: 1; }
  .symbole { order: -1; margin: 0 0 2svh; height: clamp(26px, 4.4svh, 36px); }
  .promesse { margin-top: 1.6svh; font-size: max(16px, 4.3vw); }
  .scene {
    grid-row: 2; position: relative; left: auto; top: auto; width: 100vw; height: auto; margin: 0;
    container-type: size; overflow: visible; background: none; z-index: 0;
    -webkit-mask-image: none; mask-image: none;
  }
  .scene picture { display: contents; }
  .scene-img, .scene-video {
    --hv: calc(100cqh / .7);
    position: absolute; left: 50%; top: calc(-.05 * var(--hv)); height: var(--hv); width: auto; aspect-ratio: 9 / 16;
    max-width: none; transform: translateX(-50%); object-fit: cover;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  }
  .scene-video { opacity: 0; transition: opacity .6s; }
  .scene.joue .scene-video { opacity: 1; }
  .volets, .voile { display: none; }
  /* Hauteur fixe, celle de l'état de succès (coche, phrase, date) : la vidéo
     ne rétrécit pas quand la date arrive. */
  .centre { grid-row: 3; position: relative; top: auto; margin: 0; padding: 1.5svh var(--g) 0; z-index: 1;
    height: calc(var(--hp) + 1.5svh + 62px); justify-content: flex-start; }
  /* Une erreur (trois lignes au plus) prend la place de la ligne RGPD, déjà
     lue à l'ouverture du champ : sinon elle descendait sur le pied (mesuré). */
  .inscription:has(.etat.erreur) .info { display: none; }
  .reseaux {
    position: fixed; left: max(env(safe-area-inset-left), 8px); bottom: max(env(safe-area-inset-bottom), 10px); margin: 0; z-index: 2;
  }
  .net-a svg { transform: scale(.82); }
  .folio {
    position: fixed; left: auto; right: max(env(safe-area-inset-right), 14px); bottom: max(env(safe-area-inset-bottom), 10px);
    padding: 0; height: 44px; gap: 1.2em; z-index: 2;
  }
  .registre { display: none; }
  .legaux { margin-left: 0; }
}

/* ── Mouvement réduit : aucun volet, aucun dépliage ; les états se
   remplacent par un fondu de 150 ms. ─────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .volets { display: none; }
  .verre, .joindre, .plus, input[type="email"] { transition: opacity .15s !important; }
  .anime[data-etat="fait"] .coche path, .anime[data-etat="fait"] .coche .anneau, .secoue .verre { animation: none; }
  .anime[data-etat="fait"] .etat { animation: fondu .15s; }
  .anime[data-etat="fait"] .ouverture { animation: fondu .15s .2s backwards; }
  html, .inscription.degel { transition: none; }
  .carte, .reseaux .carte.pose { transition: opacity .15s, display .15s allow-discrete !important; transform: none !important; }
  .volet, .reseaux .volet { transition: opacity .15s, visibility 0s !important; }
}
@keyframes fondu { from { opacity: 0; } }

/* ── Les pages légales de la porte (/en/privacy, /en/legal) ─────────────
   Même registre que la page d'attente : fond encre, Archivo, Martian Mono,
   sans scène. Elles défilent (la page d'attente, elle, tient dans l'écran). */
html.doc, html.doc body { height: auto; overflow: auto; }
html.doc body { font: 400 15px/1.7 var(--large); font-stretch: 125%; letter-spacing: -.005em; }
.doc-page { max-width: 46rem; margin: 0 auto; padding: 32px 24px 64px; }
.doc-retour { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
.doc-retour svg { height: 40px; fill: var(--blanc); }
.doc-titre { margin: 40px 0 12px; font: 900 clamp(40px, 9vw, 88px)/.9 var(--large); font-stretch: 125%; text-transform: uppercase; letter-spacing: -.02em; }
.doc-lede { font-size: 18px; line-height: 1.5; margin-bottom: 40px; color: rgb(244 241 234 / .86); }
.doc-bloc { padding: 24px 0; border-top: 1px solid rgb(244 241 234 / .16); }
.doc-bloc h2 { font: 400 var(--m)/1.4 var(--mono); text-transform: uppercase; letter-spacing: .14em; margin-bottom: 12px; }
.doc-bloc h2 span { opacity: .6; margin-right: .8em; }
.doc-bloc p + p { margin-top: .8em; }
.doc-bloc dl { display: grid; grid-template-columns: minmax(8em, 30%) 1fr; gap: 6px 16px; margin-bottom: .8em; }
.doc-bloc dt { font: 400 12px/1.7 var(--mono); text-transform: uppercase; letter-spacing: .1em; color: rgb(244 241 234 / .7); }
.doc-page a { text-underline-offset: .2em; }
.a-completer { background: #FFE14D; color: #111; padding: 0 .3em; font: 600 13px/1.5 var(--mono); }
.doc-date { margin-top: 32px; font: 400 12px/1.5 var(--mono); color: rgb(244 241 234 / .7); }
.doc-pied { display: flex; gap: 2em; margin-top: 24px; font: 400 12px/1.5 var(--mono); text-transform: uppercase; letter-spacing: .14em; }
.doc-pied a { display: inline-flex; align-items: center; min-height: 44px; }
@media (max-width: 520px) { .doc-bloc dl { grid-template-columns: 1fr; } .doc-bloc dd { margin-bottom: 8px; } }
