/* =========================================================
   BLAK MARKETING AGENCY — CAPA DE MOVIMIENTO
   ---------------------------------------------------------
   Todo lo que se mueve vive aquí, separado de styles.css
   para que la hoja base siga siendo legible.

   Lenguaje visual: sala de edición. Cinta de 35 mm, carretes
   girando, iris de lente, grano de película, fuga de luz y
   un visor que sigue al cursor.

   Reglas que se respetan siempre:
     · Sólo se animan transform y opacity (no reflow).
     · Nada de esto es información: todo va aria-hidden.
     · prefers-reduced-motion apaga el bloque entero al final.
     · Sin dependencias y sin estilos en línea (CSP estricta).
   ========================================================= */

:root{
  --film:      #141414;                 /* negro de la emulsión */
  --perf:      rgba(249,241,232,.62);   /* perforaciones */
  --glow-lt:   rgba(141,182,197,.5);
}

/* =========================================================
   1 · GRANO DE PELÍCULA
   Ruido fractal en un SVG data: URI, desplazándose a saltos.
   Cubre todo el sitio a muy baja opacidad: no se ve, se siente.
   ========================================================= */
.grain{
  position:fixed;inset:-6%;z-index:400;pointer-events:none;
  contain:strict;
  /* Sin mix-blend-mode a propósito: mezclar una capa fija del tamaño
     de la pantalla obliga al navegador a recomponer todo el documento
     en cada cuadro y tumba el rendimiento. Con opacidad baja se ve igual. */
  opacity:.055;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain .8s steps(1) infinite;
}
@keyframes grain{
  0%  {transform:translate3d(0,0,0)}
  10% {transform:translate3d(-2%,-3%,0)}
  20% {transform:translate3d(-4%,2%,0)}
  30% {transform:translate3d(2%,-4%,0)}
  40% {transform:translate3d(-1%,3%,0)}
  50% {transform:translate3d(-3%,1%,0)}
  60% {transform:translate3d(3%,0,0)}
  70% {transform:translate3d(0,2%,0)}
  80% {transform:translate3d(-2%,-1%,0)}
  90% {transform:translate3d(2%,3%,0)}
  100%{transform:translate3d(0,0,0)}
}

/* =========================================================
   2 · CINTA DE 35 mm  (pieza reutilizable)
   Un cuerpo oscuro, dos filas de perforaciones que corren y
   una fila de fotogramas apenas insinuados.
   ========================================================= */
.fstrip{
  position:relative;overflow:hidden;
  background:linear-gradient(180deg,#1b1b1b,var(--film) 50%,#101010);
  border-block:1px solid rgba(249,241,232,.14);
}
.fstrip__perf,
.fstrip__frames{position:absolute;left:-40px;width:calc(100% + 80px);pointer-events:none}

.fstrip__perf{
  height:8px;border-radius:2px;
  background:repeating-linear-gradient(90deg,
    var(--perf) 0 11px, transparent 11px 30px);
  animation:perf-run 1.1s linear infinite;
}
.fstrip__perf--t{top:6px}
.fstrip__perf--b{bottom:6px}
@keyframes perf-run{to{transform:translate3d(-30px,0,0)}}

/* Los fotogramas: rectángulos tenues, más lentos que las perforaciones. */
.fstrip__frames{
  top:20px;bottom:20px;
  background:repeating-linear-gradient(90deg,
    rgba(249,241,232,.055) 0 78px,
    rgba(249,241,232,.02)  78px 82px,
    transparent            82px 86px);
  animation:perf-run 3.9s linear infinite;
}

/* =========================================================
   3 · ESCENA DE ESTUDIO EN EL HERO
   Capa de fondo, detrás del texto. Todo decorativo.
   ========================================================= */
.studio{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0;contain:paint}
.hero__inner,.pagehead .wrap{position:relative;z-index:2}

/* --- cintas cruzando la pantalla en diagonal --- */
.studio__strip{
  position:absolute;left:-30%;width:160%;height:64px;
  opacity:.5;border-radius:3px;
  box-shadow:0 30px 60px -30px rgba(0,0,0,.9);
}
.studio__strip--a{top:13%;opacity:.34;transform:rotate(-9deg);animation:strip-drift-a 16s ease-in-out infinite}
.studio__strip--b{bottom:6%;opacity:.2;transform:rotate(6deg);animation:strip-drift-b 21s ease-in-out infinite}

/* Velo: el texto siempre gana. La escena queda viva a la derecha
   y se apaga sobre la columna donde vive el titular. */
.studio::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(101deg,
    rgba(32,32,32,.94) 0%,
    rgba(32,32,32,.86) 34%,
    rgba(32,32,32,.42) 62%,
    rgba(32,32,32,.06) 84%,
    transparent 100%);
}
@keyframes strip-drift-a{
  0%,100%{transform:rotate(-9deg) translate3d(0,0,0)}
  50%    {transform:rotate(-7.4deg) translate3d(0,-16px,0)}
}
@keyframes strip-drift-b{
  0%,100%{transform:rotate(6deg) translate3d(0,0,0)}
  50%    {transform:rotate(4.6deg) translate3d(0,14px,0)}
}

/* --- carretes --- */
.reel{position:absolute;pointer-events:none;overflow:visible;z-index:1}
.reel--l{width:clamp(180px,26vw,330px);top:6%;right:-4%;opacity:.55}
.reel--r{width:clamp(120px,17vw,200px);bottom:-7%;left:-6%;opacity:.2}

.reel__spin{transform-origin:60px 60px;animation:spin 14s linear infinite}
.reel--r .reel__spin{animation-duration:9s;animation-direction:reverse}

.reel__ring,.reel__hub,.reel__holes circle,.reel__tape{
  fill:none;stroke:var(--army-lt);vector-effect:non-scaling-stroke;
}
.reel__ring{stroke-width:2}
.reel__tape{stroke-width:9;stroke-opacity:.24}
.reel__hub{stroke-width:2.5}
.reel__holes circle{stroke-width:1.6;stroke-opacity:.75}
.reel__spokes path{fill:none;stroke:var(--army-lt);stroke-width:1;stroke-opacity:.28;vector-effect:non-scaling-stroke}

/* Aquí vivía un "latido" del aro que animaba stroke-opacity. Se quitó:
   stroke-opacity es propiedad de pintado, así que obligaba a redibujar
   el SVG completo en cada cuadro, y hay carretes en todas las páginas.
   El giro ya da toda la vida que hacía falta. */
@keyframes spin{to{transform:rotate(360deg)}}

/* --- lente con iris que respira --- */
.lens{
  position:absolute;z-index:1;width:clamp(150px,19vw,250px);
  right:11%;bottom:4%;opacity:.24;pointer-events:none;
}
.lens__barrel{fill:none;stroke:var(--army-lt);stroke-width:1.6;vector-effect:non-scaling-stroke}
.lens__iris{
  fill:none;stroke:var(--army-lt);stroke-width:2;vector-effect:non-scaling-stroke;
  transform-origin:60px 60px;
  animation:iris 7.5s cubic-bezier(.6,0,.25,1) infinite;
}
.lens__blade{fill:none;stroke:var(--army-lt);stroke-width:1;stroke-opacity:.45;vector-effect:non-scaling-stroke}
.lens__blades{transform-origin:60px 60px;animation:blades 7.5s cubic-bezier(.6,0,.25,1) infinite}
@keyframes iris{
  0%,100%{transform:scale(1) rotate(0deg);stroke-opacity:.95}
  45%,55%{transform:scale(.42) rotate(34deg);stroke-opacity:.55}
}
@keyframes blades{
  0%,100%{transform:rotate(0deg)}
  45%,55%{transform:rotate(34deg)}
}

/* --- fuga de luz: un barrido cálido cada pocos segundos --- */
.leak{
  position:absolute;top:-40%;left:-45%;width:55%;height:190%;
  transform:rotate(14deg);
  /* El difuminado sale del propio degradado: un filter:blur() sobre
     una superficie de este tamaño se rasteriza en cada cuadro. */
  background:linear-gradient(90deg,
    transparent 0%,
    rgba(141,182,197,.05) 20%,
    rgba(141,182,197,.11) 36%,
    rgba(249,241,232,.15) 50%,
    rgba(141,182,197,.11) 64%,
    rgba(141,182,197,.05) 80%,
    transparent 100%);
  animation:leak 11s ease-in-out infinite;
}
@keyframes leak{
  0%,72%,100%{transform:rotate(14deg) translate3d(0,0,0);opacity:0}
  76%        {opacity:.95}
  99%        {transform:rotate(14deg) translate3d(230%,0,0);opacity:0}
}

/* --- línea de tracking, como cinta de video --- */
.scan{
  position:absolute;left:0;right:0;height:130px;top:-140px;
  background:linear-gradient(180deg,
    transparent,
    rgba(249,241,232,.045) 46%,
    rgba(249,241,232,.10) 50%,
    rgba(249,241,232,.045) 54%,
    transparent);
  animation:scan 8.5s linear infinite;
}
@keyframes scan{
  0%  {transform:translate3d(0,0,0);opacity:0}
  6%  {opacity:1}
  94% {opacity:1}
  100%{transform:translate3d(0,140vh,0);opacity:0}
}

/* --- rejilla de encuadre (regla de tercios), muy tenue --- */
.thirds{
  position:absolute;inset:0;opacity:0;
  background:
    linear-gradient(90deg,transparent 33.2%,rgba(249,241,232,.16) 33.2% 33.35%,transparent 33.35%),
    linear-gradient(90deg,transparent 66.5%,rgba(249,241,232,.16) 66.5% 66.65%,transparent 66.65%),
    linear-gradient(180deg,transparent 33.2%,rgba(249,241,232,.16) 33.2% 33.35%,transparent 33.35%),
    linear-gradient(180deg,transparent 66.5%,rgba(249,241,232,.16) 66.5% 66.65%,transparent 66.65%);
  animation:thirds 13s ease-in-out infinite;
}
@keyframes thirds{
  0%,60%,100%{opacity:0}
  68%,88%    {opacity:.55}
}

/* Versión ligera para las páginas interiores: menos capas, menos ruido. */
.pagehead .studio__strip--a{top:22%;opacity:.34}
.pagehead .reel--l{width:clamp(140px,19vw,230px);top:2%;opacity:.34}
.pagehead .lens{display:none}

/* =========================================================
   4 · INDICADOR "REC" + TIMECODE
   ========================================================= */
.rec{
  display:inline-flex;align-items:center;gap:9px;
  font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--army-lt);
  border:1px solid rgba(141,182,197,.34);border-radius:999px;
  padding:7px 14px 7px 11px;margin-bottom:22px;
  background:rgba(32,32,32,.62);
}
.rec__dot{
  width:8px;height:8px;border-radius:50%;flex:none;background:#E4483C;
  box-shadow:0 0 0 0 rgba(228,72,60,.7);
  animation:rec-blink 1.6s ease-out infinite;
}
/* Parpadeo limpio, sin halo: es el que usan los puntos azules.
   El halo rojo queda reservado para el testigo de grabación. */
@keyframes dot-blink{
  0%,100%{opacity:1}
  55%    {opacity:.2}
}
@keyframes rec-blink{
  0%  {opacity:1;box-shadow:0 0 0 0 rgba(228,72,60,.65)}
  70% {opacity:.35;box-shadow:0 0 0 9px rgba(228,72,60,0)}
  100%{opacity:1;box-shadow:0 0 0 0 rgba(228,72,60,0)}
}
.rec__tc{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  letter-spacing:.06em;font-weight:400;
  color:rgba(249,241,232,.72);
  padding-left:9px;border-left:1px solid rgba(249,241,232,.18);
  font-variant-numeric:tabular-nums;
}

/* =========================================================
   5 · TÍTULO CON TIRO DE FOCO
   Cada palabra entra desenfocada y "enfoca" — como un
   focus pull de lente.
   ========================================================= */
.pull{display:inline-block;overflow:hidden;vertical-align:bottom}
.pull__w{
  display:inline-block;
  opacity:0;filter:blur(8px);
  transform:translate3d(0,.5em,0) scale(1.05);
  animation:pull-focus .95s cubic-bezier(.2,.7,.25,1) forwards;
}
@keyframes pull-focus{
  to{opacity:1;filter:blur(0);transform:translate3d(0,0,0) scale(1)}
}
/* El escalonado lo reparte motion.js con --d (CSSOM, no atributo style:
   la CSP estricta sigue contenta). Estos spans sólo existen si el JS corrió,
   así que no hace falta un respaldo en CSS. */
.pull__w{animation-delay:var(--d,.2s)}

/* =========================================================
   6 · BARRA DE PROGRESO PERFORADA
   La película que ya corrió. --p la escribe motion.js.
   ========================================================= */
.progress{
  position:fixed;top:0;left:0;right:0;height:4px;z-index:500;
  pointer-events:none;background:rgba(32,32,32,.16);
}
.progress__bar{
  height:100%;width:100%;
  transform:scaleX(var(--p,0));transform-origin:0 50%;
  background:
    repeating-linear-gradient(90deg,
      rgba(32,32,32,.45) 0 4px, transparent 4px 12px),
    linear-gradient(90deg,var(--army),var(--army-lt));
}

/* =========================================================
   8 · CORTINILLA DE ENTRADA (iris de obturador)
   Sólo CSS: si el JS falla, igual se abre.
   ========================================================= */
.intro{
  position:fixed;inset:0;z-index:900;pointer-events:none;
  background:var(--aurora);
  animation:intro-out 1.05s cubic-bezier(.7,0,.2,1) forwards;
}
.intro__iris{
  position:absolute;top:50%;left:50%;width:min(46vw,420px);aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.2);
  border:1.5px solid var(--army-lt);
  clip-path:polygon(50% 0,93% 25%,93% 75%,50% 100%,7% 75%,7% 25%);
  animation:intro-iris 1.05s cubic-bezier(.7,0,.2,1) forwards;
}
@keyframes intro-iris{
  0%  {transform:translate(-50%,-50%) scale(.18) rotate(0deg);opacity:0}
  22% {opacity:1}
  100%{transform:translate(-50%,-50%) scale(4.2) rotate(46deg);opacity:0}
}
@keyframes intro-out{
  0%  {opacity:1}
  55% {opacity:1}
  100%{opacity:0;visibility:hidden}
}

/* =========================================================
   9 · MARQUEE COMO CINTA
   Se le añaden perforaciones y una segunda fila al revés.
   ========================================================= */
.marquee--film{background:var(--film);border-block:1px solid rgba(249,241,232,.14);padding:26px 0 24px}
.marquee--film .marquee__track span{color:rgba(249,241,232,.82)}
.marquee--film .marquee__track i{color:var(--army-lt)}
.marquee__track--back{animation-direction:reverse;animation-duration:47s;opacity:.42;margin-top:12px}
.marquee__track--back span{font-weight:400}

/* =========================================================
   10 · TARJETAS: BRILLO, INCLINACIÓN Y ENTRADA EN 3D
   --rx / --ry las escribe motion.js al pasar el ratón.
   ========================================================= */
/* Sin perspective en el contenedor ni transform-style:preserve-3d en la
   tarjeta: juntos hacen que Chrome deje de pintar el contenido largo de
   la tarjeta (las listas de los paquetes desaparecían a media altura).
   La perspectiva va dentro del propio transform, que es todo lo que
   hace falta para inclinar cada tarjeta por su cuenta. */
.card,.plan,.item{
  position:relative;overflow:hidden;
  transform:
    perspective(900px)
    rotateX(var(--rx,0deg))
    rotateY(var(--ry,0deg))
    translateY(var(--ty,0px));
  transition:transform .45s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease);
}
.card:hover,.plan:hover,.item:hover{--ty:-5px}

/* Barrido de luz al pasar por encima. */
.card::before,.plan::before,.item::before{
  content:"";position:absolute;top:-60%;left:-75%;
  width:45%;height:220%;pointer-events:none;
  background:linear-gradient(90deg,
    transparent,rgba(141,182,197,.16),rgba(249,241,232,.30),rgba(141,182,197,.16),transparent);
  transform:rotate(18deg) translate3d(0,0,0);
  opacity:0;transition:opacity .2s linear;
}
.card:hover::before,.plan:hover::before,.item:hover::before{opacity:1;animation:sheen .85s cubic-bezier(.3,.6,.3,1)}
@keyframes sheen{to{transform:rotate(18deg) translate3d(420%,0,0)}}

/* La numeración se vuelve timecode. */
.card__num{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-variant-numeric:tabular-nums;
  position:relative;padding-left:15px;
}
.card__num::before{
  content:"";position:absolute;left:0;top:50%;margin-top:-3px;
  width:6px;height:6px;border-radius:50%;background:currentColor;
  animation:dot-blink 2.8s ease-in-out infinite;
}

/* Entrada: la tarjeta llega inclinada y se endereza. */
.grid .reveal,.plans .reveal,.item.reveal{transform:translate3d(0,34px,0) rotateX(9deg) scale(.985)}
.grid .reveal.is-in,.plans .reveal.is-in,.item.reveal.is-in{transform:none}

/* =========================================================
   11 · CLAQUETA EN LOS ENCABEZADOS
   Una barra de rayas diagonales que se abre al entrar en
   pantalla, como el brazo de una claqueta.
   ========================================================= */
.section__head,.pagehead__title{position:relative}
.section__head::before{
  content:"";display:block;height:7px;width:0;margin-bottom:18px;border-radius:2px;
  background:repeating-linear-gradient(118deg,
    var(--head) 0 8px, var(--bg) 8px 16px);
  outline:1px solid var(--line);
  transition:width .85s cubic-bezier(.2,.8,.25,1) .12s;
}
.section__head.is-in::before{width:clamp(104px,15vw,180px)}

/* El eyebrow lleva su propio punto de grabación. */
.eyebrow{display:flex;align-items:center;gap:9px}
.eyebrow::before{
  content:"";width:6px;height:6px;border-radius:50%;flex:none;
  background:currentColor;animation:dot-blink 2.4s ease-in-out infinite;
}

/* =========================================================
   12 · REVEALS DIRECCIONALES
   Los bloques ya traen .reveal desde styles.css; aquí se les
   sube el gesto sin tocar la hoja base.
   ========================================================= */
.reveal{transition:opacity .8s var(--ease),transform .8s var(--ease),filter .8s var(--ease)}
.section__lead,.pagehead__sub,.hero__sub{filter:blur(0)}
.reveal:not(.is-in).section__head,
.reveal:not(.is-in).section__title{filter:blur(6px)}

/* La cascada existente se alarga un poco más. */
.reveal:nth-child(7){transition-delay:420ms}
.reveal:nth-child(8){transition-delay:490ms}

/* =========================================================
   13 · BOTONES Y ENLACES
   ========================================================= */
.btn{position:relative;overflow:hidden;isolation:isolate}
.btn::after{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,transparent,rgba(249,241,232,.28),transparent);
  transform:translate3d(-115%,0,0);
}
.btn:hover::after{animation:btn-sweep .7s cubic-bezier(.3,.6,.3,1) forwards}
@keyframes btn-sweep{to{transform:translate3d(115%,0,0)}}

/* El botón principal del hero llama la atención cada tanto. */
.hero__cta .btn:first-child{animation:pulse-ring 4.5s ease-out infinite 2.4s}
@keyframes pulse-ring{
  0%,100%{box-shadow:0 0 0 0 rgba(141,182,197,0)}
  12%    {box-shadow:0 0 0 0 rgba(141,182,197,.42)}
  38%    {box-shadow:0 0 0 16px rgba(141,182,197,0)}
}

/* Enlaces del menú: subrayado que corre de izquierda a derecha.
   La página actual ya tiene su punto azul en styles.css, así que
   este subrayado sólo se pone en las demás. */
.nav__links a:not([aria-current])::after{
  content:"";position:absolute;left:15px;right:15px;bottom:5px;height:1.5px;
  background:var(--army-lt);
  transform:scaleX(0);transform-origin:100% 50%;
  transition:transform .38s var(--ease);
}
.nav__links a:not([aria-current]):hover::after{transform:scaleX(1);transform-origin:0 50%}

/* El cuadro del logo gira como un carrete y se abre al pasar el ratón. */
.logo__mark{
  border-radius:50%;position:relative;
  box-shadow:inset 0 0 0 1.5px var(--army-lt);
  background:transparent;
  animation:spin 7s linear infinite;
  transition:box-shadow .3s var(--ease),transform .3s var(--ease);
}
.logo__mark::after{
  content:"";position:absolute;inset:3px;border-radius:50%;
  background:var(--army-lt);
}
.logo:hover .logo__mark{box-shadow:inset 0 0 0 1.5px var(--cream);transform:scale(1.15)}

/* =========================================================
   14 · CONTADORES
   El número arranca en cero y sube; motion.js escribe el texto.
   ========================================================= */
.count{font-variant-numeric:tabular-nums;display:inline-block}
.stat dt{position:relative;overflow:visible}
.stat{position:relative;padding-left:0;transition:transform .4s var(--ease)}
.stat:hover{transform:translateY(-3px)}

/* Línea que se dibuja bajo cada estadística al entrar. */
.stats.is-in .stat::after{transform:scaleX(1)}
.stat::after{
  content:"";position:absolute;left:0;right:0;bottom:-14px;height:1px;
  background:linear-gradient(90deg,var(--army-lt),transparent);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .9s var(--ease);
}
.stat:nth-child(2)::after{transition-delay:.14s}
.stat:nth-child(3)::after{transition-delay:.28s}

/* Precios: el dígito se asienta con un pequeño rebote al entrar. */
.plan__price .count,.item__price .count{animation:price-land .6s var(--ease) both}
@keyframes price-land{
  from{transform:translate3d(0,10px,0);opacity:0}
  to  {transform:none;opacity:1}
}

/* =========================================================
   15 · PARALLAX SUAVE
   --sy es el desplazamiento en píxeles que escribe motion.js.
   Se mueve el contenedor de la escena, no cada pieza: así las
   animaciones propias de carretes y cintas siguen intactas.
   ========================================================= */
.studio{transform:translate3d(0,calc(var(--sy,0) * 1px),0);will-change:transform}
.hero__glow{transform:translate3d(-50%,calc(var(--sy,0) * .45px),0)}
.pagehead__glow{transform:translate3d(-50%,calc(var(--sy,0) * .3px),0)}

/* =========================================================
   17 · FONDOS QUE SE MUEVEN CON EL SCROLL
   ---------------------------------------------------------
   Cada sección del sitio recibe una capa de fondo (.bgfx) que
   motion.js le inyecta. La capa vive DEBAJO del contenido:
   la sección es el contexto de posicionamiento y el .wrap
   sube a z-index 1, así que nada de esto puede taparle una
   palabra a nadie.

   Variables que escribe motion.js:
     --sc   desplazamiento total de la página, en píxeles
     --fy   ciclo 0…26 px para que las perforaciones corran
     --e    avance de ESTA sección por la pantalla, de 0 a 1
     --p    el mismo avance ya convertido a píxeles de parallax

   Las secciones fuera de pantalla llevan las animaciones en
   pausa: sólo se mueve lo que se está viendo.
   ========================================================= */

/* isolation:isolate deja cada capa encerrada en su sección:
   nada de lo decorativo puede escaparse a otra parte de la página. */
.section,.cta,.footer{position:relative;isolation:isolate}
.hero,.pagehead{position:relative}
.section > .wrap,
.cta > .wrap,
.footer > .wrap{position:relative;z-index:1}

/* El encabezado también recibe capa, y ahí el orden importa más que en
   una sección normal porque ya vive gente: el .studio de index y el
   resplandor de la marca. Queda así, de abajo hacia arriba:
   la capa de fondo, luego el resplandor, y hasta arriba el texto. */
.hero > .bgfx,
.pagehead > .bgfx{z-index:0}
.hero__glow,
.pagehead__glow{z-index:1}

/* En el encabezado la foto pelea contra el resplandor de la marca y,
   en index, contra el decorado del .studio. Sube en vez de bajar: al
   valor de las secciones claras se perdía del todo sobre el fondo
   oscuro del hero. */
.hero > .bgfx .bgfx__foto,
.pagehead > .bgfx .bgfx__foto{opacity:.5}

.bgfx{
  position:absolute;inset:0;z-index:0;
  overflow:hidden;pointer-events:none;
  contain:paint;
}

/* ---------- carrete que gira conforme bajas ---------- */
.bgfx__reel{
  position:absolute;pointer-events:none;
  width:clamp(260px,34vw,520px);aspect-ratio:1;
  opacity:.5;
}
.bgfx__reel svg{width:100%;height:100%;display:block}
.bgfx__reel .reel__spin{
  animation:none;                       /* aquí no manda el reloj, manda el scroll */
  transform:rotate(calc(var(--sc,0) * .07deg));
}
.bgfx__reel--r{right:-11%;top:6%}
.bgfx__reel--l{left:-13%;bottom:4%}
.bgfx__reel--l .reel__spin{transform:rotate(calc(var(--sc,0) * -.05deg))}

/* En claro el carrete es casi un susurro; en oscuro puede respirar. */
.section .bgfx__reel{opacity:.14}
.dark .bgfx__reel{opacity:.34}

/* ---------- hoja de contactos: rejilla de fotogramas ---------- */
.bgfx__sheet{
  position:absolute;inset:-25% -8%;
  background-image:
    linear-gradient(  0deg,var(--line-soft) 1px,transparent 1px),
    linear-gradient(90deg,var(--line-soft) 1px,transparent 1px);
  background-size:146px 104px;
  transform:translate3d(0,calc(var(--p,0) * -.5px),0);
  -webkit-mask-image:radial-gradient(ellipse 72% 58% at 50% 50%,#000,transparent 74%);
  mask-image:radial-gradient(ellipse 72% 58% at 50% 50%,#000,transparent 74%);
}
.dark .bgfx__sheet{
  background-image:
    linear-gradient(  0deg,rgba(249,241,232,.07) 1px,transparent 1px),
    linear-gradient(90deg,rgba(249,241,232,.07) 1px,transparent 1px);
}

/* ---------- manchas de luz a la deriva ---------- */
.bgfx__glow{
  position:absolute;width:min(70vw,760px);aspect-ratio:1.3;
  border-radius:50%;
  transform:translate3d(0,calc(var(--p,0) * .55px),0);
}
.bgfx__glow--1{
  top:-22%;left:-14%;
  background:radial-gradient(closest-side,rgba(59,116,137,.16),transparent 72%);
  animation:glow-drift 19s ease-in-out infinite;
}
.bgfx__glow--2{
  bottom:-26%;right:-12%;
  background:radial-gradient(closest-side,rgba(59,116,137,.11),transparent 72%);
  animation:glow-drift 25s ease-in-out infinite reverse;
}
.dark .bgfx__glow--1{background:radial-gradient(closest-side,rgba(141,182,197,.15),transparent 72%)}
.dark .bgfx__glow--2{background:radial-gradient(closest-side,rgba(141,182,197,.10),transparent 72%)}
@keyframes glow-drift{
  0%,100%{translate:0 0}
  33%    {translate:7% -5%}
  66%    {translate:-5% 6%}
}

/* ---------- barrido de luz atado al scroll ----------
   No va por reloj: cruza la sección exactamente conforme
   la sección cruza la pantalla. --e va de 0 a 1. */
.bgfx__sweep{
  position:absolute;top:-30%;height:160%;width:34%;left:0;
  background:linear-gradient(90deg,
    transparent,
    rgba(141,182,197,.07) 30%,
    rgba(249,241,232,.5) 50%,
    rgba(141,182,197,.07) 70%,
    transparent);
  opacity:.5;
  transform:translate3d(calc((var(--e,0) * 340% ) - 120%),0,0) rotate(9deg);
}
.section .bgfx__sweep{
  background:linear-gradient(90deg,
    transparent,
    rgba(59,116,137,.05) 30%,
    rgba(59,116,137,.10) 50%,
    rgba(59,116,137,.05) 70%,
    transparent);
  opacity:.85;
}

/* ---------- borde perforado entre secciones ---------- */
.bgfx__edge{
  position:absolute;left:-40px;right:-40px;height:9px;
  background:repeating-linear-gradient(90deg,
    var(--line) 0 11px, transparent 11px 30px);
  opacity:.5;
  transform:translate3d(calc(var(--fy,0) * -1.2px),0,0);
}
.bgfx__edge--t{top:16px}
.bgfx__edge--b{bottom:16px}
.dark .bgfx__edge{background:repeating-linear-gradient(90deg,
    rgba(249,241,232,.24) 0 11px, transparent 11px 30px)}

/* ---------- polvo en el haz de luz ---------- */
.bgfx__mote{
  position:absolute;width:4px;height:4px;border-radius:50%;
  background:var(--army-lt);opacity:0;
  animation:mote 14s linear infinite;
}
@keyframes mote{
  0%  {opacity:0;   translate:0 40px;   scale:.5}
  12% {opacity:.55}
  80% {opacity:.35}
  100%{opacity:0;   translate:26px -260px; scale:1.1}
}
.section .bgfx__mote{background:var(--army);}

/* ---------- barras de nivel de audio ---------- */
.bgfx__meter{
  position:absolute;left:0;right:0;bottom:0;height:74px;
  display:flex;align-items:flex-end;gap:5px;padding:0 3vw;
  opacity:.34;
}
.bgfx__bar{
  flex:1;height:100%;min-width:2px;border-radius:2px 2px 0 0;
  background:linear-gradient(180deg,var(--army-lt),rgba(141,182,197,0));
  transform:scaleY(.14);transform-origin:50% 100%;
  animation:meter 1.9s ease-in-out infinite alternate;
}
.section .bgfx__bar{background:linear-gradient(180deg,var(--army),rgba(59,116,137,0))}
@keyframes meter{
  0%  {transform:scaleY(.10)}
  100%{transform:scaleY(.92)}
}

/* ---------- claqueta gigante de marca de agua ---------- */
.bgfx__slate{
  /* Arriba del todo: a media altura cruzaba por el encabezado, y
     además chocaba con la claqueta que ya trae cada título. */
  position:absolute;top:1.5%;left:50%;
  width:min(62vw,660px);height:26px;border-radius:3px;
  background:repeating-linear-gradient(118deg,
    var(--line) 0 22px, transparent 22px 44px);
  opacity:.34;
  transform:translate3d(-50%,calc(var(--p,0) * .8px),0) rotate(-4deg);
}
.dark .bgfx__slate{background:repeating-linear-gradient(118deg,
    rgba(249,241,232,.10) 0 22px, transparent 22px 44px)}

/* ---------- cinta cruzando la sección, arrastrada por el scroll ----------
   Pasa POR DETRÁS de las tarjetas, que son opacas: se asoma nada más
   por los huecos, como si la película corriera detrás de todo. */
.bgfx__belt{
  position:absolute;left:-32%;width:164%;height:60px;top:56%;
  border-radius:3px;
  background:linear-gradient(180deg,#1e1e1e,var(--film) 50%,#111);
  opacity:.09;
  transform:rotate(-6.5deg) translate3d(calc(var(--e,0) * -13%),0,0);
}
.dark .bgfx__belt{opacity:.4}
.bgfx__belt--t{top:12%;transform:rotate(5deg) translate3d(calc(var(--e,0) * 12%),0,0)}
.bgfx__belt::before,
.bgfx__belt::after{
  content:"";position:absolute;left:-40px;right:-40px;height:8px;border-radius:2px;
  background:repeating-linear-gradient(90deg,
    var(--perf) 0 11px, transparent 11px 30px);
  transform:translate3d(calc(var(--fy,0) * -1.4px),0,0);
}
.bgfx__belt::before{top:6px}
.bgfx__belt::after{bottom:6px}

/* ---------- lente cuyo iris se abre conforme pasas la sección ---------- */
.bgfx__lens{
  position:absolute;width:min(44vw,500px);aspect-ratio:1;
  border:1.5px solid var(--line);border-radius:50%;
  opacity:.55;
  transform:translate3d(0,calc(var(--p,0) * .3px),0);
}
.bgfx__lens::before{
  content:"";position:absolute;inset:11%;
  border:1.5px solid var(--line);border-radius:50%;
}
.bgfx__lens::after{
  content:"";position:absolute;inset:24%;
  background:rgba(59,116,137,.055);
  clip-path:polygon(50% 0,93% 25%,93% 75%,50% 100%,7% 75%,7% 25%);
  transform:scale(calc(.34 + var(--e,0) * .78)) rotate(calc(var(--e,0) * 46deg));
}
.bgfx__lens--l{left:-13%;top:14%}
.bgfx__lens--r{right:-13%;bottom:8%}
.dark .bgfx__lens{border-color:rgba(141,182,197,.26);opacity:.8}
.dark .bgfx__lens::before{border-color:rgba(141,182,197,.26)}
.dark .bgfx__lens::after{background:rgba(141,182,197,.07)}

/* ---------- regla de tiempo, como el scrubber de una timeline ---------- */
.bgfx__ticks{
  position:absolute;top:-12%;height:124%;width:38px;
  /* Un solo degradado: con dos capas más la máscara, esta pieza costaba
     el triple que cualquier otra en el recálculo de estilo. */
  background:repeating-linear-gradient(180deg,
    var(--line) 0 1px,
    transparent 1px 12px,
    var(--line) 12px 13px,
    transparent 13px 24px);
  background-size:16px 100%;
  background-repeat:repeat-y;
  opacity:.6;
  transform:translate3d(0,calc(var(--fy,0) * -1.6px),0);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 16%,#000 84%,transparent);
  mask-image:linear-gradient(180deg,transparent,#000 16%,#000 84%,transparent);
}
.dark .bgfx__ticks{
  background-image:repeating-linear-gradient(180deg,
    rgba(141,182,197,.4) 0 1px,
    transparent 1px 12px,
    rgba(141,182,197,.4) 12px 13px,
    transparent 13px 24px);
}
.bgfx__ticks--l{left:max(6px,calc(50% - 636px))}
.bgfx__ticks--r{right:max(6px,calc(50% - 636px))}

/* ---------- haz de proyector ----------
   Un cono de luz que respira. Sólo se le anima la opacidad,
   que es de las dos cosas que el navegador puede componer sin
   volver a dibujar nada. */
.bgfx__beam{
  position:absolute;top:-45%;left:-12%;width:66%;height:190%;
  background:linear-gradient(102deg,
    transparent 38%,
    rgba(59,116,137,.09) 50%,
    transparent 62%);
  clip-path:polygon(0 44%,100% 0,100% 100%,0 56%);
  animation:beam 9.5s ease-in-out infinite;
}
.bgfx__beam--r{left:auto;right:-12%;transform:scaleX(-1)}
.dark .bgfx__beam{background:linear-gradient(102deg,
    transparent 38%,rgba(141,182,197,.13) 50%,transparent 62%)}
@keyframes beam{
  0%,100%{opacity:.3}
  50%    {opacity:.85}
}

/* ---------- cuenta regresiva de academia ----------
   El círculo con la cruz y la manecilla que barre, igual que
   la cola de arranque de un rollo. La manecilla no gira con el
   reloj: gira con lo que llevas recorrido de la sección. */
.bgfx__leader{
  position:absolute;width:min(30vw,330px);aspect-ratio:1;
  border:1.5px solid var(--line);border-radius:50%;
  opacity:.55;
  transform:translate3d(0,calc(var(--p,0) * .4px),0);
}
.bgfx__leader::before{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(  0deg,transparent calc(50% - .75px),var(--line) calc(50% - .75px) calc(50% + .75px),transparent calc(50% + .75px)),
    linear-gradient( 90deg,transparent calc(50% - .75px),var(--line) calc(50% - .75px) calc(50% + .75px),transparent calc(50% + .75px));
  border-radius:50%;
}
.bgfx__leader::after{
  content:"";position:absolute;left:50%;top:2%;width:2px;height:48%;
  margin-left:-1px;border-radius:2px;
  background:linear-gradient(180deg,var(--army),transparent);
  transform-origin:50% 100%;
  transform:rotate(calc(var(--e,0) * 720deg));
}
.bgfx__leader--l{left:-9%;top:12%}
.bgfx__leader--r{right:-9%;bottom:10%}
.dark .bgfx__leader{border-color:rgba(141,182,197,.26);opacity:.85}
.dark .bgfx__leader::before{
  background:
    linear-gradient(  0deg,transparent calc(50% - .75px),rgba(141,182,197,.26) calc(50% - .75px) calc(50% + .75px),transparent calc(50% + .75px)),
    linear-gradient( 90deg,transparent calc(50% - .75px),rgba(141,182,197,.26) calc(50% - .75px) calc(50% + .75px),transparent calc(50% + .75px));
}
.dark .bgfx__leader::after{background:linear-gradient(180deg,var(--army-lt),transparent)}

/* ---------- barras de ajuste, en los tonos de la marca ---------- */
.bgfx__bars{
  position:absolute;top:-8%;height:116%;width:78px;
  opacity:.16;
  background:linear-gradient(180deg,
    var(--aurora)  0 14.28%,
    var(--army)    14.28% 28.56%,
    var(--army-lt) 28.56% 42.84%,
    var(--cream)   42.84% 57.12%,
    var(--army-lt) 57.12% 71.4%,
    var(--army)    71.4% 85.68%,
    var(--aurora)  85.68% 100%);
  transform:translate3d(0,calc(var(--p,0) * .9px),0);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 22%,#000 78%,transparent);
  mask-image:linear-gradient(180deg,transparent,#000 22%,#000 78%,transparent);
}
.dark .bgfx__bars{opacity:.3}
.bgfx__bars--l{left:max(4px,calc(50% - 664px))}
.bgfx__bars--r{right:max(4px,calc(50% - 664px))}

/* ---------- onda de audio corriendo ----------
   El <svg> lo arma motion.js: son dos ciclos idénticos y el
   grupo se recorre justo la mitad, así el bucle no se ve. */
.bgfx__wave{
  position:absolute;left:0;right:0;bottom:11%;height:120px;
  opacity:.4;
}
.bgfx__wave svg{width:100%;height:100%;display:block;overflow:visible}
.bgfx__wave path{fill:none;stroke:var(--army);stroke-width:1.4;vector-effect:non-scaling-stroke}
.dark .bgfx__wave path{stroke:var(--army-lt)}
.bgfx__wave g{animation:wave-run 16s linear infinite}
@keyframes wave-run{to{transform:translateX(-50%)}}

/* ---------- fotogramas que se encienden en la hoja de contactos ---------- */
.bgfx__flash{
  position:absolute;width:104px;height:74px;border-radius:2px;
  background:rgba(59,116,137,.14);
  opacity:0;
  animation:flash 7s ease-in-out infinite;
}
.dark .bgfx__flash{background:rgba(141,182,197,.14)}
@keyframes flash{
  0%,64%,100%{opacity:0}
  72%,86%    {opacity:1}
}

/* ---------- línea que se dibuja al cruzar la sección ----------
   scaleX es transform puro: el navegador no vuelve a dibujar
   nada, sólo estira una capa que ya tenía lista. */
.bgfx__trace{
  position:absolute;left:0;right:0;height:2px;
  background:linear-gradient(90deg,var(--army),rgba(59,116,137,0));
  transform:scaleX(var(--e,0));transform-origin:0 50%;
  opacity:.55;
}
.dark .bgfx__trace{background:linear-gradient(90deg,var(--army-lt),rgba(141,182,197,0))}
.bgfx__trace--t{top:0}
.bgfx__trace--b{bottom:0}

/* =========================================================
   FOTOGRAFÍA DE FONDO
   ---------------------------------------------------------
   Un recuadro con una foto tratada en duotono, que hace
   parallax al pasar la sección. Vive fuera de la columna de
   texto y por debajo de todo, como el resto del decorado.

   El duotono es un degradado encima, sin mix-blend-mode: se
   probó con blend y obligaba a recomponer de más. Un filtro
   estático (no animado) se rasteriza una sola vez, así que
   sale gratis después del primer cuadro.
   ========================================================= */
.bgfx__foto{
  position:absolute;overflow:hidden;
  width:clamp(280px,33vw,470px);aspect-ratio:1/1;
  opacity:.62;
  transform:translate3d(0,calc(var(--p,0) * .75px),0) rotate(var(--giro,0deg));
  /* Sin marco ni sombra: los bordes se difuminan contra la página.
     Un rectángulo de bordes duros se lee como una imagen pegada encima
     del diseño; difuminado se lee como parte del fondo.

     Los radios son 50% y 50% por una razón exacta: con radios mayores
     (76%) la elipse todavía va a media opacidad cuando llega al borde
     de la caja, y ahí el recorte deja una línea recta bien visible. Al
     50% el degradado termina justo en el borde y no hay corte. */
  -webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 52%,transparent 100%);
  mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 52%,transparent 100%);
}
.dark .bgfx__foto{opacity:.46}
/* Sobre negro hay que bajarle el brillo: una foto de fondo claro
   —un ciclorama, una pared blanca— se dispara y le roba peso al texto. */
.dark .bgfx__foto img{filter:grayscale(1) contrast(1.24) brightness(.92)}

.bgfx__foto img{
  width:100%;height:100%;object-fit:cover;display:block;
  /* El filtro no se anima nunca: se rasteriza una vez y ya.
     El brillo va MUY abajo a propósito: el fondo del sitio es crema
     (#F9F1E8) y estas fotos son claras — una encima de la otra se
     anulan. Bajándole el brillo la foto se vuelve un tono medio
     oscuro que sí separa del papel. */
  filter:grayscale(1) contrast(1.5) brightness(.45);
}

/* La capa de color: es lo que hace que ocho fotos de ocho fotógrafos
   distintos se vean como una sola serie, y en los colores de la marca. */
.bgfx__foto::after{
  content:"";position:absolute;inset:0;
  /* El velo tiñe, no tapa. Con más alfa la foto se volvía una mancha
     verde: el chiste es que se reconozca qué está pasando en ella. */
  background:linear-gradient(158deg,
    rgba(59,116,137,.4) 0%,
    rgba(32,32,32,.1) 50%,
    rgba(141,182,197,.3) 100%);
}
.dark .bgfx__foto::after{
  background:linear-gradient(158deg,
    rgba(59,116,137,.44) 0%,
    rgba(32,32,32,.34) 50%,
    rgba(141,182,197,.26) 100%);
}

/* Colocaciones: pegadas al margen, lejos de la columna de texto. */
/* Todo el sitio alinea el texto a la izquierda y ninguna columna pasa
   de 760 px, así que el hueco de verdad está a la derecha. Las de la
   izquierda se reservan para las secciones de texto centrado (el CTA). */
.bgfx__foto--tr{right:-5%;top:4%;--giro:2.4deg}
.bgfx__foto--br{right:-6%;bottom:3%;--giro:-1.8deg}
.bgfx__foto--bl{left:-6%;bottom:4%;--giro:2deg}
.bgfx__foto--tl{left:-5%;top:6%;--giro:-2.6deg}

/* Cuando van dos, la segunda es más chica: se lee como un par de
   copias sobre la mesa, no como una sola imagen suelta. */
.bgfx__foto--par{
  width:clamp(180px,21vw,300px);aspect-ratio:1;
  opacity:.46;
  transform:translate3d(0,calc(var(--p,0) * 1.2px),0) rotate(var(--giro,0deg));
}
.dark .bgfx__foto--par{opacity:.36}
.bgfx__foto--par.bgfx__foto--tr{right:2%;top:auto;bottom:7%;--giro:-3.4deg}
.bgfx__foto--par.bgfx__foto--bl{left:-3%;bottom:auto;top:8%;--giro:3.2deg}

/* =========================================================
   CRECIMIENTO, AUDIENCIA Y ALCANCE
   Piezas que no hablan de cine sino de para qué sirve:
   más público, más alcance, más gente entrando al negocio.
   ========================================================= */

/* ---------- gráfica de barras que crece con el scroll ---------- */
.bgfx__subida{
  position:absolute;display:flex;align-items:flex-end;gap:9px;
  width:clamp(180px,22vw,300px);height:clamp(90px,11vw,150px);
  opacity:.5;
}
.bgfx__subida--r{right:5%;bottom:13%}
.bgfx__subida span{
  flex:1;border-radius:3px 3px 0 0;
  background:linear-gradient(180deg,var(--army),rgba(59,116,137,.15));
  transform-origin:50% 100%;
  /* cada barra llega a su altura conforme avanza la sección */
  transform:scaleY(calc(var(--e,0) * var(--alto,.5)));
}
.dark .bgfx__subida span{background:linear-gradient(180deg,var(--army-lt),rgba(141,182,197,.15))}

/* ---------- audiencia: círculos que se van sumando ---------- */
/* Columna angosta: a la izquierda sólo caben 185 px antes de la columna
   de texto, así que la audiencia se apila en vertical y no en bloque. */
.bgfx__publico{
  position:absolute;width:clamp(86px,11vw,150px);height:clamp(200px,27vw,360px);
  opacity:.6;
}
.bgfx__publico--l{left:.5%;top:12%}
.bgfx__publico--r{right:1.5%;top:14%}
.bgfx__publico span{
  position:absolute;border-radius:50%;
  border:1.5px solid var(--army);
  background:rgba(59,116,137,.07);
  /* aparecen de una en una según lo que llevas de la sección */
  opacity:calc((var(--e,0) - var(--turno,0)) * 6);
  transform:scale(calc(.55 + var(--e,0) * .45));
}
.dark .bgfx__publico span{border-color:var(--army-lt);background:rgba(141,182,197,.09)}

/* ---------- likes y comentarios subiendo ---------- */
.bgfx__reaccion{
  position:absolute;width:26px;height:26px;
  border:1.5px solid var(--army);border-radius:50% 50% 50% 4px;
  transform:rotate(-45deg);
  opacity:0;
  animation:reaccion 9s ease-out infinite;
}
.dark .bgfx__reaccion{border-color:var(--army-lt)}
@keyframes reaccion{
  0%  {opacity:0;   translate:0 30px;    scale:.4}
  14% {opacity:.85}
  76% {opacity:.5}
  100%{opacity:0;   translate:14px -230px; scale:1}
}

/* ---------- pines de mapa: SEO local ---------- */
.bgfx__mapa{
  position:absolute;width:clamp(190px,24vw,320px);aspect-ratio:1.25;
  opacity:.55;
  /* la retícula de calles */
  background-image:
    repeating-linear-gradient( 90deg,var(--line) 0 1px,transparent 1px 46px),
    repeating-linear-gradient(  0deg,var(--line) 0 1px,transparent 1px 38px);
  transform:translate3d(0,calc(var(--p,0) * .5px),0);
  -webkit-mask-image:radial-gradient(ellipse at 50% 50%,#000 30%,transparent 74%);
  mask-image:radial-gradient(ellipse at 50% 50%,#000 30%,transparent 74%);
}
.dark .bgfx__mapa{
  background-image:
    repeating-linear-gradient( 90deg,rgba(141,182,197,.3) 0 1px,transparent 1px 46px),
    repeating-linear-gradient(  0deg,rgba(141,182,197,.3) 0 1px,transparent 1px 38px);
}
.bgfx__mapa--r{right:5%;top:15%}
.bgfx__pin{
  position:absolute;width:15px;height:15px;
  border:2px solid var(--army);border-radius:50% 50% 50% 0;
  transform:rotate(-45deg);
  animation:pin 5.5s ease-in-out infinite;
}
.dark .bgfx__pin{border-color:var(--army-lt)}
@keyframes pin{
  0%,100%{opacity:.25; scale:.85}
  46%,58%{opacity:1;   scale:1.18}
}

/* ---------- celular vertical con un reel corriendo ---------- */
.bgfx__movil{
  position:absolute;width:clamp(120px,14vw,190px);aspect-ratio:9/19;
  border:2px solid var(--line);border-radius:22px;
  opacity:.6;overflow:hidden;
  transform:translate3d(0,calc(var(--p,0) * .85px),0) rotate(var(--giro,-4deg));
}
.dark .bgfx__movil{border-color:rgba(141,182,197,.34)}
.bgfx__movil--r{right:6%;bottom:8%;--giro:4deg}
/* la muesca */
.bgfx__movil::before{
  content:"";position:absolute;top:7px;left:50%;margin-left:-22px;
  width:44px;height:5px;border-radius:3px;background:var(--line);
}
/* los "fotogramas" del reel pasando */
.bgfx__movil::after{
  content:"";position:absolute;left:6px;right:6px;top:20px;bottom:20px;
  border-radius:14px;
  background:repeating-linear-gradient(180deg,
    rgba(59,116,137,.16) 0 54px,
    transparent 54px 60px);
  animation:reel-corre 7s linear infinite;
}
.dark .bgfx__movil::after{
  background:repeating-linear-gradient(180deg,
    rgba(141,182,197,.2) 0 54px, transparent 54px 60px);
}
@keyframes reel-corre{to{translate:0 -60px}}

/* ---------- pausa de lo que no se está viendo ----------
   Va al final y con dos clases a propósito. El atajo `animation:`
   de cada pieza reinicia animation-play-state a "running", así que
   una regla declarada ANTES y con la misma especificidad no servía
   de nada: todo seguía animándose fuera de pantalla. Con
   .bgfx:not(.is-live) * la regla pesa más que cualquier pieza y
   gana esté donde esté. */
.bgfx:not(.is-live) *{animation-play-state:paused}

/* ---------- de dónde sale el espacio ---------- */
@media (max-width:1320px){
  .bgfx__ticks,.bgfx__bars{display:none}
}
@media (max-width:860px){
  /* En móvil se queda lo barato: luz, rejilla y barrido. */
  .bgfx__reel,.bgfx__meter,.bgfx__slate,.bgfx__mote,
  .bgfx__lens,.bgfx__leader,.bgfx__flash,.bgfx__wave{display:none}
  .bgfx__belt{height:40px}
  .bgfx__sheet{background-size:104px 76px}
}
@media (prefers-reduced-motion:reduce){
  .bgfx{display:none!important}
}

/* =========================================================
   16 · ACCESIBILIDAD
   Si el sistema pide menos movimiento, se apaga todo lo
   decorativo — no sólo se acelera.
   ========================================================= */
@media (prefers-reduced-motion:reduce){
  .grain,.studio,.leak,.scan,.thirds,.intro,.progress{display:none!important}
  .fstrip__perf,.fstrip__frames,.reel__spin,.lens__iris,.lens__blades,
  .logo__mark,.rec__dot,.eyebrow::before,.card__num::before{animation:none!important}
  .pull__w{opacity:1;filter:none;transform:none;animation:none!important}
  .card,.plan,.item{transform:none!important}
  .section__head::before{width:clamp(120px,17vw,210px);transition:none}
  .reveal{filter:none!important}
}

/* En pantallas chicas se aligera la escena: menos capas, más batería. */
@media (max-width:1100px){
  .lens{display:none}
}

@media (max-width:760px){
  .studio__strip--b,.thirds{display:none}
  .reel--l{width:190px;top:4%;right:-14%;opacity:.34}
  .reel--r{display:none}
  .grain{opacity:.035}
}

/* =========================================================
   19 · FLUIDEZ  (21/09/2026)
   ---------------------------------------------------------
   Mismo sitio, mismos efectos; sólo se quita lo que hacía que
   el navegador repintara de más al hacer scroll. Medido con
   Chrome antes y después (ver LEEME → «Fluidez»).
   ========================================================= */

/* Los bloques aparecen con opacidad y posición, sin desenfoque:
   animar filter:blur() obliga a repintar cada bloque cuadro por
   cuadro justo mientras la persona está bajando. */
.reveal{transition:opacity .75s var(--ease),transform .75s var(--ease)}
.reveal:not(.is-in).section__head,
.reveal:not(.is-in).section__title{filter:none}

/* La escena del encabezado (cintas, carretes, lente, fuga de luz)
   se congela mientras no se ve. motion.js pone .is-off cuando
   sale de la pantalla y la quita al volver. Misma técnica que
   .bgfx:not(.is-live) de arriba: dos clases para ganarle al
   atajo `animation:` de cada pieza. */
.studio.is-off *,.studio.is-off{animation-play-state:paused}

/* El grano sigue ahí, pero quieto mientras se hace scroll:
   motion.js pone .is-scrolling en <html> y la quita al parar. */
html.is-scrolling .grain{animation-play-state:paused}

/* En celulares y tablets el grano casi no se nota (ya iba a
   opacidad .035) y es una capa del tamaño de la pantalla que el
   teléfono tiene que componer en cada cuadro: ahí se apaga. */
@media (hover:none) and (pointer:coarse){
  .grain{display:none}
}

/* Transiciones entre páginas: en Chrome, Edge y Safari la página
   nueva entra con un fundido corto en vez de un corte en blanco.
   Los navegadores que no lo soportan simplemente lo ignoran. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vt-sale .22s var(--ease) both}
::view-transition-new(root){animation:vt-entra .32s var(--ease) both}
@keyframes vt-sale{to{opacity:0}}
@keyframes vt-entra{from{opacity:0}}
/* La barra no parpadea al cambiar de página: se queda fija. */
.nav{view-transition-name:barra}
::view-transition-group(barra){animation:none}

@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}
