/* ============================================================
   ORYX — le storytelling au scroll
   Structure reprise de la maquette validée : une scène collante
   en 100vh, des chapitres qui défilent PAR-DESSUS grâce à un
   margin-top négatif. Le scroll natif n'est jamais détourné.
   ============================================================ */

/* ---------- barre de progression : la preuve que le scroll agit ---------- */
.progress{
  position:fixed; top:calc(var(--bar-h) + var(--nav-h)); left:0; right:0; height:2px;
  z-index:99; background:rgba(244,239,230,.08);
}
.progress i{ display:block; height:100%; width:0; background:var(--pulse); transition:width .1s linear; }

/* ---------- hero ---------- */
.hero{
  position:relative; z-index:2; min-height:100vh; min-height:100svh;
  display:flex; flex-direction:column; justify-content:center;
  padding:calc(var(--bar-h) + var(--nav-h) + 6vh) var(--gutter) 0;
}
.hero .eyebrow{ letter-spacing:.32em; }
.hero h1{
  font-family:var(--display); font-weight:800; line-height:.92; letter-spacing:-.045em;
  font-size:clamp(46px,9.2vw,132px); margin:14px 0 0; max-width:16ch;
}
/* Le mot en contour. Deux réglages non évidents :
   1. `-webkit-text-stroke` dessine le trait CENTRÉ sur le contour ; sa
      moitié intérieure envahit les contreformes. On peint donc le trait
      avant le remplissage et on remplit de la couleur du fond, ce qui
      recouvre la moitié intérieure. N'est possible que sur un fond uni.
   2. L'interlettrage du titre est serré (-0,045em) : rempli cela ne se
      voit pas, en contour les traits voisins se rejoignent. On desserre.
   La graisse est allégée : en 800, l'ouverture du « e » de cette police
   est une fente horizontale qui, tracée, ressemble à une barre en travers
   de la lettre. */
.hero h1 .outline{
  /* Manrope, et non la police d'affichage : l'ouverture du « e » de
     Bricolage Grotesque est une fente horizontale qui court jusqu'au bord
     droit du glyphe. Remplie on ne la voit pas, tracée en contour elle
     devient une barre en travers de la lettre — à toutes les graisses.
     Manrope est déjà chargée pour le corps de texte, donc gratuite. */
  font-family:var(--sans);
  color:var(--ink);
  -webkit-text-fill-color:var(--ink);
  -webkit-text-stroke:max(1.8px, 0.026em) var(--bone);
  paint-order:stroke fill;
  letter-spacing:0;
}
.hero .lead{ max-width:56ch; }
.hero .cta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:34px; align-items:center; }
.hero .price{ font-family:var(--mono); font-size:12px; color:var(--tert); }
.hero .cue{
  margin-top:auto; padding:6vh 0 5vh; display:flex; align-items:center; gap:12px;
  color:var(--tert); font-family:var(--mono); font-size:11px; letter-spacing:.14em;
}
.hero .cue i{ display:block; width:1px; height:38px; background:linear-gradient(var(--pulse),transparent); animation:cue 2.1s infinite; }
@keyframes cue{ 0%{opacity:0;transform:translateY(-8px)} 40%{opacity:1} 100%{opacity:0;transform:translateY(8px)} }

/* ---------- la scène 3D ---------- */
.story{ position:relative; z-index:2; }
.stage{
  position:sticky; top:0; height:100vh; height:100svh; z-index:1;
  pointer-events:none; overflow:hidden;
}
.stage canvas{ width:100%; height:100%; display:block; }
/* image de repli : servie tant que la 3D n'est pas prête, ou à sa place */
/* En repli, l'image tient la place exacte de la machine : d'un seul
   côté du cadre. Plein cadre, elle passait sous le texte du chapitre
   et le rendait illisible. */
.stage .poster{
  position:absolute; inset:0; background-size:auto 76%; background-repeat:no-repeat;
  background-position:center; opacity:0; transition:opacity .45s var(--ease-out),
  background-position .6s var(--ease-out);
}
.stage .poster.on{ opacity:1; }

/* Voile de lisibilité. Quand la caméra plonge sur le plateau, la machine
   remplit tout le cadre et le texte se retrouve posé sur des gris clairs.
   Le voile éteint la moitié qui porte le texte — jamais celle qui porte
   la machine, et il suit donc l'alternance des chapitres. */
.stage .scrim{
  position:absolute; inset:0; opacity:0;
  transition:opacity .45s var(--ease-out), background .45s var(--ease-out);
}
.stage[data-scrim="left"] .scrim{
  opacity:1;
  background:linear-gradient(90deg,var(--ink) 0%,rgba(5,7,15,.90) 24%,rgba(5,7,15,0) 54%);
}
.stage[data-scrim="right"] .scrim{
  opacity:1;
  background:linear-gradient(270deg,var(--ink) 0%,rgba(5,7,15,.90) 24%,rgba(5,7,15,0) 54%);
}


/* ---------- les chapitres ---------- */
.chapters{ position:relative; margin-top:-100vh; margin-top:-100svh; z-index:2; }
.chapter{ min-height:200vh; min-height:200svh; padding:0 var(--gutter); }
/* Le chapitre d'ouverture est plus court : rien ne s'y imprime, il n'a
   qu'à établir la machine et prouver que le scroll agit. À la longueur
   des autres, il retenait le lecteur avant même que le récit commence. */
.chapter[data-chapter="intro"]{ min-height:125vh; min-height:125svh; }
.chapter:last-of-type{ padding-bottom:24vh; }
.copy{ position:sticky; top:32vh; width:min(40vw,470px); }
/* imprimante à gauche → texte à droite, et l'inverse */
.chapter[data-side="left"]  .copy{ margin-left:auto; }
.chapter[data-side="right"] .copy{ margin-right:auto; }
.copy .num{ font-family:var(--mono); font-size:11px; letter-spacing:.2em; color:var(--pulse); }
.copy h2{
  font-family:var(--display); font-weight:800; font-size:clamp(30px,3.8vw,52px);
  line-height:1.02; letter-spacing:-.03em; margin:14px 0 0;
}
.copy .pain{ margin:16px 0 0; font-size:15.5px; color:var(--desert); font-style:italic; }
.copy p{ color:var(--dim); line-height:1.68; font-size:16px; margin:16px 0 0; }
.copy ul{ margin:20px 0 0; padding:0; list-style:none; display:flex; flex-direction:column; gap:9px; }
.copy li{ font-family:var(--mono); font-size:12.5px; color:var(--bone); padding-left:18px; position:relative; }
.copy li::before{ content:""; position:absolute; left:0; top:7px; width:6px; height:6px; background:var(--pulse); border-radius:1px; }
/* le fondu est piloté en JS depuis la position du bloc : sans JS,
   tout reste visible et la page se lit de haut en bas. */
.js .copy{ opacity:0; will-change:opacity, transform; }

/* ---------- l'étagère : la récompense cumulative ---------- */
.shelf{
  position:fixed; left:0; right:0; bottom:0; z-index:40; height:52px;
  display:flex; align-items:center;
  background:linear-gradient(180deg,rgba(5,7,15,0),rgba(5,7,15,.94) 40%);
  border-top:1px solid var(--line);
  transform:translateY(100%); transition:transform .45s var(--ease);
}
.shelf.on{ transform:none; }
.shelf .lbl{ font-family:var(--mono); font-size:10px; letter-spacing:.18em; color:var(--tert); padding:0 18px 0 var(--gutter); white-space:nowrap; }
.shelf .slots{ display:flex; gap:10px; flex:1; }
.slot{
  width:34px; height:34px; border:1px solid var(--line); border-radius:7px;
  display:grid; place-items:center; opacity:.28;
  transition:opacity .5s var(--ease-out), border-color .5s, transform .5s var(--ease-out);
}
.slot.filled{ opacity:1; border-color:rgba(16,242,160,.5); transform:translateY(-2px); }
.slot svg{ width:19px; height:19px; stroke:var(--bone); fill:none; stroke-width:1.6; }
.slot.filled svg{ stroke:var(--pulse); }
.shelf .buy{ padding-right:var(--gutter); }
.shelf .buy .btn{ padding:9px 16px; font-size:13px; min-height:38px; }

/* ---------- sortie du storytelling ---------- */
.story-exit{ position:relative; z-index:2; height:34vh; }

/* ---------- mobile : on GARDE l'alternance, en plus petit ----------
   Le bandeau en surplomb rejetait le texte sous l'image et cassait la
   composition qui fait tout le style de la page. On conserve donc la
   scène collante et la colonne de texte à côté ; seule la typographie
   rétrécit, et la caméra recule pour que la machine tienne dans sa
   moitié. Le voile devient indispensable : la colonne est étroite. */
@media (max-width:900px){
  .stage{ top:0; height:100vh; height:100svh; }
  .chapter{ min-height:190vh; min-height:190svh; padding:0 var(--gutter); }
  .chapter[data-chapter="intro"]{ min-height:115vh; min-height:115svh; }
  /* 48 % : chaque point rendu à la colonne d'image évite de reculer la
     caméra d'autant, et la machine reste lisible. */
  .copy{ top:23vh; width:48%; }
  .copy .num{ font-size:9.5px; letter-spacing:.16em; }
  .copy h2{ font-size:clamp(19px,5.2vw,30px); line-height:1.06; margin-top:9px; }
  /* L'interligne du titre est très serré (0,92). Rempli, le chevauchement
     des lignes passe pour du style ; en contour, les descendantes croisent
     la ligne du dessous. En français le titre tient sur trois lignes ici. */
  .hero h1{ line-height:.99; }
  .copy .pain{ font-size:12.5px; margin-top:11px; }
  .copy p{ font-size:13px; line-height:1.55; margin-top:11px; }
  .copy ul{ margin-top:13px; gap:6px; }
  .copy li{ font-size:10.5px; padding-left:13px; }
  .copy li::before{ width:5px; height:5px; top:5px; }
  .copy .proof{ font-size:10.5px; }
  .stage[data-scrim="left"] .scrim{
    background:linear-gradient(90deg,var(--ink) 0%,rgba(5,7,15,.93) 38%,rgba(5,7,15,0) 66%);
  }
  .stage[data-scrim="right"] .scrim{
    background:linear-gradient(270deg,var(--ink) 0%,rgba(5,7,15,.93) 38%,rgba(5,7,15,0) 66%);
  }
  .stage .poster{ background-size:auto 46%; }
  .shelf .lbl{ padding:0 12px 0 var(--gutter); font-size:9px; }
  .slot{ width:28px; height:28px; }
  .story-exit{ height:14vh; }
}

/* Très petits écrans : la colonne de texte ne peut plus rétrécir sans
   devenir illisible, c'est la machine qui cède du terrain. */
@media (max-width:430px){
  .copy{ width:54%; top:21vh; }
  .copy h2{ font-size:clamp(18px,5.6vw,24px); }
  /* La colonne mange 58 % de la largeur : le voile doit couvrir autant,
     sinon la machine passe sous les fins de ligne. */
  .stage[data-scrim="left"] .scrim{
    background:linear-gradient(90deg,var(--ink) 0%,var(--ink) 34%,rgba(5,7,15,.94) 56%,rgba(5,7,15,0) 82%);
  }
  .stage[data-scrim="right"] .scrim{
    background:linear-gradient(270deg,var(--ink) 0%,var(--ink) 34%,rgba(5,7,15,.94) 56%,rgba(5,7,15,0) 82%);
  }
}

@media (prefers-reduced-motion: reduce){
  .hero .cue i{ animation:none; }
  .js .copy{ opacity:1 !important; transform:none !important; }
  .progress i{ transition:none; }
}
