/* ============================================================
   MAEStudio · SKELETON v3 — atmósfera continua + oficio
   El fondo es UN espacio (D-026): tres actos con amanecer y
   anochecer graduales dentro del propio lienzo (D-045) — sin
   líneas de corte entre secciones. Vidrio real, micro-etiquetas
   HUD, vacíos generosos.
   ============================================================ */

/* ---------- Grano global ---------- */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 98; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.032; mix-blend-mode: overlay;
}

/* ============================================================
   ACTOS — el lienzo continuo
   ============================================================ */
.acto { position: relative; z-index: 1; }   /* los actos tapan al lienzo fijo al pasar */

/* Acto I · noche (S2–S3): TRANSPARENTE — su cielo vive en .bg-noche (lienzo fijo) */
.acto--noche1 { background: transparent; }

/* ============================================================
   LIENZO FIJO DEL ACTO NOCHE (2026-07-19) — el fondo no se
   desplaza: MUTA. foto+nubes ⇄ TF ida/vuelta ⇄ cerro de líneas.
   ============================================================ */
/* el logo MAE en 3D: capa fija sobre el fondo, bajo el contenido (.acto z-1) */
.fg3d {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; display: none;
  /* NIVEL 3 · F6 — micro-contraste. PERILLAS: contrast 1.00-1.10 ·
     saturate 1.00-1.15. El filtro se aplica AL CANVAS (no a la página) y no
     toca el alfa: el cerro se sigue viendo entre los fragmentos. */
  /* …y el BRILLO CERCANO de la jaula (2026-07-22). El halo ancho NO se hace
     aquí: lo hace #fg3dBloom, que sí conserva el color de cada arista. */
  filter: contrast(1.02) saturate(1.04)
          drop-shadow(0 0 2px rgba(255, 255, 255, 1))
          drop-shadow(0 0 7px rgba(238, 243, 255, 0.85));
}

/* ============================================================
   BLOOM DE LA JAULA (2026-07-22) — el resplandor con COLOR
   Por qué existe: las barras aditivas dentro de la escena nunca dieron
   halo (son geometría con borde, no luz difusa) y el post-proceso 3D
   está descartado porque rompe el alfa del canvas (PASO 13.3). La salida
   es la misma que usa el hero: desenfocar por CSS. Esta capa es una COPIA
   del canvas 3D a 1/3 de resolución, desenfocada y sumada en modo screen
   — como copia el contenido real, el halo hereda el violeta y el cian de
   cada arista en vez de teñirse de un color plano.
   PERILLAS: el blur y la opacidad de aquí; el 1/3 está en fg3d.js.
   ============================================================ */
.fg3d-bloom {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; display: none;
  filter: blur(7px);
  opacity: 0.95;
  mix-blend-mode: screen;
}

/* JAULA NEÓN 2D (2026-07-22): capa que sigue la geometría 3D y traza las
   aristas con shadowBlur. El glow ya lo hace el propio canvas 2D — aquí NO
   se pone filtro. Sobre el canvas 3D del cubo, bajo el contenido. */
.fg3d-cage {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; display: none;
}
/* NIVEL 3 · F6 — viñeteo: negros ricos en las esquinas, centro intacto.
   PERILLAS: el 55% es dónde empieza a caer · el .42 final, cuánto cierra. */
.fg3d-vig {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; display: none;
  background: radial-gradient(ellipse 80% 70% at 50% 46%,
              rgba(5, 7, 13, 0) 55%, rgba(5, 7, 13, .42) 100%);
}

/* S3 · CLIP 1 por vídeo (2026-07-22). El <video> es sólo fuente de píxeles
   —nunca se ve—; el canvas es quien pinta, ya recortado por luma. Su tamaño
   y posición los fija clip1.js cada frame a partir de HERO_FRAC: aquí NO se
   pone ancho, o se estaría decidiendo la escala dos veces. */
.clip1-src {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; pointer-events: none; left: -9999px;
}
/* LOS DOS INQUILINOS DE LA CAJA DEL OBJETO (2026-07-28).
   `.idle-cycle` da la caja; estos dos la llenan y se turnan. Comparten tamaño
   y centro POR CONSTRUCCIÓN — antes el clip era `position: fixed` y calculaba
   su caja midiendo `.idle-cycle` en cada fotograma, encadenando cuatro
   constantes para llegar a un número que el layout ya sabía. */
.hero-cubo { position: absolute; inset: 0; }

/* El lienzo de la esclusa. Su caja la escribe clip1.js UNA VEZ (al cargar y al
   redimensionar), no en cada fotograma: aquí NO se decide tamaño, o se estaría
   eligiendo la escala dos veces. */
.clip1-layer {
  position: fixed; z-index: 0; pointer-events: none; display: none;
  transform: translateZ(0); will-change: opacity;
}
@media (prefers-reduced-motion: reduce) { .clip1-layer { display: none !important; } }

/* S3 · RACIMO EN REPOSO (2026-07-27; desde el 29-jul es el BUCLE, no un PNG).
   Capa hermana de la del clip: misma altura de pila (bajo el contenido de las
   secciones, sobre el fondo). El ancho, la posición y la opacidad los escribe
   idle3.js a partir de las leyes de fg3d — aquí NO se decide tamaño, o se
   estaría eligiendo la escala dos veces. */
.s3-cubo {
  position: fixed; z-index: 0; pointer-events: none; opacity: 0;
  will-change: opacity; transform: translateZ(0);
}

.bg-noche { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.bg-noche.is-off { display: none; }
/* orden de capas (idea de Mau): las nubes VIVAS van ENCIMA del video TF y son
   ellas las que se desvanecen moviéndose; el still nítido corona al final */
.bg-noche__tf { z-index: 1; }
.bg-noche .hero__bg--anim { z-index: 2; }
.bg-noche__lineas { z-index: 3; }
/* idle de S3 (canvas WebGL): mismo encuadre que el still al que sustituye */
.bg-noche__idle {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 62%;
  z-index: 3; opacity: 0; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .bg-noche__idle { display: none !important; } }
.bg-noche .stars, .bg-noche .stars2 { z-index: 4; }
.bg-noche .hero__bg-fusion { z-index: 5; }
.bg-noche__neb {
  position: absolute; inset: 0;
  background:
    radial-gradient(1300px 900px at 82% -4%, #16223F 0%, transparent 55%),
    radial-gradient(1000px 760px at 6% 88%, rgba(157, 123, 255, 0.055) 0%, transparent 55%),
    radial-gradient(800px 600px at 60% 55%, rgba(77, 125, 242, 0.03) 0%, transparent 60%),
    #0A0E1A;
}
/* PAR 1:1 (2026-07-20): foto, video TF y still de líneas comparten lienzo
   2752×1536 y encuadre — una sola cámara fija, cero registro */
.bg-noche__lineas, .bg-noche__tf {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 62%;
}
/* MÁSCARA DE BANDA SUPERIOR (idea de Mau): solo las NUBES ALTAS del video y
   de la foto quedan ocultas — niebla, faldas y cerro intactos. El cielo alto
   lo cuentan las nubes vivas desvaneciéndose. */
.bg-noche__tf {
  -webkit-mask-image: url("../assets/F01-mask.png");
  mask-image: url("../assets/F01-mask.png");
  -webkit-mask-size: cover; mask-size: cover;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 50% 62%; mask-position: 50% 62%;
}
.bg-noche #heroBg {
  -webkit-mask-image: url("../assets/F01-mask.png");
  mask-image: url("../assets/F01-mask.png");
  -webkit-mask-size: cover; mask-size: cover;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 50% 62%; mask-position: 50% 62%;
}
.bg-noche__lineas { opacity: 0; transition: opacity 0.6s var(--ease-out); }
.bg-noche__lineas.is-set { opacity: 1; }
.bg-noche__tf { opacity: 0; transition: opacity 0.4s var(--ease-out); }
.bg-noche__tf.is-playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .bg-noche__tf { display: none !important; } }

/* Acto II · papel (S4–S7): el amanecer entra y el día se apaga
   DENTRO del gradiente — bandas de respiro arriba y abajo */
.acto--papel {
  padding-top: 24vh;      /* la explosión blanquea (vacío de transición) */
  padding-bottom: 34vh;   /* T_S07-S08 anochece */
  background: linear-gradient(180deg,
    #0A0E1A 0,
    #8E97B0 11vh,
    #EEF3FF 19vh,          /* el destello */
    #F2F0EB 27vh,
    #F2F0EB calc(100% - 30vh),
    #B7B2A6 calc(100% - 18vh),
    #3A3F4A calc(100% - 8vh),
    #05070D 100%);
}
/* retícula de plano de estudio, solo en pleno día (enmascarada) */
.acto--papel::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(rgba(43, 47, 56, 0.05) 1px, transparent 1px) 0 0 / 56px 56px,
    linear-gradient(90deg, rgba(43, 47, 56, 0.05) 1px, transparent 1px) 0 0 / 56px 56px;
  mask-image: linear-gradient(180deg,
    transparent 22vh, #000 34vh,
    #000 calc(100% - 36vh), transparent calc(100% - 22vh));
}
/* viñeta cálida del papel */
.acto--papel::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%, transparent 55%, rgba(180, 172, 155, 0.4) 100%);
  mask-image: linear-gradient(180deg, transparent 20vh, #000 32vh,
    #000 calc(100% - 34vh), transparent calc(100% - 20vh));
}

/* Acto III · noche (S8–S20): del apagón al azul profundo del cierre */
.acto--noche2 {
  background:
    radial-gradient(1100px 700px at 22% 90vh, rgba(255, 61, 166, 0.025) 0%, transparent 55%),
    radial-gradient(1100px 800px at 85% 28%, rgba(157, 123, 255, 0.045) 0%, transparent 55%),
    radial-gradient(1000px 800px at 12% 62%, rgba(84, 207, 224, 0.03) 0%, transparent 55%),
    linear-gradient(180deg,
      #05070D 0,
      #05070D 110vh,
      #0A0E1A 220vh,
      #0A0E1A calc(100% - 220vh),
      #060910 calc(100% - 80vh),
      #060910 100%);
}

/* ---------- Sección base (transparente: el acto pinta) ---------- */
.sec {
  min-height: 100vh; position: relative;
  display: flex; align-items: center; justify-content: center; flex-direction: column;
  padding: 130px var(--gutter) 100px;
  background: transparent; color: var(--text);
  scroll-margin-top: 56px;
}
.sec--band { min-height: 54vh; }
.sec--half { min-height: 74vh; }

/* ---------- Micro-etiquetas HUD (punto + línea + mono) ---------- */
.spec {
  position: absolute; z-index: var(--z-contenido);
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-data); font-size: 0.625rem; letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--dim) 90%, transparent);
  pointer-events: none;
}
.spec::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%; flex: none;
  background: var(--accent); box-shadow: 0 0 9px var(--accent);
}
.spec::after {
  content: ""; width: 54px; height: 1px; flex: none;
  background: linear-gradient(90deg, currentColor, transparent); opacity: 0.5;
}
.spec--r { flex-direction: row-reverse; }
.spec--r::after { background: linear-gradient(270deg, currentColor, transparent); }

/* Marcador de zona de fondo (esqueleto; discreto) */
.f-tag {
  position: absolute; bottom: 26px; right: var(--gutter); z-index: var(--z-contenido);
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--dim) 55%, transparent);
  opacity: 0.8; pointer-events: none;
}

/* ---------- Kicker con índice ---------- */
.kicker { display: flex; align-items: center; gap: 13px; }
.kicker .idx {
  font-family: var(--font-data); font-weight: 400; font-size: 0.625rem;
  color: var(--dim); letter-spacing: 0.1em; padding: 2px 7px;
  border: 1px solid color-mix(in srgb, var(--dim) 28%, transparent);
  border-radius: 4px;
}
.kicker::after {
  content: ""; flex: 0 0 40px; height: 1px;
  background: linear-gradient(90deg, var(--accent), transparent); opacity: 0.65;
}

/* ============================================================
   RANURAS — marcos técnicos de plano
   ============================================================ */
.ranura {
  --rk: color-mix(in srgb, var(--dim) 55%, transparent);
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 200px;
}
.ranura::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(var(--rk), var(--rk)) top left / 24px 1px,
    linear-gradient(var(--rk), var(--rk)) top left / 1px 24px,
    linear-gradient(var(--rk), var(--rk)) top right / 24px 1px,
    linear-gradient(var(--rk), var(--rk)) top right / 1px 24px,
    linear-gradient(var(--rk), var(--rk)) bottom left / 24px 1px,
    linear-gradient(var(--rk), var(--rk)) bottom left / 1px 24px,
    linear-gradient(var(--rk), var(--rk)) bottom right / 24px 1px,
    linear-gradient(var(--rk), var(--rk)) bottom right / 1px 24px;
  background-repeat: no-repeat;
}
.ranura::after {
  content: ""; position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  width: 16px; height: 16px; pointer-events: none; opacity: 0.4;
  background:
    linear-gradient(var(--rk), var(--rk)) center / 100% 1px,
    linear-gradient(var(--rk), var(--rk)) center / 1px 100%;
  background-repeat: no-repeat;
}
.ranura__tag {
  position: absolute; bottom: 13px; left: 50%; translate: -50% 0;
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.1em;
  white-space: nowrap; color: var(--dim);
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--dim) 22%, transparent);
  border-radius: 99px; padding: 4px 12px;
  backdrop-filter: blur(6px);
}
.ranura--logo    { aspect-ratio: 1 / 1; max-width: min(42vh, 380px); min-height: 0; }
.ranura--logo-sm { aspect-ratio: 1 / 1; max-width: min(30vh, 250px); min-height: 0; }
.halo {
  position: absolute; width: 135%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, var(--glow) 0%, transparent 60%);
  pointer-events: none; z-index: -1;
  animation: halo-breathe 8s var(--ease-inout) infinite;
}
@keyframes halo-breathe {
  0%, 100% { opacity: 0.45; scale: 0.95; }
  50%      { opacity: 0.9;  scale: 1.03; }
}

/* ============================================================
   S1 · NAVBAR — mínima, precisa
   ============================================================ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-nav);
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 38px;
  transition: background 0.5s, border-color 0.5s, color 0.5s;
  border-bottom: 1px solid transparent;
  color: var(--obs-linea-n);
}
.nav.solid { backdrop-filter: blur(16px) saturate(1.15); }
.nav.solid[data-under="noche"] {
  background: color-mix(in srgb, #0B111F 72%, transparent);
  border-bottom-color: rgba(232, 236, 244, 0.07);
}
.nav.solid[data-under="papel"] {
  background: color-mix(in srgb, var(--obs-papel-2) 82%, transparent);
  border-bottom-color: rgba(43, 47, 56, 0.1);
  color: var(--obs-grafito-0);
}
.nav__brand {
  display: flex; align-items: center; gap: 11px;
  font-family: var(--font-display); font-weight: 600;
  letter-spacing: 0.26em; font-size: 0.75rem;
  color: inherit; text-decoration: none;
}
.nav__brand svg { width: 25px; height: 25px; stroke: currentColor; transition: transform 0.6s var(--ease-out); }
.nav__brand:hover svg { transform: rotate(90deg); }
.nav__links { display: flex; gap: 2px; }
.nav__links a {
  color: inherit; opacity: 0.62; text-decoration: none;
  font-size: 0.75rem; letter-spacing: 0.05em; padding: 8px 13px; border-radius: 99px;
  transition: opacity var(--dur-micro), background var(--dur-micro);
}
.nav__links a:hover { opacity: 1; background: color-mix(in srgb, currentColor 6%, transparent); }
.nav .btn--cta { padding: 8px 18px; }

/* ============================================================
   BOTONES v3 — píldoras con flecha
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-display); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; text-decoration: none;
  border-radius: 99px; padding: 12px 24px;
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s, background 0.3s, border-color 0.3s;
}
.btn:hover { transform: translateY(-2px); }
.btn--cta {
  background: var(--cta); color: var(--cta-text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18),
              0 8px 24px -10px rgba(194, 42, 40, 0.55);
}
.btn--cta:hover { background: var(--cta-hover); }
.btn--cta::after { content: "→"; font-family: var(--font-body); transition: translate 0.3s var(--ease-out); }
.btn--cta:hover::after { translate: 3px 0; }
.btn--ghost {
  border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
  color: var(--title); background: transparent;
}
.btn--ghost:hover {
  border-color: color-mix(in srgb, currentColor 45%, transparent);
  background: color-mix(in srgb, currentColor 5%, transparent);
}

/* ============================================================
   S2 · HERO
   ============================================================ */
.hero { padding-bottom: 0; }
.stars, .stars2 { position: absolute; inset: 0; background-repeat: repeat; }
.stars {
  background-image:
    radial-gradient(1px 1px at 20px 30px, #fff, transparent),
    radial-gradient(1px 1px at 90px 140px, #dfe7ff, transparent),
    radial-gradient(1.5px 1.5px at 160px 60px, #fff, transparent),
    radial-gradient(1px 1px at 240px 190px, #c9d6ff, transparent),
    radial-gradient(1px 1px at 310px 90px, #fff, transparent);
  background-size: 360px 240px;
  animation: twinkle 6s ease-in-out infinite alternate;
}
.stars2 {
  background-image:
    radial-gradient(1px 1px at 60px 80px, #aebadd, transparent),
    radial-gradient(1px 1px at 180px 20px, #fff, transparent),
    radial-gradient(1px 1px at 280px 150px, #dfe7ff, transparent);
  background-size: 420px 300px;
  animation: twinkle 8s ease-in-out infinite alternate-reverse;
}
@keyframes twinkle { from { opacity: 0.4; } to { opacity: 0.85; } }
.milky {
  position: absolute; inset: -10%;
  background: linear-gradient(115deg, transparent 38%,
    rgba(190, 205, 240, 0.04) 45%, rgba(220, 230, 255, 0.085) 52%,
    rgba(190, 205, 240, 0.04) 59%, transparent 66%);
}
.ridge { position: absolute; bottom: -2px; left: 0; width: 100%; height: 34vh; z-index: 1; }
.hero__slot { z-index: var(--z-objeto); margin-bottom: 10vh; animation: floaty 9s var(--ease-inout) infinite; }
@keyframes floaty { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
.hero__title { position: absolute; left: var(--gutter); bottom: 12vh; z-index: var(--z-contenido); }
.hero__title .pre {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-data); color: var(--dim);
  font-size: 0.6875rem; letter-spacing: 0.22em; text-transform: uppercase;
  margin-bottom: 16px;
}
.hero__title .pre .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 12px var(--accent);
  animation: dot-pulse 3s ease-in-out infinite;
}
@keyframes dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.hero__title h1 { letter-spacing: -0.015em; }
.hero__title h1 .sw {
  background: linear-gradient(180deg, #FFFFFF 52%, #8FA0C6 135%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* palabra fantasma (ref. Unwind) */
.hero__title h1 .gw {
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(238, 243, 255, 0.34);
}
.hero__ctas { margin-top: 30px; display: flex; gap: 14px; flex-wrap: wrap; }
.hero__aside {
  position: absolute; right: var(--gutter); bottom: 13vh; z-index: var(--z-contenido);
  max-width: 270px; color: var(--dim); font-size: 0.8125rem;
  line-height: 1.75; text-align: right;
}
.hero__aside::before {
  content: ""; display: block; margin: 0 0 16px auto; width: 40px; height: 1px;
  background: linear-gradient(270deg, var(--accent), transparent);
}
.hero__scroll {
  position: absolute; bottom: 4vh; left: 50%; translate: -50% 0; z-index: var(--z-contenido);
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.34em;
  text-transform: uppercase; color: var(--dim); text-decoration: none;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.hero__scroll::after {
  content: ""; width: 1px; height: 36px;
  background: linear-gradient(180deg, var(--dim), transparent);
  animation: scroll-hint 2.4s var(--ease-inout) infinite;
}
@keyframes scroll-hint {
  0% { transform: scaleY(0); transform-origin: top; }
  45% { transform: scaleY(1); transform-origin: top; }
  55% { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* ============================================================
   S3 · BRAND REVEAL
   ============================================================ */
.ghost {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(80px, 16vw, 230px); letter-spacing: 0.05em;
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--obs-neon) 6.5%, transparent);
  user-select: none; white-space: nowrap; z-index: 0;
}
.corner-tl, .corner-br {
  position: absolute; z-index: var(--z-contenido);
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--fs-h3); color: var(--title); letter-spacing: 0;
}
.corner-tl { top: 17vh; left: var(--gutter); }
.corner-br { bottom: 15vh; right: var(--gutter); text-align: right; }
.corner-tl small, .corner-br small {
  display: block; font-family: var(--font-data); font-weight: 400;
  font-size: 0.625rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--dim); margin-top: 9px;
}
.hud-note {
  position: absolute; font-family: var(--font-data); font-size: 0.625rem;
  letter-spacing: 0.14em; color: color-mix(in srgb, var(--obs-cian) 55%, transparent);
  animation: hud-blink 7s steps(1) infinite; pointer-events: none;
}
@keyframes hud-blink { 0%, 78%, 100% { opacity: 0.8; } 82%, 90% { opacity: 0.15; } }

/* ============================================================
   S3 · NOTAS DE DATOS sobre el cerro (2026-07-20)
   Punto de anclaje + línea guía + dato. Aparecen y desaparecen
   en ciclos desfasados (--d) para que el fondo "se lea" solo.
   ============================================================ */
/* viven dentro del lienzo FIJO → coordenadas de pantalla, ancladas al cerro.
   Su opacidad la gobierna el scroll (aparecen con el dibujo de líneas). */
.dnotes { position: absolute; inset: 0; z-index: 6; pointer-events: none; opacity: 0; }
/* la nota se ancla EN el punto que señala (tamaño cero); de ahí sale una guía
   QUEBRADA: tramo diagonal (--r) + tramo horizontal (--h) + el dato */
.dnote {
  position: absolute; width: 0; height: 0;
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.16em;
  text-transform: uppercase; white-space: nowrap;
  opacity: 0; animation: dnote-cycle 16s ease-in-out infinite; animation-delay: var(--d, 0s);
  --cos: 0.788; --sin: 0.616;          /* codo a 38° */
}
.dnote i {                             /* punto de anclaje sobre el dibujo */
  position: absolute; left: -3px; top: -3px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 10px var(--accent), 0 0 3px #fff inset;
}
.dnote u { position: absolute; height: 1px; display: block;
  background: color-mix(in srgb, var(--obs-cian) 70%, transparent); }
.dnote u.d {                           /* tramo diagonal desde el punto */
  left: 0; top: 0; width: var(--r, 110px);
  transform-origin: 0 50%; transform: rotate(-38deg);
}
.dnote u.h {                           /* tramo horizontal (el quiebre) */
  left: calc(var(--r, 110px) * var(--cos));
  top: calc(var(--r, 110px) * var(--sin) * -1);
  width: var(--h, 48px);
}
.dnote em {                            /* el dato, al final de la guía */
  position: absolute; font-style: normal;
  left: calc(var(--r, 110px) * var(--cos) + var(--h, 48px) + 9px);
  top: calc(var(--r, 110px) * var(--sin) * -1);
  transform: translateY(-50%);
}
.dnote b { font-weight: 700; color: color-mix(in srgb, var(--text) 88%, transparent); }
.dnote span { margin-left: 9px; color: color-mix(in srgb, var(--obs-cian) 60%, transparent); }

/* variante: el codo sale hacia la IZQUIERDA */
.dnote--l u.d { transform: rotate(-142deg); }
.dnote--l u.h { left: calc(var(--r, 110px) * var(--cos) * -1 - var(--h, 48px)); }
.dnote--l em {
  left: calc((var(--r, 110px) * var(--cos) + var(--h, 48px) + 9px) * -1);
  transform: translate(-100%, -50%);
}

@keyframes dnote-cycle {
  0%, 100% { opacity: 0; }
  4%       { opacity: 0.15; }          /* parpadeo de encendido */
  6%       { opacity: 0.9; }
  8%       { opacity: 0.35; }
  10%, 30% { opacity: 0.9; }
  34%      { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .dnote { animation: none; opacity: 0.8; }
}
@media (max-width: 860px) { .dnotes { display: none; } }

/* ============================================================
   S4–S7 · ÁREAS — vidrio con oficio
   ============================================================ */
.area__inner {
  display: grid; grid-template-columns: 1.08fr 1fr; gap: 7vw;
  align-items: center; width: 100%; max-width: var(--max-w);
}
.area__inner.flip { grid-template-columns: 1fr 1.08fr; }
.area__inner.flip .area-card { order: -1; }
.area-card {
  position: relative; padding: 50px 48px;
  background: linear-gradient(168deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-card);
  backdrop-filter: blur(16px) saturate(1.05);
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    0 34px 64px -38px var(--glass-shadow);
  transition: transform 0.55s var(--ease-out), box-shadow 0.55s var(--ease-out), border-color 0.55s;
}
.area-card:hover {
  transform: translateY(-5px);
  border-color: color-mix(in srgb, var(--obs-lila) 30%, var(--glass-line));
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    0 40px 72px -40px var(--glass-shadow),
    0 -22px 52px -36px var(--obs-lila);
}
.area-card::before {
  content: ""; position: absolute; top: 18px; right: 18px; width: 15px; height: 15px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
  transition: width 0.4s var(--ease-out), height 0.4s var(--ease-out);
}
.area-card:hover::before { width: 26px; height: 26px; }
.area-card h2 { margin: 12px 0 4px; }
.area-card .meaning {
  font-family: var(--font-data); color: var(--dim);
  font-size: 0.625rem; letter-spacing: 0.12em; margin-bottom: 24px;
}
.area-card .lead { margin-bottom: 10px; }
.area-card p:not(.lead) { max-width: 44ch; color: var(--dim); }
.area-card .btn { margin-top: 32px; }
.area-fig { display: flex; align-items: center; justify-content: center; position: relative; }

/* ============================================================
   S8 · CRASH — fuera de sistema (texturas con fundido, sin cortes)
   ============================================================ */
.crash::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.3;
  background: repeating-linear-gradient(0deg,
    rgba(238, 243, 255, 0.025) 0 1px, transparent 1px 5px);
  mask-image: linear-gradient(180deg, transparent, #000 18%, #000 82%, transparent);
}
.crash::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(720px 420px at 30% 26%, rgba(255, 61, 166, 0.05) 0%, transparent 60%),
    radial-gradient(680px 440px at 74% 74%, rgba(46, 242, 242, 0.04) 0%, transparent 60%);
}
.crash > * { z-index: 1; }
.crash .err {
  font-family: var(--font-data); text-align: center; line-height: 2.1;
  color: var(--obs-err-cian); font-size: var(--fs-small);
}
.crash .err b {
  display: block; color: var(--obs-err-magenta);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem); letter-spacing: 0.04em;
  text-shadow: 2px 0 0 rgba(46, 242, 242, 0.55), -2px 0 0 rgba(255, 61, 166, 0.55);
  margin-bottom: 6px;
}
.crash .err .cursor { animation: caret 1.1s steps(1) infinite; }
@keyframes caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.crash .err small { color: var(--obs-tenue-n); font-size: 0.6875rem; }

/* ============================================================
   S9–S12 · BANDAS (documento 2D — paneles deliberados) + carrusel
   ============================================================ */
.mat-panel { border-block: 1px solid var(--mat-panel-line); }
.band-head { text-align: center; z-index: 1; }
.band-head h2 { margin-top: 12px; }
.band-head .kicker, .manifiesto .kicker, .planes-head .kicker { justify-content: center; }
.band-head .kicker::after, .manifiesto .kicker::after, .planes-head .kicker::after { display: none; }

.carrusel {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
  width: 100%; max-width: var(--max-w); z-index: 1;
}
.carrusel .card {
  position: relative; padding: 32px 30px; min-height: 230px;
  background: linear-gradient(168deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
  border: 1px solid var(--glass-line); border-radius: 18px;
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  transition: transform 0.5s var(--ease-out), border-color 0.5s;
}
.carrusel .card:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--obs-lila) 28%, var(--glass-line));
}
.carrusel .card .tag {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--obs-lila-bright);
}
.carrusel .card .tag::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--obs-lila) 30%, transparent), transparent);
}
.carrusel .card h3 { font-size: var(--fs-lead); margin: 16px 0 8px; }
.carrusel .card p { color: var(--dim); font-size: var(--fs-small); }

.manifiesto { text-align: center; max-width: 860px; z-index: 1; }
.manifiesto h2 {
  font-weight: 500; line-height: 1.32; margin-top: 16px;
  font-size: clamp(1.75rem, 3.2vw, 2.75rem);
}
.manifiesto h2 em { font-style: normal; color: var(--obs-lila-bright); }

/* ============================================================
   S13 · IDENTIDAD
   ============================================================ */
.identidad {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 5vw;
  align-items: center; width: 100%; max-width: var(--max-w);
}
.identidad .col h3 {
  font-size: 0.6875rem; letter-spacing: 0.3em; text-transform: uppercase;
  font-weight: 500; color: var(--accent); margin-bottom: 18px;
}
.identidad .col p { color: var(--dim); font-size: var(--fs-small); max-width: 32ch; line-height: 1.8; }
.identidad .col--r { text-align: right; }
.identidad .col--r p { margin-left: auto; }

.split {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7vw;
  align-items: center; width: 100%; max-width: var(--max-w);
}
.split h2 { margin: 12px 0 18px; }
.split p { max-width: 50ch; color: var(--dim); line-height: 1.8; }

/* ============================================================
   S17 · SUSCRIPCIONES
   ============================================================ */
.planes-head { text-align: center; margin-bottom: 48px; }
.planes-head h2 { margin-top: 12px; }
.planes {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
  width: 100%; max-width: var(--max-w); align-items: stretch;
}
.plan {
  position: relative; padding: 42px 34px; text-align: center;
  background: linear-gradient(168deg, var(--glass-fill) 0%, var(--glass-fill-2) 100%);
  border: 1px solid var(--glass-line); border-radius: var(--r-card);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  transition: transform 0.5s var(--ease-out), border-color 0.5s, box-shadow 0.5s;
}
.plan:hover { transform: translateY(-5px); }
.plan--featured {
  border-color: color-mix(in srgb, var(--obs-lila) 38%, var(--glass-line));
  background: linear-gradient(175deg,
    color-mix(in srgb, var(--obs-lila) 8%, transparent) 0%, var(--glass-fill-2) 50%);
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 26px 56px -34px var(--obs-lila-deep);
}
.plan--featured::before {
  content: "Recomendado"; position: absolute; top: -11px; left: 50%; translate: -50% 0;
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: #fff;
  background: var(--obs-lila-deep); border-radius: 99px; padding: 4px 14px;
}
.plan h3 {
  font-size: 0.6875rem; letter-spacing: 0.28em; text-transform: uppercase;
  font-weight: 500; color: var(--dim);
}
.plan .precio {
  font-family: var(--font-display); font-size: var(--fs-h2);
  color: var(--title); font-weight: 700; margin-top: 16px;
}
.plan .precio small { font-size: var(--fs-small); color: var(--dim); font-weight: 400; }
.plan ul {
  list-style: none; margin: 26px 0 32px; color: var(--dim);
  font-size: var(--fs-small); line-height: 2.4;
}
.plan ul li:not(:last-child) {
  border-bottom: 1px solid color-mix(in srgb, var(--dim) 10%, transparent);
}

/* ============================================================
   S18 · SELLO + reflejo
   ============================================================ */
.sello-wrap { display: flex; flex-direction: column; align-items: center; }
.sello-sq {
  width: 96px; height: 96px;
  border: 1.5px solid var(--obs-neon);
  box-shadow: 0 0 18px rgba(238, 243, 255, 0.16), inset 0 0 14px rgba(238, 243, 255, 0.05);
  animation: sello-pulso 5s var(--ease-inout) infinite;
}
.sello-reflejo {
  width: 96px; height: 96px; margin-top: 12px;
  border: 1.5px solid var(--obs-neon);
  transform: scaleY(-0.85) skewX(3deg);
  mask-image: linear-gradient(180deg, transparent 12%, #000 100%);
  opacity: 0.13; filter: blur(1.5px);
  animation: sello-pulso 5s var(--ease-inout) infinite;
}
@keyframes sello-pulso {
  0%, 100% { box-shadow: 0 0 14px rgba(238, 243, 255, 0.1); opacity: 0.85; }
  50%      { box-shadow: 0 0 30px rgba(238, 243, 255, 0.3); opacity: 1; }
}
/* ⚠️ LA ÚNICA QUE SE HABÍA QUEDADO SIN CUBRIR (2026-08-17). Contadas en la
   página, de S8 a S20 corren ocho animaciones infinitas y siete respetaban ya
   `prefers-reduced-motion`; el sello de S18 no. Se para en su punto medio —con
   el resplandor puesto, no apagado— para que quien pida menos movimiento vea el
   sello igual de acabado, sólo que quieto. */
@media (prefers-reduced-motion: reduce) {
  .sello-sq, .sello-reflejo { animation: none !important; }
}

/* ============================================================
   S19–S20 · SOCIAL + CONTACTO (el acto pinta el fondo profundo)
   ============================================================ */
.social { display: flex; gap: 13px; }
.social a {
  color: var(--dim); text-decoration: none;
  font-family: var(--font-display); font-size: 0.75rem;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  border: 1px solid color-mix(in srgb, var(--dim) 24%, transparent);
  border-radius: 99px; padding: 12px 26px;
  transition: color var(--dur-micro), border-color var(--dur-micro), transform var(--dur-micro);
}
.social a:hover { color: var(--title); border-color: var(--dim); transform: translateY(-2px); }

.contacto {
  display: grid; grid-template-columns: 1.1fr 1fr; gap: 7vw;
  width: 100%; max-width: var(--max-w); align-items: start;
}
.contacto h2 { font-size: clamp(2.5rem, 5vw, 4.5rem); margin: 14px 0 24px; letter-spacing: -0.015em; }
.contacto .addr { color: var(--dim); font-size: var(--fs-small); line-height: 2.2; }
.contacto .addr a {
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--obs-lila) 40%, transparent);
  transition: border-color var(--dur-micro), color var(--dur-micro);
}
.contacto .addr a:hover { color: var(--obs-lila-bright); border-color: var(--obs-lila-bright); }
.form { display: grid; gap: 13px; }
.form input, .form textarea {
  background: color-mix(in srgb, var(--obs-noche-2) 40%, transparent);
  border: 1px solid var(--glass-line);
  border-radius: 12px; padding: 15px 18px;
  color: var(--text); font-family: var(--font-body); font-size: var(--fs-small);
  transition: border-color var(--dur-micro), background var(--dur-micro);
}
.form input:focus, .form textarea:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--obs-lila) 50%, transparent);
  background: color-mix(in srgb, var(--obs-noche-2) 65%, transparent);
}
.form input::placeholder, .form textarea::placeholder { color: var(--dim); }
.form textarea { min-height: 120px; resize: vertical; }
.form .btn { justify-self: start; border: 0; cursor: pointer; }

.colophon {
  display: flex; justify-content: space-between; gap: 22px; flex-wrap: wrap;
  width: 100%; max-width: var(--max-w);
  margin-top: 90px; padding-top: 26px;
  border-top: 1px solid color-mix(in srgb, var(--dim) 13%, transparent);
  color: var(--dim); font-size: 0.6875rem; letter-spacing: 0.08em;
}

/* Aviso de etapa */
.stage-badge {
  position: fixed; bottom: 14px; left: 14px; z-index: var(--z-overlay);
  font-family: var(--font-data); font-size: 0.5625rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--obs-tenue-n);
  border: 1px solid rgba(138, 148, 168, 0.25);
  padding: 6px 11px; border-radius: 99px;
  background: rgba(10, 14, 26, 0.82); backdrop-filter: blur(8px);
}

/* ---------- Reveal: desenfoque → nitidez, hijos en cascada ---------- */
.reveal {
  opacity: 0; transform: translateY(24px); filter: blur(7px);
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out), filter 0.9s var(--ease-out);
}
.reveal.on { opacity: 1; transform: none; filter: none; }
.reveal > * { transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out); }
.reveal:not(.on) > * { opacity: 0; transform: translateY(12px); }
.reveal.on > * { opacity: 1; transform: none; }
.reveal.on > *:nth-child(2) { transition-delay: 0.08s; }
.reveal.on > *:nth-child(3) { transition-delay: 0.16s; }
.reveal.on > *:nth-child(4) { transition-delay: 0.24s; }
.reveal.on > *:nth-child(5) { transition-delay: 0.32s; }
.reveal.on > *:nth-child(6) { transition-delay: 0.4s; }

/* ---------- Responsive ---------- */
@media (max-width: 860px) {
  .nav { padding: 11px 18px; }
  .nav__links { display: none; }
  .area__inner, .area__inner.flip, .split, .contacto,
  .carrusel, .planes { grid-template-columns: 1fr; }
  .area__inner.flip .area-card { order: 0; }
  .identidad { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .identidad .col--r { text-align: center; }
  .hero__aside { display: none; }
  .hero__title { bottom: 15vh; }
  .corner-tl, .corner-br { position: static; margin: 14px 0; text-align: center; }
  .spec { display: none; }
  .acto--papel { padding-top: 18vh; padding-bottom: 26vh; }
}

/* ============================================================
   RESCATES DEL PACK (2026-07-15) — técnicas de código
   ============================================================ */

/* ---------- Cursor personalizado: punto coral + anillo con retardo ---------- */
@media (pointer: fine) {
  body.cursor-on, body.cursor-on a, body.cursor-on button { cursor: none; }
  .cur-dot, .cur-ring {
    position: fixed; top: 0; left: 0; z-index: 100; pointer-events: none;
    border-radius: 50%; translate: -50% -50%;
  }
  .cur-dot {
    width: 6px; height: 6px; background: var(--obs-coral);
    box-shadow: 0 0 10px rgba(224, 90, 78, 0.6);
  }
  .cur-ring {
    width: 34px; height: 34px;
    border: 1px solid color-mix(in srgb, var(--obs-coral) 55%, transparent);
    transition: width 0.25s var(--ease-out), height 0.25s var(--ease-out),
                border-color 0.25s, opacity 0.25s;
  }
  body.cursor-hover .cur-ring {
    width: 52px; height: 52px;
    border-color: color-mix(in srgb, var(--obs-lila) 70%, transparent);
  }
}
@media (pointer: coarse) { .cur-dot, .cur-ring { display: none; } }

/* ---------- HUD de progreso (medidor de descenso) ---------- */
.progress {
  position: fixed; right: 22px; top: 50%; translate: 0 -50%;
  z-index: var(--z-nav); pointer-events: none;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.progress__code {
  font-family: var(--font-data); font-size: 0.625rem; letter-spacing: 0.14em;
  color: var(--obs-cian); writing-mode: vertical-rl;
  text-shadow: 0 0 12px rgba(84, 207, 224, 0.35);
}
.progress__rail {
  width: 1px; height: 30vh; position: relative;
  background: color-mix(in srgb, var(--obs-tenue-n) 30%, transparent);
}
.progress__fill {
  position: absolute; top: 0; left: -0.5px; width: 2px; height: 0%;
  background: linear-gradient(180deg, var(--obs-lila), var(--obs-cian));
  box-shadow: 0 0 8px rgba(157, 123, 255, 0.5);
}
@media (max-width: 860px) { .progress { display: none; } }

/* ---------- Manifiesto cinético (palabra a palabra) ---------- */
.kinetic { display: block; }
.kinetic .w {
  display: inline-block; opacity: 0.12;
  transform: translateY(0.25em);
  filter: blur(4px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out), filter 0.7s var(--ease-out);
  transition-delay: calc(var(--i) * 0.14s);
}
.reveal.on .kinetic .w { opacity: 1; transform: none; filter: none; }

/* ---------- Marquee de marca ---------- */
.marquee {
  position: absolute; bottom: 0; left: 0; right: 0; overflow: hidden;
  padding: 13px 0; pointer-events: none;
  border-top: 1px solid var(--mat-panel-line);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track {
  display: flex; gap: 3.5rem; width: max-content;
  animation: marquee 36s linear infinite;
  font-family: var(--font-data); font-size: 0.625rem; letter-spacing: 0.3em;
  text-transform: uppercase; color: color-mix(in srgb, var(--dim) 70%, transparent);
  white-space: nowrap;
}
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  .cur-dot, .cur-ring { display: none; }
  body.cursor-on, body.cursor-on a, body.cursor-on button { cursor: auto; }
  .kinetic .w { opacity: 1; transform: none; filter: none; }
  .marquee__track { animation: none; }
}

/* ============================================================
   S2 EN CÓDIGO — cubo MAE vivo: respiración + linterna (D-032)
   La dirección real del proyecto: objetos = código, videos = previz.
   ============================================================ */

.mae-cube {
  position: relative; width: min(42vh, 380px); aspect-ratio: 1 / 1;
  --mx: 50%; --my: 42%;        /* posición de la linterna (JS) */
  --lamp: 0;                    /* intensidad 0-1 (JS: hover del hero) */
}
.mae-cube svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* capa base: siempre visible, tenue */
.mae-cube__base .cage { opacity: 0.4; }
.mae-cube__base .seams { animation: seams-breathe 7s var(--ease-inout) infinite; }
@keyframes seams-breathe {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 0.85; }
}
.mae-cube__base .inner {
  transform-box: fill-box; transform-origin: center;
  animation: cube-breathe 7s var(--ease-inout) infinite;
}
@keyframes cube-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.015); }
}

/* capa linterna: jaula brillante revelada solo alrededor del cursor */
.mae-cube__bright {
  opacity: var(--lamp);
  transition: opacity 0.5s var(--ease-out);
  mask-image: radial-gradient(circle 130px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.35) 55%, transparent 100%);
  -webkit-mask-image: radial-gradient(circle 130px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.35) 55%, transparent 100%);
}

@media (prefers-reduced-motion: reduce) {
  .mae-cube__base .cage { opacity: 0.75; }   /* sin linterna: jaula más visible de base */
  .mae-cube__bright { display: none; }
}

/* ============================================================
   S2 · CICLO DE REPOSO (máquina de estados, 2026-07-16)
   cubo (quieto) → ida → glitch (quieto) → vuelta → repite
   ============================================================ */
.idle-cycle { position: relative; width: min(42vh, 380px); aspect-ratio: 1 / 1; }
/* flotación permanente (contención interactiva 2026-07-18): el conjunto
   video+jaula respira en el aire; el mouse es quien descontiene */
@keyframes cubeFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
.idle-cycle { animation: cubeFloat 7s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .idle-cycle { animation: none !important; } }
/* (reglas de video de la era luma-key retiradas — los videos v3 usan .cycle-vid) */

/* ráfaga de glitch: tapa el salto de estado cuando el scroll exige llegar YA */
.glitch-flash {
  position: absolute; inset: -8%; pointer-events: none; opacity: 0; z-index: 3;
  background:
    repeating-linear-gradient(0deg,
      rgba(255, 61, 166, 0.35) 0 3px, transparent 3px 11px,
      rgba(46, 242, 242, 0.3) 11px 13px, transparent 13px 23px);
  mix-blend-mode: screen;
}
.glitch-flash.on { animation: flash-burst 0.16s steps(3) 1; }
@keyframes flash-burst {
  0% { opacity: 1; transform: translateX(-4px); }
  50% { opacity: 0.7; transform: translateX(5px); }
  100% { opacity: 0; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .glitch-flash { display: none !important; }
}

/* ============================================================
   S2 · JAULA INTERACTIVA (2026-07-16; el luma-key fue retirado)
   ============================================================ */

.cage-overlay {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; overflow: visible;
  --mx: 50%; --my: 45%; --lamp: 0;
}
.cage-ref { fill: none; stroke: none; }
/* capa linterna: solo visible alrededor del cursor */
.cage-glow path {
  fill: none; stroke: #FFFFFF; stroke-width: 3;
  filter: drop-shadow(0 0 5px rgba(238, 243, 255, 0.9));
}
.cage-glow {
  opacity: var(--lamp);
  transition: opacity 0.4s var(--ease-out);
  mask-image: radial-gradient(circle 120px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.3) 60%, transparent 100%);
  -webkit-mask-image: radial-gradient(circle 120px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.3) 60%, transparent 100%);
}
/* pulsos que recorren las aristas en reposo */
.cage-dot {
  fill: #EEF3FF; filter: url(#dotGlow);
  opacity: calc(0.9 - var(--lamp) * 0.9);   /* si la linterna manda, los pulsos ceden */
}
.cage-dot--small { fill: #B9A3FF; }

@media (prefers-reduced-motion: reduce) {
  #keyCanvas, .cage-overlay { display: none !important; }
}

/* ============================================================
   S2 · JAULA v2 — calco de Mau + brillo constante + nudo de luz
   (2026-07-17)
   ============================================================ */
/* brillo constante: la jaula SIEMPRE encendida como el logo original */
.cage-base path {
  fill: none; stroke: #EEF3FF; stroke-width: 6;   /* espesor dictado por Mau (Figma) */
  stroke-linecap: round;
}
/* elegido por Mau (2026-07-18): línea al brillo MÁXIMO constante (nitidez 4px);
   el RESPLANDOR vive en .cage-halo y PALPITA solo (máximo↔nulo, ~3.4s,
   independiente del mouse) */
.cage-base path {
  opacity: 1;
  filter: drop-shadow(0 0 4px rgba(238, 243, 255, 1));
}
.cage-halo path { fill: none; stroke: #EEF3FF; stroke-width: 9; filter: blur(13px); }
.cage-halo { opacity: 0; animation: cageBreath 3.4s ease-in-out infinite; }
@keyframes cageBreath { 0%, 100% { opacity: 0; } 50% { opacity: 0.95; } }
@media (prefers-reduced-motion: reduce) { .cage-halo { animation: none; opacity: 0.5; } }
/* el nudo: núcleo + estelas alargadas a lo largo de la línea */
.cage-knot { pointer-events: none; }
.knot-core { fill: #FFFFFF; filter: url(#dotGlow); }
.knot-mid  { opacity: 0.9; }
.knot-tail { opacity: 0.75; }

/* ============================================================
   S2 · ESTRELLA FUGAZ (v3 del viajero) — la luz fundida en la línea
   ============================================================ */
/* HAZ DE LUZ (pedido de Mau 2026-07-18): desenfoque máximo — la línea/punto
   desaparece como trazo y solo queda un resplandor que viaja por la arista */
.shoot path { fill: none; stroke-linecap: round; }
.shoot__tail {
  stroke: #9DBFFF; stroke-width: 16; opacity: 0.5;
  filter: blur(16px);
}
.shoot__mid {
  stroke: #DFEBFF; stroke-width: 11; opacity: 0.8;
  filter: blur(8px);
}
.shoot__core {
  stroke: #FFFFFF; stroke-width: 7; opacity: 1;
  filter: blur(3px) drop-shadow(0 0 7px rgba(255, 255, 255, 0.9));
}

/* ============================================================
   S2 · CICLO v2 SIN JAULA (interino stills, 2026-07-17)
   ============================================================ */
.cycle-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; opacity: 0;
  transition: opacity 0.9s var(--ease-inout);
  pointer-events: none;
}
.cycle-img.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .cycle-img { transition: none !important; }
  .cycle-img--cubo { opacity: 1 !important; }
  .cycle-img--glitch { opacity: 0 !important; }
}

/* ============================================================
   S2 · CICLO v3 — videos reales sin jaula (2026-07-18)
   Fondo del video ≈ fondo de la web: máscara radial funde bordes
   ============================================================ */
.cycle-vid {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; opacity: 0;
  transition: opacity 0.35s var(--ease-inout);
  pointer-events: none;
  mask-image: radial-gradient(ellipse 43% 46% at 50% 50%, #000 82%, transparent 99%);
  -webkit-mask-image: radial-gradient(ellipse 43% 46% at 50% 50%, #000 82%, transparent 99%);
}
.cycle-vid.is-on { opacity: 1; }
/* en modo video, el still del cubo solo es fallback */
.idle-cycle.video-mode .cycle-img { opacity: 0 !important; }

@media (prefers-reduced-motion: reduce) {
  .cycle-vid { display: none !important; }
}

/* Suavizado de reproducción: capas de video promovidas a GPU */
.cycle-vid {
  will-change: opacity;
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* ============================================================
   F01 · EL ILLIMANI REAL EN EL HERO (2026-07-18)
   ============================================================ */
.hero__bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 62%;
  z-index: 0;
}
/* F01_ANIM: las nubes reales encima del still — mismo montaje, fundido al llegar */
.hero__bg--anim { opacity: 0; transition: opacity 1.6s ease; }
.hero__bg--anim.is-live { opacity: 1; }
/* fusión con el acto: garantiza navy puro arriba (navbar) y abajo (paso a S3) */
.hero__bg-fusion {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, #0A0E1A 0%, rgba(10, 14, 26, 0) 22%),
    linear-gradient(0deg, #0A0E1A 0%, rgba(10, 14, 26, 0) 16%);
}
/* las estrellas acompañan al cielo real, discretas */
.hero .stars, .hero .stars2 { z-index: 2; opacity: 0.5; }

/* aura oscura tras el cubo: cama para el fondo plano de los videos
   sobre el cielo fotográfico (sin ella, el rectángulo del video se nota) */
.cube-aura {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  width: 100%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle,
    rgba(8, 11, 20, 0.05) 34%,
    rgba(8, 11, 20, 0.02) 46%,
    transparent 54%);
  pointer-events: none; z-index: -2;
}

/* ============================================================
   S2 · LUMA-KEY v2 (2026-07-18) — fondo del video transparente
   de verdad; los <video> vuelven a ser solo fuentes de píxeles
   ============================================================ */
.cycle-vid { display: none !important; mask-image: none; -webkit-mask-image: none; }
.key-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block;
  will-change: contents; transform: translateZ(0);
  transition: filter 0.35s var(--ease-out);
}
/* caos espeso PROGRESIVO: mouse sobre el cubo — --chaos (0→1 en ~7s, JS)
   escala saturación/contraste; el playbackRate del loop sube en paralelo */
.idle-cycle { --chaos: 0; }
.idle-cycle.caos-denso .key-canvas {
  filter: saturate(calc(1.2 + 0.5 * var(--chaos)))
          contrast(calc(1.04 + 0.1 * var(--chaos)))
          brightness(calc(1.03 + 0.09 * var(--chaos)));
}
.idle-cycle.no-webgl .key-canvas { display: none; }
.idle-cycle.no-webgl .cycle-img--cubo { opacity: 1 !important; }
@media (prefers-reduced-motion: reduce) { .key-canvas { display: none !important; } }
