/* Réserve l'espace de scroll (100vh) que .studio-scene occupait avant de
   passer en position:fixed — sans ça .studio-panels-wrap démarrerait trop
   tôt et tout le minutage du scroll serait décalé. */
.studio-scene-spacer {
  height: 100vh;
}

.studio-scene {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  /* Sous les 6 panels (z-index 100-106 plus bas) — comportement d'origine :
     .studio-body (les 3 colonnes hero) a été sorti de .studio-scene (voir
     commentaire HTML) précisément pour pouvoir rester, LUI, au-dessus des
     panels (z-index 150, css/studio.css) sans faire monter la vidéo avec —
     un z-index posé ici serait hérité par TOUT .studio-scene, vidéo comprise,
     ce qu'on ne veut plus (cf. mémoire project_studio_hero_scene_stacking).
     50 : nettement sous les panels (100-106), nettement au-dessus du flux
     normal (0/auto) si jamais un futur enfant de .studio-scene en avait
     besoin. */
  z-index: 50;
}

.studio-video-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

/* Copié de .hero-scroll-hint (css/home.css) pour le hero vidéo de studio.html.
   opacity mise à 1 (au lieu de 0 comme sur home.css) : rien dans le CSS ou le
   JS du site ne fait jamais passer .hero-scroll-hint d'opacity 0 à 1, donc
   copier la valeur telle quelle la rendrait invisible en permanence ici aussi.
   position: fixed (au lieu de absolute) : élément déplacé dans le HTML pour
   vivre hors de .studio-scene (voir commentaire HTML) — .studio-scene
   couvrant exactement le viewport (top:0/left:0/100%/100vh), bottom/left
   donnent le même résultat visuel calculés depuis le viewport plutôt que
   depuis .studio-scene. */
.hero-scroll-hint {
  position: fixed;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9000;
  opacity: 0.2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.hero-scroll-hint .scroll-glyph {
  font-family: var(--mono);
  font-size: 1.2rem;
  color: var(--offwhite);
  opacity: 1;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85);
  animation: scrollBounce 2s ease-in-out infinite;
}

/* Rotation posée sur .hero-scroll-hint (pas .scroll-glyph) : .scroll-glyph a
   une animation qui pilote transform: translateY(...) en continu, et une
   animation CSS écrase entièrement la valeur "transform" statique d'une
   règle pendant qu'elle tourne — un transform: rotate() sur .scroll-glyph
   n'aurait donc jamais d'effet visible (vérifié). .hero-scroll-hint n'a
   qu'un transform statique (translateX(-50%) pour le centrage), donc y
   composer rotate(180deg) fonctionne sans conflit. */
.hero-scroll-hint.scroll-hint-reversed {
  transform: translateX(-50%) rotate(180deg);
}

@keyframes scrollBounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(6px); }
}

.desktop-only { display: block; }
.mobile-only  { display: none; }

.studio-video-wrap iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 177.78vh;
  min-width: 100%;
  height: 56.25vw;
  min-height: 100%;
  border: none;
  pointer-events: none;
}

/* Overlay hero (3 colonnes de texte) — sorti de .studio-scene (voir
   commentaire HTML) pour avoir son propre z-index indépendant de la vidéo.
   position: fixed (au lieu de absolute) + bottom/left/right calculés depuis
   le viewport plutôt que depuis .studio-scene comme containing block —
   .studio-scene couvrant exactement le viewport, le résultat visuel est
   identique à avant (même remarque que .hero-scroll-hint, css/studio.css). */
.studio-body {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* Au-dessus des 6 panels (100-106) : sans ça, #panel-1 commencerait à
     recouvrir ces colonnes dès qu'il entre dans le viewport en montant
     depuis le bas — bien avant que son propre reveal de texte démarre. Le
     ScrollTrigger dédié (js/animations.js, initStudioPanels()) fade ces
     colonnes vers opacity:0 juste avant que ce reveal démarre, donc dès que
     ce z-index élevé cesse d'être nécessaire visuellement, l'élément est
     déjà invisible — reste sous .site-footer (8998) / .studio-title-fixed
     (8999) / #pageTransition (9000). */
  z-index: 150;
  /* padding-bottom élargi (au lieu de 2rem) pour que le CTA ne passe pas
     sous .site-footer, qui est fixed/z-index:8998 sur cette page (voir
     .studio-panels-wrap + .site-footer plus bas) et couvre en permanence
     ~100px en bas du viewport, y compris pendant l'écran d'accueil. */
  padding: 2rem 2.5rem 7rem;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 3rem;
}

.studio-text {
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1.6;
  color: #777;
  font-weight: 300;
}

.studio-text strong { color: var(--offwhite); font-weight: 400; }
.studio-text a      { color: var(--red); }

.studio-services {
  border-left: 1px solid var(--border);
  padding-left: 3rem;
}

.studio-services h3 {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 1.5rem;
}

.studio-services ul { list-style: none; }

.studio-services ul li {
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(0.9rem, 1.5vw, 1.2rem);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: #777;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
  transition: color 0.2s;
}

.studio-services ul li:hover { color: var(--offwhite); }

.studio-services ul li:last-child { border-bottom: none; }

.studio-tools {
  border-left: 1px solid var(--border);
  padding-left: 3rem;
}

.studio-tools h3 {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 1.5rem;
}

.tools-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tool-tag {
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #777;
  border: 1px solid currentColor;
  padding: 0.3rem 0.7rem;
  transition: color 0.2s, border-color 0.2s;
}

.tool-tag:hover { color: var(--offwhite); border-color: #fff; }

@media (max-width: 768px) {
  /* Colonnes 2 (Services) et 3 (Generative Stack) masquées sur mobile —
     seule la colonne 1 (.studio-text) reste visible. .studio-body garde
     grid-template-columns: 1fr ci-dessus, donc la colonne 1 occupe déjà
     toute la largeur disponible une fois les deux autres retirées de la
     grille par display:none — aucun ajustement de largeur/centrage requis. */
  /* .studio-body reste ancré en bottom:0 (cf. règle de base plus haut) —
     c'est ce qui garantit que GET IN TOUCH reste visible même sur les plus
     petits écrans, donc pas question de passer en top-anchoring. Mais cet
     ancrage bottom fait que le vide sous le titre fixe (.studio-title-fixed,
     lui indépendant du viewport) grandit avec la hauteur d'écran : mesuré à
     ~15px sur iPhone SE (667px de haut) contre ~192px sur iPhone 14 (844px)
     et ~303px sur iPhone 14 Pro Max (932px) — une valeur de padding-bottom
     fixe ne peut donc pas combler l'écart sur toutes les tailles (soit elle
     ne change presque rien sur SE, soit elle laisse un grand vide sur Pro
     Max). padding-bottom scale donc avec 100vh via calc(), pour que le haut
     de .studio-body (donc le premier paragraphe visible) se rapproche du
     titre de façon à peu près constante (~20-30px) quel que soit l'iPhone.
     clamp() garde 6rem comme plancher (la valeur d'origine, qui assurait
     déjà la marge de sécurité pour le footer) : sur SE, calc() donne ~87px
     (sous les 96px d'origine), donc le plancher 6rem s'applique et rien ne
     change visuellement sur ce modèle, qui n'avait de toute façon presque
     pas de vide à combler. Constante 580px dérivée empiriquement (mesures
     Playwright sur SE/14/Pro Max, cf. session) — à réajuster si un test sur
     iPhone réel montre un écart notable. */
  .studio-body    { grid-template-columns: 1fr; gap: 2.5rem; padding-bottom: clamp(6rem, calc(100vh - 580px), 380px); }
  .studio-services {
    display: none;
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 2rem;
  }
  .studio-tools {
    display: none;
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 2rem;
  }

  /* .studio-text (colonne bio, seule colonne encore visible sur mobile,
     cf. commentaire ci-dessus) est structurée en p/br/p/br/p/br/p/br/div
     (espacement par <br> manuels, pas de margin CSS) — masquer les 2
     premiers <p> sans masquer aussi leurs <br> associés laisserait 2
     lignes vides orphelines en haut du bloc. :nth-of-type compte par tag,
     donc br:nth-of-type(1)/(2) ciblent bien les <br> qui suivaient
     immédiatement ces deux <p>. */
  .studio-text > p:nth-of-type(1),
  .studio-text > p:nth-of-type(2),
  .studio-text > br:nth-of-type(1),
  .studio-text > br:nth-of-type(2) {
    display: none;
  }

  .studio-video-wrap {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .studio-video-wrap iframe {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 177.78vh;
    min-width: 100%;
    height: 100%;
    min-height: 56.25vw;
  }

  .desktop-only { display: none; }
  .mobile-only  { display: block; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
}

.studio-cta {
  margin-top: 1rem;
}

.studio-cta a {
  font-family: var(--mono);
  font-size: 1rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--offwhite);
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  transition: gap 0.3s ease;
}

.studio-cta a:hover { gap: 1.2rem; }

.studio-cta a span { color: var(--red); }

/* .studio-panels-wrap est le dernier bloc avant le footer (le bloc 3
   colonnes .studio-body est maintenant en overlay à l'intérieur de
   .studio-scene, plus un élément séparé dans le flux) — le sélecteur
   adjacent doit cibler .studio-panels-wrap pour que le footer reste
   fixé/transparent en bas de la page. z-index 8998 : au-dessus des panels
   (101-106) pour que le footer reste visible pendant tout le scroll, mais
   sous #pageTransition (9000, voir transitions.css) pour que la transition
   de page recouvre bien le footer au changement de page. */
.studio-panels-wrap + .site-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 8998;
  background: transparent;
  border-top: none;
}

/* ── TITRE ÉPINGLÉ ──
   Padding aligné sur .page-header de boards.css (8rem 2.5rem 4rem) pour un
   positionnement identique au titre de boards.html — font-size/weight/
   letter-spacing/line-height ci-dessous correspondaient déjà à
   .page-header .studio-title. */
.studio-title-fixed {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 8999; /* sous le header/burger (9999) et sous #pageTransition (9000) — au-dessus des panels (101-106) */
  padding: 8rem 2.5rem 4rem;
  pointer-events: none;
}

.studio-title-fixed .title-solid,
.studio-title-fixed .title-outline {
  display: block;
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(3rem, 7vw, 7rem);
  letter-spacing: -0.04em;
  text-transform: uppercase;
  line-height: 0.9;
}

.studio-title-fixed .title-outline {
  -webkit-text-stroke: 1px var(--offwhite);
  color: transparent;
}

/* ── SCROLLYTELLING PANELS (studio-panels-wrap) ── */

/* Bande de dégradé UNIQUE (un seul nœud DOM, jamais déplacé) remplaçant les
   6 .story-overlay individuels qui vivaient auparavant dans chaque
   .studio-panel ET l'ancien dégradé propre au hero vidéo
   (.studio-video-wrap::after, supprimé). Reste strictement position:fixed,
   au niveau racine, en permanence — au-dessus des 6 panels (100-106) et de
   la vidéo hero (.studio-scene, 50), sous .studio-body (150) et
   .site-footer (8998) — visible dès le tout premier pixel de la page et
   jusqu'à la fin du scrollytelling, sans exception ni cas particulier par
   panel. height: 60vh + stops 0%/100% : la portion visuellement active de
   l'ancien gradient par-panel (inset:0 sur 100vh, stops 0%/60% — seule
   l'échelle change ici, la portion 60%-100% de l'ancien gradient était de
   toute façon transparente et sans effet visuel). */
.studio-panels-fade {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 60vh;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 100%);
  z-index: 120;
  pointer-events: none;
}

/* Donne la hauteur de scroll nécessaire aux panels position:fixed pour
   jouer leur animation à 2 phases (montée 100vh, puis zoom+texte 220vh) :
   6 panels × 320vh = 1920vh (recalculée/posée en JS via wrap.style.height
   dans js/animations.js — cette valeur n'est qu'un fallback avant
   l'exécution du script). */
.studio-panels-wrap {
  display: block;
  position: relative;
  height: 1920vh;
  margin: 0;
  padding: 0;
}

/* Chaque panel est fixe plein écran, positionné hors-écran en bas par
   défaut ; le JS l'anime en y via ScrollTrigger. */
.studio-panel {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  transform: translateY(100vh);
  transform-origin: center center;
  z-index: 100;
  overflow: hidden; /* clippe le zoom de .story-bg pour ne pas créer de vide */
  /* Aligne .story-content sans transform sur cet élément lui-même — évite
     de combiner transform + clip-path animé sur le même noeud. Aligné à
     gauche (flex-start) : .story-content garde son padding-left: 2.5rem
     existant, ce qui fait coïncider le texte avec .site-logo et
     .studio-title-fixed (padding-left: 2.5rem toutes les deux, cf.
     css/main.css et plus bas dans ce fichier).
     align-items: flex-start (pas center) : un centrage vertical dans les
     100vh du panel fait varier la position du texte selon sa longueur
     (donc selon le panel) — .story-content ancre plutôt le texte à une
     distance fixe du haut via son propre padding-top, cf. plus bas. */
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
}

/* z-index croissant : chaque panel recouvre le précédent en montant */
#panel-1 { z-index: 101; }
#panel-2 { z-index: 102; }
#panel-3 { z-index: 103; }
#panel-4 { z-index: 104; }
#panel-5 { z-index: 105; }
#panel-6 { z-index: 106; }

/* Panel 2 : image dédiée desktop (studio_scrolly_02_b.jpg). Déplacée de
   l'inline style (utilisé par les 5 autres panels) vers une règle CSS
   propre à ce panel, pour pouvoir la resplitter en mobile ci-dessous sans
   !important — l'inline style aurait sinon priorité sur la media query. */
#panel-2 .story-bg {
  /* url() relatif à ce fichier CSS (css/), pas au HTML — ../ requis pour
     remonter à la racine du site où vit le dossier images/. */
  background-image: url('../images/studio/studio_scrolly_02_b.jpg');
}

@media (max-width: 768px) {
  /* Mobile garde l'image d'origine (studio_scrolly_02.jpg), non demandée
     ici — seul le desktop passe sur la variante _b. */
  #panel-2 .story-bg {
    background-image: url('../images/studio/studio_scrolly_02.jpg');
  }
}

/* RGB split hover (panel 1) — calque clone localisé au curseur.
   Un filtre SVG n'a pas de notion de position : le falloff radial vient du
   mask-image (cercle autour de --glitch-x/--glitch-y), pas du filtre lui-
   même. Le clone est nourri en JS (js/animations.js), rafraîchi à chaque
   mouseenter pour rester synchro avec le zoom/texte animés de #panel-1.
   Positionné en absolute imbriqué DANS #panel-1 (pas en sibling) : hérite
   ainsi de son overflow:hidden et de son z-index sans calcul de position
   séparé — #panel-1 étant fixed + transformé par GSAP, il constitue déjà
   le containing block correct pour ce calque. */
.panel-1-glitch-layer {
  position: absolute;
  inset: 0;
  z-index: 3; /* au-dessus de .story-content (z-index: 2) */
  pointer-events: none;
  /* Le clone de .story-content est positionné par le flex de SON parent,
     pas par sa propre position — sans ce display:flex ici (identique à
     .studio-panel), le clone retombe en display:block et son texte ne
     coïncide plus avec l'original. Doit rester synchronisé avec les
     valeurs align-items/justify-content de .studio-panel ci-dessus. */
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  filter: url(#rgb-split-panel-1);
  -webkit-mask-image: radial-gradient(
    circle var(--glitch-radius, 180px) at var(--glitch-x, 50%) var(--glitch-y, 50%),
    black 0%,
    black 40%,
    transparent 100%
  );
  mask-image: radial-gradient(
    circle var(--glitch-radius, 180px) at var(--glitch-x, 50%) var(--glitch-y, 50%),
    black 0%,
    black 40%,
    transparent 100%
  );
  opacity: 0;
  transition: opacity 0.2s ease;
}

.panel-1-glitch-layer.active {
  opacity: 1;
}

/* Image de fond plein écran */
.story-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  transform-origin: center center;
  will-change: transform;
  z-index: 0;
}

/* Positionné par le flex de .studio-panel (justify-content: flex-start) —
   pas de position: absolute + top/left/transform ici, pour rester
   compatible avec l'animation de clip-path (transform + clip-path animés
   sur le même élément peut créer des artefacts de rendu sur certains
   navigateurs). padding-left: 2.5rem aligne le texte sur .site-logo /
   .studio-title-fixed, qui utilisent le même padding-left. */
.story-content {
  position: relative;
  z-index: 2;
  width: 800px;
  max-width: 90vw;
  /* padding-top ancre le texte à une distance fixe du bas du titre épinglé
     (.studio-title-fixed : padding-top 8rem + 2 lignes ~ jusqu'à 353px de
     haut à 1280px de large), identique sur les 6 panels — au lieu d'un
     align-items: center qui faisait varier la position selon la longueur
     du texte de chaque panel. */
  padding: 24rem 2.5rem 4rem;
  text-align: left;
}

/* Sur mobile, .studio-title-fixed garde son padding-top d'origine (8rem,
   cf. règle de base plus haut) — c'est le texte du panel qui remonte vers
   le titre plutôt que l'inverse, en réduisant le padding-top de
   .story-content (partagé par les 6 panels, donc l'ajustement s'applique
   uniformément). La phase 2 de chaque panel (js/animations.js,
   initStudioPanels) fait dériver .story-content de y:0 à y:-25px pendant
   tout le dwell (zoom continu) — 16rem laisse un gap d'environ [X] avec le
   titre sur toute la durée du dwell, vérifié aux deux bornes (début/fin de
   phase 2) sur SE/14/Pro Max. */
@media (max-width: 768px) {
  .story-content {
    padding-top: 16rem;
  }
}

/* Etat initial du bouton BACK : invisible tant que le reveal du texte
   (js/animations.js, timeline `tl` du panel) n'a pas atteint son dernier
   tween — évite un flash du bouton dès l'arrivée du panel. Scopé à
   .story-content pour ne pas toucher le .studio-cta du bloc hero 3
   colonnes (GET IN TOUCH), qui doit rester visible immédiatement. */
.story-content .studio-cta {
  opacity: 0;
}

/* BACK sans le décalage latéral au hover : le gap 1.2rem de
   .studio-cta a:hover (pensé pour l'espacement texte/flèche de GET IN
   TOUCH) est neutralisé ici, seuls la couleur et le letter-roll (déjà
   gérés par initLetterRoll dans js/nav.js) restent actifs au survol.
   font-size répété ici (même valeur que .studio-cta a, 1rem) pour
   documenter explicitement que BACK et GET IN TOUCH sont alignés. */
.story-content .studio-cta a {
  font-size: 1rem;
}

.story-content .studio-cta a:hover {
  gap: 0.75rem;
}

.story-text {
  font-family: var(--sans);
  font-size: clamp(1.2rem, 2.5vw, 2rem);
  font-weight: 300;
  color: var(--offwhite);
  line-height: 1.5;
  letter-spacing: -0.01em;
}

.story-text--large {
  font-size: clamp(1.8rem, 4vw, 3.5rem);
  font-weight: 700;
  letter-spacing: -0.03em;
}
