/* ==========================================================================
   PANDEMIC — Design System v3
   Dirección: infraestructura tecnológica premium. Editorial, con profundidad,
   capas y movimiento que explica. No plantilla SaaS, no glow azul en todo.

   La pieza central es el SISTEMA DE AMBIENTES: el fondo no cambia de golpe
   entre secciones. Un lienzo fijo interpola color mientras el scroll avanza
   (un IntersectionObserver escribe data-env en <html>), y encima algunas
   secciones hacen crecer superficies que se convierten en el fondo siguiente.
   ========================================================================== */

/* ─── Tipografía autoalojada ─────────────────────────────────────────────── */
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ─── Reset ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
img, picture, svg, video { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
ul, ol { list-style: none; padding: 0; }

/* ─── Paleta base ───────────────────────────────────────────────────────── */
:root {
  --blue-50:  #EEF4FF;
  --blue-100: #DAE7FF;
  --blue-200: #B9D0FF;
  --blue-300: #8AB0FF;
  --blue-400: #5A90FF;
  --blue-500: #2D7CFF;
  --blue-600: #1560F0;
  --blue-700: #0E48C4;
  --blue-900: #0A2A73;

  /* Neutros fríos con sesgo azul — nunca gris puro */
  --ink-1000: #05080F;
  --ink-950:  #080C16;
  --ink-900:  #0B1020;
  --ink-850:  #0E1526;
  --ink-800:  #121B31;
  --ink-700:  #2A3550;
  --ink-500:  #566384;
  --ink-400:  #7A87A6;
  --ink-300:  #9BA6C0;
  --ink-200:  #C4CCDF;
  --ink-100:  #E3E8F2;
  --ink-50:   #F1F4FA;
  --white:    #FFFFFF;

  /* Sin naranja en ningún punto del sistema: el capítulo de casos usa un
     azul muy frío, no una temperatura cálida. */

  --green-500: #17B87A;
  --red-500:   #E0455F;

  /* ── Ambiente por defecto (01 · claro / frío / premium) ── */
  --env-bg:      #F4F7FC;
  --env-bg-2:    #EAF0FA;
  --surface:     #FFFFFF;
  --surface-2:   #F1F5FC;
  --surface-in:  rgba(255,255,255,.72);
  --text:        var(--ink-900);
  --text-2:      var(--ink-700);
  --text-3:      var(--ink-500);
  --text-mute:   var(--ink-400);
  --line:        rgba(20,32,64,.10);
  --line-2:      rgba(20,32,64,.18);
  --accent:      var(--blue-600);
  --accent-2:    var(--blue-500);
  --accent-soft: var(--blue-50);
  --on-accent:   #FFFFFF;
  --shadow-1: 0 1px 2px rgba(11,16,32,.04), 0 8px 24px -12px rgba(11,16,32,.18);
  --shadow-2: 0 2px 4px rgba(11,16,32,.05), 0 24px 56px -20px rgba(11,16,32,.30);
  --shadow-3: 0 40px 90px -30px rgba(11,16,32,.42);
  --grain-op: .035;

  --font-sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Escala fluida, mobile-first */
  --fs-micro: .6875rem;
  --fs-xs:    .75rem;
  --fs-sm:    .875rem;
  --fs-base:  1rem;
  --fs-md:    clamp(1.0625rem, 1rem + .3vw, 1.1875rem);
  --fs-lg:    clamp(1.1875rem, 1.05rem + .7vw, 1.5rem);
  --fs-xl:    clamp(1.375rem, 1.15rem + 1.1vw, 2rem);
  --fs-h3:    clamp(1.5rem, 1.2rem + 1.5vw, 2.375rem);
  --fs-h2:    clamp(1.875rem, 1.35rem + 2.6vw, 3.5rem);
  --fs-h1:    clamp(2.375rem, 1.6rem + 4.4vw, 5rem);
  --fs-mega:  clamp(3rem, 1.8rem + 7vw, 7rem);

  --sp-1: .25rem; --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.5rem; --sp-6: 2rem;   --sp-7: 3rem;   --sp-8: 4rem;
  --sp-9: 6rem;   --sp-10: 8rem;

  --r-sm: 10px; --r: 16px; --r-lg: 24px; --r-xl: 32px; --r-full: 999px;
  --nav-h: 56px;
  --wrap: 1240px;
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,.84,.44,1);
}

/* ── Ambiente 02 · profundidad / azul / distribución ── */
html[data-env="deep"] {
  --env-bg: #0F2A6B; --env-bg-2: #0A1E52;
  --surface: rgba(255,255,255,.07); --surface-2: rgba(255,255,255,.04);
  --surface-in: rgba(8,20,50,.5);
  --text: #FFFFFF; --text-2: #D3E0FA; --text-3: #A3B8E4; --text-mute: #7C93C8;
  --line: rgba(255,255,255,.14); --line-2: rgba(255,255,255,.24);
  --accent: #7FB0FF; --accent-2: #A9CAFF; --accent-soft: rgba(127,176,255,.14);
  --on-accent: #06122E;
  --shadow-1: 0 2px 10px rgba(0,0,0,.28); --shadow-2: 0 24px 60px -24px rgba(0,0,0,.6);
  --shadow-3: 0 50px 100px -30px rgba(0,0,0,.7);
  --grain-op: .06;
}

/* ── Ambiente 03 · oscuro / tecnológico / roadmap ── */
html[data-env="dark"] {
  --env-bg: var(--ink-1000); --env-bg-2: var(--ink-900);
  --surface: #0D1424; --surface-2: #101a2f;
  --surface-in: rgba(255,255,255,.04);
  --text: #F3F6FC; --text-2: #C3CDE2; --text-3: #93A0BC; --text-mute: #66738F;
  --line: rgba(255,255,255,.09); --line-2: rgba(255,255,255,.18);
  --accent: var(--blue-400); --accent-2: var(--blue-300); --accent-soft: rgba(90,144,255,.12);
  --on-accent: #05080F;
  --shadow-1: 0 2px 10px rgba(0,0,0,.4); --shadow-2: 0 24px 60px -24px rgba(0,0,0,.75);
  --shadow-3: 0 50px 110px -30px rgba(0,0,0,.85);
  --grain-op: .07;
}

/* ── Ambiente 02 · claro azul frío (casos) ── */
html[data-env="chill"] {
  --env-bg: #EAF1FC; --env-bg-2: #DEEAFB;
  --surface: #FFFFFF; --surface-2: #F0F5FE;
  --surface-in: rgba(255,255,255,.74);
  --text: var(--ink-900); --text-2: #26324D; --text-3: #4E5D80; --text-mute: #77869F;
  --line: rgba(18,38,80,.11); --line-2: rgba(18,38,80,.19);
  --accent: var(--blue-600); --accent-2: var(--blue-500); --accent-soft: rgba(21,96,240,.09);
  --on-accent: #FFFFFF;
  --grain-op: .04;
}

/* ── Ambiente 05 · limpio / aplicación ── */
html[data-env="clean"] {
  --env-bg: #FBFCFE; --env-bg-2: #F4F7FC;
  --grain-op: .025;
}

/* ─── Lienzo de ambiente + grano ────────────────────────────────────────── */
.env {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 0%, var(--env-bg-2) 0%, transparent 60%),
    var(--env-bg);
  transition: background-color 900ms var(--ease), background-image 900ms var(--ease);
}
/* Grano: textura sutil que quita el plano perfecto de los degradados */
.grain {
  position: fixed; inset: -50%; z-index: -1; pointer-events: none;
  opacity: var(--grain-op); transition: opacity 900ms var(--ease);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ─── Base ──────────────────────────────────────────────────────────────── */
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: 1.55;
  color: var(--text-2);
  background: transparent;
  -webkit-font-smoothing: antialiased;
  /* clip, no hidden: hidden crea un contenedor de scroll y puede romper
     position:sticky en los descendientes. clip corta igual sin crearlo. */
  overflow-x: hidden;
  overflow-x: clip;
  transition: color 900ms var(--ease);
}
h1,h2,h3,h4 { color: var(--text); font-weight: 800; line-height: 1.04; letter-spacing: -.03em; text-wrap: balance; transition: color 900ms var(--ease); }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -.02em; }
p { text-wrap: pretty; }
strong { color: var(--text); font-weight: 700; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.skip-link { position: absolute; left: 1rem; top: -100px; z-index: 200; padding: .75rem 1.25rem; background: var(--accent); color: var(--on-accent); font-weight: 700; border-radius: var(--r-full); transition: top .15s; }
.skip-link:focus { top: 1rem; }
.vh { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* ─── Layout ────────────────────────────────────────────────────────────── */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--sp-4); }
@media (min-width: 720px) { .wrap { padding-inline: var(--sp-6); } }
.sec { position: relative; padding-block: clamp(2.25rem, 1.7rem + 3.5vw, 5.5rem); }
.sec--tight { padding-block: clamp(1.5rem, 1.2rem + 2vw, 3rem); }

.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-mute); margin-bottom: var(--sp-4);
}
.eyebrow::before { content: ''; width: 20px; height: 1px; background: currentColor; opacity: .6; }
.lede { font-size: var(--fs-md); color: var(--text-3); max-width: 54ch; }
.mono { font-family: var(--font-mono); }

/* ─── Movimiento: primitivas ────────────────────────────────────────────── */
.js [data-r] { opacity: 0; will-change: transform, opacity; }
.js [data-r].in { opacity: 1; transform: none; }
.js [data-r="up"]    { transform: translateY(30px); transition: opacity .8s var(--ease), transform .9s var(--ease-out); }
.js [data-r="left"]  { transform: translateX(-40px); transition: opacity .8s var(--ease), transform .9s var(--ease-out); }
.js [data-r="right"] { transform: translateX(40px); transition: opacity .8s var(--ease), transform .9s var(--ease-out); }
.js [data-r="scale"] { transform: scale(.94); transition: opacity .8s var(--ease), transform 1s var(--ease-out); }
.js [data-r][data-d="1"] { transition-delay: .10s; }
.js [data-r][data-d="2"] { transition-delay: .20s; }
.js [data-r][data-d="3"] { transition-delay: .30s; }
.js [data-r][data-d="4"] { transition-delay: .40s; }
.js [data-r][data-d="5"] { transition-delay: .50s; }

/* ─── Botones ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  padding: 1rem 1.75rem; min-height: 52px;
  font-weight: 700; font-size: var(--fs-sm); letter-spacing: -.01em;
  border-radius: var(--r-full); text-decoration: none;
  transition: transform .2s var(--ease), background-color .25s, box-shadow .25s, border-color .25s;
}
.btn:active { transform: scale(.985); }
.btn--primary { background: var(--accent); color: var(--on-accent); box-shadow: 0 12px 30px -12px rgba(21,96,240,.6); }
.btn--primary:hover { background: var(--accent-2); }
.btn--ghost { border: 1px solid var(--line-2); color: var(--text); background: var(--surface-in); backdrop-filter: blur(10px); }
.btn--ghost:hover { border-color: var(--accent); }
.btn--lg { padding: 1.15rem 2.25rem; font-size: var(--fs-md); min-height: 60px; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.btn-row--center { justify-content: center; }

/* ─── Nav ───────────────────────────────────────────────────────────────── */
.nav { position: sticky; top: .5rem; z-index: 90; padding-inline: var(--sp-3); }
.nav__in {
  max-width: var(--wrap); margin-inline: auto;
  display: flex; align-items: center; gap: var(--sp-4);
  min-height: 52px; padding: 0 .5rem 0 1rem;
  background: var(--surface-in); backdrop-filter: blur(16px) saturate(1.4);
  border: 1px solid var(--line); border-radius: var(--r-full);
  box-shadow: var(--shadow-1);
  transition: background-color .6s var(--ease), border-color .6s var(--ease);
}
.nav__brand { display: inline-flex; align-items: center; gap: .55rem; font-weight: 800; color: var(--text); text-decoration: none; letter-spacing: -.02em; margin-right: auto; }
.nav__brand img { width: 24px; height: 24px; border-radius: 6px; }
.nav__links { display: none; gap: var(--sp-5); }
@media (min-width: 900px) { .nav__links { display: flex; } }
.nav__links a { color: var(--text-3); font-size: var(--fs-sm); font-weight: 600; text-decoration: none; transition: color .2s; }
.nav__links a:hover { color: var(--text); }
.nav__cta { padding: .6rem 1.1rem; min-height: 40px; font-size: var(--fs-sm); }

/* ─── 01 HERO ───────────────────────────────────────────────────────────── */
.hero { position: relative; padding-block: clamp(1.25rem, .8rem + 3vw, 3rem) clamp(2rem, 1.5rem + 4vw, 4.5rem); overflow: hidden; }
.hero__stage { position: relative; z-index: 2; }

/* Secuencia tipográfica: la 1 entra, se desplaza y aparece la 2 */
.hero__l1, .hero__l2 { display: block; font-size: var(--fs-h1); font-weight: 800; letter-spacing: -.035em; line-height: 1.02; }
.hero__l1 { color: var(--text-3); }
.hero__l2 { color: var(--text); }
.js .hero__l1 { opacity: 0; transform: translateY(18px); animation: heroIn .9s var(--ease-out) .15s forwards; }
.js .hero__l2 { opacity: 0; transform: translateY(22px); animation: heroIn .9s var(--ease-out) .95s forwards; }
@keyframes heroIn { to { opacity: 1; transform: none; } }

/* Móvil: titular → campo de clips (el golpe visual) → claim → CTA, y el
   párrafo explicativo por debajo del pliegue. El brief pide impacto visual
   dentro de la primera pantalla, no un muro de texto.
   Escritorio: rejilla de dos columnas con el campo a la derecha. */
.hero__stage { display: flex; flex-direction: column; }
.hero__h     { order: 1; }
.hero__field { order: 2; }
.hero__claim { order: 3; }
.hero__cta   { order: 4; }
.hero__cue   { order: 5; }
.hero__lead  { order: 6; }

.hero__lead { margin-top: var(--sp-6); max-width: 46ch; color: var(--text-3); font-size: var(--fs-md); }
.hero__lead p + p { margin-top: var(--sp-4); }

.hero__claim { margin-top: var(--sp-2); }
.hero__claim b { display: block; font-size: var(--fs-xl); color: var(--text); font-weight: 800; letter-spacing: -.03em; }
.hero__claim span { display: block; font-size: var(--fs-md); color: var(--accent); font-weight: 700; }
.hero__cta { margin-top: var(--sp-5); }

/* ─── Muro de video infinito ────────────────────────────────────────────────
   Tres filas de piezas verticales que corren en direcciones alternas. El loop
   es seamless porque cada fila lleva su contenido DUPLICADO y la animación
   desplaza exactamente -50% del ancho total: al terminar, la segunda mitad
   está donde estaba la primera, así que no hay salto ni punto de reinicio
   perceptible. Nada de rotaciones: la profundidad viene de escala, opacidad
   y desenfoque por fila. */
.wall {
  /* min-width:0 y la columna fija son imprescindibles: un contenedor grid
     tiene min-width:auto y las filas (width:max-content) lo estirarían a
     miles de px, rompiendo el ancho de pantalla y el fade. */
  position: relative; display: grid; gap: 8px; overflow: hidden;
  min-width: 0; grid-template-columns: minmax(0, 1fr);
  margin: var(--sp-5) 0 var(--sp-4);
  /* A sangre en móvil: los clips cruzan todo el ancho de pantalla, no sólo
     la columna de texto, y se disuelven en los bordes del viewport. */
  width: 100vw; margin-left: 50%; transform: translateX(-50%);
  /* no-repeat es imprescindible: por defecto la máscara se repetiría fuera
     de la caja y el degradado dejaría de leerse como un fade continuo. */
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  /* Fundido en los CUATRO bordes: los clips emergen del fondo y vuelven a
     disolverse en él. Dos capas de máscara cruzadas (horizontal x vertical)
     con composite intersect; sin la capa vertical el muro terminaba en un
     filo recto arriba y abajo y se veía el límite de la sección. */
  --mask-x: linear-gradient(90deg, transparent 0, rgba(0,0,0,.35) 8%, #000 26%, #000 74%, rgba(0,0,0,.35) 92%, transparent 100%);
  --mask-y: linear-gradient(180deg, transparent 0, rgba(0,0,0,.6) 6%, #000 15%, #000 85%, rgba(0,0,0,.6) 94%, transparent 100%);
  -webkit-mask-image: var(--mask-x), var(--mask-y);
  mask-image: var(--mask-x), var(--mask-y);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.wall__row { display: flex; gap: 8px; width: max-content; will-change: transform; }
.wall__row--a { animation: wallL 56s linear infinite; }
.wall__row--b { animation: wallR 68s linear infinite; }

@keyframes wallL { from { transform: translate3d(0,0,0); }      to { transform: translate3d(-50%,0,0); } }
@keyframes wallR { from { transform: translate3d(-50%,0,0); }   to { transform: translate3d(0,0,0); } }
.wall:hover .wall__row { animation-play-state: paused; }

/* Profundidad por fila, sin inclinar nada */
.wall__row--b .wclip { transform: scale(.9);  opacity: .78; }


.wclip {
  position: relative; flex: 0 0 auto;
  width: 68px; aspect-ratio: 9/16; border-radius: 10px; overflow: hidden;
  background: linear-gradient(165deg, var(--blue-700) 0%, var(--blue-900) 52%, var(--ink-1000) 100%);
  box-shadow: var(--shadow-1);
  border: 1px solid rgba(255,255,255,.12);
}
@media (min-width: 720px) { .wclip { width: 96px; border-radius: 12px; } .wall { gap: 12px; } .wall__row { gap: 12px; } }
.wclip::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 70% at 28% 10%, rgba(90,144,255,.42), transparent 62%),
              repeating-linear-gradient(112deg, rgba(255,255,255,.05) 0 2px, transparent 2px 20px);
}
/* Hueco listo para el vídeo real: basta sustituir el div por <video> con
   estas mismas clases; muted/playsinline/loop y object-fit ya están puestos. */
.wclip > video, .wclip > img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;
}
.wclip__d {
  position: absolute; top: 5px; right: 5px; z-index: 2;
  font-size: .5rem; font-weight: 700; color: #fff;
  background: rgba(0,0,0,.42); padding: 1px 4px; border-radius: 20px;
}
@media (prefers-reduced-motion: reduce) { .wall__row { animation: none; } }

/* Escritorio: el hero pasa a dos columnas por áreas; el muro vuelve a su
   celda (sin sangre) y el orden vertical del móvil deja de aplicarse. */
@media (min-width: 900px) {
  .hero { padding-block: clamp(3rem,2rem+4vw,5rem) clamp(4rem,3rem+5vw,7rem); }
  .hero__stage {
    display: grid; align-items: center;
    grid-template-columns: minmax(0,1.05fr) minmax(0,.95fr);
    grid-template-areas: "h field" "lead field" "claim field" "cta field" "cue field";
    column-gap: var(--sp-8); row-gap: 0;
  }
  .hero__h { grid-area: h; }
  .hero__lead { grid-area: lead; margin-top: var(--sp-5); }
  .hero__claim { grid-area: claim; margin-top: var(--sp-6); }
  .hero__cta { grid-area: cta; justify-content: flex-start; }
  .hero__cue { grid-area: cue; }
  .hero__field { grid-area: field; margin: 0; align-self: center; min-width: 0; }
  .hero__field .wall { width: 100%; margin-left: 0; transform: none; }
}

.hero__cue { display: inline-flex; align-items: center; gap: .5rem; margin-top: var(--sp-6); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute); }
.hero__cue i { width: 1px; height: 22px; background: currentColor; opacity: .4; animation: cue 1.8s ease-in-out infinite; }
@keyframes cue { 0%,100% { transform: scaleY(.4); opacity: .25 } 50% { transform: scaleY(1); opacity: .7 } }

/* ─── 02 CASOS DE ÉXITO — coverflow ────────────────────────────────────────
   Card activa recta y centrada; las laterales ladeadas, a menor escala y
   parcialmente visibles, para que se vea de inmediato que hay más. */
.cover {
  position: relative; margin-top: var(--sp-6);
  /* Sin esto las cards laterales se salen del viewport y en el móvil se ve
     como si la página estuviera cortada por los lados. */
  overflow: hidden;
}
.cover__stage {
  /* +72px: la banda de imagen y la cifra grande necesitan sitio real.
     La card sigue siendo una sola pantalla, no una página por caso. */
  position: relative; height: 612px; perspective: 1300px;
  touch-action: pan-y; cursor: grab; user-select: none;
}
.cover__stage:active { cursor: grabbing; }
@media (min-width: 900px) { .cover__stage { height: 566px; } }
.cover__dots { display: flex; justify-content: center; gap: 6px; margin-top: var(--sp-4); }
.cover__dots b { width: 5px; height: 5px; border-radius: 50%; background: var(--line-2); transition: background .3s, width .3s; }
.cover__dots b.on { background: var(--accent); width: 18px; border-radius: 3px; }

/* Compactas a propósito: una colección de ejemplos, no una página por caso */
.cs {
  position: absolute; left: 50%; top: 0;
  width: min(78vw, 320px); height: 100%; margin-left: min(-39vw, -160px);
  border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-2);
  display: flex; flex-direction: column;
  transform-style: preserve-3d; backface-visibility: hidden;
  transition: opacity .4s var(--ease), box-shadow .4s var(--ease);
  will-change: transform, opacity;
}
.cs.is-active { box-shadow: var(--shadow-3); }
@media (min-width: 900px) { .cs { width: 330px; margin-left: -165px; } }
.cs__pad { padding: var(--sp-4); display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
.cs__tag { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.cs__who { margin-top: .5rem; font-size: var(--fs-md); font-weight: 800; color: var(--text); letter-spacing: -.02em; }
.cs__ctx { font-size: var(--fs-xs); color: var(--text-mute); }

/* ── Card A · escala: la cifra manda ── */
.cs__mega { font-size: clamp(2.25rem, 1.7rem + 3.4vw, 3rem); font-weight: 800; letter-spacing: -.05em; line-height: .92; color: var(--text); font-variant-numeric: tabular-nums; }
.cs__megaSub { font-size: var(--fs-sm); color: var(--text-3); font-weight: 700; margin-top: .25rem; }
.cs__second { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--line); display: flex; gap: var(--sp-5); }
.cs__second b { display: block; font-size: var(--fs-lg); color: var(--text); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.cs__second span { font-size: var(--fs-xs); color: var(--text-mute); }
.branchviz { margin-top: var(--sp-3); }
/* Hueco para retrato del creador: mismo sitio que el diagrama, recortado a
   16:9 para que la card conserve exactamente la misma altura con foto o sin
   ella y el carrusel no dé un salto al cambiar de caso. */
.cs__photo {
  margin-top: var(--sp-3); border-radius: var(--r);
  overflow: hidden; aspect-ratio: 16 / 9; background: var(--surface-2);
}
.cs__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.branchviz svg { width: 100%; height: auto; overflow: visible; }
.bv__edge { fill: none; stroke: var(--accent); stroke-width: 1.4; opacity: .55;
  stroke-dasharray: var(--len,200); stroke-dashoffset: var(--len,200); }
.cs.on .bv__edge { stroke-dashoffset: 0; transition: stroke-dashoffset 1.1s var(--ease); }
.cs.on .bv__edge:nth-of-type(2){transition-delay:.06s} .cs.on .bv__edge:nth-of-type(3){transition-delay:.12s}
.cs.on .bv__edge:nth-of-type(4){transition-delay:.18s} .cs.on .bv__edge:nth-of-type(5){transition-delay:.24s}
.cs.on .bv__edge:nth-of-type(6){transition-delay:.30s} .cs.on .bv__edge:nth-of-type(7){transition-delay:.36s}
.bv__seed { fill: var(--accent); }
.bv__leaf { fill: var(--accent); opacity: 0; transform-box: fill-box; transform-origin: center; }
.cs.on .bv__leaf { opacity: .85; transition: opacity .5s ease .5s; }
.bv__label { fill: var(--text-mute); font: 700 8px var(--font-sans); }

/* ── Card B · continuidad: dos líneas, una cae y otra sube ── */
.cs--dark { background: var(--ink-950); border-color: rgba(255,255,255,.12); }
.cs--dark .cs__who, .cs--dark .cs__mega, .cs--dark .cs__title { color: #fff; }
.cs--dark .cs__ctx, .cs--dark .cs__second span { color: #8494B4; }
.cs--dark .cs__second { border-color: rgba(255,255,255,.12); }
.cs--dark .cs__second b { color: #fff; }
.cs__title { font-size: var(--fs-md); font-weight: 800; color: var(--text); letter-spacing: -.025em; line-height: 1.22; margin-top: var(--sp-3); }
.lines { margin-top: var(--sp-4); }
.lines svg { width: 100%; height: auto; overflow: visible; }
.ln { fill: none; stroke-width: 2.2; stroke-linecap: round;
  stroke-dasharray: var(--len,300); stroke-dashoffset: var(--len,300); }
.cs.on .ln { stroke-dashoffset: 0; transition: stroke-dashoffset 1.4s var(--ease) .15s; }
.ln--down { stroke: var(--red-500); }
.ln--up { stroke: #2BD99B; }
.ln__dot { opacity: 0; }
.cs.on .ln__dot { opacity: 1; transition: opacity .4s ease 1.3s; }
.lines__key { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3); font-size: var(--fs-xs); }
.lines__key i { font-style: normal; font-weight: 800; }
.lines__key .dn { color: var(--red-500); } .lines__key .up { color: #2BD99B; }
.cs__mult { margin-top: var(--sp-4); font-size: var(--fs-xs); color: #8494B4; }
.cs__close { margin-top: var(--sp-5); font-size: var(--fs-md); font-weight: 800; letter-spacing: -.02em; line-height: 1.3; }
.cs__close b { display: block; color: #fff; }
.cs__close i { display: block; font-style: normal; color: #2BD99B; }

/* ── Card C · retrato + quote ── */
.cs__portrait {
  position: relative; aspect-ratio: 4/3; background: linear-gradient(160deg, var(--blue-700), var(--ink-900));
  display: grid; place-items: center; overflow: hidden;
}
.cs__portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cs__ph { color: rgba(255,255,255,.55); font-size: var(--fs-xs); font-weight: 700; text-align: center; padding: var(--sp-4); }
.cs__quote { font-size: var(--fs-lg); font-weight: 800; color: var(--text); letter-spacing: -.025em; line-height: 1.3; }
.cs__quote::before { content: '“'; color: var(--accent); }
.cs__quote::after { content: '”'; color: var(--accent); }
.cs__qwho { margin-top: var(--sp-4); font-size: var(--fs-xs); color: var(--text-mute); font-weight: 700; }
.cs__inline { display: flex; gap: var(--sp-4); margin-top: auto; padding-top: var(--sp-4); }
.cs__inline b { font-size: var(--fs-md); color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.cs__inline span { font-size: var(--fs-xs); color: var(--text-mute); display: block; }

/* ── Card D · testimonio en vídeo (preparada, aún sin archivo) ── */
.cs__video { position: relative; aspect-ratio: 9/13; background: linear-gradient(165deg, var(--ink-800), var(--ink-1000)); overflow: hidden; }
.cs__video video, .cs__video img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cs__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.92); color: var(--ink-900); z-index: 2;
  box-shadow: 0 10px 30px -8px rgba(0,0,0,.5);
}
.cs__play svg { width: 20px; height: 20px; margin-left: 3px; }
.cs__soon { position: absolute; left: 0; right: 0; bottom: 0; padding: var(--sp-4); z-index: 2;
  background: linear-gradient(0deg, rgba(5,8,15,.9), transparent); color: #fff; }
.cs__soon b { display: block; font-size: var(--fs-sm); font-weight: 800; }
.cs__soon span { font-size: var(--fs-xs); opacity: .7; }

.rail__hint { font-size: var(--fs-xs); color: var(--text-mute); text-align: center; margin-top: var(--sp-2); }
@media (min-width: 900px) { .rail__hint { display: none; } }

/* ─── 03 PROBLEMA ───────────────────────────────────────────────────────── */
.prob__beats { margin-top: var(--sp-6); display: grid; gap: .2rem; }
.prob__beats b { font-size: var(--fs-xl); color: var(--text); font-weight: 800; letter-spacing: -.03em; }
.prob__against { margin-top: var(--sp-4); font-size: var(--fs-md); color: var(--text-3); }
.prob__turn { margin-top: var(--sp-7); display: grid; gap: .35rem; }
.prob__turn b { font-size: var(--fs-lg); color: var(--text); letter-spacing: -.02em; }
.prob__turn i { font-style: normal; font-size: var(--fs-lg); color: var(--accent); font-weight: 800; letter-spacing: -.02em; }

/* Comparación: 1 punto contra una escalera de puntos */
.ladder { display: grid; gap: var(--sp-4); margin-top: var(--sp-7); grid-template-columns: 1fr 1fr; }
.ladder__side { border-radius: var(--r-lg); border: 1px solid var(--line); background: var(--surface); padding: var(--sp-4); box-shadow: var(--shadow-1); }
.ladder__side--b { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-1); }
.ladder__label { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text-mute); }
.ladder__n { font-size: clamp(2rem, 1.4rem + 3vw, 3.25rem); font-weight: 800; letter-spacing: -.04em; color: var(--text); line-height: 1; margin-top: .3rem; font-variant-numeric: tabular-nums; }
.ladder__side--b .ladder__n { color: var(--accent); }
.ladder__dots { display: flex; flex-wrap: wrap; gap: 4px; margin-top: var(--sp-4); }
.ladder__dots i { width: 7px; height: 7px; border-radius: 2px; background: var(--line-2); }
.ladder__dots i.on { background: var(--accent); }
.js .ladder__dots i { opacity: 0; transform: scale(.4); transition: opacity .28s, transform .34s var(--ease-out); }
.js .in .ladder__dots i { opacity: 1; transform: none; }
.js .in .ladder__dots i:nth-child(8n+1){transition-delay:.02s} .js .in .ladder__dots i:nth-child(8n+2){transition-delay:.06s}
.js .in .ladder__dots i:nth-child(8n+3){transition-delay:.10s} .js .in .ladder__dots i:nth-child(8n+4){transition-delay:.14s}
.js .in .ladder__dots i:nth-child(8n+5){transition-delay:.18s} .js .in .ladder__dots i:nth-child(8n+6){transition-delay:.22s}
.js .in .ladder__dots i:nth-child(8n+7){transition-delay:.26s} .js .in .ladder__dots i:nth-child(8n){transition-delay:.30s}
.prob__close { margin-top: var(--sp-7); padding-top: var(--sp-6); border-top: 1px solid var(--line); }
.prob__close b { display: block; font-size: var(--fs-lg); color: var(--text-3); font-weight: 700; }
.prob__close i { display: block; font-style: normal; font-size: var(--fs-h3); color: var(--text); font-weight: 800; letter-spacing: -.03em; margin-top: .3rem; }

/* ─── 04 PRESENCIA — campo de clips con profundidad ─────────────────────── */
/* SIN overflow: en WebKit un ancestro con overflow convierte la sección en
   contenedor de scroll y el position:sticky de dentro deja de fijarse — el
   escenario se iba con la página y quedaban 1295px de track vacío. El
   recorte de la parrilla ya lo hace .fyp__sticky, que sí debe tenerlo. */
.presence { position: relative; }
.field { position: relative; height: 420px; margin-top: var(--sp-6); perspective: 1000px; }
@media (min-width: 900px) { .field { height: 560px; } }
.fclip {
  position: absolute; border-radius: 12px; overflow: hidden;
  background: linear-gradient(165deg, rgba(255,255,255,.16), rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.18);
  box-shadow: 0 18px 40px -18px rgba(0,0,0,.5);
}
.fclip::after { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(115deg, rgba(255,255,255,.06) 0 2px, transparent 2px 20px); }
.js .fclip { opacity: 0; transform: translateY(30px) scale(.9); transition: opacity .9s var(--ease), transform 1.1s var(--ease-out); }
.js .in .fclip { opacity: var(--o, 1); transform: none; }
.presence__beats { display: grid; gap: .2rem; margin-top: var(--sp-6); }
.presence__beats b { font-size: var(--fs-lg); color: var(--text); letter-spacing: -.02em; }

/* ─── 05 ROADMAP ────────────────────────────────────────────────────────── */
.rm { position: relative; margin-top: var(--sp-6); }
.rm__spine { position: absolute; left: 19px; top: 0; bottom: 0; width: 2px; background: var(--line-2); }
.rm__spine i { position: absolute; inset: 0; background: linear-gradient(180deg, var(--accent), var(--accent-2)); transform-origin: top; transform: scaleY(0); }
.js .rm.in .rm__spine i { transform: scaleY(1); transition: transform 2.4s var(--ease); }
@media (min-width: 900px) { .rm__spine { left: 27px; } }

.stage { position: relative; padding-left: 52px; padding-bottom: var(--sp-6); }
@media (min-width: 900px) { .stage { padding-left: 80px; padding-bottom: var(--sp-8); } }
.stage__n {
  position: absolute; left: 0; top: 0; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; z-index: 2;
  background: var(--surface); border: 2px solid var(--accent); color: var(--accent);
  font-family: var(--font-mono); font-size: .6875rem; font-weight: 700;
  box-shadow: 0 0 0 6px var(--env-bg);
}
@media (min-width: 900px) { .stage__n { width: 56px; height: 56px; font-size: .8125rem; } }
.stage__kicker { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--text-mute); }
.stage__title { font-size: var(--fs-h3); margin-top: .5rem; max-width: 20ch; }
.stage__body { margin-top: var(--sp-4); color: var(--text-3); max-width: 52ch; font-size: var(--fs-sm); }
.stage__body + .stage__body { margin-top: var(--sp-3); }
.stage__close { margin-top: var(--sp-5); display: flex; gap: var(--sp-4); flex-wrap: wrap; }
.stage__close b, .stage__close i { font-style: normal; font-size: var(--fs-md); font-weight: 800; letter-spacing: -.02em; }
.stage__close b { color: var(--accent); }
.stage__close i { color: var(--text); }
.stage__viz { margin-top: var(--sp-5); }

/* Viz: convergencia (IA) */
.vconv { display: grid; gap: var(--sp-3); }
.vconv__ins { display: grid; gap: .5rem; }
.vconv__in { display: flex; align-items: center; gap: .6rem; font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); }
.vconv__in::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; }
.vconv__arrow { height: 22px; border-left: 2px dashed var(--line-2); margin-left: 3px; }
.vconv__out { display: inline-flex; align-items: center; gap: .5rem; font-weight: 800; color: var(--text); font-size: var(--fs-sm); background: var(--accent-soft); border: 1px solid var(--accent); padding: .5rem .9rem; border-radius: var(--r-full); align-self: flex-start; }

/* Viz: triage humano */
.vtri { display: grid; gap: .45rem; }
.vtri__row { display: flex; align-items: center; gap: .6rem; font-size: var(--fs-xs); font-weight: 700; padding: .5rem .7rem; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); }
.vtri__row b { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; font-size: .625rem; color: #fff; flex: 0 0 auto; }
.vtri__row--keep b { background: var(--green-500); }
.vtri__row--drop b { background: var(--red-500); }
.vtri__row--edit b { background: var(--blue-400); }
.vtri__row--drop { opacity: .55; }
.vtri__row span { color: var(--text-3); }

/* Viz: ramificación */
.vbr { display: grid; gap: .5rem; }
.vbr__root { display: inline-flex; align-self: flex-start; font-weight: 800; font-size: var(--fs-sm); color: var(--text); background: var(--surface); border: 1px solid var(--line-2); padding: .5rem .9rem; border-radius: var(--r-full); }
.vbr__list { display: flex; flex-wrap: wrap; gap: .4rem; padding-left: var(--sp-4); border-left: 2px solid var(--line-2); }
.vbr__list span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); background: var(--surface-2); border: 1px solid var(--line); padding: .35rem .65rem; border-radius: var(--r-full); }

/* Viz: caos que se ordena */
.vchaos { display: flex; flex-wrap: wrap; gap: .4rem; }
.vchaos span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); border: 1px solid var(--line); background: var(--surface); padding: .4rem .7rem; border-radius: var(--r-sm); }
.stage__big { margin-top: var(--sp-6); padding-top: var(--sp-5); border-top: 1px solid var(--line); }
.stage__big b { display: block; font-size: var(--fs-lg); color: var(--text-3); font-weight: 700; letter-spacing: -.02em; }
.stage__big i { display: block; font-style: normal; margin-top: .35rem; font-size: var(--fs-xl); color: var(--text); font-weight: 800; letter-spacing: -.03em; }

/* Viz: satélites */
.vsat { display: grid; gap: .55rem; }
.vsat__row { display: flex; align-items: center; gap: .55rem; }
.vsat__acct { width: 22px; height: 22px; border-radius: 50%; background: linear-gradient(150deg, var(--accent-2), var(--accent)); flex: 0 0 auto; }
.vsat__clips { display: flex; gap: 4px; }
.vsat__clips i { width: 13px; height: 18px; border-radius: 3px; background: var(--accent-soft); border: 1px solid var(--accent); display: block; }
.js .vsat__row { opacity: 0; transform: translateX(-12px); transition: opacity .5s, transform .55s var(--ease-out); }
.js .in .vsat__row { opacity: 1; transform: none; }
.js .in .vsat__row:nth-child(1){transition-delay:.1s} .js .in .vsat__row:nth-child(2){transition-delay:.22s}
.js .in .vsat__row:nth-child(3){transition-delay:.34s} .js .in .vsat__row:nth-child(4){transition-delay:.46s}
.js .in .vsat__row:nth-child(5){transition-delay:.58s}
.stage__nots { margin-top: var(--sp-4); display: grid; gap: .3rem; }
.stage__nots span { font-size: var(--fs-sm); color: var(--text-mute); }

/* Viz: el loop */
.vloop { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.vloop span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); background: var(--surface); border: 1px solid var(--line); padding: .4rem .7rem; border-radius: var(--r-full); }
.vloop i { font-style: normal; color: var(--accent); font-weight: 800; }
.vloop__back { margin-top: .6rem; font-size: var(--fs-xs); font-weight: 800; color: var(--accent); display: inline-flex; align-items: center; gap: .4rem; }
.stage__beats { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: var(--sp-4); }
.stage__beats b { font-size: var(--fs-sm); color: var(--text); font-weight: 800; }
.rm__close { margin-top: var(--sp-6); padding-top: var(--sp-6); border-top: 1px solid var(--line); }
.rm__close b { display: block; font-size: var(--fs-lg); color: var(--text-3); font-weight: 700; }
.rm__close i { display: block; font-style: normal; font-size: var(--fs-h3); color: var(--text); font-weight: 800; letter-spacing: -.03em; margin-top: .3rem; }

/* ─── 06 CALCULADORA ────────────────────────────────────────────────────── */
.calc { text-align: left; border-radius: var(--r-xl); border: 1px solid var(--line); background: var(--surface); padding: var(--sp-5); box-shadow: var(--shadow-2); margin-top: var(--sp-6); }
@media (min-width: 900px) { .calc { padding: var(--sp-7); } }
.calc__label { font-size: var(--fs-sm); font-weight: 700; color: var(--text); }
.calc__range { width: 100%; margin-top: var(--sp-5); accent-color: var(--accent); height: 32px; }
.calc__ticks { display: flex; justify-content: space-between; font-size: var(--fs-xs); color: var(--text-mute); font-weight: 700; font-variant-numeric: tabular-nums; }
.calc__out { margin-top: var(--sp-6); display: grid; gap: var(--sp-4); }
@media (min-width: 720px) { .calc__out { grid-template-columns: auto 1fr; align-items: center; gap: var(--sp-6); } }
.calc__big { font-size: clamp(2.75rem, 2rem + 5vw, 5rem); font-weight: 800; letter-spacing: -.045em; color: var(--accent); line-height: .95; font-variant-numeric: tabular-nums; }
.calc__unit { font-size: var(--fs-sm); color: var(--text-3); font-weight: 700; }
.calc__sub { font-size: var(--fs-xs); color: var(--text-mute); }
.calc__grid { display: flex; flex-wrap: wrap; gap: 3px; max-height: 132px; overflow: hidden; }
.calc__grid i { width: 7px; height: 7px; border-radius: 2px; background: var(--accent); opacity: .85; }
.calc__net { display: flex; align-items: center; gap: .5rem; margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--line); flex-wrap: wrap; }
.calc__net b { width: 26px; height: 26px; border-radius: 50%; background: linear-gradient(150deg, var(--accent-2), var(--accent)); }
.calc__net span { font-size: var(--fs-xs); color: var(--text-mute); font-weight: 700; margin-left: .3rem; }
.calc__note { margin-top: var(--sp-5); font-size: var(--fs-xs); color: var(--text-mute); max-width: 62ch; }
.calc__note + .calc__note { margin-top: .5rem; }

/* ─── 07 PARA QUIÉN — acordeón nativo exclusivo ─────────────────────────── */
.who { margin-top: var(--sp-6); border-top: 1px solid var(--line); }
.who__item { border-bottom: 1px solid var(--line); }
.who { text-align: left; }
.who__item > summary {
  list-style: none; cursor: pointer; display: flex; align-items: baseline; gap: var(--sp-4);
  padding: var(--sp-5) 0; text-align: left;
}
.who__item > summary::-webkit-details-marker { display: none; }
.who__n { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-mute); font-weight: 700; }
.who__t { font-size: var(--fs-xl); font-weight: 800; color: var(--text); letter-spacing: -.03em; flex: 1; }
.who__item[open] .who__t { color: var(--accent); }
.who__plus { color: var(--text-mute); font-size: 1.25rem; line-height: 1; transition: transform .35s var(--ease); }
.who__item[open] .who__plus { transform: rotate(45deg); color: var(--accent); }
.who__panel { padding-bottom: var(--sp-6); display: grid; gap: var(--sp-4); }
@media (min-width: 820px) { .who__panel { grid-template-columns: minmax(0,1.15fr) minmax(0,.85fr); align-items: start; gap: var(--sp-7); } }
.who__body { color: var(--text-3); font-size: var(--fs-sm); max-width: 56ch; }
.who__viz { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.who__viz span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); background: var(--surface-2); border: 1px solid var(--line); padding: .4rem .7rem; border-radius: var(--r-full); }
.who__viz i { font-style: normal; color: var(--accent); font-weight: 800; }

/* ─── 08 FAQ ────────────────────────────────────────────────────────────── */
.faq { margin-top: var(--sp-6); border-top: 1px solid var(--line); text-align: left; }
.faq__i { border-bottom: 1px solid var(--line); }
.faq__i > summary { list-style: none; cursor: pointer; display: flex; gap: var(--sp-4); justify-content: space-between; align-items: flex-start; padding: var(--sp-5) 0; font-size: var(--fs-md); font-weight: 700; color: var(--text); }
.faq__i > summary::-webkit-details-marker { display: none; }
.faq__i > summary::after { content: '+'; color: var(--accent); font-size: 1.35rem; line-height: 1; font-weight: 400; flex: 0 0 auto; }
.faq__i[open] > summary::after { content: '−'; }
.faq__a { padding-bottom: var(--sp-5); color: var(--text-3); font-size: var(--fs-sm); max-width: 66ch; }
.faq__a p + p { margin-top: var(--sp-3); }

/* ─── 09 EXCLUSIVIDAD ───────────────────────────────────────────────────── */
.excl { text-align: center; }
.excl h2 { max-width: 18ch; margin-inline: auto; }
.excl h2 i { font-style: normal; display: block; color: var(--text-3); }
.excl__body { margin: var(--sp-5) auto 0; max-width: 56ch; color: var(--text-3); font-size: var(--fs-sm); }
.excl__cta { margin-top: var(--sp-7); }
.excl__sub { margin: var(--sp-4) auto 0; max-width: 50ch; font-size: var(--fs-xs); color: var(--text-mute); }

/* ─── 10 FORMULARIO ─────────────────────────────────────────────────────── */
.form { margin-top: var(--sp-6); display: grid; gap: var(--sp-5); max-width: 680px; }
.f { display: grid; gap: .5rem; }
.f > label { font-size: var(--fs-sm); font-weight: 700; color: var(--text); }
.f__hint { font-size: var(--fs-xs); color: var(--text-mute); }
.f input, .f select, .f textarea {
  width: 100%; padding: .85rem 1rem; min-height: 52px;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-sm); color: var(--text);
  transition: border-color .2s, box-shadow .2s;
}
.f textarea { min-height: 110px; resize: vertical; }
.f input:focus, .f select:focus, .f textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.f__row { display: grid; gap: var(--sp-4); }
@media (min-width: 640px) { .f__row--2 { grid-template-columns: 1fr 1fr; } }
.f__group { display: grid; gap: var(--sp-3); padding: var(--sp-4); border: 1px solid var(--line); border-radius: var(--r); background: var(--surface-2); }
.form__note { font-size: var(--fs-xs); color: var(--text-mute); }

/* Estado post-envío */
.sent { display: none; border-radius: var(--r-xl); border: 1px solid var(--accent); background: var(--surface); padding: var(--sp-7) var(--sp-5); box-shadow: var(--shadow-2); text-align: center; }
.sent.on { display: block; }
.sent__tick { width: 54px; height: 54px; border-radius: 50%; margin: 0 auto var(--sp-5); display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); font-size: 1.5rem; }
.sent p { margin: var(--sp-4) auto 0; max-width: 52ch; color: var(--text-3); font-size: var(--fs-sm); }
.sent__close { margin-top: var(--sp-5); font-weight: 800; color: var(--text); font-size: var(--fs-sm); }

/* ─── Footer ────────────────────────────────────────────────────────────── */
.foot { padding-block: var(--sp-7) var(--sp-6); border-top: 1px solid var(--line); font-size: var(--fs-xs); color: var(--text-mute); }
.foot__in { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: space-between; align-items: center; }
.foot a { color: var(--text-3); text-decoration: none; }
.foot a:hover { color: var(--text); }

@media print { .nav, .env, .grain { display: none; } }

/* ─── DATA LOOP — círculo real, construido por el progreso del scroll ───────
   La sección mide varias alturas de viewport; dentro, un contenedor sticky
   mantiene el círculo fijo mientras el scroll avanza. Todo el estado (arco
   recorrido, nodo activo, copy) se DERIVA del progreso, no de un disparo
   único: por eso al subir se desconstruye solo, sin lógica aparte. */
.loop { position: relative; }
.loop__track { position: relative; }
.loop__sticky {
  position: sticky; top: 0; min-height: 88svh;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--sp-5); padding-block: var(--sp-6);
}
@media (min-width: 960px) {
  .loop__sticky { flex-direction: row; align-items: center; gap: var(--sp-8); }
  .loop__viz { flex: 0 0 46%; }
  .loop__side { flex: 1; }
}

.loop__viz { position: relative; width: min(78vw, 420px); margin-inline: auto; }
.loop__viz svg { width: 100%; height: auto; overflow: visible; display: block; }
.lp__track { fill: none; stroke: var(--line-2); stroke-width: 2; }
.lp__prog {
  fill: none; stroke: var(--accent); stroke-width: 3.5; stroke-linecap: round;
  /* dashoffset lo escribe el JS con el progreso; sin transición para que
     siga al dedo en ambas direcciones */
}
.lp__node { transition: opacity .35s ease, r .35s var(--ease); }
.lp__dot { fill: var(--env-bg); stroke: var(--line-2); stroke-width: 2; }
.lp__node.on .lp__dot { fill: var(--accent); stroke: var(--accent); }
.lp__ring { fill: none; stroke: var(--accent); stroke-width: 2; opacity: 0; transform-box: fill-box; transform-origin: center; }
.lp__node.on .lp__ring { opacity: .35; animation: lpPulse 2.4s ease-in-out infinite; }
@keyframes lpPulse { 0%,100% { transform: scale(1); opacity: .3 } 50% { transform: scale(1.5); opacity: 0 } }
.lp__label { fill: var(--text-mute); font: 700 8.5px var(--font-sans); letter-spacing: .04em; opacity: 0; transition: opacity .35s ease, fill .35s ease; }
.lp__node.on .lp__label { opacity: 1; fill: var(--text); }
/* Centro: el mensaje aparece sólo al cerrar el círculo */
.lp__center { opacity: 0; transition: opacity .5s var(--ease); }
.loop.done .lp__center { opacity: 1; }
.lp__center span {
  display: block; text-align: center; font-weight: 800; letter-spacing: -.03em;
  line-height: 1.15; color: var(--text); font-size: clamp(.9rem, .55rem + 1.6vw, 1.25rem);
  padding-inline: 12%;
}

/* Copy contextual: sólo la etapa activa */
.loop__stage { min-height: 8.5rem; }
.loop__n { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700; color: var(--accent); letter-spacing: .1em; }
.loop__t { font-size: var(--fs-xl); font-weight: 800; color: var(--text); letter-spacing: -.03em; margin-top: .4rem; }
.loop__c { margin-top: .6rem; color: var(--text-3); font-size: var(--fs-sm); max-width: 42ch; }
.loop__bar { margin-top: var(--sp-5); height: 3px; border-radius: 3px; background: var(--line-2); overflow: hidden; }
.loop__bar i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 3px; }
.loop__steps { display: flex; gap: 4px; margin-top: var(--sp-3); }
.loop__steps b { flex: 1; height: 2px; border-radius: 2px; background: var(--line-2); transition: background .3s; }
.loop__steps b.on { background: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  /* Sin sticky ni recorrido: el círculo se muestra completo de una vez */
  .loop__track { height: auto !important; }
  .loop__sticky { position: static; min-height: 0; }
  .lp__prog { stroke-dashoffset: 0 !important; }
  .lp__node { opacity: 1 !important; }
  .lp__node .lp__dot { fill: var(--accent); stroke: var(--accent); }
  .lp__node .lp__label { opacity: 1; fill: var(--text); }
  .lp__center { opacity: 1; }
}

/* ─── PRESENCIA — pared de contenido ───────────────────────────────────────
   Parrilla estrictamente simétrica: mismo número de piezas por columna y
   mismo tamaño de celda. Sangra por los cuatro lados para que se lea como
   una red que continúa fuera de pantalla. El movimiento lo manda el scroll. */
.fyp { position: relative; }
.fyp__sticky {
  /* Sin padding superior: la parrilla arranca pegada al borde y llena el
     viewport desde el primer frame. El texto lleva su propio halo, así que
     no necesita que la sección le reserve hueco. */
  /* ALTURA VISUAL DEL ESCENARIO: exactamente un viewport, y en unidad
     ESTÁTICA (vh = lvh en iOS). Con dvh el documento cambiaba de altura al
     plegarse la barra de Safari y eso es un salto de layout. Al ser lvh el
     escenario nunca es más bajo que la pantalla: no puede aparecer franja
     de fondo por debajo. Lo que sí se centra sobre la pantalla real es el
     texto, que va en absolute y no aporta altura. */
  position: sticky; top: 0; height: 100vh; overflow: hidden;
}

.wallgrid {
  position: absolute; inset: -22% -16%;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px;
  /* El fundido tiene que caer donde está el BORDE VISIBLE, no donde acaba
     la parrilla. La parrilla mide 144% del panel (inset vertical -22%), así
     que el borde de arriba cae en 22/144 = 15.3% y el de abajo en 122/144 =
     84.7%. Con los porcentajes anteriores el borde superior quedaba al 61%
     de opacidad y overflow:hidden lo cortaba en seco: ese era el filo. */
  -webkit-mask-image: linear-gradient(180deg, transparent 15.3%, rgba(0,0,0,.55) 22%, #000 29.2%, #000 70.8%, rgba(0,0,0,.55) 78%, transparent 84.7%);
  mask-image: linear-gradient(180deg, transparent 15.3%, rgba(0,0,0,.55) 22%, #000 29.2%, #000 70.8%, rgba(0,0,0,.55) 78%, transparent 84.7%);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
}
@media (min-width: 430px)  { .wallgrid { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 720px)  { .wallgrid { grid-template-columns: repeat(6, 1fr); gap: 10px; inset: -22% -8%; } }
@media (min-width: 1024px) { .wallgrid { grid-template-columns: repeat(7, 1fr); gap: 12px; } }
.wallcol { overflow: hidden; }
.wallcol--5, .wallcol--6, .wallcol--7 { display: none; }
@media (min-width: 430px)  { .wallcol--5 { display: block; } }
@media (min-width: 720px)  { .wallcol--6 { display: block; } }
@media (min-width: 1024px) { .wallcol--7 { display: block; } }
.wallcol__rail { display: grid; gap: 7px; will-change: transform; }
@media (min-width: 720px) { .wallcol__rail { gap: 10px; } }

/* ClipCard: el mismo componente aquí y en el hero. Al llegar los vídeos se
   inserta <video>/<img> dentro y nada más cambia. */
.clipcard {
  position: relative; aspect-ratio: 9/16; border-radius: 10px; overflow: hidden;
  background: linear-gradient(165deg, rgba(255,255,255,.16), rgba(255,255,255,.045));
  border: 1px solid rgba(255,255,255,.15);
  box-shadow: 0 10px 26px -14px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.2);
}
.clipcard::after {
  content: ''; position: absolute; inset: 0;
  background: repeating-linear-gradient(115deg, rgba(255,255,255,.055) 0 2px, transparent 2px 17px);
}
.clipcard > img, .clipcard > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.clipcard__d {
  position: absolute; bottom: 5px; left: 5px; z-index: 2;
  font-size: .4375rem; font-weight: 700; color: #fff;
  background: rgba(0,0,0,.42); padding: 1px 4px; border-radius: 20px;
}
.wallcol--2 .clipcard { opacity: .9; }  .wallcol--3 .clipcard { opacity: .97; }
.wallcol--4 .clipcard { opacity: .86; } .wallcol--5 .clipcard { opacity: .8; }
.wallcol--6 .clipcard { opacity: .74; } .wallcol--7 .clipcard { opacity: .68; }

/* El texto va ABSOLUTO: no aporta altura al escenario (así la altura del
   documento no depende del texto) y se centra sobre el área útil REAL —dvh
   menos la navbar—, no sobre la caja de 100vh. Con dvh sólo aquí, plegar la
   barra de Safari recoloca el texto pero no cambia el layout: sin saltos. */
.fyp__copy {
  position: absolute; left: 0; right: 0; z-index: 2;
  top: calc(50vh + var(--nav-h) / 2);
  top: calc(50dvh + var(--nav-h) / 2);
  transform: translateY(-50%);
  padding-inline: var(--sp-4); text-align: center;
}
/* Halo bajo el texto: más ancho y con más paradas para que el degradado no
   corte. Dos capas —un núcleo denso y un velo amplio— separan el texto del
   muro sin que se note dónde empieza ni dónde acaba la sombra. */
.fyp__copy::before {
  content: ''; position: absolute; inset: -85% -120%;
  background:
    radial-gradient(46% 34% at 50% 50%,
      rgba(6,16,44,.92) 0%, rgba(6,16,44,.86) 26%, rgba(6,16,44,.62) 48%,
      rgba(6,16,44,.3) 66%, rgba(6,16,44,.1) 82%, transparent 94%),
    radial-gradient(78% 62% at 50% 50%,
      rgba(6,16,44,.5) 0%, rgba(6,16,44,.3) 40%, rgba(6,16,44,.12) 68%, transparent 88%);
  z-index: -1; pointer-events: none;
}
/* Los statements ocupan TODOS la misma celda: entran, se leen y salen en el
   mismo sitio. Antes era una lista vertical, así que el bloque crecía, el
   titular subía y varios se leían a la vez. Al estar todos siempre en el
   DOM y apilados, la celda mide lo que el más alto: la altura no cambia
   nunca y no hay salto. Opacidad y transform los escribe el scroll. */
.beats { display: grid; margin-top: var(--sp-5); }
.js .beats > * { grid-area: 1 / 1; }
.beat {
  font-size: var(--fs-lg); font-weight: 800; color: var(--text); letter-spacing: -.02em;
  align-self: center;
}
.js .beat { opacity: 0; will-change: opacity, transform; }
/* El párrafo es el último paso de la secuencia: comparte el mecanismo de
   entrada de las frases (.beat) pero conserva su propia voz tipográfica. */
.presence__body {
  font-size: var(--fs-sm); color: var(--text-3);
  max-width: 40ch; margin-inline: auto;
  font-weight: 400; letter-spacing: normal;
}
@media (prefers-reduced-motion: reduce) {
  .fyp { height: auto !important; }
  .fyp__sticky { position: static; height: auto; padding-block: var(--sp-8); }
  .fyp__copy { position: static; top: auto; transform: none; margin-top: var(--sp-6); }
  .wallgrid { position: relative; inset: auto; height: 56svh; }
  /* Sin apilar: se leen como lista, todos visibles */
  .js .beats > * { grid-area: auto; }
  .beats { gap: .35rem; }
  .js .beat, .beat { opacity: 1 !important; transform: none !important; visibility: visible !important; }
}

/* ─── Cards nuevas de casos ────────────────────────────────────────────── */
.cs__quote--big { font-size: clamp(1.125rem, .95rem + 1.2vw, 1.5rem); margin-top: var(--sp-3); line-height: 1.2; }
.chain { display: grid; gap: .1rem; margin-top: var(--sp-3); justify-items: start; }
.chain span { font-size: var(--fs-xs); font-weight: 700; color: var(--text-3); }
.chain i { font-style: normal; color: var(--accent); font-size: .8rem; line-height: 1; }
.cs__result {
  margin-top: var(--sp-4); padding: var(--sp-3); border-radius: var(--r);
  background: var(--accent-soft); border: 1px solid var(--line-2);
}
.cs__result b { display: block; font-size: clamp(1.25rem, 1.05rem + 1vw, 1.6rem); font-weight: 800; color: var(--accent); letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.cs__result span { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--text); }
.cs__result em { display: block; margin-top: .4rem; font-style: normal; font-size: var(--fs-xs); color: var(--text-mute); }

.ba { display: grid; gap: var(--sp-2); margin-top: var(--sp-3); }
.ba__side { padding: var(--sp-3); border-radius: var(--r); border: 1px solid var(--line); background: var(--surface-2); }
.ba__side--on { border-color: var(--accent); background: var(--accent-soft); }
.ba__l { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--text-mute); }
.ba__side--on .ba__l { color: var(--accent); }
.ba__side p { margin-top: .3rem; font-size: var(--fs-xs); color: var(--text-3); line-height: 1.4; }

/* Hueco de vídeo reutilizable: al llegar el archivo se sustituye el span
   por un <video> con la misma clase y el layout no se mueve. */
.vslot {
  position: relative; margin-top: var(--sp-5); aspect-ratio: 16/10;
  border-radius: var(--r); overflow: hidden;
  background: linear-gradient(160deg, rgba(255,255,255,.1), rgba(10,20,45,.35));
  border: 1px solid var(--line-2);
  backdrop-filter: blur(8px);
  display: grid; place-items: center;
}
.vslot__v { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vslot__play {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.9); color: var(--ink-900);
  box-shadow: 0 8px 24px -8px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.8);
}
.vslot__play svg { width: 16px; height: 16px; margin-left: 2px; }
.vslot__meta { position: absolute; left: 0; right: 0; bottom: 0; padding: var(--sp-3) var(--sp-4); }
.vslot__meta b { display: block; font-size: var(--fs-xs); font-weight: 800; color: var(--text); }
.vslot__meta span { font-size: .6875rem; color: var(--text-mute); }

/* ─── Data loop · capas y detalle ──────────────────────────────────────────
   Profundidad con glass, bloom y halos; iconografía de media (frame, chispa,
   cursor, ojo, tijeras, ondas, pulso, ciclo). Nada de nubes ni servidores. */
.lp__bloom { opacity: .5; }
.lp__glass {
  fill: rgba(255,255,255,.03); stroke: rgba(255,255,255,.07); stroke-width: 1;
}
.lp__disc { fill: var(--env-bg); stroke: var(--line-2); stroke-width: 1.5; transition: fill .4s, stroke .4s; }
.lp__node.on .lp__disc { fill: color-mix(in srgb, var(--accent) 16%, var(--env-bg)); stroke: var(--accent); }
.lp__dot { fill: var(--line-2); stroke: none; transition: fill .4s; }
.lp__node.on .lp__dot { fill: var(--accent); }
.lp__halo { fill: var(--accent); opacity: 0; transition: opacity .5s; }
.lp__node.on .lp__halo { opacity: .1; }
.lp__ico { fill: none; color: var(--text-mute); stroke: var(--text-mute); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; opacity: .45; transition: stroke .4s, opacity .4s; }
.lp__node.on .lp__ico { stroke: var(--accent); color: var(--accent); opacity: 1; }
/* El destello viaja en la punta del trazo: JS le escribe cx/cy */
.lp__spark { fill: #fff; opacity: 0; filter: drop-shadow(0 0 6px var(--accent)); }
.loop.live .lp__spark { opacity: .95; }
@media (prefers-reduced-motion: reduce) { .lp__spark { display: none; } }

/* ─── Solapamientos ────────────────────────────────────────────────────────
   La navbar es sticky y mide ~52px + su separación: sin esto, al saltar por
   un ancla el título queda por debajo de ella. scroll-margin-top lo resuelve
   sin añadir espacio visual cuando se llega scrolleando. */
[id] { scroll-margin-top: 84px; }

/* Las secciones fijadas (loop y FYP) reservan hueco para la navbar, para que
   ningún título quede parcialmente tapado al quedarse pegadas arriba. */
.loop__sticky { padding-top: calc(var(--sp-4) + 56px); }
@media (min-width: 960px) { .loop__sticky { padding-top: var(--sp-6); } }
/* El panel de clips NO reserva hueco para la navbar: ahora el propio
   fundido de la máscara despeja la zona de arriba. */

/* La navbar siempre por encima del contenido animado, y los lienzos de fondo
   siempre por debajo: sin esto un clip podía pasar por delante del menú. */
.nav { z-index: 90; }
.fyp__grid, .wall, .loop__viz { z-index: 0; }

/* El botón del formulario, centrado (los inputs mantienen su ancho) */
.form .btn-row { justify-content: center; }

/* ═══ REGLA GLOBAL: hooks y statements centrados ═══════════════════════════
   Todo bloque conceptual (hero, hook, statement, frase de transición) va
   centrado sobre un eje: no basta text-align, hace falta max-width + auto
   para que los saltos de línea queden equilibrados y se lea bien en móvil.
   Los párrafos largos, la data y el formulario NO entran en esta regla. */
.center-block { text-align: center; margin-inline: auto; }
.center-block h1, .center-block h2, .center-block h3 { margin-inline: auto; }
.statement { text-align: center; margin-inline: auto; max-width: 22ch; }
.statement--wide { max-width: 30ch; }
.statement--lede { max-width: 46ch; }
/* Sólo la cabecera conceptual va centrada. Todo lo que cuelgue debajo
   (listas, acordeones, formularios, data) recupera alineación editorial:
   el centrado indiscriminado fue el error de la ronda anterior. */
.sec-head-c { text-align: center; margin-inline: auto; max-width: 42rem; }
.sec-head-c .who, .sec-head-c .faq, .sec-head-c .calc, .sec-head-c .form { text-align: left; }
.sec-head-c .eyebrow { justify-content: center; }
.sec-head-c .eyebrow::before { display: none; }
.sec-head-c .lede { margin-inline: auto; }

/* ── Hero centrado sobre un eje ── */
.hero__stage { text-align: center; }
.hero__h { margin-inline: auto; max-width: 16ch; }
.hero__claim { text-align: center; }
.hero__cue { justify-content: center; }
.hero__lead { margin-inline: auto; text-align: center; }
@media (min-width: 900px) {
  /* Se anula la rejilla de dos columnas: el hero pasa a eje central y el
     muro corre a lo ancho por debajo del bloque de texto. */
  .hero__stage {
    display: flex; flex-direction: column; align-items: center;
    grid-template-columns: none; grid-template-areas: none;
  }
  .hero__h, .hero__lead, .hero__claim, .hero__cta, .hero__cue, .hero__field { grid-area: auto; }
  .hero__cta { justify-content: center; }
  .hero__field { width: 100%; order: 2; }
  .hero__field .wall { width: 100vw; margin-left: 50%; transform: translateX(-50%); }
  .hero__lead { order: 6; max-width: 52ch; }
}

/* ── Las dos filas del muro, idénticas ──
   Se quita la reducción de escala/opacidad de la fila 2: mismo tamaño,
   mismo gap, misma densidad, sólo cambia la dirección. */
.wall__row--b .wclip { transform: none; opacity: 1; }

/* ═══ Data loop · escenario central ════════════════════════════════════════
   El anillo exterior mantiene la arquitectura; el interior es un escenario
   que cambia con la etapa activa. Sólo una escena visible a la vez: entran
   y salen con opacity+scale, sin acumular ruido. */
.loop__scenes {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 52%; aspect-ratio: 1; display: grid; place-items: center;
  pointer-events: none; z-index: 2;
}
.scene {
  grid-area: 1/1; width: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .5rem;
  opacity: 0; transform: scale(.94); transition: opacity .45s var(--ease), transform .5s var(--ease);
}
.scene.on { opacity: 1; transform: none; }
.sc-cap { font-size: .5625rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute); }

@media (prefers-reduced-motion: reduce) {
  .sv-scanline, .sv-edit__head, .sv-ph, .sv-ac, .sv-d1, .sv-d2, .sv-flow i, .sv-learn__in, .sv-bar i { animation: none !important; }
}

/* ═══ Data loop · visualizaciones por etapa ════════════════════════════════
   Regla: si se mira sin leer el título, debe intuirse qué ocurre.
   El contenido de origen va SIEMPRE horizontal (es un podcast/directo);
   lo vertical sólo aparece cuando el sistema ya recortó la pieza. */
.sv-cap { font-size: .5rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--text-mute); text-align: center; }

/* 01/02 · pieza horizontal y su lectura */
.sv-long { position: relative; width: 116px; aspect-ratio: 16/9; border-radius: 6px;
  background: linear-gradient(160deg, var(--blue-700), var(--ink-900));
  border: 1px solid rgba(255,255,255,.16); overflow: hidden; display: grid; place-items: center; }
.sv-long__bar { position: absolute; left: 6px; right: 6px; bottom: 5px; height: 2px; border-radius: 2px; background: rgba(255,255,255,.28); }
.sv-long__play { width: 0; height: 0; border-left: 9px solid rgba(255,255,255,.9); border-block: 6px solid transparent; margin-left: 3px; }
.sv-marks { position: absolute; left: 6px; right: 6px; bottom: 5px; height: 2px; }
.sv-marks i { position: absolute; top: -3px; width: 3px; height: 8px; border-radius: 2px; background: var(--accent-2); transform: translateX(-50%); opacity: 0; }
.scene.on .sv-marks i { animation: svMark .4s var(--ease-out) both; }
.sv-marks i:nth-child(1){animation-delay:.15s} .sv-marks i:nth-child(2){animation-delay:.25s}
.sv-marks i:nth-child(3){animation-delay:.35s} .sv-marks i:nth-child(4){animation-delay:.45s}
.sv-marks i:nth-child(5){animation-delay:.55s} .sv-marks i:nth-child(6){animation-delay:.65s}
.sv-marks i:nth-child(7){animation-delay:.75s}
@keyframes svMark { from { opacity: 0; transform: translateX(-50%) scaleY(.2) } to { opacity: 1; transform: translateX(-50%) } }
.sv-scanline { position: absolute; top: 0; bottom: 0; width: 28px; left: -28px;
  background: linear-gradient(90deg, transparent, rgba(122,170,255,.5), transparent); }
.scene.on .sv-scanline { animation: svScan 2.2s ease-in-out infinite; }
@keyframes svScan { from { left: -28px } to { left: 116px } }

/* 03 · candidatos comparados */
.sv-list { display: grid; gap: 4px; width: 132px; }
.sv-cand { display: flex; align-items: center; gap: 6px; }
.sv-cand b { font-family: var(--font-mono); font-size: .4375rem; font-weight: 700; color: var(--text-mute); width: 26px; }
.sv-bar { flex: 1; height: 7px; border-radius: 4px; background: var(--surface-2); border: 1px solid var(--line-2); overflow: hidden; }
.sv-bar i { display: block; height: 100%; width: 0; border-radius: 4px; background: var(--accent); }
.scene.on .sv-bar i { animation: svFill .6s var(--ease-out) forwards; }
.sv-cand:nth-child(2) .sv-bar i { animation-delay: .08s } .sv-cand:nth-child(3) .sv-bar i { animation-delay: .16s }
.sv-cand:nth-child(4) .sv-bar i { animation-delay: .24s } .sv-cand:nth-child(5) .sv-bar i { animation-delay: .32s }
@keyframes svFill { to { width: var(--w) } }
.sv-cand.is-drop { opacity: .38 } .sv-cand.is-drop .sv-bar i { background: var(--text-mute) }

/* 04 · revisión humana */
.sv-review { display: grid; gap: 4px; width: 128px; }
.sv-review__row { display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 3px 6px; border-radius: 5px; border: 1px solid var(--accent); background: var(--accent-soft); }
.sv-review__row b { font-family: var(--font-mono); font-size: .4375rem; color: var(--text-3); }
.sv-review__row span { font-size: .4375rem; font-weight: 800; }
.sv-review__row .ok { color: var(--green-500) }
.sv-review__row.is-edit { border-color: var(--accent-2) } .sv-review__row .ed { color: var(--accent-2) }
.sv-review__row.is-no { border-color: var(--line-2); background: transparent; opacity: .45 }
.sv-review__row .no { color: var(--red-500) }

/* 05 · edición: el horizontal se reencuadra a vertical */
.sv-edit { display: flex; align-items: center; gap: 10px; }
.sv-edit__src { position: relative; width: 78px; aspect-ratio: 16/9; border-radius: 5px;
  background: linear-gradient(160deg, var(--blue-700), var(--ink-900)); border: 1px solid rgba(255,255,255,.15); }
.sv-edit__crop { position: absolute; top: 3px; bottom: 3px; left: 50%; width: 26px; transform: translateX(-50%);
  border: 1.5px solid var(--accent-2); border-radius: 3px; box-shadow: 0 0 0 40px rgba(3,8,20,.5); }
.sv-edit__out { width: 26px; aspect-ratio: 9/16; border-radius: 4px;
  background: linear-gradient(160deg, var(--accent), var(--blue-900)); border: 1px solid rgba(255,255,255,.2); }
.sv-edit__tl { position: relative; width: 116px; height: 8px; margin-top: 8px; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--line-2); overflow: hidden; }
.sv-edit__head { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent); left: 8%; }
.scene.on .sv-edit__head { animation: svHead 3s linear infinite; }
@keyframes svHead { from { left: 5% } to { left: 95% } }
.sv-chips { display: flex; gap: 4px; margin-top: 7px; }
.sv-chips span { font-size: .4375rem; font-weight: 700; color: var(--accent); background: var(--accent-soft);
  border: 1px solid var(--line-2); padding: 2px 5px; border-radius: 20px; }

/* 06 · Distribución jerárquica: 1 pieza → 5 dispositivos → 25 cuentas.
   Nada de partículas sueltas: cada trazo y cada punto significan algo. Los
   dos niveles se dibujan en dos tandas para que se lea la jerarquía. */
.sv-net { width: 158px; height: 126px; overflow: visible; }
.sv-src { fill: var(--accent); }
.sv-d1, .sv-d2 {
  fill: none; stroke: var(--accent); stroke-linecap: round;
  stroke-dasharray: 70; stroke-dashoffset: 70;
}
.sv-d1 { stroke-width: .9; opacity: .7; }
.sv-d2 { stroke-width: .5; opacity: .4; }
.scene.on .sv-d1, .scene.on .sv-d2 {
  animation: svDraw .55s var(--ease-out) both; animation-delay: var(--d, 0s);
}
@keyframes svDraw { to { stroke-dashoffset: 0 } }

.sv-ph rect { fill: color-mix(in srgb, var(--accent) 18%, var(--env-bg)); stroke: var(--accent); stroke-width: .8; }
.sv-ph .sv-ph__scr { fill: var(--accent); stroke: none; opacity: .55; }
.sv-ph { opacity: 0; transform-box: fill-box; transform-origin: center; }
.scene.on .sv-ph { animation: svPop .32s var(--ease-out) both; animation-delay: var(--d, 0s); }

.sv-ac { fill: var(--accent); opacity: 0; transform-box: fill-box; transform-origin: center; }
.scene.on .sv-ac { animation: svPop .3s var(--ease-out) both; animation-delay: var(--d, 0s); }
@keyframes svPop { from { opacity: 0; transform: scale(.2) } to { opacity: .9; transform: none } }

/* 07 · señales que vuelven */
.sv-mets { display: grid; gap: 3px; width: 120px; }
.sv-met { display: flex; align-items: center; justify-content: space-between;
  padding: 3px 7px; border-radius: 5px; background: var(--surface-2); border: 1px solid var(--line-2); }
.sv-met b { font-size: .4375rem; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; }
.sv-met span { font-size: .5rem; color: var(--green-500); font-weight: 800; }
.sv-flow { display: flex; gap: 5px; margin-top: 7px; }
.sv-flow i { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); opacity: .3; }
.scene.on .sv-flow i { animation: svFlow 1.4s ease-in-out infinite; }
.sv-flow i:nth-child(2){animation-delay:.16s} .sv-flow i:nth-child(3){animation-delay:.32s}
@keyframes svFlow { 0%,100% { transform: translateX(5px); opacity: .25 } 50% { transform: translateX(-5px); opacity: 1 } }

/* 08 · lo aprendido regresa al modelo */
.sv-learn { position: relative; width: 120px; height: 54px; display: grid; place-items: center; }
.sv-learn__model { width: 26px; height: 26px; border-radius: 8px;
  background: linear-gradient(150deg, var(--accent), var(--blue-700)); box-shadow: 0 0 18px -4px var(--accent); }
.sv-learn__in { position: absolute; right: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2); }
.sv-learn__in:nth-of-type(2) { top: 6px } .sv-learn__in:nth-of-type(3) { top: 24px } .sv-learn__in:nth-of-type(4) { top: 42px }
.scene.on .sv-learn__in { animation: svIn 1.8s ease-in-out infinite; }
.sv-learn__in:nth-of-type(3) { animation-delay: .3s } .sv-learn__in:nth-of-type(4) { animation-delay: .6s }
@keyframes svIn { 0% { transform: translateX(0); opacity: 0 } 30% { opacity: 1 } 100% { transform: translateX(-84px); opacity: 0 } }

/* Identidad de la card: hueco de foto listo, terminado sin ella */
.cs__id { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-2); }
.cs__av {
  width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto; overflow: hidden;
  display: grid; place-items: center;
  background: linear-gradient(150deg, var(--accent-2), var(--blue-700));
  color: #fff; font-weight: 800; font-size: .625rem;
}
.cs__av img { width: 100%; height: 100%; object-fit: cover; }
.cs--dark .cs__av { background: linear-gradient(150deg, #3B4763, var(--ink-900)); }


/* El loop entra en cuanto pasa su titular: sin padding inferior propio, el
   círculo aparece antes y no queda una franja de transición sin nada. */
.loop { padding-bottom: 0; }
.loop > .wrap { padding-bottom: var(--sp-4); }
.rm__close { margin-top: var(--sp-5); padding-top: var(--sp-5); }

/* ═══ DATA LOOP · tiempos y cierre ══════════════════════════════════════════
   Cada etapa va nodo → gráfico → texto → hold → salida, y ninguna de esas
   piezas pisa a la siguiente. El bloque lateral se desvanece entre etapas
   para que el texto nunca aparezca antes de que se entienda la animación. */
.loop__stage {
  opacity: 0; transform: translateY(10px);
  transition: opacity .4s var(--ease), transform .45s var(--ease-out);
}
.loop__stage.on { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .loop__stage { opacity: 1 !important; transform: none !important; }
}

/* Arco de barrido del cierre: repasa el círculo entero por encima del arco
   de progreso mientras los nodos se encienden uno a uno. */
.lp__sweep {
  fill: none; stroke: var(--accent); stroke-width: 3.5; stroke-linecap: round;
  opacity: 0; transition: opacity .4s ease;
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--accent) 70%, transparent));
}
.loop.closing .lp__sweep { opacity: .95; }

/* Momento en que el sistema entero queda encendido a la vez */
.loop.all-on .lp__halo { opacity: .22; }
.loop.all-on .lp__ring { opacity: .6; }
.loop.all-on .lp__sweep { stroke-width: 4.5; }
.loop.all-on .lp__bloom { opacity: .95; }
.lp__bloom { transition: opacity .6s var(--ease); }

/* Statement final, en el centro del círculo */
.loop__close {
  position: absolute; inset: 15%; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .7rem; text-align: center; pointer-events: none;
  padding-inline: 2%;
  opacity: 0; transition: opacity .5s var(--ease);
}
.loop__close.on { opacity: 1; }
/* El titular se escribe letra a letra: un fantasma con el texto completo
   reserva la caja, y el texto real se dibuja encima en la misma celda. Así
   la composición es la definitiva desde el primer carácter y no salta de
   línea al ir apareciendo. Los saltos vienen del contenido (pre-line). */
.loop__close-h {
  display: grid; white-space: pre-line;
  font-size: clamp(.88rem, .72rem + .8vw, 1.18rem); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.22; color: var(--text);
  text-wrap: balance;
}
.loop__close-h > * { grid-area: 1 / 1; }
.loop__close-ghost { visibility: hidden; }
.loop__close-c {
  white-space: pre-line;
  font-size: clamp(.62rem, .56rem + .3vw, .78rem);
  color: var(--text-3); line-height: 1.45;
  max-width: 24ch; opacity: 0; transition: opacity .55s var(--ease) .25s;
}
.loop.all-on .loop__close-c { opacity: 1; }
/* Con el círculo encendido, el interior se oscurece un punto para que el
   statement se lea sin competir con el glow. */
.loop.closing .lp__glass { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .loop__close { position: static; inset: auto; opacity: 1; margin-top: var(--sp-5); }
  .lp__sweep { display: none; }
}


/* ═══ CASOS DE ÉXITO · jerarquía ════════════════════════════════════════════
   Lo primero que entra por los ojos es la cifra. La identidad va sobre una
   banda que es, literalmente, el hueco para la foto del cliente. */

/* 1 · Banda de imagen + identidad encima */
.cs__band {
  /* flex:0 0 auto es imprescindible: sin ello el flex de .cs__pad encogía la
     banda de forma distinta en cada card (109/70/84/67px) y el hueco de la
     foto dejaba de ser un hueco fiable. */
  flex: 0 0 auto;
  position: relative; margin-top: var(--sp-2);
  aspect-ratio: 5 / 2; border-radius: var(--r);
  overflow: hidden; background: var(--surface-2);
  display: flex; align-items: flex-end;
}
.cs__band img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cs__band-ph {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 95% at 18% 0%, color-mix(in srgb, var(--accent) 26%, transparent), transparent 68%),
    linear-gradient(150deg, var(--ink-800), var(--ink-1000));
}
.cs__band-ph::after {
  content: ''; position: absolute; inset: 0;
  background: repeating-linear-gradient(118deg, rgba(255,255,255,.05) 0 2px, transparent 2px 16px);
}
.cs__band .cs__id {
  position: relative; z-index: 1; width: 100%; margin: 0;
  padding: var(--sp-4) var(--sp-3) var(--sp-3);
  background: linear-gradient(to top, rgba(3,10,30,.9) 25%, rgba(3,10,30,.35) 70%, transparent);
}
/* Sobre la banda el texto siempre va en claro, en card clara y oscura */
.cs__band .cs__who { color: #fff; }
.cs__band .cs__ctx { color: rgba(255,255,255,.7); }

/* 2 · La cifra manda */
.cs__mega { font-size: clamp(3.5rem, 2.6rem + 5vw, 4.8rem); line-height: .84; }
.cs__megaSub { font-size: var(--fs-sm); margin-top: .4rem; }
.cs__result b { font-size: clamp(2.7rem, 2rem + 3.4vw, 3.6rem); line-height: .88; }
.cs__result { margin-top: var(--sp-3); padding: var(--sp-3) var(--sp-3) var(--sp-4); }

/* 3 · Cifra secundaria clara, sin competir con la principal */
.cs__second b, .cs__inline b { font-size: clamp(1.05rem, .9rem + .6vw, 1.3rem); }
.cs__second { margin-top: var(--sp-3); padding-top: var(--sp-3); gap: var(--sp-4); }

/* 4 · Soporte visual: red multicuenta, no barras */
.netviz { margin-top: var(--sp-3); }
.netviz svg { width: 100%; height: auto; max-height: 84px; overflow: visible; }
.nv__src { fill: var(--accent); }
.nv__e {
  fill: none; stroke: var(--accent); stroke-width: .8; opacity: .45;
  stroke-dasharray: 90; stroke-dashoffset: 90;
}
.cs.on .nv__e { animation: nvDraw .6s var(--ease-out) both; animation-delay: var(--d, 0s); }
@keyframes nvDraw { to { stroke-dashoffset: 0 } }
.nv__n { fill: var(--accent); opacity: 0; transform-box: fill-box; transform-origin: center; }
.cs.on .nv__n { animation: nvPop .32s var(--ease-out) both; animation-delay: var(--d, 0s); }
@keyframes nvPop { from { opacity: 0; transform: scale(.2) } to { opacity: .9; transform: none } }
@media (prefers-reduced-motion: reduce) {
  .nv__e, .nv__n { animation: none !important; stroke-dashoffset: 0; opacity: .8; }
}

/* La curva de continuidad ocupaba 244px de alto y desbordaba la card */
.lines svg { max-height: 118px; }
.lines { flex: 0 1 auto; min-height: 0; }

/* ═══ CLIPS REALES ═════════════════════════════════════════════════════════
   La imagen entra DENTRO de .wclip / .clipcard / .cs__band, que ya tenían
   overflow:hidden y su aspect-ratio. No cambia ni un tamaño ni una animación:
   solo se rellena el hueco que ya estaba previsto. */
.cimg, .cs__band img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* El degradado del placeholder se mantiene debajo como color de carga */
.wclip, .clipcard { background-color: var(--ink-900); }

/* Overlay de métricas: discreto, sin logos de plataforma, con la tipografía
   y el radio del sistema. Se apoya en un velo inferior para que la cifra se
   lea sobre cualquier fotograma. */
.cmets {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; flex-wrap: wrap; gap: .35rem .5rem;
  padding: .9rem .4rem .3rem;
  background: linear-gradient(to top, rgba(3,10,30,.8), transparent);
  pointer-events: none;
}
.cmet {
  display: inline-flex; align-items: center; gap: .16rem;
  font-size: .5rem; font-weight: 800; color: #fff;
  letter-spacing: -.01em; font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.cmet svg {
  width: .62em; height: .62em; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
/* En la banda de los casos hay sitio de sobra: cifras mayores y separadas */
.cs__band .cmets { padding: 1.4rem var(--sp-3) .5rem; gap: .5rem .9rem; bottom: auto; top: 0;
  background: linear-gradient(to bottom, rgba(3,10,30,.72), transparent); }
.cs__band .cmet { font-size: .68rem; }

/* Aviso de error del formulario. Solo aparece si el envío falla de verdad:
   antes el form siempre pintaba "gracias" aunque no mandara nada. */
.form__err {
  margin-top: var(--sp-3); padding: var(--sp-3);
  border-radius: var(--r); text-align: center;
  font-size: var(--fs-sm); font-weight: 700; line-height: 1.4;
  color: var(--red-500);
  background: color-mix(in srgb, var(--red-500) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--red-500) 30%, transparent);
}
