/* ══════════════════════════════════════════════════════════════════════
   LYQUIA — lyquia.com
   Un solo CSS para todo el sitio. Tema oscuro único: la paleta viva de
   lyquia.com (navy profundo + cian), intocable — está fichada en
   _fuente/vivo/inventario.md.

   Dos reglas de disciplina, heredadas de la casa (DEVIA):

   1 · LOS COLORES NO SE ESCRIBEN EN LOS COMPONENTES. Cada superficie
       redefine --texto, --texto-suave, --acento, --acento-vivo y
       --filete; todo lo de dentro hereda. Añadir un componente no
       obliga a pensar sobre qué fondo va a caer.

   2 · EL RITMO VERTICAL VIVE EN UN ÚNICO SITIO: .seccion. Ningún
       componente lleva margen exterior propio.

   La elevación en oscuro no son sombras negras (sobre #080f1f no se
   ven): es superficie un paso más clara + brillo superior de 1px
   (--alza) y, solo en los momentos de marca, el halo cian (--glow).

   TESIS DE MOVIMIENTO — escrita antes de animar nada:
   Lyquia vende liquidez; el movimiento de la casa es EL FLUIR. Todo
   entra como agua que se asienta: fundidos y desplazamientos cortos
   hacia arriba, ninguna salida, ningún rebote. El único dibujo animado
   del sitio es la propia curva de caja, que se traza en el héroe y se
   rompe — y reaparece plana y sobre cero en el cierre. El scroll trae
   contenido, nunca lo quita. Movimiento reducido no es apagado nuclear
   sino «menos y más suave»: muere el desplazamiento, sobreviven el
   color y la opacidad que confirman acciones.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Tokens ──────────────────────────────────────────────────────────── */

:root {
  /* Paleta viva de lyquia.com — NO tocar */
  --bg: #080f1f;
  --navy: #0c1e3a;
  --card: #0e1c33;
  --cyan: #28cabe;
  --cyan-l: #8bf1e6;
  --txt: #e8eef7;
  --mut: #8fa3bd;
  --linea: rgba(255, 255, 255, 0.08);

  /* Derivados (contraste medido sobre lo pintado, ver auditar.js)
     --txt/--bg 16,4:1 · --mut/--bg 7,4:1 · --mut/--card 6,6:1 ·
     --mut/--card-alta 6,1:1 · --cyan/--bg 9,4:1 · tinta sobre cian 9,4:1.
     No inventar más grises: si algo pide menos presencia que --mut,
     se baja el tamaño o se sube el aire, no el contraste. */
  --card-alta: #13233f;
  --linea-fuerte: rgba(255, 255, 255, 0.14);
  --linea-cyan: rgba(40, 202, 190, 0.35);
  --tinta-boton: #080f1f;
  --rojo-cursor: #f27e6b; /* el coral del producto: lo que reclama atención */
  --glow: 0 0 60px rgba(40, 202, 190, 0.14);
  --alza: inset 0 1px 0 rgba(255, 255, 255, 0.05);

  /* Tipografías (autoalojadas en assets/tipos/) */
  --letra-cuerpo: 'Montserrat', 'Montserrat de reserva', -apple-system, 'Segoe UI', sans-serif;
  --letra-titular: 'Libre Baskerville', 'Libre Baskerville de reserva', Georgia, 'Times New Roman', serif;
  --letra-cifra: 'Geist Mono', ui-monospace, 'Cascadia Mono', monospace;

  /* Movimiento — tokens de la marca (lyquia-app/globals.css) más los
     dos propios de esta web. --ease-revelar es la curva de la
     referencia (oakandgrid.com), calcada de su .reveal. */
  --ease-asentar: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-suave: cubic-bezier(0.33, 0.1, 0.25, 1);
  --ease-revelar: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-toque: 120ms;
  --dur-cerca: 220ms;
  --dur-panel: 340ms;
  --dur-vista: 420ms;
  --dur-focal: 650ms;
  --dur-trazo: 1400ms;

  /* Maqueta */
  --wrap: 1200px;
  --radio-s: 8px;
  --radio: 14px;
  --radio-l: 20px;

  color-scheme: dark;
}

/* ── Reset corto y base ─────────────────────────────────────────────── */

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* La barra fija no debe tapar el destino de las anclas. */
  scroll-padding-top: 92px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--letra-cuerpo);
  font-weight: 300;
  font-size: 1.0625rem;
  line-height: 1.7;
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* Superficie raíz: la mesa. Los componentes solo usan estas cinco. */
  --texto: var(--txt);
  --texto-suave: var(--mut);
  --acento: var(--cyan);
  --acento-vivo: var(--cyan-l);
  --filete: var(--linea);
  color: var(--texto);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

ul,
ol {
  list-style: none;
}

/* Superficies del navegador, tematizadas: la casa llega hasta el caret. */
::selection {
  background: var(--cyan);
  color: var(--tinta-boton);
}

html {
  caret-color: var(--cyan);
  scrollbar-color: #22375c var(--bg);
}

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

/* ── El cursor: punto exacto y anillo que llega tarde ──────────────────
   El punto va clavado donde está el ratón; el anillo lo persigue con
   inercia y se cierra sobre él al pasar sobre algo pulsable. Existe
   solo si lo enciende lyquia.js (html.con-cursor), que a su vez solo lo
   hace con ratón fino y sin movimiento reducido: nadie pierde su cursor
   del sistema por culpa de una decoración. Sobre campos de texto vuelve
   el cursor de siempre, porque ahí la forma del puntero es información
   (dónde se va a escribir), no adorno. */

html.con-cursor,
html.con-cursor a,
html.con-cursor button,
html.con-cursor summary,
html.con-cursor [data-plegable],
html.con-cursor .vista[data-ampliable],
html.con-cursor .plan[data-sitio]:not([data-sitio='centro']) {
  cursor: none;
}

html.con-cursor input,
html.con-cursor textarea,
html.con-cursor [contenteditable] {
  cursor: auto;
}

.cursor-punto,
.cursor-anillo {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 200;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  /* La POSICIÓN la escribe lyquia.js en `translate`, no en `transform`:
     así `transform` queda libre para la vibración, y las dos cosas se
     componen en vez de pisarse (translate se aplica antes). */
  will-change: translate;
  transition: opacity var(--dur-cerca) var(--ease-suave);
}

html.cursor-dentro .cursor-punto,
html.cursor-dentro .cursor-anillo {
  opacity: 1;
}

/* Sobre un campo de texto manda el cursor del sistema: el nuestro se
   aparta en vez de estorbar. */
html.cursor-escribiendo .cursor-punto,
html.cursor-escribiendo .cursor-anillo {
  opacity: 0;
}

.cursor-punto {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  background: var(--cyan-l);
}

.cursor-anillo {
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid var(--cyan);
  transition:
    opacity var(--dur-cerca) var(--ease-suave),
    width var(--dur-cerca) var(--ease-asentar),
    height var(--dur-cerca) var(--ease-asentar),
    margin var(--dur-cerca) var(--ease-asentar),
    background-color var(--dur-cerca) var(--ease-suave),
    border-color var(--dur-cerca) var(--ease-suave);
}

/* Sobre lo pulsable el anillo se cierra sobre el punto, los dos se
   tiñen de rojo y el anillo vibra: el puntero avisa de que ahí hay algo
   que responde antes incluso de leer el elemento. El rojo es el mismo
   coral que el producto usa para lo que reclama atención, no un color
   nuevo. */
html.cursor-sobre-accion .cursor-punto {
  background: var(--rojo-cursor);
}

html.cursor-sobre-accion .cursor-anillo {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  background: rgba(242, 126, 107, 0.16);
  border-color: var(--rojo-cursor);
  animation: vibrar 150ms steps(4, end) infinite;
}

/* Un pelo de temblor, no un terremoto: ±1px basta para que se note en
   un anillo de 16. */
@keyframes vibrar {
  0% { transform: translate(0.6px, -0.6px); }
  25% { transform: translate(-0.6px, 0.6px); }
  50% { transform: translate(-0.6px, -0.6px); }
  75% { transform: translate(0.6px, 0.6px); }
  100% { transform: translate(0.6px, -0.6px); }
}

/* ── Atmósfera ──────────────────────────────────────────────────────────
   Grano feTurbulence en velo fijo sin eventos: convierte el navy digital
   en un material y mata el banding de los degradados. Data-URI: cero
   peticiones. Receta de la casa. */

body::after {
  content: '';
  position: fixed;
  inset: 0;
  /* Por encima de todo, portada (120) y barra (100) incluidas: el
     grano es el material de la casa, no un adorno del fondo. */
  z-index: 130;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* El velo del héroe: un amanecer cian muy tenue tras la composición. */
.heroe {
  background:
    radial-gradient(60% 50% at 50% -10%, rgba(40, 202, 190, 0.08), transparent 70%),
    radial-gradient(90% 60% at 50% -20%, rgba(22, 41, 77, 0.9), transparent 65%);
}

/* ── Tipografías ────────────────────────────────────────────────────── */

@font-face {
  font-family: 'Montserrat';
  font-weight: 300;
  font-style: normal;
  font-display: swap;
  src: url('../tipos/montserrat-300.woff2') format('woff2');
}

@font-face {
  font-family: 'Montserrat';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('../tipos/montserrat-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Montserrat';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url('../tipos/montserrat-500.woff2') format('woff2');
}

@font-face {
  font-family: 'Libre Baskerville';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('../tipos/baskerville-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Libre Baskerville';
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  src: url('../tipos/baskerville-400i.woff2') format('woff2');
}

@font-face {
  font-family: 'Geist Mono';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('../tipos/geistmono-400.woff2') format('woff2');
}

/* ── Tipografías de reserva ───────────────────────────────────────────
   Mientras llegan las de la casa, el navegador pinta con Georgia y con
   Arial y vuelve a pintar al llegar las buenas. Si no miden lo mismo, la
   página salta: 0,109 de CLS medido en una primera visita de escritorio,
   que antes no contaba porque el héroe estaba a opacidad 0 y ahora está
   pintado bajo la cubierta desde el primer pintado. Estas dos caras
   apuntan a la fuente local y la estiran (size-adjust y los tres
   override) hasta que ocupa exactamente lo mismo que la de la casa, así
   que el cambio de letra no mueve nada. Los números los calcula
   _fuente/tipos-de-reserva.mjs desde los .woff2 que sirve la web; no
   se retocan a mano. */
@font-face {
  font-family: 'Libre Baskerville de reserva';
  src: local('Georgia');
  size-adjust: 115.31%;
  ascent-override: 84.12%;
  descent-override: 23.41%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Montserrat de reserva';
  src: local('Arial');
  size-adjust: 108.83%;
  ascent-override: 88.95%;
  descent-override: 23.06%;
  line-gap-override: 0%;
}

/* ── Escala tipográfica ─────────────────────────────────────────────── */

h1,
h2 {
  font-family: var(--letra-titular);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.01em;
  text-wrap: balance;
  color: var(--texto);
}

h1 {
  font-size: clamp(2.5rem, 1.2rem + 4.8vw, 4.5rem);
  line-height: 1.08;
}

h1 em,
.acento-serif {
  font-style: italic;
  color: var(--acento-vivo);
}

h2 {
  font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3rem);
}

h3 {
  font-family: var(--letra-cuerpo);
  font-weight: 500;
  font-size: 1.125rem;
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--texto);
  text-wrap: balance;
}

p {
  color: var(--texto-suave);
}

p strong,
li strong {
  font-weight: 500;
  color: var(--texto);
}

/* El único antetítulo del sitio vive en el héroe de portada. */
.kicker {
  display: block;
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--acento);
}

/* Cifras y numeración editorial: siempre en mono, siempre tabulares. */
.cifra,
.numero {
  font-family: var(--letra-cifra);
  font-variant-numeric: tabular-nums;
}

.numero {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  color: var(--texto-suave);
}

.micro {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--texto-suave);
}

/* ── Maqueta ────────────────────────────────────────────────────────── */

.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}

/* Único dueño del ritmo vertical. El silencio es parte del diseño. */
.seccion {
  padding-block: clamp(4.75rem, 3.2rem + 5.2vw, 8.75rem);
}

.seccion + .seccion {
  border-top: 1px solid var(--filete);
}

/* Cabecera de sección: editorial, a la izquierda, titular que carga solo. */
.cabecera-seccion {
  max-width: 46rem;
  margin-bottom: clamp(2.75rem, 2rem + 3vw, 4.5rem);
}

.cabecera-seccion .entradilla {
  margin-top: 1.25rem;
  max-width: 38rem;
}

/* Salto accesible: invisible hasta que el teclado lo pide. */
.saltar {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--card-alta);
  color: var(--texto);
  border-radius: var(--radio-s);
  text-decoration: none;
}

.saltar:focus-visible {
  left: 1rem;
  top: 1rem;
}

/* ── Botones ────────────────────────────────────────────────────────── */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.8rem 1.65rem;
  border-radius: var(--radio-s);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition:
    background-color var(--dur-cerca) var(--ease-suave),
    border-color var(--dur-cerca) var(--ease-suave),
    color var(--dur-cerca) var(--ease-suave);
}

.boton-primario {
  background: var(--acento);
  color: var(--tinta-boton);
}

.boton-primario:hover {
  background: var(--acento-vivo);
}

.boton-fantasma {
  border: 1px solid var(--linea-fuerte);
  color: var(--texto);
}

.boton-fantasma:hover {
  border-color: var(--linea-cyan);
  color: var(--acento-vivo);
}

/* Enlaces de texto: se tiñen, sin moverse. */
.enlace {
  color: var(--acento-vivo);
  text-decoration: underline;
  text-decoration-color: var(--linea-cyan);
  text-underline-offset: 0.2em;
  transition:
    color var(--dur-cerca) var(--ease-suave),
    text-decoration-color var(--dur-cerca) var(--ease-suave);
}

.enlace:hover {
  text-decoration-color: currentColor;
}

/* ── La barra ───────────────────────────────────────────────────────────
   Fija y transparente al nacer; a unos píxeles de scroll (sentinel de
   IntersectionObserver, cero listeners) se asienta: fondo, velo y
   hairline. */

/* El sentinel del que depende .con-fondo: 1px en lo alto del documento. */
#sentinel-barra {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
}

.barra {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition:
    background-color var(--dur-panel) var(--ease-suave),
    border-color var(--dur-panel) var(--ease-suave),
    backdrop-filter var(--dur-panel) var(--ease-suave);
}

.barra.con-fondo {
  background: rgba(8, 15, 31, 0.72);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: var(--filete);
}

.barra-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 68px;
}

.marca {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  text-decoration: none;
}

.marca img {
  width: 28px;
  height: 28px;
}

/* El logotipo es el del producto, trazado del brandbook: la misma
   geometria que pinta la aplicacion (`lib/brand/palabra.ts`). Va en
   linea y con `currentColor` para heredar el color del texto que lo
   rodea, que es lo que la web pedia y un fichero externo no da.

   El alto que se le pone es el de la CAJA, no el de la mayuscula: la L
   ocupa 607,2 de los 757,3 que mide la caja, y por debajo solo bajan la
   y y la q. La proporcion con la baldosa es la del producto —mayuscula
   de 0,43 de su lado—, asi que a baldosa de 28 px le toca mayuscula de
   12, o sea 15 px de caja. */
.marca .logotipo {
  height: 15px;
  width: auto;
  color: var(--texto);
}

.barra nav {
  display: flex;
  align-items: center;
  gap: 1.9rem;
}

.barra nav a:not(.boton) {
  font-weight: 400;
  font-size: 0.9rem;
  text-decoration: none;
  color: var(--texto-suave);
  transition: color var(--dur-cerca) var(--ease-suave);
}

.barra nav a:not(.boton):hover,
.barra nav a:not(.boton):focus-visible {
  color: var(--acento-vivo);
}

.barra .boton {
  padding: 0.55rem 1.15rem;
  font-size: 0.875rem;
}

/* El menú en móvil: la barra entera despliega su lista. */
.menu-boton {
  display: none;
  width: 44px;
  height: 44px;
  border-radius: var(--radio-s);
  place-items: center;
}

.menu-boton svg {
  width: 22px;
  height: 22px;
  stroke: var(--texto);
  stroke-width: 1.6;
  fill: none;
}

.menu-boton .cerrar {
  display: none;
}

@media (max-width: 880px) {
  .menu-boton {
    display: grid;
  }

  .barra nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem clamp(1.25rem, 4vw, 2.5rem) 1.5rem;
    background: rgba(8, 15, 31, 0.96);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--filete);
  }

  .barra[data-abierto='si'] nav {
    display: flex;
  }

  .barra[data-abierto='si'] {
    background: rgba(8, 15, 31, 0.96);
    border-bottom-color: var(--filete);
  }

  .barra[data-abierto='si'] .menu-boton .abrir {
    display: none;
  }

  .barra[data-abierto='si'] .menu-boton .cerrar {
    display: block;
  }

  .barra nav a:not(.boton) {
    padding: 0.9rem 0;
    font-size: 1rem;
    border-bottom: 1px solid var(--filete);
  }

  .barra nav .boton {
    margin-top: 1.1rem;
    justify-content: center;
  }
}

/* ── El héroe ───────────────────────────────────────────────────────── */

.heroe {
  padding-top: clamp(9rem, 7rem + 6vw, 12.5rem);
  padding-bottom: clamp(4rem, 3rem + 3vw, 6rem);
  text-align: center;
}

.heroe h1 {
  max-width: 24ch;
  margin: 1.4rem auto 0;
}

.heroe .entradilla {
  max-width: 36rem;
  margin: 1.6rem auto 0;
  font-size: 1.125rem;
}

.heroe .cta {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 2.4rem;
}

.heroe .fiabilidad {
  margin-top: 1.4rem;
}

/* La curva que se rompe: el momento firma. Decorativa (aria-hidden),
   sin cifras inventadas; solo la forma del problema que Lyquia detecta.
   Nace completa y quieta; el bloque MOVIMIENTO la traza si puede. */
.curva-caja {
  position: relative;
  margin-top: clamp(2.5rem, 2rem + 2vw, 4rem);
}

.curva-caja svg {
  display: block;
  width: 100%;
  height: clamp(90px, 12vw, 150px);
}

.curva-caja .linea {
  stroke: var(--acento);
  stroke-width: 2;
  fill: none;
  opacity: 0.55;
}

.curva-caja .cero {
  stroke: var(--texto-suave);
  stroke-width: 1;
  stroke-dasharray: 3 6;
  opacity: 0.3;
}

/* El marcador de la rotura es HTML sobre el SVG: el dibujo se estira
   con la ventana (preserveAspectRatio none) y un texto o un círculo
   dentro se deformarían. El punto cae donde la curva cruza el cero
   (838/1200 · 100/160). */
.curva-caja .marcador {
  position: absolute;
  left: 69.8%;
  top: 62.5%;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  transform: translateY(-50%);
}

.curva-caja .punto {
  flex: none;
  width: 8px;
  height: 8px;
  margin-left: -4px;
  border-radius: 50%;
  background: var(--acento-vivo);
  box-shadow: 0 0 14px rgba(40, 202, 190, 0.7);
}

.curva-caja .etiqueta {
  font-family: var(--letra-cifra);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--texto-suave);
  white-space: nowrap;
}

/* ── Las pantallas del producto, incrustadas ──────────────────
   No son capturas ni imitaciones: son el HTML que pinta Lyquia, dentro
   de ESTE documento. Estuvieron en <iframe>, que regalaba el
   aislamiento, pero una ventana dentro de otra se lee como una lámina
   pegada encima: su fondo no es el de la página, su canto es una recta
   y su contenido no puede desbordar hacia el texto.

   Ahora el aislamiento se fabrica: `lyquia-producto.css` es el CSS del
   producto con todos sus selectores colgados de `.lyq`. Así `.lyq h1`
   (0,1,1) gana a `h1` (0,0,1) y las dos hojas dejan de verse. A cambio,
   la pantalla comparte lienzo, tipografías y grano con la página, se
   recorta a la altura que interesa y se disuelve por los bordes.

   El HTML no se toca a mano: lo incrusta `_fuente/demos/incrustar.py`
   entre las marcas <!-- pantalla:… -->. */

.escenario {
  width: min(1560px, 94vw);
  margin: clamp(2.5rem, 2rem + 2vw, 4rem) auto 0;
}

/* La isla. Tres puentes con el producto, y nada más.

   `.vista .lyq` y no `.lyq` a secas: el `:root`, el `html` y el
   `body` del producto aterrizan todos sobre `.lyq`, así que con una
   sola clase el puente empataba y perdía por orden. */
.vista .lyq {
  /* Las familias que el producto pide por variable son las que la web
     ya sirve: ni una descarga más. */
  --font-montserrat: 'Montserrat', system-ui, sans-serif;
  --font-baskerville: 'Libre Baskerville', Georgia, serif;
  --font-geist-mono: 'Geist Mono', ui-monospace, monospace;
  /* El lienzo de la aplicación pasa a ser el de la página. Es el único
     color del producto que se toca, y era el que delataba el recorte:
     un rectángulo #020617 sobre un fondo #080f1f se ve. Los paneles,
     las tarjetas, los gráficos y los semánticos siguen siendo suyos. */
  --lab-lienzo: var(--bg);
  background: transparent;
  /* La web escribe 17 px con interlínea 1,7; la aplicación se dibuja
     sobre 16 px con 1,5. Sin devolver la base, todo lo que dentro no
     lleva medida propia crece y descuadra. */
  font-size: 1rem;
  line-height: 1.5;
  /* La aplicación se dibuja para una ventana: las pantallas que son
     documento se desbordan hacia abajo y las recorta el hueco; las que
     son marco (el Lab, los diálogos) se ajustan a él. */
  height: 100%;
}

/* El envoltorio del producto pide una pantalla entera de alto. Aquí el
   alto lo pone el hueco. */
.vista .lyq .min-h-screen {
  /* Tres clases: el producto trae esta misma clase con dos, y su
     hoja cierra la cascada. */
  min-height: 0;
}

/* La web viste `p` por elemento (color apagado); dentro de la isla ese
   color lo ponen las clases del producto, y donde no las hay, la
   herencia. Con `:where` para no pesar más que ellas. */
.vista .lyq :where(p) {
  color: inherit;
}

/* La ventana por la que asoma: sin borde, sin fondo, sin radio. Lo que
   se ve es la interfaz del producto, no un recuadro que la contiene. */
.vista {
  position: relative;
}

.vista-isla {
  height: var(--vista-alto, 26rem);
  overflow: clip;
  /* Esto no es un detalle: media aplicación se cuelga de `fixed` o de
     `absolute` (el raíl del Lab, el diálogo de financiación, el plan de
     la IA). Sin un bloque contenedor propio, esos trozos se colocan
     contra el viewport y salen flotando sobre la página; con
     contención de pintado, la ventana ES su viewport. */
  contain: paint;
  /* Los bordes se disuelven en la página. Esto es lo que hace que la
     pantalla nazca del documento en lugar de estar pegada encima: por
     abajo se desvanece (y así se lee que sigue más allá), y por los
     lados se apaga el filo recto. */
  -webkit-mask-image:
    linear-gradient(to bottom, #000 calc(100% - var(--vista-humo, 6.5rem)), transparent),
    linear-gradient(to right, transparent, #000 2.4%, #000 97.6%, transparent);
  mask-image:
    linear-gradient(to bottom, #000 calc(100% - var(--vista-humo, 6.5rem)), transparent),
    linear-gradient(to right, transparent, #000 2.4%, #000 97.6%, transparent);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* Cada pantalla enseña el tramo del que habla su texto. */
.vista .vista-isla > .lyq {
  margin-top: calc(-1 * var(--vista-desde, 0px));
}

.vista-heroe {
  --vista-alto: min(72vh, 44rem);
  --vista-humo: 9rem;
}

/* Los diálogos del producto se centran en su ventana. Recortado por la
   mitad, un panel centrado se lee como un error; apoyado en la cima y
   disuelto por abajo, se lee como lo que es. */
.vista-cima .lyq .place-items-center {
  place-items: start center;
}

/* En pantallas estrechas manda el diseño adaptable del propio producto,
   que para eso lo tiene. Solo se recorta con más alto: en vertical su
   contenido se apila y hace falta más sitio para que se entienda. */
@media (max-width: 880px) {
  .vista {
    --vista-alto: 30rem;
    --vista-humo: 5rem;
  }

  .vista-heroe {
    --vista-alto: 32rem;
  }
}

/* ── El cartel: la pantalla espera velada hasta que te acercas ─────
   Dos capas y un fundido cruzado, la receta de la referencia. La
   pantalla no se tapa: se desenfoca y se apaga, así se ve que debajo
   hay un producto de verdad y no una promesa. Al acercar el cursor (o
   al llegar con el teclado, o siempre en táctil, donde no hay
   «acercar») el desenfoque se disuelve. */

.velo-demo {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  gap: 0.6rem;
  align-content: center;
  text-align: center;
  pointer-events: none;
  background:
    radial-gradient(60% 60% at 50% 50%, rgba(8, 15, 31, 0.72), rgba(8, 15, 31, 0.94));
  transition: opacity var(--dur-panel) var(--ease-suave);
}

.velo-demo .titulo {
  font-family: var(--letra-titular);
  font-size: clamp(1.4rem, 1.1rem + 1.4vw, 2.1rem);
  letter-spacing: 0.01em;
  color: var(--txt);
}

.velo-demo .titulo span {
  color: var(--cyan-l);
}

.velo-demo .pista {
  font-family: var(--letra-cifra);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mut);
}

.vista-heroe .vista-isla .lyq {
  filter: blur(7px) saturate(0.7);
  opacity: 0.5;
  transition:
    filter var(--dur-lejos) var(--ease-asentar),
    opacity var(--dur-lejos) var(--ease-asentar);
}

.vista-heroe:hover .vista-isla .lyq,
.vista-heroe:focus-within .vista-isla .lyq,
.vista-heroe.revelada .vista-isla .lyq {
  filter: none;
  opacity: 1;
}

.vista-heroe:hover .velo-demo,
.vista-heroe:focus-within .velo-demo,
.vista-heroe.revelada .velo-demo {
  opacity: 0;
}

/* Sin «acercar el cursor» no puede haber revelado por acercarlo: en
   táctil y con movimiento reducido, la pantalla se ve desde el
   principio. */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .velo-demo {
    display: none;
  }

  .vista-heroe .vista-isla .lyq {
    filter: none;
    opacity: 1;
  }
}

.vista-ampliar {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 6;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  border: 1px solid var(--linea-fuerte);
  background: rgba(8, 15, 31, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--mut);
  opacity: 0;
  transition:
    opacity var(--dur-cerca) var(--ease-suave),
    color var(--dur-cerca) var(--ease-suave),
    border-color var(--dur-cerca) var(--ease-suave);
}

.vista[data-ampliable]:hover .vista-ampliar,
.vista-ampliar:focus-visible {
  opacity: 1;
}

.vista-ampliar:hover {
  color: var(--cyan-l);
  border-color: var(--linea-cyan);
}

.vista-ampliar svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
}

/* ── El bento de funciones ──────────────────────────────────────────── */

.bento {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 0.9rem;
}

.celda {
  grid-column: span 12;
  border: 1px solid var(--filete);
  border-radius: var(--radio);
  background: var(--card);
  box-shadow: var(--alza);
  padding: clamp(1.5rem, 1.2rem + 1vw, 2.25rem);
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  transition:
    background-color var(--dur-cerca) var(--ease-asentar),
    border-color var(--dur-cerca) var(--ease-asentar);
}

.celda p {
  font-size: 0.9375rem;
  line-height: 1.65;
}

.celda .motivo {
  margin-top: auto;
  padding-top: 1.25rem;
}

@media (min-width: 880px) {
  .celda-7 { grid-column: span 7; }
  .celda-5 { grid-column: span 5; }
  .celda-4 { grid-column: span 4; }
  .celda-12 { grid-column: span 12; }

  /* La banda baja es distinta a propósito: horizontal, sin motivo. */
  .celda-12 {
    flex-direction: row;
    align-items: baseline;
    gap: 2.5rem;
  }

  .celda-12 h3 {
    flex: 0 0 14rem;
  }

  .celda-12 p {
    max-width: 52rem;
  }
}

/* Motivo de la celda grande: la mini-curva con su rotura, estática. */
.motivo-curva svg {
  display: block;
  width: 100%;
  height: 56px;
}

.motivo-curva .linea {
  stroke: var(--acento);
  stroke-width: 1.5;
  fill: none;
  opacity: 0.45;
}

.motivo-curva .cero {
  stroke: var(--texto-suave);
  stroke-width: 1;
  stroke-dasharray: 2 5;
  opacity: 0.3;
}

.motivo-curva .punto {
  fill: var(--acento-vivo);
}

/* Motivo de la celda de simulación: dos fichas de movimiento, quietas. */
.motivo-fichas {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.motivo-fichas span {
  font-family: var(--letra-cifra);
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  color: var(--texto-suave);
  border: 1px solid var(--filete);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
}

.motivo-fichas .ficha-viva {
  color: var(--acento-vivo);
  border-color: var(--linea-cyan);
}

/* ── Los capítulos (Lyquia en acción) ───────────────────────────────── */

.capitulo {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.75rem, 1.5rem + 2vw, 3.5rem);
  align-items: center;
  padding-block: clamp(2.75rem, 2rem + 3vw, 4.75rem);
}

.capitulo + .capitulo {
  border-top: 1px solid var(--filete);
}

/* Las celdas de la rejilla pueden encoger por debajo de su contenido:
   sin esto, la demo del Lab (ancho máximo interno) ensancharía la
   página en móvil en vez de desplazarse por dentro. */
.capitulo-texto,
.capitulo-media {
  min-width: 0;
}

@media (min-width: 880px) {
  .capitulo {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  .capitulo .capitulo-texto {
    max-width: 62ch;
  }
}

.capitulo .numero {
  display: block;
  font-size: 1rem;
  margin-bottom: 1.1rem;
  color: var(--acento);
  opacity: 0.75;
}

.capitulo h3 {
  font-family: var(--letra-titular);
  font-weight: 400;
  font-size: clamp(1.4rem, 1.1rem + 1.4vw, 1.9rem);
  line-height: 1.22;
  letter-spacing: -0.005em;
}

.capitulo p {
  margin-top: 1.1rem;
  font-size: 0.9875rem;
}

/* El capítulo ancho (pool bancario): la media a todo el ancho. */
.capitulo-ancho {
  display: block;
}

.capitulo-ancho .capitulo-texto {
  max-width: 46rem;
  margin-bottom: 2.25rem;
}

/* ── Integraciones: dos sendas hermanas, no gemelas ─────────────────── */

.sendas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
}

@media (min-width: 880px) {
  .sendas {
    grid-template-columns: 1fr 1fr;
  }
}

.senda {
  border: 1px solid var(--filete);
  border-radius: var(--radio);
  background: var(--card);
  box-shadow: var(--alza);
  padding: clamp(1.75rem, 1.4rem + 1.2vw, 2.5rem);
  display: flex;
  flex-direction: column;
}

.senda-erp {
  border-color: var(--linea-cyan);
}

.senda h3 {
  font-size: 1.25rem;
}

.senda p {
  margin-top: 0.9rem;
  font-size: 0.9375rem;
}

/* ── Las guías: cartas hermanas de las sendas, en rejilla de tres ─────
   Reutilizan .senda (borde, fondo, aire y el alzarse al pasar) y la
   cadencia de reveals de la casa; lo único propio es la rejilla y que la
   carta entera sea el enlace. Sección normal: la página ya tiene sus dos
   escenas fijadas y no cabe una tercera. */

.guias {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
}

@media (min-width: 720px) {
  .guias {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1080px) {
  .guias {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.guias .senda {
  text-decoration: none;
  color: inherit;
}

.guias .senda h3 {
  margin-top: 0.7rem;
  transition: color var(--dur-cerca) var(--ease-suave);
}

.guias .senda:hover h3,
.guias .senda:focus-visible h3 {
  color: var(--acento-vivo);
}

.guias .senda .pie {
  color: var(--acento);
}

/* ── La conexión con el ERP, contada ──────────────────────────────────
   Una clavija recorre su cable hasta cada sistema y lo enciende. El
   cable mide lo mismo en las tres filas (un ancho fijo, no un 1fr), y
   por dos razones: los logos quedan alineados entre sí, y el viaje de
   la clavija puede escribirse como una traslación exacta en vez de
   depender de cuánto mida la columna. */

.conexiones {
  --cable: 104px;
  display: grid;
  gap: 1.1rem;
  margin-top: 1.75rem;
}

.conexion {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  min-height: 26px;
}

.conexion .cable {
  position: relative;
  flex: none;
  width: var(--cable);
  height: 1px;
  background: var(--filete);
}

/* La corriente: el tramo ya recorrido, encendido detrás de la clavija. */
.conexion .corriente {
  position: absolute;
  inset: 0;
  transform-origin: left;
  background: linear-gradient(90deg, transparent, var(--cyan) 85%);
}

.conexion .clavija {
  position: absolute;
  right: -3px;
  top: 50%;
  width: 26px;
  height: 14px;
  margin-top: -7px;
  stroke: var(--cyan-l);
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.conexion img {
  height: 20px;
  width: auto;
  flex: none;
}

.conexion img.l-odoo { height: 25px; }
.conexion img.l-holded { height: 17px; }

.conexion--otros {
  padding-left: calc(var(--cable) + 0.9rem);
}

.conexion .otros {
  font-family: var(--letra-cifra);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  color: var(--texto-suave);
}

@media (max-width: 1100px) {
  .conexiones { --cable: 68px; }
}

/* ── El importador, contado ────────────────────────────────────────── */

.importador {
  margin-top: 1.6rem;
  padding: 1rem 1.15rem 1.1rem;
  border: 1px solid var(--filete);
  border-left: 2px solid var(--cyan);
  border-radius: var(--radio-s);
  background: rgba(255, 255, 255, 0.02);
}

.importador .libro {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.importador .hoja {
  flex: none;
  width: 19px;
  height: 19px;
  stroke: var(--cyan-l);
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.importador .nombre {
  font-size: 0.8125rem;
  color: var(--texto);
}

.importador .peso {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--texto-suave);
}

.importador .progreso {
  height: 3px;
  border-radius: 2px;
  margin-top: 0.85rem;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.importador .progreso i {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--cyan);
  transform-origin: left;
}

.importador .leido {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.8rem;
  font-family: var(--letra-cifra);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--cyan-l);
}

.importador .visto {
  flex: none;
  width: 13px;
  height: 13px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.importador .columnas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.7rem;
}

.importador .columnas li {
  font-family: var(--letra-cifra);
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--filete);
  border-radius: 999px;
  color: var(--texto-suave);
}

/* ── El enlace de descarga ─────────────────────────────────────────── */

.descarga {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0 1rem;
  margin-top: 1.5rem;
  padding: 0.85rem 1.15rem;
  border: 1px solid var(--linea-cyan);
  border-radius: var(--radio);
  background: var(--card-alta);
  box-shadow: var(--alza);
  text-decoration: none;
  transition:
    border-color var(--dur-cerca) var(--ease-suave),
    background-color var(--dur-cerca) var(--ease-suave);
}

.descarga:hover {
  border-color: var(--cyan);
}

.descarga .bajar {
  grid-row: span 2;
  width: 21px;
  height: 21px;
  stroke: var(--acento-vivo);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.descarga .que {
  font-weight: 400;
  font-size: 0.9375rem;
  color: var(--texto);
}

.descarga .meta {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--texto-suave);
}

.senda .pie {
  margin-top: auto;
  padding-top: 1.4rem;
  font-size: 0.8125rem;
  border-top: 1px solid var(--filete);
}

.senda .pie:not(:first-child) {
  margin-top: 1.6rem;
}

/* ── Los tres pasos, sobre su eje ───────────────────────────────────── */

.pasos {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.25rem;
}

/* El eje: nace completo; el bloque MOVIMIENTO lo dibuja si puede. */
.pasos::before {
  content: '';
  position: absolute;
  top: 5px;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--acento), var(--linea-cyan) 60%, transparent);
  opacity: 0.55;
}

@media (min-width: 880px) {
  .pasos {
    grid-template-columns: repeat(3, 1fr);
    gap: 2.75rem;
  }
}

.paso {
  padding-top: 2.1rem;
  position: relative;
}

.paso::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--acento);
}

.paso .numero {
  color: var(--acento);
}

.paso h3 {
  margin-top: 0.5rem;
}

.paso p {
  margin-top: 0.6rem;
  font-size: 0.9375rem;
}

/* ── Los planes ─────────────────────────────────────────────────────── */

.planes {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
  align-items: stretch;
}

@media (min-width: 940px) {
  .planes {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 939.98px) {
  .planes {
    max-width: 430px;
    margin-inline: auto;
  }
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--filete);
  border-radius: var(--radio);
  background: var(--card);
  box-shadow: var(--alza);
  padding: clamp(1.75rem, 1.4rem + 1.2vw, 2.4rem);
}

.plan-pro {
  border-color: var(--linea-cyan);
  background: var(--card-alta);
  box-shadow: var(--alza), var(--glow);
}

.plan .distintivo {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--letra-cifra);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tinta-boton);
  background: var(--acento);
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
}

.plan .nombre {
  font-family: var(--letra-cifra);
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--acento-vivo);
}

.plan .lema {
  font-family: var(--letra-titular);
  font-size: 1.3rem;
  color: var(--texto);
  margin-top: 0.35rem;
}

.plan .precio {
  font-family: var(--letra-cifra);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.5rem, 2rem + 1.6vw, 3.25rem);
  line-height: 1;
  color: var(--texto);
  margin-top: 1.6rem;
}

.plan .precio small {
  font-size: 0.875rem;
  color: var(--texto-suave);
  letter-spacing: 0.02em;
}

.plan ul {
  margin: 1.6rem 0 1.9rem;
  display: grid;
  gap: 0.65rem;
  flex: 1;
}

.plan li {
  display: flex;
  gap: 0.65rem;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--texto-suave);
}

.plan li::before {
  content: '✓';
  color: var(--acento);
  font-weight: 400;
  flex: none;
}

.plan li.mas {
  color: var(--texto);
  font-weight: 400;
}

.plan .boton {
  justify-content: center;
}

.nota-planes {
  /* Los 2,6rem que separaban los planes de lo que viene debajo los
     ponía la nota del precio fundador, que ya no está. */
  margin-top: 2.6rem;
  text-align: center;
  font-size: 0.8125rem;
}

/* ── La noria de los planes ────────────────────────────────
   Tres columnas iguales dicen que los tres planes valen lo mismo. Una
   noria dice otra cosa: el del centro manda —de frente, más grande y
   delante— y los otros dos esperan a los lados, girados hacia él. Al
   pulsar uno de los lados la noria gira una posición y ese plan se
   pone delante; el que estaba en el centro cede el sitio y el tercero
   cruza por detrás, que es lo que hace que el giro se entienda.

   La entrada cuenta lo mismo en pequeño: primero emerge Pro desde el
   fondo, y cuando ya está puesto llegan Básico por la izquierda y Full
   por la derecha.

   Vive bajo tres guardas: que haya sitio (940 px), que haya JS (es
   `data-noria` quien la enciende) y que nadie haya pedido menos
   movimiento. Si falta cualquiera de las tres, los tres planes se leen
   como siempre, en fila y del mismo tamaño. */

@media (min-width: 940px) and (prefers-reduced-motion: no-preference) {
  /* Las cartas nacen fuera de la pantalla para poder entrar, y un
     elemento desplazado con `transform` SIGUE contando para el ancho
     desplazable: sin este recorte la página traía barra horizontal
     desde que carga hasta que los planes se revelan (medido: 184 px de
     sobra a 1128). Se recorta en la sección y no en el carril, porque
     `overflow` distinto de `visible` sobre el elemento que lleva
     `preserve-3d` lo aplana y se pierde el orden por profundidad. */
  #planes {
    overflow-x: clip;
  }

  .planes[data-noria] {
    --dur-noria: 660ms;
    grid-template-columns: minmax(0, 1fr);
    /* El punto de fuga, en el centro del carril. Sin `preserve-3d` las
       cartas no se ordenarían por profundidad y la que cruza pasaría
       por delante de la del centro en vez de por detrás. */
    perspective: 1600px;
    transform-style: preserve-3d;
    /* Y aquí está el truco que no se ve venir: en 3D, un hijo con
       `translateZ` negativo queda DETRÁS del plano de su propio padre.
       Se pinta igual (el padre no tiene fondo), pero el que recibe el
       clic es el padre, así que las cartas de los lados no se podían
       pulsar. El carril deja de ser blanco de los punteros y cada carta
       los recoge por su cuenta. */
    pointer-events: none;
  }

  .planes[data-noria] .plan {
    grid-area: 1 / 1;
    justify-self: center;
    width: min(25rem, 38%);
    pointer-events: auto;
  }

  /* Los tres sitios. `translateX` en porcentaje se mide sobre la propia
     carta, así que el reparto aguanta cualquier ancho. */
  .planes[data-noria] .plan[data-sitio='centro'] {
    --reposo: translateX(0) translateZ(0) rotateY(0deg) scale(1);
    --llegada: translateZ(-420px) scale(0.92);
    z-index: 3;
  }

  .planes[data-noria] .plan[data-sitio='izquierda'] {
    --reposo: translateX(-90%) translateZ(-170px) rotateY(20deg) scale(0.86);
    --llegada: translateX(-170%) translateZ(-300px) rotateY(34deg) scale(0.78);
    z-index: 2;
  }

  .planes[data-noria] .plan[data-sitio='derecha'] {
    --reposo: translateX(90%) translateZ(-170px) rotateY(-20deg) scale(0.86);
    --llegada: translateX(170%) translateZ(-300px) rotateY(-34deg) scale(0.78);
    z-index: 2;
  }

  /* El sitio de reposo, y el viaje entre sitios. La especificidad
     (cuatro clases) no es capricho: los reveals en cadencia escriben
     sobre estas mismas cartas más abajo en la hoja. */
  html.con-js .planes[data-noria] .plan[data-sitio],
  .planes[data-noria] .plan[data-sitio] {
    transform: var(--reposo);
    transition:
      transform var(--dur-noria) var(--ease-asentar),
      opacity var(--dur-noria) var(--ease-suave),
      box-shadow var(--dur-noria) var(--ease-suave);
    transition-delay: 0s;
  }

  /* Lo que está delante se nota también por el suelo que proyecta. */
  .planes[data-noria] .plan[data-sitio='centro'] {
    box-shadow: var(--alza), 0 40px 90px -42px rgba(0, 0, 0, 0.85);
  }

  .planes[data-noria] .plan-pro[data-sitio='centro'] {
    box-shadow: var(--alza), var(--glow), 0 40px 90px -42px rgba(0, 0, 0, 0.85);
  }

  /* Los lados invitan a pulsarse; el del centro ya está donde tiene que
     estar y no hace nada. Solo cuando NO manda el cursor de la casa: con
     él, lo que avisa es el anillo cerrándose, y una flecha del sistema
     encima sería el segundo cursor en pantalla. */
  html:not(.con-cursor) .planes[data-noria] .plan[data-sitio]:not([data-sitio='centro']) {
    cursor: pointer;
  }

  /* Y su botón no responde mientras está a un lado: pulsar una carta de
     lado la trae al centro, no abre el correo. Con el teclado sigue
     siendo alcanzable —`pointer-events` no quita el foco—, y al
     recibirlo la carta se pone delante sola. */
  .planes[data-noria] .plan[data-sitio]:not([data-sitio='centro']) .boton {
    pointer-events: none;
  }

  /* La entrada: escondidas y fuera de sitio hasta que la sección se
     revela. Bajo `html.con-js` como todo lo que se esconde, para que
     sin JS los planes nazcan visibles. */
  html.con-js .planes[data-noria] .plan[data-sitio] {
    opacity: 0;
    transform: var(--llegada);
  }

  html.con-js .planes[data-noria].es-visible .plan[data-sitio] {
    opacity: 1;
    transform: var(--reposo);
  }

  /* Primero Pro, y cuando ya está puesto, los dos lados. El retardo
     vive en un atributo que el JS retira al terminar: si se quedase,
     cada giro saldría tarde. Y va con `html.con-js` delante para pesar
     más que el `transition-delay: 0s` de arriba, que existe para que
     los reveals en cadencia no cuelen aquí sus propios retardos. */
  html.con-js .planes[data-noria][data-entrando] .plan[data-sitio='izquierda'] {
    transition-delay: 300ms;
  }

  html.con-js .planes[data-noria][data-entrando] .plan[data-sitio='derecha'] {
    transition-delay: 380ms;
  }
}

/* ── La noria de las guías ─────────────────────────────────
   La misma noria que la de los planes, con ocho cartas: tres a la
   vista (izquierda, centro, derecha) y cinco esperando al fondo,
   detrás de la del centro y sin punteros, que salen por un lado
   cuando la rueda gira. Con cinco escondidas hace falta decir que
   están: dos flechas y un contador bajo la rueda, que solo existen
   cuando la rueda gira (las mismas tres guardas). Sin rueda, las ocho
   se leen en rejilla, que es como deben leerse cuando no hay rueda.
   Las cartas son enlaces enteros: pulsar una de lado la trae al
   centro sin navegar, y navegar es cosa de la del centro. */

@media (min-width: 940px) and (prefers-reduced-motion: no-preference) {
  #guias {
    overflow-x: clip;
  }

  .guias[data-noria] {
    --dur-noria: 660ms;
    grid-template-columns: minmax(0, 1fr);
    perspective: 1600px;
    transform-style: preserve-3d;
    pointer-events: none;
  }

  .guias[data-noria] .senda {
    grid-area: 1 / 1;
    justify-self: center;
    width: min(25rem, 38%);
    pointer-events: auto;
  }

  .guias[data-noria] .senda[data-sitio='centro'] {
    --reposo: translateX(0) translateZ(0) rotateY(0deg) scale(1);
    --llegada: translateZ(-420px) scale(0.92);
    z-index: 3;
  }

  .guias[data-noria] .senda[data-sitio='izquierda'] {
    --reposo: translateX(-90%) translateZ(-170px) rotateY(20deg) scale(0.86);
    --llegada: translateX(-170%) translateZ(-300px) rotateY(34deg) scale(0.78);
    z-index: 2;
  }

  .guias[data-noria] .senda[data-sitio='derecha'] {
    --reposo: translateX(90%) translateZ(-170px) rotateY(-20deg) scale(0.86);
    --llegada: translateX(170%) translateZ(-300px) rotateY(-34deg) scale(0.78);
    z-index: 2;
  }

  /* Las del fondo: detrás de la del centro, y del tamaño de los lados
     para que al salir por uno de ellos no cambien de escala de golpe. */
  .guias[data-noria] .senda[data-sitio='fondo'] {
    --reposo: translateZ(-420px) scale(0.86);
    --llegada: translateZ(-420px) scale(0.86);
    z-index: 1;
  }

  html.con-js .guias[data-noria] .senda[data-sitio],
  .guias[data-noria] .senda[data-sitio] {
    transform: var(--reposo);
    transition:
      transform var(--dur-noria) var(--ease-asentar),
      opacity var(--dur-noria) var(--ease-suave),
      box-shadow var(--dur-noria) var(--ease-suave);
    transition-delay: 0s;
  }

  .guias[data-noria] .senda[data-sitio='centro'] {
    box-shadow: var(--alza), 0 40px 90px -42px rgba(0, 0, 0, 0.85);
  }

  html.con-js .guias[data-noria] .senda[data-sitio] {
    opacity: 0;
    transform: var(--llegada);
  }

  html.con-js .guias[data-noria].es-visible .senda[data-sitio] {
    opacity: 1;
    transform: var(--reposo);
  }

  /* Las del fondo no se ven ni se pulsan, también después de la
     entrada; el foco sí les llega, y las trae al centro. Va detrás de
     la regla de arriba y con su misma especificidad para ganarle. */
  html.con-js .guias[data-noria].es-visible .senda[data-sitio='fondo'],
  .guias[data-noria] .senda[data-sitio='fondo'] {
    opacity: 0;
    pointer-events: none;
  }

  html.con-js .guias[data-noria][data-entrando] .senda[data-sitio='izquierda'] {
    transition-delay: 300ms;
  }

  html.con-js .guias[data-noria][data-entrando] .senda[data-sitio='derecha'] {
    transition-delay: 380ms;
  }

  /* Los mandos, solo cuando la rueda gira: mismas tres guardas. */
  html.con-js .guias[data-noria] + .noria-mandos {
    display: flex;
  }
}

/* Las flechas y el contador de la noria. Nacen escondidos: sin rueda
   no hay nada que mandar. */
.noria-mandos {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1.75rem;
}

.noria-paso {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--filete);
  border-radius: 50%;
  background: var(--card);
  color: var(--texto);
  cursor: pointer;
  transition:
    border-color var(--dur-cerca) var(--ease-asentar),
    background-color var(--dur-cerca) var(--ease-asentar);
}

.noria-paso:hover,
.noria-paso:focus-visible {
  border-color: var(--linea-cyan);
  background: var(--card-alta);
}

.noria-paso svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.noria-contador {
  min-width: 4.5rem;
  margin: 0;
  text-align: center;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  color: var(--texto-suave);
}

/* ── Preguntas ──────────────────────────────────────────────────────── */

/* Alineadas a la izquierda como el resto del cuerpo: los dos únicos
   momentos centrados de la portada son el héroe y el cierre. */
.preguntas {
  max-width: 720px;
  border-top: 1px solid var(--filete);
}

.preguntas details {
  border-bottom: 1px solid var(--filete);
}

.preguntas summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.25rem;
  padding: 1.4rem 0.25rem;
  font-weight: 400;
  font-size: 1.0625rem;
  color: var(--texto);
  transition: color var(--dur-cerca) var(--ease-suave);
}

.preguntas summary::-webkit-details-marker {
  display: none;
}

.preguntas summary:hover {
  color: var(--acento-vivo);
}

.preguntas summary .mas {
  flex: none;
  font-family: var(--letra-cifra);
  font-size: 1.15rem;
  color: var(--acento);
  transition: transform var(--dur-cerca) var(--ease-asentar);
  transform-origin: center;
  align-self: center;
}

.preguntas details[open] summary .mas {
  transform: rotate(45deg);
}

.preguntas details p {
  padding: 0 2.5rem 1.5rem 0.25rem;
  font-size: 0.9375rem;
}

/* ── El cierre ──────────────────────────────────────────────────────── */

.final {
  text-align: center;
}

/* El eco de la curva: plana y sobre cero. La caja bajo control. */
.curva-calma {
  max-width: 560px;
  margin: 0 auto 2.75rem;
}

.curva-calma svg {
  display: block;
  width: 100%;
  height: 64px;
}

.curva-calma .linea {
  stroke: var(--acento);
  stroke-width: 2;
  fill: none;
  opacity: 0.55;
}

.curva-calma .cero {
  stroke: var(--texto-suave);
  stroke-width: 1;
  stroke-dasharray: 3 6;
  opacity: 0.3;
}

.final h2 {
  max-width: 24ch;
  margin-inline: auto;
}

.final .entradilla {
  max-width: 30rem;
  margin: 1.4rem auto 2.4rem;
}

/* ── El pie ─────────────────────────────────────────────────────────── */

.pie-pagina {
  border-top: 1px solid var(--filete);
  padding-block: clamp(3rem, 2.5rem + 2vw, 4.5rem) 2rem;
}

.pie-columnas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}

@media (min-width: 760px) {
  .pie-columnas {
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 2rem;
  }
}

.pie-pagina .marca img {
  width: 32px;
  height: 32px;
}

.pie-pagina .marca .logotipo {
  height: 17px;
}

.pie-pagina .descriptor {
  margin-top: 1rem;
  max-width: 24rem;
  font-size: 0.9375rem;
}

.pie-pagina .pie-titulo {
  font-family: var(--letra-cifra);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-suave);
  margin-bottom: 1.1rem;
}

.pie-pagina nav ul {
  display: grid;
  gap: 0.55rem;
}

.pie-pagina nav a {
  font-size: 0.9375rem;
  font-weight: 400;
  text-decoration: none;
  color: var(--texto-suave);
  transition: color var(--dur-cerca) var(--ease-suave);
}

.pie-pagina nav a:hover,
.pie-pagina nav a:focus-visible {
  color: var(--acento-vivo);
}

.pie-final {
  margin-top: clamp(2.5rem, 2rem + 2vw, 4rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--filete);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-size: 0.8125rem;
}

.pie-final p,
.pie-final a {
  color: var(--texto-suave);
}

/* ── Páginas interiores (guías y legales) ───────────────────────────── */

.pagina-interior main {
  padding-top: clamp(8rem, 7rem + 4vw, 10.5rem);
  padding-bottom: clamp(4.75rem, 4rem + 3vw, 7.5rem);
}

.miga {
  font-family: var(--letra-cifra);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texto-suave);
}

.pagina-interior h1 {
  font-size: clamp(2rem, 1.2rem + 2.8vw, 3.25rem);
  max-width: 22ch;
  margin-top: 1.1rem;
}

.pagina-interior .meta {
  font-family: var(--letra-cifra);
  font-size: 0.8125rem;
  color: var(--texto-suave);
  margin-top: 1.25rem;
}

/* El lienzo interior: prosa + índice pegajoso en pantallas anchas. */
.interior-lienzo {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3rem;
  margin-top: clamp(2.5rem, 2rem + 2vw, 4rem);
}

@media (min-width: 1280px) {
  .interior-lienzo {
    grid-template-columns: minmax(0, 68ch) 250px;
    gap: 5rem;
  }

  .indice {
    position: sticky;
    top: 108px;
    align-self: start;
  }
}

.indice h2 {
  font-family: var(--letra-cifra);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-suave);
  margin-bottom: 1rem;
}

.indice ul {
  display: grid;
  gap: 0.5rem;
  border-left: 1px solid var(--filete);
}

.indice a {
  display: block;
  padding-left: 1rem;
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.5;
  text-decoration: none;
  color: var(--texto-suave);
  border-left: 1px solid transparent;
  margin-left: -1px;
  transition:
    color var(--dur-cerca) var(--ease-suave),
    border-color var(--dur-cerca) var(--ease-suave);
}

.indice a:hover,
.indice a:focus-visible {
  color: var(--acento-vivo);
  border-left-color: var(--acento);
}

/* La prosa: medida de lectura, aire y jerarquía serif. */
.prosa {
  max-width: 68ch;
}

.prosa > * + * {
  margin-top: 1.1rem;
}

.prosa p,
.prosa li {
  font-size: 1rem;
  line-height: 1.75;
}

.prosa h2 {
  font-size: clamp(1.4rem, 1.2rem + 1vw, 1.75rem);
  padding-top: 2.25rem;
}

.prosa h3 {
  font-size: 1.0625rem;
  padding-top: 1.1rem;
}

.prosa ul,
.prosa ol {
  display: grid;
  gap: 0.55rem;
  padding-left: 1.4rem;
}

.prosa ul {
  list-style: disc;
}

.prosa ol {
  list-style: decimal;
}

.prosa ::marker {
  color: var(--acento);
  font-family: var(--letra-cifra);
  font-size: 0.9em;
}

.prosa a {
  color: var(--acento-vivo);
  text-decoration: underline;
  text-decoration-color: var(--linea-cyan);
  text-underline-offset: 0.2em;
  transition: text-decoration-color var(--dur-cerca) var(--ease-suave);
}

.prosa a:hover {
  text-decoration-color: currentColor;
}

/* Los botones dentro de la prosa no son enlaces de prosa: recuperan su
   tinta y pierden el subrayado (la regla .prosa a los pisaba y dejaba
   cian sobre cian, 1,5:1 — lo cazó auditar.js). */
.prosa a.boton {
  text-decoration: none;
}

.prosa a.boton-primario,
.prosa a.boton-primario:hover {
  color: var(--tinta-boton);
}

/* Tablas: hairlines y cifras tabulares, sin cajas pesadas. */
.prosa table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.prosa th,
.prosa td {
  text-align: left;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--filete);
  color: var(--texto-suave);
  vertical-align: top;
}

.prosa th {
  font-family: var(--letra-cifra);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texto);
  border-bottom-color: var(--linea-fuerte);
}

.prosa td strong {
  color: var(--texto);
}

/* La caja destacada: un dato apoyado, no una banda. */
.prosa .caja {
  border: 1px solid var(--filete);
  border-left: 2px solid var(--acento);
  border-radius: var(--radio-s);
  background: var(--card);
  padding: 1.25rem 1.5rem;
}

/* La firma de la guía: quién la escribe, en la caja destacada. Va con
   clase propia porque .caja también viste el titular de las legales, y
   porque el aire entre párrafos de la prosa solo alcanza a los hijos
   directos de .prosa. */
.prosa .autor {
  margin-top: 2.75rem;
}

.prosa .autor > * + * {
  margin-top: 0.55rem;
}

.prosa .autor .miga {
  margin-bottom: 0.35rem;
}

.prosa .autor p {
  font-size: 0.9375rem;
}

/* La banda de CTA de las guías y la de descarga. */
.prosa .cta-caja,
.prosa .descarga {
  border: 1px solid var(--linea-cyan);
  border-radius: var(--radio);
  background: var(--card-alta);
  box-shadow: var(--alza);
  padding: 1.75rem 2rem;
  margin-block: 2.25rem;
}

.prosa .cta-caja p,
.prosa .descarga p {
  margin: 0 0 1.25rem;
}

.prosa .descarga {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  flex-wrap: wrap;
}

.prosa .descarga p {
  margin: 0;
  flex: 1;
  min-width: 220px;
}

.enlaces-relacionados {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--filete);
  font-size: 0.9375rem;
}

/* Pie compacto de las interiores. */
.pie-simple {
  border-top: 1px solid var(--filete);
  padding-block: 2rem;
}

.pie-simple .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.8125rem;
}

.pie-simple p {
  color: var(--texto-suave);
}

.pie-simple nav {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.pie-simple a {
  color: var(--texto-suave);
  text-decoration: none;
  transition: color var(--dur-cerca) var(--ease-suave);
}

.pie-simple a:hover,
.pie-simple a:focus-visible {
  color: var(--acento-vivo);
}

/* ── La lupa: la pantalla entera, el resto en penumbra ─────────────
   <dialog> nativo: capa superior (escapa de overflow y de cualquier
   apilado), foco atrapado, Escape gratis y ::backdrop para la penumbra.

   En la página la pantalla va recortada; aquí se ve ENTERA, a su tamaño
   y con desplazamiento propio, que es exactamente lo que el recorte
   promete. Por eso ya no hay viaje FLIP: el origen es un trozo y el
   destino es la pantalla completa, y escalar de uno al otro deformaba.
   Entra como entra todo en esta casa: fundiendo y subiendo un dedo.

   Se clona, no se muda: mover la isla dejaría un hueco en la página y
   obligaría a devolverla al cerrar. */

/* fixed + inset: el diálogo del navegador nace en position absolute con
   top auto, o sea colocado según el flujo del documento; en una página
   larga eso deja la lupa a mil píxeles de la mirada. */
.lupa {
  position: fixed;
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  overflow: hidden;
}

.lupa::backdrop {
  background: rgba(4, 8, 16, 0.82);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}

@media (prefers-reduced-motion: no-preference) {
  .lupa[open]::backdrop,
  .lupa[open] .lupa-cerrar {
    animation: fundir 300ms var(--ease-suave) both;
  }

  .lupa.cerrando::backdrop,
  .lupa.cerrando .lupa-cerrar {
    animation: apagar 340ms var(--ease-suave) both;
  }
}

@keyframes apagar {
  to {
    opacity: 0;
  }
}

.lupa .lupa-mesa {
  width: 100%;
  height: 100%;
  display: grid;
  /* Columna explícita: con una columna automática, el `100%` del ancho
     de la pantalla se resuelve contra una columna que a su vez se mide
     por el contenido, y la pantalla se abría más ancha que el diálogo. */
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  /* La pantalla entera no cabe en un viewport: se recorre. */
  overflow: auto;
  overscroll-behavior: contain;
  padding: clamp(1rem, 3vw, 3rem) clamp(1rem, 3vw, 3rem) 25vh;
  cursor: zoom-out;
}

/* El único sitio donde la pantalla recupera su caja: flotando sobre
   la penumbra necesita un canto y un suelo que la separen del fondo.
   Y aquí se ve ENTERA: sin recorte, sin humo y a su tamaño. */
.lupa .vista {
  width: min(1560px, 100%);
  border-radius: var(--radio-l);
  border: 1px solid var(--linea-fuerte);
  background: var(--bg);
  box-shadow: var(--alza), 0 40px 90px -30px rgba(0, 0, 0, 0.85);
  /* El radio tiene que recortar a la pantalla, o los cantos del
     producto asoman por las esquinas. */
  overflow: clip;
  transition: none;
}

.lupa .vista-isla {
  height: auto;
  overflow: visible;
  contain: none;
  -webkit-mask-image: none;
  mask-image: none;
}

/* Las pantallas que son documento crecen a lo que midan y se recorren.
   Las que son marco no tienen alto propio (su contenido va colgado de
   `inset: 0`), así que aquí se les da una ventana grande. */
.lupa .vista-app .vista-isla {
  height: min(84vh, 52rem);
  overflow: clip;
  contain: paint;
}

.lupa .vista .vista .vista-isla > .lyq {
  margin-top: 0;
}

.lupa .vista-ampliar,
.lupa .velo-demo {
  display: none;
}

/* Apoyar el diálogo en la cima es cosa del recorte; aquí cabe entero y
   vuelve a su sitio, que es el centro. */
.lupa .vista-cima .lyq .place-items-center {
  place-items: center;
}

.lupa-cerrar {
  position: fixed;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--linea-fuerte);
  background: rgba(8, 15, 31, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--txt);
  transition:
    color var(--dur-cerca) var(--ease-suave),
    border-color var(--dur-cerca) var(--ease-suave);
}

.lupa-cerrar:hover {
  color: var(--cyan-l);
  border-color: var(--linea-cyan);
}

.lupa-cerrar svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
}

.lupa-hueco {
  flex: none;
}

/* ═════════════════════════════════════════════════════════════════════
   MOVIMIENTO
   El fluir: fundidos y desplazamientos cortos hacia arriba, curvas que
   asientan, ninguna salida. Mecanismo de revelado: IntersectionObserver
   con la receta de la referencia (threshold .12, rootMargin -40px,
   clase .es-visible UNA vez). Se eligió IO y no ViewTimeline porque es
   «una vez» de verdad, es la receta de oakandgrid.com, y es verificable
   por DOM en el navegador integrado.

   Guarda anti-contenido-oculto: el estado oculto de .revela vive SOLO
   bajo html.con-js (la pone un script inline solo si existe
   IntersectionObserver) y bajo no-preference. Sin JS o con movimiento
   reducido, la página nace completa y quieta.
   ═════════════════════════════════════════════════════════════════════ */

/* ── 1 · Transiciones entre páginas (continuidad, CSS puro) ─────────── */

@view-transition {
  navigation: auto;
}

/* Asimetría deliberada: la que sale solo se apaga, rápida; la que entra
   sube por encima, más lenta. El agua no da portazos. */
::view-transition-old(root) {
  animation: vt-salir 240ms var(--ease-suave) both;
}

::view-transition-new(root) {
  animation: vt-entrar var(--dur-vista) var(--ease-asentar) both;
}

@keyframes vt-salir {
  to {
    opacity: 0;
  }
}

@keyframes vt-entrar {
  from {
    opacity: 0;
    transform: translateY(0.55rem);
  }
}

/* ── 1b · La portada (solo Inicio, una vez por visita) ───────────────
   La cubierta de carga: el navy de la casa con la marca en el centro y
   una línea que se llena como sube el nivel de un depósito, ~4 s en
   total y la página descubierta al abrirse hacia arriba. Sin contador
   de porcentaje: no hay carga que medir y esta web no enseña cifras
   que no son; la línea llenándose es el gesto, no un dato.

   Existe solo si el script de cabecera puso html.con-portada (una vez
   por visita vía sessionStorage; cualquier página del sitio deja la
   marca) y bajo la guarda de movimiento reducido: sin JS o con
   reducido, este div ni llega a pintarse. pagereveal la retira en
   llegadas por transición de vista. Es LA excepción deliberada a
   «ninguna salida»: la cubierta yéndose es el gesto que descubre.

   Compás: icono 150-800 ms · wordmark 350-1000 · línea 500-3100 ·
   la marca se apaga 3050-3350 · apertura 3300-3980. El héroe arranca
   en 3650 (--espera-heroe), cuando la cubierta ya despeja su tercio.

   Y el héroe está PINTADO debajo desde el primer pintado: con la
   cubierta puesta su entrada es solo desplazamiento («posarse», en el
   bloque 2). Un h1 a opacidad 0 no cuenta como LCP, y con el fundido de
   siempre el LCP de escritorio se iba a 4,7 s (medido con
   _fuente/pruebas/vitales.mjs); lo que está tapado sí cuenta. */

.portada {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  html.con-portada {
    --espera-heroe: 3650ms;
  }

  html.con-portada .portada {
    display: grid;
    place-items: center;
    position: fixed;
    inset: 0;
    /* Sobre la barra (100), bajo el grano (130): también es material. */
    z-index: 120;
    background: var(--bg);
    animation: portada-abrirse 680ms ease-in-out 3300ms both;
  }

  html.con-portada .portada-contenido {
    display: grid;
    justify-items: center;
    gap: 1.4rem;
    animation: portada-apagarse 300ms var(--ease-suave) 3050ms forwards;
  }

  html.con-portada .portada .icono {
    width: 76px;
    height: 76px;
    filter: drop-shadow(0 10px 34px rgba(40, 202, 190, 0.4));
    animation: alzar var(--dur-focal) var(--ease-asentar) 150ms backwards;
  }

  html.con-portada .portada .wordmark {
    /* Baldosa de 76 px: mayuscula de 33, o sea 41 de caja. */
    height: 41px;
    width: auto;
    color: var(--txt);
    animation: alzar var(--dur-focal) var(--ease-asentar) 350ms backwards;
  }

  html.con-portada .portada .linea-carga {
    width: 180px;
    height: 2px;
    border-radius: 1px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
    animation: fundir 300ms var(--ease-suave) 500ms backwards;
  }

  html.con-portada .portada .linea-carga::before {
    content: '';
    display: block;
    height: 100%;
    background: var(--cyan);
    box-shadow: 0 0 12px rgba(40, 202, 190, 0.55);
    transform-origin: left;
    animation: portada-llenarse 2600ms ease-in-out 500ms both;
  }
}

@keyframes portada-llenarse {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

@keyframes portada-apagarse {
  to {
    opacity: 0;
  }
}

@keyframes portada-abrirse {
  to {
    transform: translateY(-100%);
    visibility: hidden;
  }
}

/* ── 2 · La entrada del héroe (el momento focal) ─────────────────────
   Solo en llegadas directas: si la página entra por transición de
   vista, pagereveal marca html.llega-con-transicion y la entrada se
   salta para que el fundido aterrice sobre página completa. Si hay
   portada, todo el compás se desplaza --espera-heroe. */

@media (prefers-reduced-motion: no-preference) {
  html:not(.llega-con-transicion) .heroe .kicker {
    animation: alzar var(--dur-focal) var(--ease-asentar) var(--espera-heroe, 0ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe h1 {
    animation: alzar var(--dur-focal) var(--ease-asentar) calc(var(--espera-heroe, 0ms) + 90ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .entradilla {
    animation: alzar var(--dur-focal) var(--ease-asentar) calc(var(--espera-heroe, 0ms) + 180ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .cta {
    animation: alzar var(--dur-focal) var(--ease-asentar) calc(var(--espera-heroe, 0ms) + 260ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .fiabilidad {
    animation: alzar var(--dur-focal) var(--ease-asentar) calc(var(--espera-heroe, 0ms) + 320ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .escenario {
    animation: aterrizar 700ms var(--ease-asentar) calc(var(--espera-heroe, 0ms) + 380ms) backwards;
  }

  /* La curva se traza cuando el H1 ya se ha posado. pathLength="1" en
     el SVG normaliza el trazo; el dasharray existe solo aquí dentro,
     así que sin esta guarda la curva está completa desde el primer
     frame. El punto y la etiqueta funden al terminar el trazo. */
  html:not(.llega-con-transicion) .curva-caja .linea {
    stroke-dasharray: 1;
    animation: trazar-caja var(--dur-trazo) ease-in-out calc(var(--espera-heroe, 0ms) + 500ms) both;
  }

  html:not(.llega-con-transicion) .curva-caja .marcador {
    animation: fundir 300ms var(--ease-suave) calc(var(--espera-heroe, 0ms) + 1800ms) backwards;
  }

  /* Con la cubierta puesta, el héroe NO se funde: está pintado a
     opacidad 1 debajo de la cubierta opaca desde el primer pintado y al
     arrancar solo se posa (transform). Así el h1 cuenta como LCP en el
     primer pintado (~1 s) y no cuando la cubierta lo descubre (4,7 s
     medidos): la cubierta yéndose ya es el fundido, y fundir dos veces
     era pagar dos veces. Solo cambia el nombre de la animación; duración,
     retardo y relleno siguen siendo los del compás. Sin cubierta, la
     entrada es la de siempre. Si alguien vuelve a meter opacidad aquí,
     el LCP vuelve a los 4,7 s. */
  html.con-portada:not(.llega-con-transicion) .heroe .kicker,
  html.con-portada:not(.llega-con-transicion) .heroe h1,
  html.con-portada:not(.llega-con-transicion) .heroe .entradilla,
  html.con-portada:not(.llega-con-transicion) .heroe .cta,
  html.con-portada:not(.llega-con-transicion) .heroe .fiabilidad {
    animation-name: posarse;
  }

  html.con-portada:not(.llega-con-transicion) .heroe .escenario {
    animation-name: aterrizar-quieto;
  }
}

@keyframes alzar {
  from {
    opacity: 0;
    transform: translateY(0.8rem);
  }
}

@keyframes aterrizar {
  from {
    opacity: 0;
    transform: translateY(1.4rem) scale(0.97);
  }
}

/* Los gemelos sin opacidad de alzar y aterrizar, para el héroe bajo la
   cubierta. */
@keyframes posarse {
  from {
    transform: translateY(0.8rem);
  }
}

@keyframes aterrizar-quieto {
  from {
    transform: translateY(1.4rem) scale(0.97);
  }
}

@keyframes trazar-caja {
  from {
    stroke-dashoffset: 1;
  }

  to {
    stroke-dashoffset: 0;
  }
}

@keyframes fundir {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* ── 2b · La escena: el bento se retira y el relevo emerge ────────────
   La única sección fijada de la web. El scroll no se secuestra —la barra
   sigue siendo del lector y avanza a su ritmo—: lo que se fija es el
   lienzo, y el recorrido de esos 220vh se reparte entre las seis celdas
   escapando cada una por su lado y la cabecera siguiente creciendo desde
   el centro.

   Nace apagada. Solo existe donde hay líneas de tiempo de scroll en CSS,
   con movimiento permitido y sitio de sobra (en móvil el bento es una
   columna y fijar la pantalla ahí solo estorbaría). En cualquier otro
   caso las dos capas se apilan y se leen seguidas, que es exactamente
   lo que la sección era antes. */

.escena-capa {
  min-width: 0;
}

.escena-relevo {
  padding-block: clamp(3.5rem, 3rem + 2vw, 5.5rem) 0;
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 1000px) and (min-height: 700px) {
    /* Dentro de la escena el bento es un vistazo, no una lectura: hay
       que meterlo entero en una pantalla o la banda de abajo se queda
       fuera del lienzo (medido: 911px de bento contra 796 de alto útil
       en un portátil de 1280×800). Se aprieta el aire, no el texto. */
    .escena-bento .cabecera-seccion {
      margin-bottom: 1.6rem;
    }

    .escena-bento .cabecera-seccion .entradilla {
      display: none;
    }

    .escena-bento .bento {
      gap: 0.7rem;
    }

    .escena-bento .celda {
      padding: 1.15rem 1.35rem;
      gap: 0.45rem;
    }

    .escena-bento .celda p {
      font-size: 0.875rem;
      line-height: 1.55;
    }

    .escena-bento .celda .motivo {
      padding-top: 0.8rem;
    }

    .escena-bento .motivo-curva svg {
      height: 40px;
    }

    .escena {
      /* 100vh de lienzo + 220vh de recorrido para la coreografía. */
      height: 320vh;
      padding-block: 0;
      view-timeline-name: --escena;
      view-timeline-axis: block;
    }

    .escena-lienzo {
      position: sticky;
      top: 0;
      height: 100vh;
      display: grid;
      align-content: center;
      /* clip y no hidden: no crea contenedor de scroll, y sin él las
         celdas que escapan ensancharían la página. */
      overflow: clip;
    }

    .escena-capa {
      grid-area: 1 / 1;
    }

    .escena-relevo {
      padding-block: 0;
      text-align: center;
      opacity: 0;
      animation: emerger linear both;
      animation-timeline: --escena;
      animation-range: contain 50% contain 88%;
    }

    .escena-relevo .cabecera-seccion {
      margin-bottom: 0;
      margin-inline: auto;
    }

    .escena-relevo .entradilla {
      margin-inline: auto;
    }

    /* Dentro de la escena manda la coreografía, no los reveals: dejar
       el estado oculto de .revela debajo de una animación que hereda su
       valor base es la manera de que algo no aparezca nunca. */
    .escena-bento .cabecera-seccion.revela,
    .escena-bento .cadencia > * {
      opacity: 1;
      transform: none;
      transition: none;
    }

    /* El titular del bento se va primero: abre el camino. */
    .escena-bento .cabecera-seccion {
      animation: escapar linear both;
      animation-timeline: --escena;
      animation-range: contain 4% contain 42%;
      --sale-y: -34vh;
    }

    .escena-bento .celda {
      animation: escapar linear both;
      animation-timeline: --escena;
      animation-range: contain 10% contain 58%;
    }

    /* Cada una por su lado: la de la izquierda por la izquierda, la de
       abajo por abajo, y la del centro hacia quien mira. */
    .escena-bento .celda:nth-child(1) { --sale-x: -72vw; --sale-y: -18vh; }
    .escena-bento .celda:nth-child(2) { --sale-x: 72vw; --sale-y: -18vh; }
    .escena-bento .celda:nth-child(3) { --sale-x: -78vw; animation-range: contain 14% contain 60%; }
    .escena-bento .celda:nth-child(4) { --sale-escala: 1.4; animation-range: contain 20% contain 62%; }
    .escena-bento .celda:nth-child(5) { --sale-x: 78vw; animation-range: contain 14% contain 60%; }
    .escena-bento .celda:nth-child(6) { --sale-y: 82vh; animation-range: contain 8% contain 56%; }
  }
}

/* ── 2c · El turno de los capítulos ───────────────────────────────────
   Los cinco comparten un mismo lugar y se relevan: cada uno entra por la
   derecha, se para en el centro el tramo largo del recorrido (que es
   donde se lee) y sale por la izquierda. La visibilidad se anima junto
   con la opacidad, y no por gusto: un panel a opacidad 0 sigue siendo
   alcanzable con el tabulador, y el foco se iría a un capítulo que nadie
   está viendo. Con visibility oculto, sus enlaces salen del recorrido. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 1000px) and (min-height: 700px) {
    .escena-h {
      /* 100vh de lienzo + ~104vh de recorrido por capítulo. */
      height: 620vh;
      padding-block: 0;
      view-timeline-name: --capitulos;
      view-timeline-axis: block;
    }

    .escena-h-lienzo {
      position: sticky;
      top: 0;
      height: 100vh;
      display: grid;
      align-content: center;
      overflow: clip;
    }

    .escena-h .capitulo .capitulo-texto p {
      margin-top: 0.6rem;
      font-size: 0.9375rem;
    }

    .escena-h .capitulo .numero {
      margin-bottom: 0.5rem;
    }

    .escena-h .capitulo {
      grid-area: 1 / 1;
      gap: 1.1rem;
      /* Sin esto no se estira: el carril lleva margin-inline auto, y un
         margen automático anula el estirado del grid — el panel se
         quedaba en 774 px y la pantalla del producto salía diminuta. */
      width: 100%;
      padding-block: 0;
      border-top: 0;
      animation: pasar-de-largo linear both;
      animation-timeline: --capitulos;
    }

    /* Cada uno con su turno, con un dedo de solape para que el que sale
       se cruce con el que entra y no quede la pantalla vacía.

       Los extremos son la excepción, y por lo mismo: el primero empieza
       a entrar mientras la sección todavía sube (entry 76%), así que
       cuando el lienzo se fija ya hay algo que mirar; y el último no
       sale por la izquierda, se queda hasta el final y se lo lleva la
       página al despegarse. Sin eso, entrar y salir de la escena
       costaba una pantalla vacía en cada extremo. */
    .escena-h .capitulo:nth-child(1) { animation-range: entry 76% contain 22%; }
    .escena-h .capitulo:nth-child(2) { animation-range: contain 19% contain 41%; }
    .escena-h .capitulo:nth-child(3) { animation-range: contain 38% contain 60%; }
    .escena-h .capitulo:nth-child(4) { animation-range: contain 57% contain 79%; }

    .escena-h .capitulo:nth-child(5) {
      animation-name: llegar-y-quedarse;
      animation-range: contain 76% contain 100%;
    }

    /* Aquí tampoco mandan los reveals: ver la nota de la escena de arriba. */
    .escena-h .capitulo.revela {
      transition: none;
    }

    /* Dentro de la escena el carril se ensancha: el texto se queda en
       sus 62 caracteres y la pantalla se lleva el resto, que es lo que
       la hace parecer parte de la página y no una lámina centrada. */
    .escena-h .capitulo {
      --wrap: min(1560px, 94vw);
    }

    .escena-h .vista {
      --vista-alto: min(52vh, 30rem);
      --vista-humo: 7rem;
    }
  }
}

@keyframes pasar-de-largo {
  0% {
    opacity: 0;
    visibility: hidden;
    transform: translateX(46vw);
  }

  6% {
    visibility: visible;
  }

  26% {
    opacity: 1;
    transform: none;
  }

  74% {
    opacity: 1;
    transform: none;
  }

  94% {
    visibility: visible;
  }

  100% {
    opacity: 0;
    visibility: hidden;
    transform: translateX(-46vw);
  }
}

@keyframes llegar-y-quedarse {
  0% {
    opacity: 0;
    visibility: hidden;
    transform: translateX(46vw);
  }

  8% {
    visibility: visible;
  }

  55% {
    opacity: 1;
    transform: none;
  }

  100% {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
}

@keyframes escapar {
  to {
    opacity: 0;
    transform: translate(var(--sale-x, 0), var(--sale-y, 0)) scale(var(--sale-escala, 1));
  }
}

@keyframes emerger {
  from {
    opacity: 0;
    transform: scale(0.82);
  }

  60% {
    opacity: 1;
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ── 3 · El scroll trae contenido (reveals, una sola vez) ───────────── */

@media (prefers-reduced-motion: no-preference) {
  html.con-js .revela {
    opacity: 0;
    transform: translateY(14px);
    transition:
      opacity var(--dur-focal) var(--ease-revelar),
      transform var(--dur-focal) var(--ease-revelar);
  }

  html.con-js .revela.es-visible {
    opacity: 1;
    transform: none;
  }

  /* Cadencia en rejillas: los hijos llegan en oleada corta (tope 5). */
  html.con-js .cadencia > * {
    opacity: 0;
    transform: translateY(14px);
    transition:
      opacity var(--dur-focal) var(--ease-revelar),
      transform var(--dur-focal) var(--ease-revelar);
  }

  html.con-js .cadencia.es-visible > * {
    opacity: 1;
    transform: none;
  }

  html.con-js .cadencia.es-visible > :nth-child(2) { transition-delay: 60ms; }
  html.con-js .cadencia.es-visible > :nth-child(3) { transition-delay: 120ms; }
  html.con-js .cadencia.es-visible > :nth-child(4) { transition-delay: 180ms; }
  html.con-js .cadencia.es-visible > :nth-child(5) { transition-delay: 240ms; }
  html.con-js .cadencia.es-visible > :nth-child(n + 6) { transition-delay: 300ms; }

  /* El eje de los pasos se dibuja de izquierda a derecha al revelarse. */
  html.con-js .pasos::before {
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 900ms ease-in-out 120ms;
  }

  html.con-js .pasos.es-visible::before {
    transform: scaleX(1);
  }
}

/* ── 3b · La secuencia de las dos sendas, en dos actos ────────────────
   Primero se cuenta el ERP, con la tarjeta sola en el centro: una
   clavija recorre su cable y enciende el sistema, por turnos. Cuando
   los tres están conectados, esa tarjeta CEDE EL SITIO —se desplaza a
   su mitad— y entra por la derecha la del Excel, que cuenta lo suyo: el
   libro llega, la barra avanza y aparecen las columnas reconocidas.

   Todo el compás vive en las cinco variables de abajo. Para que la
   secuencia entera vaya más rápida o más lenta se tocan ahí y en un
   solo sitio, no en catorce reglas.

   Como el resto de la casa: el estado apagado vive SOLO bajo html.con-js
   y movimiento permitido. Sin JS o con reduced-motion, las dos tarjetas
   están en su sitio, los sistemas conectados y el Excel leído desde el
   primer instante — que es el final de la historia, no un fallo. */

.sendas {
  --sec-base: 320ms;    /* cuándo arranca la primera clavija */
  --sec-viaje: 1000ms;  /* lo que tarda una clavija en llegar */
  --sec-paso: 1040ms;   /* de una conexión a la siguiente */
  --sec-relevo: 3750ms; /* cuándo el ERP cede el sitio */
  --sec-excel: 4350ms;  /* cuándo arranca el importador */
}

@media (prefers-reduced-motion: no-preference) {
  html.con-js .sendas .corriente {
    transform: scaleX(0);
  }

  html.con-js .sendas .clavija {
    transform: translateX(calc(-1 * var(--cable)));
  }

  html.con-js .sendas .conexion img {
    filter: grayscale(1) brightness(1.7);
    opacity: 0.45;
  }

  html.con-js .sendas .conexion--otros,
  html.con-js .sendas .importador .libro,
  html.con-js .sendas .importador .leido,
  html.con-js .sendas .importador .columnas li {
    opacity: 0;
  }

  html.con-js .sendas .progreso i {
    transform: scaleX(0);
  }

  /* ACTO 1 · las tres conexiones, una detrás de otra. */
  html.con-js .sendas.es-visible .clavija {
    animation: enchufar var(--sec-viaje) var(--ease-asentar)
      calc(var(--sec-base) + var(--turno) * var(--sec-paso)) both;
  }

  html.con-js .sendas.es-visible .corriente {
    animation: dar-corriente var(--sec-viaje) var(--ease-asentar)
      calc(var(--sec-base) + var(--turno) * var(--sec-paso)) both;
  }

  html.con-js .sendas.es-visible .conexion img {
    animation: encender 520ms var(--ease-asentar)
      calc(var(--sec-base) + var(--turno) * var(--sec-paso) + 780ms) both;
  }

  html.con-js .sendas.es-visible .conexion--otros {
    animation: fundir 600ms var(--ease-suave)
      calc(var(--sec-base) + var(--turno) * var(--sec-paso)) both;
  }

  /* ACTO 2 · el relevo y el importador. */
  html.con-js .sendas.es-visible .senda-excel {
    animation: entrar-por-la-derecha 1100ms var(--ease-asentar) var(--sec-relevo) both;
  }

  html.con-js .sendas.es-visible .importador .libro {
    animation: caer 760ms var(--ease-asentar) var(--sec-excel) both;
  }

  html.con-js .sendas.es-visible .progreso i {
    animation: llenar 1500ms var(--ease-suave) calc(var(--sec-excel) + 620ms) both;
  }

  html.con-js .sendas.es-visible .importador .leido {
    animation: fundir 460ms var(--ease-suave) calc(var(--sec-excel) + 2160ms) both;
  }

  html.con-js .sendas.es-visible .columnas li {
    animation: asomar 460ms var(--ease-asentar)
      calc(var(--sec-excel) + 2300ms + var(--turno) * 140ms) both;
  }

  /* El desplazamiento solo tiene sentido con las dos tarjetas en fila:
     en una sola columna no hay sitio que ceder, y mover media anchura
     sacaría la tarjeta de la pantalla. */
  @media (min-width: 880px) {
    html.con-js .sendas .senda-erp {
      transform: translateX(calc(50% + 0.45rem));
    }

    html.con-js .sendas.es-visible .senda-erp {
      animation: ceder-el-sitio 1100ms var(--ease-asentar) var(--sec-relevo) both;
    }
  }
}

@keyframes ceder-el-sitio {
  from {
    transform: translateX(calc(50% + 0.45rem));
  }

  to {
    transform: none;
  }
}

@keyframes entrar-por-la-derecha {
  from {
    opacity: 0;
    transform: translateX(26%);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes enchufar {
  from {
    transform: translateX(calc(-1 * var(--cable)));
  }

  to {
    transform: none;
  }
}

@keyframes dar-corriente {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

@keyframes encender {
  0% {
    filter: grayscale(1) brightness(1.7);
    opacity: 0.45;
    transform: scale(0.97);
  }

  55% {
    transform: scale(1.035);
  }

  100% {
    filter: none;
    opacity: 1;
    transform: none;
  }
}

@keyframes caer {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes llenar {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

@keyframes asomar {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ── 4 · Hovers: solo donde hay ratón de verdad ─────────────────────── */

@media (hover: hover) and (pointer: fine) {
  .celda:hover {
    background: var(--card-alta);
    border-color: var(--linea-fuerte);
  }

  @media (prefers-reduced-motion: no-preference) {
    .celda,
    .senda,
    .plan {
      transition:
        background-color var(--dur-cerca) var(--ease-asentar),
        border-color var(--dur-cerca) var(--ease-asentar),
        transform var(--dur-cerca) var(--ease-asentar),
        box-shadow var(--dur-cerca) var(--ease-asentar);
    }

    .celda:hover,
    .senda:hover,
    .plan:hover {
      transform: translateY(-2px);
    }
  }
}

/* La pulsación baja más rápido de lo que subió. */
@media (prefers-reduced-motion: no-preference) {
  .boton {
    transition:
      background-color var(--dur-cerca) var(--ease-suave),
      border-color var(--dur-cerca) var(--ease-suave),
      color var(--dur-cerca) var(--ease-suave),
      transform var(--dur-toque) var(--ease-suave);
  }

  .boton:active {
    transform: scale(0.97);
  }
}

/* ── 5 · Las preguntas se despliegan como agua (mejora progresiva) ──── */

@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    .preguntas details::details-content {
      block-size: 0;
      overflow-y: clip;
      opacity: 0;
      transition:
        block-size var(--dur-panel) var(--ease-asentar),
        opacity var(--dur-panel) var(--ease-suave),
        content-visibility var(--dur-panel) allow-discrete;
    }

    .preguntas details[open]::details-content {
      block-size: auto;
      opacity: 1;
      interpolate-size: allow-keywords;
    }
  }
}

/* ── Movimiento reducido: menos y más suave, no cero ─────────────────
   Mueren los desplazamientos, el trazado y las transiciones de página;
   sobreviven el color y la opacidad de hovers y foco. Todas las
   animaciones espaciales de esta hoja ya viven detrás de la guarda
   no-preference; aquí se apaga lo que quedaba. */

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }

  html {
    scroll-behavior: auto;
  }
}

/* ── Impresión ──────────────────────────────────────────────────────── */

@media print {
  .barra,
  .curva-caja,
  .curva-calma,
  .vista,
  body::after {
    display: none;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  body,
  .prosa p,
  .prosa li,
  p {
    --texto: #000;
    --texto-suave: #333;
    color: #000;
  }

  .pagina-interior main {
    padding-top: 2rem;
  }
}
