/* =====================================================================
   Norus — Capa premium (NorusAnalytics2)
   ---------------------------------------------------------------------
   Se carga la ÚLTIMA, después de styles.css, nsa.css y nsa-hero.css, y
   las sobrescribe sin tocarlas: si algo de aquí sobra, se quita el
   <link> y la web vuelve a ser la de NorusAnalytics. Paleta intacta:
   violeta #8B5CF6 / #6D28D9 / #7C3AED, lavanda #A78BFA, fondo #080B12,
   línea #1B2230, texto #F8FAFC. No hay ningún color nuevo.

   ÍNDICE
   1 · Tokens (movimiento, tipografía, espacio, superficies)
   2 · Base: tipografía, foco, selección, transición entre páginas
   3 · Cabecera: subrayado, sección activa, progreso de lectura
   4 · Sistema de revelado: palabras, bloques, secuencia del héroe
   5 · Botones y superficies (foco de luz que sigue al puntero)
   6 · Cabeceras de sección editoriales
   7 · Héroe: titular y CTA
   8 · Franja de pilares
   9 · Solución: explorador de preguntas
  10 · Servicios
  11 · Proceso: «el viaje del dato»
  12 · Planificación y precios
  13 · FAQ, CTA, contacto y formulario
  14 · Pie, CTA móvil, volver arriba
  15 · Cursor-sector
  16 · Pantalla de carga y ventana de demostración
  17 · Movimiento reducido · contraste forzado · sin JavaScript
===================================================================== */

/* ---------------------------------------------------------
   1 · TOKENS
   Un único vocabulario de movimiento para toda la web. Curvas de
   la skill `animate` (no inventadas): salida fuerte para entradas,
   entrada-salida fuerte para lo que se mueve en pantalla. La curva
   «expo» es la que ya usaba el héroe (--ease-out-expo).
--------------------------------------------------------- */
:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);

  --dur-press: 140ms;   /* pulsar: respuesta inmediata */
  --dur-fast: 200ms;    /* hover, foco, tooltips */
  --dur-base: 320ms;    /* cambios de estado, menús, ventana */
  --dur-slow: 700ms;    /* revelado al hacer scroll */
  --dur-scene: 1000ms;  /* coreografía del héroe y del viaje del dato */
  --stagger: 60ms;      /* escalón entre hermanos que entran juntos */

  --fs-hero: clamp(2.125rem, 1.1rem + 2.15vw, 3.75rem);
  --fs-h2: clamp(1.875rem, 1rem + 2.7vw, 3.25rem);
  --fs-h3: clamp(1.125rem, 1.04rem + 0.45vw, 1.375rem);
  --fs-lead: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  --fs-micro: 0.75rem;

  --sp-section: clamp(88px, 9vw, 148px);

  --hair: rgba(167, 139, 250, 0.16);
  --hair-strong: rgba(167, 139, 250, 0.34);
  --surface: linear-gradient(158deg, rgba(30, 37, 57, 0.86) 0%, rgba(14, 18, 30, 0.94) 58%, rgba(11, 14, 23, 0.97) 100%);
  --focus: var(--lavender);
}

/* ---------------------------------------------------------
   2 · BASE
   Inter autoalojada solo trae el eje de grosor y los números
   tabulares (medido: no incluye alternates ni eje óptico), así que el
   oficio tipográfico sale de tres cosas: interletraje por tamaño,
   grosor 600–650 en titulares y reparto de líneas equilibrado.
--------------------------------------------------------- */
/* `color-scheme: dark` pinta de oscuro lo que el navegador dibuja por su
   cuenta: casillas, desplegables, burbujas de validación y barras. */
:root { color-scheme: dark; }
html { text-rendering: optimizeLegibility; }
.demo-modal-head h2 { font-size: 15px; font-weight: 700; margin: 0; letter-spacing: 0; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
.num, .ch-table td, .nsa-legend em, .bm-value { font-variant-numeric: tabular-nums; }
/* Inter 4: en las etiquetas en mayúsculas, `case` alinea signos y guiones con
   la altura de las capitales (el punto medio, los paréntesis…). */
.eyebrow, .et .et-n, .proof-u, .pillar b, .footer-col h5 { font-feature-settings: "case"; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

/* Transición entre páginas (inicio ↔ páginas legales). Sin JavaScript:
   el navegador funde la instantánea saliente con la entrante. Donde no
   se soporta (Firefox hoy), la navegación es la de siempre. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--dur-base);
  animation-timing-function: var(--ease-out);
}

/* ---------------------------------------------------------
   3 · CABECERA
--------------------------------------------------------- */
.nav-progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg, var(--violet), var(--lavender));
  transform-origin: 0 50%;
  transform: scaleX(var(--p, 0));
  opacity: 0.9;
  pointer-events: none;
}
.nav-links { gap: clamp(20px, 2.1vw, 34px); }
.nav-links a { position: relative; padding: 8px 2px; }
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 2px;
  height: 1px;
  background: var(--lavender);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav-links a[aria-current="true"] { color: var(--text); }
.nav-links a[aria-current="true"]::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .nav-links a:hover::after { transform: scaleX(1); }
}
/* 6 enlaces + marca + CTA necesitan ≈ 900 px de ancho útil (medido: a
   1081 px sobran 103 px a cada lado de los enlaces), así que el menú
   compacto entra a 1000 px y no a los 900 de NorusAnalytics. */
@media (max-width: 1000px) {
  .nav-links { display: none; }
  .nav-toggle { display: flex; }
  .nav-cta .btn-ghost { display: none; }
}
/* El menú móvil tiene 7 enlaces + botón (≈ 445 px). En un móvil en
   horizontal (375–414 px de alto) se salía por abajo y los últimos enlaces
   eran inalcanzables. Ahora no pasa del alto visible (menos la cabecera) y
   hace scroll por dentro; `overscroll-behavior` evita que arrastre la
   página; `data-lenis-prevent` (en el HTML) deja el scroll nativo. */
.mobile-menu {
  max-height: calc(100vh - 100px);
  max-height: calc(100dvh - 100px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
@media (max-height: 520px) {
  .mobile-menu { padding: 12px 16px; gap: 2px; }
  .mobile-menu a { padding: 9px 6px; }
  .mobile-menu .mobile-cta { margin-top: 6px; }
}

/* ---------------------------------------------------------
   4 · SISTEMA DE REVELADO
   Tres piezas, todas con CSS (transform + opacity, compositor) y un
   solo disparador: la clase `.is-in`, que pone nsa-motion.js cuando
   el elemento entra en pantalla. Nada de GSAP para esto: una
   transición CSS se puede interrumpir y no compite por el hilo
   principal mientras carga el vídeo.
--------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
}
/* Se anima con `animation` y no con `transition`: las tarjetas ya traen
   su propio `transition` (hover de fondo) con más especificidad y se
   comerían el de aquí. Con `backwards` el elemento espera invisible
   durante su retraso y, al terminar, queda con los estilos base, así
   que el hover y los transforms posteriores siguen funcionando. */
.reveal.is-in {
  opacity: 1;
  transform: none;
  animation: nsaReveal var(--dur-slow) var(--ease-out) backwards;
  animation-delay: calc(var(--rd, 0) * var(--stagger));
}
@keyframes nsaReveal {
  from { opacity: 0; transform: translate3d(0, 22px, 0); }
}

/* Titulares: cada palabra sube desde una máscara. */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}
.wi {
  display: inline-block;
  transform: translate3d(0, 108%, 0);
  transition: transform var(--dur-scene) var(--ease-expo);
  transition-delay: calc(var(--wi, 0) * 55ms + var(--wd, 0ms));
}
.is-in .wi { transform: none; }

/* El degradado de «próximo paso» pasa de la caja al glifo de cada
   palabra: un recorte de texto no atraviesa inline-blocks. */
.hero h1 .accent {
  animation: none;       /* el brillo en bucle repintaba el texto cada fotograma */
  background-size: auto;
}
.hero h1[data-split-done] .accent { background: none; }
.hero h1 .accent .wi {
  background: linear-gradient(135deg, var(--lavender), var(--violet) 62%, var(--violet-mid));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Secuencia del héroe: tras la pantalla de carga entra el titular, y
   a continuación —cada elemento un escalón después— el resto. */
.hero.is-ready .reveal {
  opacity: 1;
  transform: none;
  animation: nsaReveal var(--dur-scene) var(--ease-expo) backwards;
  animation-delay: calc(var(--rd, 0) * 90ms + 380ms);
}

/* ---------------------------------------------------------
   5 · BOTONES Y SUPERFICIES
--------------------------------------------------------- */
.btn {
  transition:
    scale var(--dur-press) var(--ease-out),
    translate var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}
.btn:active { scale: 0.97; }
.btn-primary {
  box-shadow: 0 8px 30px rgba(139, 92, 246, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-primary:hover { transform: none; translate: 0 -1px; box-shadow: 0 14px 40px rgba(139, 92, 246, 0.42), inset 0 1px 0 rgba(255, 255, 255, 0.28); }
.btn-ghost:hover, .btn-light:hover { transform: none; }
.btn .btn-ico { width: 15px; height: 15px; flex: none; }
.btn[disabled] { opacity: 0.7; cursor: progress; }
@media (hover: none) {
  .btn-primary:hover { translate: none; }
}

/* Brillo suave que sigue al puntero dentro de una tarjeta: señala la
   zona que se está mirando, sin abrir ni mostrar nada. Solo con ratón; en
   táctil no existe. JS escribe `--mx`/`--my` en la propia tarjeta. */
@media (hover: hover) and (pointer: fine) {
  [data-spot] { position: relative; isolation: isolate; }
  [data-spot]::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    z-index: -1;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out);
    background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%), rgba(167, 139, 250, 0.13), transparent 62%);
  }
  [data-spot]::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out);
    background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(196, 181, 253, 0.6), transparent 70%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  }
  [data-spot]:hover::before, [data-spot]:hover::after { opacity: 1; }
}

/* ---------------------------------------------------------
   6 · CABECERAS DE SECCIÓN
   Todas igual: etiqueta fina, titular a la izquierda, apoyo a la
   derecha. Antes tres se centraban y tres no.
--------------------------------------------------------- */
/* `overflow: clip` y no `hidden`: recorta igual los halos de sección pero
   NO crea un contenedor de scroll, que es lo que rompía `position: sticky`
   (el objeto del Proceso y la cabecera del FAQ) dentro de cada sección. En
   un navegador sin `clip` la regla se descarta y queda el `hidden` de
   styles.css: la web se ve igual, solo sin el efecto fijo. */
.section { padding: var(--sp-section) 0; overflow: clip; }
.section-tight { padding: calc(var(--sp-section) * 0.6) 0; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 22px;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--lavender);
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}
.eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--lavender));
}

.sec-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-bottom: clamp(40px, 5vw, 72px);
}
.sec-head > .eyebrow { grid-column: 1 / -1; justify-self: start; }
h2.h2 {
  font-size: var(--fs-h2);
  font-weight: 620;
  letter-spacing: -0.03em;
  line-height: 1.04;
  max-width: 20ch;
  margin: 0;
}
.sec-head .sec-side { margin-top: 20px; display: grid; gap: 22px; justify-items: start; }
.sec-side p { font-size: var(--fs-lead); line-height: 1.55; max-width: 46ch; }
@media (min-width: 960px) {
  .sec-head { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(40px, 6vw, 96px); align-items: end; }
  .sec-head .sec-side { margin-top: 0; padding-bottom: 6px; }
}

/* ---------------------------------------------------------
   7 · HÉROE
--------------------------------------------------------- */
.hero .hero-copy h1 {
  font-size: var(--fs-hero);
  font-weight: 640;
  letter-spacing: -0.032em;
  line-height: 1.03;
  margin-bottom: 22px;
}
/* Línea de palabras clave dentro del h1 (SEO): se lee como una etiqueta de
   sección, no como parte del titular. */
.hero h1 .h1-kicker {
  display: block;
  margin-bottom: 20px;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.18em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--lavender);
  text-shadow: none;
  font-feature-settings: "case";
}
.hero .hero-copy p.lead {
  font-size: var(--fs-lead);
  line-height: 1.55;
  max-width: 34em;
  margin-bottom: 32px;
}
.hero .hero-cta { gap: 12px; flex-wrap: wrap; }
.hero .hero-cta .btn { padding: 15px 26px; }
.btn-demo { gap: 10px; }
.btn-demo .btn-ico { width: 13px; height: 13px; }
.hero-trust { margin-top: 22px; }
@media (max-width: 600px) {
  .hero .hero-cta .btn { width: 100%; }
}

/* ---------------------------------------------------------
   8 · FRANJA DE PILARES
   Los cuatro mensajes de la portada pasan aquí: la portada deja
   de competir consigo misma y la franja hace de prueba de método.
--------------------------------------------------------- */
.pillars { position: relative; padding: clamp(8px, 2vw, 24px) 0 0; }
.pillar-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}
.pillar {
  padding: 28px clamp(16px, 2.2vw, 36px);
  border-left: 1px solid var(--hair);
}
.pillar:first-child { border-left: 0; padding-left: 0; }
.pillar b {
  display: block;
  margin-bottom: 10px;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lavender);
}
.pillar span { display: block; font-size: 0.9375rem; line-height: 1.5; color: var(--text-dim); }
@media (max-width: 900px) {
  .pillar-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pillar:nth-child(odd) { border-left: 0; padding-left: 0; }
  .pillar:nth-child(n+3) { border-top: 1px solid var(--hair); }
}
@media (max-width: 420px) {
  .pillar span { display: none; }
  .pillar { padding-block: 18px; }
  .pillar b { margin: 0; }
}

/* ---------------------------------------------------------
   9 · SOLUCIÓN (antes «El sistema») — explorador de preguntas
   Cada pregunta de negocio enseña el informe que la responde. Las
   capturas son fotogramas del vídeo de demostración (datos ficticios);
   que hoy sean cuatro es cosa de la demo, no de la solución.
--------------------------------------------------------- */
/* Base (< 1240 px): una columna, las preguntas arriba y el informe debajo.
   `.explorer-stage` se disuelve (display: contents) para que sus hijos
   —el marco y el pie del informe— entren directamente en la rejilla, y así
   en escritorio las preguntas y el marco pueden compartir fila. */
.explorer {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 18px;
}
.explorer-stage { display: contents; }
.explorer-tabs { display: flex; flex-direction: column; gap: 6px; }
.et {
  display: grid;
  gap: 6px;
  width: 100%;
  padding: 20px 22px;
  text-align: left;
  font: inherit;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 16px;
  cursor: pointer;
  transition:
    background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}
.et .et-n {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dimmer);
  transition: color var(--dur-base) var(--ease-out);
}
.et .et-q { font-size: 1.0625rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.012em; }
.et .et-d {
  display: grid;
  grid-template-rows: 0fr;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text-dim);
  transition: grid-template-rows var(--dur-base) var(--ease-out);
}
.et .et-d > span { overflow: hidden; }
.et[aria-selected="true"] {
  background: var(--surface);
  border-color: var(--hair-strong);
  color: var(--text);
}
.et[aria-selected="true"] .et-n { color: var(--lavender); }
.et[aria-selected="true"] .et-d { grid-template-rows: 1fr; }
.et[aria-selected="true"] .et-d > span { padding-top: 4px; }
@media (hover: hover) and (pointer: fine) {
  .et:not([aria-selected="true"]):hover { background: rgba(167, 139, 250, 0.06); color: var(--text); }
}

/* Marco del informe. El margen oscuro es el mismo por los cuatro lados: el
   `padding` en % se calcula siempre sobre el ANCHO, así que arriba y abajo
   valen lo mismo que a los lados. Los informes están recortados a la ventana
   de Power BI (sin la franja oscura del vídeo, que era desigual), y la
   proporción del marco es la del informe (1260 × 708) más ese margen:
   (1 − 2·1,3 %) · 708/1260 + 2·1,3 % = 0,573 del ancho. */
.shots {
  justify-self: stretch;
  position: relative;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  padding: 1.3%;
  aspect-ratio: 1000 / 573;
  border-radius: 20px;
  border: 1px solid var(--hair-strong);
  background: #0A1927;
  box-shadow: 0 50px 110px -40px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(8, 11, 18, 0.6);
}
.shot {
  grid-area: 1 / 1;
  min-width: 0;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
}
.shot.is-active { opacity: 1; visibility: visible; transition-delay: 0s; }
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
}
.shot-note { font-size: 0.8125rem; color: var(--text-dimmer); margin: 0; }
.shot-open { font-size: 0.875rem; padding: 11px 20px; }

/* El informe es pulsable (abre la demo en su capítulo): el cursor lo dice
   con la misma etiqueta «Ver demo» que los botones de demostración. */
.shots { cursor: pointer; }

/* Escritorio (≥ 1240 px): preguntas a la izquierda y marco del informe a la
   derecha en la MISMA fila, así que miden lo mismo; la nota y el botón van
   debajo, en la fila 2. Las cuatro preguntas se reparten ese alto a partes
   iguales (`flex: 1 1 auto`) y su contenido va centrado. Con esta
   tipografía, la pregunta más larga con su respuesta cabe en el marco desde
   1240 px de ancho (medido: sobran ≈ 30 px a 1280 y 1440); por debajo ya no
   cabría sin recortar el informe, por eso la disposición cambia a columna. */
@media (min-width: 1240px) {
  .explorer {
    grid-template-columns: minmax(0, 0.38fr) minmax(0, 0.62fr);
    grid-template-rows: auto auto;
    column-gap: clamp(24px, 3.4vw, 48px);
    align-items: stretch;
  }
  .explorer-tabs { grid-column: 1; grid-row: 1; gap: 4px; }
  .shots { grid-column: 2; grid-row: 1; align-self: stretch; }
  .shot-bar { grid-column: 2; grid-row: 2; }
  .et { flex: 1 1 auto; align-content: center; gap: 3px; padding: 12px 20px; }
  .et .et-q { font-size: 1rem; line-height: 1.28; }
  .et .et-d { font-size: 0.875rem; line-height: 1.5; }
  .et[aria-selected="true"] .et-d > span { padding-top: 2px; }
}

@media (max-width: 899px) {
  .explorer { row-gap: 14px; }
  .explorer-tabs {
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 10px;
    margin-inline: calc(var(--gutter) * -1);
    padding: 2px var(--gutter) 8px;
    scrollbar-width: none;
  }
  .explorer-tabs::-webkit-scrollbar { display: none; }
  .et { flex: 0 0 min(78%, 320px); scroll-snap-align: start; border-color: var(--hair); }
  .et .et-d { display: none; }
}

/* ---------------------------------------------------------
  10 · SERVICIOS
--------------------------------------------------------- */
.card-grid .card { padding: clamp(28px, 3vw, 44px); }
.card-grid .card h3 { font-size: var(--fs-h3); letter-spacing: -0.02em; font-weight: 600; }
.card-grid .card p { font-size: 0.9375rem; line-height: 1.6; }
.card-icon { transition: border-color var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }

/* ---------------------------------------------------------
  11 · PROCESO — «el viaje del dato»
  Un único objeto, sticky, que cambia de estado según el paso que se
  está leyendo: datos sueltos → modelo conectado → decisión. Lo
  gobierna una variable (`data-act`) y lo mueven transiciones CSS,
  así que se puede interrumpir y no depende de un scrub.
--------------------------------------------------------- */
.journey {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: clamp(32px, 6vw, 104px);
  align-items: start;
}
.journey-stage {
  position: sticky;
  top: 112px;
  align-self: start;
  padding: clamp(20px, 2.4vw, 32px);
  border-radius: 24px;
  border: 1px solid var(--hair);
  background: var(--surface);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.jv { display: block; width: 100%; height: auto; overflow: visible; }
/* El objeto es fijo (sticky) a partir de 960 px: si fuese más alto que la
   pantalla, su pie se quedaría fuera y no habría forma de leerlo. Se limita
   su alto al disponible (alto − cabecera − relleno − pie ≈ 262 px) y el SVG
   se reduce solo, centrado. */
@media (min-width: 960px) {
  .jv { max-height: max(220px, calc(100vh - 262px)); max-height: max(220px, calc(100dvh - 262px)); }
}
.jv .base, .jv .tgt { stroke: rgba(148, 163, 184, 0.3); stroke-width: 1; opacity: 0; transition: opacity var(--dur-slow) var(--ease-out); }
.jv .tgt { stroke: rgba(167, 139, 250, 0.7); stroke-dasharray: 5 4; stroke-width: 1.5; }

/* Cada nodo lleva sus tres posiciones como variables; el estado
   elige cuál se aplica. Transform y opacidad, nada más. */
.jv .n {
  --x: var(--x1); --y: var(--y1); --r: var(--r1);
  transform: translate(calc(var(--x) * 1px), calc(var(--y) * 1px)) rotate(var(--r)) scale(var(--sx, 1), var(--sy, 1));
  transition: transform var(--dur-scene) var(--ease-expo);
  transition-delay: calc(var(--i) * 45ms);
}
.jv .nr {
  fill: rgba(148, 163, 184, 0.14);
  stroke: rgba(148, 163, 184, 0.42);
  stroke-width: 1;
  transition: fill var(--dur-slow) var(--ease-out), stroke var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--i) * 45ms);
}
.jv .nt {
  fill: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-anchor: middle;
  dominant-baseline: central;
  transition: opacity var(--dur-base) var(--ease-out);
}
.jv .nt.t2, .jv .nt.t3 { opacity: 0; }
.jv .ln {
  fill: none;
  stroke: rgba(167, 139, 250, 0.55);
  stroke-width: 1.5;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset var(--dur-scene) var(--ease-expo), opacity var(--dur-slow) var(--ease-out);
}
.jv .bar {
  fill: rgba(167, 139, 250, 0.5);
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transform: scaleY(0);
  transition: transform var(--dur-scene) var(--ease-expo), fill var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--i) * 45ms);
}
.jv .bar.peak { fill: var(--violet); filter: drop-shadow(0 0 14px rgba(139, 92, 246, 0.55)); }

.journey[data-act="2"] .jv .n { --x: var(--x2); --y: var(--y2); --r: 0deg; }
.journey[data-act="2"] .jv .nr { fill: rgba(139, 92, 246, 0.18); stroke: var(--lavender); }
.journey[data-act="2"] .jv .nt.t1 { opacity: 0; }
.journey[data-act="2"] .jv .nt.t2 { opacity: 1; }
.journey[data-act="2"] .jv .ln { stroke-dashoffset: 0; transition-delay: calc(0.3s + var(--i) * 70ms), 0s; }
.jv .lbl { fill: var(--lavender); font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-anchor: start; opacity: 0; transition: opacity var(--dur-slow) var(--ease-out); }
.journey[data-act="3"] .jv .lbl { opacity: 1; }

/* Estado 3: el nodo se aplana hasta ser la «tapa» de su columna (56×30 →
   30×6, el ancho exacto de la columna). */
.journey[data-act="3"] .jv .n { --x: var(--x3); --y: var(--y3); --r: 0deg; --sx: 0.54; --sy: 0.2; }
.journey[data-act="3"] .jv .nr { fill: var(--lavender); stroke: var(--lavender); }
.journey[data-act="3"] .jv .nt { opacity: 0; }
.journey[data-act="3"] .jv .ln { opacity: 0; stroke-dashoffset: 0; }
.journey[data-act="3"] .jv .bar { transform: scaleY(1); }
.journey[data-act="3"] .jv .base, .journey[data-act="3"] .jv .tgt { opacity: 1; }

.jv-cap {
  position: relative;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--hair);
  min-height: 3.2em;
}
.jv-cap span {
  position: absolute;
  inset: 16px 0 auto 0;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-dim);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.jv-cap b { color: var(--text); font-weight: 600; }
.journey[data-act="1"] .jv-cap [data-cap="1"],
.journey[data-act="2"] .jv-cap [data-cap="2"],
.journey[data-act="3"] .jv-cap [data-cap="3"] { opacity: 1; transform: none; }

.journey-steps { list-style: none; margin: 0; padding: 0; counter-reset: jst; }
/* El paso inactivo baja a 0,72, no menos: con 0,42 el párrafo caía a ~2,6:1
   de contraste (calculado a mano, mezclando el color con el fondo), por
   debajo del 4,5:1 de la WCAG. Lo que marca cuál
   es el activo es, además, un filete lavanda a la izquierda. */
.jstep {
  position: relative;
  min-height: min(68vh, 560px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 28px 0 28px 28px;
  opacity: 0.72;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.jstep::before {
  content: "";
  position: absolute;
  left: 0; top: 18%; bottom: 18%;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, transparent, var(--lavender), transparent);
  transform: scaleY(0.3);
  opacity: 0;
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-slow) var(--ease-out);
}
.jstep.is-active { opacity: 1; }
.jstep.is-active::before { transform: none; opacity: 1; }
.jstep h3 { font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.125rem); letter-spacing: -0.026em; font-weight: 620; margin-bottom: 14px; max-width: 18ch; }
/* El número va dentro del título, en lavanda y con un respiro antes del texto. */
.jstep .jn { color: var(--lavender); font-variant-numeric: tabular-nums; margin-right: 0.12em; }
.jstep p { font-size: var(--fs-lead); line-height: 1.55; max-width: 38ch; }
.jstep .j-meta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  padding: 8px 14px;
  border: 1px solid var(--hair);
  border-radius: 999px;
  font-size: 0.8125rem;
  color: var(--text-dim);
  width: fit-content;
}
.jstep .j-meta::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--violet); }
.jstep .mock-panel { margin-top: 26px; max-width: 360px; background: var(--surface); border-color: var(--hair); }

@media (max-width: 959px) {
  .journey { grid-template-columns: minmax(0, 1fr); }
  .journey-stage { position: relative; top: 0; }
  .jstep { min-height: 0; opacity: 1; padding: 22px 0; border-top: 1px solid var(--hair); }
  .jstep::before { display: none; }
  .jstep:first-child { border-top: 0; }
}

/* ---------------------------------------------------------
  12 · PLANIFICACIÓN Y PRECIOS
--------------------------------------------------------- */
.proof-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--hair);
}
.proof-item {
  padding: clamp(24px, 3vw, 40px) clamp(16px, 2vw, 32px) 0 0;
}
.proof-item + .proof-item { border-left: 1px solid var(--hair); padding-left: clamp(16px, 2vw, 32px); }
/* La cifra, la unidad y la explicación van en tres líneas con aire entre
   ellas. Antes la unidad iba pegada a la cifra y el interletraje de −0,045 em
   dejaba «6–8» como un bloque apretado; ahora la cifra respira (−0,02 em),
   el guion de rango se separa de los números y la unidad pasa a una línea
   propia, en versalitas finas. */
.proof-n {
  display: block;
  font-size: clamp(2.25rem, 1.4rem + 2.6vw, 3.5rem);
  font-weight: 560;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(135deg, #fff 10%, var(--lavender) 95%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.proof-n .rng { white-space: nowrap; }
.proof-n i { font-style: normal; margin: 0 0.14em; font-weight: 400; }
.proof-u {
  display: block;
  margin-top: 14px;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--lavender);
}
.proof-t { display: block; margin-top: 10px; font-size: 0.9375rem; line-height: 1.55; color: var(--text-dim); max-width: 30ch; }
.proof-foot { margin: 28px 0 0; font-size: 0.8125rem; color: var(--text-dimmer); }
.proof-foot a { color: var(--lavender); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 900px) {
  .proof-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .proof-item { padding-bottom: 28px; }
  .proof-item:nth-child(odd) { border-left: 0; padding-left: 0; }
  .proof-item:nth-child(even) { border-left: 1px solid var(--hair); }
  .proof-item:nth-child(n+3) { border-top: 1px solid var(--hair); }
}

.price-value .amount { font-size: clamp(2rem, 1.4rem + 1.6vw, 2.75rem); font-weight: 650; letter-spacing: -0.03em; }
.price-note { margin: 28px auto 0; max-width: 62ch; text-align: center; font-size: 0.9375rem; color: var(--text-dim); }

/* ---------------------------------------------------------
  13 · FAQ, CTA, CONTACTO
--------------------------------------------------------- */
#faq .container { display: grid; grid-template-columns: minmax(0, 0.4fr) minmax(0, 0.6fr); gap: clamp(32px, 6vw, 96px); align-items: start; }
#faq .sec-head { display: block; margin-bottom: 0; position: sticky; top: 120px; }
#faq .sec-head .sec-side { margin-top: 20px; }
.faq-list { max-width: none; margin: 0; gap: 0; border-top: 1px solid var(--hair); }
.faq-item {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hair);
  border-radius: 0;
  box-shadow: none;
}
.faq-q { padding: 24px 4px; font-size: 1.125rem; font-weight: 600; letter-spacing: -0.015em; transition: color var(--dur-fast) var(--ease-out); }
.faq-q svg { transition: transform var(--dur-base) var(--ease-out); }
/* Altura animada con grid (0fr → 1fr): interrumpible y sin medir nada
   en JS. `visibility` oculta la respuesta cerrada a lectores de pantalla
   y al tabulador una vez terminada la animación. */
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  max-height: none;
  visibility: hidden;
  transition: grid-template-rows var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
}
.faq-item.open .faq-a { grid-template-rows: 1fr; max-height: none; visibility: visible; transition-delay: 0s; }
.faq-a p { padding: 0 4px 24px; font-size: 1rem; line-height: 1.65; max-width: 60ch; min-height: 0; overflow: hidden; }
@media (hover: hover) and (pointer: fine) { .faq-q:hover { color: var(--lavender); } }
@media (max-width: 959px) {
  #faq .container { grid-template-columns: minmax(0, 1fr); }
  #faq .sec-head { position: static; margin-bottom: 32px; }
}

.cta-banner h2 { font-size: var(--fs-h2); font-weight: 620; letter-spacing: -0.03em; max-width: 24ch; margin-inline: auto; }
.cta-banner p { font-size: var(--fs-lead); }

.contact-wrap { gap: clamp(32px, 5vw, 80px); }
.next-steps { list-style: none; margin: 0 0 40px; padding: 0; counter-reset: ns; }
.next-steps li {
  counter-increment: ns;
  position: relative;
  padding: 0 0 22px 52px;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--text-dim);
}
.next-steps li::before {
  content: counter(ns);
  position: absolute;
  left: 0; top: -2px;
  width: 34px; height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--hair-strong);
  border-radius: 50%;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--lavender);
  font-variant-numeric: tabular-nums;
}
.next-steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 16.5px; top: 36px; bottom: 4px;
  width: 1px;
  background: var(--hair);
}
.next-steps b { display: block; color: var(--text); font-weight: 600; margin-bottom: 2px; }

.contact-form { border-radius: 24px; padding: clamp(24px, 3vw, 40px); }
.contact-form label { font-size: 0.8125rem; font-weight: 500; color: var(--text-dim); }
.contact-form label .req { color: var(--lavender); margin-left: 3px; }
.contact-form input, .contact-form textarea, .contact-form select {
  font-size: 1rem; /* 16 px: iOS no hace zoom al enfocar */
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.contact-form input:focus, .contact-form textarea:focus, .contact-form select:focus {
  outline: none;
  border-color: var(--violet);
  background-color: rgba(255, 255, 255, 0.05);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.28);
}
.contact-form input:user-invalid, .contact-form textarea:user-invalid { border-color: #f87171; box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.18); }
.contact-form .consent-row input { box-shadow: none; width: 20px; height: 20px; flex: none; margin-top: 0; }
.contact-form .consent-row { align-items: center; font-size: 0.8125rem; }

.topics { border: 0; margin: 0; padding: 0; min-width: 0; }
.topics legend { font-size: 0.8125rem; font-weight: 500; color: var(--text-dim); margin-bottom: 10px; padding: 0; }
.topic-row { display: flex; flex-wrap: wrap; gap: 8px; }
.topic { position: relative; display: block; margin: 0 !important; }
.topic input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.topic span {
  display: inline-flex;
  align-items: center;
  padding: 9px 16px;
  border: 1px solid var(--hair);
  border-radius: 999px;
  font-size: 0.875rem;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.02);
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), scale var(--dur-press) var(--ease-out);
}
.topic input:checked + span { background: rgba(139, 92, 246, 0.2); border-color: var(--lavender); color: var(--text); }
.topic input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
.topic input:active + span { scale: 0.96; }

.form-note { font-size: 0.8125rem; min-height: 1.4em; }
.contact-form button[type="submit"] { position: relative; }
.contact-form button[type="submit"] .spin {
  display: none;
  width: 16px; height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: nsaSpin 0.7s linear infinite;
}
.contact-form.is-sending button[type="submit"] .spin { display: inline-block; }
@keyframes nsaSpin { to { rotate: 360deg; } }

/* ---------------------------------------------------------
  14 · PIE, CTA MÓVIL, VOLVER ARRIBA
--------------------------------------------------------- */
footer { position: relative; overflow: hidden; }
.footer-mark {
  display: block;
  width: min(1040px, 92%);
  height: auto;
  margin: 8px auto -2%;
  opacity: 0.06;
  pointer-events: none;
  user-select: none;
}
.sticky-cta {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  z-index: 160;
  display: none;
  justify-content: center;
  padding: 16px 20px;
  border-radius: 999px;
  font-size: 0.9375rem;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--violet) 0%, var(--violet-mid) 100%);
  box-shadow: 0 16px 40px -8px rgba(109, 40, 217, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  translate: 0 140%;
  transition: translate var(--dur-base) var(--ease-out);
}
.sticky-cta.is-visible { translate: 0 0; }
.sticky-cta:active { scale: 0.98; }
@media (max-width: 767px) {
  .sticky-cta { display: flex; }
  footer { padding-bottom: 96px; }
  .back-top { bottom: calc(84px + env(safe-area-inset-bottom, 0px)); right: 14px; width: 42px; height: 42px; }
}
.back-top { transition: opacity var(--dur-base) var(--ease-out), translate var(--dur-base) var(--ease-out), scale var(--dur-press) var(--ease-out); }
.back-top:hover { transform: none; translate: 0 -3px; }
.back-top:active { scale: 0.94; }

.footer-bottom .links { align-items: center; flex-wrap: wrap; }
.motion-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--hair);
  border-radius: 999px;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out), scale var(--dur-press) var(--ease-out);
}
.motion-toggle::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--text-dimmer); transition: background-color var(--dur-fast) var(--ease-out); }
.motion-toggle[aria-pressed="true"] { color: var(--text); border-color: var(--lavender); background: rgba(139, 92, 246, 0.14); }
.motion-toggle[aria-pressed="true"]::before { background: var(--lavender); }
.motion-toggle:active { scale: 0.96; }
@media (hover: hover) and (pointer: fine) { .motion-toggle:hover { color: var(--text); border-color: var(--hair-strong); } }

/* ---------------------------------------------------------
  15 · CURSOR-SECTOR
  La O de NORUS es un diagrama de sectores: un anillo con un sector
  separado. Ese anillo es el puntero. Lo acompaña con un poco de retardo
  y cambia de estado según lo que hay debajo (enlace, demo, texto). No se
  abre ni se agranda más allá de eso. El puntero nativo NO se oculta: el
  anillo acompaña, no sustituye (accesibilidad).
--------------------------------------------------------- */
.nsa-cursor {
  position: fixed;
  left: 0; top: 0;
  width: 40px; height: 40px;
  margin: -20px 0 0 -20px;
  z-index: 9998;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
  will-change: transform;
}
.nsa-cursor.on { opacity: 1; }
.nsa-cursor.is-hidden { opacity: 0; }
.nsa-cursor svg { display: block; width: 100%; height: 100%; overflow: visible; transition: scale var(--dur-base) var(--ease-out); }
.nsa-cursor .nc-ring { fill: none; stroke: var(--lavender); stroke-width: 1.5; vector-effect: non-scaling-stroke; opacity: 0.75; transition: opacity var(--dur-base) var(--ease-out), fill var(--dur-base) var(--ease-out); }
.nsa-cursor .nc-seg { fill: none; stroke: var(--lavender); stroke-width: 2.4; stroke-linecap: round; vector-effect: non-scaling-stroke; transform-origin: 50px 50px; animation: nsaOrbit 7s linear infinite; }
@keyframes nsaOrbit { to { rotate: 360deg; } }
.nsa-cursor[data-state="link"] svg { scale: 1.45; }
.nsa-cursor[data-state="link"] .nc-ring { fill: rgba(139, 92, 246, 0.14); opacity: 1; }
.nsa-cursor[data-state="link"] .nc-seg { animation-duration: 2.2s; }
.nsa-cursor[data-state="text"] svg { scale: 0.28; }
.nsa-cursor.is-down svg { scale: 0.82; }
.nsa-cursor .nc-label {
  position: absolute;
  left: 50%; top: 50%;
  translate: -50% -50%;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #fff;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.nsa-cursor[data-state="label"] svg { scale: 2.1; }
.nsa-cursor[data-state="label"] .nc-ring { fill: var(--violet); opacity: 0.92; stroke: transparent; }
.nsa-cursor[data-state="label"] .nc-seg { opacity: 0; }
.nsa-cursor[data-state="label"] .nc-label { opacity: 1; }

/* ---------------------------------------------------------
  16 · PANTALLA DE CARGA Y VENTANA DE DEMOSTRACIÓN
--------------------------------------------------------- */
.preloader {
  transition: clip-path 0.85s var(--ease-in-out), opacity 0.4s linear 0.55s, visibility 0s linear 0.95s;
  clip-path: inset(0 0 0 0);
}
.preloader.hide { opacity: 0; visibility: hidden; clip-path: inset(0 0 100% 0); }
.preloader.hide .preloader-mark { opacity: 0; translate: 0 -18px; transition: opacity 0.35s var(--ease-out), translate 0.5s var(--ease-in-out); }
.preloader.hide .preloader-bar { opacity: 0; transition: opacity 0.2s linear; }

/* La ventana de la demo se adapta a CUALQUIER pantalla (2026-10-01).
   El fallo: la ventana medía `min(1180px, 94vw)` de ancho y el vídeo
   (16:9) llevaba esa altura sin mirar la de la pantalla; con un portátil
   bajo o un móvil en horizontal el vídeo era más alto que la ventana, que
   tiene `overflow: hidden`, y se cortaba por abajo —justo donde están los
   controles—. A 1366×650 se perdían 179 px.
   La solución: el ANCHO de la ventana sale también del ALTO disponible
   (alto − cabecera y capítulos, por la proporción 1280/724 ≈ 1,768), de
   modo que el vídeo siempre cabe entero y sin bandas. Además la ventana es
   una columna flex con `max-height` y el vídeo puede encogerse
   (`min-height: 0` + `object-fit: contain`) por si la cabecera ocupa más de
   lo previsto (titular en dos líneas). `dvh` descuenta las barras del
   navegador móvil; `vh` queda de respaldo. */
.demo-modal {
  --demo-chrome: 140px; /* cabecera + fila de capítulos */
  width: min(1180px, 94vw, calc((100vh - var(--demo-chrome) - 16px) * 1.768));
  width: min(1180px, 94vw, calc((100dvh - var(--demo-chrome) - 16px) * 1.768));
  max-height: calc(100vh - 16px);
  max-height: calc(100dvh - 16px);
  opacity: 0;
  scale: 0.965;
  transition: opacity var(--dur-base) var(--ease-out), scale var(--dur-base) var(--ease-out), overlay var(--dur-base) allow-discrete, display var(--dur-base) allow-discrete;
}
.demo-modal[open] { display: flex; flex-direction: column; }
.demo-modal-head, .demo-chapters { flex: none; }
.demo-modal video { flex: 0 1 auto; min-height: 0; aspect-ratio: 1280 / 724; object-fit: contain; }
.demo-modal[open] { opacity: 1; scale: 1; }
@starting-style { .demo-modal[open] { opacity: 0; scale: 0.965; } }
.demo-modal::backdrop { opacity: 0; transition: opacity var(--dur-base) var(--ease-out), overlay var(--dur-base) allow-discrete, display var(--dur-base) allow-discrete; }
.demo-modal[open]::backdrop { opacity: 1; }
@starting-style { .demo-modal[open]::backdrop { opacity: 0; } }
.demo-chapters { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 18px; border-bottom: 1px solid var(--line); }
.demo-chapters button {
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  padding: 7px 14px;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--hair);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), scale var(--dur-press) var(--ease-out);
}
.demo-chapters button[aria-pressed="true"] { background: rgba(139, 92, 246, 0.2); border-color: var(--lavender); color: var(--text); }
.demo-chapters button:active { scale: 0.96; }
/* Pantallas bajas (portátil pequeño, móvil en horizontal): cabecera y
   capítulos más compactos para dejar el sitio al vídeo. VAN DESPUÉS de las
   reglas base de los capítulos: con la misma especificidad, gana la que
   está más abajo (en la primera versión iban antes y no se aplicaban). */
@media (max-height: 560px) {
  .demo-modal { --demo-chrome: 96px; }
  .demo-modal-head { padding: 9px 14px; }
  .demo-modal-head p { display: none; }
  .demo-modal-head h2 { font-size: 13px; }
  .demo-close { width: 30px; height: 30px; }
  .demo-chapters { padding: 7px 14px; gap: 6px; }
  .demo-chapters button { padding: 4px 11px; font-size: 0.75rem; }
}
@media (max-width: 420px) {
  .demo-modal-head { padding: 12px 14px; }
  .demo-chapters { padding: 10px 14px; }
}

/* Sin JS de lazy-load (ahorro de datos): el fondo es un degradado
   estático con la misma paleta. */
.no-3d .vanta-bg {
  opacity: 1;
  background:
    radial-gradient(60% 50% at 20% 10%, rgba(139, 92, 246, 0.16), transparent 70%),
    radial-gradient(50% 45% at 85% 90%, rgba(109, 40, 217, 0.14), transparent 70%),
    var(--bg);
}

/* ---------------------------------------------------------
  17 · MOVIMIENTO REDUCIDO · CONTRASTE FORZADO · SIN JAVASCRIPT
  «Reducido» no es «cero»: se conservan los cambios de color y de
  opacidad que ayudan a entender; se quitan los desplazamientos, el
  giro y todo lo que se mueve solo.
--------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.is-in, .hero.is-ready .reveal { opacity: 1; transform: none; transition: none; animation: none; }
  .wi { transform: none; transition: none; }
  .jv .n, .jv .nr, .jv .ln, .jv .bar, .jstep, .jv-cap span { transition: none; }
  .nsa-cursor .nc-seg { animation: none; }
  .nsa-cursor, .nsa-cursor svg { transition: none; }
  .preloader { transition: opacity 0.2s linear; clip-path: none; }
  .preloader.hide { clip-path: none; }
  .preloader.hide .preloader-mark { translate: none; }
  .demo-modal { scale: 1; transition: opacity var(--dur-fast) linear; }
  .sticky-cta, .back-top { transition: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* «Pausar animaciones» (interruptor del pie): mismas reglas que el ajuste
   del sistema. `html.motion-off` lo pone nsa-motion-pref.js. Las reglas
   de styles.css, nsa.css y nsa-hero.css que cuelgan de la consulta
   multimedia se repiten aquí con la clase, porque una consulta y una clase
   no se pueden unir en un solo selector. */
html.motion-off *, html.motion-off *::before, html.motion-off *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
html.motion-off .reveal, html.motion-off .reveal.is-in, html.motion-off .hero.is-ready .reveal { opacity: 1; transform: none; animation: none; }
html.motion-off .wi { transform: none; }
html.motion-off .vanta-bg { transition: none; }
html.motion-off .nsa-chart .ch-grow { animation: none !important; transform: none !important; }
html.motion-off .hero-rig { opacity: 1; --rig-yaw: 0deg; }
html.motion-off .rig-stage { perspective: none; }
html.motion-off .hero-rig:not(.is-in) .rig-scene { --rig-yaw: 0deg; --rig-lift: 0px; }
html.motion-off .hero-scroll .hs-rail::after { animation: none; opacity: 1; }
html.motion-off .nsa-cursor .nc-seg { animation: none; }
html.motion-off .preloader { clip-path: none; }
html.motion-off .sticky-cta, html.motion-off .back-top { transition: none; }

@media (forced-colors: active) {
  .btn-primary, .sticky-cta { border: 1px solid ButtonText; }
  .et[aria-selected="true"], .topic input:checked + span { outline: 2px solid Highlight; }
  .nsa-cursor { display: none; }
}

@media (scripting: none) {
  .reveal, .wi { opacity: 1; transform: none; }
}
