/* ===========================================================================
 * Landing comercial — FOUNDATION VISUAL + HERO
 * ===========================================================================
 *
 * Dirección: negra, premium, B2B seria. Tres colores con oficio distinto y sin
 * solaparse, para que la página no se convierta en un arcoíris neón:
 *
 *   CIAN    señal y producto  → badge y diagrama de pasos
 *   MORADO  la acción que queremos → highlight del H1 y CTA principal
 *   AZUL    la vía de contacto → CTA flotante
 *
 * ÍNDICE
 *   01. Tokens: color
 *   02. Tokens: tipografía
 *   03. Tokens: espaciado
 *   04. Tokens: radios, sombras y glows
 *   05. Tokens: movimiento
 *   06. Reset y base del documento
 *   07. Accesibilidad base
 *   08. Entrada escalonada
 *   09. Containers
 *   10. Escala tipográfica
 *   11. Botones
 *   12. Superficies y cards
 *   13. Hero: composición
 *   14. Hero: badge, titular y métricas
 *   15. Diagrama de 4 pasos
 *   16. CTA flotante
 *   17. Demo
 *   18. Antes / Después
 *   19. Calculadora — Pasos 1 y 2
 *   20. Resultados
 *   21. Piloto
 *   22. Preguntas frecuentes
 *   23. Cierre comercial
 *   24. Pie de página
 *   25. Página de privacidad
 *
 * BREAKPOINTS. Solo dos, y a propósito: `clamp()` hace casi todo el trabajo
 * fluido, así que los cortes duros se reservan para cambios de composición que
 * una interpolación no puede expresar.
 *
 *   md   768px   tablet
 *   lg  1024px   escritorio, donde el Hero pasa a dos columnas
 *
 * Las media queries no aceptan custom properties, así que esos dos valores van
 * escritos a mano donde hagan falta. Están aquí para que haya UN sitio donde
 * leerlos.
 * ======================================================================== */

:root {
  /* La página es oscura y lo declara: los controles nativos (scrollbars,
     campos de formulario) se pintan en oscuro en vez de en blanco. */
  color-scheme: dark;

  /* --- 01. Color ------------------------------------------------------ */
  /* NEGRO, no azul marino. El fondo anterior llevaba una pizca de azul que,
     sumada a dos degradados a pantalla completa, teñía toda la página. Este
     casi-negro es prácticamente neutro: deja que el cian y el morado sean lo
     único que brilla. No es `#000` puro, que aplasta la profundidad. */
  --lp-bg: #040507;
  --lp-bg-elevated: #0d0f15;
  --lp-surface: #12151c;
  --lp-surface-hover: #171b24;

  --lp-text: #f2f4f8;
  --lp-text-secondary: #a8b0c0;
  --lp-text-muted: #767f90;

  /* Cian: la señal del producto. Badge y diagrama. 11:1 sobre el fondo. */
  --lp-cian: #22d3ee;

  /* Azul: la vía de contacto. `--lp-blue` es el que se LEE (foco, selección);
     los dos `fill` son el relleno del CTA flotante, más profundos a propósito
     porque sobre el azul claro el texto blanco se queda en 3:1 y no pasa AA.
     Con estos, el punto más claro del degradado da 4.56:1. */
  --lp-blue: #2f8dff;
  --lp-blue-fill-top: #1668e8;
  --lp-blue-fill-bottom: #1159d2;

  /* Morado: la acción. El neón es para texto sobre negro (5.8:1); los `fill`
     son el relleno del CTA principal, calculados para que el rótulo blanco
     encima dé 5.3:1 en el punto más claro. Un morado más luminoso de fondo
     quedaría bonito y dejaría el texto por debajo de AA. */
  --lp-purple-neon: #9d6bff;
  --lp-purple-fill-top: #7038f5;
  --lp-purple-fill-bottom: #5f22e0;

  /* Rojo: el único estado de error de la página. 6.7:1 sobre la card y 7.3:1
     sobre el fondo, así que el mensaje se lee sin forzar la vista. Nunca va
     solo: el texto del error, el filo de 2px y `aria-invalid` dicen lo mismo
     sin depender de que alguien distinga este tono. */
  --lp-error: #ff6b6b;

  --lp-border: #1e2230;
  --lp-border-strong: #2c3244;

  /* --- 02. Tipografía ------------------------------------------------- */
  /* Stack de sistema: cero peticiones externas y cero salto de layout al
     cargar la fuente, porque ya está en la máquina. */
  --lp-font: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto,
    "Helvetica Neue", Arial, sans-serif;

  /* Solo los dos que marcan jerarquía. El peso normal del texto lo hereda del
     `body`, así que declararlo como token no añadiría nada. */
  --lp-weight-semibold: 600;
  --lp-weight-bold: 700;

  /* Escala fluida. El techo del display se queda en 5.5rem: en una landing
     B2B seria la jerarquía la marca el contraste, no el grito. */
  --lp-text-display: clamp(2.75rem, 1.6rem + 5.2vw, 5.5rem);
  --lp-text-heading-lg: clamp(2.25rem, 1.5rem + 3.2vw, 3.75rem);
  --lp-text-heading-md: clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem);
  --lp-text-heading-sm: clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
  --lp-text-body-lg: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  --lp-text-body: 1rem;
  --lp-text-body-sm: 0.875rem;
  --lp-text-label: 0.75rem;

  --lp-leading-tight: 1.05;
  --lp-leading-heading: 1.15;
  --lp-leading-body: 1.6;

  --lp-tracking-tight: -0.02em;
  --lp-tracking-snug: -0.01em;
  --lp-tracking-wide: 0.08em;

  /* --- 03. Espaciado -------------------------------------------------- */
  /* Base 4px. Nueve escalones cubren de micro a separación de bloque; el aire
     entre secciones lo pone `--lp-space-section`, justo debajo. */
  --lp-space-3xs: 0.25rem;
  --lp-space-2xs: 0.5rem;
  --lp-space-xs: 0.75rem;
  --lp-space-sm: 1rem;
  --lp-space-md: 1.5rem;
  --lp-space-lg: 2rem;
  --lp-space-xl: 3rem;
  --lp-space-2xl: 4rem;
  --lp-space-3xl: 6rem;

  /* Aire entre secciones y gutter lateral. Fluidos, para no gastar un
     breakpoint en algo que una interpolación resuelve mejor. */
  --lp-space-section: clamp(4rem, 8vw, 8rem);
  --lp-gutter: clamp(1.25rem, 4vw, 2.5rem);

  /* --- 04. Radios, sombras y glows ------------------------------------ */
  /* REGLA DE FORMA, una sola para toda la página: controles pequeños `sm`,
     botones `cta`, cards `lg`, paneles grandes `xl`, y `999px` reservado a
     etiquetas de estado —nunca a botones, que píldora entera se lee barato. */
  --lp-radius-sm: 6px;
  --lp-radius-md: 10px;
  --lp-radius-cta: 16px;
  --lp-radius-lg: 14px;
  --lp-radius-xl: 20px;
  --lp-radius-pill: 999px;

  /* Sombras tintadas hacia el fondo, nunca negro puro. */
  --lp-shadow-sm: 0 1px 2px rgba(3, 5, 10, 0.5);
  --lp-shadow-md: 0 4px 16px -4px rgba(3, 5, 10, 0.6);
  --lp-shadow-lg: 0 24px 60px -20px rgba(3, 5, 10, 0.75);

  /* Filo interior: la luz que hace que una superficie parezca material y no
     un rectángulo pintado. Es el recurso de profundidad de toda la página, y
     sustituye al vidrio esmerilado que aquí no queremos. */
  --lp-edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  --lp-edge-light-strong: inset 0 1px 0 rgba(255, 255, 255, 0.18);

  /* Glows: de uso puntual y siempre cortos de radio. Nunca ambientales sobre
     toda la pantalla, que es lo que convierte un negro premium en un azul
     lavado. Aquí solo marcan un elemento concreto. */
  --lp-glow-cian: 0 0 24px -8px rgba(34, 211, 238, 0.55);
  --lp-glow-purple: 0 8px 28px -10px rgba(112, 56, 245, 0.5);
  --lp-glow-purple-strong: 0 10px 34px -8px rgba(112, 56, 245, 0.72);
  --lp-glow-blue: 0 10px 34px -10px rgba(47, 141, 255, 0.6);
  --lp-glow-blue-strong: 0 12px 40px -8px rgba(47, 141, 255, 0.78);

  /* --- 05. Movimiento ------------------------------------------------- */
  /* Curva propia: las de serie son demasiado flojas y suenan a plantilla.
     Nada de `ease-in` en interfaz: arranca lento justo en el momento que el
     usuario está mirando, y hace que todo parezca pesado. */
  --lp-ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  /* Pulsación y hover. Por debajo de 300ms, que es donde una interfaz deja
     de sentirse instantánea. */
  --lp-duration-fast: 140ms;
  --lp-duration: 200ms;

  /* Entrada del Hero. 360ms por elemento y 70ms entre uno y el siguiente:
     ocho elementos terminan en ~850ms, dentro de lo que se percibe como una
     sola presentación y no como una cola de animaciones. */
  --lp-duration-reveal: 360ms;
  --lp-stagger: 70ms;
}

/* ===========================================================================
 * 06. Reset y base del documento
 * ======================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
}

body.landing {
  margin: 0;
  /* `dvh` con respaldo en `vh`: en iOS la barra de direcciones cambia el alto
     de la ventana y `vh` a secas provoca un salto al empezar a hacer scroll. */
  min-height: 100vh;
  min-height: 100dvh;

  /* Negro liso, sin un solo degradado a pantalla completa. La iluminación
     ambiental que había antes tapaba de azul los 1200px de ancho y era justo
     lo que impedía leer el fondo como negro. La poca luz que queda está
     LOCALIZADA detrás del diagrama, y se declara allí. */
  background-color: var(--lp-bg);

  color: var(--lp-text);
  font-family: var(--lp-font);
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  /* Nada puede empujar la página a lo ancho. */
  overflow-x: hidden;
}

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

/* ===========================================================================
 * 07. Accesibilidad base
 * ======================================================================== */

/* Un único anillo de foco para toda la landing, visible sobre el fondo
   oscuro. `:focus-visible` y no `:focus`: el ratón no debe dispararlo. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--lp-blue);
  outline-offset: 2px;
}

::selection {
  background-color: rgba(47, 141, 255, 0.3);
  color: var(--lp-text);
}

/* ===========================================================================
 * 08. Entrada escalonada
 * ===========================================================================
 *
 * Un solo mecanismo para toda la página: el HTML declara en qué orden entra
 * cada elemento con `--reveal-index`, y el retardo sale de multiplicar. No
 * hace falta JavaScript, ni `nth-child` —que se rompería en cuanto un
 * elemento cambie de sitio o de contenedor—, ni una clase por paso.
 *
 * VA DENTRO DE `no-preference`, NO AL REVÉS. Es la diferencia entre una
 * animación y un contenido que puede quedarse invisible: con movimiento
 * reducido, o si esta regla no llegara a aplicarse, todo está visible desde
 * el primer fotograma porque nadie ha tocado su opacidad.
 * ======================================================================== */

@media (prefers-reduced-motion: no-preference) {
  [data-reveal] {
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
    animation-delay: calc(var(--reveal-index, 0) * var(--lp-stagger));
  }
}

/* Sin escala, sin rebote, sin rotación: solo un empujón de 8px hacia arriba.
   Nada aparece "de la nada", que es lo que delata una animación barata. */
@keyframes landing-reveal {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* ===========================================================================
 * 09. Containers
 * ======================================================================== */

/* Centra la CAJA, no el texto: qué va alineado y cómo lo decide cada sección.
   El gutter crece con la ventana sin necesitar un breakpoint propio. */
.landing-container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--lp-gutter);
}

/* Única primitiva para copy: 1200px daría una línea imposible de seguir, y
   720px deja una medida de lectura cómoda sin inventar una segunda utilidad
   que hiciera lo mismo por otro camino. */
.landing-container--narrow {
  max-width: 720px;
}

/* ===========================================================================
 * 10. Escala tipográfica
 * ======================================================================== */

/* Clases y no selectores de elemento: el nivel semántico (`h1`, `h2`) y el
   tamaño visual son decisiones distintas. Atarlas obliga a pelearse con la
   especificidad en cuanto una sección necesita un h2 pequeño o un párrafo
   grande. */

.landing-display {
  margin: 0;
  font-size: var(--lp-text-display);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-tight);
  letter-spacing: var(--lp-tracking-tight);
}

.landing-heading-lg {
  margin: 0;
  font-size: var(--lp-text-heading-lg);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
}

.landing-heading-md {
  margin: 0;
  font-size: var(--lp-text-heading-md);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-snug);
}

.landing-heading-sm {
  margin: 0;
  font-size: var(--lp-text-heading-sm);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-snug);
}

.landing-body-lg {
  margin: 0;
  font-size: var(--lp-text-body-lg);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
}

.landing-body {
  margin: 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
}

.landing-body-sm {
  margin: 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

.landing-label {
  margin: 0;
  font-size: var(--lp-text-label);
  font-weight: var(--lp-weight-semibold);
  line-height: 1.2;
  letter-spacing: var(--lp-tracking-wide);
  text-transform: uppercase;
  color: var(--lp-text-muted);
}

/* ===========================================================================
 * 11. Botones
 * ======================================================================== */

.landing-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--lp-space-2xs);
  /* 44px: el mínimo cómodo para un pulgar. */
  min-height: 2.75rem;
  padding-inline: var(--lp-space-md);
  border: 1px solid transparent;
  border-radius: var(--lp-radius-cta);
  font-family: inherit;
  font-size: var(--lp-text-body);
  font-weight: var(--lp-weight-semibold);
  line-height: 1;
  letter-spacing: var(--lp-tracking-snug);
  text-decoration: none;
  /* Un CTA partido en dos líneas es un CTA roto. */
  white-space: nowrap;
  cursor: pointer;
  /* Propiedades enumeradas una a una: `transition: all` anima también lo que
     no se pretendía, y encima cuesta frames. */
  transition:
    background-color var(--lp-duration) var(--lp-ease-out),
    background-image var(--lp-duration) var(--lp-ease-out),
    border-color var(--lp-duration) var(--lp-ease-out),
    color var(--lp-duration) var(--lp-ease-out),
    box-shadow var(--lp-duration) var(--lp-ease-out),
    transform var(--lp-duration-fast) var(--lp-ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* El botón tiene que acusar el golpe: sin esto la interfaz parece no estar
   escuchando. 0.97 se percibe sin convertir el botón en un juguete. */
.landing-button:active {
  transform: scale(0.97);
}

/* Movimiento reducido significa MENOS movimiento, no cero transiciones: el
   color y la opacidad ayudan a entender qué ha cambiado y se quedan. Lo que
   desaparece es el desplazamiento.

   VA DEBAJO, Y NO ARRIBA CON EL RESTO DE ACCESIBILIDAD, POR LA CASCADA. Una
   media query no añade especificidad: `.landing-button:active` pesa lo mismo
   dentro que fuera de ella, así que entre dos reglas idénticas gana la última
   del fichero. Estando en la sección 07 esta llegaba ANTES que el
   `scale(0.97)` de aquí y no anulaba nada: el botón seguía encogiéndose con
   movimiento reducido. Pegada a la regla que corrige, la cascada la respeta
   sin `!important` y sin inflar el selector. */
@media (prefers-reduced-motion: reduce) {
  .landing-button:active {
    transform: none;
  }
}

.landing-button:disabled,
.landing-button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* --- Primario: morado neón -------------------------------------------- */
/* El color de la acción que queremos que ocurra. El glow en reposo es corto
   de radio a propósito: marca el botón sin encender media pantalla. */
.landing-button--primary {
  color: var(--lp-text);
  background-image: linear-gradient(
    180deg,
    var(--lp-purple-fill-top),
    var(--lp-purple-fill-bottom)
  );
  box-shadow:
    var(--lp-shadow-sm),
    var(--lp-edge-light-strong),
    var(--lp-glow-purple);
}

/* --- Secundario: contorno, casi transparente --------------------------- */
/* Antes era morado relleno y competía de tú a tú con el principal. Vaciarlo
   es lo que deja claro cuál de los dos es la acción de cabecera. */
.landing-button--secondary {
  color: var(--lp-text);
  background-color: rgba(255, 255, 255, 0.03);
  border-color: var(--lp-border-strong);
  box-shadow: var(--lp-edge-light);
}

/* --- Fantasma: acciones de poca voz ------------------------------------ */
.landing-button--ghost {
  color: var(--lp-text-secondary);
  background-color: transparent;
  border-color: var(--lp-border-strong);
}

/* Los hover van detrás de esta consulta porque en pantallas táctiles el hover
   se dispara al tocar y el estado se queda pegado después del tap. */
@media (hover: hover) and (pointer: fine) {
  .landing-button--primary:hover {
    /* El degradado se aplana hacia su tono superior en vez de aclararse: el
       punto más claro sigue siendo el mismo y el contraste no se mueve.
       Lo que sube es el glow, que no toca la legibilidad del rótulo. */
    background-image: linear-gradient(
      180deg,
      var(--lp-purple-fill-top),
      var(--lp-purple-fill-top)
    );
    box-shadow:
      var(--lp-shadow-sm),
      var(--lp-edge-light-strong),
      var(--lp-glow-purple-strong);
  }

  .landing-button--secondary:hover {
    background-color: rgba(255, 255, 255, 0.07);
    border-color: var(--lp-border-strong);
    box-shadow: var(--lp-edge-light), 0 0 0 1px rgba(255, 255, 255, 0.06);
  }

  .landing-button--ghost:hover {
    color: var(--lp-text);
    background-color: var(--lp-surface-hover);
  }
}

/* ===========================================================================
 * 12. Superficies y cards
 * ======================================================================== */

.landing-card {
  background-color: var(--lp-surface);
  border: 1px solid var(--lp-border);
  border-radius: var(--lp-radius-lg);
  padding: clamp(1.25rem, 2.5vw, 2rem);
  box-shadow: var(--lp-shadow-md), var(--lp-edge-light);
}

/* Un escalón por encima, para lo que deba destacar dentro de un grupo.
   Comparte superficie con la card base a propósito: lo que la eleva es la
   profundidad, no el color. */
.landing-card--raised {
  border-color: var(--lp-border-strong);
  box-shadow: var(--lp-shadow-lg), var(--lp-edge-light);
}

/* Solo para cards que de verdad son pulsables o enlazan a algo: una card
   informativa que reacciona al ratón promete una acción que no existe. */
.landing-card--interactive {
  transition:
    background-color var(--lp-duration) var(--lp-ease-out),
    border-color var(--lp-duration) var(--lp-ease-out),
    box-shadow var(--lp-duration) var(--lp-ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .landing-card--interactive:hover {
    background-color: var(--lp-surface-hover);
    border-color: var(--lp-border-strong);
  }
}

/* ===========================================================================
 * 13. Hero: composición
 * ======================================================================== */

.landing-hero {
  padding-block: var(--lp-space-section);
}

/* Una columna hasta `lg`, con el diagrama al final: en móvil primero se lee
   qué es y qué hacer, y el flujo se ve después. */
/* `row-gap: 0` y el ritmo vertical por márgenes. El detalle pasó a ser un
   tercer hijo de la rejilla, y con un row-gap uniforme se habría sumado a su
   propio `margin-top`: 112px entre las métricas y el explicativo donde antes
   había 48. Dejando el hueco en manos de los márgenes, el espaciado en móvil
   queda EXACTAMENTE como estaba. */
.landing-hero__grid {
  display: grid;
  column-gap: var(--lp-space-2xl);
  row-gap: 0;
}

/* Alineado a la izquierda, no centrado: con un titular de varias líneas y
   cuatro bloques debajo, centrar obligaría al ojo a buscar el inicio de cada
   línea. El borde izquierdo común es lo que sostiene la jerarquía. */
.landing-hero__copy {
  min-width: 0;
}

@media (min-width: 1024px) {
  /* 1.15fr / 1fr ≈ 53,5% / 46,5%. El diagrama gana ~9 puntos respecto al
     reparto anterior, que le quedaba corto. Sigue sin ser 50/50: la columna de
     copy conserva la ventaja, que es lo que mantiene al titular de protagonista
     aunque el diagrama ahora pese más. `minmax(0, …)` evita que una palabra
     larga reviente la columna. */
  .landing-hero__grid {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    /* `start` y no `center`. Centrado, el diagrama se colocaba a media altura
       de una columna de copy mucho más larga, y el primer nodo caía por el
       lead. Anclando las dos columnas arriba, el diagrama arranca en la misma
       banda que el badge sin un solo desplazamiento mágico: es la rejilla la
       que alinea, no un offset que habría que recalcular a cada ancho. */
    align-items: start;
  }

  /* Colocación EXPLÍCITA de los tres hijos. Sin ella, el detalle se colaría en
     la celda libre de la derecha por autocolocación. Dos celdas arriba y una
     fila entera abajo. */
  .landing-hero__copy {
    grid-column: 1;
    grid-row: 1;
  }

  .landing-hero__visual {
    grid-column: 2;
    grid-row: 1;
    /* El margen que separa diagrama de explicativo en móvil sobra aquí: en
       escritorio están en columnas distintas, y mantenerlo rompería la
       alineación con el badge. */
    margin-top: 0;
    /* Lo único que separa el primer nodo del borde superior de la fila. Con
       8px, el cuerpo del círculo y el anillo quedan justo por debajo del filo
       del badge —nada sobresale— y ambos se leen en la misma línea. */
    padding-top: 0.5rem;
  }

  /* La fila entera. El párrafo deja de ser una columna angosta bajo el copy y
     se extiende por debajo de las dos, y la línea divisoria se estira con él
     porque es su propio `border-top`: no hay que dibujar nada nuevo.
     `min(104ch, 90%)` combina dos topes a propósito: el porcentaje garantiza
     un margen derecho visible a cualquier ancho —no llega al borde—, y los
     104ch impiden que en una pantalla muy ancha la línea se vuelva imposible
     de seguir. Manda el que sea más restrictivo. */
  .landing-hero__detail {
    grid-column: 1 / -1;
    grid-row: 2;
    max-width: min(104ch, 90%);
  }
}

/* ===========================================================================
 * 14. Hero: badge, titular y métricas
 * ======================================================================== */

/* Etiqueta de estado, no botón: por eso es píldora —el único sitio de la
   página donde ese radio está permitido— y por eso no tiene `cursor` ni
   estados de interacción. El glow es corto y tenue; lo que la hace visible es
   el contraste del cian sobre negro, no el brillo. */
.landing-hero__badge {
  display: inline-flex;
  align-items: center;
  padding: 0.375rem 0.75rem;
  border: 1px solid rgba(34, 211, 238, 0.4);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.08);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* `text-wrap: balance` reparte las líneas del titular para que ninguna quede
   con una palabra suelta. Donde el navegador no lo soporte, se ignora. */
.landing-hero__title {
  margin-top: var(--lp-space-sm);
  text-wrap: balance;
}

@media (min-width: 1024px) {
  /* En dos columnas el titular dispone de ~57% del ancho. Sin bajar el techo
     de la escala, 89 caracteres a 60px caerían en cuatro o cinco líneas. A
     44px caben en tres y el titular sigue siendo, de largo, lo más grande de
     la pantalla. */
  .landing-hero__title {
    font-size: clamp(2.25rem, 1.6rem + 1.6vw, 2.75rem);
  }
}

/* El acento va en UNA parte corta. Mismo peso y misma familia que el resto del
   titular: lo único que cambia es el color, sin degradado de texto. El morado
   neón da 5.8:1 sobre el negro, así que destaca sin dejar de leerse. */
.landing-hero__accent {
  color: var(--lp-purple-neon);
}

/* Medidas de línea decrecientes: cuanto más subordinado es el texto, más corta
   la línea. `ch` se recalcula con el tamaño de cada bloque, así que la relación
   se mantiene en cualquier ventana sin un solo breakpoint. */
.landing-hero__lead {
  max-width: 52ch;
  margin-top: var(--lp-space-md);
  text-wrap: pretty;
}

.landing-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lp-space-sm);
  margin-top: var(--lp-space-lg);
}

/* Tres datos DESCRIPTIVOS, no resultados. Rejilla de tres y no `flex-wrap`:
   al envolverse, un elemento con separador a la izquierda quedaría abriendo
   fila con una línea colgando. Con rejilla siempre son tres columnas y lo que
   se parte, si acaso, es el rótulo. */
.landing-hero__metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--lp-space-sm);
  margin: var(--lp-space-lg) 0 0;
  padding: 0;
  list-style: none;
}

/* `minmax(0, max-content)` y no `max-content` a secas: entre 1024 y 1200px la
   columna de copy se estrecha y tres rótulos a su ancho natural se salían de
   la rejilla. Con el mínimo en 0 pueden ceder y partir el rótulo en vez de
   desbordar. */
@media (min-width: 768px) {
  .landing-hero__metrics {
    grid-template-columns: repeat(3, minmax(0, max-content));
    gap: var(--lp-space-lg);
  }
}

/* Separadores en vez de cajas: tres cards aquí pesarían más que los CTA que
   tienen justo encima. */
.landing-hero__metric {
  display: flex;
  flex-direction: column;
  gap: var(--lp-space-3xs);
}

.landing-hero__metric + .landing-hero__metric {
  padding-left: var(--lp-space-sm);
  border-left: 1px solid var(--lp-border);
}

@media (min-width: 768px) {
  .landing-hero__metric + .landing-hero__metric {
    padding-left: var(--lp-space-lg);
  }
}

.landing-hero__metric-value {
  font-size: var(--lp-text-heading-sm);
  font-weight: var(--lp-weight-bold);
  line-height: 1;
  letter-spacing: var(--lp-tracking-tight);
  color: var(--lp-text);
}

.landing-hero__metric-label {
  font-size: var(--lp-text-body-sm);
  line-height: 1.3;
  color: var(--lp-text-muted);
}

/* El detalle largo va DEBAJO de los CTA y separado por una línea, no dentro de
   una card: quien ya está convencido pulsa arriba, y quien necesita saber qué
   hace el producto sigue leyendo. */
.landing-hero__detail {
  max-width: 62ch;
  margin-top: var(--lp-space-xl);
  padding-top: var(--lp-space-md);
  border-top: 1px solid var(--lp-border);
}

.landing-hero__explainer,
.landing-hero__note {
  text-wrap: pretty;
}

.landing-hero__note {
  margin-top: var(--lp-space-sm);
}

/* ===========================================================================
 * 15. Diagrama de 4 pasos
 * ===========================================================================
 *
 * Recorrido vertical con raíl conector.
 *
 * POR QUÉ SIGUE SIENDO VERTICAL Y NO UNA ESCALERA. La referencia es un póster
 * 3:4 donde los rótulos flotan libres alrededor de la diagonal. Aquí viven en
 * una columna: si los nodos van escalonando hacia la derecha, los rótulos
 * escalonan con ellos, el cuarto paso pierde ~55px de ancho respecto al primero
 * y el borde izquierdo del texto queda en diente de sierra. Eso pelea justo con
 * la alineación limpia sobre la que se apoya el resto del Hero.
 *
 * De la referencia se toma lo que SÍ da presencia y no cuesta claridad: nodos
 * grandes con anillo luminoso, y un raíl que se enciende hacia el último paso.
 * El tamaño es lo que resuelve el problema de presencia, no la geometría.
 * ======================================================================== */

.landing-hero__visual {
  position: relative;
  /* Reemplaza al `row-gap` que la rejilla ya no aplica: en móvil son los 64px
     que siempre hubo entre el explicativo y el diagrama. En escritorio se
     anula, porque allí están en columnas distintas. */
  margin-top: var(--lp-space-2xl);
  /* El diagrama no llega a los bordes de su columna: respira. Fluido para no
     comerse el ancho de texto en móvil, donde cada píxel cuenta. */
  padding: clamp(0.5rem, 2vw, 2rem);
}

/* La ÚNICA luz ambiental de la página, y está localizada detrás del diagrama.
   Nada de degradados a pantalla completa: el fondo tiene que seguir leyéndose
   como negro a dos palmos del diagrama. */
.landing-hero__visual::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -6%;
  /* Alargado en vertical para acompañar al recorrido, que ahora es bastante
     más alto. Misma intensidad de antes: la pieza crece, la luz no, porque lo
     que no puede cambiar es que el fondo se siga leyendo negro. */
  background: radial-gradient(
    52% 62% at 40% 48%,
    rgba(34, 211, 238, 0.09),
    transparent 72%
  );
  pointer-events: none;
}

.landing-flow {
  /* Un sitio para el tamaño del nodo y la separación: el conector se calcula a
     partir de los dos, así que cambiarlos no descuadra nada.
     Ambos son fluidos, de modo que el diagrama crece con la ventana sin gastar
     un breakpoint: 54px/34px en un móvil de 375px, 68px/51px en escritorio.
     Alto total del recorrido: 318px en móvil y 425px en escritorio.

     Los mínimos del `clamp` crecen menos que los máximos a propósito: el
     último retoque subió ~6% en escritorio y solo ~4% en móvil, porque en una
     pantalla estrecha el recorrido ya era lo bastante alto y lo que manda allí
     es la legibilidad, no el tamaño. */
  --flow-node: clamp(3.375rem, 3.15rem + 1.3vw, 4.25rem);
  --flow-gap: clamp(2.125rem, 1.3rem + 2.5vw, 3.1875rem);

  display: grid;
  gap: var(--flow-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: paso;
}

/* Escalón extra de tamaño SOLO por debajo de escritorio: en una columna única
   el diagrama tiene el ancho entero para él y se puede permitir más presencia,
   mientras que en escritorio ya está aprobado y no se toca.
   Los topes (4rem y 2.9rem) son exactamente los valores que la curva base
   alcanza en 1024px, así que al cruzar el breakpoint el diagrama no da ningún
   salto: a 1023px mide lo mismo que a 1024px. */
@media (max-width: 1023px) {
  .landing-flow {
    --flow-node: clamp(3.625rem, 3.4rem + 1.3vw, 4rem);
    --flow-gap: clamp(2.25rem, 1.45rem + 2.5vw, 2.9rem);
  }
}

.landing-flow__step {
  position: relative;
  display: grid;
  grid-template-columns: var(--flow-node) minmax(0, 1fr);
  gap: var(--lp-space-md);
  align-items: start;
  counter-increment: paso;
}

/* Conector: del borde inferior de este nodo al superior del siguiente. Se
   apoya en `align-items: start`, que fija el nodo arriba del todo y hace que
   el tramo sea calculable sin conocer el alto del texto. */
/* Raíl de 2px con halo corto: a los tamaños nuevos, 1px seco se quedaba en un
   hilo y el recorrido no se leía como un recorrido. */
.landing-flow__step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(var(--flow-node) / 2);
  top: calc(var(--flow-node) + 6px);
  width: 2px;
  height: calc(100% - var(--flow-node) + var(--flow-gap) - 12px);
  border-radius: 1px;
  transform: translateX(-1px);
  background: linear-gradient(
    180deg,
    rgba(34, 211, 238, 0.65),
    rgba(34, 211, 238, 0.3)
  );
  box-shadow: 0 0 8px rgba(34, 211, 238, 0.3);
}

/* Nodo oscuro con iluminación de borde, no relleno de cian: así el icono se
   lee y el conjunto no se convierte en cuatro focos. */
.landing-flow__node {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--flow-node);
  height: var(--flow-node);
  border: 1px solid rgba(34, 211, 238, 0.38);
  border-radius: 50%;
  background-color: rgba(34, 211, 238, 0.06);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* Anillo parcial luminoso. Es lo único que se trae literalmente de la
   referencia, y es lo que más presencia añade por línea de CSS: media
   circunferencia de 2px, girada para que el corte no caiga en la vertical.
   El halo va por `drop-shadow` y no por `box-shadow` porque el primero sigue
   los píxeles pintados —solo el arco— y el segundo iluminaría el círculo
   entero, que es como se consigue un borrón en vez de un filo. */
.landing-flow__node::before {
  content: "";
  position: absolute;
  inset: -5px;
  border: 2px solid transparent;
  border-top-color: var(--lp-cian);
  border-left-color: var(--lp-cian);
  border-radius: 50%;
  transform: rotate(-35deg);
  filter: drop-shadow(0 0 6px rgba(34, 211, 238, 0.55));
  pointer-events: none;
}

/* Proporcional al nodo: al crecer el círculo, el icono crece con él y la
   relación óptica no cambia. */
.landing-flow__icon {
  width: calc(var(--flow-node) * 0.4);
  height: calc(var(--flow-node) * 0.4);
}

.landing-flow__text {
  display: flex;
  flex-direction: column;
  gap: var(--lp-space-3xs);
  /* Centra la PRIMERA LÍNEA con el nodo. Se calcula desde `--flow-node` en vez
     de fijar un valor: el nodo ahora es fluido, y un padding constante dejaría
     el texto descolgado en un extremo del rango. 1.5rem es el alto aproximado
     de esa primera línea. */
  padding-top: calc((var(--flow-node) - 1.5rem) / 2);
}

/* Un escalón por encima del cuerpo de texto: el rótulo de cada paso es lo que
   se lee de un vistazo, y a 16px competía con el subtexto. */
.landing-flow__label {
  font-size: var(--lp-text-body-lg);
  font-weight: var(--lp-weight-semibold);
  line-height: 1.25;
  color: var(--lp-text);
}

/* El número lo pone el contador de la lista: el orden ya está en el marcado,
   así que escribirlo a mano en el texto lo duplicaría. */
.landing-flow__label::before {
  content: counter(paso);
  margin-right: 0.5em;
  color: var(--lp-cian);
  font-variant-numeric: tabular-nums;
}

.landing-flow__sub {
  font-size: var(--lp-text-body);
  line-height: 1.4;
  color: var(--lp-text-muted);
}

/* ===========================================================================
 * 16. CTA flotante
 * ======================================================================== */

/* MORADO, y ya no azul. El reparto original —azul para la vía de contacto,
   morado para la acción— dejó de sostenerse cuando el cierre de Resultados
   pasó a ser un CTA morado que abre el mismo SMS: había dos colores para una
   sola cosa. Ahora todo lo que lleva a escribirnos es morado.

   NO ES EL CTA PRINCIPAL REPINTADO. Comparte los tonos de relleno, pero se
   distingue en tres cosas: el degradado va en diagonal y no en vertical, lleva
   un filo de neón morado que el primario no tiene, y la sombra es la larga de
   elemento flotante. Puestos uno al lado del otro se reconocen como parientes,
   no como copias.

   El resto lo hereda de `.landing-button`: radio, transición enumerada,
   pulsación, anillo de foco y el estado apagado mientras no hay número.

   Rectangular redondeado y con rótulo, como antes: una burbuja en la esquina
   se lee como un chat, y aquí no hay nadie al otro lado tecleando. */
.landing-floating-cta {
  position: fixed;
  right: var(--lp-gutter);
  /* SUMA, NO MÁXIMO. Con `max()` el botón se quedaba con el mayor de los dos
     valores, así que en un iPhone con barra de gestos —donde `env()` vale unos
     34px— acababa apoyado justo sobre ella y perdía su propio margen. Sumando,
     el espacio del sistema y el respiro de la página se respetan a la vez;
     donde no hay safe-area, `env()` es 0 y quedan los 16px de siempre. */
  bottom: calc(var(--lp-space-sm) + env(safe-area-inset-bottom));
  /* Único elemento en capa de toda la página; de ahí un literal y no una
     escala de niveles que hoy no tendría nada que ordenar. */
  z-index: 10;
  /* 44px: el mismo objetivo cómodo que el resto de botones de la página. Eran
     40 y se quedaban por debajo del sistema; cuatro píxeles no lo hacen grande
     y sí lo hacen más sólido. El ancho NO se toca —sigue con el padding
     pequeño— para que no tape más contenido del que ya tapaba. */
  min-height: 2.75rem;
  padding-inline: var(--lp-space-sm);
  font-size: var(--lp-text-body-sm);
  color: var(--lp-text);
  /* EL MARCO ES LA PIEZA. Con el relleno apagándose hacia el negro, la esquina
     inferior derecha del botón casi se funde con la página: lo que dibuja la
     silueta es esta línea de luz, no el fondo. Por eso el borde sube al 75% y
     no al 55% de antes. `.landing-button` ya reserva el borde de 1px
     transparente, así que esto no mueve ni un píxel el layout. */
  border-color: rgba(157, 107, 255, 0.75);
  /* DEGRADADO MORADO → NEGRO, en diagonal y con una parada intermedia para que
     el morado no muera a medio camino: neón arriba a la izquierda, morado
     profundo en el centro y casi negro abajo a la derecha.

     El extremo oscuro es `--lp-bg-elevated` y no el negro puro de la página:
     con `--lp-bg` esa esquina desaparecería del todo y el botón dejaría de
     leerse como una superficie.

     Las tres paradas son del mismo tono: un degradado premium es una familia de
     color apagándose, no dos colores peleando. */
  background-image: linear-gradient(
    145deg,
    var(--lp-purple-fill-top) 0%,
    var(--lp-purple-fill-bottom) 42%,
    var(--lp-bg-elevated) 100%
  );
  /* Halo ALREDEDOR —radio sin desplazamiento— en vez de la sombra proyectada de
     antes: el botón tiene que verse encendido por su propio contorno. Radio
     negativo para que el resplandor quede corto y no encienda media esquina;
     vive sobre una FAQ deliberadamente sobria. */
  box-shadow:
    var(--lp-shadow-lg),
    var(--lp-edge-light-strong),
    0 0 22px -6px rgba(157, 107, 255, 0.5);
}

.landing-floating-cta__icon {
  flex: none;
  width: 1rem;
  height: 1rem;
}

@media (hover: hover) and (pointer: fine) {
  /* Al pasar por encima, el marco se enciende del todo y el halo crece. El
     degradado NO se aclara: el morado se queda donde está y solo retrocede el
     punto en que empieza a apagarse, así que el rótulo conserva exactamente el
     mismo contraste que en reposo. */
  .landing-floating-cta:hover {
    border-color: var(--lp-purple-neon);
    background-image: linear-gradient(
      145deg,
      var(--lp-purple-fill-top) 0%,
      var(--lp-purple-fill-bottom) 58%,
      var(--lp-bg-elevated) 100%
    );
    box-shadow:
      var(--lp-shadow-lg),
      var(--lp-edge-light-strong),
      0 0 30px -4px rgba(157, 107, 255, 0.72);
  }
}


/* ===========================================================================
 * 17. Demo
 * ===========================================================================
 *
 * DOS COMPOSICIONES DISTINTAS, no una reducida.
 *
 *   móvil       una columna centrada: cabecera, diagrama vertical, párrafo.
 *   escritorio  cabecera partida —etiqueta y titular a la izquierda, párrafo a
 *               la derecha— y el diagrama horizontal cruzando las dos columnas.
 *
 * El orden del MARCADO es el de móvil. En escritorio la rejilla recoloca con
 * `grid-column` y `grid-row`, así que no hay un solo elemento duplicado ni JS
 * moviendo nodos.
 *
 * Cero tokens nuevos: color, tipografía, espaciado, curvas y tiempos salen de
 * la foundation. Lo que se añade aquí es composición.
 * ======================================================================== */

.landing-demo {
  position: relative;
  padding-block: var(--lp-space-section);
  /* El salto desde el CTA del Hero no aterriza pegado al borde superior. */
  scroll-margin-top: var(--lp-space-lg);
}

/* La separación entre Hero y Demo la hace el espacio: dos `--lp-space-section`
   seguidos, uno de cada sección. Este filo de 1px solo la hace deliberada.
   Se desvanece en los extremos para que no corte la pantalla de lado a lado:
   una banda de otro color habría roto el negro continuo de la página. */
.landing-demo::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

/* `row-gap: 0`: el ritmo vertical lo llevan los márgenes de cada bloque, que
   es lo que permite que móvil y escritorio tengan separaciones distintas sin
   pelearse con el hueco de la rejilla. */
.landing-demo__grid {
  display: grid;
  row-gap: 0;
  align-items: start;
}

.landing-demo__head {
  display: flex;
  flex-direction: column;
  /* Centrado en móvil; en escritorio pasa al borde izquierdo. */
  align-items: center;
}

/* Etiqueta en píldora, emparentada con el badge del Hero pero no calcada: más
   relleno y borde más vivo. Sigue siendo cian porque en esta página el cian
   significa "producto", que es justo lo que esta sección explica. */
.landing-demo__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* Negrita y 40px de techo: por debajo de los 44px del H1 del Hero, que sigue
   siendo el titular de la página. No se apoya en `.landing-heading-md` porque
   necesitaba otro peso y otra escala, y sobrescribir tres propiedades de una
   clase de la foundation ensucia más que declarar las cuatro aquí. */
.landing-demo__title {
  max-width: 24ch;
  margin: var(--lp-space-md) 0 0;
  font-size: clamp(2rem, 1.5rem + 1.8vw, 2.5rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-align: center;
  text-wrap: balance;
}

/* Una sola palabra, en el mismo morado que el acento del Hero: 5,8:1 sobre el
   negro. Mismo peso, misma familia, sin degradado de texto.
   `inline-block` porque una palabra suelta admite `transform` sin romper el
   flujo del texto —un `span` en línea lo ignoraría— y es lo que le permite
   entrar un compás después que el resto del titular. */
.landing-demo__accent {
  display: inline-block;
  color: var(--lp-purple-neon);
}

/* Panel del diagrama.
 *
 * EL PROBLEMA QUE RESUELVE. Los dos PNG tienen el fondo en `#000000` exacto
 * —comprobado leyendo su píxel (0,0)— mientras la página es `#040507`. Cuatro
 * puntos de diferencia bastan para que el rectángulo de la imagen se recorte
 * contra el fondo y parezca pegado encima.
 *
 * LA SOLUCIÓN NO ES DISIMULARLO, ES DECLARARLO. El panel se pinta del MISMO
 * negro que las imágenes, así que dentro del marco no hay ningún borde que
 * ver: la imagen y su panel son la misma superficie. Y el marco morado pasa a
 * ser el único límite, que ahora se lee como una decisión y no como una
 * costura.
 *
 * Es el único sitio de la hoja donde `#000` puro se usa como COLOR, y es a
 * propósito: no es una decisión de paleta, es una medida que tiene que
 * coincidir con un fichero. Por eso no sale de un token. (Más abajo aparece
 * otra vez dentro de la máscara, pero allí no pinta: en una máscara el valor
 * se lee como opacidad.)
 *
 * El halo cian que había antes detrás desaparece: un fondo opaco lo habría
 * tapado igualmente —un `::before` con z-index negativo se pinta ANTES que el
 * fondo de su propio contenedor— y su trabajo, integrar la imagen, lo hace
 * ahora el marco. Dejar además un resplandor cian alrededor de un borde morado
 * habría puesto dos acentos sobre el mismo elemento. */
.landing-demo__visual {
  position: relative;
  width: 100%;
  /* `<figure>` trae margen propio del navegador. */
  margin: var(--lp-space-2xl) 0 0;
  padding: var(--lp-space-2xs);
  border: 2px solid rgba(157, 107, 255, 0.45);
  border-radius: var(--lp-radius-xl);
  background-color: #000;
  /* Resplandor centrado y corto de radio, no una sombra negra: acompaña el
     borde sin separar el panel de la página. Más el filo superior que usan
     todas las superficies de la landing. */
  box-shadow: 0 0 32px -8px rgba(157, 107, 255, 0.35), var(--lp-edge-light);
}

/* `aspect-ratio` reserva el hueco exacto antes de que la imagen llegue, así
   nada salta al cargar. El valor es el de la imagen VERTICAL, que es la que
   `<picture>` sirve en este tramo; el de escritorio se corrige justo debajo.
   `contain` se queda como red de seguridad ante un fichero de otra proporción:
   se ajustaría dentro en vez de recortarse, que en un diagrama rotulado
   significaría perder pasos.
   La máscara desvanece un 2% de cada borde. Desde que el panel se pinta del
   mismo `#000` que las imágenes ya casi no se nota —el degradado cae sobre un
   fondo idéntico—, pero se queda como red de seguridad: si algún día se
   sustituye un PNG por otro con el fondo ligeramente distinto, el filo no
   aparecerá de golpe. Es prescindible; no estorba. */
.landing-demo__image {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 941 / 1672;
  object-fit: contain;
  margin-inline: auto;
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0, #000 2%, #000 98%, transparent 100%),
    linear-gradient(to right, transparent 0, #000 2%, #000 98%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to bottom, transparent 0, #000 2%, #000 98%, transparent 100%),
    linear-gradient(to right, transparent 0, #000 2%, #000 98%, transparent 100%);
  mask-composite: intersect;
}

/* Desde 768px `<picture>` ya sirve el diagrama horizontal, así que la
   proporción reservada tiene que cambiar con él. El corte es EXACTAMENTE el
   mismo que el `media` del `<source>`: desacoplarlos dejaría una franja negra
   o un salto al cargar. */
@media (min-width: 768px) {
  .landing-demo__image {
    aspect-ratio: 1672 / 941;
  }
}

.landing-demo__text {
  max-width: 56ch;
  margin-top: var(--lp-space-2xl);
  margin-inline: auto;
  text-align: center;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
 * Escritorio: cabecera partida y diagrama a todo el ancho
 * ------------------------------------------------------------------------ */

@media (min-width: 1024px) {
  /* 1.2fr / 1fr = 54,5% / 45,5%. El titular se lleva la ventaja porque es
     quien manda en la cabecera; el párrafo ocupa el resto y respira contra el
     borde derecho del container. */
  .landing-demo__grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    column-gap: var(--lp-space-3xl);
  }

  /* Colocación explícita. Sin ella, la autocolocación pondría el diagrama en
     la celda libre de la derecha en vez de cruzar las dos columnas. */
  .landing-demo__head {
    grid-column: 1;
    grid-row: 1;
    align-items: flex-start;
  }

  .landing-demo__title {
    text-align: left;
  }

  .landing-demo__text {
    grid-column: 2;
    grid-row: 1;
    /* Alineación ÓPTICA con el titular, no con el borde de la fila: la
       etiqueta ocupa la banda de arriba en la columna izquierda, así que el
       párrafo arranca a su altura y no por encima. No busca coincidir al
       píxel con la primera letra; busca que las dos columnas se lean a la
       misma altura. */
    margin-top: var(--lp-space-xl);
    margin-inline: 0;
    text-align: left;
  }

  /* Cruza las dos columnas, en la fila de abajo. El marco se separa un poco
     más de la imagen: a 1120px de ancho, 8px de margen interior se leerían
     como un filo pegado y no como un panel. */
  .landing-demo__visual {
    grid-column: 1 / -1;
    grid-row: 2;
    margin-top: var(--lp-space-3xl);
    padding: var(--lp-space-sm);
  }

  /* Casi todo el ancho útil del container (1120px). El diagrama es el centro
     de la sección y con nueve pasos necesita cada píxel para que sus rótulos
     se lean. */
  .landing-demo__image {
    max-width: 70rem;
  }
}

/* ---------------------------------------------------------------------------
 * Entrada al entrar en viewport
 * ---------------------------------------------------------------------------
 *
 * El Hero anima al cargar porque está en la primera pantalla. Demo no: animar
 * al cargar significaría que quien llega scrolleando se encuentra la secuencia
 * ya terminada. De ahí el observador de `landing.js`.
 *
 * MEJORA PROGRESIVA, y este es el punto importante: nada de esto se aplica por
 * sí solo. Hace falta que JavaScript añada `js-demo-reveal`, y solo lo hace si
 * existe `IntersectionObserver` y el usuario no ha pedido menos movimiento.
 * Sin JS, con JS roto o con movimiento reducido, estas reglas no llegan a
 * existir y el contenido está visible desde el primer fotograma, que es como
 * nace en el HTML. La animación puede fallar; la información no.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  /* Armado: JS ya sabe que va a animar, así que esconde. */
  .landing-demo.js-demo-reveal [data-demo-reveal] {
    opacity: 0;
  }

  /* Disparado: la sección ha entrado en pantalla. Misma curva, mismo tiempo y
     mismo escalonado que el Hero —`landing-reveal`, 360ms, 70ms— para que la
     página tenga UNA sola personalidad de movimiento y no dos. */
  .landing-demo.js-demo-reveal.is-revealed [data-demo-reveal] {
    opacity: 1;
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
    animation-delay: calc(var(--reveal-index, 0) * var(--lp-stagger));
  }
}

/* ===========================================================================
 * 18. Antes / Después
 * ===========================================================================
 *
 * Comparación en dos columnas iguales en anchura y OPUESTAS en peso visual.
 * Iguales porque comparar pide simetría; opuestas porque una es el statu quo y
 * la otra el producto, y eso debe entenderse antes de leer una palabra.
 *
 * La diferencia se consigue con lo que ya existe: `.landing-card` a secas para
 * "Antes" —la superficie neutra de la foundation, que hasta ahora no había
 * estrenado nadie— y `.landing-card--raised` más el marco morado del diagrama
 * de Demo para el bloque del producto. Sin checks verdes, sin cruces rojas,
 * sin iconos: el color ya dice cuál es cuál.
 *
 * SOBRE LA DUPLICACIÓN. El filo divisorio superior y la píldora de etiqueta
 * repiten lo que hace Demo en su propio bloque. Es deliberado: generalizarlos
 * obligaría a tocar una sección cerrada, y se prefiere esta duplicación
 * controlada. Queda anotado para el polish global.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-compare {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* Mismo filo que abre Demo: se desvanece en los extremos para no cortar la
   pantalla de lado a lado y para que el negro de la página siga siendo
   continuo. Marca la transición sin meter una banda de otro color. */
.landing-compare::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

/* Cabecera centrada sobre las dos columnas. Centrarla es lo correcto aquí: la
   comparación de abajo es simétrica y un titular descolgado a la izquierda la
   dejaba sin eje.
   La versión anterior limitaba el ancho AQUÍ con `34ch`, y era un error: `ch`
   se resuelve contra el tamaño de ESTE elemento (16px), no contra el del
   titular, así que la cabecera quedaba encajonada en unos 300px. El tope va
   ahora en el propio titular, donde `ch` mide lo que debe. */
.landing-compare__head {
  text-align: center;
}

.landing-compare__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* Un escalón por encima del titular de Demo (36-42px frente a 32-40px) porque
   aquí abre una comparación a dos columnas y necesita sostenerlas. El techo se
   queda en 42px, por debajo de los 44px del H1 del Hero, que sigue siendo el
   titular de la página.
   `26ch` a este tamaño son unos 545px: dos líneas parejas en escritorio. Aquí
   sí es la unidad correcta, porque se resuelve contra los 42px del titular. */
.landing-compare__title {
  max-width: 26ch;
  margin: var(--lp-space-md) auto 0;
  font-size: clamp(2.25rem, 1.65rem + 1.9vw, 2.625rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-wrap: balance;
}

/* El único fragmento coloreado del titular, en el azul de marca: 6:1 sobre el
   fondo. NO en morado, a diferencia del H1 del Hero y del H2 de Demo — un
   tercer titular con acento morado habría convertido el recurso en un tic, y
   aquí el morado tiene un trabajo mejor: marcar la card del producto.
   Mismo peso y misma familia; lo único que cambia es el color. */
.landing-compare__accent {
  color: var(--lp-blue);
  /* El neón sale del halo, no de aclarar el color: dos capas de `text-shadow`
     sin desplazamiento —una corta para el núcleo caliente y otra ancha para el
     resplandor— dejan intacto el trazo de las letras. Aclarar el azul habría
     dado brillo a costa de contraste; así el texto sigue en 6:1 y solo gana
     luz alrededor.
     Los radios van en `em` y no en píxeles para que el halo guarde la misma
     proporción a 36px en móvil que a 42px en escritorio. */
  text-shadow:
    0 0 0.15em rgba(47, 141, 255, 0.35),
    0 0 0.45em rgba(47, 141, 255, 0.5);
}

.landing-compare__grid {
  display: grid;
  gap: var(--lp-space-md);
  margin-top: var(--lp-space-2xl);
}

/* `.landing-card` ya pone superficie, borde, radio y sombra. La columna añade
   su reparto interno y MÁS AIRE ARRIBA Y ABAJO que a los lados: es lo que, con
   las jaulas de dentro, endereza la proporción. Antes eran cajas anchas y
   bajas; con 40px de respiro vertical frente a 32px lateral la silueta se
   alarga sin estrechar la columna ni tocar el 50/50. */
.landing-compare__col {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1.25rem, 2.5vw, 2rem);
}

/* El bloque del producto. Borde de 2px y resplandor corto, los mismos valores
   exactos que enmarcan el diagrama de Demo: en esta página ese marco ya
   significa "esto es el producto", y repetirlo aquí ahorra explicarlo.
   Sustituye al borde de `--raised`, no se suma: por eso va después. */
.landing-compare__col--after {
  border: 2px solid rgba(157, 107, 255, 0.45);
  box-shadow: 0 0 32px -8px rgba(157, 107, 255, 0.35), var(--lp-edge-light);
}

.landing-compare__col-title {
  margin: 0 0 var(--lp-space-sm);
  font-size: var(--lp-text-body-lg);
  font-weight: var(--lp-weight-semibold);
  line-height: 1.25;
  color: var(--lp-text-secondary);
}

/* El rótulo del producto es lo único de la card que va en morado neón, y basta
   para que el ojo sepa dónde mirar sin necesidad de un icono. */
.landing-compare__col--after .landing-compare__col-title {
  color: var(--lp-purple-neon);
}

.landing-compare__list {
  display: grid;
  gap: var(--lp-space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Cada punto en su propia jaula.
 *
 * EL FONDO ES MÁS OSCURO QUE LA CARD, no más claro, y no es capricho. Un relleno
 * claro habría dejado el texto atenuado de "Antes" en 4,27:1, por debajo de AA;
 * hundiéndolo un 22% hacia el negro sube a 4,69:1 y pasa. Además un hueco
 * hundido se lee como jaula, que es justo la palabra: no parece un botón ni un
 * campo de formulario, que es lo que habría dado un relleno elevado.
 *
 * Borde gris de 1px, radio `md` —un escalón por debajo del `lg` de la card que
 * las contiene, que es como se anidan bien las formas— y ni sombra ni glow:
 * son contenedores de lectura, no elementos con peso propio. */
.landing-compare__item {
  padding: var(--lp-space-sm);
  border: 1px solid var(--lp-border);
  border-radius: var(--lp-radius-md);
  background-color: rgba(0, 0, 0, 0.22);
  font-size: var(--lp-text-body);
  /* Semibold, no negrita de titular: sube la presencia de cada jaula y hace
     que la comparación se escanee de un vistazo, sin que ocho bloques de texto
     empiecen a competir con los rótulos de las columnas. Es además el mismo
     peso que ya usan los rótulos, así que no entra un valor nuevo. */
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
  text-wrap: pretty;
}

/* Texto más vivo en el lado del producto: 8,4:1 sobre la superficie frente a
   4,5:1 del lado "Antes". Es el mismo contraste diciendo cuál de los dos
   estados queremos que se lea primero. */
.landing-compare__col--after .landing-compare__item {
  color: var(--lp-text-secondary);
}

/* Dos columnas desde 1024px, el mismo corte que usan Hero y Demo.
 *
 * NO desde 768px, aunque el texto cupiera: a ese ancho la columna deja unos
 * 34 caracteres por línea y los ítems caen en dos o tres líneas según su
 * longitud, con lo que las filas dejan de coincidir y se pierde el
 * emparejamiento 1↔1. Desde 1024px hay sitio para 46 caracteres o más y los
 * ocho ítems ocupan exactamente dos líneas, así que las filas se alinean solas
 * sin subgrid ni alturas forzadas. */
@media (min-width: 1024px) {
  .landing-compare__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--lp-space-lg);
    align-items: start;
  }
}

/* ---------------------------------------------------------------------------
 * Entrada al entrar en viewport
 * ---------------------------------------------------------------------------
 *
 * Mismo planteamiento que Demo, con sus propias clases para no tocar las
 * suyas: el HTML nace visible y solo si `landing.js` añade `js-compare-reveal`
 * el CSS se atreve a esconder. Sin JS, con JS roto o con movimiento reducido,
 * estas reglas no llegan a existir y la sección se lee entera.
 *
 * Cuatro elementos a 70ms de escalonado y 360ms cada uno: ~570ms en total,
 * con los tokens y la curva que ya usan el Hero y Demo.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  .landing-compare.js-compare-reveal [data-compare-reveal] {
    opacity: 0;
  }

  .landing-compare.js-compare-reveal.is-revealed [data-compare-reveal] {
    opacity: 1;
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
    animation-delay: calc(var(--reveal-index, 0) * var(--lp-stagger));
  }
}

/* ===========================================================================
 * 19. Calculadora — Pasos 1 y 2
 * ===========================================================================
 *
 * Copy a la izquierda, herramienta a la derecha. Es la tercera composición
 * distinta de la página —Hero reparte 53/47, Compare centra la cabecera y aquí
 * el peso se va al lado derecho— y así ninguna sección se lee como la anterior.
 *
 * La card NO es decorativa: es el formulario, y por eso se lleva el lado ancho
 * y un padding mayor que el de una card corriente.
 *
 * Los primitivos de campo se llaman `.landing-field*` y NO
 * `.landing-calculator__field*` a propósito: el Paso 2 pide nombre, correo,
 * teléfono y ciudad con exactamente la misma anatomía. Nacen aquí porque aquí
 * hacen falta, pero no son de esta sección.
 *
 * Un solo token nuevo en toda la sección, `--lp-error`, y vive arriba con los
 * demás: la foundation no tenía color de error porque hasta ahora nada fallaba.
 * ======================================================================== */

.landing-calculator {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* Mismo filo que abre Demo y Compare: marca la transición sin meter una banda
   de otro color que rompería el negro continuo de la página. */
.landing-calculator::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

.landing-calculator__grid {
  display: grid;
  gap: var(--lp-space-2xl);
}

/* --- Columna de copy ---------------------------------------------------- */

/* El bloque explicativo va dentro de una card, como la herramienta de al lado:
   suelto sobre el fondo se leía como un texto de relleno junto a un objeto
   importante, y las dos mitades de esta sección tienen el mismo rango.
   Hereda de `.landing-card` la superficie charcoal y el radio; lo que cambia
   aquí es el filo morado y el padding.
   NO lleva la sombra larga de la card del formulario: ésa es la diferencia de
   profundidad que mantiene a la herramienta como protagonista. */
.landing-calculator__copy {
  padding: clamp(1.5rem, 3vw, 2.5rem);
  border: 1px solid rgba(157, 107, 255, 0.4);
  box-shadow: 0 0 28px -10px rgba(157, 107, 255, 0.28), var(--lp-edge-light);
}

.landing-calculator__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* Un punto por debajo del titular de Compare (32-38px frente a 36-42px): la
   pregunta es larga y el protagonismo de esta sección lo tiene la herramienta.
 *
 * ENTERO EN MORADO NEÓN, no una palabra suelta. Aquí el titular ES el acento:
 * anuncia la herramienta que tiene al lado y comparte color con su borde y con
 * el CTA que la cierra, de modo que el morado dibuja el recorrido completo de
 * la sección.
 *
 * El glow es MÁS SUAVE que el del acento azul de Compare (0,25/0,35 frente a
 * 0,35/0,5) precisamente porque aquí brillan 74 caracteres y no dos palabras:
 * la misma intensidad sobre un titular entero emborrona la lectura. Sin
 * desplazamiento, así que el trazo de las letras queda intacto y solo se añade
 * luz alrededor. Radios en `em` para que la proporción aguante de 32 a 38px.
 *
 * Contraste: 5,2:1 sobre la superficie de la card, y a este tamaño cuenta como
 * texto grande, cuyo mínimo es 3:1. */
.landing-calculator__title {
  max-width: 22ch;
  margin: var(--lp-space-md) 0 0;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.375rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  color: var(--lp-purple-neon);
  text-shadow:
    0 0 0.15em rgba(157, 107, 255, 0.25),
    0 0 0.45em rgba(157, 107, 255, 0.35);
  text-wrap: balance;
}

/* Medida algo más larga que antes: dentro de una card, un párrafo que termina
   mucho antes que el borde deja la caja a medio llenar. */
.landing-calculator__text {
  max-width: 58ch;
  margin-top: var(--lp-space-md);
  text-wrap: pretty;
}

/* La nota de alcance va atenuada y pequeña, pero VISIBLE y junto al resto del
   copy, no escondida al pie de la sección. */
.landing-calculator__note {
  max-width: 58ch;
  margin-top: var(--lp-space-sm);
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

/* --- La card ------------------------------------------------------------ */

/* Más aire que una card corriente: dentro hay nueve controles y necesitan
   respirar para no leerse como un panel de administración.
   Mismo filo morado de 1px que la card de la izquierda —las dos pertenecen a
   la misma sección y deben leerse como pareja—, pero con la sombra larga y un
   resplandor algo mayor. Esa profundidad, y no un borde más grueso, es lo que
   la deja por delante: la herramienta manda, el bloque explicativo acompaña. */
.landing-calculator__card {
  padding: clamp(1.5rem, 3vw, 2.5rem);
  border: 1px solid rgba(157, 107, 255, 0.4);
  box-shadow:
    var(--lp-shadow-lg),
    0 0 36px -8px rgba(157, 107, 255, 0.35),
    var(--lp-edge-light);
}

.landing-calculator__step {
  margin: 0;
  font-size: var(--lp-text-label);
  font-weight: var(--lp-weight-semibold);
  letter-spacing: var(--lp-tracking-wide);
  text-transform: uppercase;
  color: var(--lp-text-muted);
}

.landing-calculator__card-title {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-heading-sm);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  color: var(--lp-text);
}

.landing-calculator__card-text {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
}

/* El aviso del Paso 2. Discreto pero no escondido: filo izquierdo cian para
   que el ojo lo registre como información de proceso y no como un párrafo
   más. Sin fondo ni caja, que lo convertirían en una alerta. */
.landing-calculator__heads-up {
  margin: var(--lp-space-md) 0 0;
  padding-left: var(--lp-space-sm);
  border-left: 2px solid rgba(34, 211, 238, 0.45);
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

/* Dos columnas dentro de la card en escritorio: seis preguntas en una sola
   columna harían una card larguísima y el formulario parecería más trabajo del
   que es. En móvil, una. */
.landing-calculator__fields {
  display: grid;
  gap: var(--lp-space-md);
}

/* --- Primitivas de campo (las reutilizará el Paso 2) -------------------- */

.landing-field {
  display: flex;
  flex-direction: column;
}

/* El label SIEMPRE visible y asociado con `for`. Nunca un placeholder
   haciendo su trabajo: desaparece al escribir y deja al usuario sin saber qué
   estaba respondiendo. */
.landing-field__label {
  margin-bottom: var(--lp-space-2xs);
  font-size: var(--lp-text-body-sm);
  font-weight: var(--lp-weight-semibold);
  line-height: 1.35;
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* Control hundido respecto a la card, igual que las jaulas de Compare: un
   campo de formulario se lee mejor como hueco que como relieve. */
.landing-field__control {
  width: 100%;
  min-height: 2.75rem;
  padding: 0 var(--lp-space-sm);
  border: 1px solid var(--lp-border-strong);
  border-radius: var(--lp-radius-md);
  background-color: rgba(0, 0, 0, 0.28);
  color: var(--lp-text);
  font-family: inherit;
  font-size: var(--lp-text-body);
  line-height: 1.2;
  /* Propiedades enumeradas: `transition: all` animaría también lo que no toca. */
  transition:
    border-color var(--lp-duration) var(--lp-ease-out),
    box-shadow var(--lp-duration) var(--lp-ease-out);
}

/* El `<select>` conserva su flecha nativa: quitarla con `appearance: none`
   obligaría a dibujar un icono propio, y aquí no queremos iconografía
   inventada. `color-scheme: dark` del `:root` ya hace que el desplegable del
   sistema se pinte oscuro. */
select.landing-field__control {
  height: 2.75rem;
  padding-right: var(--lp-space-2xs);
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .landing-field__control:hover {
    border-color: var(--lp-purple-neon);
  }
}

/* El foco de los controles va en MORADO, no en el azul del anillo general de
   la página: dentro de un formulario el morado es la señal de "esto está
   activo", igual que marca el CTA. Se mantiene el mismo grosor y el mismo
   `outline-offset` que el resto del sitio para no romper el patrón. */
.landing-field__control:focus-visible {
  outline: 2px solid var(--lp-purple-neon);
  outline-offset: 2px;
  border-color: var(--lp-purple-neon);
}

/* Sitio para la unidad dentro del propio control, no detrás. */
.landing-field__wrap {
  position: relative;
  display: flex;
}

.landing-field__control--unit {
  padding-right: 4.5rem;
}

.landing-field__unit {
  position: absolute;
  top: 50%;
  right: var(--lp-space-sm);
  transform: translateY(-50%);
  font-size: var(--lp-text-body-sm);
  color: var(--lp-text-muted);
  /* La unidad la anuncia `aria-describedby`; para el ratón no es un objetivo. */
  pointer-events: none;
}

.landing-field__help {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-body-sm);
  line-height: 1.45;
  color: var(--lp-text-muted);
  text-wrap: pretty;
}

/* --- Bloque opcional ---------------------------------------------------- */

/* `<details>` nativo: se abre y se cierra sin una línea de JavaScript, y si el
   JS de la página fallara seguiría funcionando. Conserva su marcador propio
   del navegador en vez de un icono dibujado a mano. */
.landing-calculator__optional {
  margin-top: var(--lp-space-lg);
  padding-top: var(--lp-space-md);
  border-top: 1px solid var(--lp-border);
}

.landing-calculator__summary {
  font-size: var(--lp-text-body);
  font-weight: var(--lp-weight-semibold);
  color: var(--lp-text-secondary);
  cursor: pointer;
  transition: color var(--lp-duration) var(--lp-ease-out);
}

.landing-calculator__summary:focus-visible {
  outline: 2px solid var(--lp-purple-neon);
  outline-offset: 2px;
  border-radius: var(--lp-radius-sm);
}

@media (hover: hover) and (pointer: fine) {
  .landing-calculator__summary:hover {
    color: var(--lp-text);
  }
}

.landing-calculator__optional-body {
  margin-top: var(--lp-space-md);
}

.landing-calculator__optional-text {
  margin: 0 0 var(--lp-space-md);
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
  text-wrap: pretty;
}

/* El `<fieldset>` trae borde y padding propios del navegador; se neutralizan y
   se sustituyen por un filo izquierdo, que agrupa sin dibujar otra caja dentro
   de la card. */
.landing-calculator__pair {
  margin: 0;
  padding: 0 0 0 var(--lp-space-sm);
  border: 0;
  border-left: 1px solid var(--lp-border-strong);
}

.landing-calculator__pair-legend {
  padding: 0;
  margin-bottom: var(--lp-space-2xs);
  font-size: var(--lp-text-label);
  font-weight: var(--lp-weight-semibold);
  letter-spacing: var(--lp-tracking-wide);
  text-transform: uppercase;
  color: var(--lp-text-muted);
}

.landing-calculator__margin {
  margin-top: var(--lp-space-md);
}

/* --- Acción ------------------------------------------------------------- */

/* Ancho completo dentro de la card: es la única acción del paso y no compite
   con nada. Hereda del CTA principal todo lo demás. */
.landing-calculator__submit {
  width: 100%;
  margin-top: var(--lp-space-lg);
}

/* ---------------------------------------------------------------------------
 * Escritorio
 * ------------------------------------------------------------------------ */

@media (min-width: 1024px) {
  /* 1fr / 1.45fr = 40,8% / 59,2%. El lado ancho es el de la herramienta, que
     es justo al revés que en el Hero: allí manda el texto. */
  .landing-calculator__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.45fr);
    column-gap: var(--lp-space-3xl);
    align-items: start;
  }

  /* La columna de copy se queda arriba mientras la card crece hacia abajo. */
  .landing-calculator__copy {
    position: sticky;
    top: var(--lp-space-2xl);
  }

  .landing-calculator__fields {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--lp-space-md);
  }
}

/* ---------------------------------------------------------------------------
 * Paso 2, errores y estados
 *
 * Todo lo de aquí abajo sirve al MISMO componente: la card de la derecha. No
 * hay una segunda card, ni una segunda base de campos, ni un wizard. El Paso 2
 * reutiliza `.landing-field*` y `.landing-calculator__fields` tal cual, y lo
 * único propio suyo es el bloque de consentimiento y la fila de botones.
 * ------------------------------------------------------------------------ */

/* El `hidden` del HTML tiene que ganarle a cualquier `display` que venga de
   una clase —el de `__alert` o el de `__consent`, sin ir más lejos—. La hoja
   no usa un solo `!important`, así que se resuelve por especificidad: dos
   selectores (0,2,0) contra la clase suelta (0,1,0). */
.landing-calculator [hidden] {
  display: none;
}

/* El panel NO declara `display` a propósito: así el `hidden` del atributo
   basta para esconderlo y no hace falta una clase de estado en paralelo
   diciendo lo mismo. Lo único que necesita es separar su primer grupo de
   campos de la cabecera del paso. */
.landing-calculator__panel > .landing-calculator__fields {
  margin-top: var(--lp-space-lg);
}

/* --- Error de un campo -------------------------------------------------- */

/* NO SOLO COLOR. Quien no distinga el rojo tiene otras tres señales: el
   mensaje, que antes no estaba; el filo de 2px a su izquierda; y el borde del
   control, que se dobla SIN mover un píxel del layout porque va por
   `box-shadow` interior y no por `border-width`. Y `aria-invalid` lo dice en
   voz alta para quien no esté mirando la pantalla. */
.landing-field__error {
  margin: var(--lp-space-2xs) 0 0;
  padding-left: var(--lp-space-2xs);
  border-left: 2px solid var(--lp-error);
  font-size: var(--lp-text-body-sm);
  font-weight: var(--lp-weight-semibold);
  line-height: 1.45;
  color: var(--lp-error);
  text-wrap: pretty;
}

.landing-field__control[aria-invalid="true"] {
  border-color: var(--lp-error);
  box-shadow: inset 0 0 0 1px var(--lp-error);
}

/* Con el campo en error, el anillo de foco también se pone rojo: el morado
   diría "aquí estás" y el rojo dice además "aquí está el problema". */
.landing-field__control[aria-invalid="true"]:focus-visible {
  outline-color: var(--lp-error);
  border-color: var(--lp-error);
}

/* --- Carga y fallo del consentimiento ----------------------------------- */

.landing-calculator__status {
  margin: var(--lp-space-sm) 0 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

.landing-calculator__alert {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--lp-space-sm);
  margin-top: var(--lp-space-sm);
  padding: var(--lp-space-sm);
  border: 1px solid var(--lp-error);
  border-radius: var(--lp-radius-md);
  background-color: rgba(255, 107, 107, 0.08);
}

.landing-calculator__alert-text {
  /* Con poco ancho, el botón se va a su propia línea en vez de estrujar el
     texto hasta partirlo en cuatro renglones. */
  flex: 1 1 14rem;
  margin: 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text);
}

/* --- Consentimiento ----------------------------------------------------- */

/* Ancho completo SIEMPRE, también en escritorio: se queda fuera de la rejilla
   de dos columnas porque es el texto que alguien va a aceptar, y meterlo en
   media card lo convertiría en letra pequeña. Hundido como los controles,
   para que se lea como parte del formulario y no como un aviso legal pegado
   al final. */
.landing-calculator__consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--lp-space-sm);
  align-items: start;
  margin-top: var(--lp-space-lg);
  padding: var(--lp-space-md);
  border: 1px solid var(--lp-border-strong);
  border-radius: var(--lp-radius-md);
  background-color: rgba(0, 0, 0, 0.28);
}

/* Casilla NATIVA. `accent-color` la pinta del morado de la acción sin
   esconderla detrás de un cuadrado dibujado a mano, que es justo como se
   pierden el foco, el alto contraste y el soporte de los lectores. */
.landing-calculator__checkbox {
  width: 1.125rem;
  height: 1.125rem;
  /* Alineada con la PRIMERA LÍNEA del texto, no con el centro del párrafo. */
  margin: 0.1875rem 0 0;
  accent-color: var(--lp-purple-neon);
  cursor: pointer;
}

.landing-calculator__checkbox:focus-visible {
  outline: 2px solid var(--lp-purple-neon);
  outline-offset: 2px;
}

.landing-calculator__consent-text {
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  cursor: pointer;
  text-wrap: pretty;
}

/* Enlace a la política, justo debajo de la casilla.

   FUERA del recuadro del consentimiento y fuera del `<label>`, a propósito y
   por dos motivos que apuntan al mismo sitio. Dentro del `<label>`, pulsar el
   enlace también marcaría la casilla: quien va a leer la política acabaría
   habiendo aceptado sin querer. Y dentro del recuadro se leería como parte del
   texto que se acepta, cuando es lo contrario — información que se ofrece
   ANTES de aceptar, no algo que se esté autorizando.

   Alineado con el texto del consentimiento, no con la casilla: el `padding`
   del recuadro más el ancho de la casilla más su hueco. Se escribe con los
   mismos tokens que lo generan, así que si el recuadro cambia, esto lo sigue.

   Azul y subrayado, como los enlaces del cuerpo de la política. Es el único
   enlace del formulario y tiene que encontrarse sin buscarlo. */
.landing-calculator__privacy {
  margin: var(--lp-space-2xs) 0 0;
  padding-left: calc(var(--lp-space-md) + 1.125rem + var(--lp-space-sm));
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
}

.landing-calculator__privacy-link {
  color: var(--lp-blue);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  transition: color var(--lp-duration) var(--lp-ease-out);
}

.landing-calculator__privacy-link:hover {
  color: var(--lp-text);
}

/* --- Acciones del Paso 2 ------------------------------------------------ */

/* "Volver" ocupa lo que mide y el CTA se queda con el resto, igual de ancho
   que el "Continuar" del Paso 1. Si los dos no caben —pantallas de 320px—,
   el primario se va a su propia línea en vez de desbordar la card. */
.landing-calculator__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lp-space-sm);
  margin-top: var(--lp-space-lg);
}

.landing-calculator__actions .landing-button--secondary {
  flex: 0 1 auto;
}

.landing-calculator__actions .landing-button--primary {
  flex: 1 1 12rem;
}

/* --- Cambio de paso ----------------------------------------------------- */

/* El panel que entra reutiliza la MISMA animación que el resto de la página;
   no hay un segundo `@keyframes` para esto. Va dentro de `no-preference`: con
   movimiento reducido el cambio es instantáneo y no se pierde información,
   porque lo que avisa de que cambió el paso es el foco, no el desplazamiento. */
@media (prefers-reduced-motion: no-preference) {
  .landing-calculator__panel.is-entering {
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
  }
}

/* ===========================================================================
 * 20. Resultados
 * ===========================================================================
 *
 * La sección más sobria de la página, y a propósito: aquí ya no hay que
 * convencer a nadie, hay que dejar leer cuatro cifras. Por eso no lleva
 * iconos, ni gráficas, ni medidores, ni una segunda gama de colores. Cards
 * oscuras sobre el mismo negro, mucho aire y números grandes.
 *
 * UN SOLO ACENTO. El morado se lo lleva la métrica que da nombre a la sección
 * —las horas al mes— y ninguna otra. Pintar las cuatro de colores distintos
 * convertiría un informe en un salpicadero, y las cuatro pesarían igual, que
 * es justo lo contrario de lo que hace falta para escanearla de un vistazo.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-results {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* El mismo filo que abre Demo, Compare y la Calculadora. */
.landing-results::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

/* La sección nace oculta y dos de sus cards también. `hidden` tiene que ganar
   al `display` que traen de su clase: se resuelve por especificidad, sin un
   `!important` que esta hoja no usa en ningún sitio. */
.landing-results[hidden],
.landing-results [hidden] {
  display: none;
}

/* --- Cabecera ----------------------------------------------------------- */

/* Centrada, como la de Compare: encima de una rejilla, una cabecera alineada a
   la izquierda deja el bloque descolgado. */
.landing-results__head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}

.landing-results__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

.landing-results__title {
  max-width: 26ch;
  margin: var(--lp-space-md) auto 0;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.375rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-wrap: balance;
}

.landing-results__note {
  margin: var(--lp-space-sm) auto 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

/* --- Rejilla ------------------------------------------------------------ */

.landing-results__grid {
  display: grid;
  gap: var(--lp-space-md);
  margin-top: var(--lp-space-2xl);
}

.landing-results__card {
  display: flex;
  flex-direction: column;
}

/* La card de cabeza: más aire y el mismo filo morado de la calculadora, para
   que se lea como continuación de lo que se acaba de rellenar. */
.landing-results__card--lead {
  padding: clamp(1.5rem, 3vw, 2.5rem);
  border-color: rgba(157, 107, 255, 0.4);
  box-shadow:
    var(--lp-shadow-md),
    0 0 36px -8px rgba(157, 107, 255, 0.35),
    var(--lp-edge-light);
}

/* --- Cifras ------------------------------------------------------------- */

/* `tabular-nums`: los dígitos ocupan todos lo mismo, así que una cifra no
   baila respecto a la de al lado ni al volver a renderizarse. */
.landing-results__value {
  margin: 0;
  font-size: var(--lp-text-heading-md);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-tight);
  letter-spacing: var(--lp-tracking-tight);
  color: var(--lp-text);
  font-variant-numeric: tabular-nums;
}

.landing-results__value--lead {
  font-size: clamp(3rem, 2.2rem + 3.4vw, 4.5rem);
  color: var(--lp-purple-neon);
  text-shadow:
    0 0 0.15em rgba(157, 107, 255, 0.25),
    0 0 0.45em rgba(157, 107, 255, 0.35);
}

.landing-results__metric {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* El dato del año va después de la etiqueta y atenuado: acompaña a la cifra
   grande, no compite con ella. */
.landing-results__aside {
  margin: var(--lp-space-sm) 0 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

.landing-results__currency {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
}

/* Filo cian a la izquierda, igual que el aviso del Paso 2: marca "esto es
   información sobre el dato" sin convertirse en una alerta. */
.landing-results__disclaimer {
  margin: var(--lp-space-sm) 0 0;
  padding-left: var(--lp-space-sm);
  border-left: 2px solid rgba(34, 211, 238, 0.45);
  font-size: var(--lp-text-body-sm);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-muted);
  text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
 * Tablet y escritorio
 *
 * DOS columnas, no tres: con tres, los números tendrían que encoger y la
 * sección entera perdería lo único que la hace escaneable. La card de cabeza y
 * la de demanda ocupan la fila entera —la primera por peso, la segunda porque
 * su aclaración necesita renglones largos para no partirse en cinco líneas—,
 * así que las filas quedan: horas / [no atendidas · hora punta] / demanda /
 * [opcionales].
 * ------------------------------------------------------------------------ */

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

  .landing-results__card--lead,
  .landing-results__card--wide {
    grid-column: 1 / -1;
  }
}

/* --- Fragmento destacado del titular ------------------------------------ */

/* AZUL, y no el morado de la acción: lo que se resalta aquí es el problema que
   describe la frase, no algo que haya que pulsar. El tono es el que la hoja
   reserva para LEERSE —6.2:1 sobre el fondo—, así que el glow lo acompaña sin
   tener que sostener la legibilidad él solo. */
.landing-results__accent {
  color: var(--lp-blue);
  text-shadow:
    0 0 0.15em rgba(47, 141, 255, 0.25),
    0 0 0.45em rgba(47, 141, 255, 0.35);
}

/* --- CTA de cierre ------------------------------------------------------- */

.landing-results__actions {
  display: flex;
  justify-content: center;
  /* Separación de sección, no de párrafo: el botón tiene que leerse como el
     final del informe y no como una card más pegada a la rejilla. */
  margin-top: var(--lp-space-2xl);
}

/* Hereda TODO el aspecto del CTA principal —degradado morado, glow y sus
   estados— y solo cambia de talla: es el cierre de la sección más importante
   de la página. El `box-shadow` NO se toca a propósito: el hover del botón
   principal ya sube el glow, y subirlo también en reposo dejaría los dos
   estados iguales.

   Ancho completo hasta un tope: en el móvil ocupa el gutter y es cómodo de
   tocar; en escritorio se queda en 22rem y centrado, con presencia pero sin
   convertirse en una barra. */
.landing-results__cta {
  width: 100%;
  max-width: 22rem;
  min-height: 3.25rem;
  padding-inline: var(--lp-space-xl);
  font-size: var(--lp-text-body-lg);
}

/* La sección no entra por scroll —aparece porque alguien pulsó un botón—, así
   que reutiliza la animación de la página una sola vez, al desvelarse. */
@media (prefers-reduced-motion: no-preference) {
  .landing-results.is-entering {
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
  }
}

/* ===========================================================================
 * 21. Piloto
 * ===========================================================================
 *
 * La banda tipográfica de la página, y la única sección sin cards. Encima tiene
 * tres rejillas seguidas —Compare, Calculator y Results—, así que lo que rompe
 * el ritmo aquí no es otra composición de cajas: es quitarlas. Quedan numerales,
 * contornos de 1px y aire — marcos sin relleno, que dibujan el módulo sin
 * convertirlo en una superficie.
 *
 * CIAN. El morado está reservado a la acción y en la mitad inferior ya aparece
 * catorce veces entre CTA, Calculadora y Resultados. El cian es la señal del
 * producto —11:1 sobre el fondo— y no se usa como acento estructural desde el
 * diagrama del Hero.
 *
 * NO REPITE EL DIAGRAMA DEL HERO, aunque los dos cuenten cuatro pasos y los dos
 * usen un círculo: aquel es vertical, con iconos dentro del nodo, aro cian y un
 * raíl que los encadena; este es horizontal, con el número dentro de un círculo
 * gris, sin icono, sin conector y sin relleno. Mismo recurso, dos géneros
 * visuales distintos.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-pilot {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* El mismo filo que abre Demo, Compare, la Calculadora y Resultados. */
.landing-pilot::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

/* --- Cabecera ----------------------------------------------------------- */

.landing-pilot__head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}

.landing-pilot__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* 30ch y no 26ch como Compare: este titular tiene 89 caracteres y con la medida
   de allí caía en cinco líneas. */
.landing-pilot__title {
  max-width: 30ch;
  margin: var(--lp-space-md) auto 0;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.375rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-wrap: balance;
}

/* El fragmento destacado del titular.

   MORADO SOBRE UNA SECCIÓN CIAN, y no es un descuido: el cian es la estructura
   —el marco de los pasos, los filos, el ancla— y el morado se queda para lo que
   se afirma. Al separar los dos trabajos, ninguno de los dos compite.

   EL "OSCURO" SALE DEL HALO, NO DEL TRAZO. Bajar el morado a los tonos de
   relleno del CTA daría 3.5:1 y dejaría el titular al filo del mínimo; en su
   lugar las letras se quedan en `--lp-purple-neon` —5.8:1 sobre el negro— y el
   halo usa el morado profundo del relleno. Así el conjunto se lee denso y
   tecnológico sin pagarlo en legibilidad.

   Dos capas sin desplazamiento, como en Compare: una corta para el núcleo y
   otra ancha para el resplandor, con los radios en `em` para que el halo guarde
   la proporción a cualquier tamaño del `clamp`. */
.landing-pilot__accent {
  color: var(--lp-purple-neon);
  text-shadow:
    0 0 0.15em rgba(112, 56, 245, 0.45),
    0 0 0.5em rgba(112, 56, 245, 0.6);
}

/* --- Ancla -------------------------------------------------------------- */

/* Alineada a la IZQUIERDA contra una cabecera centrada: ese cambio de eje es lo
   que anuncia que aquí empieza el método. La regla sale del texto y se apaga
   hacia el borde del contenido, así que marca un comienzo sin cerrar una caja. */
.landing-pilot__anchor {
  display: flex;
  align-items: center;
  gap: var(--lp-space-md);
  margin-top: var(--lp-space-2xl);
}

.landing-pilot__anchor::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, rgba(34, 211, 238, 0.5), transparent);
}

.landing-pilot__anchor-text {
  margin: 0;
  font-size: clamp(2rem, 1.4rem + 2vw, 2.875rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-tight);
  letter-spacing: var(--lp-tracking-tight);
  color: var(--lp-cian);
  /* Una sola capa y baja: el brillo acompaña al rótulo, no lo envuelve. */
  text-shadow: 0 0 0.4em rgba(34, 211, 238, 0.25);
  text-wrap: balance;
}

/* --- Los cuatro pasos --------------------------------------------------- */

.landing-pilot__steps {
  margin: var(--lp-space-xl) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  /* Con marco propio, cada paso es un módulo y necesita aire alrededor: el
     hueco sustituye a los filos de 1px que antes hacían de separador. */
  gap: var(--lp-space-md);
}

/* MÓVIL: el círculo y el título comparten la primera línea —"01 Adaptamos"— y
   la explicación cae debajo ocupando el ancho entero. Es lo que lo separa de la
   escalera vertical del Hero, donde el texto siempre va al lado del nodo.

   EL MARCO ES UNA LÍNEA, NO UNA CARD. Sin relleno: el fondo sigue siendo el
   negro de la página, así que lo único que se añade es el contorno. Un
   `background` aquí convertiría los cuatro pasos en cuatro superficies y la
   sección volvería a ser una rejilla de cajas, que es justo lo que no es.

   El cian va al 50%: por debajo de ese valor el borde compuesto sobre el fondo
   se queda en 2.5:1 y deja de cumplir el mínimo de 3:1 para un elemento
   gráfico. A 0.5 da 3.4:1 y sigue leyéndose como un hilo, no como un reborde. */
.landing-pilot__step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--lp-space-sm);
  row-gap: var(--lp-space-xs);
  align-items: center;
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
  border: 1px solid rgba(34, 211, 238, 0.5);
  border-radius: var(--lp-radius-md);
  /* Un solo halo, corto y por dentro del borde: marca el módulo sin encender
     cuatro focos en la misma fila. */
  box-shadow: 0 0 24px -14px rgba(34, 211, 238, 0.55), var(--lp-edge-light);
}

/* Círculo GRIS, y a propósito: el color de la sección ya lo pone el marco, y
   un numeral cian dentro de un borde cian serían dos acentos peleándose en
   cuatro centímetros. En gris, el círculo hace de contrapunto neutro y el que
   brilla sigue siendo el contorno.

   `inline-flex` y no `block`: dentro de una columna el bloque se estiraría al
   ancho disponible y el círculo dejaría de ser un círculo. 44px es además el
   objetivo cómodo que la hoja usa para todo lo pulsable, así que la pieza
   encaja con el resto sin inventar una medida nueva. */
.landing-pilot__number {
  grid-column: 1;
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0;
  border: 1px solid var(--lp-border-strong);
  border-radius: 50%;
  background-color: var(--lp-surface-hover);
  font-size: var(--lp-text-body);
  font-weight: var(--lp-weight-semibold);
  line-height: 1;
  color: var(--lp-text);
  font-variant-numeric: tabular-nums;
  /* Filo superior de luz, el mismo de las cards. NO es un glow: no hay halo
     de color, solo el borde interior que da volumen. */
  box-shadow: var(--lp-edge-light);
}

.landing-pilot__step-title {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  font-size: var(--lp-text-heading-sm);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-snug);
  color: var(--lp-text);
}

.landing-pilot__step-text {
  grid-column: 1 / -1;
  grid-row: 2;
  margin: 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* --- Qué medimos -------------------------------------------------------- */

.landing-pilot__measure {
  margin-top: var(--lp-space-2xl);
}

/* Etiqueta estructural en CÁPSULA GRIS, y no la píldora cian que abre la
   sección: aquella lleva contorno de color y halo, y dos de esas en la misma
   pantalla harían parecer que la sección empieza tres veces. Esta usa los
   mismos grises que el círculo de los pasos —fondo `surface-hover`, contorno
   `border-strong`— así que se lee como un rótulo interno, no como un comienzo.

   El texto se queda en cian: 9.5:1 sobre ese gris, de sobra para un rótulo de
   12px en mayúsculas. Ningún halo de color; el `edge-light` es el filo interior
   que ya traen las cards y el círculo, no un glow.

   6px de radio y no la cápsula de 999px de la píldora: redondeada pero con
   esquina reconocible, que es lo que la separa de un botón.

   `inline-flex` es lo que hace que mida lo que mide el texto. Sin eso, un
   `<p>` ocuparía el ancho entero de la columna y en móvil se convertiría en una
   barra de lado a lado. */
.landing-pilot__measure-label,
.landing-pilot__close-label {
  display: inline-flex;
  align-items: center;
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--lp-border-strong);
  border-radius: var(--lp-radius-sm);
  background-color: var(--lp-surface-hover);
  color: var(--lp-cian);
  box-shadow: var(--lp-edge-light);
}

.landing-pilot__metrics {
  margin: var(--lp-space-md) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--lp-space-md);
}

/* LA MISMA TARJETA QUE LOS CUATRO PASOS DE ARRIBA, un punto más contenida.

   Idéntico borde —`rgba(34, 211, 238, 0.5)`, el mínimo que cumple 3:1 sobre el
   fondo— e idéntico radio, porque estas métricas pertenecen a la misma sección
   y al mismo producto que los pasos. Lo que cambia es la dosis: el halo baja de
   `0 0 24px -14px / 0.55` a `0 0 18px -14px / 0.4` y el relleno se acorta.
   Son SIETE tarjetas frente a cuatro, y con el brillo de los pasos la sección
   se convertiría en una parrilla de focos. El borde es el protagonista; el halo
   solo evita que el contorno se vea recortado contra el negro.

   Sin fondo propio, como los pasos: lo que dibuja el módulo es la línea.

   MÓVIL Y TABLET: icono y nombre en la misma fila. Es la anatomía que ya usan
   los pasos de arriba en esos anchos —"01 Adaptamos"— y mantiene la tarjeta
   baja, que es lo que hace que siete quepan sin convertir la sección en un
   scroll. En escritorio pasan a apilarse. */
.landing-pilot__metric {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--lp-space-sm);
  align-items: center;
  padding: clamp(1rem, 2vw, 1.25rem);
  border: 1px solid rgba(34, 211, 238, 0.5);
  border-radius: var(--lp-radius-md);
  box-shadow: 0 0 18px -14px rgba(34, 211, 238, 0.4), var(--lp-edge-light);
}

/* La MISMA pastilla que el círculo de los numerales: gris sobre gris, filo de
   luz interior y ni un halo de color. Lo único que cambia es lo que lleva
   dentro —un trazo en vez de una cifra— y que ese trazo va en cian, que es el
   color con el que esta página habla de sistema y de medición.

   `inline-flex` y medida fija para que en escritorio, dentro de una columna,
   no se estire y deje de ser un círculo. */
.landing-pilot__metric-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--lp-border-strong);
  border-radius: 50%;
  background-color: var(--lp-surface-hover);
  color: var(--lp-cian);
  box-shadow: var(--lp-edge-light);
}

.landing-pilot__metric-icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* Semibold y en blanco: por encima del texto secundario que tenían como lista,
   y por debajo del `heading-sm` de los títulos de paso. Son nombres de
   variable, no titulares. */
.landing-pilot__metric-name {
  font-size: var(--lp-text-body);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  color: var(--lp-text);
  text-wrap: pretty;
}

/* --- Cierre ------------------------------------------------------------- */

/* Lo más neutro de la sección, y a propósito: aquí se habla de ROI. Sin card,
   sin fondo, sin glow y sin destacar una sola palabra. El filo cian es el mismo
   dispositivo del aviso del Paso 2 y del disclaimer de Resultados, que en esta
   página significa "precisión sobre el dato". */
.landing-pilot__close {
  max-width: 62ch;
  margin-top: var(--lp-space-2xl);
  padding-left: var(--lp-space-sm);
  border-left: 2px solid rgba(34, 211, 238, 0.45);
}

.landing-pilot__close-text {
  margin: var(--lp-space-2xs) 0 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
 * Tablet
 * ------------------------------------------------------------------------ */

@media (min-width: 768px) {
  /* Dos columnas. Siete no se reparten en pares, así que la séptima ocupa la
     fila entera en vez de quedarse huérfana a un lado: con el icono y el nombre
     en línea, una tarjeta ancha se lee como una fila más, no como un hueco. */
  .landing-pilot__metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .landing-pilot__metric:nth-child(7) {
    grid-column: 1 / -1;
  }
}

/* ---------------------------------------------------------------------------
 * Escritorio
 * ------------------------------------------------------------------------ */

@media (min-width: 1024px) {
  /* Cuatro columnas y el filo pasa de horizontal a vertical: el recorrido se
     lee de izquierda a derecha, como una línea de tiempo, sin dibujar ninguna. */
  .landing-pilot__steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  /* Una columna dentro de cada módulo: el círculo pasa a su propia línea y
     debajo caen título y texto. El marco ya separa, así que aquí no queda
     ningún filo que dibujar. */
  .landing-pilot__step {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--lp-space-sm);
    /* `start` y no `center`: con una sola columna, centrar dejaría el texto
       corto flotando en mitad del módulo en vez de alineado arriba. */
    align-items: start;
  }

  .landing-pilot__number,
  .landing-pilot__step-title,
  .landing-pilot__step-text {
    grid-column: 1;
    grid-row: auto;
  }

  /* CUATRO COLUMNAS SOBRE UNA REJILLA DE OCHO, y no cuatro columnas a secas.
     El motivo es que son siete tarjetas: en una rejilla de cuatro, la segunda
     fila se queda con un hueco pegado al margen derecho. Con ocho columnas y
     tarjetas de dos, basta arrancar la quinta en la columna 2 para que las tres
     de abajo queden centradas, con una columna libre a cada lado. Sin anchos
     fijos y sin tarjetas de tamaños distintos. */
  .landing-pilot__metrics {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }

  .landing-pilot__metric {
    grid-column: span 2;
    /* Aquí el icono sube encima del nombre, como los pasos de al lado. */
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--lp-space-sm);
    align-items: start;
  }

  .landing-pilot__metric:nth-child(5) {
    grid-column: 2 / span 2;
  }

  /* Deshace el ancho completo que la séptima tiene desde `md`: aquí vuelve a
     ser una tarjeta normal y cierra la fila centrada. */
  .landing-pilot__metric:nth-child(7) {
    grid-column: span 2;
  }
}

/* ---------------------------------------------------------------------------
 * Entrada al entrar en viewport
 *
 * SOLO LOS CUATRO PASOS. La cabecera, el ancla, la lista de medición y el
 * cierre no se animan: son contenido, y el de ROI especialmente no debe
 * "aparecer" — un texto delicado que se presenta con efecto se lee como
 * argumento de venta.
 *
 * Mismo planteamiento que Demo y Compare, con clases propias para no tocar las
 * suyas: el HTML nace visible y solo si `landing.js` añade `js-pilot-reveal` el
 * CSS se atreve a esconder. Sin JS, con JS roto o con movimiento reducido,
 * estas reglas no existen y los cuatro pasos se leen enteros.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  .landing-pilot.js-pilot-reveal [data-pilot-reveal] {
    opacity: 0;
  }

  .landing-pilot.js-pilot-reveal.is-revealed [data-pilot-reveal] {
    opacity: 1;
    animation: landing-reveal var(--lp-duration-reveal) var(--lp-ease-out) both;
    animation-delay: calc(var(--reveal-index, 0) * var(--lp-stagger));
  }
}

/* ===========================================================================
 * 22. Preguntas frecuentes
 * ===========================================================================
 *
 * La sección MÁS ESTRECHA de la página, y a propósito: aquí solo se lee. El
 * contenedor sigue midiendo 1200px, pero la columna de preguntas se queda en
 * 48rem porque una respuesta de 1200px de ancho obliga a barrer la cabeza de un
 * lado a otro en cada renglón. La página se va cerrando al final.
 *
 * SIN JAVASCRIPT. Cinco `<details>` nativos: abrir, cerrar, el teclado y el
 * estado que se anuncia salen del elemento. Lo único que pone el CSS es el
 * aspecto — y un indicador que ni siquiera es texto.
 *
 * UN SOLO ACENTO Y SOLO AL ABRIR. En reposo, gris; abierta, morado discreto.
 * La información es lo que manda, así que cinco módulos con halo encendido
 * habrían competido justo con lo que hay que leer.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-faq {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* El mismo filo que abre Demo, Compare, la Calculadora, Resultados y Piloto. */
.landing-faq::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

/* --- Cabecera ----------------------------------------------------------- */

.landing-faq__head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}

.landing-faq__label {
  display: inline-flex;
  align-items: center;
  padding: 0.4375rem 0.875rem;
  border: 1px solid rgba(34, 211, 238, 0.55);
  border-radius: var(--lp-radius-pill);
  background-color: rgba(34, 211, 238, 0.12);
  color: var(--lp-cian);
  box-shadow: var(--lp-glow-cian), var(--lp-edge-light);
}

/* Sin fragmento coloreado: es el único titular de sección sin acento, y es
   deliberado. Cinco seguidos con una palabra encendida convierten el recurso
   en un tic; aquí el trabajo del titular es anunciar, no subrayar. */
.landing-faq__title {
  max-width: 24ch;
  margin: var(--lp-space-md) auto 0;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.375rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-wrap: balance;
}

/* --- La lista ----------------------------------------------------------- */

.landing-faq__list {
  display: grid;
  gap: var(--lp-space-sm);
  max-width: 48rem;
  margin: var(--lp-space-2xl) auto 0;
}

/* Módulo oscuro con filo gris en reposo. El relleno es el mismo \`surface\` de
   las cards: sobre el negro la diferencia es mínima, y lo que dibuja el módulo
   es el borde. Eso basta para que se lea como una pieza pulsable sin encender
   nada. */
.landing-faq__item {
  border: 1px solid var(--lp-border);
  border-radius: var(--lp-radius-md);
  background-color: var(--lp-surface);
  /* Enumeradas: \`transition: all\` animaría también el layout al abrirse. */
  transition:
    border-color var(--lp-duration) var(--lp-ease-out),
    background-color var(--lp-duration) var(--lp-ease-out);
}

/* ABIERTA: el borde pasa a morado y la superficie sube un punto. Dos señales,
   ninguna de ellas un halo. El morado es el de la acción en toda la página, y
   aquí marca "esto es lo que estás mirando" sin convertir la respuesta en una
   card de neón. */
.landing-faq__item[open] {
  border-color: rgba(157, 107, 255, 0.45);
  background-color: var(--lp-surface-hover);
}

@media (hover: hover) and (pointer: fine) {
  .landing-faq__item:hover {
    border-color: var(--lp-border-strong);
  }

  .landing-faq__item[open]:hover {
    border-color: rgba(157, 107, 255, 0.6);
  }
}

/* --- La pregunta -------------------------------------------------------- */

/* \`list-style: none\` va SOLO aquí, no en \`summary\` a secas: el \`<details>\` de
   los campos opcionales de la Calculadora conserva su marcador nativo a
   propósito y no debe perderlo. */
.landing-faq__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--lp-space-md);
  padding: clamp(1rem, 2vw, 1.25rem) clamp(1rem, 2.5vw, 1.5rem);
  list-style: none;
  font-size: var(--lp-text-body-lg);
  font-weight: var(--lp-weight-semibold);
  line-height: var(--lp-leading-heading);
  color: var(--lp-text);
  cursor: pointer;
  text-wrap: pretty;
  /* Toda la fila es el objetivo: en móvil se toca en cualquier punto, no solo
     sobre las letras. */
  -webkit-tap-highlight-color: transparent;
}

/* Safari todavía dibuja su triángulo con el prefijo. */
.landing-faq__summary::-webkit-details-marker {
  display: none;
}

/* EL INDICADOR, DIBUJADO CON DOS DEGRADADOS sobre un \`content\` vacío.
   Un \`content: "+"\` sería texto y los lectores de pantalla lo recitarían antes
   de cada pregunta, cuando el estado abierto/cerrado ya lo anuncia el propio
   \`<summary>\`. Con las barras pintadas de fondo, el símbolo es lo que tiene que
   ser: decoración.

   Barra horizontal + barra vertical = "+". Al abrir, la vertical se va a cero y
   queda "−". \`flex: none\` para que la pregunta larga lo empuje pero no lo
   estruje. */
.landing-faq__summary::after {
  content: "";
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-size: 100% 1.5px, 1.5px 100%;
  background-position: center, center;
  background-repeat: no-repeat;
  color: var(--lp-text-muted);
}

.landing-faq__item[open] .landing-faq__summary::after {
  background-size: 100% 1.5px, 1.5px 0;
  color: var(--lp-purple-neon);
}

/* --- La respuesta ------------------------------------------------------- */

/* Filo de separación dentro del módulo: la respuesta empieza claramente donde
   termina la pregunta, sin necesidad de un segundo bloque ni de más color. */
.landing-faq__answer {
  padding: var(--lp-space-sm) clamp(1rem, 2.5vw, 1.5rem) clamp(1rem, 2vw, 1.25rem);
  border-top: 1px solid var(--lp-border);
}

.landing-faq__text {
  max-width: 68ch;
  margin: 0;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
 * Movimiento
 *
 * El cambio de color va SIEMPRE: con movimiento reducido lo que sobra es el
 * desplazamiento, no la transición que explica qué acaba de cambiar —el mismo
 * criterio que el resto de la hoja—. Lo que sí se guarda es el gesto del
 * indicador, que es una forma cambiando de tamaño.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  .landing-faq__summary::after {
    transition:
      background-size var(--lp-duration) var(--lp-ease-out),
      color var(--lp-duration) var(--lp-ease-out);
  }
}

/* ===========================================================================
 * 23. Cierre comercial
 * ===========================================================================
 *
 * El final de la página, y la única sección sin superficie NI estructura: ni
 * card, ni rejilla, ni filos internos. Encima quedan tres secciones con
 * contenedor propio —cards en Resultados, marcos en Piloto, módulos en la
 * FAQ—; aquí lo que cierra es el vacío alrededor del texto.
 *
 * Tampoco lleva píldora de sección, a diferencia de las seis anteriores: el
 * titular es el mensaje y una etiqueta encima solo lo categorizaría.
 *
 * UN SOLO ACENTO: el morado del CTA primario. Nada más en la sección lleva
 * color, así que el ojo va donde tiene que ir.
 *
 * NO SE PARECE AL CTA FLOTANTE, y es deliberado: aquel tiene degradado a negro
 * y marco neón porque flota sobre cualquier fondo; este es el `--primary` de
 * siempre, que es lo que en esta página ya significa "acción".
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-cta {
  position: relative;
  padding-block: var(--lp-space-section);
  scroll-margin-top: var(--lp-space-lg);
}

/* El mismo filo que abre las cinco secciones anteriores. */
.landing-cta::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--lp-border-strong) 30%,
    var(--lp-border-strong) 70%,
    transparent
  );
}

.landing-cta__inner {
  text-align: center;
}

/* UN PUNTO POR ENCIMA del resto de titulares de sección (que llegan a 2.375rem)
   y bien por debajo del H1 del Hero (3.75rem): es lo que lo sitúa como cierre
   sin convertirlo en un segundo comienzo.

   28ch deja el titular en tres líneas en escritorio. Medida de display, no de
   lectura: más ancho obligaría a barrer la cabeza en cada renglón.

   EL CLAMP BAJA SOLO POR ABAJO. El suelo pasa de 2.25rem a 2.0625rem y la
   pendiente sube de 2.2vw a 2.4vw para compensar: en un móvil de 360px el
   titular pierde 3px y deja de comerse tantas líneas, en tablet queda en
   42.4px —siete centésimas de píxel por debajo de lo que ya medía— y de 1024px
   en adelante sigue tocando el mismo techo de 2.875rem. Escritorio intacto,
   sin gastar un breakpoint en ello. */
.landing-cta__title {
  max-width: 28ch;
  margin: 0 auto;
  font-size: clamp(2.0625rem, 1.5rem + 2.4vw, 2.875rem);
  font-weight: var(--lp-weight-bold);
  line-height: var(--lp-leading-heading);
  letter-spacing: var(--lp-tracking-tight);
  text-wrap: balance;
}

.landing-cta__text {
  max-width: 54ch;
  margin: var(--lp-space-md) auto 0;
  font-size: var(--lp-text-body-lg);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
  text-wrap: pretty;
}

/* --- Acciones ----------------------------------------------------------- */

/* `xl` y no `lg` de separación: el salto entre leer y actuar es el único sitio
   de la sección donde el aire tiene que notarse. */
.landing-cta__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--lp-space-sm);
  margin-top: var(--lp-space-xl);
}

/* En móvil los dos ocupan el ancho disponible —hasta un tope— para que la
   pareja no quede descuadrada: uno corto centrado y otro largo debajo. A
   partir de `md` cada uno vuelve a medir lo que mide su rótulo. */
.landing-cta__actions .landing-button {
  width: 100%;
  max-width: 24rem;
}

/* El primario, un punto más grande que un botón normal: es la acción del
   cierre de la página. Mismo relleno morado que el resto de primarios; lo
   único que cambia es la talla. */
.landing-cta__primary {
  min-height: 3.25rem;
  padding-inline: var(--lp-space-xl);
  font-size: var(--lp-text-body-lg);
}

/* EL SECUNDARIO TIENE QUE PODER PARTIRSE. Su rótulo son 57 caracteres y
   `.landing-button` trae `white-space: nowrap`: tal cual, el botón mediría más
   de 500px y desbordaría cualquier móvil. Aquí se le permite envolver, se
   centra el texto y se recupera el interlineado, que el botón base aplasta a 1
   porque da por hecho una sola línea.

   Y PESA MENOS QUE EL PRIMARIO, no solo en relleno. Con el cuerpo de 16px del
   botón corriente, 57 caracteres medían unos 520px y el secundario acababa
   siendo la pieza más ancha de la sección: dominaba por tamaño justo lo que
   tenía que acompañar. Bajarlo al cuerpo pequeño y recortar el relleno lateral
   lo deja en unos 445px y abre la distancia tipográfica con el primario, que
   va de 17 a 20px. Sigue en semibold y sigue midiendo 44px de alto, así que no
   se vuelve un enlace tímido: cambia de rango, no de categoría.

   1.75 de interlineado, algo más que el 1.6 del cuerpo: cuando en móvil parte
   en dos líneas, esas dos líneas necesitan más aire dentro del botón que un
   párrafo dentro de una columna. En escritorio va en una sola línea, así que
   la altura la sigue fijando el `min-height` y el cambio no se nota. */
.landing-cta__secondary {
  padding-block: var(--lp-space-2xs);
  padding-inline: var(--lp-space-sm);
  font-size: var(--lp-text-body-sm);
  white-space: normal;
  line-height: 1.75;
  text-align: center;
  text-wrap: balance;
}

/* ---------------------------------------------------------------------------
 * Tablet y escritorio
 * ------------------------------------------------------------------------ */

@media (min-width: 768px) {
  .landing-cta__actions .landing-button {
    width: auto;
    max-width: none;
  }
}

/* El hueco para el CTA flotante ya NO se reserva aquí: desde que existe el pie
   de página, la última sección de la página es el pie, y es él quien tiene que
   dejar sitio al botón fijo. Ver `.landing-footer--con-cta-flotante` en la
   sección 24. Esta sección vuelve a su `padding-block` normal. */

/* ===========================================================================
 * 24. Pie de página
 * ===========================================================================
 *
 * Lo contrario del cierre comercial que tiene encima, y a propósito. Aquel es
 * el último argumento de venta; esto es el rótulo de la puerta: quién firma la
 * página, dónde está la política y a qué dirección se escribe.
 *
 * NADA DE LO QUE USA EL RESTO DE LA PÁGINA. Sin card, sin degradado, sin glow,
 * sin píldora de sección, sin acento de color y sin entrada escalonada. Un
 * filo de 1px, texto pequeño en gris y aire. Si compitiera con el CTA de
 * arriba estaría haciendo el trabajo de otro.
 *
 * El filo es `--lp-border` y no `--lp-border-strong`: las secciones se separan
 * entre ellas con el filo fuerte, y el pie no es otra sección más — es lo que
 * queda debajo de todas.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

.landing-footer {
  border-top: 1px solid var(--lp-border);
  padding-block: var(--lp-space-xl);
}

/* En columna hasta `md` y en fila a partir de ahí. No hay rejilla: son tres
   bloques cortos y `flex` con `wrap` los coloca sin inventar columnas que en
   móvil habría que deshacer. */
.landing-footer__inner {
  display: flex;
  flex-direction: column;
  gap: var(--lp-space-md);
  align-items: flex-start;
}

/* Reutiliza `.landing-label` —versalita, espaciada— y solo sube el color: la
   firma es lo único del pie que debe leerse antes que el resto. */
.landing-footer__brand {
  color: var(--lp-text-secondary);
}

.landing-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lp-space-md);
}

/* SUBRAYADOS, no solo de otro color. Aquí no hay contexto que indique que son
   enlaces —ni forma de botón, ni flecha, ni un párrafo alrededor—, así que el
   subrayado es lo único que los declara. El desplazamiento los separa de la
   línea base sin engordar la caja. */
.landing-footer__link {
  font-size: var(--lp-text-body-sm);
  color: var(--lp-text-secondary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--lp-border-strong);
  transition:
    color var(--lp-duration) var(--lp-ease-out),
    text-decoration-color var(--lp-duration) var(--lp-ease-out);
}

.landing-footer__link:hover {
  color: var(--lp-text);
  text-decoration-color: currentColor;
}

/* El aviso de copia: el texto más apagado de toda la página, que es justo el
   peso que le corresponde. 5.1:1 sobre el fondo, muy por encima del mínimo. */
.landing-footer__legal {
  color: var(--lp-text-muted);
}

/* ---------------------------------------------------------------------------
 * Hueco para el CTA flotante
 *
 * Hasta `md` el botón fijo se posa sobre la esquina inferior derecha, encima
 * de lo último que haya en la página — que desde ahora es este pie. El respiro
 * se reserva AQUÍ, y solo en el pie que convive con ese botón: la página de
 * privacidad monta el mismo pie sin esta clase porque allí no flota nada.
 * ------------------------------------------------------------------------ */

@media (max-width: 767px) {
  .landing-footer--con-cta-flotante {
    padding-bottom: calc(var(--lp-space-xl) + var(--lp-space-2xl));
  }
}

@media (min-width: 768px) {
  .landing-footer__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--lp-space-lg);
  }
}

/* ===========================================================================
 * 25. Página de privacidad
 * ===========================================================================
 *
 * `privacy.html`, el único documento de la landing que no vende nada. Comparte
 * hoja de estilos con la página —los mismos tokens, el mismo negro, la misma
 * tipografía, el mismo pie— y no tiene NADA de lo demás: ni entradas
 * escalonadas, ni cards, ni acentos, ni CTA flotante, ni JavaScript.
 *
 * La prioridad aquí es una sola: que se lea. Una columna estrecha
 * —`.landing-container--narrow`, 720px, la misma primitiva que ya usa el
 * resto—, jerarquía de dos niveles y aire suficiente entre apartados para que
 * se puedan recorrer de un vistazo.
 *
 * LOS ENLACES DEL CUERPO VAN EN AZUL. Es el único sitio de la página donde hay
 * enlaces DENTRO de un párrafo, y ahí el subrayado solo no basta para
 * encontrarlos de un vistazo. El azul es además el color con el que esta hoja
 * ya dibuja el anillo de foco, así que no entra ninguna idea nueva: 6.2:1
 * sobre el fondo, por encima del mínimo AA.
 *
 * Cero tokens nuevos.
 * ======================================================================== */

/* --- Cabecera ----------------------------------------------------------- */

.landing-legal__header {
  padding-block: var(--lp-space-xl) var(--lp-space-lg);
  border-bottom: 1px solid var(--lp-border);
}

/* Arriba del todo y no solo en el pie: quien llega desde el formulario a medio
   rellenar tiene que ver la salida sin recorrer el documento entero. */
.landing-legal__back {
  display: inline-block;
  margin-bottom: var(--lp-space-lg);
  font-size: var(--lp-text-body-sm);
  color: var(--lp-text-secondary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--lp-border-strong);
  transition:
    color var(--lp-duration) var(--lp-ease-out),
    text-decoration-color var(--lp-duration) var(--lp-ease-out);
}

.landing-legal__back:hover {
  color: var(--lp-text);
  text-decoration-color: currentColor;
}

.landing-legal__title {
  margin-top: var(--lp-space-xs);
}

.landing-legal__updated {
  margin-top: var(--lp-space-sm);
}

/* --- Cuerpo ------------------------------------------------------------- */

.landing-legal__main {
  padding-block: var(--lp-space-xl) var(--lp-space-2xl);
}

/* La entradilla NO lleva titular propio: el `<h1>` de arriba ya dice de qué va
   la página, y un "Privacidad" repetido sobre el primer párrafo solo añadiría
   un nivel de jerarquía que no separa nada. */
.landing-legal__lead {
  text-wrap: pretty;
}

/* El margen va ENTRE apartados y no debajo de cada uno: así el primero arranca
   pegado al `padding` del contenedor y el último no arrastra un hueco muerto
   antes del pie. */
.landing-legal__lead + .landing-legal__section,
.landing-legal__section + .landing-legal__section {
  margin-top: var(--lp-space-xl);
}

.landing-legal__section-title {
  color: var(--lp-text);
}

/* `--lp-text-body` y no `body-sm`: es un texto para leer entero, no una nota
   al pie. El `text-wrap: pretty` evita que una palabra suelta cierre el
   párrafo. */
.landing-legal__text {
  margin-top: var(--lp-space-sm);
  text-wrap: pretty;
}

/* Lista con viñeta nativa: son enumeraciones de verdad —qué datos, para qué— y
   una lista sin marca visible se lee como párrafos sueltos. La sangría es la
   mínima para que la viñeta no se salga de la columna de lectura. */
.landing-legal__list {
  margin: var(--lp-space-sm) 0 0;
  padding-left: var(--lp-space-md);
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
}

.landing-legal__list li + li {
  margin-top: var(--lp-space-2xs);
}

/* Los datos del responsable: sin viñetas y en líneas cortas, porque es un
   bloque de identificación, no una enumeración. */
.landing-legal__contact {
  margin: var(--lp-space-sm) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--lp-text-body);
  line-height: var(--lp-leading-body);
  color: var(--lp-text-secondary);
}

.landing-legal__link {
  color: var(--lp-blue);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  transition: color var(--lp-duration) var(--lp-ease-out);
}

.landing-legal__link:hover {
  color: var(--lp-text);
}
