/* ══════════════════════════════════════════════════════════════════════
   Lyquia · la portada

   Corta y a lo grande, a la manera de las páginas de producto de Apple:
   un vídeo que arranca solo, la pregunta de siempre, cuatro vídeos del
   producto de verdad, un escenario con pestañas, la escena del ERP y los
   planes. Lo común (tokens, tipos, barra, pie) vive en base.css.

   El movimiento de la casa sigue siendo el fluir: fundidos, subidas
   cortas, nada que rebote. Lo nuevo es que ahora lo llevan los medios (el
   vídeo, la galería, el mar de puntos) y no el texto.

   Todo lo que se mueve cuelga de html.con-movimiento, que pone la
   cabecera solo si no se pide menos movimiento, no hay ahorro de datos y
   la página está servida (y que se retira sola si portada.js no llega a
   confirmar). Sin ella la portada es la misma, quieta y entera: el héroe
   se queda en su imagen, la galería en sus carteles, las pestañas se
   leen una debajo de otra y las sendas y los planes, como siempre.

   Las medidas de altura de las escenas van en lvh (la ventana con la
   barra de Safari escondida) y lo que se lee, dentro de una caja de svh
   (con la barra a la vista): así nada queda debajo de la barra de iOS.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Lo de toda la portada ─────────────────────────────────────────── */

/* Las anclas de antes (#accion, #como, #guias) siguen llevando a algún
   sitio: hay enlaces de fuera que las usan. */
.ancla-vieja {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Las cabeceras de sección, a lo Apple: grandes, centradas y solas. */
.cabecera-grande {
  font-size: clamp(2rem, 1.35rem + 2.4vw, 3rem);
  line-height: 1.08;
  text-align: center;
  text-wrap: balance;
}

/* Las cabeceras de las secciones que vienen de antes, centradas como
   las nuevas. */
#datos .cabecera-seccion,
#planes .cabecera-seccion {
  margin-inline: auto;
  text-align: center;
}

#datos .cabecera-seccion .entradilla,
#planes .cabecera-seccion .entradilla {
  margin-inline: auto;
}

.boton-grande {
  font-size: 1.0625rem;
  padding: 1rem 2.1rem;
}

/* Para los lectores de pantalla y nadie más (la cifra de verdad de un
   KPI mientras la copia cuenta). */
.solo-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── 1 · El héroe: el portátil se enciende ─────────────────────────────
   En horizontal, el vídeo es ancho (2,4:1) y llena el escenario (cover):
   en una pantalla de 16:10 se recortan los lados, que son mesa, y en una
   ultrapanorámica se ve entero, sin bandas. El portátil queda siempre en
   el centro, y al final se ve con la pantalla entera y margen. En
   vertical, su propio render (9:16), que cabe entero (contain). El fondo
   del render es el de la página y los cantos se funden, así que donde
   sobra ventana no se ve el borde.

   El vídeo va debajo de la barra (62 px con su margen, base.css, y algo
   de aire), no detrás. --caja es el ancho del vídeo; el banner va en su
   centro, que es el centro de la pantalla del portátil (la cámara acaba
   apuntando ahí), y «Volver a ver» en la esquina de lo que se ve. */
.heroe {
  --barra: 68px;
  --alto: calc(100svh - var(--barra));
  --caja: max(100%, calc(var(--alto) * 2.4));
  position: relative;
}

.heroe-escenario {
  position: relative;
  height: 100svh;
  min-height: 30rem;
  overflow: clip;
}

.heroe-caja {
  position: absolute;
  left: 50%;
  top: calc(50% + var(--barra) / 2);
  width: var(--caja);
  aspect-ratio: 12 / 5;
  translate: -50% -50%;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 1.5%, #000 98.5%, transparent),
    linear-gradient(to bottom, transparent, #000 2%, #000 98%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 1.5%, #000 98.5%, transparent),
    linear-gradient(to bottom, transparent, #000 2%, #000 98%, transparent);
  mask-composite: intersect;
}

@media (orientation: portrait) {
  .heroe {
    --caja: min(100%, calc(var(--alto) * 0.5625));
  }

  .heroe-caja {
    aspect-ratio: 9 / 16;
  }
}

.heroe-imagen,
.heroe-imagen img,
.heroe-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.heroe-imagen img,
.heroe-video {
  object-fit: cover;
}

/* El vídeo no se ve hasta que suena: hasta entonces manda la imagen del
   primer fotograma, que es el LCP. */
.heroe-video {
  opacity: 0;
  transition: opacity 240ms var(--ease-suave);
}

.heroe.en-marcha .heroe-video {
  opacity: 1;
}

.heroe.al-final .heroe-video {
  opacity: 0;
  transition: none;
}

/* Los fundidos de la imagen: al final sin vídeo, y antes de «Volver a
   ver». Quien vuelve desde otra página de la casa no ve el primer
   fotograma: la imagen espera oculta a tener el último (heroe.js). Sin
   portada.js, el vigilante de la cabecera quita .con-movimiento y se ve. */
.heroe-imagen {
  transition: opacity 450ms var(--ease-suave);
}

.heroe.relevo .heroe-imagen,
html.con-movimiento.heroe-visto .heroe:not(.al-final) .heroe-imagen {
  opacity: 0;
  transition-duration: 200ms;
}

/* El banner: blanco, como el aviso «Conectando con Lyquia» de la escena
   del ERP. Sin movimiento está desde el principio; con él, se despliega
   al acabar el vídeo. */
.heroe-banner {
  position: absolute;
  left: 50%;
  top: calc(50% + var(--barra) / 2);
  z-index: 2;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.35rem 1rem;
  width: max-content;
  max-width: calc(100vw - 2.5rem);
  margin: 0;
  padding: 1rem 1.5rem 1.1rem 1.1rem;
  translate: -50% -50%;
  border-radius: 1.1rem;
  background: #fff;
  color: #0b1426;
  box-shadow: 0 30px 60px -24px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.4);
  font-size: clamp(0.95rem, 0.85rem + 0.5vw, 1.2rem);
  line-height: 1.3;
}

.heroe-banner img {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.7rem;
}

.heroe-banner-texto > span {
  display: block;
}

.heroe-banner strong {
  font-weight: 600;
  color: inherit;
}

.heroe-progreso {
  grid-column: 1 / -1;
  position: relative;
  height: 3px;
  margin-top: 0.45rem;
  border-radius: 3px;
  background: rgba(11, 20, 38, 0.1);
  overflow: hidden;
}

.heroe-progreso > i {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #1fb5a9, #28cabe);
  transform-origin: left;
}

.heroe-otra-vez {
  position: absolute;
  right: max(clamp(1rem, 3vw, 2rem), calc((100% - var(--caja)) / 2 + clamp(1rem, 3vw, 2rem)));
  bottom: clamp(1rem, 3svh, 2rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 0.95rem;
  border: 0;
  border-radius: 999px;
  background: rgba(20, 31, 54, 0.72);
  color: var(--txt);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}

.heroe-otra-vez svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.heroe-otra-vez[hidden] {
  display: none;
}

/* En el móvil la pantalla del portátil mide lo que el teléfono de ancho:
   el banner, más recogido, para que detrás se vea el plan aplicándose. */
@media (max-width: 734px) {
  .heroe-banner {
    gap: 0.2rem 0.7rem;
    max-width: min(20rem, calc(100vw - 4rem));
    padding: 0.7rem 1rem 0.8rem 0.75rem;
    font-size: 0.875rem;
  }

  .heroe-banner img {
    width: 2rem;
    height: 2rem;
  }

  .heroe-otra-vez {
    right: auto;
    left: 50%;
    translate: -50% 0;
  }
}

/* El banner sale cuando la cámara se para (.con-banner, heroe.js), con
   el plan aplicándose detrás; su barra se llena lo que tardan las cifras
   en cambiar. Sin vídeo, con el final (.al-final). */
html.con-movimiento .heroe:not(.al-final):not(.con-banner) .heroe-banner {
  opacity: 0;
  visibility: hidden;
}

html.con-movimiento .heroe.con-banner .heroe-banner,
html.con-movimiento .heroe.al-final .heroe-banner {
  animation: banner-desplegar 700ms var(--ease-asentar) both;
}

html.con-movimiento .heroe.con-banner .heroe-progreso > i,
html.con-movimiento .heroe.al-final .heroe-progreso > i {
  animation: banner-progreso 2600ms var(--ease-suave) 200ms both;
}

@keyframes banner-desplegar {
  from {
    opacity: 0;
    transform: translateY(1.2rem) scale(0.96);
    clip-path: inset(0 0 100% 0 round 1.1rem);
  }

  to {
    clip-path: inset(0 0 0 0 round 1.1rem);
  }
}

@keyframes banner-progreso {
  from {
    transform: scaleX(0);
  }
}

/* ── 2 · El titular: la pregunta ───────────────────────────────────────
   Solo el H1 de siempre y un botón. Entra con escala y fundido desde un
   estado que arma el JS (como todo .revela), así que sin JS se ve. Detrás,
   la curva de caja, que se traza y se rompe cuando el titular llega. */

.titular {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-height: 90svh;
  padding-block: clamp(6rem, 4rem + 6vw, 10rem);
  overflow: clip;
  text-align: center;
}

.titular-in {
  display: grid;
  justify-items: center;
  gap: clamp(2rem, 1.5rem + 1.5vw, 3rem);
}

.titular h1 {
  max-width: 13ch;
  margin: 0;
  font-size: clamp(2.7rem, 1.2rem + 6vw, 6rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
}

/* La curva va detrás, a lo ancho y algo por debajo del centro. */
.titular .curva-caja {
  position: absolute;
  inset: auto 0 14% 0;
  z-index: -1;
  margin: 0;
  opacity: 0.85;
}

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

.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 punto de la rotura es HTML sobre el SVG: el dibujo se estira con la
   ventana (preserveAspectRatio none) y un círculo dentro se deformaría.
   Cae donde la curva cruza el cero (838/1200 · 100/160). */
.curva-caja .marcador {
  position: absolute;
  left: 69.8%;
  top: 62.5%;
  transform: translateY(-50%);
}

.curva-caja .punto {
  display: block;
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: var(--acento-vivo);
  box-shadow: 0 0 16px rgba(40, 202, 190, 0.75);
}

@media (prefers-reduced-motion: no-preference) {
  html.con-js .titular-in.revela {
    transform: translateY(30px) scale(0.96);
    transition:
      opacity 900ms var(--ease-revelar),
      transform 900ms var(--ease-revelar);
  }

  html.con-js .titular-in.revela.es-visible {
    transform: none;
  }

  /* La curva, con el dasharray solo aquí dentro: sin la guarda está
     completa desde el primer pintado. */
  html.con-js .titular .curva-caja .linea {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }

  html.con-js .titular-in.es-visible + .curva-caja .linea {
    animation: trazar-caja var(--dur-trazo) ease-in-out 350ms both;
  }

  html.con-js .titular .curva-caja .marcador {
    opacity: 0;
  }

  html.con-js .titular-in.es-visible + .curva-caja .marcador {
    animation: fundir 300ms var(--ease-suave) 1650ms both;
  }
}

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

  to {
    stroke-dashoffset: 0;
  }
}

@keyframes fundir {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

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

/* ── 3 · Lo principal: cuatro vídeos ───────────────────────────────────
   En escritorio, cada vídeo va en la pantalla de un iPad renderizado de
   frente, y los cuatro iPads van en fila: el activo en el centro, y el
   siguiente (y el anterior) asoman por los lados. Pasar de vídeo es
   desplazarse de un iPad a otro. La pantalla es un rectángulo en
   porcentajes de la imagen (dispositivos.py --ipad y frente.mjs), así que
   el vídeo se coloca con CSS a cualquier ancho. En móvil, donde el Lab no
   tiene versión de teléfono, van en tarjetas verticales sin marco y en un
   carrusel nativo con imán: el dedo desliza como en cualquier lista. */

.principal {
  overflow-x: clip;
}

.galeria {
  /* la pantalla del iPad, en porcentajes de su imagen
     (node _fuente/estudio/frente.mjs ipad los escribe) */
  --rectx: 4.42%;
  --recty: 5.74%;
  --rectw: 91.19%;
  --recth: 88.57%;
  --radio: 4.24% / 5.66%;
  --proporcion-ipad: 1.2959; /* 2400 / 1852 */
  /* el ancho de cada iPad: que quepa con el rótulo y los mandos en la
     ventana, y que a los lados asome el vecino */
  --w: min(1180px, 68vw, calc((100svh - 19rem) * var(--proporcion-ipad)));
  --hueco: min(6vw, 96px);
  display: flex;
  flex-direction: column;
  margin-top: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}

/* Los mandos van antes que el escenario en el HTML y debajo en pantalla:
   la pausa es lo primero que alcanza el teclado (patrón de carrusel de la
   WAI), para poder parar el movimiento antes de nada. */
.galeria-escenario {
  order: 1;
}

.galeria-mandos {
  order: 2;
}

.galeria-rotulos {
  display: grid;
  width: min(40rem, calc(100% - 2.5rem));
  margin: 0 auto clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
  text-align: center;
}

.galeria-rotulo {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 450ms var(--ease-suave),
    visibility 450ms;
}

.galeria-rotulo:first-child,
.galeria[data-activa] .galeria-rotulo.activo {
  visibility: visible;
  opacity: 1;
}

.galeria[data-activa] .galeria-rotulo:not(.activo) {
  visibility: hidden;
  opacity: 0;
}

.galeria-rotulo h3 {
  display: inline;
  font-family: var(--letra-titular);
  font-weight: 400;
  font-size: clamp(1.3rem, 1.05rem + 1vw, 1.75rem);
  line-height: 1.3;
  color: var(--txt);
}

.galeria-rotulo p {
  display: inline;
  margin: 0;
  font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.4rem);
  line-height: 1.4;
  color: var(--mut);
}

.galeria-escenario {
  position: relative;
  width: 100%;
}

/* La fila de iPads: empieza en el centro del escenario y se corre un
   iPad (más su hueco) por vídeo. */
.galeria-pista {
  display: flex;
  gap: var(--hueco);
  width: max-content;
  margin: 0 0 0 50%;
  padding: 0;
  list-style: none;
  transform: translateX(calc(var(--w) / -2 - var(--actual, 0) * (var(--w) + var(--hueco))));
  transition: transform 1s cubic-bezier(0.65, 0, 0.35, 1);
  touch-action: pan-y;
}

.galeria-diapo {
  position: relative;
  flex: 0 0 var(--w);
  aspect-ratio: 2400 / 1852;
  opacity: 0.55;
  transition: opacity 700ms var(--ease-suave);
}

.galeria-diapo.activa,
.galeria:not([data-activa]) .galeria-diapo:first-child {
  opacity: 1;
}

.galeria-diapo:not(.activa) {
  cursor: pointer;
}

.galeria-ipad {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  user-select: none;
}

.galeria-pantalla {
  position: absolute;
  left: var(--rectx);
  top: var(--recty);
  width: var(--rectw);
  height: var(--recth);
  overflow: clip;
  border-radius: var(--radio);
  background: #05080f;
}

.galeria-cartel,
.galeria-cartel img,
.galeria-diapo video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.galeria-cartel img,
.galeria-diapo video {
  object-fit: cover;
  object-position: top center;
}

/* El vídeo tapa el cartel desde que suena, y SIGUE tapándolo cuando el
   iPad deja de ser el activo: se queda en el fotograma en el que se
   cambió, no vuelve al primero. */
.galeria-diapo video {
  opacity: 0;
  transition: opacity 300ms var(--ease-suave);
}

.galeria-diapo.sonando video {
  opacity: 1;
}

/* Las flechas, en el hueco entre iPads: a los lados del activo y sin
   tocarlo. */
.galeria-flecha {
  position: absolute;
  top: calc(var(--w) / var(--proporcion-ipad) / 2);
  z-index: 2;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-top: -1.5rem;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 50%;
  background: rgba(20, 31, 54, 0.8);
  color: var(--txt);
  cursor: pointer;
  transition:
    background-color var(--dur-cerca) var(--ease-suave),
    opacity var(--dur-cerca) var(--ease-suave);
}

.galeria-flecha svg {
  width: 1.2rem;
  height: 1.2rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.galeria-anterior {
  left: calc(50% - var(--w) / 2 - var(--hueco) / 2 - 1.5rem);
}

.galeria-siguiente {
  left: calc(50% + var(--w) / 2 + var(--hueco) / 2 - 1.5rem);
}

.galeria-flecha:disabled {
  opacity: 0.3;
  cursor: default;
}

@media (hover: hover) and (pointer: fine) {
  .galeria-flecha:not(:disabled):hover {
    background: var(--card-alta);
  }
}

/* Los mandos: la pausa y los puntos, en una píldora bajo el portátil. El
   punto activo se estira y se llena con el vídeo. */
.galeria-mandos {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: clamp(1.25rem, 1rem + 1vw, 2rem);
}

.galeria-pausa {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--txt);
  cursor: pointer;
}

.galeria-pausa svg {
  grid-area: 1 / 1;
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  visibility: hidden;
}

.galeria-pausa .seguir {
  fill: currentColor;
  stroke: none;
}

.galeria[data-estado='sonando'] .galeria-pausa .pausar,
.galeria[data-estado='quieta'] .galeria-pausa .seguir,
.galeria:not([data-estado]) .galeria-pausa .seguir,
.galeria[data-estado='fin'] .galeria-pausa .repetir {
  visibility: visible;
}

.galeria-puntos {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0 0.6rem;
  height: 2.75rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
}

.galeria-punto {
  display: grid;
  place-items: center;
  width: auto;
  min-width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.galeria-punto i {
  position: relative;
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.35);
  overflow: hidden;
  transition: width 400ms var(--ease-asentar), background-color 400ms var(--ease-suave);
}

.galeria-punto[aria-current='true'] i {
  width: 44px;
  background: rgba(255, 255, 255, 0.22);
}

.galeria-punto[aria-current='true'] i::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--txt);
  transform-origin: left;
  transform: scaleX(var(--p, 0));
}

.galeria-pausa:focus-visible,
.galeria-punto:focus-visible,
.galeria-flecha:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 3px;
}

/* Móvil: tarjetas verticales, sin iPad. */
@media (max-width: 734px) {
  .galeria-escenario {
    width: 100%;
  }

  .galeria-ipad {
    display: none;
  }

  .galeria-pantalla {
    inset: 0;
    width: auto;
    height: auto;
    border-radius: 0;
  }

  .galeria-pista {
    position: static;
    display: flex;
    gap: 0.75rem;
    width: auto;
    height: auto;
    margin: 0;
    padding-inline: 7.5vw;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 7.5vw;
    scrollbar-width: none;
    background: none;
    transform: none;
    transition: none;
    touch-action: auto;
  }

  .galeria-pista::-webkit-scrollbar {
    display: none;
  }

  .galeria-diapo {
    position: relative;
    inset: auto;
    flex: 0 0 85vw;
    aspect-ratio: 2 / 3;
    overflow: clip;
    border-radius: var(--radio-l);
    background: var(--card);
    opacity: 1;
    scroll-snap-align: center;
    scroll-snap-stop: always;
  }

  /* Las flechas bajan a la fila de los mandos, una a cada lado: sobre
     la tarjeta tapaban justo las cifras que el vídeo quiere enseñar. */
  .galeria {
    position: relative;
  }

  .galeria-escenario {
    position: static;
  }

  .galeria-flecha {
    top: auto;
    bottom: 0;
    width: 2.75rem;
    height: 2.75rem;
    margin-top: 0;
  }

  .galeria-anterior {
    left: 1rem;
  }

  .galeria-siguiente {
    right: 1rem;
  }
}

@media (max-width: 359px) {
  .galeria-punto[aria-current='true'] i {
    width: 30px;
  }
}

/* ── La cinta, entre «Lo principal» y «Todo a la vista» ─────────────────
   Dos filas de chips del Lab que pasan solas y sin fin: los
   indicadores hacia la derecha y los productos financieros hacia la
   izquierda, a velocidades algo distintas. No dependen del scroll: es el
   pulso de fondo entre dos secciones quietas. Fina a propósito: los chips
   horizontales de la app (no tarjetas), lentos (unos 20 px por segundo) y
   fundidos en los bordes.
   La mueve cinta.js (copia cada fila hasta cubrir el ancho y le da --paso
   y --cinta-dur); sin él, o sin movimiento, se queda quieta. Fuera de la
   vista se para. Sin botón de parar, a propósito: es decoración fina y el
   botón pesaba más que ella (con movimiento reducido no se mueve). */

.seccion:has(+ .cinta) {
  padding-bottom: clamp(1.75rem, 1.25rem + 1.5vw, 2.75rem);
}

.cinta + .seccion {
  padding-top: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
}

.cinta {
  --cinta-hueco: 0.5rem;
  --cinta-rojo: #fb7185;
  --cinta-verde: #34d399;
  display: grid;
  gap: var(--cinta-hueco);
  overflow: clip;
}

.cinta-fila {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

.cinta-tira {
  display: flex;
  width: max-content;
}

.cinta-juego {
  display: flex;
  gap: var(--cinta-hueco);
  margin: 0;
  padding: 0 var(--cinta-hueco) 0 0;
  list-style: none;
}

/* Los chips del Lab, tal cual (chip-kpi.tsx, euribor-chip.tsx y los cubos
   de «Productos financieros» de lab-header.tsx), algo más grandes. */
.cinta-kpi,
.cinta-euribor,
.cinta-producto {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.45rem;
  height: 2.15rem;
  padding: 0 0.9rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  white-space: nowrap;
  color: var(--txt);
}

.cinta-kpi span,
.cinta-euribor span {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.cinta-kpi b,
.cinta-euribor b,
.cinta-producto b {
  font-size: 0.9rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cinta-kpi b {
  margin-left: 0.35rem;
}

/* los tonos de tono-chip.ts: relleno, anillo y tinta */
.cinta-bien {
  border-color: rgba(52, 211, 153, 0.4);
  background: rgba(16, 185, 129, 0.15);
  color: var(--cinta-verde);
}

.cinta-aviso {
  border-color: rgba(251, 191, 36, 0.4);
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
}

.cinta-mal {
  border-color: rgba(251, 113, 133, 0.4);
  background: rgba(244, 63, 94, 0.15);
  color: var(--cinta-rojo);
}

.cinta-euribor {
  border-radius: 8px;
  color: var(--mut);
}

.cinta-euribor b {
  color: var(--txt);
}

.cinta-producto {
  height: 2rem;
  padding: 0 0.8rem;
  font-size: 0.82rem;
}

.cinta-producto span {
  color: var(--txt);
}

.cinta-punto {
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.cinta-esmeralda {
  background: #34d399;
}

.cinta-cielo {
  background: #38bdf8;
}

.cinta-violeta {
  background: #a78bfa;
}

.cinta-flecha,
.cinta-icono {
  width: 0.8rem;
  height: 0.8rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cinta-producto .cinta-flecha {
  color: var(--mut);
}

@media (max-width: 734px) {
  .cinta {
    --cinta-hueco: 0.4rem;
  }

  .cinta-kpi,
  .cinta-euribor {
    height: 1.95rem;
    padding: 0 0.75rem;
  }

  .cinta-producto {
    height: 1.8rem;
    padding: 0 0.7rem;
    font-size: 0.78rem;
  }
}

@media (prefers-reduced-motion: no-preference) {
  html.con-movimiento .cinta.lista .cinta-tira {
    animation: cinta-a-izquierda var(--cinta-dur, 40s) linear infinite;
    will-change: transform;
  }

  html.con-movimiento .cinta.lista .cinta-a-derecha .cinta-tira {
    animation-name: cinta-a-derecha;
  }

  html.con-movimiento .cinta.lista.fuera .cinta-tira {
    animation-play-state: paused;
  }

  /* aparece una vez, al verse; luego solo pasa */
  html.con-movimiento .cinta.lista .cinta-fila {
    transition:
      opacity 900ms var(--ease-suave),
      transform 900ms var(--ease-asentar);
  }

  html.con-movimiento .cinta.lista .cinta-a-izquierda {
    transition-delay: 160ms;
  }

  html.con-movimiento .cinta.lista:not(.vista) .cinta-fila {
    opacity: 0;
    transform: translateY(14px);
  }
}

@keyframes cinta-a-izquierda {
  to {
    transform: translate3d(calc(-1 * var(--paso, 0px)), 0, 0);
  }
}

@keyframes cinta-a-derecha {
  from {
    transform: translate3d(calc(-1 * var(--paso, 0px)), 0, 0);
  }

  to {
    transform: none;
  }
}

/* ── 4 · Todo a la vista: el escenario con pestañas ────────────────────
   Como «Las posibilidades crecen» de Apple: un escenario grande, las
   pestañas en una píldora debajo y el pie bajo ellas. Los paneles y los
   pies se apilan en una misma celda y se cambian con visibilidad: la
   altura no se mueve al cambiar (sin CLS). Sin JS (sin [data-activa]) se
   leen los tres, uno debajo de otro, y la barra de pestañas no aparece. */

.todo {
  display: flex;
  flex-direction: column;
  width: min(1120px, 90vw);
  margin: clamp(2rem, 1.5rem + 2vw, 3.5rem) auto 0;
}

/* Las pestañas van antes que los paneles en el HTML, como pide el patrón
   (el foco pasa de la pestaña activa a su panel), y debajo en pantalla. */
.todo-escenario {
  order: 1;
}

.todo-pestanas {
  order: 2;
}

.todo-pies {
  order: 3;
}

.todo-escenario {
  position: relative;
  display: grid;
  border-radius: var(--radio-l);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(40, 202, 190, 0.1), transparent 60%),
    var(--card);
  border: 1px solid var(--linea);
  overflow: clip;
  touch-action: pan-y;
}

.todo-pestanas,
.todo-otra-vez {
  display: none;
}

.todo-pie {
  margin: 0;
  padding: 1rem 0 2rem;
  text-align: center;
  color: var(--mut);
  font-size: clamp(1rem, 0.92rem + 0.35vw, 1.15rem);
}

.todo-pie strong {
  color: var(--txt);
  font-weight: 400;
}

.todo[data-activa] .todo-escenario {
  aspect-ratio: 2 / 1;
}

.todo[data-activa] .todo-panel {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 500ms var(--ease-suave),
    visibility 500ms;
}

.todo[data-activa] .todo-panel.activo {
  visibility: visible;
  opacity: 1;
}

.todo[data-activa] .todo-pestanas {
  position: relative;
  display: flex;
  width: max-content;
  max-width: 100%;
  margin: 1.4rem auto 0;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  overflow-x: auto;
  scrollbar-width: none;
}

.todo-pestana {
  position: relative;
  z-index: 1;
  flex: none;
  min-height: 2.5rem;
  padding: 0 1.2rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--mut);
  font: inherit;
  font-size: 0.9375rem;
  white-space: nowrap;
  cursor: pointer;
  transition: color 320ms var(--ease-suave);
}

.todo-pestana[aria-selected='true'] {
  color: var(--bg);
}

.todo-pestana:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}

.todo-pildora {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 0;
  border-radius: 999px;
  background: var(--txt);
  transition:
    transform 320ms var(--ease-asentar),
    width 320ms var(--ease-asentar);
}

.todo[data-activa] .todo-pies {
  display: grid;
  width: min(38rem, 100%);
  margin: 0 auto;
}

.todo[data-activa] .todo-pie {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  padding: 1.1rem 0 0;
  transition:
    opacity 400ms var(--ease-suave),
    visibility 400ms;
}

.todo[data-activa] .todo-pie.activo {
  visibility: visible;
  opacity: 1;
}

.todo[data-activa] .todo-otra-vez:not([hidden]) {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--txt);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}

.todo-otra-vez svg {
  width: 0.95rem;
  height: 0.95rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* En el móvil, el escenario es exactamente una tarjeta de la galería:
   el 85 % del ancho, 2:3, redondeada y con el vídeo a sangre, grabado
   como los de la galería (360 px de ancho). A sangre de la pantalla
   parecía la app a pantalla completa («gigante»), y con una pantalla
   enmarcada dentro de la tarjeta, una tarjeta dentro de otra. */
@media (max-width: 734px) {
  .todo {
    width: 85vw;
  }

  .todo-pestana {
    padding: 0 0.8rem;
    font-size: 0.8125rem;
  }

  /* En el móvil, los nombres cortos: con los largos, «Alarmas» quedaba
     fuera de la barra y no se veía que existía. */
  .todo-pestana .en-ancho {
    display: none;
  }

  .todo[data-activa] .todo-escenario {
    aspect-ratio: 2 / 3;
  }
}

@media (max-width: 359px) {
  .todo-pestana {
    padding: 0 0.6rem;
  }
}

/* «Todo a la vista» en el móvil: en vez de las pestañas con vídeo, una
   composición pequeña en HTML, nítida y sin vídeo que bajar. Los vídeos
   del escritorio, recortados o regrabados para el teléfono, se veían
   gigantes o diminutos en todas las pruebas. Arriba los KPIs, que cuentan
   hasta su cifra; en medio, un cobro y un pago que vuelan a su día; abajo,
   las alarmas, con el resplandor de su color. Sin movimiento (o sin JS),
   se ve el estado final. Los tonos son los del Lab (rosa, ámbar, esmeralda). */
.todo-movil {
  display: none;
}

@media (max-width: 734px) {
  .todo .todo-pestanas,
  .todo .todo-escenario,
  .todo .todo-pies,
  .todo[data-activa] .todo-pestanas,
  .todo[data-activa] .todo-pies {
    display: none;
  }

  .todo {
    width: min(100% - 2.5rem, 26rem);
  }

  .todo-movil {
    --tm-rojo: #fb7185;
    --tm-ambar: #fbbf24;
    --tm-verde: #34d399;
    --tm-fila: 2.75rem;
    --tm-hueco: 0.5rem;
    --tm-dia: calc((100% - 30px) / 11);
    display: grid;
    gap: 1.75rem;
  }

  .tm-bloque {
    margin: 0;
  }

  .tm-titulo {
    margin: 0 0 0.75rem;
    font-family: var(--letra-cuerpo);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .tm-rojo { --tono: var(--tm-rojo); }
  .tm-ambar { --tono: var(--tm-ambar); }
  .tm-verde { --tono: var(--tm-verde); }

  /* Los KPIs: cuatro fichas con el filo de su semáforo */
  .tm-kpis {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
  }

  .tm-kpi {
    position: relative;
    display: grid;
    gap: 0.3rem;
    margin: 0;
    padding: 0.85rem 0.9rem 0.8rem;
    overflow: hidden;
    border: 1px solid var(--linea);
    border-radius: var(--radio);
    background: var(--card);
  }

  .tm-kpi::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: var(--tono);
  }

  .tm-kpi span {
    font-size: 0.72rem;
    color: var(--mut);
  }

  .tm-kpi b {
    font-family: var(--letra-cifra);
    font-size: 1.05rem;
    font-weight: 500;
    white-space: nowrap;
    color: var(--tono);
  }

  /* El cobro y el pago, en fila, y la tira de días donde se colocan */
  .tm-mesa {
    position: relative;
  }

  .tm-mov {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: var(--tm-fila);
    margin: 0 0 var(--tm-hueco);
    padding: 0 0.9rem;
    border: 1px solid var(--linea);
    border-radius: var(--radio);
    background: var(--card);
    font-size: 0.8rem;
  }

  .tm-mov span {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--txt);
  }

  .tm-mov b {
    font-family: var(--letra-cifra);
    font-weight: 500;
  }

  .tm-cobro b { color: var(--tm-verde); }
  .tm-pago b { color: var(--tm-rojo); }

  .tm-dias {
    display: grid;
    grid-template-columns: repeat(11, 1fr);
    gap: 3px;
    margin-top: 0.4rem;
  }

  .tm-dias i {
    display: grid;
    place-items: center;
    height: 2.2rem;
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.035);
    font-family: var(--letra-cifra);
    font-size: 0.66rem;
    font-style: normal;
    color: var(--mut);
  }

  /* los dos días, ya ocupados (el estado final) */
  .tm-dias .tm-dia-cobro,
  .tm-dias .tm-dia-pago {
    font-weight: 600;
  }

  .tm-dias .tm-dia-cobro {
    background: color-mix(in srgb, var(--tm-verde) 22%, transparent);
    box-shadow: 0 0 18px -2px color-mix(in srgb, var(--tm-verde) 55%, transparent);
    color: var(--tm-verde);
  }

  .tm-dias .tm-dia-pago {
    background: color-mix(in srgb, var(--tm-rojo) 22%, transparent);
    box-shadow: 0 0 18px -2px color-mix(in srgb, var(--tm-rojo) 55%, transparent);
    color: var(--tm-rojo);
  }

  .tm-etiquetas {
    position: relative;
    height: 1.4rem;
    margin: 0.45rem 0 0;
    font-family: var(--letra-cifra);
    font-size: 0.66rem;
  }

  .tm-etiquetas span {
    position: absolute;
    top: 0;
    white-space: nowrap;
  }

  /* bajo su día: el 20 es la tercera casilla y el 27, la décima */
  .tm-et-cobro {
    left: calc(2 * (var(--tm-dia) + 3px));
    color: var(--tm-verde);
  }

  .tm-et-pago {
    right: calc(var(--tm-dia) + 3px);
    color: var(--tm-rojo);
  }

  /* lo que vuela de la fila a su día; quieto, no se ve */
  .tm-vuela {
    position: absolute;
    opacity: 0;
    border-radius: 7px;
    pointer-events: none;
  }

  .tm-vuela-cobro {
    --t0: calc((var(--tm-fila) - 1.65rem) / 2);
    --c: var(--tm-verde);
    --l1: calc(2 * (var(--tm-dia) + 3px));
  }

  .tm-vuela-pago {
    --t0: calc(var(--tm-fila) + var(--tm-hueco) + (var(--tm-fila) - 1.65rem) / 2);
    --c: var(--tm-rojo);
    --l1: calc(9 * (var(--tm-dia) + 3px));
  }

  .tm-vuela {
    --t1: calc(2 * (var(--tm-fila) + var(--tm-hueco)) + 0.4rem);
    background: color-mix(in srgb, var(--c) 30%, transparent);
    box-shadow: 0 0 0 1px var(--c), 0 0 20px color-mix(in srgb, var(--c) 50%, transparent);
  }

  /* Las alarmas, en fila, con el filo y el resplandor de su color */
  .tm-alarmas {
    display: grid;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .tm-alarmas li {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid color-mix(in srgb, var(--tono) 35%, transparent);
    border-radius: var(--radio);
    background: var(--card);
    font-size: 0.8rem;
  }

  .tm-alarmas b {
    font-weight: 600;
    white-space: nowrap;
    color: var(--tono);
  }

  .tm-alarmas span {
    font-size: 0.72rem;
    color: var(--mut);
  }
}

/* El movimiento: solo si está permitido y cuando todo.js dice que se ve
   (.en-marcha); antes, con .listo, todo espera en su sitio de salida. */
@media (max-width: 734px) and (prefers-reduced-motion: no-preference) {
  html.con-movimiento .todo-movil.listo:not(.en-marcha) :is(.tm-kpi, .tm-mov, .tm-alarmas li, .tm-etiquetas span) {
    opacity: 0;
  }

  html.con-movimiento .todo-movil.listo:not(.en-marcha) :is(.tm-dia-cobro, .tm-dia-pago) {
    background: rgba(255, 255, 255, 0.035);
    box-shadow: none;
    color: var(--mut);
  }

  html.con-movimiento .todo-movil.en-marcha .tm-kpi {
    animation: tm-sube 600ms var(--ease-asentar) both;
    animation-delay: calc(var(--i, 0) * 110ms);
  }

  html.con-movimiento .todo-movil.en-marcha .tm-kpi:nth-child(2) { --i: 1; }
  html.con-movimiento .todo-movil.en-marcha .tm-kpi:nth-child(3) { --i: 2; }
  html.con-movimiento .todo-movil.en-marcha .tm-kpi:nth-child(4) { --i: 3; }

  html.con-movimiento .todo-movil.en-marcha .tm-cobro {
    animation: tm-entra-izq 550ms var(--ease-asentar) 1100ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-pago {
    animation: tm-entra-der 550ms var(--ease-asentar) 1350ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-vuela-cobro {
    animation: tm-vuela 750ms var(--ease-revelar) 1900ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-vuela-pago {
    animation: tm-vuela 750ms var(--ease-revelar) 2250ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-dia-cobro {
    animation: tm-dia 500ms var(--ease-suave) 2600ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-dia-pago {
    animation: tm-dia 500ms var(--ease-suave) 2950ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-et-cobro {
    animation: tm-sube 400ms var(--ease-asentar) 2700ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-et-pago {
    animation: tm-sube 400ms var(--ease-asentar) 3050ms both;
  }

  html.con-movimiento .todo-movil.en-marcha .tm-alarmas li {
    animation:
      tm-entra-der 550ms var(--ease-asentar) both,
      tm-resplandor 1600ms var(--ease-suave) both;
    animation-delay: calc(3300ms + var(--i, 0) * 180ms), calc(3500ms + var(--i, 0) * 180ms);
  }

  html.con-movimiento .todo-movil.en-marcha .tm-alarmas li:nth-child(2) { --i: 1; }
  html.con-movimiento .todo-movil.en-marcha .tm-alarmas li:nth-child(3) { --i: 2; }
}

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

@keyframes tm-entra-izq {
  from {
    opacity: 0;
    transform: translateX(-28px);
  }
}

@keyframes tm-entra-der {
  from {
    opacity: 0;
    transform: translateX(28px);
  }
}

/* de la cifra de la fila a la casilla de su día, encogiéndose */
@keyframes tm-vuela {
  0% {
    top: var(--t0);
    left: calc(100% - 6.6rem);
    width: 5.6rem;
    height: 1.65rem;
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  85% {
    opacity: 1;
  }

  100% {
    top: var(--t1);
    left: var(--l1);
    width: var(--tm-dia);
    height: 2.2rem;
    opacity: 0;
  }
}

@keyframes tm-dia {
  from {
    background: rgba(255, 255, 255, 0.035);
    box-shadow: none;
    color: var(--mut);
  }
}

/* el resplandor de las alarmas: sale de detrás de toda la fila y se queda
   en su filo */
@keyframes tm-resplandor {
  0% {
    box-shadow: 0 0 0 0 transparent;
  }

  35% {
    box-shadow: 0 0 22px 2px color-mix(in srgb, var(--tono) 45%, transparent);
  }

  100% {
    box-shadow: 0 0 10px -2px color-mix(in srgb, var(--tono) 30%, transparent);
  }
}

/* Cada panel es un vídeo del producto de verdad, con su cartel (el primer
   fotograma) debajo: sin movimiento, o si no se deja reproducir, se queda
   el cartel. El vídeo tapa el cartel desde que suena. */
.todo-panel {
  position: relative;
  padding: 0;
}

.todo-cartel,
.todo-cartel img,
.todo-panel video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.todo-cartel img,
.todo-panel video {
  object-fit: cover;
}

.todo-panel video {
  opacity: 0;
  transition: opacity 300ms var(--ease-suave);
}

.todo-panel.sonando video {
  opacity: 1;
}

/* Sin JS, los tres paneles uno debajo de otro, cada uno con su forma. */
.todo:not([data-activa]) .todo-panel {
  aspect-ratio: 2 / 1;
}

@media (max-width: 734px) {
  .todo:not([data-activa]) .todo-panel {
    aspect-ratio: 2 / 3;
  }
}

/* ── 6 · Los planes, en el mar de puntos ───────────────────────────────
   Un canvas detrás de la sección (no se fija: no se secuestra el scroll).
   Los puntos generan las tarjetas cuando la sección llega y ondulan con
   el puntero o el dedo fuera de ellas. En escritorio, la noria de antes;
   en móvil, un carrusel nativo con imán que abre en Pro. */

#planes {
  position: relative;
  isolation: isolate;
}

.planes-puntos {
  display: none;
}

html.con-movimiento .planes-puntos {
  display: block;
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
}

.planes-mandos {
  display: none;
}

html.con-movimiento .planes-mandos {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.6rem;
}

@media (max-width: 939.98px) {
  html.con-movimiento .planes {
    display: flex;
    gap: 0.9rem;
    max-width: none;
    margin-inline: calc(-1 * clamp(1.25rem, 4vw, 2.5rem));
    padding: 1.4rem 7.5vw 0.5rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 7.5vw;
    scrollbar-width: none;
  }

  html.con-movimiento .planes::-webkit-scrollbar {
    display: none;
  }

  html.con-movimiento .planes .plan {
    flex: 0 0 min(85vw, 24rem);
    scroll-snap-align: center;
    scroll-snap-stop: always;
  }
}

/* Las flechas de los planes, las de la noria de siempre. */
.noria-paso {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--filete);
  border-radius: 50%;
  background: var(--card);
  color: var(--texto);
  cursor: pointer;
  transition: background-color var(--dur-cerca) var(--ease-suave);
}

.noria-paso svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

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

@media (hover: hover) and (pointer: fine) {
  .noria-paso:hover {
    background: var(--card-alta);
  }
}

/* ══ Lo que se conserva de la portada anterior ══════════════════════ */

/* ── 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);
}

/* ── 2d · La conexión con el ERP, contada ─────────────────────────────
   La escena de «Importa tus datos en un clic».
   Un iPhone flotando se enciende y se pulsa «Conecta tu ERP»; la señal
   sale en ondas de puntos hacia la derecha mientras el iPhone se va por
   la izquierda; entra un portátil, se enciende con el ERP y aparece el
   aviso «Conectando con Lyquia»; el portátil se recoge hacia el centro y
   Odoo, Holded y Sage quedan orbitando entre los puntos, que vibran y se
   apartan a su paso. Al final emerge la plantilla de Excel.

   El recorrido lo cuenta erp.js en pantallas de 100lvh (y el tiempo,
   que aquí también cuenta: los puntos vibran y las marcas giran aunque no
   se haga scroll, hasta que la escena se aquieta a los cinco segundos sin
   gesto). El CSS coloca las piezas y las viste. Funciona igual en móvil:
   ya no depende de animation-timeline ni de un ancho mínimo; solo de que
   la ventana tenga algo de alto (con un teléfono en horizontal, las
   sendas se leen quietas).

   Los dispositivos son renders con fondo transparente
   (_fuente/estudio/dispositivos.py); sus pantallas, HTML, puestas sobre
   el panel con una homografía, como en el héroe. El panel del portátil
   es un ERP genérico con el logotipo de Holded: no copia su interfaz.

   Sin escena, nada de esto se pinta y las dos sendas se leen como
   siempre, con su propia animación (3b). */

.erp-escenario,
.erp-frase {
  display: none;
}

@media (min-height: 500px) {
  html.con-movimiento #datos {
    padding-bottom: 0;
  }

  html.con-movimiento .erp-escena {
    /* La ventana entera (100lvh) más el recorrido: FIN pantallas (erp.js).
       Si se toca FIN, se toca aquí. */
    height: calc(100lvh * 3.9);
    margin-top: clamp(1.5rem, 1rem + 2vw, 3rem);
  }

  html.con-movimiento .erp-lienzo {
    position: sticky;
    top: 0;
    height: 100lvh;
    overflow: clip;
  }

  html.con-movimiento .erp-escenario {
    display: block;
    position: absolute;
    inset: 0;
  }

  html.con-movimiento .erp-puntos {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  /* Los dos dispositivos: centrados, y desde ahí los mueve erp.js. */
  html.con-movimiento .erp-movil,
  html.con-movimiento .erp-mac {
    position: absolute;
    left: 50%;
    top: 50%;
    visibility: hidden;
  }

  html.con-movimiento .erp-movil {
    height: min(80svh, 56vw);
    aspect-ratio: 1200 / 1700;
  }

  html.con-movimiento .erp-mac {
    width: min(80vw, 108svh);
    aspect-ratio: 4 / 3;
  }

  html.con-movimiento .erp-foto {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  html.con-movimiento .erp-pantalla {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
    overflow: clip;
  }

  /* Las marcas que orbitan, y la hoja de cálculo. */
  html.con-movimiento .erp-logos {
    position: absolute;
    inset: 0;
  }

  html.con-movimiento .erp-logo {
    position: absolute;
    left: 0;
    top: 0;
    display: grid;
    place-items: center;
    width: 11.5rem;
    height: 4.6rem;
    margin: -2.3rem 0 0 -5.75rem;
    border-radius: 1.2rem;
    /* Sin backdrop-filter: sobre un canvas que se repinta en cada
       fotograma costaba más que todo lo demás junto. */
    background: rgba(20, 31, 54, 0.9);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.8), 0 0 36px -10px rgba(40, 202, 190, 0.35);
    opacity: 0;
  }

  html.con-movimiento .erp-logo img {
    height: 1.9rem;
    width: auto;
  }

  /* A la misma altura óptica: Odoo es un logotipo corto y alto, Holded
     uno largo y bajo. */
  html.con-movimiento .erp-logo:nth-child(1) img {
    height: 2.7rem;
  }

  html.con-movimiento .erp-logo:nth-child(2) img {
    height: 1.35rem;
  }

  html.con-movimiento .erp-excel {
    position: absolute;
    left: 50%;
    top: 44%;
    width: min(19svh, 10rem);
    aspect-ratio: 1;
    margin: calc(min(19svh, 10rem) / -2) 0 0 calc(min(19svh, 10rem) / -2);
    filter: drop-shadow(0 22px 40px rgba(29, 138, 82, 0.35));
    opacity: 0;
  }

  html.con-movimiento .erp-excel svg {
    display: block;
    width: 100%;
    height: 100%;
  }

  html.con-movimiento .erp-frase {
    display: block;
    position: absolute;
    left: 50%;
    top: calc(44% + min(19svh, 10rem) / 2 + 2.2rem);
    width: min(44rem, 88vw);
    translate: -50% 0;
    margin: 0;
    text-align: center;
    font-family: var(--letra-titular);
    font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.35rem);
    line-height: 1.22;
    color: var(--txt);
    opacity: 0;
  }

  /* Lo que se lee, fuera de la animación: las dos sendas, sin cajas.
     La del ERP, como pie abajo a la izquierda mientras orbitan las
     marcas; la de Excel se queda solo con su descarga, bajo la frase. */
  html.con-movimiento .erp-lienzo .sendas {
    display: contents;
  }

  html.con-movimiento .erp-lienzo .sendas.cadencia > * {
    transform: none;
    transition: none;
  }

  html.con-movimiento .erp-lienzo .senda-excel {
    display: contents;
  }

  html.con-movimiento .erp-lienzo .sendas.cadencia > .senda-erp {
    --borde: calc(max(0px, (100vw - var(--wrap)) / 2) + clamp(1.25rem, 4vw, 2.5rem));
    display: block;
    position: absolute;
    left: var(--borde);
    /* dentro de la caja de svh: que no quede bajo la barra de Safari */
    bottom: calc(100lvh - 100svh + 8svh);
    width: min(27rem, 34vw);
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    opacity: 0;
    visibility: hidden;
  }

  html.con-movimiento .erp-lienzo .senda-erp .conexiones {
    display: none;
  }

  html.con-movimiento .erp-lienzo .senda-excel > :not(.descarga) {
    display: none;
  }

  html.con-movimiento .erp-lienzo .senda-excel .descarga {
    width: max-content;
    white-space: nowrap;
    position: absolute;
    left: 50%;
    top: calc(44% + min(19svh, 10rem) / 2 + 2.2rem + 3.6rem + clamp(1.6rem, 1.2rem + 1.5vw, 2.35rem) * 1.22);
    translate: -50% 0;
    opacity: 0;
    /* sin visibility: el teclado tiene que poder llegar (erp.js) */
    pointer-events: none;
  }

  /* En vertical: el iPhone y el portátil, a lo ancho; la órbita, más
     estrecha (la calcula erp.js); el pie de la senda, a todo lo ancho. */
  @media (max-width: 734px) {
    html.con-movimiento .erp-movil {
      height: min(56svh, 118vw);
    }

    html.con-movimiento .erp-mac {
      width: min(94vw, 108svh);
    }

    html.con-movimiento .erp-logo {
      width: 7.2rem;
      height: 3rem;
      margin: -1.5rem 0 0 -3.6rem;
      border-radius: 0.85rem;
    }

    html.con-movimiento .erp-logo img {
      height: 1.2rem;
    }

    html.con-movimiento .erp-logo:nth-child(1) img {
      height: 2rem;
    }

    html.con-movimiento .erp-logo:nth-child(2) img {
      height: 1rem;
    }

    html.con-movimiento .erp-lienzo .sendas.cadencia > .senda-erp {
      left: 1.25rem;
      right: 1.25rem;
      width: auto;
    }
  }
}

/* ── Las pantallas de los dispositivos ────────────────────────────────
   A su tamaño lógico (el iPhone, 390×844; el portátil, 1440×900), y de
   ahí las lleva erp.js a su sitio. Solo se pintan dentro de la escena. */

.erp-pantalla-movil {
  width: 390px;
  height: 844px;
  border-radius: 55px;
}

.movil-app {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: inherit;
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(40, 202, 190, 0.22), transparent 60%),
    linear-gradient(180deg, #0b1628, #080f1f 70%);
  color: #fff;
  font-family: var(--letra-cuerpo);
}

.movil-estado {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 34px 0 42px;
  font-size: 16px;
  font-weight: 500;
}

.movil-iconos {
  display: flex;
  gap: 6px;
}

.movil-iconos i {
  display: block;
  width: 17px;
  height: 11px;
  border-radius: 3px;
  background: #fff;
  opacity: 0.9;
}

.movil-iconos i:first-child {
  width: 14px;
  opacity: 0.8;
}

.movil-isla {
  position: absolute;
  top: 11px;
  left: 50%;
  width: 124px;
  height: 36px;
  margin-left: -62px;
  border-radius: 20px;
  background: #000;
}

.movil-cuerpo {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 150px 34px 0;
  text-align: center;
}

.movil-icono {
  width: 96px;
  height: 96px;
  border-radius: 22px;
  box-shadow: 0 16px 40px -12px rgba(40, 202, 190, 0.55);
}

.movil-titulo {
  margin-top: 38px;
  font-family: var(--letra-titular);
  font-size: 36px;
  line-height: 1.15;
}

.movil-texto {
  margin-top: 18px;
  font-size: 17px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.7);
}

.movil-boton {
  position: relative;
  overflow: hidden;
  margin-top: 70px;
  width: 300px;
  padding: 20px 0;
  border-radius: 18px;
  background: var(--cyan, #28cabe);
  color: #04121f;
  font-size: 19px;
  font-weight: 600;
  box-shadow: 0 18px 40px -16px rgba(40, 202, 190, 0.8);
}

.movil-toque {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 60px;
  height: 60px;
  margin: -30px 0 0 -30px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  opacity: 0;
  transform: scale(0.2);
}

.movil-casa {
  position: absolute;
  bottom: 9px;
  left: 50%;
  width: 136px;
  height: 5px;
  margin-left: -68px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.75);
}

/* El ERP del portátil: un panel genérico, claro, con la marca de Holded
   en una barra oscura (su logotipo es blanco y rojo). */
.erp-pantalla-mac {
  width: 1440px;
  height: 900px;
  border-radius: 11px 11px 0 0;
}

.erp-app {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background: #f3f5f8;
  color: #1c2433;
  font-family: var(--letra-cuerpo);
  font-size: 15px;
}

.erp-barra {
  display: flex;
  align-items: center;
  gap: 40px;
  height: 66px;
  padding: 0 30px;
  background: #151b27;
  color: rgba(255, 255, 255, 0.7);
}

.erp-marca {
  height: 24px;
  width: auto;
}

.erp-nav {
  display: flex;
  gap: 30px;
  font-size: 15px;
}

.erp-nav b {
  color: #fff;
  font-weight: 600;
}

.erp-empresa {
  margin-left: auto;
  font-size: 14px;
}

.erp-avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #ef4444;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}

.erp-cuerpo {
  display: flex;
  flex: 1;
  min-height: 0;
}

.erp-menu {
  display: flex;
  flex-direction: column;
  gap: 26px;
  width: 72px;
  padding-top: 28px;
  align-items: center;
  background: #fff;
  border-right: 1px solid #e3e7ee;
}

.erp-menu i {
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: #d9dee8;
}

.erp-menu i:first-child {
  background: #ef4444;
}

.erp-panel {
  flex: 1;
  padding: 30px 36px;
}

.erp-titulo {
  font-size: 26px;
  font-weight: 600;
}

.erp-titulo span {
  color: #7a8599;
  font-weight: 400;
}

.erp-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin-top: 24px;
}

.erp-kpis > div,
.erp-grafica,
.erp-facturas {
  padding: 20px 22px;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(20, 27, 40, 0.06), 0 8px 24px -16px rgba(20, 27, 40, 0.25);
}

.erp-kpis span,
.erp-rotulo {
  display: block;
  color: #7a8599;
  font-size: 14px;
}

.erp-kpis b {
  display: block;
  margin-top: 8px;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.erp-kpis em {
  display: inline-block;
  margin-top: 8px;
  font-style: normal;
  font-size: 13px;
  color: #7a8599;
}

.erp-kpis em.sube {
  color: #16a34a;
}

.erp-kpis em.baja {
  color: #dc2626;
}

.erp-fila {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 18px;
  margin-top: 18px;
}

.erp-barras {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  height: 330px;
  margin-top: 22px;
  padding-bottom: 6px;
  border-bottom: 1px solid #e3e7ee;
}

.erp-barras i {
  position: relative;
  flex: 1;
  height: 100%;
}

.erp-barras i::before,
.erp-barras i::after {
  content: '';
  position: absolute;
  bottom: 0;
  width: 46%;
  border-radius: 5px 5px 0 0;
}

.erp-barras i::before {
  left: 0;
  height: calc(var(--v) * 100%);
  background: #ef4444;
}

.erp-barras i::after {
  right: 0;
  height: calc(var(--g) * 100%);
  background: #cbd2de;
}

.erp-factura {
  display: grid;
  grid-template-columns: 110px 1fr auto 104px;
  gap: 12px;
  align-items: center;
  padding: 15px 0;
  border-bottom: 1px solid #eef1f5;
  font-size: 14px;
}

.erp-factura:last-child {
  border-bottom: 0;
}

.erp-factura span:first-child {
  color: #7a8599;
}

.erp-factura b {
  font-weight: 600;
}

.erp-factura em {
  justify-self: end;
  padding: 4px 10px;
  border-radius: 999px;
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
}

.erp-factura em.pagada {
  background: #dcfce7;
  color: #15803d;
}

.erp-factura em.vence {
  background: #fef3c7;
  color: #b45309;
}

.erp-factura em.vencida {
  background: #fee2e2;
  color: #b91c1c;
}

/* El aviso blanco: «Conectando con Lyquia». */
.erp-aviso {
  position: absolute;
  left: 50%;
  top: 290px;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 20px;
  width: 640px;
  margin-left: -320px;
  padding: 30px 34px 26px;
  border-radius: 22px;
  background: #fff;
  color: #0b1628;
  box-shadow: 0 40px 90px -30px rgba(8, 15, 31, 0.65), 0 0 0 1px rgba(8, 15, 31, 0.06);
  font-family: var(--letra-cuerpo);
  opacity: 0;
}

.erp-aviso img {
  width: 56px;
  height: 56px;
  border-radius: 14px;
}

.erp-aviso-texto {
  font-size: 27px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.erp-aviso-texto small {
  display: block;
  margin-top: 4px;
  font-size: 15px;
  font-weight: 400;
  color: #5b6577;
}

.erp-progreso {
  grid-column: 1 / -1;
  display: block;
  height: 6px;
  margin-top: 22px;
  border-radius: 3px;
  background: #e6ebf2;
  overflow: hidden;
}

.erp-progreso i {
  display: block;
  width: calc(var(--p, 0) * 100%);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #28cabe, #5fe3d7);
}

@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;
  }
}

/* ── 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;
  }
}

/* ── 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;
  }
}
