/* Bioboros · portada.
   Solo lo que es del héroe con recorrido y no se repite en ninguna otra
   página. Todo lo compartido (tokens, fuentes, barra, botones, secciones,
   pie y movimiento reducido) vive en site.css y se carga antes que esto. */

/* Los DOS tokens propios del recorrido. Viven aquí y no en site.css porque
   ninguna otra página los usa.

   `--hero-vh` es load-bearing y no cosmético: `.hero` calcula su altura con él,
   y sin definirlo el `calc()` queda inválido, la región del héroe colapsa a la
   altura de su contenido y el recorrido se queda SIN DISTANCIA DE SCROLL. El
   síntoma es silencioso y feo: el vídeo carga, las bandas se ven, y el tiempo se
   queda clavado en 0 pase lo que pase. Se perdió una vez al separar las hojas y
   lo cazó la auditoría del navegador, no la vista. */
:root{
  --hero-vh:440;
  --tshadow:0 1px 2px rgba(5,5,10,.95),0 3px 12px rgba(5,5,10,.78),0 10px 44px rgba(5,5,10,.8);
}

/* ══ 4. HÉROE: región fijada + escenario pegajoso ══════════════════════ */
.hero{position:relative;height:calc(var(--hero-vh) * 1vh)}
.stage{position:sticky;top:0;height:100vh;overflow:hidden;background:#0A0D18}

.poster{position:absolute;inset:0;background-size:cover;background-position:center;transition:opacity .8s var(--ease)}
#hero{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .9s var(--ease);will-change:transform;transform:translateZ(0);
}
.stage.video-ready #hero{opacity:1}
.stage.video-ready .poster{opacity:0}
.stage.video-failed #hero{display:none}

/* scrim base global: ningún cuadro queda crudo detrás de la página */
.scrim{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 50% 45%,rgba(10,10,18,0) 35%,rgba(10,10,18,.62) 100%)}

/* anillo de carga */
.ring{position:absolute;left:50%;bottom:2.4rem;transform:translateX(-50%);width:44px;height:44px;color:var(--text-secondary);opacity:.85}
.ring circle{transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .12s linear}
.chev{position:absolute;left:50%;bottom:2.4rem;transform:translateX(-50%);color:var(--text-secondary);animation:chev 2.6s var(--ease) infinite}
@keyframes chev{0%,100%{transform:translate(-50%,0);opacity:.45}50%{transform:translate(-50%,7px);opacity:.9}}

/* ══ 5. BANDAS DE TEXTO SOBRE EL PLANO ═════════════════════════════════ */
.bands{position:absolute;inset:0;pointer-events:none}
.band{
  position:absolute;top:0;bottom:0;left:0;
  /* Medido: a 46ch el titular llegaba a la franja de luz del túnel y, en el
     asentamiento, encima del plato blanco. La calle de la acción vive en el
     centro; el texto se queda en el tercio tranquilo. */
  width:min(38ch,36vw);
  padding-left:var(--gut);padding-right:1rem;
  display:flex;flex-direction:column;justify-content:center;
  opacity:0;text-shadow:var(--tshadow);
  isolation:isolate;   /* obliga a un contexto de apilamiento SIEMPRE: sin esto, a
                          opacidad 1 la banda no crea contexto y su scrim (z-index:-1)
                          cae detrás del vídeo. Medido: 1,16 : 1 de contraste. */
}
/* Scrim por banda. Lineal anclado a la izquierda y no radial centrado: todo el
   texto vive en la columna izquierda, así que la penumbra tiene que ser una
   pared, no una elipse. Muere al 82 % para que el centro del plano siga vivo. */
/* La caja del scrim se estira MUCHO a la derecha para que la caída del degradado
   ocurra fuera del texto. Antes moría al 86 % de una caja que apenas rebasaba la
   columna, así que el borde derecho del titular recibía 0,07 de alfa sobre una
   pared clara: 1,30 : 1 medido. Alfa baja y sostenida en vez de alta y corta,
   que es lo que atenúa sin aplastar. */
.band::before{
  content:"";position:absolute;inset:-8% -55% -8% -34%;pointer-events:none;z-index:-1;
  opacity:calc(.25 + .75*var(--k,1));
  background:linear-gradient(to right,
    rgba(5,5,10,.60) 0%,rgba(5,5,10,.58) 62%,rgba(5,5,10,.54) 72%,
    rgba(5,5,10,.30) 86%,rgba(5,5,10,0) 100%);
}
.band .kicker{font-family:var(--mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--text-secondary);margin:0 0 1rem}
.band h2,.band .h{
  font-family:var(--display);font-weight:800;letter-spacing:-.03em;line-height:.98;
  font-size:clamp(2.3rem,5.6vw,4.4rem);margin:0;text-wrap:balance;
}
.band p{margin:1.1rem 0 0;max-width:30ch;color:var(--text-primary);font-size:clamp(1rem,.9rem + .35vw,1.18rem)}

/* palabras y caracteres partidos */
.w{display:inline-block;white-space:pre}
.c{display:inline-block;will-change:transform,opacity}

/* (a) caída: las palabras bajan a su sitio */
.e-drift .w{--kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * -26px))}
/* (b) alineación en retícula: los caracteres entran en orden de lectura */
.e-grid .c{--kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc)) * var(--jx,0px)))}
/* (e) subida palabra por palabra, asentamiento en tres tiempos */
.e-rise .w{--kc:clamp(0,(var(--k,0) - var(--th,0))*2.7,1);opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 30px))}
.b3 .sub{--ks:clamp(0,(var(--k,0) - .60)*4,1);opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 14px))}
.b3 .row{--kb:clamp(0,(var(--k,0) - .74)*5,1);opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb)) * 14px))}

.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ══ 7. HÉROE ESTÁTICO (teléfonos, tabletas verticales, movimiento reducido) ══
   Maquetación DISEÑADA, no un recorte de emergencia. Un `cover` de una imagen
   16:9 sobre 375×812 enseña el 26 % del ancho y deja el titular encima del
   arroz. Aquí la imagen ocupa la mitad de arriba y se funde al lienzo; el texto
   vive sobre el lienzo, donde el contraste no depende de la foto. */
.static-hero{display:none;position:relative;min-height:100svh;background:var(--canvas)}
.static-media{position:relative;height:44svh;min-height:280px;
  background:#0A0D18 center 62%/cover no-repeat}
.static-media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom,rgba(14,18,32,.62) 0%,rgba(14,18,32,.12) 34%,
    rgba(14,18,32,.72) 78%,var(--canvas) 100%)}
.static-inner{padding:2rem var(--gut) 3.4rem}
.static-kick{font-family:var(--mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-secondary);margin:0 0 1rem}
.static-inner h1{font-family:var(--display);font-weight:800;letter-spacing:-.03em;line-height:1.02;
  font-size:clamp(2.15rem,8.2vw,3.4rem);margin:0;text-wrap:balance}
.static-inner p{margin:1.1rem 0 0;max-width:38ch;color:var(--text-secondary)}

@media (max-width:720px),
       (orientation:portrait) and (max-width:1024px),
       (orientation:portrait) and (pointer:coarse),
       (orientation:landscape) and (pointer:coarse) and (max-height:560px),
       (prefers-reduced-motion:reduce){
  .hero{display:none}
  .static-hero{display:block}
}
@media (max-height:560px){.ring,.chev{display:none}}

/* ══ El momento interactivo: acota el plato ══ */
.acota{margin-top:3rem;background:var(--panel);border:1px solid var(--line);border-radius:20px;padding:clamp(1.4rem,3vw,2.4rem)}
.macros{display:grid;gap:1rem;margin:0 0 1.8rem}
.macro{display:grid;grid-template-columns:9ch 1fr 7ch;gap:1rem;align-items:center}
.macro .lbl{font-family:var(--mono);font-size:.76rem;letter-spacing:.06em;color:var(--text-secondary)}
.macro .track{position:relative;height:8px;border-radius:99px;background:rgba(155,163,190,.14);overflow:hidden}
.macro .band-ok{position:absolute;top:0;bottom:0;left:78%;right:6%;background:var(--accent-muted)}
.macro .fill{position:absolute;top:0;bottom:0;left:0;width:calc(var(--p,0) * 88%);background:var(--accent);border-radius:99px}
.macro .val{font-family:var(--mono);font-size:.86rem;text-align:right;font-variant-numeric:tabular-nums}
.hold{
  font-family:var(--body);font-weight:500;font-size:1rem;cursor:pointer;user-select:none;
  touch-action:none;   /* así el gesto de sostener no necesita preventDefault en JS */
  padding:.85rem 1.5rem;border-radius:999px;border:1px solid var(--line-strong);
  background:transparent;color:var(--text-primary);position:relative;overflow:hidden;
  transition:border-color .22s var(--ease)}
.hold::before{content:"";position:absolute;inset:0;background:var(--accent);
  transform:scaleX(var(--p,0));transform-origin:left;opacity:.30}
.hold span{position:relative}
.hold:hover{border-color:var(--accent-hover)}
.acota .after{margin-top:1.6rem;opacity:0;transform:translateY(12px);
  transition:opacity .6s var(--ease-out),transform .6s var(--ease-out)}
.acota.done .after{opacity:1;transform:none}
@media (pointer:coarse){.hold{min-height:44px}}
