/*
 * vectia — hoja del sitio
 *
 * Traducción de docs/design/components.md a CSS plano. La regla del sistema:
 * implementar un componente es TRADUCIR la spec, no inventarla. Si aquí hace
 * falta un valor que no existe como token, se añade primero al sistema
 * (marca/sistemas/vectia/docs/design/tokens/tokens.css) y se vuelve a copiar
 * tokens.static.css. No se escribe un hex suelto aquí.
 *
 * Único valor que no viene de un token: los `rgb(… / …)` derivados de tokens
 * para velos y bordes translúcidos, que CSS no puede expresar de otro modo
 * sin duplicar el color.
 */

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

html { scroll-behavior: smooth; scroll-padding-top: 5.5rem; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-ink);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

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

.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ═══ Iconos · style-guide.md §6 ════════════════════════════════════════
 * El trazo y las esquinas se declaran UNA vez, aquí, y no en cada <symbol>.
 * Así un icono nuevo no puede salir con el grosor equivocado: hereda o no
 * existe. `currentColor` hace que cada icono tome el color de su contexto,
 * que es la razón por la que el mismo símbolo sirve en fondo claro y oscuro.
 * ═══════════════════════════════════════════════════════════════════════ */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* El selector es `svg:has(use)`: cualquier <svg> que dibuje un símbolo del
 * sprite, tenga la clase que tenga. Antes decía `svg[class*="__ico"]`, y esa
 * versión incumplía la promesa del párrafo de arriba — al añadir los iconos
 * de la reorganización a multipágina, ninguno llevaba una clase terminada en
 * «__ico» y todos salieron rellenos de negro en vez de trazados, porque el
 * relleno es el valor por defecto de SVG. Un icono no debe depender de cómo
 * lo llamó quien lo puso.
 * Los dos selectores viejos se conservan por si algún día un icono se dibuja
 * en línea sin pasar por el sprite. */
svg:has(use), svg[class*="__ico"], .si svg, .no svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: square;   /* a escuadra, para rimar con los cortes del wordmark */
  stroke-linejoin: miter;
  flex: none;
}

/* Única excepción, y a propósito estrecha: los logotipos de terceros. Un
 * logotipo no es un icono del sistema — no se puede redibujar a trazo 1.5 sin
 * dejar de ser el logotipo. Se marca con `logo-marca` en el <svg>, que gana a
 * la regla de arriba por especificidad (0,1,1 contra 0,0,2) sin tener que
 * repetir el selector ni usar !important.
 * Hoy solo lo lleva el logotipo de WhatsApp del botón verde. */
svg.logo-marca {
  fill: currentColor;
  stroke: none;
}

/* Primer tabulador: saltar la navegación. */
.saltar {
  position: absolute; left: var(--spacing-md); top: calc(var(--spacing-md) * -4);
  z-index: 100; padding: var(--spacing-sm) var(--spacing-md);
  background: var(--color-accent); color: var(--color-accent-ink);
  border-radius: var(--radius-md); text-decoration: none;
  transition: top var(--duration-fast) var(--ease-brand);
}
.saltar:focus { top: var(--spacing-md); }

.contenedor {
  max-width: var(--container-page); margin-inline: auto;
  padding-inline: var(--spacing-md);
}
@media (min-width: 768px) {
  .contenedor { padding-inline: var(--spacing-lg); }
}
.contenedor--angosto { max-width: var(--container-prose); }

/* ═══ Tipografía ═══════════════════════════════════════════════════════ */

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0;
}
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-2xl); letter-spacing: -0.01em; }
h3 { font-size: var(--text-lg); letter-spacing: -0.01em; }

@media (min-width: 1024px) {
  h1 { font-size: var(--text-5xl); }
  h2 { font-size: var(--text-3xl); }
}

/* style-guide §3: el énfasis del titular es UNA palabra, en la itálica del
   display. Ni negrita ni color, y nunca las dos. */
h1 em, h2 em { font-style: italic; font-weight: 400; }

p { margin: 0; max-width: 62ch; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-ink-muted);
  margin-bottom: var(--spacing-sm);
}

/* ═══ Botón · components.md §1 ═════════════════════════════════════════ */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--spacing-xs);
  min-height: 44px;                       /* tap target, style-guide §9 */
  padding: var(--spacing-sm) var(--spacing-lg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  position: relative;
  transition: background-color var(--duration-fast) var(--ease-brand),
              color var(--duration-fast) var(--ease-brand),
              border-color var(--duration-fast) var(--ease-brand);
}

.btn--primario {
  background: var(--color-accent);
  color: var(--color-accent-ink);
}
.btn--primario:hover { background: var(--color-accent-700); }

/* Uso 2 del recurso propio (style-guide §7): el borde inferior en ocre
   entrando de izquierda a derecha. Es el único adorno animado del sistema. */
.btn--primario::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--color-alt);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--duration-base) var(--ease-brand);
}
.btn--primario:hover::after,
.btn--primario:focus-visible::after { transform: scaleX(1); }

.btn--secundario {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-border-strong);
}
.btn--secundario:hover {
  border-color: var(--color-ink);
  background: rgb(21 15 38 / 0.04);
}

/* Botón de WhatsApp — el verde de la marca de terceros.
   Existe como variante propia y no como `btn--secundario` con un icono porque
   el reconocimiento ES la conversión: la gente identifica ese verde y ese
   glifo antes de leer la etiqueta, y en Perú WhatsApp es el canal donde de
   verdad se cierra. Un botón neutro con un iconito de línea al lado no compra
   nada de eso.

   El texto va en tinta oscura, no en blanco. Blanco sobre #25D366 da 1.98:1 —
   incumple AA por más del doble. Con --color-ink son 9.2:1, y de paso el botón
   se ve más actual que el verde-con-blanco de plantilla.

   No lleva el borde inferior en ocre de `btn--primario`: ese es el recurso
   propio de vectia (style-guide §7) y no pinta nada sobre una marca ajena.

   Se mantiene por debajo de `btn--primario` en jerarquía: el CTA del sitio
   sigue siendo pedir el diagnóstico. Este es la vía rápida, no la principal,
   por eso nunca van los dos como primario en el mismo bloque. */
.btn--whatsapp {
  background: var(--color-whatsapp);
  color: var(--color-ink);
  border-color: transparent;
}
.btn--whatsapp:hover { background: var(--color-whatsapp-700); }

/* En superficie oscura el verde ya destaca solo; lo que hace falta es que no
   parezca flotando, así que gana un borde de su propio color más claro. */
.hero .btn--whatsapp,
.seccion--oscura .btn--whatsapp,
.franja-cta .btn--whatsapp,
.banner-pagina .btn--whatsapp {
  color: var(--color-ink);
  border-color: var(--color-whatsapp);
}

.btn--ancho { width: 100%; }

/* Sobre superficie oscura el secundario invierte. La franja de cierre y el
   banner de página se sumaron a la lista al pasar a multipágina: son las otras
   dos superficies oscuras del sitio. */
.hero .btn--secundario,
.seccion--oscura .btn--secundario,
.franja-cta .btn--secundario,
.banner-pagina .btn--secundario {
  color: var(--color-ink-inverse);
  border-color: rgb(244 241 250 / 0.35);
}
.hero .btn--secundario:hover,
.seccion--oscura .btn--secundario:hover,
.franja-cta .btn--secundario:hover,
.banner-pagina .btn--secundario:hover {
  border-color: var(--color-ink-inverse);
  background: rgb(244 241 250 / 0.08);
}

/* ═══ Nav · components.md §2 ═══════════════════════════════════════════ */

.nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--color-dark);
  color: var(--color-ink-inverse);
}
.nav--elevada { box-shadow: var(--shadow-card); }

.nav__interior {
  max-width: var(--container-page); margin-inline: auto;
  padding-inline: var(--spacing-md);
  min-height: 72px;
  display: flex; align-items: center; gap: var(--spacing-lg);
}
@media (min-width: 768px) {
  .nav__interior { padding-inline: var(--spacing-lg); min-height: 80px; }
}

.nav__logo { display: block; margin-right: auto; }
.nav__logo img { width: 132px; }

.nav__menu {
  display: none;
  align-items: center; gap: var(--spacing-lg);
}
.nav__menu a {
  color: rgb(244 241 250 / 0.8);
  text-decoration: none;
  font-size: var(--text-base);
}
.nav__menu a:hover { color: var(--color-ink-inverse); }
.nav__cta { color: var(--color-accent-ink) !important; }

/* Menú móvil */
.nav__hamburguesa {
  display: grid; place-items: center;
  width: 44px; height: 44px; padding: 0;
  background: none; border: 0; cursor: pointer;
  color: var(--color-ink-inverse);
}

/* Este bloque tiene que ir DESPUÉS de la regla base de `.nav__hamburguesa`.
   Estaba antes, y como las dos reglas tienen la misma especificidad ganaba la
   última del archivo: la hamburguesa se veía también en escritorio, al lado
   del menú completo. */
@media (min-width: 900px) {
  .nav__hamburguesa { display: none; }
  .nav__menu { display: flex; }
}
.nav__barras,
.nav__barras::before,
.nav__barras::after {
  display: block; width: 22px; height: 2px;
  background: currentColor; border-radius: var(--radius-pill);
  transition: transform var(--duration-fast) var(--ease-brand),
              opacity var(--duration-fast) var(--ease-brand);
}
.nav__barras::before, .nav__barras::after { content: ""; position: absolute; }
.nav__barras::before { transform: translateY(-7px); }
.nav__barras::after  { transform: translateY(7px); }

[aria-expanded="true"] .nav__barras { background: transparent; }
[aria-expanded="true"] .nav__barras::before { transform: rotate(45deg); }
[aria-expanded="true"] .nav__barras::after  { transform: rotate(-45deg); }

@media (max-width: 899px) {
  .nav__menu[data-abierto] {
    display: flex; flex-direction: column; align-items: stretch;
    gap: var(--spacing-md);
    position: absolute; left: 0; right: 0; top: 100%;
    padding: var(--spacing-lg) var(--spacing-md) var(--spacing-xl);
    background: var(--color-dark);
    box-shadow: var(--shadow-lift);
  }
  .nav__menu[data-abierto] a { padding-block: var(--spacing-sm); }
}

/* ═══ Hero · components.md §3 ══════════════════════════════════════════ */

.hero {
  background: var(--color-dark);
  color: var(--color-ink-inverse);
  padding-block: var(--spacing-2xl);
}
@media (min-width: 768px) {
  .hero { padding-block: var(--spacing-3xl); }
}

.hero__interior {
  max-width: var(--container-page); margin-inline: auto;
  padding-inline: var(--spacing-md);
  display: grid; gap: var(--spacing-xl);
}
@media (min-width: 768px) {
  .hero__interior { padding-inline: var(--spacing-lg); }
}
@media (min-width: 1024px) {
  .hero__interior {
    grid-template-columns: 1.15fr 1fr;
    align-items: center; gap: var(--spacing-3xl);
  }
}

.hero .eyebrow { color: var(--color-accent-300); }
.hero__bajada {
  margin-top: var(--spacing-md);
  font-size: var(--text-md);
  color: rgb(244 241 250 / 0.82);
  max-width: 32ch;
}
.hero__botones {
  display: flex; flex-wrap: wrap; gap: var(--spacing-md);
  margin-top: var(--spacing-xl);
}

/* Uso 3 de motion (style-guide §5): la entrada del hero, una sola vez. */
.hero__texto > * { animation: entrar var(--duration-slow) var(--ease-brand) both; }
.hero__texto > :nth-child(2) { animation-delay: 60ms; }
.hero__texto > :nth-child(3) { animation-delay: 120ms; }
.hero__texto > :nth-child(4) { animation-delay: 180ms; }
@keyframes entrar {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* Marco de celular. Es una maqueta, no una captura, y el pie lo dice: el
   asistente de vectia todavía no existe — ver la nota de components.md §11.
   El marco existe para que la figura tenga volumen sin fingir un producto. */
.telefono {
  max-width: 20rem; margin-inline: auto;
  background: var(--color-dark-900);
  border: 2px solid rgb(196 184 223 / 0.25);
  border-radius: 2.25rem;
  padding: var(--spacing-md);
  box-shadow: var(--shadow-lift);
}

.telefono__barra {
  display: flex; align-items: center; gap: var(--spacing-sm);
  padding: var(--spacing-xs) var(--spacing-sm) var(--spacing-md);
  border-bottom: 1px solid rgb(244 241 250 / 0.1);
  margin-bottom: var(--spacing-md);
}
.telefono__ico { flex: none; color: var(--color-accent-300); }
.telefono__nombre {
  font-family: var(--font-body); font-size: var(--text-sm); font-weight: 500;
  color: var(--color-ink-inverse); margin-right: auto;
}
/* El estado va con texto, no solo con el punto: en escala de grises los dos
   acentos se confunden (style-guide §2), así que el color nunca informa solo. */
.telefono__estado {
  display: flex; align-items: center; gap: var(--spacing-xs);
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: rgb(244 241 250 / 0.6);
}
.telefono__estado::before {
  content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill);
  background: var(--color-success);
}

.chat { display: grid; gap: var(--spacing-sm); }
.chat__burbuja {
  margin: 0; padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--radius-lg); font-size: var(--text-sm);
  max-width: 88%;
}
.chat__burbuja--bot {
  background: var(--color-surface); color: var(--color-ink);
  border-bottom-left-radius: var(--radius-sm);
}
.chat__burbuja--yo {
  background: var(--color-accent); color: var(--color-accent-ink);
  margin-left: auto; border-bottom-right-radius: var(--radius-sm);
}
.chat__hora {
  display: block; text-align: right; margin-top: var(--spacing-xs);
  font-family: var(--font-mono); font-size: var(--text-xs);
  font-variant-numeric: tabular-nums; opacity: 0.55;
}

/* Tres puntos, estáticos. style-guide §5: nada hace loop ni pulsa. */
.chat__escribiendo {
  margin: 0; display: flex; gap: var(--spacing-xs);
  padding: var(--spacing-sm) var(--spacing-md);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border-bottom-left-radius: var(--radius-sm);
  width: fit-content;
}
.chat__escribiendo span {
  width: 6px; height: 6px; border-radius: var(--radius-pill);
  background: var(--color-ink-muted);
}

.chat__pie {
  margin-top: var(--spacing-md); font-family: var(--font-mono);
  font-size: var(--text-xs); color: rgb(244 241 250 / 0.5);
  text-align: center;
}

/* ═══ Divisor · components.md §4 — el recurso propio ═══════════════════ */

.divisor {
  max-width: var(--container-page); margin-inline: auto;
  padding-inline: var(--spacing-md);
  display: flex; align-items: center; gap: var(--spacing-md);
}
.divisor::before {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg,
    transparent, var(--color-border) 15%, var(--color-border-strong));
}
/* El chevron: la V girada, apuntando a la derecha. */
.divisor::after {
  content: ""; flex: none; width: 10px; height: 18px;
  background: var(--color-accent);
  clip-path: polygon(0 0, 55% 50%, 0 100%, 42% 100%, 100% 50%, 42% 0);
}

/* ═══ Secciones ════════════════════════════════════════════════════════ */

.seccion { padding-block: var(--spacing-2xl); }
@media (min-width: 768px) {
  .seccion { padding-block: var(--spacing-3xl); }
}
.seccion--alterna { background: var(--color-surface); }
.seccion--oscura {
  background: var(--color-dark);
  color: var(--color-ink-inverse);
}
.seccion--oscura .eyebrow { color: var(--color-accent-300); }

.seccion__entrada {
  margin-top: var(--spacing-md);
  font-size: var(--text-md);
  color: var(--color-ink-muted);
}
.seccion--oscura .seccion__entrada { color: rgb(244 241 250 / 0.82); }

/* ═══ Pasos ════════════════════════════════════════════════════════════ */

.pasos {
  list-style: none; padding: 0;
  margin: var(--spacing-xl) 0 0;
  display: grid; gap: var(--spacing-lg);
  counter-reset: paso;
}
@media (min-width: 768px) { .pasos { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .pasos { grid-template-columns: repeat(4, 1fr); } }

/* Riel de progreso — uso 3 del recurso propio (style-guide §7). Uno solo para
   toda la lista: la regla es no repetir la flecha más de una vez por
   componente. Solo desde 1024px, que es donde los cuatro pasos van en fila y
   el riel de verdad los encadena; apilados, un riel vertical sería adorno. */
.pasos--riel { position: relative; }
@media (min-width: 1024px) {
  /* El riel va a la altura del centro de los círculos (32px de alto, así que
     16px), no encima de ellos: tiene que ENCADENAR los cuatro pasos. Separado
     por arriba se leía como un divisor más, que es justo lo que no es. */
  .pasos--riel::before {
    content: ""; position: absolute; top: 16px;
    left: 16px; right: 26px; height: 2px;
    background-image: var(--gradient-brand);
    border-radius: var(--radius-pill);
  }
  /* La punta: la V girada hasta apuntar a la derecha. Toma el color del
     extremo del degradado para que la línea y la punta sean una sola pieza. */
  .pasos--riel::after {
    content: ""; position: absolute; top: 8px; right: 0;
    width: 10px; height: 18px;
    background: var(--color-dark);
    clip-path: polygon(0 0, 55% 50%, 0 100%, 42% 100%, 100% 50%, 42% 0);
  }
  /* El número tapa el riel a su paso, que es lo que hace que se vean como
     cuentas ensartadas en un hilo y no como una línea con números debajo. */
  .pasos--riel .paso__num {
    position: relative;
    background: var(--color-bg);
  }
}

.paso { display: grid; gap: var(--spacing-sm); align-content: start; }
/* Uso 3 del recurso propio: numerar está justificado en un indicador de
   progreso, y solo ahí. */
.paso__num {
  font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500;
  color: var(--color-accent);
  width: 32px; height: 32px; display: grid; place-items: center;
  border: 1px solid var(--color-accent-300);
  border-radius: var(--radius-pill);
}
.paso p { color: var(--color-ink-muted); font-size: var(--text-sm); }

/* ═══ Tarjeta de servicio · components.md §5 ═══════════════════════════ */

.tarjetas {
  margin-top: var(--spacing-xl);
  display: grid; gap: var(--spacing-lg);
}
@media (min-width: 768px) { .tarjetas { grid-template-columns: repeat(3, 1fr); } }

.tarjeta {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  display: grid; gap: var(--spacing-sm); align-content: start;
  position: relative;
  transition: box-shadow var(--duration-fast) var(--ease-brand),
              transform var(--duration-fast) var(--ease-brand);
}
.tarjeta:hover { box-shadow: var(--shadow-card); }
.tarjeta p { color: var(--color-ink-muted); font-size: var(--text-sm); }

/* components.md §5: 24px, trazo 1.5, en acento. El icono va en la destacada
   igual que en las otras dos — el destacado es el borde y la pastilla. */
.tarjeta__ico {
  color: var(--color-accent);
  margin-bottom: var(--spacing-xs);
}

/* style-guide §2: el destacado se hace con borde y etiqueta, nunca rellenando
   la tarjeta del color del acento. El acento no es superficie. */
.tarjeta--destacada {
  border: 2px solid var(--color-accent);
  padding-top: var(--spacing-xl);
}
.pastilla {
  position: absolute; top: 0; left: var(--spacing-lg);
  transform: translateY(-50%);
  background: var(--color-accent); color: var(--color-accent-ink) !important;
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: 0.1em;
  padding: var(--spacing-xs) var(--spacing-sm);
  border-radius: var(--radius-sm);
}

/* `.precio` queda sin uso desde que el sitio dejó de publicar importes: el
   precio sale del diagnóstico, porque depende de cuántos pasos tenga el
   proceso del cliente, y una cifra en la web ancla al visitante antes de que
   nadie haya mirado su caso. Se conserva comentado —no borrado— porque la
   conversación de precio existe igual y puede volver al sitio; rehacerlo
   costaría más que dejarlo escrito. Su gemelo `.th__precio` está en el bloque
   de la tabla, también comentado.

.precio {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: 500;
  color: var(--color-accent) !important;
  margin-top: var(--spacing-sm);
  font-variant-numeric: tabular-nums;
}
*/

/* La frase de beneficio de la tarjeta de servicio: qué deja de pasarle al
   negocio. Va antes que la lista y pesa más que ella, porque es lo único que
   se lee si solo se lee una línea. */
.tarjeta__beneficio {
  color: var(--color-ink) !important;
  font-size: var(--text-base) !important;
  font-weight: 500;
}

/* Lista con palomita. Reutiliza #ico-check, el mismo de la tabla, para que
   «incluido» se diga igual en todo el sitio. El icono va como máscara y no
   como <svg> para no repetir el marcado en cada <li>. */
.beneficios {
  list-style: none; padding: 0;
  margin: var(--spacing-sm) 0 0;
  display: grid; gap: var(--spacing-sm);
}
.beneficios li {
  position: relative;
  padding-left: calc(var(--spacing-lg) + var(--spacing-xs));
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
  line-height: 1.5;
}
.beneficios li::before {
  content: "";
  position: absolute; left: 0; top: 0.15em;
  width: 18px; height: 18px;
  background: var(--color-accent);
  /* El mismo trazo del sprite, dibujado aquí porque una máscara no puede
     apuntar a un <symbol>. Si cambia #ico-check, cambia también esto. */
  mask: no-repeat center / contain
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5"><path d="M4 12.5l5 5L20 6.5"/></svg>');
}
.seccion--oscura .beneficios li { color: rgb(244 241 250 / 0.82); }

/* ═══ Tarjeta de caso · components.md §7 ═══════════════════════════════ */

.casos {
  margin-top: var(--spacing-xl);
  display: grid; gap: var(--spacing-lg);
}
@media (min-width: 640px) { .casos { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .casos { grid-template-columns: repeat(3, 1fr); } }

.caso {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  display: grid; gap: var(--spacing-xs); align-content: start;
  background: var(--color-bg);
  transition: box-shadow var(--duration-base) var(--ease-brand),
              transform var(--duration-base) var(--ease-brand);
}
/* components.md §7: los mismos estados que la tarjeta de servicio, para que
   ambas compartan vocabulario de movimiento. El levantado de 4px se añadió al
   pasar a multipágina: ahora la tarjeta es un enlace a la página del caso, y
   tiene que anunciarse como algo en lo que se puede entrar. */
.caso:hover {
  box-shadow: var(--shadow-card);
  transform: translateY(-4px);
}

/* La captura del proyecto. El aspect-ratio se declara además del width/height
   del HTML: si un WebP faltara, el hueco sigue midiendo lo mismo y la rejilla
   no salta. */
.caso__img {
  width: 100%; height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: top;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  margin-bottom: var(--spacing-sm);
}
.caso__rubro {
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--color-alt);
}
.caso p:last-child {
  color: var(--color-ink-muted); font-size: var(--text-sm);
  margin-top: var(--spacing-xs);
}

/* ═══ Tabla de precios · components.md §6 ══════════════════════════════ */

.tabla-envoltorio {
  margin-top: var(--spacing-xl);
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.precios { border-collapse: collapse; width: 100%; min-width: 46rem; }
.precios th, .precios td {
  padding: var(--spacing-md);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--text-sm);
}
.precios thead th {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-base);
  vertical-align: bottom;
  background: var(--color-surface);
}
.precios tbody th { font-weight: 400; color: var(--color-ink-muted); }
.precios tbody tr:last-child th,
.precios tbody tr:last-child td { border-bottom: 0; }

/* Sin uso desde que la tabla dejó de llevar importes. Ver la nota junto a
   `.precio`, más arriba: se conserva por si el precio vuelve al sitio.

.th__precio {
  display: block; margin-top: var(--spacing-xs);
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 500;
  color: var(--color-accent); font-variant-numeric: tabular-nums;
}
*/
.th--destacada { box-shadow: inset 0 3px 0 var(--color-accent); }
.td--destacada { background: var(--color-accent-50); }
.td--nota { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* components.md §6: lo no incluido se atenúa CON UN ICONO DISTINTO, no se
   omite — omitirlo obliga a comparar columnas de memoria.
 *
 * Antes esto era `content: "✓ "` y `content: "— "`. Se cambió por SVG reales
 * por dos motivos. Uno, los pseudo-elementos con `content` los anuncian unos
 * lectores de pantalla y otros no: el «— » se leía como guion, como «raya» o
 * como nada. Ahora el icono es decorativo y la palabra va en el DOM, oculta a
 * la vista pero siempre leída. Y dos, lo que distingue es la FORMA —marca
 * frente a trazo—, no el color: en escala de grises los dos acentos de la
 * paleta se confunden (style-guide §2, ΔE 5.9), así que el color nunca puede
 * ser lo único que informe. */
.si { color: var(--color-success); display: block; }
.no { color: var(--color-ink-muted); display: block; }

.nota-pago {
  margin-top: var(--spacing-md);
  font-size: var(--text-sm); color: var(--color-ink-muted);
}

/* ═══ Formulario · components.md §8 ════════════════════════════════════ */

.formulario {
  margin-top: var(--spacing-xl);
  display: grid; gap: var(--spacing-lg);
}
/* En /contacto el formulario abre la sección —el titular está en el banner
   oscuro de arriba—, así que su margen se sumaba al padding de sección y
   dejaba un hueco muerto de 140px antes del primer campo. En la portada sí
   lleva margen, porque ahí viene detrás del párrafo de entrada. */
.formulario:first-child { margin-top: 0; }
.campo { display: grid; gap: var(--spacing-xs); }

/* El formulario nació dentro de una sección oscura y solo existía ahí, así
   que su texto se fijó al color claro. Al pasar a multipágina se repitió en
   /contacto, que va sobre fondo claro, y las etiquetas se volvieron
   ilegibles: blanco sobre blanco.
   Ahora el caso base es el fondo CLARO —que es el que hay en once de las doce
   páginas— y el oscuro se declara como excepción, más abajo. Así el error de
   contraste, si vuelve, se ve en el sitio donde se está trabajando y no en el
   único que nadie mira. */
.campo label {
  font-size: var(--text-sm); font-weight: 500;
  color: var(--color-ink);
}
.campo input, .campo textarea {
  font-family: var(--font-body); font-size: var(--text-base);
  color: var(--color-ink);
  background: var(--color-bg);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  min-height: 44px;
  width: 100%;
  transition: border-color var(--duration-fast) var(--ease-brand);
}
.campo input:hover, .campo textarea:hover { border-color: var(--color-accent-300); }
.campo textarea { resize: vertical; }

.campo__ayuda, .campo__error {
  font-size: var(--text-sm); margin: 0;
}
.campo__ayuda { color: var(--color-ink-muted); }
.campo__error { color: var(--color-danger); font-weight: 500; }
.campo__error::before { content: "⚠ "; }
.campo[data-error] input,
.campo[data-error] textarea { border-color: var(--color-danger); }

.formulario__nota {
  font-size: var(--text-sm); color: var(--color-ink-muted);
  text-align: center; margin-inline: auto;
}

/* Sobre superficie oscura (el formulario de la portada) todo invierte.
   `--color-danger` es un rojo pensado para fondo claro y sobre el morado
   oscuro pierde contraste, así que el error usa el ocre claro. */
.seccion--oscura .campo label { color: var(--color-ink-inverse); }
.seccion--oscura .campo__ayuda,
.seccion--oscura .formulario__nota { color: rgb(244 241 250 / 0.7); }
.seccion--oscura .campo__error { color: var(--color-alt-300); }
.seccion--oscura .campo[data-error] input,
.seccion--oscura .campo[data-error] textarea {
  border-color: var(--color-alt-300);
}

/* ═══ Pie · components.md §10 ══════════════════════════════════════════ */

.pie { background: var(--color-dark); color: var(--color-ink-inverse); }
.pie__interior {
  padding-block: var(--spacing-2xl);
  display: grid; gap: var(--spacing-xl);
}
/* Tres columnas: marca, «Explorar» y «Contacto». La de «Explorar» nació con
   la reorganización a multipágina — con once páginas, el pie es la segunda
   vía de navegación del sitio.
   Falta la cuarta, «Legal», apartada hasta que exista el RUC; los pasos para
   devolverla están en el comentario de _parciales/pie.html. Cuando vuelva,
   esto pasa a `1.4fr 1fr 1fr 1fr`. */
@media (min-width: 768px) {
  .pie__interior { grid-template-columns: 1.4fr 1fr 1fr; }
}
.pie__logo { width: 128px; }
.pie__lema {
  margin-top: var(--spacing-md);
  color: rgb(244 241 250 / 0.75); font-size: var(--text-sm);
  max-width: 34ch;
}
.pie__titulo {
  font-family: var(--font-body); font-size: var(--text-sm); font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: rgb(244 241 250 / 0.6);
  margin: 0 0 var(--spacing-md);
}
.pie__lista { list-style: none; padding: 0; margin: 0; display: grid;
  gap: var(--spacing-sm); }
.pie__lista a {
  color: var(--color-ink-inverse); text-decoration: none;
  font-size: var(--text-sm);
  display: flex; align-items: center; gap: var(--spacing-sm);
}
.pie__lista a:hover { color: var(--color-accent-300); }
/* El icono es un poco más apagado que la etiqueta a propósito: identifica el
   canal sin competir con el texto, que es lo que se lee. */
.pie__ico { color: var(--color-accent-300); }
.pie__lista a:hover .pie__ico { color: currentColor; }

/* «Pedir diagnóstico» no lleva icono: es una acción, no un canal, y no hay
   ningún símbolo honesto para ella —la flecha tiene su lista cerrada de usos
   (style-guide §7) y esta no está en ella—. Pero sin icono la etiqueta se
   desalineaba de las otras dos, así que ocupa el hueco con un espaciador del
   mismo ancho. Alinear no exige inventarse un icono. */
.pie__lista a:not(:has(.pie__ico))::before {
  content: ""; width: 16px; flex: none;
}

/* Libro de Reclamaciones — obligatorio en Perú, style-guide §10. */
.libro {
  display: inline-flex; align-items: center; gap: var(--spacing-sm);
  margin-top: var(--spacing-md);
  border: 2px solid var(--color-ink-inverse);
  border-radius: var(--radius-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  font-family: var(--font-body); font-size: var(--text-xs);
  font-weight: 600; line-height: 1.25; text-align: left;
  color: var(--color-ink-inverse); text-decoration: none;
}
.libro__ico { color: currentColor; }
.libro:hover { background: rgb(244 241 250 / 0.1); }

.pie__legal {
  padding-block: var(--spacing-lg);
  border-top: 1px solid rgb(244 241 250 / 0.14);
}
.pie__legal p {
  font-size: var(--text-sm); color: rgb(244 241 250 / 0.6);
  font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════════
 * MULTIPÁGINA
 *
 * Todo lo que sigue nació al partir la one-page en once páginas. Ninguna de
 * estas reglas pisa a las de arriba: se añaden componentes, no se reescriben.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ─── Nav: la entrada activa ───────────────────────────────────────────
   `.brand-underline` de tokens.static.css ya trae el estado
   [aria-current="page"], pero pinta el subrayado con --gradient-brand, que
   termina en --color-dark: sobre la nav, que es de ese mismo color, la mitad
   derecha del subrayado desaparece y parece un fallo de render. Aquí se
   sustituye por el acento secundario, que es el único token que resalta
   sobre --color-dark. */
.nav__menu .brand-underline {
  background-image: linear-gradient(90deg,
    var(--color-alt-300) 0%, var(--color-alt) 100%);
}
.nav__menu a[aria-current="page"] { color: var(--color-ink-inverse); }
/* El CTA es un botón: no se subraya, ya se distingue por sí mismo. */
.nav__cta { background-image: none !important; padding-bottom: 0; }

/* ─── Banner de página · components.md §12 ─────────────────────────────
   Cabecera plana y sin foto de las páginas internas. Es deliberadamente más
   corta que el hero (2xl frente a 3xl) para que el hero siga siendo el único
   momento «tesis» del sitio. Sin foto, sin botones y sin fila de datos: la
   spec lo prohíbe expresamente.
   El `.brand-line` del borde inferior hace de primer divisor hacia el
   contenido, así que estas páginas no llevan `.divisor` después. */
.banner-pagina {
  background: var(--color-dark);
  color: var(--color-ink-inverse);
  padding-top: var(--spacing-xl);
}
@media (min-width: 768px) {
  .banner-pagina { padding-top: var(--spacing-2xl); }
}
.banner-pagina .eyebrow { color: var(--color-accent-300); }
.banner-pagina h1 {
  font-size: var(--text-3xl);
  margin-top: var(--spacing-sm);
}
@media (min-width: 768px) {
  .banner-pagina h1 { font-size: var(--text-4xl); }
}
.banner-pagina__entrada {
  /* lg y no md: el titular del banner es text-4xl y su descendente casi toca
     la primera línea de la bajada con el espaciado normal de sección. */
  margin-top: var(--spacing-lg);
  margin-bottom: var(--spacing-xl);
  font-size: var(--text-md);
  color: rgb(244 241 250 / 0.82);
  max-width: 60ch;
}
@media (min-width: 768px) {
  .banner-pagina__entrada { margin-bottom: var(--spacing-2xl); }
}

/* ─── Enlace con flecha ────────────────────────────────────────────────
   El «Ver el caso →» que cierra cada tarjeta y cada página de detalle. Es el
   uso 2 del recurso propio (style-guide §7): la flecha marca continuidad
   hacia otra página, no adorna. Una por componente, nunca dos.
   La flecha avanza 3px en hover; el enlace entero no se mueve, porque dentro
   de una tarjeta que ya se levanta, dos movimientos a la vez marean. */
.enlace-flecha {
  display: inline-flex; align-items: center; gap: var(--spacing-sm);
  color: var(--color-accent);
  font-size: var(--text-sm); font-weight: 500;
  text-decoration: none;
}
.enlace-flecha svg {
  transition: transform var(--duration-base) var(--ease-brand);
}
.enlace-flecha:hover { color: var(--color-accent-700); }
.enlace-flecha:hover svg { transform: translateX(3px); }
.seccion--oscura .enlace-flecha,
.franja-cta .enlace-flecha { color: var(--color-accent-300); }

/* El pie de sección que lleva a la página completa («Ver los seis casos»). */
.seccion__mas { margin-top: var(--spacing-xl); }

/* ─── Mosaico de casos ─────────────────────────────────────────────────
   Rejilla de 12 columnas alternando 7+5 y 5+7, siguiendo la referencia de
   nova-tek. El ritmo se declara con dos clases explícitas y no con
   :nth-child, para que reordenar las tarjetas en el HTML no descoloque el
   mosaico entero ni obligue a contar posiciones.
   Solo desde 1024px: por debajo son dos columnas iguales, y en móvil una. */
.mosaico {
  display: grid; gap: var(--spacing-lg);
}
@media (min-width: 640px) {
  .mosaico { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .mosaico { grid-template-columns: repeat(12, 1fr); }
  .caso--ancho { grid-column: span 7; }
  .caso--angosto { grid-column: span 5; }
}

/* La tarjeta de caso en su versión de página: el titular es h2 y lleva
   enlace, y debajo van los campos rotulados. */
.mosaico .caso { gap: var(--spacing-sm); }
.caso h2 {
  font-size: var(--text-lg);
  margin-top: var(--spacing-xs);
}
.caso h2 a, .caso h3 a {
  color: inherit; text-decoration: none;
}
.caso h2 a:hover, .caso h3 a:hover { color: var(--color-accent); }
/* La imagen también entra al caso, pero fuera del orden de tabulación: el
   titular ya lleva al mismo sitio y dos paradas de teclado seguidas hacia el
   mismo destino son ruido para quien navega sin ratón. */
.caso__enlace-img { display: block; }

/* Campos rotulados — Rubro / Resuelve / Hecho con. La etiqueta va en mono y
   mayúsculas, el mismo tratamiento que `.caso__rubro` ya usaba, para que las
   dos versiones de la tarjeta se lean como el mismo componente. */
.caso__meta {
  margin: 0; display: grid; gap: var(--spacing-md);
}
.caso__meta > div { display: grid; gap: var(--spacing-xs); }
.caso__meta dt {
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--color-alt);
}
.caso__meta dd {
  margin: 0;
  font-size: var(--text-sm); color: var(--color-ink-muted);
  line-height: 1.5;
}

/* Chips de tecnología. Superficie, nunca acento: el acento es para acciones,
   y estas etiquetas no se pulsan (style-guide §2). */
.chips {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: var(--spacing-xs);
}
.chips li {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 2px var(--spacing-sm);
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--color-ink-muted);
}

/* El pie de la tarjeta, separado por una línea. Necesita ganarle en
   especificidad a `.caso p:last-child`, que lo dejaría gris y pequeño. */
.caso .caso__pie {
  margin-top: auto;
  padding-top: var(--spacing-md);
  border-top: 1px solid var(--color-border);
  color: inherit; font-size: inherit;
}

/* ─── Servicio desarrollado (/servicios) ───────────────────────────────
   La versión larga de la tarjeta de servicio: aquí hay sitio para explicar,
   así que el bloque se abre en dos partes —cabecera con icono y cuerpo— en
   vez de apretarlo todo en una columna. */
.servicio {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  padding: var(--spacing-lg);
  position: relative;
}
.servicio + .servicio { margin-top: var(--spacing-xl); }
@media (min-width: 900px) {
  .servicio {
    display: grid; grid-template-columns: 1fr 1.2fr;
    gap: var(--spacing-xl);
    padding: var(--spacing-xl);
  }
}
.servicio--destacado {
  border: 2px solid var(--color-accent);
  padding-top: var(--spacing-xl);
}
.servicio__cabecera {
  display: flex; gap: var(--spacing-md); align-items: flex-start;
}
/* El icono en caja con borde, tomado de la referencia de nova-tek. El borde
   lo separa del texto sin tener que agrandarlo. */
.servicio__ico {
  flex: none;
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-accent);
}
.servicio h2 { font-size: var(--text-xl); }
.servicio__beneficio {
  margin-top: var(--spacing-sm);
  font-size: var(--text-base); font-weight: 500;
  color: var(--color-ink);
}
.servicio__cuerpo { margin-top: var(--spacing-lg); }
@media (min-width: 900px) {
  .servicio__cuerpo { margin-top: 0; }
}
.servicio__cuerpo > p {
  color: var(--color-ink-muted); font-size: var(--text-sm);
}

/* ─── Misión y Visión (dos cajas gemelas) ──────────────────────────────
   Maquetación tomada de la página de referencia: icono arriba, título,
   párrafo. Gemelas de verdad —misma anchura— porque ninguna de las dos manda
   sobre la otra. */
.duo {
  display: grid; gap: var(--spacing-lg);
}
@media (min-width: 768px) {
  .duo { grid-template-columns: repeat(2, 1fr); }
}
.duo__caja {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  padding: var(--spacing-xl);
}
.duo__ico {
  display: grid; place-items: center;
  width: 56px; height: 56px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-accent);
  margin-bottom: var(--spacing-md);
}
.duo__caja h2 { font-size: var(--text-xl); }
.duo__caja p {
  margin-top: var(--spacing-sm);
  color: var(--color-ink-muted);
}

/* ─── Valores («Por qué elegirnos») ────────────────────────────────────
   Rejilla 2×2 con el icono arriba centrado, también de la referencia. Se
   centra el bloque entero, no solo el icono: un icono centrado sobre texto
   alineado a la izquierda deja el eje visual roto. */
.valores {
  margin-top: var(--spacing-xl);
  display: grid; gap: var(--spacing-xl);
}
@media (min-width: 768px) {
  .valores { grid-template-columns: repeat(2, 1fr); }
}
.valor { text-align: center; }
.valor__ico {
  display: inline-grid; place-items: center;
  width: 56px; height: 56px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  color: var(--color-accent);
  margin-bottom: var(--spacing-md);
}
.valor h3 { font-size: var(--text-lg); }
.valor p {
  margin-top: var(--spacing-sm);
  color: var(--color-ink-muted); font-size: var(--text-sm);
  max-width: 46ch; margin-inline: auto;
}

/* ─── Franja de cierre ─────────────────────────────────────────────────
   Cierra las páginas que no llevan el formulario. Sin divisor encima: el
   cambio a fondo oscuro ya marca la transición (style-guide §7). */
.franja-cta {
  background: var(--color-dark);
  color: var(--color-ink-inverse);
  padding-block: var(--spacing-2xl);
}
.franja-cta__interior {
  display: grid; gap: var(--spacing-lg);
  align-items: center;
}
@media (min-width: 900px) {
  .franja-cta__interior {
    grid-template-columns: 1fr auto;
    gap: var(--spacing-2xl);
  }
}
.franja-cta h2 { font-size: var(--text-xl); }
.franja-cta p {
  margin-top: var(--spacing-sm);
  color: rgb(244 241 250 / 0.82); font-size: var(--text-sm);
  max-width: 58ch;
}
/* Dos botones: pedir el diagnóstico por formulario, o escribir directo por
   WhatsApp. Se apilan en móvil y van en fila desde 900px, donde ya conviven
   con el texto a la izquierda. */
.franja-cta__botones {
  display: flex; flex-wrap: wrap; gap: var(--spacing-md);
}
@media (min-width: 900px) {
  .franja-cta__botones { flex-direction: column; align-items: stretch; }
}
.franja-cta .btn { justify-self: start; }

/* ─── Página de detalle de caso ────────────────────────────────────────*/
/* La figura se limita a 56rem en vez de ocupar el contenedor entero (72rem),
   por dos razones que apuntan al mismo sitio. La editorial: una captura a
   toda anchura se come la página y empuja el texto —que es lo que explica el
   caso— por debajo del pliegue. Y la técnica: la captura de origen mide
   1152px, así que a 72rem se estaría estirando, mientras que a 56rem va
   sobrada en pantalla normal y razonable en retina. Servir bien una captura
   nítida a 1152 CSS px pediría un archivo de ~2200px, y el peso ligero es
   requisito del brief (style-guide §6). */
.caso-figura {
  margin: 0 auto;
  max-width: 56rem;
}
.caso-figura img {
  width: 100%; height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover; object-position: top;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.caso-figura figcaption {
  margin-top: var(--spacing-sm);
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--color-ink-muted);
  text-align: center;
}
/* La sección de la figura y la del texto son dos `.seccion` seguidas: sin
   este ajuste sumarían 12rem de aire entre la captura y «El problema». */
.caso-figura + * { margin-top: 0; }
.caso-detalle { padding-top: var(--spacing-xl); }
.caso-detalle h2 {
  font-size: var(--text-xl);
  margin-top: var(--spacing-xl);
}
.caso-detalle h2:first-child { margin-top: 0; }
.caso-detalle p { margin-top: var(--spacing-md); }
.caso-detalle .chips { margin-top: var(--spacing-md); }
.caso-detalle__volver {
  margin-top: var(--spacing-xl);
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--color-border);
}

/* ─── Canales alternos al formulario ───────────────────────────────────
   Van debajo del formulario en las dos páginas que lo llevan. Como botones y
   no como enlaces de texto: son la vía que usa quien NO va a rellenar el
   formulario, y un enlace pequeño debajo de un botón grande se lee como una
   nota al pie en vez de como la otra opción. */
.formulario__alterno {
  margin-top: var(--spacing-xl);
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--color-border);
  text-align: center;
}
.formulario__alterno > p {
  color: var(--color-ink-muted); font-size: var(--text-sm);
}
.formulario__canales {
  margin-top: var(--spacing-md);
  display: flex; flex-wrap: wrap; gap: var(--spacing-md);
  justify-content: center;
}
.seccion--oscura .formulario__alterno {
  border-top-color: rgb(244 241 250 / 0.14);
}
.seccion--oscura .formulario__alterno > p { color: rgb(244 241 250 / 0.7); }

/* Lista de enlaces con flecha — la usa la página 404. */
.lista-enlaces {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: var(--spacing-md);
}

/* ═══ Motion reducido ══════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .hero__texto > * { animation: none; }
  .btn--primario::after { transition: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
 * PÁGINAS LEGALES — Libro de Reclamaciones y privacidad
 *
 * Texto corrido a `container-prose`, sin hero. Reutilizan los componentes de
 * arriba (botón, campo, tabla) y solo añaden lo que no existía.
 * ═══════════════════════════════════════════════════════════════════════ */

.legal { padding-block: var(--spacing-2xl) var(--spacing-3xl); }
.legal h1 { margin-bottom: var(--spacing-md); }
.legal h2 {
  font-size: var(--text-xl);
  margin-top: var(--spacing-2xl);
  margin-bottom: var(--spacing-sm);
}
.legal p { margin-bottom: var(--spacing-md); }
.legal__entrada { font-size: var(--text-md); color: var(--color-ink-muted); }
.legal__fecha {
  font-family: var(--font-mono); font-size: var(--text-sm);
  color: var(--color-ink-muted);
}
.legal a { color: var(--color-accent); }
.legal .tabla-envoltorio table { min-width: 34rem; }

/* La nav de las legales no tiene menú: solo la vuelta al inicio. */
.nav__menu--simple { display: flex; }
.nav__menu--simple a { font-size: var(--text-sm); }

/* Datos del proveedor · Anexo I del reglamento */
.proveedor {
  margin: var(--spacing-lg) 0 var(--spacing-xl);
  padding: var(--spacing-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  display: grid; gap: var(--spacing-md);
}
@media (min-width: 640px) {
  .proveedor { grid-template-columns: repeat(2, 1fr); }
}
.proveedor dt {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--color-ink-muted);
  font-family: var(--font-mono);
}
.proveedor dd { margin: var(--spacing-xs) 0 0; font-weight: 500; }
/* Lo que aún no está rellenado se ve. Un dato legal a medias no puede pasar
   desapercibido al revisar la página. */
[data-pendiente] {
  color: var(--color-danger);
  background: rgb(163 35 27 / 0.08);
  padding: 2px var(--spacing-xs);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--text-sm);
}

.aviso {
  margin: var(--spacing-xl) 0;
  padding: var(--spacing-lg);
  border-left: 3px solid var(--color-alt);
  background: var(--color-surface);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.aviso h2 { margin: 0 0 var(--spacing-sm); font-size: var(--text-lg); }
.aviso p:last-child { margin-bottom: 0; }
.aviso--tenue {
  border-left-color: var(--color-border-strong);
  font-size: var(--text-sm); color: var(--color-ink-muted);
}

/* ── Formulario legal: fondo claro, a diferencia del de contacto ─────── */

.formulario--legal { margin-top: var(--spacing-xl); gap: var(--spacing-xl); }
.formulario--legal fieldset {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  margin: 0;
  display: grid; gap: var(--spacing-lg);
}
.formulario--legal legend {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-sm); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--color-ink-muted);
  padding-inline: var(--spacing-sm);
}
.formulario--legal label,
.campo__titulo {
  color: var(--color-ink);
  font-size: var(--text-sm); font-weight: 500;
}
.formulario--legal .campo__ayuda { color: var(--color-ink-muted); }
.formulario--legal .formulario__nota { color: var(--color-ink-muted); }
.formulario--legal .campo__error { color: var(--color-danger); }
.campo[data-error] input,
.campo[data-error] textarea,
.campo[data-error] select { border-color: var(--color-danger); }

.campo-fila { display: grid; gap: var(--spacing-lg); }
@media (min-width: 640px) {
  .campo-fila { grid-template-columns: 1fr 1fr; }
}

.campo select {
  font-family: var(--font-body); font-size: var(--text-base);
  color: var(--color-ink); background: var(--color-bg);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  min-height: 44px; width: 100%;
}

/* Casillas y radios: el tap target sigue siendo 44px aunque el cuadrito
   sea pequeño — style-guide §9. */
.campo input[type="checkbox"],
.campo input[type="radio"] {
  width: 1.15rem; height: 1.15rem; min-height: 0;
  margin-right: var(--spacing-sm);
  accent-color: var(--color-accent);
  flex: none;
}
.campo label:has(input[type="checkbox"]),
.opcion {
  display: flex; align-items: flex-start; gap: var(--spacing-xs);
  min-height: 44px; padding-block: var(--spacing-xs);
  font-weight: 400; cursor: pointer;
}
.opciones { display: grid; gap: var(--spacing-xs); }
.opcion span { line-height: 1.5; }

.campo--conformidad {
  padding: var(--spacing-md);
  background: var(--color-accent-50);
  border-radius: var(--radius-md);
}

/* Trampa de robots: fuera de pantalla, invisible y sin foco. */
.trampa {
  position: absolute; left: -9999px;
  width: 1px; height: 1px; overflow: hidden;
}

.formulario__fallo {
  color: var(--color-danger); font-size: var(--text-sm); font-weight: 500;
  margin: 0;
}
.formulario__fallo::before { content: "⚠ "; }

/* ── Constancia ─────────────────────────────────────────────────────── */

.constancia {
  margin-top: var(--spacing-xl);
  padding: var(--spacing-xl);
  border: 2px solid var(--color-accent);
  border-radius: var(--radius-lg);
  background: var(--color-accent-50);
  display: grid; gap: var(--spacing-md);
}
.constancia h2 { margin: 0; }
.constancia__numero {
  font-family: var(--font-mono); font-size: var(--text-2xl);
  font-weight: 500; color: var(--color-accent);
  font-variant-numeric: tabular-nums; margin: 0;
}

/* ── Pie reducido de las legales ─────────────────────────────────────── */

.pie__legal--solo {
  border-top: 0;
  display: flex; flex-wrap: wrap; gap: var(--spacing-sm) var(--spacing-lg);
  justify-content: space-between;
}
.pie__legal--solo a { color: var(--color-ink-inverse); }
.pie__legal--solo a:hover { color: var(--color-accent-300); }

/* ═══════════════════════════════════════════════════════════════════════
   FONDOS CON TEXTURA Y BOTÓN FLOTANTE DE WHATSAPP
   Añadido después de la reorganización a multipágina.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── Textura de las superficies oscuras ───────────────────────────────
   Las cinco superficies oscuras del sitio (hero, sección de contacto de la
   portada, banner de página, franja de cierre y pie) eran un plano liso de
   #17123A. Con una sola página se sostenía; con doce, el banner oscuro se
   repite en cada página y el plano liso empezó a leerse como «sin terminar».

   Se resuelve con luz, no con una imagen: dos halos muy abiertos —morado
   arriba a la izquierda, ocre abajo a la derecha, que son los dos colores de
   marca— más una retícula de puntos finísima. Todo es CSS, así que no añade
   ni un byte de descarga, escala a cualquier pantalla y no puede llegar
   pixelado a un retina.

   Por qué NO una fotografía de fondo: style-guide §6 prohíbe el stock
   («no parecer una copia de internet»), y §7 prohíbe el chevron de marca a
   sangre completa. Una foto real de proceso sí valdría, pero hoy no existe
   ninguna en el repositorio y fabricarla no es cosa del CSS.

   El halo morado sube la luminancia del fondo de 0.013 a 0.023 en su punto
   más intenso. El texto claro pasa de 15.9:1 a 12.7:1 — sigue muy por encima
   del 4.5:1 de AA, que es la condición para que esto pueda existir. */
.hero,
.seccion--oscura,
.banner-pagina,
.franja-cta,
.pie {
  background-color: var(--color-dark);
  background-image:
    radial-gradient(48rem 32rem at 12% -20%, rgb(96 52 201 / 0.26), transparent 62%),
    radial-gradient(38rem 26rem at 92% 118%, rgb(176 71 14 / 0.14), transparent 60%),
    radial-gradient(circle at 1px 1px, rgb(244 241 250 / 0.05) 1px, transparent 0);
  background-size: auto, auto, 26px 26px;
  background-repeat: no-repeat, no-repeat, repeat;
}

/* ─── Textura de la sección clara ──────────────────────────────────────
   La contrapartida en claro, para /contacto. Mismos dos halos y misma
   retícula, bajados a la intensidad que aguanta un fondo claro sin que el
   texto pierda contraste. */
.seccion--textura {
  background-color: var(--color-surface);
  background-image:
    radial-gradient(52rem 30rem at 10% -15%, rgb(96 52 201 / 0.11), transparent 62%),
    radial-gradient(40rem 26rem at 95% 112%, rgb(176 71 14 / 0.08), transparent 60%),
    radial-gradient(circle at 1px 1px, rgb(21 15 38 / 0.05) 1px, transparent 0);
  background-size: auto, auto, 24px 24px;
  background-repeat: no-repeat, no-repeat, repeat;
}

/* ─── El formulario como tarjeta ───────────────────────────────────────
   Solo en /contacto. En la portada el formulario vive dentro de la sección
   oscura y ya está claramente delimitado por el cambio de fondo; en
   /contacto flotaba suelto sobre el fondo de página, sin nada que dijera
   dónde empieza y dónde acaba.

   Puesto sobre la textura de arriba, la tarjeta hace además el trabajo que
   la textura sola no puede: devuelve un fondo LISO justo detrás de los
   campos. Una retícula de puntos corriendo por debajo de un input es
   exactamente el sitio donde una textura deja de ser fondo y se vuelve
   ruido. */
.formulario-tarjeta {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  box-shadow: var(--shadow-card);
}
@media (min-width: 768px) {
  .formulario-tarjeta { padding: var(--spacing-xl); }
}

/* ─── Botón flotante de WhatsApp ───────────────────────────────────────
   Fijo abajo a la derecha en las doce páginas. Va en z-index 40, por debajo
   de la nav (50): con el menú móvil abierto el botón queda tapado, que es lo
   correcto — dos capas flotantes discutiéndose la misma esquina es un fallo
   clásico de este componente.

   En móvil es un círculo de 56px, muy por encima del mínimo de 44 que pide
   style-guide §9. Desde 768px se estira y enseña la etiqueta: en escritorio
   sobra el espacio y un círculo verde sin texto obliga a adivinar. */
.wa-flotante {
  position: fixed;
  right: var(--spacing-md);
  bottom: var(--spacing-md);
  z-index: 40;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--spacing-sm);
  width: 56px; height: 56px;
  background: var(--color-whatsapp);
  color: var(--color-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lift);
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--text-base); font-weight: 500; line-height: 1;
  transition: background-color var(--duration-fast) var(--ease-brand);
}
.wa-flotante:hover { background: var(--color-whatsapp-700); }

/* La etiqueta se OCULTA VISUALMENTE en móvil, no se quita: `display: none`
   la sacaría también del árbol de accesibilidad y el enlace se quedaría sin
   nombre accesible, con un SVG decorativo como único contenido. */
.wa-flotante__texto {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
@media (min-width: 768px) {
  .wa-flotante {
    right: var(--spacing-lg); bottom: var(--spacing-lg);
    width: auto; height: auto; min-height: 56px;
    padding-inline: var(--spacing-lg);
  }
  .wa-flotante__texto {
    position: static; width: auto; height: auto; padding: 0; margin: 0;
    overflow: visible; clip-path: none;
  }
}

/* El flotante tapa la línea de copyright en móvil, que es justo donde el pie
   tiene menos aire. Se le reserva el hueco: 56 del botón + 16 de separación. */
@media (max-width: 767px) {
  .pie__legal { padding-bottom: calc(56px + var(--spacing-xl)); }
}
