/* ============================================================================
   seuil-lk.css — LE SEUIL : le rideau de velours, premier écran de l'accueil.
   À charger APRÈS css/tour-lk.css, AVANT css/vestibule-lk.css.

   CE QUI A CHANGÉ LE 23 AOÛT 2026. Le rideau était dessiné en CSS : 28 plis,
   un chambranle, deux battants, et une progression scrubée au défilement.
   C'est désormais une VIDÉO tournée pour ça (assets/tour/rideau_lk.mp4, 8 s).
   Tout le velours dessiné a donc disparu de cette feuille — il ne reste que
   la typographie du carton titre, et la mécanique qui fait traverser.

   LE TRUC QUI FAIT TOUT : `mix-blend-mode: screen` sur la section.

   Le centre de la vidéo est un noir pur. En fondu « screen », le noir ne
   peint rien : le VESTIBULE, posé juste derrière (z-index 38), se voit donc
   par l'ouverture du rideau, et l'ouverture grandit avec elle. Le velours,
   lui, reste posé par-dessus. Sans ce fondu, la vidéo serait un mur opaque :
   on verrait le rideau s'ouvrir sur du noir, puis un fondu vers le couloir —
   deux plans au lieu d'un mouvement.

   Pour que le fondu prenne le couloir comme fond, la section doit blender
   dans le contexte d'empilement RACINE. C'est le cas : `.plan-seuil` est un
   enfant direct de <body>, et rien au-dessus n'isole (pas de filtre, pas
   d'opacité, pas de transform sur body). Ne pas envelopper le seuil dans un
   conteneur transformé — ça couperait le lien avec le couloir.
   ========================================================================== */

:root {
  --seuil-noir: #04040a;
}

/* ---------------------------------------------------------------------------
   Tant que le seuil est là, les trois plans du parcours restent muets. La
   classe est posée dès le HTML (et non par JS) pour qu'aucun plan ne clignote
   avant que le script ne s'exécute.
   --------------------------------------------------------------------------- */
body.seuil-actif main .plan {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Le seuil verrouille la page : aucun défilement natif pendant que la molette
   ouvre le rideau. */
body.seuil-actif {
  overflow: hidden;
}

/* ---------------------------------------------------------------------------
   La scène
   --------------------------------------------------------------------------- */
.plan-seuil {
  position: fixed;
  inset: 0;
  z-index: 40;
  overflow: hidden;
  background: transparent;
  /* voir l'en-tête : c'est lui qui laisse voir le couloir par l'ouverture */
  mix-blend-mode: screen;
  opacity: 1;
  transition: opacity .85s ease;
}

/* Sortie : on ne se contente pas d'un fondu, on TRAVERSE. Toute la scène
   grandit et passe hors champ pendant qu'elle s'efface, au moment précis où le
   couloir démarre son avance : les deux mouvements se recouvrent et le regard
   passe entre les pans. */
.plan-seuil.seuil-sortie {
  opacity: 0;
  transform: scale(1.42);
  pointer-events: none;
  transition:
    opacity 1.1s ease,
    transform 1.4s cubic-bezier(.32, 0, .24, 1);
}
.plan-seuil[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   LA VIDÉO DU RIDEAU
   ----------------------------------------------------------------------------
   `cover` : elle remplit l'écran quel que soit son format. Sur un téléphone en
   portrait, les pans sont rognés sur les côtés — c'est le bon compromis, le
   mouvement du milieu est ce qui compte.
   --------------------------------------------------------------------------- */
.seuil-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  background: #000;
  /* Le velours filmé est vif ; la direction artistique du seuil demande un
     rouge ÉTEINT, lumière de service — pas un chapiteau. On le baisse d'un
     cran. Retirer cette ligne rend la vidéo telle qu'elle a été tournée. */
  filter: brightness(.86) saturate(.94) contrast(1.04);
  /* Lente avancée pendant que le rideau s'ouvre : le velours grandit à peine,
     mais assez pour que l'œil sente qu'on approche avant même de traverser.
     La durée colle à celle de la vidéo. */
  transform: scale(1);
  transition: transform 8s linear;
  will-change: transform;
}

.plan-seuil.seuil-ouvre .seuil-video { transform: scale(1.1); }

/* ---------------------------------------------------------------------------
   Le titre — blanc sur le velours, capitales resserrées. Même typographie que
   le reste de l'accueil.
   --------------------------------------------------------------------------- */
.seuil-titre {
  position: relative;
  z-index: 7;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: clamp(1.5rem, 4vw, 3rem);
  pointer-events: none;
  /* Ombre portée : le velours est clair par endroits, le blanc pur s'y perd. */
  text-shadow: 0 2px 30px rgba(0, 0, 0, .8);
  opacity: 1;
  transition: opacity .5s ease;
}

/* Le rideau part : le carton titre s'efface, sans attendre la fin. */
.plan-seuil.seuil-ouvre .seuil-titre {
  opacity: 0;
  transition: opacity 1.5s ease .35s;
}

/* Un voile sombre sous le carton titre. Le velours filmé est clair par
   endroits et le blanc pur s'y perdait. En fondu « screen », assombrir la
   vidéo à cet endroit revient à laisser passer le noir du couloir : le texte
   se pose donc sur un creux, pas sur un rectangle rapporté. */
.seuil-titre::before {
  content: "";
  position: absolute;
  inset: -8vh -10vw;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center,
    rgba(0, 0, 0, .82) 0%,
    rgba(0, 0, 0, .62) 42%,
    rgba(0, 0, 0, .28) 66%,
    rgba(0, 0, 0, 0) 82%);
}

.seuil-marque {
  display: block;                   /* pour que la hauteur réservée à l'écriture tienne */
  font-family: 'DM Mono', monospace;
  font-size: .68rem;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .68);
  margin-bottom: clamp(1rem, 2.4vw, 1.8rem);
}

/* ---------------------------------------------------------------------------
   LE BRIEFING — le texte qui s'écrit tout seul au chargement.

   Aligné à gauche dans une colonne centrée : cent mots centrés ne se lisent
   pas. La largeur est bornée à 62 caractères, la mesure au-delà de laquelle
   l'œil perd sa ligne.
   --------------------------------------------------------------------------- */
.seuil-brief {
  margin: clamp(1.2rem, 2.6vw, 2.1rem) auto 0;
  max-width: 62ch;
  text-align: left;
}

.seuil-brief p {
  margin: 0;
  font-family: var(--hero-sans, 'Inter', sans-serif);
  font-size: clamp(.84rem, 1.02vw, .98rem);
  line-height: 1.72;
  color: rgba(255, 255, 255, .9);
}
.seuil-brief strong { color: #fff; font-weight: 600; }

/* Le second paragraphe est la consigne, pas le propos : un ton plus bas. */
.seuil-brief-suite {
  margin-top: clamp(.7rem, 1.6vw, 1.1rem) !important;
  color: rgba(255, 255, 255, .62) !important;
}

/* Avant que le script n'ait vidé les blocs, on ne montre pas le texte plein :
   il apparaîtrait une fraction de seconde, puis disparaîtrait pour se
   réécrire. `visibility` et non `opacity` : l'animation d'entrée tient déjà
   l'opacité du sur-titre et l'emporterait. */
.plan-seuil:not(.seuil-brief-pret) [data-machine] { visibility: hidden; }

/* Le curseur, sur le bloc en cours d'écriture. Un bloc plein et non un trait :
   sur du velours, un trait d'un pixel ne se voit pas. */
[data-machine].seuil-ecrit::after {
  content: "";
  display: inline-block;
  width: .5em;
  height: 1em;
  margin-left: .1em;
  vertical-align: -.14em;
  background: rgba(255, 255, 255, .85);
  animation: seuil-curseur 1s steps(1) infinite;
}

@keyframes seuil-curseur {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.seuil-titre h1 {
  margin: 0;
  /* Une seule ligne, deux moitiés : « LK » part avec le pan gauche, « Studio »
     avec le pan droit. Le titre s'ouvre en même temps que le rideau. */
  display: flex;
  justify-content: center;
  gap: .22em;
  /* Le serif éditorial de l'accueil (.studio-home h1) : c'est LUI la police
     du carton titre, pas le grotesque des plans. Déclaré explicitement pour ne
     pas dépendre de l'ordre des feuilles. */
  font-family: 'DM Serif Display', Georgia, serif;
  font-weight: 400;
  /* Un cran plus petit qu'avant : le hero porte maintenant cent mots de
     briefing sous le titre, il faut leur laisser la place. */
  font-size: clamp(2.2rem, 5.4vw, 4.8rem);
  line-height: .92;
  letter-spacing: -.035em;
  text-transform: uppercase;
  color: #fff;
}

.seuil-mot {
  display: inline-block;
  will-change: transform;
  /* L'écartement suit le velours : long, et posé aux deux bouts. */
  transition: transform 2.8s cubic-bezier(.22, 1, .32, 1);
}

.plan-seuil.seuil-ouvre .seuil-mot--haut { transform: translateX(-52vw); }
.plan-seuil.seuil-ouvre .seuil-mot--bas  { transform: translateX(52vw); }

/* La ligne du bas est légèrement décalée en clair : deux blancs, pas un seul,
   pour que le titre ne soit pas un bloc plat. */
.seuil-mot--bas { color: rgba(255, 255, 255, .82); }

/* column-reverse : le trait est écrit avant le texte dans le HTML, il se
   pose donc SOUS lui — un vrai indicateur de défilement, pas une barre
   plantée à côté du mot.
   L'invite attend la fin du briefing : proposer d'ouvrir pendant que le texte
   s'écrit, ce serait inviter à ne pas le lire. */
.seuil-invite {
  margin: clamp(1.4rem, 3vw, 2.4rem) 0 0;
  display: inline-flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: .9rem;
  font-family: 'DM Mono', monospace;
  font-size: .68rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .68);
  opacity: 0;
  transition: opacity .9s ease;
}

.plan-seuil.seuil-brief-fini .seuil-invite { opacity: 1; }

/* La flèche respire, seule chose qui bouge sur l'écran d'arrivée : c'est elle
   qui dit « faites quelque chose ». */
.seuil-fleche {
  display: block;
  width: 1px;
  height: 2.4rem;
  background: linear-gradient(to bottom, rgba(255, 255, 255, .7), transparent);
  animation: seuil-respire 2.4s ease-in-out infinite;
}

@keyframes seuil-respire {
  0%, 100% { opacity: .25; transform: translateY(-4px); }
  50%      { opacity: .9;  transform: translateY(4px); }
}

/* ---------------------------------------------------------------------------
   Entrée à l'arrivée sur la page : montée + net progressif, décalée élément
   par élément via --d.

   ANIMATION, ET NON TRANSITION. Une transition doit être déclenchée par un
   changement d'état — donc par du JavaScript. Si ce JavaScript n'arrive pas
   (onglet ouvert en arrière-plan, script en erreur, fichier en cache), l'état
   de repos ne se lève jamais et le carton titre reste vide pour toujours.
   C'est exactement le bug qu'on a eu, deux fois.

   Une animation, elle, part toute seule au chargement, et son état final EST
   l'état visible. Le pire cas devient « pas d'animation », plus jamais « pas
   de texte ».
   --------------------------------------------------------------------------- */
.plan-seuil [data-anim] {
  animation: seuil-apparait .8s cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: var(--d, 0s);
}

@keyframes seuil-apparait {
  from { opacity: 0; transform: translateY(18px); filter: blur(7px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* Les deux moitiés du titre s'écartent par une transition : leur animation
   d'entrée ne doit donc surtout pas toucher à transform, sinon elle
   continuerait de l'imposer une fois terminée (fill both) et le titre
   resterait planté au centre. */
.seuil-mot[data-anim] { animation-name: seuil-apparait-mot; }

@keyframes seuil-apparait-mot {
  from { opacity: 0; filter: blur(7px); }
  to   { opacity: 1; filter: none; }
}

/* ---------------------------------------------------------------------------
   L'INVITE DE FRANCHISSEMENT — rideau déjà ouvert (on revient du couloir).
   La vidéo est alors posée sur sa dernière image : il ne reste qu'un pas, et
   on ne rejoue pas les huit secondes.
   --------------------------------------------------------------------------- */
.seuil-franchir {
  position: absolute;
  left: 50%;
  bottom: clamp(1.6rem, 6vh, 3.4rem);
  transform: translateX(-50%) translateY(14px);
  z-index: 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .55rem;
  margin: 0;
  text-align: center;
  font-family: 'DM Mono', monospace;
  font-size: .66rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
  text-shadow: 0 2px 18px rgba(0, 0, 0, .95);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity .7s ease .15s,
    transform .7s cubic-bezier(.16, 1, .3, 1) .15s;
}

.plan-seuil.seuil-ouvert .seuil-franchir {
  opacity: 1;
  transform: translateX(-50%);
}

/* Rideau déjà ouvert : le carton titre ne revient pas, on l'a lu en arrivant. */
.plan-seuil.seuil-ouvert .seuil-titre { opacity: 0; }

/* ---------------------------------------------------------------------------
   Mouvement réduit : la vidéo ne se lance pas (js/seuil-lk.js s'en charge et
   entre directement), et plus rien ne clignote.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .seuil-fleche { animation: none; opacity: .6; }
  .seuil-video { transition: none; }
  /* Le briefing s'affiche d'un coup (js/seuil-lk.js) : pas de curseur qui
     clignote pour rien. */
  [data-machine].seuil-ecrit::after { display: none; }
  .plan-seuil [data-anim] {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }
  .seuil-mot { transition: none; }
  .plan-seuil,
  .seuil-franchir,
  .plan-seuil.seuil-sortie {
    transition-duration: .3s;
  }
}
