/**
 * ESCALARTE — CSS Principal (Bundle)
 *
 * Este archivo importa todos los CSS en el orden correcto.
 * PostCSS los combina en un solo archivo para producción.
 */

/* 1. Tokens (variables CSS de la marca) */
/* ESCALARTE — Web Tokens
   Importa los tokens de marca y extiende con variables específicas para la web */

/* ESCALARTE — tokens de marca v7
   Contrastes verificados por cálculo, no por estimación.
   Espaciado: vertical en múltiplos de 8, detalles internos en múltiplos de 4. */

:root {
  /* ---- Rampa azul: los tres peldaños del logo son tres paradas de esta rampa ---- */
  --azul-50:  #EAF2FE;
  --azul-100: #C9DFFB;
  --azul-200: #9CC5F7;  /* peldaño medio sobre oscuro · texto sobre oscuro (10.14:1) */
  --azul-300: #4A90E8;  /* peldaño superior sobre claro · enlaces sobre oscuro (5.56:1) */
  --azul-400: #2E77DD;  /* peldaño superior sobre oscuro · solo gráfico (4.14:1) */
  --azul-500: #1B55B8;  /* peldaño medio sobre claro · botones y enlaces (6.43:1) */
  --azul-600: #143E8C;  /* hover de botón (9.31:1) */
  --azul-700: #0E2A61;  /* superficies azules profundas */
  --tinta:    #0A1628;  /* peldaño base sobre claro · fondo oscuro · texto (16.86:1) */

  /* ---- Neutros ---- */
  --blanco:        #FFFFFF;  /* peldaño base sobre oscuro · superficies */
  --nieve:         #F4F7FA;  /* fondo claro por defecto */
  --niebla:        #DBE2E8;  /* filete decorativo. No delimita nada funcional */
  --niebla-fuerte: #B5C3D0;  /* divisor con énfasis */
  --acero:         #5A6B7D;  /* texto secundario (5.09:1) · bordes de campos */

  /* ---- Semánticos: dos valores, igual que los azules ---- */
  --exito:       #0E7A57;  /* sobre claro  (4.96:1) */
  --exito-alto:  #45C79A;  /* sobre oscuro (8.54:1) */
  --alerta:      #C0392B;  /* sobre claro  (5.06:1) */
  --alerta-alto: #FF8A7A;  /* sobre oscuro (7.92:1) */

  /* ---- Canales RGB de los colores que se usan con transparencia ----
     Las sombras de la marca nunca son negras: son tinta rebajada. Y los velos
     azules salen del 300. Antes cada rgba() repetía estos números a mano, así
     que al cambiar un color las sombras se quedaban con el valor viejo.
     Se usan así:  rgb(var(--tinta-rgb) / 0.12) */
  --tinta-rgb:    10 22 40;    /* #0A1628 */
  --azul-300-rgb: 74 144 232;  /* #4A90E8 */
  --azul-500-rgb: 27 85 184;   /* #1B55B8 */
  --blanco-rgb:   255 255 255; /* #FFFFFF */

  /* ---- Tipografía ---- */
  --display: "Archivo", Helvetica, Arial, sans-serif;
  --texto:   "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  --dato:    "JetBrains Mono", ui-monospace, Menlo, monospace;

  --t-xs:  0.75rem;   /* 12 */
  --t-sm:  0.875rem;  /* 14 */
  --t-md:  1rem;      /* 16 */
  --t-lg:  1.25rem;   /* 20 */
  --t-xl:  1.563rem;  /* 25 */
  --t-2xl: 1.953rem;  /* 31 */
  --t-3xl: 2.441rem;  /* 39 */
  --t-4xl: 3.052rem;  /* 49 */

  --u: 8px; --radio: 4px; --medida: 66ch;
}

/* Prohibiciones que salen de la medición, no del gusto:
   --azul-200 sobre nieve = 1.66:1  → jamás texto ni ícono sobre claro
   --azul-300 sobre nieve = 3.03:1  → solo barras, bloques y texto de 24px o más
   --azul-400 sobre tinta = 4.14:1  → solo gráfico. Para enlaces en oscuro usar --azul-300
   --niebla  sobre nieve = 1.22:1   → filete decorativo. Un borde que comunica algo va en --acero */

body{font-family:var(--texto);font-size:var(--t-md);line-height:1.65;color:var(--tinta);background:var(--nieve)}
h1,h2,h3{font-family:var(--display);font-weight:600;line-height:1.12;letter-spacing:-0.015em}
.cifra{font-family:var(--dato);font-variant-numeric:tabular-nums}
.sube{color:var(--exito)} .baja{color:var(--alerta)}

.boton{
  font-family:var(--display);font-weight:600;
  background:var(--azul-500);color:var(--blanco);
  border:0;border-radius:var(--radio);
  padding:calc(var(--u)*1.5) calc(var(--u)*3);cursor:pointer;
}
.boton:hover{background:var(--azul-600)}
.boton:focus-visible{outline:3px solid var(--azul-300);outline-offset:2px}

/* Modo oscuro: se reasignan siete variables y el sistema entero se invierte */
.oscuro{
  --nieve:#0A1628; --tinta:#F4F7FA;
  --niebla:#22334A; --niebla-fuerte:#3B506B; --acero:#9AAABB;
  --azul-500:#4A90E8; --azul-600:#9CC5F7;
  --exito:#45C79A; --alerta:#FF8A7A;
}

:root {
  /* ---- Timing para animaciones ---- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
  --duration-fast: 200ms;
  --duration-normal: 400ms;
  --duration-slow: 600ms;

  /* ---- Colores con opacidad (para superficies sobre fondo oscuro) ---- */
  --azul-300-15: rgb(var(--azul-300-rgb) / 0.15);
  --azul-300-40: rgb(var(--azul-300-rgb) / 0.4);

  /* ---- Sombras ---- */
  --sombra-sutil: 0 1px 3px rgb(var(--tinta-rgb) / 0.08);
  --sombra-media: 0 4px 12px rgb(var(--tinta-rgb) / 0.12);
  --sombra-elevada: 0 8px 24px rgb(var(--tinta-rgb) / 0.16);
  --sombra-fuerte: 0 24px 48px rgb(var(--tinta-rgb) / 0.3);
  --sombra-azul: 0 4px 16px rgb(var(--azul-500-rgb) / 0.24);

  /* ---- Breakpoints (solo como referencia, usar en media queries) ---- */
  /* 480px, 768px, 1024px, 1280px */

  /* ---- Escala de radios ----
     La marca fija 4px como radio base. Las superficies grandes usan múltiplos
     para no verse duras y --radio-pill es la píldora. Declarados acá para que no
     queden valores sueltos (100px, 999px) repartidos por las hojas. */
  --radio-sm: var(--radio);            /* 4px  · tarjetas, campos */
  --radio-md: calc(var(--radio) * 2);  /* 8px  · paquetes, formulario */
  --radio-lg: calc(var(--radio) * 3);  /* 12px · maquetas de chat y panel */
  --radio-xl: calc(var(--radio) * 4);  /* 16px · caja del teaser */
  --radio-pill: 999px;                 /* etiquetas y chips */

  /* ---- Contenedor ---- */
  --contenedor-max: 1200px;
  --contenedor-padding: calc(var(--u) * 2.5);

  /* ---- Fondos de Cloudinary (vacíos por defecto, agregar URLs cuando estén disponibles) ---- */
  --fondo-hero: none;
  --fondo-cierre: none;
}

@media (min-width: 768px) {
  :root {
    --contenedor-padding: calc(var(--u) * 4);
  }
}

@media (min-width: 1024px) {
  :root {
    --contenedor-padding: calc(var(--u) * 6);
  }
}

/* 2. Base (reset, tipografía, elementos HTML) */
/* ESCALARTE — Base
   Reset, tipografía y utilidades globales */

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

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

/* Sin `scroll-behavior: smooth` en html a propósito: rompía el salto inicial
   a un ancla de la URL (por ejemplo /#cierre, el CTA del header desde otra
   página), que terminaba en scrollY = 0. El suavizado de los enlaces internos
   lo hace main.js con scrollIntoView({ behavior: 'smooth' }). */

/* Al saltar a un ancla de sección, compensar el header fijo para que el
   encabezado no quede tapado (aplica a todo el sitio: #diagnostico, #cierre,
   #asis-beneficios, etc.). */
section[id],
main[id] {
  scroll-margin-top: calc(var(--u) * 14);
}

body {
  min-height: 100vh;
  text-rendering: optimizeSpeed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden; /* Evitar scroll horizontal en móvil */
}

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

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: none;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

/* ---- Tipografía ---- */
body {
  font-family: var(--texto);
  font-size: var(--t-md);
  line-height: 1.65;
  color: var(--tinta);
  background: var(--nieve);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--tinta);
}

h1 {
  font-size: clamp(var(--t-3xl), 5vw + 1rem, var(--t-4xl));
}

h2 {
  font-size: clamp(var(--t-2xl), 4vw + 0.5rem, var(--t-3xl));
}

h3 {
  font-size: var(--t-xl);
}

h4 {
  font-size: var(--t-lg);
}

p {
  max-width: var(--medida);
}

p + p {
  margin-top: calc(var(--u) * 2);
}

strong {
  font-weight: 600;
}

/* ---- Enlaces ---- */
.enlace {
  color: var(--azul-500);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--duration-fast) ease-out,
              -webkit-text-decoration-color var(--duration-fast) ease-out;
  transition: color var(--duration-fast) ease-out,
              text-decoration-color var(--duration-fast) ease-out;
  transition: color var(--duration-fast) ease-out,
              text-decoration-color var(--duration-fast) ease-out,
              -webkit-text-decoration-color var(--duration-fast) ease-out;
}

.enlace:hover {
  color: var(--azul-600);
}

.enlace:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Enlace con subrayado animado */
.enlace-animado {
  position: relative;
  text-decoration: none;
}

.enlace-animado::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: currentColor;
  transition: width var(--duration-normal) var(--ease-out-expo);
}

.enlace-animado:hover::after {
  width: 100%;
}

/* ---- Visibilidad ---- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Contenedor ---- */
.contenedor {
  width: 100%;
  max-width: var(--contenedor-max);
  margin-inline: auto;
  padding-inline: var(--contenedor-padding);
  /* iOS safe area */
  padding-left: max(var(--contenedor-padding), env(safe-area-inset-left));
  padding-right: max(var(--contenedor-padding), env(safe-area-inset-right));
}

/* 3. Componentes (botones, campos, tarjetas) */
/* ESCALARTE — Componentes
   Botones, tarjetas, campos de formulario */

/* ---- Botones ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 1);
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-md);
  line-height: 1;
  background: var(--azul-500);
  color: var(--blanco);
  border: 0;
  border-radius: var(--radio);
  padding: calc(var(--u) * 2) calc(var(--u) * 4);
  min-height: calc(var(--u) * 6);
  cursor: pointer;
  /* El box-shadow se compone de dos capas independientes: el trazo del borde
     (variantes outline) y el resplandor (variantes primario y grande). Antes cada
     modificador redeclaraba box-shadow entero y se borraban entre sí: el botón
     outline grande quedaba sin trazo porque .btn--grande ganaba por orden. */
  box-shadow: var(--btn-trazo, 0 0 transparent), var(--btn-resplandor, 0 0 transparent);
  transition: background var(--duration-fast) ease-out,
              transform var(--duration-fast) ease-out,
              box-shadow var(--duration-fast) ease-out;
}

.btn:hover {
  background: var(--azul-600);
  transform: scale(1.02);
  --btn-resplandor: var(--sombra-azul);
}

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

.btn:active {
  transform: scale(0.98);
}

/* El trazo va como box-shadow interior, no como border: así el botón outline
   mide exactamente lo mismo que el relleno (el border sumaba 4px de alto y los
   dejaba desnivelados cuando van uno al lado del otro). */
.btn--outline {
  background: transparent;
  color: var(--azul-500);
  --btn-trazo: inset 0 0 0 2px var(--azul-500);
}

.btn--outline:hover {
  background: var(--azul-50);
  color: var(--azul-600);
  --btn-trazo: inset 0 0 0 2px var(--azul-600);
  --btn-resplandor: 0 0 transparent;
}

/* Variante outline para fondos oscuros (tinta). Modificador del componente, no
   un override desde la hoja de la página. Se usa en el hero de las dos páginas
   y en el CTA del header. */
.btn--outline-claro {
  background: transparent;
  --btn-trazo: inset 0 0 0 2px var(--azul-300);
  color: var(--azul-200);
}

.btn--outline-claro:hover {
  background: var(--azul-300-15);
  --btn-trazo: inset 0 0 0 2px var(--azul-200);
  --btn-resplandor: 0 0 transparent;
  color: var(--blanco);
}

.btn--grande {
  font-size: var(--t-lg);
  padding: calc(var(--u) * 2.5) calc(var(--u) * 5);
  min-height: calc(var(--u) * 7);
}

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

/* Botón primario mejorado */
.btn--primario {
  background: linear-gradient(135deg, var(--azul-500) 0%, var(--azul-600) 100%);
  --btn-resplandor: 0 4px 14px rgb(var(--azul-500-rgb) / 0.35);
  position: relative;
  overflow: hidden;
}

.btn--primario::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgb(var(--blanco-rgb) / 0.2), transparent);
  transition: left 0.5s ease;
}

.btn--primario:hover {
  background: linear-gradient(135deg, var(--azul-400) 0%, var(--azul-500) 100%);
  --btn-resplandor: 0 6px 20px rgb(var(--azul-500-rgb) / 0.45);
  transform: translateY(-2px);
}

.btn--primario:hover::before {
  left: 100%;
}

.btn--primario:active {
  transform: translateY(0);
  --btn-resplandor: 0 2px 8px rgb(var(--azul-500-rgb) / 0.3);
}

/* Botón con icono */
.btn--enviar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 1.5);
}

.btn__icono {
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
  transition: transform var(--duration-fast) ease-out;
}

.btn--enviar:hover .btn__icono {
  transform: translateX(calc(var(--u) * 0.5));
}

/* Estado de carga */
.btn--cargando {
  pointer-events: none;
}

.btn--cargando .btn__icono {
  display: none;
}

.btn--cargando::after {
  content: '';
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
  border: 2px solid var(--blanco);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ---- Tarjetas ---- */
.card {
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-sutil);
  padding: calc(var(--u) * 3);
  transition: transform var(--duration-normal) var(--ease-out-expo),
              box-shadow var(--duration-normal) var(--ease-out-expo);
}

/* Tarjeta de síntoma */
.card--sintoma {
  display: flex;
  gap: calc(var(--u) * 2);
  align-items: flex-start;
  padding: calc(var(--u) * 3);
}

.card--sintoma .card__icono {
  flex-shrink: 0;
  width: calc(var(--u) * 6);
  height: calc(var(--u) * 6);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--azul-50);
  border-radius: var(--radio);
  color: var(--azul-500);
}

.card--sintoma .card__icono svg {
  width: calc(var(--u) * 3);
  height: calc(var(--u) * 3);
}

.card--sintoma .card__contenido {
  flex: 1;
}

.card--sintoma .card__titulo {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-md);
  margin-bottom: calc(var(--u) * 0.5);
  color: var(--tinta);
}

.card--sintoma .card__texto {
  font-size: var(--t-sm);
  color: var(--acero);
  line-height: 1.5;
}

/* ---- Campos de formulario ---- */
.field {
  position: relative;
  margin-bottom: calc(var(--u) * 3);
}

.field__label {
  display: block;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--tinta);
  margin-bottom: calc(var(--u) * 1);
}

.field__input {
  width: 100%;
  padding: calc(var(--u) * 1.5) calc(var(--u) * 2);
  font-size: var(--t-md);
  color: var(--tinta);
  background: var(--blanco);
  border: 1px solid var(--acero);
  border-radius: var(--radio);
  transition: border-color var(--duration-fast) ease-out,
              box-shadow var(--duration-fast) ease-out;
}

/* --niebla-fuerte sobre blanco da 1.80:1 y era ilegible al sol. --acero da
   5.09:1 y se sigue distinguiendo del valor escrito, que va en --tinta. */
.field__input::-moz-placeholder {
  color: var(--acero);
}
.field__input::placeholder {
  color: var(--acero);
}

.field__input:hover {
  border-color: var(--azul-400);
}

.field__input:focus {
  outline: none;
  border-color: var(--azul-500);
  box-shadow: 0 0 0 3px var(--azul-100);
}

.field__input:invalid:not(:-moz-placeholder) {
  border-color: var(--alerta);
}

.field__input:invalid:not(:placeholder-shown) {
  border-color: var(--alerta);
}

.field__error {
  font-size: var(--t-xs);
  color: var(--alerta);
  margin-top: calc(var(--u) * 0.5);
  display: none;
}

.field--error .field__input {
  border-color: var(--alerta);
}

.field--error .field__error {
  display: block;
}

/* Select estilizado */
.field--select .field__input {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235A6B7D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right calc(var(--u) * 2) center;
  padding-right: calc(var(--u) * 5);
  cursor: pointer;
}

/* ---- Grupo de checkboxes ---- */
.checkbox-group {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1.5);
}

.checkbox-group__label {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--tinta);
  margin-bottom: calc(var(--u) * 1);
}

.checkbox {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
  /* 44px de alto sin mover el dibujo del cuadro: agranda el objetivo táctil */
  min-height: calc(var(--u) * 5.5);
  cursor: pointer;
}

.checkbox__input {
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
  border: 2px solid var(--acero);
  border-radius: var(--radio);
  cursor: pointer;
  transition: background var(--duration-fast) ease-out,
              border-color var(--duration-fast) ease-out;
  position: relative;
  flex-shrink: 0;
  /* Evita auto-zoom en iOS */
  font-size: 16px;
}

.checkbox__input:hover {
  border-color: var(--azul-400);
}

.checkbox__input:checked {
  background: var(--azul-500);
  border-color: var(--azul-500);
}

.checkbox__input:checked::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 6px;
  height: 10px;
  border: solid var(--blanco);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

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

.checkbox__texto {
  font-size: var(--t-sm);
  color: var(--tinta);
}

/* ---- Checkbox expandible ---- */
.checkbox-expandible {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1);
}

.checkbox-expandible__campo {
  display: none;
  padding-left: calc(var(--u) * 3.5);
  animation: slideDown var(--duration-fast) ease-out;
}

.checkbox-expandible__campo.is-visible {
  display: block;
}

.field__input--sm {
  padding: calc(var(--u) * 1) calc(var(--u) * 1.5);
  /* Mínimo 16px para evitar auto-zoom en iOS */
  font-size: 16px;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(calc(var(--u) * -1));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ---- Enlace WhatsApp ---- */
.enlace-wa {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 1);
  min-height: calc(var(--u) * 5.5); /* 44px de área táctil */
  padding-inline: calc(var(--u) * 1);
  color: var(--acero);
  font-size: var(--t-sm);
  transition: color var(--duration-fast) ease-out;
}

.enlace-wa:hover {
  color: var(--tinta);
}

.enlace-wa:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: var(--radio-sm);
}

.enlace-wa svg {
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
}

/* ---- Mensaje de éxito del formulario ---- */
.cierre__formulario--saliendo {
  animation: fadeOutUp 0.3s ease-out forwards;
}

@keyframes fadeOutUp {
  to {
    opacity: 0;
    transform: translateY(calc(var(--u) * -2));
  }
}

.exito-mensaje {
  background: var(--blanco);
  border-radius: var(--radio-md);
  padding: calc(var(--u) * 6) calc(var(--u) * 4);
  text-align: center;
  box-shadow: var(--sombra-fuerte);
  position: relative;
  overflow: hidden;
  animation: fadeInUp 0.5s ease-out;
  min-height: calc(var(--u) * 40);
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(calc(var(--u) * 2));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.exito-mensaje__confetti {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  overflow: hidden;
}

.confetti__particula {
  position: absolute;
  width: calc(var(--u) * 1);
  height: calc(var(--u) * 1);
  top: -10px;
  border-radius: 2px;
  animation: confettiFall 2.5s ease-out forwards;
}

.confetti__particula:nth-child(odd) {
  width: calc(var(--u) * 0.75);
  height: calc(var(--u) * 1.5);
  border-radius: 1px;
}

.confetti__particula:nth-child(3n) {
  width: calc(var(--u) * 1.25);
  height: calc(var(--u) * 0.5);
}

@keyframes confettiFall {
  0% {
    transform: translateY(0) rotate(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(400px) rotate(720deg);
    opacity: 0;
  }
}

.exito-mensaje__contenido {
  position: relative;
  z-index: 1;
}

.exito-mensaje__icono {
  width: calc(var(--u) * 10);
  height: calc(var(--u) * 10);
  margin: 0 auto calc(var(--u) * 3);
  background: linear-gradient(135deg, var(--azul-400) 0%, var(--azul-500) 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--blanco);
  box-shadow: 0 8px 24px rgb(var(--azul-500-rgb) / 0.35);
  animation: checkBounce 0.6s ease-out 0.2s both;
}

.exito-mensaje__icono svg {
  width: calc(var(--u) * 5);
  height: calc(var(--u) * 5);
  animation: checkDraw 0.4s ease-out 0.5s both;
}

@keyframes checkBounce {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

@keyframes checkDraw {
  0% {
    stroke-dasharray: 50;
    stroke-dashoffset: 50;
  }
  100% {
    stroke-dasharray: 50;
    stroke-dashoffset: 0;
  }
}

.exito-mensaje__titulo {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 600;
  color: var(--tinta);
  margin-bottom: calc(var(--u) * 2);
}

.exito-mensaje__texto {
  font-size: var(--t-md);
  color: var(--acero);
  line-height: 1.6;
  max-width: 320px;
  margin: 0 auto;
}

/* ---- Banda de cierre ----
   La franja oscura con un titular y dos botones que cierra una página. Vivía en
   `asistente.css` como `.asis-cta`, atada a esa página; cuando servicios necesitó
   la misma banda, se movió acá con nombre propio en vez de copiarla. Es la regla
   de CLAUDE.md §7: un componente existe una sola vez. */
.cta-final {
  background: var(--tinta);
  background-image: var(--fondo-cierre);
  background-size: cover;
  background-position: center;
  color: var(--blanco);
  padding: calc(var(--u) * 10) 0;
  text-align: center;
}

.cta-final__titulo {
  font-size: clamp(var(--t-xl), 4vw + 0.5rem, var(--t-3xl));
  color: var(--blanco);
  margin-bottom: calc(var(--u) * 3);
  text-wrap: balance;
}

.cta-final__subtitulo {
  font-size: var(--t-lg);
  color: var(--azul-200);
  line-height: 1.6;
  max-width: 52ch;
  margin: 0 auto calc(var(--u) * 6);
}

.cta-final__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 2);
  justify-content: center;
}

.cta-final__acciones .btn {
  min-width: 224px;
}

@media (min-width: 768px) {
  .cta-final {
    padding: calc(var(--u) * 14) 0;
  }
}

/* ---- Paquetes ----
   Las tarjetas de paquete. Vivían en `sections.css` como una sección más
   de la landing; el día que `/servicios` necesitó las mismas, se movieron acá.
   Las dos páginas usan estas reglas, no una copia: es la regla de CLAUDE.md §7,
   un componente existe una sola vez. Si se editan, cambian en los dos lados. */

/* ---- Paquetes ---- */
.paquetes {
  background: var(--blanco);
  padding: calc(var(--u) * 10) 0;
  position: relative;
}

.paquetes__grid {
  display: grid;
  gap: calc(var(--u) * 4);
  max-width: 1000px;
  margin: 0 auto;
}

.paquete {
  background: var(--nieve);
  border-radius: var(--radio-md);
  padding: calc(var(--u) * 4);
  position: relative;
  overflow: hidden;
  transition: transform var(--duration-normal) var(--ease-out-expo),
              box-shadow var(--duration-normal) var(--ease-out-expo);
}

.paquete::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--azul-400), var(--azul-500));
}

.paquete:hover,
.paquete[data-animate].is-visible:hover {
  transform: var(--tilt, ) translateY(-8px);
  box-shadow: var(--sombra-elevada);
}

.paquete--destacado {
  background: linear-gradient(135deg, var(--azul-700) 0%, var(--tinta) 100%);
  color: var(--blanco);
  padding-top: calc(var(--u) * 6);
}

.paquete--destacado::before {
  background: linear-gradient(90deg, var(--azul-200), var(--azul-300));
}

.paquete__etiqueta {
  position: absolute;
  top: calc(var(--u) * 2);
  right: calc(var(--u) * 2);
  background: var(--exito-alto);
  color: var(--tinta);
  font-size: var(--t-xs);
  font-weight: 600;
  padding: calc(var(--u) * 0.5) calc(var(--u) * 1.5);
  border-radius: var(--radio);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.paquete__nombre {
  font-family: var(--display);
  font-size: var(--t-2xl);
  font-weight: 600;
  margin-bottom: calc(var(--u) * 2);
  color: var(--azul-500);
}

.paquete--destacado .paquete__nombre {
  color: var(--blanco);
}

.paquete__descripcion {
  font-size: var(--t-md);
  line-height: 1.6;
  margin-bottom: calc(var(--u) * 3);
  color: var(--acero);
}

.paquete--destacado .paquete__descripcion {
  color: var(--azul-200);
}

.paquete__lista {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1.5);
}

.paquete__item {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--u) * 1);
  font-size: var(--t-sm);
}

.paquete__item::before {
  content: '';
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231B55B8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
  background-size: contain;
}

.paquete--destacado .paquete__item::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2345C79A' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
}

.paquetes__enlace {
  text-align: center;
  margin-top: calc(var(--u) * 6);
}

/* El segundo enlace va pegado al primero: son dos caminos del mismo remate —ver
   el detalle o preguntar precio—, no dos secciones. */
.paquetes__enlace--wa {
  margin-top: calc(var(--u) * 2);
}

/* El enlace de la sección de paquetes es un objetivo táctil real */
.paquetes__enlace .enlace {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--u) * 5.5);
}

@media (min-width: 768px) {
  .paquetes {
    padding: calc(var(--u) * 14) 0;
  }

  .paquetes__grid {
    grid-template-columns: repeat(3, 1fr);
    align-items: stretch;
  }

  .paquete--destacado {
    transform: scale(1.05);
    z-index: 1;
  }

  .paquete--destacado:hover,
  .paquete--destacado[data-animate].is-visible:hover {
    /* Conserva su 5% de tamaño: antes el tilt en línea lo borraba y la tarjeta
       destacada se encogía justo al pasarle el mouse. */
    transform: var(--tilt, ) scale(1.05) translateY(-8px);
  }
}

/* La señal de inversión relativa, la misma que llevan el brochure y la propuesta.
   No es un precio: es el escalón. En la mono, porque es cifra (§6). */
.paquete__senal {
  font-family: var(--dato);
  font-size: var(--t-lg);
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--azul-500);
}

.paquete--destacado .paquete__senal {
  color: var(--azul-200);
}

/* El nombre y la señal comparten renglón: el escalón se lee junto al nivel, no
   suelto en otra línea. */
.paquete__titular {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(var(--u) * 2);
  margin-bottom: calc(var(--u) * 2);
}

.paquete__titular .paquete__nombre {
  margin-bottom: 0;
}

/* 4. Layout (header, footer, contenedores) */
/* ESCALARTE — Layout
   Header, footer, estructura general */

/* ---- Layout principal ---- */
.pagina {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.pagina__contenido {
  flex: 1;
}

/* Enlace de salto al contenido: invisible hasta que recibe el foco. Con header
   fijo y 5-7 secciones, un usuario de teclado tenía que recorrer el header en
   cada página (WCAG 2.4.1). */
/* Enlace de salto al contenido (accesibilidad por teclado).
   Se oculta recortándolo a 1px, NO desplazándolo hacia arriba: desplazado seguía
   ocupando lugar en el documento y asomaba por encima del header al hacer
   overscroll (el rebote al tirar del scroll hacia arriba). Recortado no ocupa
   espacio y no puede aparecer por accidente; al recibir el foco vuelve a su
   tamaño real. */
.salto-contenido {
  position: absolute;
  top: calc(var(--u) * 1);
  left: calc(var(--u) * 1);
  z-index: 200;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  -webkit-clip-path: inset(50%);
          clip-path: inset(50%);
  white-space: nowrap;
  background: var(--blanco);
  color: var(--azul-600);
  font-size: var(--t-sm);
  font-weight: 600;
  border-radius: var(--radio-sm);
  box-shadow: var(--sombra-media);
}

.salto-contenido:focus {
  width: auto;
  height: auto;
  padding: calc(var(--u) * 1.5) calc(var(--u) * 2);
  overflow: visible;
  -webkit-clip-path: none;
          clip-path: none;
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
}

/* ---- Header ---- */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: var(--tinta);
  border-bottom: 1px solid transparent;
  padding: calc(var(--u) * 2) 0;
  transition: background var(--duration-normal) ease,
              border-color var(--duration-normal) ease,
              -webkit-backdrop-filter var(--duration-normal) ease;
  transition: background var(--duration-normal) ease,
              border-color var(--duration-normal) ease,
              backdrop-filter var(--duration-normal) ease;
  transition: background var(--duration-normal) ease,
              border-color var(--duration-normal) ease,
              backdrop-filter var(--duration-normal) ease,
              -webkit-backdrop-filter var(--duration-normal) ease;
}

/* Header al hacer scroll */
.header.is-scrolled {
  background: rgb(var(--tinta-rgb) / 0.95);
  border-bottom-color: var(--azul-700);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.header__contenedor {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--u) * 2);
}

/* Logo del header. Dos versiones de la marca en el mismo componente:
   isotipo (compacto) en pantallas chicas e imagotipo completo desde tablet.
   `flex-shrink: 0` evita que el flex lo aplaste a un tamaño arbitrario.
   El símbolo mide 40px a los dos lados del punto de quiebre: al pasar a tablet
   no crece, solo aparece el logotipo a su lado. */
.header__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  min-height: calc(var(--u) * 5.5); /* 44px de área táctil */
}

.header__logo svg {
  height: calc(var(--u) * 5);
  width: auto;
  max-width: none;
}

.header__logo:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: 2px;
}

.header__logo-completo {
  display: none;
}

@media (min-width: 768px) {
  .header__logo-compacto {
    display: none;
  }

  .header__logo-completo {
    display: block;
  }
}

/* Navegación del header (links de texto + CTA agrupados a la derecha) */
.header__nav {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
}

.header__nav-link {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--u) * 5.5); /* 44px — área táctil mínima */
  color: var(--blanco);
  font-size: var(--t-sm);
  font-weight: 500;
  padding: calc(var(--u) * 1) calc(var(--u) * 1.5);
  transition: color var(--duration-fast) ease-out;
}

.header__nav-link:hover {
  color: var(--azul-200);
}

.header__nav-link:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: 2px;
}

@media (min-width: 480px) {
  .header__nav {
    gap: calc(var(--u) * 2.5);
  }
}

@media (min-width: 768px) {
  .header__nav {
    gap: calc(var(--u) * 3.5);
  }
}

/* Botón del header. El aspecto lo da el modificador .btn--outline-claro del
   componente (antes esta hoja repintaba el .btn desde fuera, con dos colores
   rgba que no estaban en los tokens). Acá solo lo propio del header: la etiqueta
   se acorta en celulares chicos para que el CTA no desaparezca. */
.header__cta {
  padding: calc(var(--u) * 1) calc(var(--u) * 2);
  font-size: var(--t-sm);
}

.header__cta-largo {
  display: none;
}

@media (min-width: 480px) {
  .header__cta {
    padding: calc(var(--u) * 2) calc(var(--u) * 4);
    font-size: var(--t-md);
  }

  .header__cta-largo {
    display: inline;
  }

  .header__cta-corto {
    display: none;
  }
}

@media (min-width: 768px) {
  .header {
    padding: calc(var(--u) * 2.5) 0;
  }
}

/* ---- Footer ---- */
.footer {
  background: var(--tinta);
  color: var(--blanco);
  padding: calc(var(--u) * 6) 0;
  padding-bottom: max(calc(var(--u) * 6), env(safe-area-inset-bottom));
  border-top: 1px solid var(--azul-700);
}

.footer__contenedor {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 3);
  text-align: center;
}

.footer__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  /* 44x44 de área táctil, aunque el dibujo sea más chico */
  min-height: calc(var(--u) * 5.5);
  min-width: calc(var(--u) * 5.5);
}

.footer__logo svg {
  height: calc(var(--u) * 4);
  width: auto;
}

.footer__logo:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: 2px;
}

.footer__texto {
  font-size: var(--t-sm);
  color: var(--azul-200);
  max-width: 40ch;
}

.footer__legal {
  font-size: var(--t-xs);
  /* --acero sobre tinta da 3.31:1 y no llega al mínimo AA de 4.5:1 para texto
     pequeño. --niebla-fuerte da 10.09:1 y se mantiene neutro, así que sigue
     leyéndose como secundario frente al azul de .footer__texto. */
  color: var(--niebla-fuerte);
}

.footer__nav {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 3);
}

.footer__enlace {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--u) * 5.5); /* 44px de área táctil */
  color: var(--azul-300);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--duration-fast) ease-out;
}

.footer__enlace:hover {
  color: var(--azul-200);
}

.footer__enlace:focus-visible {
  outline: 3px solid var(--azul-300);
  outline-offset: 2px;
  border-radius: var(--radio-sm);
}

@media (min-width: 768px) {
  .footer {
    padding: calc(var(--u) * 8) 0;
  }

  .footer__contenedor {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }

  .footer__logo svg {
    height: calc(var(--u) * 5);
  }
}

/* ---- Secciones ---- */
.seccion__titulo {
  margin-bottom: calc(var(--u) * 2);
}

.seccion__subtitulo {
  color: var(--acero);
  font-size: var(--t-lg);
  max-width: 50ch;
  margin-bottom: calc(var(--u) * 5);
}

/* Cabecera de sección centrada. Existe UNA sola vez y la usan las siete
   secciones de las dos páginas (antes estaba repetida cuatro veces). */
.seccion__encab {
  text-align: center;
  max-width: 600px;
  margin: 0 auto calc(var(--u) * 8);
}

.seccion__encab .seccion__titulo {
  margin-bottom: calc(var(--u) * 2);
}

.seccion__encab .seccion__subtitulo {
  color: var(--acero);
  font-size: var(--t-lg);
  /* Hereda max-width en ch, así que sin esto queda pegado a la izquierda
     mientras la tipografía todavía no cargó. */
  margin-inline: auto;
  /* El aire hasta el contenido lo pone el margen del propio .seccion__encab:
     si además se deja el del subtítulo, se suman dos márgenes. */
  margin-bottom: 0;
}

/* 5. Secciones de la landing */
/* ESCALARTE — Secciones
   Hero, diagnóstico, proceso, cierre.
   Las tarjetas de paquete se mudaron a `components.css` el 2026-08-05: las usan
   el home y /servicios, así que dejaron de ser una sección de la landing. */

/* ---- Hero ----
   Base compartida por los hero del sitio (.hero, que usan el home y /servicios,
   y .asis-hero de la landing) para que no puedan desincronizarse: el alto, el
   relleno y la retícula de tres filas —contenido centrado, indicador al pie—
   viven acá una sola vez. */
.hero,
.asis-hero {
  min-height: 100vh;
  min-height: 100dvh; /* Dynamic viewport height para iOS */
  display: grid;
  grid-template-rows: 1fr auto auto;
  align-items: center;
  padding: calc(var(--u) * 12) 0 calc(var(--u) * 3);
  background: var(--tinta);
  background-image: var(--fondo-hero);
  background-size: cover;
  background-position: center;
  position: relative;
  overflow: hidden;
}

.hero {
  text-align: center;
}

.hero__contenido {
  position: relative;
  z-index: 1;
  grid-row: 2;
  /* Layout lo maneja .contenedor - solo max-width específico para hero */
  max-width: 900px;
  justify-self: center;
}

/* Badge/Etiqueta encima del título */
.hero__badge {
  display: inline-block;
  background: var(--azul-300-15);
  border: 1px solid var(--azul-300-40);
  color: var(--azul-200);
  font-size: var(--t-sm);
  font-weight: 500;
  padding: calc(var(--u) * 1) calc(var(--u) * 3);
  border-radius: var(--radio-pill);
  margin-bottom: calc(var(--u) * 4);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
}

.hero__titulo {
  font-size: clamp(var(--t-2xl), 5vw + 1rem, var(--t-4xl));
  color: var(--blanco);
  margin-bottom: calc(var(--u) * 4);
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.hero__subtitulo,
.asis-hero__subtitulo {
  font-size: clamp(var(--t-md), 1.5vw + 0.5rem, var(--t-lg));
  color: var(--azul-200);
  margin: 0 auto calc(var(--u) * 5);
  line-height: 1.6;
  /* Medida de texto en ch, no un px suelto: antes eran 550 en una página y 540
     en la otra, dos valores casi iguales para el mismo elemento. */
  max-width: 52ch;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 2);
  justify-content: center;
  align-items: center;
}

/* En móvil los dos CTA van a ancho completo: apilados con anchos distintos
   (315 contra 202 medidos) se leían como un error de maquetado. */
.hero__cta .btn,
.asis-hero__acciones .btn {
  width: 100%;
}

@media (min-width: 768px) {
  .hero__cta .btn,
  .asis-hero__acciones .btn {
    width: auto;
    min-width: 200px;
  }
}

/* El botón outline sobre el hero oscuro usa el modificador .btn--outline-claro
   (definido en components.css), no un override desde esta hoja. */

/* Scroll indicator */
.hero__scroll {
  grid-row: 3;
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 1);
  /* Con opacidad 0.7 sobre tinta, --azul-300 daba 3.35:1 (falla AA).
     --azul-200 al 70% da 5.51:1 y sigue siendo un azul discreto. */
  color: var(--azul-200);
  font-size: var(--t-xs);
  opacity: 0.7;
  z-index: 10;
  /* Espacio superior para separar del contenido */
  margin-top: calc(var(--u) * 6);
  /* Espacio inferior seguro para iOS */
  padding-bottom: max(calc(var(--u) * 2), env(safe-area-inset-bottom));
}

/* En pantallas muy cortas, ocultar el scroll indicator */
@media (max-height: 500px) {
  .hero__scroll {
    display: none;
  }
}

.hero__scroll-icon {
  width: 24px;
  height: 24px;
}

@media (min-width: 768px) {
  .hero,
  .asis-hero {
    padding-top: calc(var(--u) * 16);
  }

  .hero__badge {
    margin-bottom: calc(var(--u) * 5);
  }

  .hero__titulo {
    margin-bottom: calc(var(--u) * 5);
  }
}

/* ---- Diagnóstico (síntomas) ---- */
.diagnostico {
  background: var(--blanco);
  position: relative;
  padding: calc(var(--u) * 10) 0;
}

.diagnostico__grid {
  display: grid;
  gap: calc(var(--u) * 3);
}

@media (min-width: 768px) {
  .diagnostico {
    padding: calc(var(--u) * 14) 0;
  }

  .diagnostico__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: calc(var(--u) * 4);
  }
}

@media (min-width: 1024px) {
  .diagnostico__grid {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto auto;
    gap: calc(var(--u) * 8) calc(var(--u) * 6);
    position: relative;
    padding: calc(var(--u) * 4) 0;
  }

  /* Líneas de conexión tipo red neuronal */
  .diagnostico__grid::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 10%;
    right: 10%;
    height: 2px;
    background: linear-gradient(90deg,
      transparent 0%,
      var(--azul-200) 20%,
      var(--azul-200) 80%,
      transparent 100%
    );
    opacity: 0.4;
    z-index: 0;
  }

  .diagnostico__grid::after {
    content: '';
    position: absolute;
    top: 20%;
    bottom: 20%;
    left: 50%;
    width: 2px;
    background: linear-gradient(180deg,
      transparent 0%,
      var(--azul-200) 30%,
      var(--azul-200) 70%,
      transparent 100%
    );
    opacity: 0.4;
    z-index: 0;
  }

  /* Las tarjetas van sobre las líneas de conexión.
     Nota: acá había además rotaciones y desplazamientos por nth-child que NUNCA
     se aplicaban —los ganaba `.card--sintoma[data-animate].is-visible`, de mayor
     especificidad y declarada después— así que se quitaron. Si alguna vez se
     quiere ese efecto orgánico, hay que declararlo como estado de revelado
     (`...is-visible`) para que gane la cascada. */
  .diagnostico__grid > * {
    z-index: 1;
  }

  .diagnostico__grid > :nth-child(4) {
    grid-column: 1 / 2;
  }

  .diagnostico__grid > :nth-child(5) {
    grid-column: 3 / 4;
  }
}

/* ---- Proceso (timeline) ---- */
.proceso {
  background: var(--nieve);
  padding: calc(var(--u) * 10) 0;
  position: relative;
  overflow: hidden;
}

.proceso__timeline {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 5);
  max-width: 800px;
  margin: 0 auto;
}

.proceso__linea {
  position: absolute;
  left: calc(var(--u) * 3 - 1px);
  /* Conecta centro del número 1 al centro del número 3 */
  top: calc(var(--u) * 3);
  bottom: calc(var(--u) * 6);
  width: 3px;
  background: linear-gradient(
    to bottom,
    var(--azul-300) 0%,
    var(--azul-500) 50%,
    var(--tinta) 100%
  );
  border-radius: 2px;
  transform-origin: top;
}

.proceso__paso {
  display: grid;
  grid-template-columns: calc(var(--u) * 6) 1fr;
  gap: calc(var(--u) * 3);
  align-items: start;
}

.proceso__paso-numero {
  width: calc(var(--u) * 6);
  height: calc(var(--u) * 6);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-lg);
  color: var(--blanco);
  position: relative;
  z-index: 1;
  box-shadow: var(--sombra-media);
}

.proceso__paso:nth-child(2) .proceso__paso-numero {
  background: linear-gradient(135deg, var(--azul-200) 0%, var(--azul-300) 100%);
}

.proceso__paso:nth-child(3) .proceso__paso-numero {
  background: linear-gradient(135deg, var(--azul-400) 0%, var(--azul-500) 100%);
}

.proceso__paso:nth-child(4) .proceso__paso-numero {
  background: linear-gradient(135deg, var(--azul-600) 0%, var(--tinta) 100%);
}

.proceso__paso-contenido {
  padding-top: calc(var(--u) * 1);
}

.proceso__paso-titulo {
  font-size: var(--t-xl);
  margin-bottom: calc(var(--u) * 1);
  color: var(--tinta);
}

.proceso__paso-texto {
  color: var(--acero);
  font-size: var(--t-md);
  line-height: 1.6;
}

@media (min-width: 768px) {
  .proceso {
    padding: calc(var(--u) * 14) 0;
  }

  .proceso__timeline {
    flex-direction: row;
    justify-content: space-between;
    gap: calc(var(--u) * 4);
    max-width: none;
  }

  .proceso__linea {
    left: 0;
    right: 0;
    top: calc(var(--u) * 3);
    bottom: auto;
    width: auto;
    height: 3px;
    background: linear-gradient(
      to right,
      var(--azul-300) 0%,
      var(--azul-500) 50%,
      var(--tinta) 100%
    );
    transform-origin: left;
  }

  .proceso__paso {
    flex: 1;
    grid-template-columns: 1fr;
    gap: calc(var(--u) * 2);
    text-align: center;
  }

  .proceso__paso-numero {
    margin: 0 auto;
  }

  .proceso__paso-contenido {
    padding-top: 0;
  }
}

/* ---- Cierre (CTA final) ---- */
.cierre {
  background: var(--tinta);
  background-image: var(--fondo-cierre);
  background-size: cover;
  background-position: center;
  color: var(--blanco);
  padding: calc(var(--u) * 10) 0;
  position: relative;
  overflow: hidden;
}

.cierre__contenedor {
  position: relative;
  z-index: 1;
}

.cierre__contenido {
  display: grid;
  gap: calc(var(--u) * 6);
  align-items: center;
}

.cierre__texto {
  text-align: center;
}

.cierre__texto .seccion__titulo {
  color: var(--blanco);
  font-size: clamp(var(--t-xl), 4vw + 0.5rem, var(--t-3xl));
  margin-bottom: calc(var(--u) * 3);
}

.cierre__texto .seccion__subtitulo {
  color: var(--azul-200);
  font-size: var(--t-lg);
  line-height: 1.6;
  max-width: 52ch;
  margin: 0 auto;
}

.cierre__formulario {
  background: var(--blanco);
  border-radius: var(--radio-md);
  padding: calc(var(--u) * 4);
  color: var(--tinta);
  box-shadow: var(--sombra-fuerte);
  max-width: 52ch;
  margin: 0 auto;
}

.cierre__formulario-titulo {
  font-size: var(--t-lg);
  margin-bottom: calc(var(--u) * 3);
  text-align: center;
}

.cierre__form-grid {
  display: grid;
  gap: 0;
}

/* Botón del formulario con separación */
.cierre__btn-submit {
  margin-top: calc(var(--u) * 3);
}

.cierre__alternativa {
  text-align: center;
  padding-top: calc(var(--u) * 3);
  border-top: 1px solid var(--niebla);
  margin-top: calc(var(--u) * 3);
}

.cierre__alternativa-texto {
  font-size: var(--t-sm);
  color: var(--acero);
  margin-bottom: calc(var(--u) * 1);
}

@media (min-width: 768px) {
  .cierre {
    padding: calc(var(--u) * 14) 0;
  }

  .cierre__contenido {
    grid-template-columns: 1fr 1fr;
    gap: calc(var(--u) * 8);
  }

  .cierre__texto {
    text-align: left;
  }

  .cierre__texto .seccion__subtitulo {
    margin: 0;
  }

  .cierre__formulario {
    padding: calc(var(--u) * 5);
    max-width: none;
  }

  .cierre__form-grid {
    grid-template-columns: 1fr 1fr;
    gap: 0 calc(var(--u) * 3);
  }

  .cierre__form-grid .field:nth-child(3),
  .cierre__form-grid .checkbox-group {
    grid-column: span 2;
  }
}

/* 6. Animaciones con Intersection Observer */
/* ESCALARTE — Sistema de Animaciones
   Profesionales y visibles, respetando prefers-reduced-motion */

/* ---- Redes de seguridad: mostrar todo el contenido de una vez ----
   Dos escenarios de falla de carga en los que el contenido NUNCA debe quedar
   invisible:
   1. `.no-js`  — el JS está deshabilitado o no cargó; la clase queda en <html>
      (ver js/deteccion.js) y el contenido se muestra completo.
   2. `.sin-animaciones` — el JS cargó (clase `js`) pero `animations.js` falló y
      nunca reveló el contenido; deteccion.js agrega esta clase pasado un tiempo
      prudente como respaldo. En el flujo normal nunca se activa. */
.no-js [data-animate],
.no-js .proceso__linea,
.sin-animaciones [data-animate],
.sin-animaciones .proceso__linea {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* ---- Estado inicial para elementos animados ---- */
[data-animate] {
  opacity: 0;
}

[data-animate="up"] {
  transform: translateY(40px);
}

[data-animate="down"] {
  transform: translateY(-40px);
}

[data-animate="left"] {
  transform: translateX(-40px);
}

[data-animate="right"] {
  transform: translateX(40px);
}

[data-animate="scale"] {
  transform: scale(0.9);
}

[data-animate="fade"] {
  transform: none;
}

/* ---- Estado visible ---- */
[data-animate].is-visible {
  opacity: 1;
  transform: translateY(0) translateX(0) scale(1);
  transition:
    opacity var(--duration-slow) var(--ease-out-expo),
    transform var(--duration-slow) var(--ease-out-expo);
}

/* ---- Delays para stagger ---- */
[data-delay="1"] { transition-delay: 100ms; }
[data-delay="2"] { transition-delay: 200ms; }
[data-delay="3"] { transition-delay: 300ms; }
[data-delay="4"] { transition-delay: 400ms; }
[data-delay="5"] { transition-delay: 500ms; }
[data-delay="6"] { transition-delay: 600ms; }

/* ---- Hero especial (home y landing del asistente) ---- */
.hero [data-animate],
.asis-hero [data-animate] {
  transition-duration: 800ms;
}

.hero__badge[data-animate] {
  transform: translateY(20px) scale(0.9);
  transition-delay: 100ms;
}

.hero__badge[data-animate].is-visible {
  transform: translateY(0) scale(1);
}

.hero__titulo[data-animate],
.asis-hero__titulo[data-animate] {
  transform: translateY(40px);
  transition-delay: 250ms;
}

/* Regla espejo obligatoria: sin esto la de arriba (misma especificidad y
   posterior a [data-animate].is-visible) gana siempre y el título queda
   40px abajo para siempre, comiéndose el aire hasta el subtítulo. */
.hero__titulo[data-animate].is-visible,
.asis-hero__titulo[data-animate].is-visible {
  transform: translateY(0);
}

.hero__subtitulo[data-animate],
.asis-hero__subtitulo[data-animate] {
  transition-delay: 450ms;
}

.hero__cta[data-animate],
.asis-hero__acciones[data-animate] {
  transition-delay: 650ms;
}

/* El indicador aparece al final; la declaración de `animation` completa (con el
   rebote) está más abajo, en el bloque de micro-interacciones. */
.hero__scroll {
  opacity: 0;
  transform: translateY(-10px);
}

@keyframes fadeInScroll {
  to {
    opacity: 0.7;
    transform: translateY(0);
  }
}

/* ---- Línea del proceso animada ---- */
.proceso__linea {
  transform: scaleY(0);
  transition: transform 1000ms var(--ease-out-expo);
}

.proceso__linea.is-visible {
  transform: scaleY(1);
}

@media (min-width: 768px) {
  .proceso__linea {
    transform: scaleX(0);
    transform-origin: left;
  }

  .proceso__linea.is-visible {
    transform: scaleX(1);
  }
}

/* ---- Pasos del proceso ---- */
.proceso__paso[data-animate] {
  transform: translateY(30px);
}

.proceso__paso[data-animate].is-visible {
  transform: translateY(0);
}

/* ---- Tarjetas de síntomas ---- */
.card--sintoma[data-animate] {
  transform: translateY(30px) scale(0.95);
}

.card--sintoma[data-animate].is-visible {
  transform: translateY(0) scale(1);
  transition:
    opacity var(--duration-normal) var(--ease-out-expo),
    transform var(--duration-normal) var(--ease-out-back);
}

/* ---- Paquetes ---- */
.paquete[data-animate] {
  transform: translateY(40px) scale(0.95);
}

.paquete[data-animate].is-visible {
  transform: translateY(0) scale(1);
  transition:
    opacity var(--duration-slow) var(--ease-out-expo),
    transform var(--duration-slow) var(--ease-out-back);
}

.paquete--destacado[data-animate].is-visible {
  transform: scale(1.05);
}

/* ---- Formulario ---- */
.cierre__formulario[data-animate] {
  transform: translateY(50px) scale(0.95);
}

.cierre__formulario[data-animate].is-visible {
  transform: translateY(0) scale(1);
  transition-duration: 700ms;
}

/* ---- Micro-interacciones ---- */

/* Botón con efecto de onda */
.btn {
  position: relative;
  overflow: hidden;
}

.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at center, rgb(var(--blanco-rgb) / 0.3) 0%, transparent 70%);
  transform: scale(0);
  opacity: 0;
  transition: transform 500ms var(--ease-out-expo), opacity 300ms ease;
}

.btn:active::after {
  transform: scale(2);
  opacity: 1;
  transition: transform 0ms, opacity 0ms;
}

/* ---- Tarjetas: un solo bloque por selector y por estado ----
   Antes esto estaba repartido en cuatro lugares con la transición y el
   box-shadow declarados dos veces cada uno. Esa fragmentación fue justo lo que
   dejó pasar los bugs de cascada: una regla pisaba a la otra en silencio. */
.card--sintoma,
.paquete {
  transform-style: preserve-3d;
  transition:
    transform var(--duration-normal) var(--ease-out-expo),
    box-shadow var(--duration-normal) var(--ease-out-expo);
}

/* El giro llega como --tilt desde main.js y se compone con la elevación, en vez
   de que el JS escriba el transform completo y borre la posición del CSS.
   El selector espeja el del estado revelado (`[data-animate].is-visible`): si no,
   pierde la cascada por especificidad y el hover queda sin efecto. */
.card--sintoma:hover,
.card--sintoma[data-animate].is-visible:hover {
  transform: var(--tilt, ) translateY(-6px);
  box-shadow:
    var(--sombra-media),
    0 15px 40px rgb(var(--azul-500-rgb) / 0.15);
}

/* Iconos con rotación suave */
.card--sintoma .card__icono {
  transition: transform var(--duration-normal) var(--ease-out-back);
}

.card--sintoma:hover .card__icono {
  transform: scale(1.1) rotate(5deg);
}

/* Números del proceso con pulso */
.proceso__paso-numero {
  transition: transform var(--duration-normal) var(--ease-out-back),
              box-shadow var(--duration-normal) var(--ease-out-expo);
}

.proceso__paso:hover .proceso__paso-numero {
  transform: scale(1.1);
  box-shadow: var(--sombra-elevada);
}

/* ---- Efecto de brillo en paquetes ---- */
.paquete {
  position: relative;
  overflow: hidden;
}

.paquete::after {
  content: '';
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: linear-gradient(
    45deg,
    transparent 40%,
    rgb(var(--blanco-rgb) / 0.1) 50%,
    transparent 60%
  );
  transform: translateX(-100%);
  transition: transform 600ms ease;
  pointer-events: none;
}

.paquete:hover::after {
  transform: translateX(100%);
}

.paquete:hover {
  box-shadow:
    var(--sombra-elevada),
    0 20px 50px rgb(var(--azul-500-rgb) / 0.2);
}

.paquete--destacado:hover {
  box-shadow:
    var(--sombra-elevada),
    0 25px 60px rgb(var(--azul-500-rgb) / 0.25);
}

/* ---- Animación de la línea del proceso ---- */
/* ---- Efecto hover en pasos del proceso ---- */
.proceso__paso {
  transition: transform var(--duration-normal) var(--ease-out-expo);
}

.proceso__paso[data-animate].is-visible:hover {
  transform: translateY(-4px);
}

.proceso__paso:hover .proceso__paso-numero {
  transform: scale(1.15) rotate(-5deg);
}

/* ---- Animación del scroll indicator ---- */
@keyframes bounce-scroll {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(10px); }
}

.hero__scroll {
  animation: fadeInScroll 600ms var(--ease-out-expo) 1.5s forwards,
             bounce-scroll 2s ease-in-out 2.5s infinite;
}

/* ---- Botón CTA con glow ---- */
.btn--grande {
  --btn-resplandor: 0 4px 15px rgb(var(--azul-500-rgb) / 0.3);
  transition:
    background var(--duration-fast) ease,
    transform var(--duration-fast) ease,
    box-shadow var(--duration-normal) ease;
}

.btn--grande:hover {
  --btn-resplandor: 0 6px 25px rgb(var(--azul-500-rgb) / 0.5);
}

/* ---- Respeto a preferencias del usuario ---- */
@media (prefers-reduced-motion: reduce) {
  [data-animate],
  [data-animate].is-visible,
  .hero__badge[data-animate],
  .hero__badge[data-animate].is-visible,
  .hero__titulo[data-animate],
  .hero__titulo[data-animate].is-visible,
  .hero__subtitulo[data-animate],
  .hero__subtitulo[data-animate].is-visible,
  .hero__cta[data-animate],
  .hero__cta[data-animate].is-visible,
  .proceso__paso[data-animate],
  .proceso__paso[data-animate].is-visible,
  .card--sintoma[data-animate],
  .card--sintoma[data-animate].is-visible,
  .paquete[data-animate],
  .paquete[data-animate].is-visible,
  .cierre__formulario[data-animate],
  .cierre__formulario[data-animate].is-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .paquete--destacado[data-animate].is-visible {
    transform: scale(1.05);
  }

  .proceso__linea,
  .proceso__linea.is-visible {
    transform: none;
    transition: none;
  }

  .btn::after,
  .paquete::after {
    display: none;
  }

  .card--sintoma:hover,
  .paquete:hover,
  .paquete--destacado:hover,
  .proceso__paso:hover {
    transform: none;
  }

  .card--sintoma:hover .card__icono,
  .proceso__paso:hover .proceso__paso-numero {
    transform: none;
  }

  /* El mensaje de éxito del formulario también tiene que quedarse quieto */
  .exito-mensaje,
  .exito-mensaje__icono,
  .exito-mensaje__icono svg,
  .cierre__formulario--saliendo {
    animation: none !important;
    transform: none !important;
  }

  .confetti__particula {
    display: none;
  }

  .hero__scroll {
    animation: none;
    opacity: 0.7;
    transform: none;
  }

}

/* 7. Animación de intro/splash */
/* ESCALARTE — Animación de Intro
   Overlay con isotipo que se recoge para revelar la página */

/* ---- Overlay de intro ---- */
.intro {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--tinta);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: all;
}

.intro.is-done {
  pointer-events: none;
}

/* ---- Isotipo animado ---- */
.intro__isotipo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--u) * 2);
  transform: scale(1.5);
}

@media (min-width: 768px) {
  .intro__isotipo {
    transform: scale(2);
  }
}

@media (min-width: 1024px) {
  .intro__isotipo {
    transform: scale(2.5);
  }
}

/* Barras del isotipo */
.intro__barra {
  height: calc(var(--u) * 2);
  transform-origin: top center;
  will-change: transform, opacity;
}

/* Variante del isotipo para fondo oscuro, la misma del header y del pie: antes
   mezclaba dos variantes y el peldaño medio (azul-500 sobre tinta) quedaba en
   2.62:1, casi invisible durante los 3 segundos del splash. */
.intro__barra--1 {
  width: calc(var(--u) * 6);
  background: var(--azul-400);
}

.intro__barra--2 {
  width: calc(var(--u) * 9);
  background: var(--azul-200);
}

.intro__barra--3 {
  width: calc(var(--u) * 12);
  background: var(--blanco);
}

/* ---- Estados de animación ---- */

/* Fase 1: Entrada de las barras (escalonado de abajo hacia arriba) */
.intro__barra {
  opacity: 0;
  transform: translateX(calc(var(--u) * -4));
  transition: opacity 400ms var(--ease-out-expo),
              transform 400ms var(--ease-out-expo);
}

.intro.is-animating .intro__barra--3 {
  opacity: 1;
  transform: translateX(0);
  transition-delay: 200ms;
}

.intro.is-animating .intro__barra--2 {
  opacity: 1;
  transform: translateX(0);
  transition-delay: 350ms;
}

.intro.is-animating .intro__barra--1 {
  opacity: 1;
  transform: translateX(0);
  transition-delay: 500ms;
}

/* Fase 2: Las barras se recogen (colapsan hacia arriba) */
.intro.is-collapsing .intro__barra {
  transition: height 500ms var(--ease-out-expo),
              opacity 300ms ease-out;
}

.intro.is-collapsing .intro__barra--3 {
  height: 0;
  opacity: 0;
  transition-delay: 0ms;
}

.intro.is-collapsing .intro__barra--2 {
  height: 0;
  opacity: 0;
  transition-delay: 150ms;
}

.intro.is-collapsing .intro__barra--1 {
  height: 0;
  opacity: 0;
  transition-delay: 300ms;
}

/* Fase 3: El overlay sube para revelar la página */
.intro.is-revealing {
  transform: translateY(-100%);
  transition: transform 800ms cubic-bezier(0.76, 0, 0.24, 1);
}

/* Fase 4: Ocultar completamente */
.intro.is-done {
  visibility: hidden;
}

/* ---- Respeto a preferencias del usuario ---- */
@media (prefers-reduced-motion: reduce) {
  .intro {
    display: none;
  }
}

/* ---- Skip intro para visitantes recurrentes ---- */
.intro.is-skipped {
  display: none;
}

/* ---- Sin JavaScript: no mostrar el overlay ----
   El overlay se retira con JS. Si el JS no está disponible, la clase `no-js`
   permanece en <html> (ver js/deteccion.js) y el overlay se oculta para que
   nunca tape la página. */
.no-js .intro {
  display: none;
}

/* ---- Red de seguridad ----
   Si el JS de la intro no completa su secuencia (p. ej. intro.js no cargó pero
   sí el resto), el overlay se retira solo pasado un tiempo prudente para no
   dejar la página tapada. Con la intro normal (≈3 s) este respaldo nunca se ve,
   porque para entonces el overlay ya se ocultó. */
@keyframes intro-seguridad {
  to {
    transform: translateY(-100%);
    visibility: hidden;
  }
}

.js .intro {
  animation: intro-seguridad 700ms cubic-bezier(0.76, 0, 0.24, 1) 4s forwards;
}

@media (prefers-reduced-motion: reduce) {
  .js .intro {
    animation: none;
  }
}

/* 8. Gráficos animados con scroll */
/* ESCALARTE — Fondos Animados
   3 componentes centralizados para usar en cualquier sección:
   1. neural: Red neuronal (fondo azul/oscuro)
   2. line: Línea alcista (fondo blanco)
   3. metrics: Barras + círculos (fondo blanco)

   Responsive: móvil primero, breakpoints 480/768/1024/1280 */

/* ---- Base: Secciones con fondo animado ---- */
.has-animated-bg {
  position: relative;
  overflow: hidden;
}

/* Contenido siempre sobre los fondos animados */
.has-animated-bg > *:not(.neural-bg__canvas):not(.line-bg__svg):not(.metrics-bg) {
  position: relative;
  z-index: 1;
}

/* ============================================================
   1. RED NEURONAL
   ============================================================ */

.neural-bg__canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* ============================================================
   2. LÍNEA ALCISTA ANIMADA
   ============================================================ */

.line-bg__svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.line-bg__line {
  fill: none;
  stroke: var(--azul-200);
  /* Fluido: 6px en móvil → 12px en desktop */
  stroke-width: clamp(6px, 1vw + 4px, 12px);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.25;
}

/* ============================================================
   3. MÉTRICAS (barras + círculos)
   ============================================================ */

.metrics-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Barras de volumen (abajo) */
.metrics-bg__bars {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: clamp(100px, 20vw, 180px);
  opacity: 0.12;
}

.metrics-bg__bar {
  fill: var(--azul-400);
}

/* Círculos esparcidos (arriba) */
.metrics-bg__circles {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 50%;
  opacity: 0.15;
}

.metrics-bg__circle-item {
  position: absolute;
}

.metrics-bg__circle-svg {
  width: 100%;
  height: 100%;
}

.metrics-bg__circle-track {
  fill: none;
  stroke: var(--niebla);
  stroke-width: 14;
}

.metrics-bg__circle-progress {
  fill: none;
  stroke: var(--azul-300);
  stroke-width: 14;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: center;
}

/* ============================================================
   ACCESIBILIDAD — prefers-reduced-motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* No se baja la opacidad del contenedor: los hijos ya traen la suya y al
     multiplicarse (0.08 × 0.25 = 0.02) los fondos desaparecían. Se atenúa cada
     hijo por separado para que se vean tenues y quietos. */
  .neural-bg__canvas {
    opacity: 0.08;
  }

  .line-bg__line {
    opacity: 0.12;
  }

  .metrics-bg__bars {
    opacity: 0.06;
  }

  .metrics-bg__circles {
    opacity: 0.07;
  }
}

/* 9. Landing del asistente con IA + teaser en el home */
/* ESCALARTE — Landing del Asistente con IA
   Estilos propios de la página /asistente y del teaser en el home.
   Reusa componentes existentes (.btn, .card--sintoma, .proceso, .hero__badge,
   .seccion__titulo). Todo el color y el espaciado sale de los tokens de marca. */

/* ==========================================================================
   Helpers
   ========================================================================== */

/* Botón outline sobre fondo oscuro: se usa el modificador .btn--outline-claro
   definido en components.css (no se sobrescribe el componente desde aquí). */

/* Ícono de WhatsApp dentro de un botón */
.asis-wa-icono {
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
  flex-shrink: 0;
}

/* Cabecera de sección reutilizable dentro de la landing */
/* ==========================================================================
   Hero de la landing
   ========================================================================== */

/* El alto, el relleno y la retícula los hereda de la base compartida
   `.hero, .asis-hero` (sections.css). Acá solo lo propio de este hero, que
   además del texto lleva la maqueta de conversación: por debajo de 1280px los
   dos se apilan y la sección pasa de una pantalla (medido: 1280px en 375x812),
   así que el indicador de scroll se oculta porque quedaría fuera de vista.
   Desde 1280px entra en dos columnas, cierra en una pantalla y el indicador
   aparece al pie, igual que en el home. */
.asis-hero {
  color: var(--blanco);
}

.asis-hero .hero__scroll {
  display: none;
}

.asis-hero__grid {
  grid-row: 2;
  position: relative;
  z-index: 1;
  display: grid;
  gap: calc(var(--u) * 6);
  align-items: center;
}

.asis-hero__copy {
  text-align: center;
}

.asis-hero__titulo {
  font-size: clamp(var(--t-2xl), 5vw + 1rem, var(--t-4xl));
  color: var(--blanco);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: calc(var(--u) * 4);
  text-wrap: balance;
}

.asis-hero__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 2);
  justify-content: center;
}

@media (min-width: 768px) {
  .asis-hero__titulo {
    margin-bottom: calc(var(--u) * 5);
  }
}

@media (min-width: 1280px) {
  .asis-hero .hero__scroll {
    display: flex;
  }

  .asis-hero__grid {
    grid-template-columns: 1.05fr 0.95fr;
    gap: calc(var(--u) * 8);
  }

  .asis-hero__copy {
    text-align: left;
  }

  .asis-hero__subtitulo {
    margin-left: 0;
    margin-right: 0;
  }

  .asis-hero__acciones {
    justify-content: flex-start;
  }
}

/* ==========================================================================
   Maqueta de conversación (chat)
   ========================================================================== */

.chat-mock {
  width: 100%;
  max-width: 380px;
  margin: 0 auto;
  background: var(--blanco);
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-fuerte);
  overflow: hidden;
}

.chat-mock__barra {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1.5);
  padding: calc(var(--u) * 2);
  background: linear-gradient(135deg, var(--azul-600) 0%, var(--tinta) 100%);
  color: var(--blanco);
}

.chat-mock__avatar {
  width: calc(var(--u) * 5);
  height: calc(var(--u) * 5);
  border-radius: 50%;
  background: var(--blanco);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.chat-mock__avatar svg {
  width: calc(var(--u) * 3);
  height: calc(var(--u) * 3);
}

.chat-mock__id {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.chat-mock__nombre {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-sm);
}

.chat-mock__estado {
  font-size: var(--t-xs);
  color: var(--azul-200);
}

.chat-mock__cuerpo {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1.5);
  padding: calc(var(--u) * 3) calc(var(--u) * 2.5);
  background: var(--nieve);
}

.chat-burbuja {
  max-width: 82%;
  padding: calc(var(--u) * 1.5) calc(var(--u) * 2);
  font-size: var(--t-sm);
  line-height: 1.5;
  border-radius: var(--radio-lg);
}

.chat-burbuja--cliente {
  align-self: flex-end;
  background: var(--blanco);
  color: var(--tinta);
  border: 1px solid var(--niebla);
  border-bottom-right-radius: var(--radio);
}

.chat-burbuja--asistente {
  align-self: flex-start;
  background: linear-gradient(135deg, var(--azul-500) 0%, var(--azul-600) 100%);
  color: var(--blanco);
  border-bottom-left-radius: var(--radio);
}

/* ==========================================================================
   Problema — tarjetas de síntomas (reusa .card--sintoma)
   ========================================================================== */

.asis-problema {
  background: var(--blanco);
  padding: calc(var(--u) * 10) 0;
}

.asis-cards {
  display: grid;
  gap: calc(var(--u) * 3);
}

@media (min-width: 768px) {
  .asis-problema {
    padding: calc(var(--u) * 14) 0;
  }

  /* Ancho acotado para que una .card--sintoma mida aquí lo mismo que en el
     home (319px) y en la sección de beneficios (329px): sin el tope, dos
     columnas a 1280px daban tarjetas de 509px. */
  .asis-cards {
    grid-template-columns: repeat(2, 1fr);
    gap: calc(var(--u) * 4);
    max-width: calc(var(--u) * 86);
    margin-inline: auto;
  }
}

/* ==========================================================================
   Beneficios — qué hace por el negocio
   ========================================================================== */

.asis-beneficios {
  background: var(--nieve);
  padding: calc(var(--u) * 10) 0;
}

.asis-beneficios__grid {
  display: grid;
  gap: calc(var(--u) * 3);
}

@media (min-width: 768px) {
  .asis-beneficios {
    padding: calc(var(--u) * 14) 0;
  }

  .asis-beneficios__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: calc(var(--u) * 4);
  }
}

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

/* Las tarjetas de beneficio reusan .card--sintoma tal cual (ya son blancas y
   el grid las estira a la misma altura con align-items: stretch por defecto). */

/* ==========================================================================
   Control — panel del dueño (texto + maqueta de panel)
   ========================================================================== */

.asis-control {
  background: var(--blanco);
  padding: calc(var(--u) * 10) 0;
}

.asis-control__grid {
  display: grid;
  gap: calc(var(--u) * 6);
  align-items: center;
}

/* Solo lo propio: el tamaño lo da .seccion__titulo */
.asis-control__titulo {
  margin-bottom: calc(var(--u) * 2);
  color: var(--tinta);
}

.asis-control__intro {
  color: var(--acero);
  font-size: var(--t-lg);
  margin-bottom: calc(var(--u) * 4);
}

.asis-control__lista {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 3);
}

.asis-punto {
  display: grid;
  grid-template-columns: calc(var(--u) * 5) 1fr;
  gap: calc(var(--u) * 2);
  align-items: start;
}

.asis-punto__icono {
  width: calc(var(--u) * 5);
  height: calc(var(--u) * 5);
  border-radius: var(--radio);
  background: var(--azul-50);
  color: var(--azul-500);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.asis-punto__icono svg {
  width: calc(var(--u) * 2.75);
  height: calc(var(--u) * 2.75);
}

.asis-punto__titulo {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--tinta);
  margin-bottom: calc(var(--u) * 0.5);
}

.asis-punto__texto {
  font-size: var(--t-sm);
  color: var(--acero);
  line-height: 1.55;
}

@media (min-width: 768px) {
  .asis-control {
    padding: calc(var(--u) * 14) 0;
  }
}

@media (min-width: 1024px) {
  .asis-control__grid {
    grid-template-columns: 1fr 1fr;
    gap: calc(var(--u) * 8);
  }

  /* La maqueta va primero visualmente en desktop */
  .asis-control__visual {
    order: -1;
  }
}

/* --- Maqueta de panel --- */
.panel-mock {
  background: var(--nieve);
  border: 1px solid var(--niebla);
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-elevada);
  overflow: hidden;
}

.panel-mock__barra {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
  padding: calc(var(--u) * 1.5) calc(var(--u) * 2);
  background: var(--tinta);
}

.panel-mock__punto {
  width: calc(var(--u) * 1.25);
  height: calc(var(--u) * 1.25);
  border-radius: 50%;
  background: var(--acero);
  opacity: 0.6;
}

.panel-mock__titulo {
  margin-left: calc(var(--u) * 1);
  font-size: var(--t-xs);
  color: var(--azul-200);
  font-family: var(--dato);
}

.panel-mock__cuerpo {
  display: grid;
  gap: calc(var(--u) * 2);
  padding: calc(var(--u) * 2.5);
}

.panel-mock__tarjeta {
  background: var(--blanco);
  border-radius: var(--radio-md);
  padding: calc(var(--u) * 2);
  box-shadow: var(--sombra-sutil);
}

.panel-mock__etiqueta {
  font-size: var(--t-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--acero);
  margin-bottom: calc(var(--u) * 1.5);
}

/* Calendario mini */
.cal-mini {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: calc(var(--u) * 0.75);
}

.cal-mini__dia {
  aspect-ratio: 1;
  border-radius: var(--radio);
  background: var(--nieve);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--dato);
  font-size: var(--t-xs);
  color: var(--acero);
}

.cal-mini__dia--activo {
  background: linear-gradient(135deg, var(--azul-500) 0%, var(--azul-600) 100%);
  color: var(--blanco);
  font-weight: 600;
}

.cal-mini__dia--hoy {
  border: 2px solid var(--azul-300);
  color: var(--azul-500);
  font-weight: 600;
}

/* Lista de conversaciones mini */
.chat-fila {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1.5);
  padding: calc(var(--u) * 1) 0;
}

.chat-fila + .chat-fila {
  border-top: 1px solid var(--nieve);
}

.chat-fila__avatar {
  width: calc(var(--u) * 4);
  height: calc(var(--u) * 4);
  border-radius: 50%;
  background: var(--azul-100);
  color: var(--azul-600);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--dato);
  font-size: var(--t-xs);
  font-weight: 600;
  flex-shrink: 0;
}

.chat-fila__lineas {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.75);
  min-width: 0;
}

.chat-fila__linea {
  height: calc(var(--u) * 1);
  border-radius: var(--radio-pill);
  background: var(--niebla);
}

.chat-fila__linea--corta {
  width: 45%;
  background: var(--nieve);
  border: 1px solid var(--niebla);
}

.chat-fila__flag {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--azul-500);
  flex-shrink: 0;
}

/* ==========================================================================
   Proceso — se reusa el componente .proceso (fondo nieve).
   En esta landing lo colocamos sobre blanco: se ajusta el fondo.
   ========================================================================== */

.asis-proceso {
  background: var(--nieve);
}

.asis-proceso__remate {
  text-align: center;
  color: var(--acero);
  font-size: var(--t-md);
  margin: calc(var(--u) * 8) auto 0;
  max-width: 50ch;
}

/* ==========================================================================
   Rubros — para qué negocios sirve
   ========================================================================== */

.asis-rubros {
  background: var(--blanco);
  padding: calc(var(--u) * 10) 0;
}

.asis-rubros__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--u) * 1.5);
  max-width: 760px;
  margin: 0 auto;
}

.rubro-chip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 1);
  padding: calc(var(--u) * 1.25) calc(var(--u) * 2.5);
  background: var(--nieve);
  border: 1px solid var(--niebla);
  border-radius: var(--radio-pill);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--tinta);
  transition: border-color var(--duration-fast) ease-out,
              color var(--duration-fast) ease-out;
}

/* Misma capa de micro-interacción que el resto del sitio */
@media (min-width: 768px) {
  .asis-rubros {
    padding: calc(var(--u) * 14) 0;
  }
}

/* ==========================================================================
   Teaser del asistente en el home (index.html)
   ========================================================================== */

.asis-teaser {
  background: var(--nieve);
  padding: calc(var(--u) * 10) 0;
}

.asis-teaser__caja {
  background: linear-gradient(135deg, var(--azul-700) 0%, var(--tinta) 100%);
  color: var(--blanco);
  border-radius: var(--radio-xl);
  padding: calc(var(--u) * 5) calc(var(--u) * 4);
  overflow: hidden;
}

.asis-teaser__grid {
  display: grid;
  gap: calc(var(--u) * 5);
  align-items: center;
}

/* Mismo tratamiento que .hero__badge (mismos colores, tipografía y radio):
   antes eran dos etiquetas con los mismos colores y tipografías distintas. */
.asis-teaser__badge {
  display: inline-block;
  background: var(--azul-300-15);
  border: 1px solid var(--azul-300-40);
  color: var(--azul-200);
  font-size: var(--t-sm);
  font-weight: 500;
  padding: calc(var(--u) * 1) calc(var(--u) * 3);
  border-radius: var(--radio-pill);
  margin-bottom: calc(var(--u) * 2.5);
}

.asis-teaser__titulo {
  font-size: clamp(var(--t-xl), 3vw + 0.5rem, var(--t-2xl));
  color: var(--blanco);
  line-height: 1.2;
  margin-bottom: calc(var(--u) * 2);
  text-wrap: balance;
}

.asis-teaser__texto {
  color: var(--azul-200);
  font-size: var(--t-md);
  line-height: 1.6;
  margin-bottom: calc(var(--u) * 3);
  max-width: 48ch;
}

.asis-teaser__lista {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1.5);
  margin-bottom: calc(var(--u) * 4);
}

.asis-teaser__item {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1.5);
  font-size: var(--t-sm);
  color: var(--blanco);
}

.asis-teaser__item svg {
  width: calc(var(--u) * 2.5);
  height: calc(var(--u) * 2.5);
  color: var(--azul-200);
  flex-shrink: 0;
}

/* La maqueta de chat se muestra en todos los tamaños y debe verse EXACTAMENTE
   igual que en la landing. El tope lo pone el propio componente (.chat-mock,
   380px): no se le impone otro desde acá. En móvil el visual se extiende hasta
   el borde de la caja (cancela su relleno lateral) para que el ancho disponible
   sea el mismo que en el hero de /asistente y las burbujas corten igual. */
.asis-teaser__visual {
  margin-inline: calc(var(--u) * -4);
}

@media (min-width: 768px) {
  .asis-teaser {
    padding: calc(var(--u) * 14) 0;
  }

  .asis-teaser__caja {
    padding: calc(var(--u) * 8) calc(var(--u) * 8);
  }

  .asis-teaser__visual {
    margin-inline: 0;
  }
}

@media (min-width: 1280px) {
  .asis-teaser__grid {
    grid-template-columns: 1fr 1fr;
    gap: calc(var(--u) * 8);
  }
}

/* 10. Página de servicios */
/**
 * ESCALARTE — Página de servicios
 *
 * Los servicios, cada uno por separado, y después los paquetes.
 * La página no inventa contenido: todo sale de `herramientas/manual/contenido.py`,
 * el mismo archivo que alimenta al brandbook, al brochure y a la propuesta, y
 * `npm run check:piezas` falla si dejan de decir lo mismo.
 *
 * QUÉ SE REUSA Y QUÉ ES PROPIO
 *   Reusado  `.hero` —la misma portada del home, con su alto de pantalla y su
 *            contenido centrado—, `.card--sintoma` para cada servicio, el bloque
 *            entero de `.paquete`, `.cta-final` para el cierre, más `.btn`,
 *            `.contenedor` y `.seccion__encab`.
 *   Propio   la rejilla de servicios y la de condiciones.
 *
 * LO QUE LA WEB NO DICE
 * Que el catálogo esté ordenado en tres es asunto interno —viene de las tres
 * barras del símbolo y vive en el brandbook, en el brochure y en la propuesta—.
 * Acá se muestran los servicios y, aparte, las formas de empezar. Nada de
 * etiquetar cada servicio con el paquete al que pertenece.
 *
 * Este archivo es corto a propósito. Cuanto más reusa, menos puede
 * desincronizarse: si mañana cambia la portada del home, cambia también acá.
 */

/* ── Los servicios ────────────────────────────────────────────────────────── */

.serv-lista {
  background: var(--nieve);
  padding: calc(var(--u) * 10) 0;
}

.serv-lista__grid {
  display: grid;
  gap: calc(var(--u) * 2.5);
}

/* Las tarjetas son `.card--sintoma`, la misma pieza del home. Sobre nieve van en
   blanco para que no desaparezcan contra el fondo: cambia el contexto, no el
   componente. */
.serv-lista .card {
  background: var(--blanco);
}

@media (min-width: 768px) {
  .serv-lista {
    padding: calc(var(--u) * 14) 0;
  }

  .serv-lista__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

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

/* ── Cuánto cuesta y cuánto tarda ─────────────────────────────────────────── */

.serv-condiciones {
  background: var(--nieve);
  padding: calc(var(--u) * 10) 0;
}

.serv-condiciones__intro {
  font-size: var(--t-md);
  line-height: 1.7;
  color: var(--acero);
  max-width: 62ch;
  margin: 0 auto calc(var(--u) * 6);
  text-align: center;
}

.serv-condiciones__grid {
  display: grid;
  gap: calc(var(--u) * 3);
  max-width: 1000px;
  margin: 0 auto;
}

/* Un filete en niebla sobre nieve da 1.22:1 y no se ve; el borde que comunica va
   en niebla fuerte. Es la regla medida de CLAUDE.md §6. */
.serv-condicion {
  padding-top: calc(var(--u) * 2);
  border-top: 1px solid var(--niebla-fuerte);
}

.serv-condicion__titulo {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--tinta);
  margin-bottom: calc(var(--u) * 1);
}

.serv-condicion__texto {
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--acero);
}

@media (min-width: 768px) {
  .serv-condiciones {
    padding: calc(var(--u) * 14) 0;
  }

  .serv-condiciones__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: calc(var(--u) * 4);
  }
}

/* 11. La rueda de navegación: reemplaza al menú hamburguesa */
/**
 * ESCALARTE — La rueda de navegación
 *
 * Reemplaza al menú hamburguesa. Vive fija en la esquina inferior derecha:
 * cerrada es un disco discreto; abierta despliega los destinos sobre un arco,
 * como las horas de un reloj, y se gira con la rueda del mouse, arrastrando o
 * con las flechas.
 *
 * Solo se ve un cuarto del círculo. El resto lo recorta la propia esquina de la
 * pantalla y los extremos se desvanecen, que es lo que da la sensación de que
 * hay más destinos girando detrás.
 *
 * LO QUE HACE CADA CAPA
 *   HTML  la lista de enlaces, en orden y navegable. Sin JS se ve como lista.
 *   CSS   el disco, el arco, el desvanecido. Las posiciones las escribe el JS
 *         en dos variables por ítem: --angulo y --cerca.
 *   JS    solo geometría y estado. No inyecta contenido ni textos.
 *
 * Todos los valores salen de los tokens. Las medidas propias de la rueda están
 * arriba, en un solo lugar, para no repetirlas por el archivo.
 */

.rueda {
  --rueda-disco: calc(var(--u) * 7);          /* 56px: área táctil cómoda */
  --rueda-brazo: calc(var(--u) * 5);          /* del centro al arranque de la manecilla */
  /* El disco no va pegado al filo: el destino que baja hacia las 6 necesita lugar
     por debajo. Medido, no estimado: con 14u se cortaba 20 px contra el borde, y
     un corte no se lee como «hay más girando atrás», se lee como error. */
  --rueda-esquina: calc(var(--u) * 3);         /* cerrada: pegada a la esquina */
  --rueda-margen: calc(var(--u) * 17);        /* abierta: lo que pide el arco */
  --rueda-ancho-item: calc(var(--u) * 16);

  position: fixed;
  /* Por encima del header (100). Abierta es modal: el velo tiene que tapar todo,
     también la cabecera, o el fondo se ve a medias oscurecido. Debajo del salto
     al contenido (200) y de la intro (9999), que mandan siempre. */
  z-index: 150;
  /* A la derecha, que es donde cae el pulgar. El arco se abre hacia adentro de
     la pantalla; toda la geometría de .rueda__item está espejada para eso.

     Cerrada va pegada a la esquina. El margen grande que necesita el arco solo
     se aplica al abrirse: dejar el disco ahí siempre lo hacía flotar a un tercio
     de la pantalla del borde, y un botón flotante que no está anclado a nada se
     lee como si se hubiera quedado a mitad de camino.

     Se anima `right`/`bottom` y no `transform` a propósito: un transform en
     .rueda convertiría al velo, que es hijo suyo y va `position: fixed`, en un
     rectángulo del tamaño del disco. */
  right: max(var(--rueda-esquina), env(safe-area-inset-right));
  bottom: max(var(--rueda-esquina), env(safe-area-inset-bottom));
  width: var(--rueda-disco);
  height: var(--rueda-disco);
  transition: right .3s var(--ease-out-expo, ease), bottom .3s var(--ease-out-expo, ease);
}

.rueda[data-abierta="si"] {
  right: max(var(--rueda-margen), env(safe-area-inset-right));
  bottom: max(var(--rueda-margen), env(safe-area-inset-bottom));
}

/* ── El disco ─────────────────────────────────────────────────────────────── */

.rueda__boton {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: var(--rueda-disco);
  height: var(--rueda-disco);
  padding: 0;
  border: 1px solid rgb(var(--azul-300-rgb) / 0.35);
  border-radius: 50%;
  background: var(--tinta);
  color: var(--nieve);
  cursor: pointer;
  box-shadow: 0 calc(var(--u) * 0.5) calc(var(--u) * 2) rgb(var(--tinta-rgb) / 0.28);
  transition: border-color .25s ease, transform .25s ease;
}

.rueda__boton:hover,
.rueda__boton:focus-visible {
  border-color: var(--azul-300);
}

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

/* ── El latido ────────────────────────────────────────────────────────────── */

/* Un botón flotante que nadie tocó no comunica que se puede tocar. El latido lo
   dice: dos anillos que salen del disco y se apagan, con una pausa larga entre
   tandas, como un pulso.

   Va en ::before y ::after y no sobre el botón: el disco NO se mueve de sitio.
   Un botón que rebota en la esquina hace que la página parezca temblar, y acá
   además pelearía con la transición de `transform` que el botón ya declara.
   Los pseudo-elementos van absolutos, así tampoco entran en la retícula del
   botón, que es un grid.

   Solo late cerrado y solo hasta que se lo toca: abierto sobra, y con el cursor
   encima ya cumplió su trabajo. */
.rueda__boton::before,
.rueda__boton::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--azul-300);
  opacity: 0;
  pointer-events: none;
}

.rueda[data-abierta="no"] .rueda__boton::before,
.rueda[data-abierta="no"] .rueda__boton::after {
  animation: rueda-latido 3.2s cubic-bezier(.16, 1, .3, 1) infinite;
}

/* El segundo anillo sale un poco después: eso es lo que se lee como latido y no
   como un temporizador. */
.rueda[data-abierta="no"] .rueda__boton::after {
  animation-delay: .38s;
}

.rueda[data-abierta="no"] .rueda__boton:hover::before,
.rueda[data-abierta="no"] .rueda__boton:hover::after,
.rueda[data-abierta="no"] .rueda__boton:focus-visible::before,
.rueda[data-abierta="no"] .rueda__boton:focus-visible::after {
  animation: none;
}

@keyframes rueda-latido {
  0%   { transform: scale(1);    opacity: .5; }
  /* El anillo se apaga antes de llegar al final: el resto del ciclo es la pausa,
     y sin pausa el disco no palpita, vibra. */
  40%  { transform: scale(1.75); opacity: 0; }
  100% { transform: scale(1.75); opacity: 0; }
}

/* La marca del selector: las tres barras del símbolo cruzadas cada 60° sobre el
   mismo centro. Cada barra es la barra base, 12u por 2u: la proporción no se
   toca. Dos excepciones que valen solo en esta pieza —las tres del mismo largo,
   y las puntas redondeadas a 1u— explicadas en la página 7.8 del brandbook.

   Un solo dibujo: entre un fondo y otro cambian los colores, nunca la forma.
   La barra base va siempre al frente, y eso lo fija el orden del SVG, no el CSS.

   Del tamaño: la marca ocupa tres cuartos del disco. Más chica dejaba el disco
   con un anillo vacío que se leía como error de centrado; más grande toca el
   borde. */
.rueda__marca-svg {
  width: calc(var(--u) * 5.5);
  height: calc(var(--u) * 5.5);
  display: block;
  transition: transform .35s ease;
}

/* Los colores son los del símbolo sobre tinta, en su orden: base, medio, chica. */
.rueda__barra { fill: currentColor; }
.rueda__barra--1 { color: var(--blanco); }
.rueda__barra--2 { color: var(--azul-200); }
.rueda__barra--3 { color: var(--azul-400); }

/* Girar 60° deja el dibujo idéntico y solo mueve los colores de sitio: es la
   simetría de las tres barras, no un efecto agregado. */
.rueda__boton:hover .rueda__marca-svg,
.rueda__boton:focus-visible .rueda__marca-svg { transform: rotate(60deg); }

/* Modificador: la rueda sobre fondo claro. Cambian el disco y los tres colores,
   que pasan a ser los del símbolo sobre nieve. No se sobrescribe desde la página:
   se agrega la clase al mismo componente. */
.rueda--claro .rueda__boton { background: var(--nieve); color: var(--tinta); }
.rueda--claro .rueda__barra--1 { color: var(--tinta); }
.rueda--claro .rueda__barra--2 { color: var(--azul-500); }
.rueda--claro .rueda__barra--3 { color: var(--azul-300); }

/* La cruz aparece solo con la rueda abierta: el mismo disco cambia de trabajo. */
.rueda__marca,
.rueda__cerrar {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  transition: opacity .2s ease, transform .2s ease;
}

.rueda__cerrar { opacity: 0; transform: rotate(-45deg) scale(.7); }
.rueda__cerrar svg { width: calc(var(--u) * 2.5); height: calc(var(--u) * 2.5); }

.rueda[data-abierta="si"] .rueda__marca { opacity: 0; transform: scale(.7); }
.rueda[data-abierta="si"] .rueda__cerrar { opacity: 1; transform: none; }

/* ── El arco ──────────────────────────────────────────────────────────────── */

/* El desvanecido de abrir y cerrar vive acá, en una transición de CSS, y NO en
   el bucle de animación. Son dos cosas distintas y conviene que lo sigan siendo:
   el giro necesita calcularse cuadro a cuadro, pero el fundido no, y dejándolo
   en CSS lo resuelve el compositor. Si el bucle no llegara a correr —una pestaña
   en segundo plano, el navegador ahorrando batería—, el menú igual aparece. */
.rueda__menu {
  position: absolute;
  left: calc(var(--rueda-disco) / 2);
  top: calc(var(--rueda-disco) / 2);
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  opacity: 0;
  transition: opacity .26s ease;
}

.rueda[data-abierta="si"] .rueda__menu {
  opacity: 1;
}

/* Cada destino es una manecilla: nace en el centro y apunta hacia afuera con su
   propio ángulo. No se contrarrota, justamente para que se lea como aguja de
   reloj y no como una lista inclinada.

   `--cerca` es el coseno del ángulo: vale 1 a las 3 en punto —el frente— y cae a
   cero en las 12 y en las 6. Por eso los destinos aparecen desde abajo y se
   desvanecen arriba, en vez de cortarse.

   NINGUNA TRANSICIÓN ACÁ, y es a propósito. El giro lo anima el JS cuadro a
   cuadro; una transición de CSS encima pelearía con él —cada cuadro reiniciaría
   la interpolación anterior— y eso es justamente lo que se sentía tosco. Todo
   lo que se mueve al girar sale de --angulo y --cerca. El fundido de abrir y
   cerrar es otra cosa y vive arriba, en .rueda__menu. */
.rueda__item {
  --angulo: 0deg;
  --cerca: 0;

  position: absolute;
  left: 0;
  top: 0;
  width: var(--rueda-ancho-item);
  /* Espejada respecto de la versión de la izquierda: se gira con el ángulo en
     positivo y se sale por el lado -X, así la manecilla apunta hacia adentro de
     la pantalla y el rótulo NO queda de cabeza. El translateX(-100%) final la
     corre su propio ancho, para que crezca hacia afuera del disco y no hacia
     atrás, encima del botón. */
  transform:
    rotate(var(--angulo))
    translateX(calc(var(--rueda-brazo) * -1))
    translateY(-50%)
    translateX(-100%);
  transform-origin: 0 0;
  opacity: var(--cerca);
  pointer-events: none;
  /* Se promueve a su propia capa: el navegador no rehace el diseño en cada
     cuadro, solo recompone. Con cinco destinos es barato y se nota. */
  will-change: transform, opacity;
}

.rueda[data-abierta="si"] .rueda__item {
  pointer-events: auto;
}

/* Con el arco abierto, el gesto vertical es de la rueda, no de la página: sin
   esto el navegador se lleva el arrastre y el arco no gira en celular. */
.rueda[data-abierta="si"] {
  touch-action: none;
}

/* Debajo de 0.25 el ítem ya es un fantasma: no se toca ni se tabula. */
.rueda[data-abierta="si"] .rueda__item[data-lejos="si"] { pointer-events: none; }

/* La manecilla: delgada a propósito. Una pastilla gruesa se lee como botón, y
   lo que se busca acá es la línea fina de una aguja de reloj. */
.rueda__enlace {
  position: relative;
  display: flex;
  /* Invertida: el ícono queda del lado del disco y el rótulo se aleja hacia
     adentro. Con el orden normal, el ícono terminaba en la punta de la aguja. */
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: center;
  gap: calc(var(--u) * 1);
  min-height: calc(var(--u) * 3.5);
  padding: calc(var(--u) * 0.5) calc(var(--u) * 1.5);
  border: 1px solid rgb(var(--azul-300-rgb) / 0.28);
  border-radius: calc(var(--u) * 1.75);
  background: rgb(var(--tinta-rgb) / 0.86);
  color: var(--nieve);
  text-decoration: none;
  white-space: nowrap;
  /* La escala también sigue a --cerca cuadro a cuadro, así que tampoco lleva
     transición: el que está al frente crece, y crece mientras gira, no después. */
  transform: scale(calc(.92 + .08 * var(--cerca)));
  transform-origin: right center;
  transition: border-color .2s ease, background-color .2s ease;
}

/* El área táctil sigue siendo de 44 px aunque la manecilla mida 28: se agranda
   por fuera, sin engordar el dibujo. Es la regla 11 de CLAUDE.md. */
.rueda__enlace::after {
  content: "";
  position: absolute;
  inset: calc((var(--u) * 3.5 - var(--u) * 5.5) / 2) 0;
}

.rueda__enlace:hover,
.rueda__enlace:focus-visible {
  border-color: var(--azul-300);
  background: var(--tinta);
}

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

.rueda__ico {
  width: calc(var(--u) * 2);
  height: calc(var(--u) * 2);
  flex: none;
  color: var(--azul-300);
}

.rueda__texto {
  font-family: var(--dato);
  font-size: var(--t-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* La página en la que estás parado se marca sola. */
.rueda__enlace[aria-current="page"] { border-color: var(--azul-300); }
.rueda__enlace[aria-current="page"] .rueda__texto { color: var(--azul-200); }

/* ── El velo ──────────────────────────────────────────────────────────────── */

.rueda__velo {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgb(var(--tinta-rgb) / 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
}

/* Abierto, el velo sí recibe eventos: es lo que hace que la rueda del mouse
   caiga siempre en el arco y no en la página, sin importar dónde esté el cursor.
   Con el velo transparente al puntero quedaban huecos —entre manecilla y
   manecilla— por donde el gesto se escapaba y movía las dos cosas a la vez. */
.rueda[data-abierta="si"] .rueda__velo {
  opacity: 1;
  pointer-events: auto;
}

/* ── Sin JavaScript ───────────────────────────────────────────────────────── */

/* La rueda es una mejora. Si el JS no corre, la navegación sigue estando: se
   muestra como una lista corriente sobre el disco, sin arco ni giro. */
/* Sin el arco, el ancho del disco ya no sirve de caja: la lista necesita el
   suyo, y apoyada al borde derecho para no salirse de la pantalla. */
.no-js .rueda { width: auto; height: auto; }

.no-js .rueda__menu {
  position: static;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: calc(var(--u) * 1);
  width: auto;
  height: auto;
  margin-bottom: calc(var(--u) * 1.5);
}

.no-js .rueda__item {
  position: static;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  width: auto;
}

.no-js .rueda__enlace { transform: none; }
.no-js .rueda__boton { display: none; }

/* ── Movimiento reducido ──────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .rueda__item,
  .rueda__enlace,
  .rueda,
  .rueda__boton,
  .rueda__marca,
  .rueda__cerrar,
  .rueda__velo { transition-duration: .01ms; }

  /* El latido es una invitación, no información: sin él la rueda se usa igual. */
  .rueda__boton::before,
  .rueda__boton::after { animation: none; }
}

/* ── Pantallas chicas ─────────────────────────────────────────────────────── */

/* En celular el radio se achica para que el arco entre completo, y los rótulos
   bajan un punto. La geometría no cambia: solo la escala. */
@media (max-width: 479px) {
  .rueda {
    --rueda-brazo: calc(var(--u) * 4.5);
    --rueda-disco: calc(var(--u) * 6.5);
    --rueda-ancho-item: calc(var(--u) * 15);
    /* 16u y no menos: medido en la pantalla más chica que se soporta, 320 × 568.
       Con 11u el destino que baja desde las 6 se cortaba 32 px contra el filo, y
       con 15u todavía asomaba 2. Un corte no se lee como «hay más girando
       atrás», se lee como error. */
    --rueda-margen: calc(var(--u) * 16);
  }
}
