:root{
/* ---- Base del sistema (sin cambios) ---- */
--ease-standard:cubic-bezier(.4,0,.2,1); /* @kind other */
--ease-out-soft:cubic-bezier(.16,1,.3,1); /* @kind other */
--ease-organic:cubic-bezier(.34,1.26,.64,1); /* @kind other */ /* overshoot suave — el easing "orgánico" */
--dur-instant:100ms; /* @kind other */
--dur-fast:160ms; /* @kind other */
--dur-base:240ms; /* @kind other */
--dur-slow:400ms; /* @kind other */
--dur-scenic:800ms; /* @kind other */
--float-duration:9s; /* @kind other */

/* ---- Sistema de escenas ---- */
--ease-scene:cubic-bezier(.22,1,.36,1); /* @kind other */ /* entradas largas */
--dur-reveal:700ms; /* @kind other */
--dur-line:900ms; /* @kind other */
--stagger:70ms; /* @kind other */
--travel-sm:12px;
--travel-md:24px;
--travel-lg:56px;
--reveal-blur:8px;
--magnet-radius:40px;
--magnet-pull:6px;
}

@keyframes he-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
@keyframes he-bloom{0%,100%{opacity:.75;transform:scale(1)}50%{opacity:1;transform:scale(1.08)}}
@keyframes he-spin{to{transform:rotate(360deg)}}
@keyframes he-sparkle{0%,100%{opacity:.5;transform:scale(.85) rotate(0deg)}50%{opacity:1;transform:scale(1) rotate(12deg)}}
@keyframes he-marquee{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}

/* ================================================================
   ESCENA — sección de varios viewports con un panel fijo dentro.
   El scroll a través de la escena se expone como --p (0 → 1).
   Todo lo de adentro anima leyendo esa variable: un solo rAF para
   toda la página, cero JS por elemento.
   ================================================================ */
/* El recorte va en la escena, no en el pin: los blooms son absolutos y
   su bloque contenedor es la escena, así que un overflow en el pin no
   los alcanza cuando éste deja de ser sticky (móvil / reduced-motion).
   overflow:clip no crea un contenedor de scroll, así que sticky sigue
   funcionando. */
.he-scene{position:relative;overflow:clip}
.he-scene[data-screens="2"]{height:200vh}
.he-scene[data-screens="3"]{height:300vh}
.he-scene[data-screens="4"]{height:400vh}
.he-scene[data-screens="6"]{height:600vh}

.he-scene__pin{
  position:sticky; top:0;
  min-height:100vh;
  display:grid; place-items:center;
  overflow:clip;
}

/* Utilidades que leen --p */
.he-p-fade  {opacity:calc(var(--p,0) * 3)}
.he-p-rise  {transform:translateY(calc((1 - var(--p,0)) * var(--travel-lg)));opacity:calc(var(--p,0) * 2)}
.he-p-scale {transform:scale(calc(.92 + var(--p,0) * .08))}
.he-p-slide {transform:translate3d(calc(var(--p,0) * -60%),0,0)}

/* ================================================================
   REVELADO DE ENTRADA — para lo que no es escena.
   ================================================================ */
[data-reveal]{
  opacity:0;
  transform:translateY(var(--travel-md));
  filter:blur(var(--reveal-blur));
  transition:
    opacity   var(--dur-reveal) var(--ease-scene),
    transform var(--dur-reveal) var(--ease-scene),
    filter    var(--dur-reveal) var(--ease-scene);
  transition-delay:calc(var(--i,0) * var(--stagger));
}
[data-reveal].is-in{opacity:1;transform:none;filter:none}

/* ================================================================
   TEXTO — tres primitivas. Una sola por bloque, nunca dos juntas.
   ================================================================ */

/* A · Revelado por líneas: cada línea sube desde debajo de una
   máscara. Es el titular premium por defecto. */
.he-lines > span{display:block;overflow:hidden}
.he-lines > span > i{
  display:block;font-style:inherit;
  transform:translateY(110%);
  transition:transform var(--dur-line) var(--ease-scene);
  transition-delay:calc(var(--i,0) * 90ms);
}
.he-lines.is-in > span > i{transform:translateY(0)}

/* B · Revelado por palabras: para bajadas y párrafos cortos.
   El partidor de scene.js escribe --n y --i. */
.he-w{display:inline-block;overflow:hidden;vertical-align:bottom}
.he-w > i{
  display:inline-block;font-style:inherit;
  transform:translateY(105%);
  transition:transform 620ms var(--ease-scene);
  transition-delay:calc(var(--i,0) * 28ms);
}
.is-in .he-w > i,.he-w.is-in > i{transform:translateY(0)}

/* C · Texto que se enciende con el scroll. Dentro de una escena,
   las palabras se iluminan una a una a medida que avanzás.
   --n lo escribe el partidor, --p la escena. */
.he-scrub{color:color-mix(in srgb, var(--text-body) 20%, transparent)}
.he-scrub .he-w{overflow:visible}
.he-scrub .he-w > i{
  transform:none;
  color:var(--text-strong);
  opacity:clamp(0, calc(var(--p,0) * var(--n,1) * 1.25 - var(--i,0)), 1);
  transition:none;
}

/* ================================================================
   IMAGEN
   ================================================================ */

/* Revelado con máscara + contra-escala: se descubre de abajo hacia
   arriba mientras se desescala. Lee como cine. */
.he-img-reveal{overflow:hidden;clip-path:inset(0 0 100% 0);transition:clip-path 1000ms var(--ease-scene)}
.he-img-reveal.is-in{clip-path:inset(0 0 0 0)}
.he-img-reveal > img{display:block;transform:scale(1.18);transition:transform 1400ms var(--ease-scene)}
.he-img-reveal.is-in > img{transform:scale(1)}

/* Parallax dentro de una escena. --k = intensidad. */
.he-img-parallax{transform:translate3d(0, calc((var(--p,.5) - .5) * var(--k, 80px) * -1), 0)}

/* Zoom-out ligado al scroll de la escena. */
.he-img-zoom{transform:scale(calc(1.16 - var(--p,0) * .16))}

/* ================================================================
   MARQUESINA — velocidad constante, contenido clonado.
   ================================================================ */
.he-marquee{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.he-marquee__track{display:flex;width:max-content;animation:he-marquee var(--marquee-dur,44s) linear infinite}
.he-marquee:hover .he-marquee__track{animation-play-state:paused}

/* ================================================================
   DEGRADACIONES — no son opcionales.
   ================================================================ */

/* Móvil: nada se fija. Todo se apila y queda [data-reveal]. */
@media (max-width: 767px){
  .he-scene{height:auto !important}
  .he-scene__pin{position:static;min-height:0}
  .he-p-slide,.he-p-scale,.he-img-parallax,.he-img-zoom{transform:none}
  .he-p-fade,.he-p-rise{opacity:1}
  .he-scrub{color:var(--text-strong)}
  .he-scrub .he-w > i{opacity:1}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .he-scene{height:auto !important}
  .he-scene__pin{position:static;min-height:0}
  [data-reveal]{opacity:1;transform:none;filter:none}
  .he-lines > span > i,.he-w > i{transform:none}
  .he-img-reveal{clip-path:none}
  .he-img-reveal > img{transform:none}
  .he-p-slide,.he-p-scale,.he-img-parallax,.he-img-zoom{transform:none}
  .he-p-fade,.he-p-rise{opacity:1}
  .he-scrub{color:var(--text-strong)}
  .he-scrub .he-w > i{opacity:1}
  .he-marquee__track{animation:none}
}
