/* ============================================================
   INVERSIONES MULTIMODAL GJG · Cimientos
   Swiss Modernism 2.0 — rejilla estricta, jerarquía tipográfica,
   un solo acento, cero decoración gratuita.

   POR QUÉ ESTE ESTILO Y NO OTRO
   El sitio es denso en información técnica: Incoterms, artículos
   prohibidos, medidas de contenedor, caracterización de cuatro modos
   de transporte. El problema no era la cantidad de texto sino que
   todo pesaba lo mismo. Una rejilla estricta con jerarquía clara es
   exactamente el instrumento para eso: deja respirar sin quitar
   información.

   TODO EL SISTEMA SE CONTROLA DESDE ESTE ARCHIVO.
   Los componentes no inventan valores: consumen estas variables.
   ============================================================ */

/* ---------- 1. Escala base ----------
   Unidad de 8 px. Todo espaciado es múltiplo suyo; por eso las cosas
   se alinean solas y nada queda a «casi» dos píxeles de su sitio. */

:root {
  --u: 8px;

  --e-1: calc(var(--u) * 0.5);    /*  4px */
  --e-2: var(--u);                /*  8px */
  --e-3: calc(var(--u) * 2);      /* 16px */
  --e-4: calc(var(--u) * 3);      /* 24px */
  --e-5: calc(var(--u) * 4);      /* 32px */
  --e-6: calc(var(--u) * 6);      /* 48px */
  --e-7: calc(var(--u) * 8);      /* 64px */
  --e-8: calc(var(--u) * 12);     /* 96px */
  --e-9: calc(var(--u) * 16);     /* 128px */

  /* Aire vertical entre secciones. Se reduce en pantallas pequeñas,
     donde 128 px de vacío es media pantalla desperdiciada. */
  --seccion-y: clamp(var(--e-6), 7vw, var(--e-9));

  --ancho-max: 1280px;
  --ancho-texto: 68ch;    /* más allá, el ojo pierde el renglón */
  --margen: clamp(var(--e-3), 5vw, var(--e-7));

  --columnas: 12;
  --hueco: var(--e-4);

  --radio: 2px;           /* Swiss: esquinas casi rectas */
  --radio-lg: 4px;
  --borde: 1px;

  --transicion: 180ms cubic-bezier(.2, .0, .2, 1);
  --transicion-lenta: 320ms cubic-bezier(.2, .0, .2, 1);
}

/* ---------- 2. Color ----------
   Un solo acento, como manda el estilo. El azul de marca (#003ec7) se
   conserva: es el activo visual que el cliente ya reconoce. El resto
   es una escala neutra fría, que es lo que deja respirar al acento.

   Se declaran en HSL por partes para poder derivar transparencias sin
   duplicar el color. */

:root {
  --tinta-h: 222;
  --tinta-s: 24%;

  --papel:        hsl(var(--tinta-h) 30% 99%);
  --papel-2:      hsl(var(--tinta-h) 26% 96.5%);
  --papel-3:      hsl(var(--tinta-h) 22% 93%);
  --linea:        hsl(var(--tinta-h) 18% 87%);
  --linea-suave:  hsl(var(--tinta-h) 18% 92%);

  --tinta:        hsl(var(--tinta-h) 40% 11%);
  --tinta-2:      hsl(var(--tinta-h) 14% 34%);
  --tinta-3:      hsl(var(--tinta-h) 12% 48%);

  --acento:       hsl(222 100% 42%);
  --acento-vivo:  hsl(222 100% 50%);
  --acento-tenue: hsl(222 100% 42% / .08);
  --sobre-acento: hsl(0 0% 100%);

  /* ---------- Familia viva ----------
     Cian y ámbar acompañan al azul de marca. Se usan en degradados,
     bloques y elementos grandes; NO en texto pequeño, donde ninguno
     de los dos llega a 4,5:1 sobre blanco.

     El ámbar es el complementario del azul: es lo que hace que el
     conjunto se lea como una identidad y no como un azul solo. */
  --cian:         hsl(187 100% 42%);
  --cian-vivo:    hsl(187 100% 52%);

  /* Cian para TEXTO. El de marca vale para trazos y bordes, donde con
     3:1 basta, pero puesto como palabra sobre el papel claro da 2,08:1
     (medido en el lema de «nosotros»). Este baja la luminosidad hasta
     cumplir 4,5:1 sin salirse del mismo tono. */
  --cian-texto:   hsl(187 100% 26%);
  --ambar:        hsl(32 100% 50%);
  --ambar-hondo:  hsl(24 95% 44%);
  --violeta:      hsl(258 90% 60%);

  /* Segundo color, solo para estados. Nunca decorativo. */
  --bien:         hsl(160 84% 32%);
  --alerta:       hsl(0 72% 45%);
  --aviso:        hsl(38 92% 40%);

  /* Rojo para el asterisco de campo obligatorio. El `--alerta` de
     arriba se disena para fondos de aviso, no para una marca de 13 px
     sobre papel: ahi daba 2,92:1. */
  --alerta-texto: hsl(0 72% 36%);

  --sombra-1: 0 1px 2px hsl(var(--tinta-h) 40% 11% / .06);
  --sombra-2: 0 2px 8px hsl(var(--tinta-h) 40% 11% / .08);
  --sombra-3: 0 12px 32px hsl(var(--tinta-h) 40% 11% / .12);

  --foco: 0 0 0 3px hsl(222 100% 47% / .35);

  /* ---------- Superficies que SIEMPRE son oscuras ----------
     El pie y las secciones de contraste son oscuros en los dos temas:
     son un recurso de composición, no una consecuencia del tema.

     Necesitan sus propios tokens porque `--tinta` y `--papel` se
     invierten al cambiar de tema. Usarlos aquí hacía que en tema
     oscuro el pie se volviera blanco con texto gris claro: 1,69:1,
     ilegible. Estos no se redefinen nunca. */
  /* La noche no es gris: lleva azul dentro. Un negro neutro apagaría
     el cian y el ámbar que van encima. */
  --noche:        hsl(224 62% 9%);
  --noche-2:      hsl(224 52% 14%);
  --sobre-noche:  hsl(var(--tinta-h) 30% 97%);
  --sobre-noche-2: hsl(214 24% 80%);
  --sobre-noche-3: hsl(214 18% 64%);
  --linea-noche:  hsl(222 30% 26%);
  --acento-noche: hsl(199 100% 66%);
  --cian-noche:   hsl(187 100% 62%);
  /* Sobre noche el recorrido se invierte: aquí lo que falla es lo
     oscuro, no lo claro. */
  --flujo-texto-noche: linear-gradient(100deg, hsl(199 100% 72%) 0%, hsl(190 100% 70%) 55%, hsl(180 95% 68%) 100%);

  /* ---------- Degradados de marca ----------
     Un solo sitio donde se definen. Cualquier componente que quiera
     el degradado lo pide por nombre y todos quedan coherentes. */
  --flujo:  linear-gradient(115deg, hsl(222 100% 46%) 0%, hsl(200 100% 46%) 48%, hsl(187 100% 48%) 100%);
  --brasa:  linear-gradient(115deg, hsl(32 100% 52%) 0%, hsl(14 95% 54%) 100%);

  /* El verde de WhatsApp, con el mismo recorrido que `--brasa`: de un
     tono a otro más hondo.

     No arranca en el #25D366 de la marca sino por debajo: este
     degradado lleva la palabra «WhatsApp» en blanco encima, y sobre el
     verde de marca el blanco se queda en 1,98:1.

     Los valores son un punto medio pedido por el cliente. Estuvo en
     #0E8047, donde el blanco daba 5:1 y cumplía de sobra, pero se veía
     apagado. Estos son un 45 % más vivos en luminancia y dejan el peor
     punto del recorrido en 3,72:1: por encima del 3:1 que basta para
     un elemento gráfico, por debajo del 4,5:1 que pide un texto de
     este tamaño. Es una concesión consciente a la vistosidad, no un
     descuido. El #25D366 puro daría 1,98:1.

     El #25D366 exacto sí está en el botón flotante, que lleva un
     logotipo y no texto.

     No es un color de la paleta de GJG: es de otra marca y por eso
     vive solo en lo que lleva a WhatsApp. El ámbar sigue siendo el
     segundo camino de la casa. */
  --wasap: linear-gradient(115deg, #139851 0%, #096E62 100%);

  /* `--flujo` es vivo y sirve para superficies grandes y para fondos
     oscuros, pero su extremo cian es demasiado claro para llevar
     texto blanco encima o para usarse como color de letra sobre
     papel: ahí se queda en 1,7:1.

     Estas dos variantes conservan el recorrido de color pero con
     luminancias que sí pasan. Se separan a propósito en vez de
     apagar `--flujo`, que perdería la fuerza donde sí funciona. */

  /* Para relleno de botón con texto blanco encima. */
  --flujo-macizo: linear-gradient(115deg, hsl(224 100% 40%) 0%, hsl(210 100% 34%) 52%, hsl(197 100% 29%) 100%);

  /* Para texto recortado sobre fondo claro. */
  --flujo-texto:  linear-gradient(100deg, hsl(224 100% 42%) 0%, hsl(206 100% 34%) 55%, hsl(193 100% 28%) 100%);
  --aurora: radial-gradient(ellipse 80% 60% at 15% 25%, hsl(222 100% 50% / .55), transparent 60%),
            radial-gradient(ellipse 70% 60% at 85% 15%, hsl(187 100% 50% / .42), transparent 62%),
            radial-gradient(ellipse 90% 70% at 60% 95%, hsl(258 90% 58% / .34), transparent 65%);
}

/* El tema oscuro no es el claro invertido: se recalculan luminancias
   para que el acento siga destacando sobre fondo oscuro, donde un azul
   al 39 % desaparecería. */
:root[data-tema="oscuro"] {
  --flujo-texto:  var(--flujo-texto-noche);
  --papel:        hsl(var(--tinta-h) 28% 8%);
  --papel-2:      hsl(var(--tinta-h) 26% 11%);
  --papel-3:      hsl(var(--tinta-h) 24% 15%);
  --linea:        hsl(var(--tinta-h) 18% 24%);
  --linea-suave:  hsl(var(--tinta-h) 18% 18%);

  --tinta:        hsl(var(--tinta-h) 30% 96%);
  --tinta-2:      hsl(var(--tinta-h) 14% 74%);
  --tinta-3:      hsl(var(--tinta-h) 12% 60%);

  --acento:       hsl(217 100% 72%);
  --acento-vivo:  hsl(217 100% 80%);
  --acento-tenue: hsl(217 100% 72% / .14);
  --sobre-acento: hsl(var(--tinta-h) 40% 10%);

  --bien:         hsl(160 60% 58%);
  --alerta:       hsl(4 90% 76%);
  --aviso:        hsl(38 92% 66%);

  /* Sobre fondo oscuro el problema se invierte: hace falta MAS claro,
     no menos, asi que estos dos toman la variante aclarada. */
  --cian-texto:   hsl(187 100% 62%);
  --alerta-texto: hsl(4 90% 76%);

  --sombra-1: 0 1px 2px hsl(0 0% 0% / .4);
  --sombra-2: 0 2px 10px hsl(0 0% 0% / .45);
  --sombra-3: 0 12px 36px hsl(0 0% 0% / .55);

  --foco: 0 0 0 3px hsl(217 100% 72% / .4);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --flujo-texto:  var(--flujo-texto-noche);
    --papel:        hsl(var(--tinta-h) 28% 8%);
    --papel-2:      hsl(var(--tinta-h) 26% 11%);
    --papel-3:      hsl(var(--tinta-h) 24% 15%);
    --linea:        hsl(var(--tinta-h) 18% 24%);
    --linea-suave:  hsl(var(--tinta-h) 18% 18%);
    --tinta:        hsl(var(--tinta-h) 30% 96%);
    --tinta-2:      hsl(var(--tinta-h) 14% 74%);
    --tinta-3:      hsl(var(--tinta-h) 12% 60%);
    --acento:       hsl(217 100% 72%);
    --acento-vivo:  hsl(217 100% 80%);
    --acento-tenue: hsl(217 100% 72% / .14);
    --sobre-acento: hsl(var(--tinta-h) 40% 10%);
    --bien:         hsl(160 60% 58%);
    --alerta:       hsl(4 90% 76%);
    --aviso:        hsl(38 92% 66%);
    --cian-texto:   hsl(187 100% 62%);
    --alerta-texto: hsl(4 90% 76%);
    --sombra-1: 0 1px 2px hsl(0 0% 0% / .4);
    --sombra-2: 0 2px 10px hsl(0 0% 0% / .45);
    --sombra-3: 0 12px 36px hsl(0 0% 0% / .55);
    --foco: 0 0 0 3px hsl(217 100% 72% / .4);
  }
}

/* ---------- 3. Tipografía ----------
   Dos familias: una de titulares con carácter y una de texto pensada
   para leerse largo. La escala es fluida con `clamp`, así que no hace
   falta redefinir tamaños en cada punto de corte.

   La escala usa razón 1.25 (cuarta menor): suficiente para que la
   jerarquía se lea de un vistazo sin que los titulares griten. */

:root {
  --fuente-titulo: 'Archivo', 'Oswald', system-ui, sans-serif;
  --fuente-texto:  'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fuente-mono:   ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

  --t-xs:   clamp(0.75rem,  0.72rem + 0.15vw, 0.813rem);
  --t-sm:   clamp(0.875rem, 0.85rem + 0.15vw, 0.938rem);
  --t-base: clamp(1rem,     0.96rem + 0.2vw,  1.063rem);
  --t-lg:   clamp(1.125rem, 1.06rem + 0.32vw, 1.25rem);
  --t-xl:   clamp(1.375rem, 1.24rem + 0.68vw, 1.75rem);
  --t-2xl:  clamp(1.75rem,  1.5rem + 1.25vw,  2.5rem);
  --t-3xl:  clamp(2.25rem,  1.8rem + 2.25vw,  3.75rem);
  --t-4xl:  clamp(2.75rem,  1.9rem + 4.25vw,  5.5rem);

  --alto-apretado: 1.1;
  --alto-titulo:   1.18;
  --alto-texto:    1.65;
}

/* ---------- 4. Reinicio ----------
   Corto a propósito. Solo lo que de verdad estorba por defecto. */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* La cabecera es fija: sin esto, saltar a un ancla deja el título
     escondido debajo de ella. */
  scroll-padding-top: calc(var(--e-8) + var(--e-3));
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--fuente-texto);
  font-size: var(--t-base);
  line-height: var(--alto-texto);
  color: var(--tinta);
  background: var(--papel);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
}

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

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

h1, h2, h3, h4 {
  font-family: var(--fuente-titulo);
  line-height: var(--alto-titulo);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;      /* evita la palabra huérfana en la última línea */
}

p { text-wrap: pretty; }

ul, ol { padding: 0; list-style: none; }

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

/* Nunca se quita el anillo de foco: se hace bonito. Quitarlo deja el
   sitio inusable para quien navega con teclado. */
:focus-visible {
  outline: 2px solid var(--acento-vivo);
  outline-offset: 2px;
  border-radius: var(--radio);
}

::selection {
  background: var(--acento);
  color: var(--sobre-acento);
}

/* ---------- 5. Rejilla ----------
   Doce columnas reales. Los componentes se colocan sobre ellas en vez
   de inventarse anchos, que es lo que hacía que el sitio anterior
   pareciera un montón de bloques sueltos apilados. */

.env {
  width: 100%;
  max-width: var(--ancho-max);
  margin-inline: auto;
  padding-inline: var(--margen);
}

.rejilla {
  display: grid;
  grid-template-columns: repeat(var(--columnas), minmax(0, 1fr));
  gap: var(--hueco);
}

/* Utilidades de tramo, las justas. Por debajo de 900 px todo pasa a
   ancho completo: en un móvil no hay doce columnas que repartir. */
.t-3  { grid-column: span 3; }
.t-4  { grid-column: span 4; }
.t-5  { grid-column: span 5; }
.t-6  { grid-column: span 6; }
.t-7  { grid-column: span 7; }
.t-8  { grid-column: span 8; }
.t-9  { grid-column: span 9; }
.t-12 { grid-column: 1 / -1; }

@media (max-width: 900px) {
  .t-3, .t-4, .t-5, .t-6, .t-7, .t-8, .t-9 { grid-column: 1 / -1; }
}

.seccion { padding-block: var(--seccion-y); }
.seccion--alterna { background: var(--papel-2); }

/* Sección con aurora: el color entra como atmósfera, por detrás del
   contenido, sin comprometer el contraste del texto porque las
   manchas van a baja opacidad y muy desenfocadas. */
.seccion--aurora {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.seccion--aurora::before {
  content: '';
  position: absolute;
  inset: -30%;
  z-index: -1;
  background: var(--aurora);
  opacity: .12;
  filter: blur(60px);
}

:root[data-tema="oscuro"] .seccion--aurora::before { opacity: .22; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .seccion--aurora::before { opacity: .22; }
}

/* Sección de contraste: oscura en los dos temas. Redefine los tokens
   de texto y línea dentro de sí misma, de modo que cualquier
   componente que caiga aquí dentro se adapta solo sin necesitar una
   variante propia. */
.seccion--tinta {
  background: var(--noche);
  color: var(--sobre-noche);
  --tinta:   var(--sobre-noche);
  --tinta-2: var(--sobre-noche-2);
  --tinta-3: var(--sobre-noche-3);
  --linea:   var(--linea-noche);
  --papel:   var(--noche);
  --papel-2: var(--noche-2);
  --acento:  var(--acento-noche);
}

.medida { max-width: var(--ancho-texto); }

/* ---------- 6. Accesibilidad ---------- */

.salta-al-contenido {
  position: absolute;
  top: var(--e-2);
  left: var(--e-2);
  z-index: 200;
  padding: var(--e-2) var(--e-4);
  background: var(--acento);
  color: var(--sobre-acento);
  border-radius: var(--radio);
  translate: 0 -200%;
  transition: translate var(--transicion);
}

.salta-al-contenido:focus { translate: 0 0; }

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


/* ============================================================
   COMPONENTES

   Ninguno inventa colores ni medidas: todos consumen las variables
   de 01-cimientos.css. Si mañana cambia el acento de la marca, se
   cambia en un sitio y el sitio entero obedece.
   ============================================================ */

/* ---------- Encabezado de sección ----------
   Antetítulo + título + entrada. Es el patrón que da jerarquía y lo
   que faltaba antes: sin él, cada sección empezaba con un titular
   suelto y todo pesaba lo mismo. */

.enc { display: grid; gap: var(--e-3); margin-bottom: var(--e-6); }

.enc__ante {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  font-family: var(--fuente-texto);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--acento);
}

/* La rayita del antetítulo ancla la sección a la rejilla y es de las
   pocas licencias decorativas del estilo: cuesta 24 px y ordena. */
.enc__ante::before {
  content: '';
  width: var(--e-4);
  height: 2px;
  background: var(--acento);
  flex-shrink: 0;
}

.enc__titulo { font-size: var(--t-2xl); }

.enc__entrada {
  font-size: var(--t-lg);
  color: var(--tinta-2);
  max-width: var(--ancho-texto);
}

/* ---------- Botones ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  /* 48 px de alto real: por encima del mínimo de 44 px que necesita
     un dedo para acertar sin pelearse con la pantalla. */
  min-height: 48px;
  padding: var(--e-3) var(--e-5);
  border: var(--borde) solid transparent;
  border-radius: var(--radio);
  /* Sin esto, un `.btn` que sea <button> se queda con el gris que le
     pone el navegador —#f0f0f0— porque ninguna regla declaraba fondo.
     En un <a> no se notaba: los enlaces no traen fondo propio. En el
     botón «Añadir otro bulto», sobre el cotizador oscuro, quedaba
     texto casi blanco sobre gris claro: 1,06:1, ilegible.
     Las variantes que sí llevan fondo lo declaran más abajo. */
  background: none;
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
  transition: background-color var(--transicion),
              border-color var(--transicion),
              color var(--transicion);
}

/* El botón principal lleva el degradado de marca y un brillo que lo
   cruza al pasar el cursor. El degradado se mueve dentro del propio
   botón: `background-position` sobre un fondo del doble de ancho,
   que no obliga a repintar la página como sí haría animar el color. */
.btn--primario {
  position: relative;
  overflow: hidden;
  background: var(--flujo-macizo);
  background-size: 200% 100%;
  background-position: 0% 50%;
  color: #fff;
  box-shadow: 0 4px 16px hsl(222 100% 46% / .32);
  transition: background-position 420ms ease, box-shadow var(--transicion);
}

.btn--primario:hover {
  background-position: 100% 50%;
  box-shadow: 0 6px 22px hsl(200 100% 46% / .42);
}

/* Destello que recorre el botón. Puramente decorativo, así que se
   marca como no anunciable y desaparece con movimiento reducido. */
.btn--primario::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%, hsl(0 0% 100% / .28) 50%, transparent 65%);
  translate: -120% 0;
}

.btn--primario:hover::after { animation: destello 900ms ease-out; }

@keyframes destello {
  to { translate: 120% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .btn--primario { transition: none; }
  .btn--primario:hover::after { animation: none; }
}

/* Variante cálida, para el segundo camino de una pantalla. El ámbar
   es el complementario del azul: contrasta sin salirse de la paleta. */
.btn--brasa {
  background: var(--brasa);
  color: hsl(24 100% 10%);
  box-shadow: 0 4px 16px hsl(28 100% 50% / .3);
}
.btn--brasa:hover { box-shadow: 0 6px 22px hsl(28 100% 50% / .42); }

/* Botón de WhatsApp. Mismo esqueleto que el ámbar —degradado de marca
   a 115°— pero en verde y con la letra en blanco.
 *
 * El verde del degradado está elegido a partir del blanco, no al
 * revés: es el más vivo con el que la palabra sigue leyéndose. Ver la
 * nota de `--wasap` en 01-cimientos. */
.btn--wa {
  background: var(--wasap);
  color: #fff;
  box-shadow: 0 4px 16px hsl(160 70% 24% / .34);
}
.btn--wa:hover { box-shadow: 0 6px 22px hsl(160 70% 24% / .48); }

.btn--linea {
  border-color: var(--linea);
  color: var(--tinta);
}
.btn--linea:hover { border-color: var(--acento); color: var(--acento); }

.seccion--tinta .btn--linea { border-color: hsl(0 0% 100% / .3); color: var(--sobre-noche); }
.seccion--tinta .btn--linea:hover { border-color: var(--sobre-noche); background: hsl(0 0% 100% / .08); }

.btn--fantasma { color: var(--acento); padding-inline: var(--e-2); }
.btn--fantasma:hover { color: var(--acento-vivo); }

.btn__icono { width: 18px; height: 18px; flex-shrink: 0; }

/* ---------- Enlace con flecha ----------
   La flecha avanza al pasar el cursor. Es movimiento con significado:
   indica que el enlace lleva a otro sitio. */

.enlace-flecha {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--acento);
}

.enlace-flecha svg { width: 16px; height: 16px; transition: translate var(--transicion); }
.enlace-flecha:hover svg { translate: 4px 0; }

@media (prefers-reduced-motion: reduce) {
  .enlace-flecha:hover svg { translate: none; }
}

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

.cabecera {
  position: sticky;
  top: 0;
  z-index: 100;
  background: hsl(from var(--papel) h s l / .88);
  backdrop-filter: blur(12px);
  border-bottom: var(--borde) solid var(--linea-suave);
}

/* `hsl(from ...)` es reciente. Para navegadores que no lo entienden,
   fondo sólido: se pierde el desenfoque, no la legibilidad. */
@supports not (background: hsl(from red h s l)) {
  .cabecera { background: var(--papel); }
}

.cabecera__barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
  height: 72px;
}

.marca { display: flex; align-items: center; gap: var(--e-3); }
.marca__logo { width: 40px; height: 40px; border-radius: 50%; }

/* En la cabecera el logotipo va un 30 % más grande: 52 px.
 *
 * Se acota a `.cabecera` porque `.marca__logo` lo comparte el pie, y
 * allí el tamaño de origen sigue siendo el correcto: en el pie el
 * logotipo acompaña, en la cabecera identifica.
 *
 * Caben de sobra en la barra de 72 px, con 10 px de aire arriba y
 * abajo. El archivo es de 192 px, así que a 52 aún sobra resolución
 * en pantallas de tres veces la densidad. */
.cabecera .marca__logo { width: 52px; height: 52px; }
.marca__texto { display: grid; line-height: 1.2; }
.marca__nombre {
  font-family: var(--fuente-titulo);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -.01em;
}
.marca__cola {
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tinta-3);
}

@media (max-width: 560px) { .marca__texto { display: none; } }

/* ---------- Navegación ---------- */

.menu { display: flex; align-items: center; gap: var(--e-1); }

.menu__enlace {
  position: relative;
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--tinta-2);
  border-radius: var(--radio);
  transition: color var(--transicion);
}

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

/* La página actual se marca con una barra bajo el enlace, no con
   color: el color solo no basta para quien no distingue tonos. */
.menu__enlace.es-actual { color: var(--acento); }
.menu__enlace.es-actual::after {
  content: '';
  position: absolute;
  left: var(--e-3);
  right: var(--e-3);
  bottom: 2px;
  height: 2px;
  background: var(--acento);
}

.menu-grupo { position: relative; }

.menu-grupo__panel {
  position: absolute;
  top: calc(100% + var(--e-2));
  left: 0;
  min-width: 260px;
  padding: var(--e-2);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-3);
  display: grid;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  translate: 0 -6px;
  transition: opacity var(--transicion), translate var(--transicion), visibility var(--transicion);
}

/* Puente invisible sobre el hueco que separa el padre del panel.
   Sin él, al bajar el ratón desde «Servicios» se cruzan 8 px sin
   nada debajo, el `:hover` se pierde y el panel se cierra en la
   cara del usuario justo cuando iba a elegir. */
.menu-grupo__panel::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--e-2) * -1);
  height: var(--e-2);
}

/* Se abre al pasar el ratón y también al llegar con el tabulador:
   `:focus-within` es lo que hace que exista para quien navega con
   teclado, que con solo `:hover` no podría verlo nunca. */
.menu-grupo:hover .menu-grupo__panel,
.menu-grupo:focus-within .menu-grupo__panel {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
}

/* El padre lleva una punta que avisa de que hay más debajo. Sin ella
   el desplegable es invisible hasta que alguien pasa por encima por
   casualidad. */
.menu-grupo > .menu__enlace {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
}

.menu__punta {
  width: 14px;
  height: 14px;
  transition: rotate var(--transicion);
}

.menu-grupo:hover .menu__punta,
.menu-grupo:focus-within .menu__punta { rotate: 180deg; }

@media (prefers-reduced-motion: reduce) {
  .menu-grupo__panel { transition: none; }
  .menu__punta { transition: none; }
}

.menu-grupo__panel .menu__enlace { padding: var(--e-3); }
.menu-grupo__panel .menu__enlace:hover { background: var(--papel-2); }
.menu-grupo__panel .menu__enlace.es-actual::after { display: none; }
.menu-grupo__panel .menu__enlace.es-actual { background: var(--acento-tenue); }

.menu-boton {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio);
  background: none;
  cursor: pointer;
}

.menu-movil {
  display: none;
  padding: var(--e-3) 0 var(--e-5);
  border-top: var(--borde) solid var(--linea-suave);
}

.menu-movil[data-abierto] { display: grid; gap: 2px; }
.menu-movil .menu__enlace { padding: var(--e-3); font-size: var(--t-base); }
.menu-movil .menu__enlace--hijo { padding-left: var(--e-5); font-size: var(--t-sm); color: var(--tinta-3); }
.menu-movil .menu__enlace.es-actual::after { display: none; }
.menu-movil .menu__enlace.es-actual { background: var(--acento-tenue); }

/* Encabezado de un grupo que no tiene página propia. No es un enlace
   porque no lleva a ninguna parte: fingirlo con un <a> obliga al lector
   de pantalla a anunciar un destino que no existe. */
.menu__rotulo {
  padding: var(--e-4) var(--e-3) var(--e-1);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tinta-3);
}

@media (max-width: 1024px) {
  .menu--escritorio { display: none; }
  .menu-boton { display: inline-flex; }
}

/* ---------- Interruptor de tema ----------
   Un conmutador con disco que se desliza, no un botón que cambia de
   icono. El icono a secas obligaba a interpretarlo; el disco enseña en
   qué lado está y hacia dónde va.

   El icono muestra el tema ACTUAL, no el que se activaría: es como se
   comportan los interruptores del sistema operativo, y el disco ya
   indica que hay dos posiciones. */

/* El tema tiene tres estados, no dos: claro, oscuro, y «lo que diga el
   sistema» cuando nadie ha elegido. Resolverlo aquí una sola vez, en
   variables, evita repetir los tres selectores en el disco, en el sol,
   en la luna y en cada color. Cambiar el recorrido del disco es tocar
   un número, no seis reglas. */
/* La pista es cielo: azul de día, azul de noche. No es adorno, es lo
   que resuelve el contraste.
 *
 * La primera versión tenía la pista clara en gris muy pálido, como el
 * ejemplo de referencia. Medido: el disco blanco daba 1,31:1 contra
 * ella y el sol ámbar 2,30:1, cuando un elemento gráfico que comunica
 * un estado necesita 3:1. Sobre azul de día, ambos suben a 4,75:1 y
 * de paso el interruptor deja de ser gris. */
:root {
  --tema-desliz: 0px;
  --tema-sol:  1;
  --tema-luna: 0;
  --tema-pista: hsl(210 85% 45%);
  --tema-disco: #fff;
  --tema-icono: #fff;
  --tema-borde: var(--linea);
}

:root[data-tema="oscuro"] {
  --tema-desliz: 28px;
  --tema-sol:  0;
  --tema-luna: 1;
  --tema-pista: hsl(224 52% 19%);
  --tema-disco: hsl(214 22% 78%);
  --tema-icono: hsl(210 92% 80%);
  --tema-borde: hsl(213 30% 52%);         /* luna: azul frío */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --tema-desliz: 28px;
    --tema-sol:  0;
    --tema-luna: 1;
    --tema-pista: hsl(224 52% 19%);
    --tema-disco: hsl(214 22% 78%);
    --tema-icono: hsl(210 92% 80%);
    --tema-borde: hsl(213 30% 52%);
  }
}

/* El botón mide 44 px de alto aunque la pastilla mida 32: es la zona
   que recibe el dedo, y por debajo de 44 se falla el objetivo. */
.tema-boton {
  display: inline-flex;
  align-items: center;
  width: 60px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.tema-boton:focus-visible { border-radius: 100px; }

.tema-boton__pista {
  position: relative;
  display: block;
  width: 100%;
  height: 32px;
  border-radius: 100px;
  background: var(--tema-pista);
  /* Borde propio y no `--linea`: en tema oscuro la pastilla es casi
     tan oscura como la barra y su contorno se perdía en 1,79:1.
     Un borde más claro lo devuelve por encima de 3:1. */
  border: var(--borde) solid var(--tema-borde);
  transition: background var(--transicion), border-color var(--transicion);
}

.tema-boton:hover .tema-boton__pista { border-color: var(--acento); }

.tema-boton__disco {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--tema-disco);
  box-shadow: 0 2px 6px hsl(222 45% 12% / .3);
  translate: var(--tema-desliz) 0;
  /* `translate` y no `transform`: las entradas de sección ya usan
     `transform` para el hover, y mezclarlos en una misma propiedad
     hace que una animación pise a la otra. */
  transition: translate .3s cubic-bezier(.34, 1.2, .5, 1),
              background var(--transicion);
}

/* Los iconos van en el lado que el disco deja libre: con el disco a la
   izquierda se ve el sol de la derecha, y al revés. */
.tema-boton svg {
  position: absolute;
  top: 50%;
  width: 15px;
  height: 15px;
  margin-top: -7.5px;
  color: var(--tema-icono);
  transition: opacity var(--transicion);
}

.tema-boton .icono-sol  { right: 8px; opacity: var(--tema-sol); }
.tema-boton .icono-luna { left:  8px; opacity: var(--tema-luna); }

@media (prefers-reduced-motion: reduce) {
  .tema-boton__disco { transition: none; }
}

/* ---------- Portada ----------
   Titular a sangre, texto mínimo y un solo camino claro. Lo que antes
   eran cinco párrafos aquí son dos frases: la portada no es donde se
   explica el servicio, es donde se decide entrar. */

/* Oscura en los dos temas, igual que el pie: es una fotografía con un
   velo encima, no una superficie que deba seguir al tema. Con
   `--tinta` el fondo se volvía claro en tema oscuro y el texto blanco
   caía sobre él allí donde el velo es más transparente. */
.portada {
  position: relative;
  display: grid;
  align-items: end;
  min-height: min(88vh, 780px);
  padding-block: var(--e-8) var(--e-7);
  overflow: hidden;
  background: var(--noche);
  color: var(--sobre-noche);

  /* Redefine los tokens dentro de sí misma, igual que .seccion--tinta.
     Sin esto, un `.btn--linea` colocado aquí tomaba `--tinta`, que en
     tema claro es casi negro, y quedaba texto oscuro sobre la
     fotografía oscura: 1,06:1. Ahora cualquier componente que caiga
     dentro de la portada se adapta solo. */
  --tinta:   var(--sobre-noche);
  --tinta-2: var(--sobre-noche-2);
  --tinta-3: var(--sobre-noche-3);
  --linea:   hsl(0 0% 100% / .32);
  --acento:  var(--acento-noche);
}

/* La foto se ve. Antes iba al 38 % bajo un velo casi negro y la
   portada quedaba apagada: se leía «sitio serio» pero también «sitio
   de hace diez años».

   Ahora va al 78 % con saturación y contraste subidos, y el velo es
   un degradado de marca en lugar de negro. El azul y el cian tiñen la
   fotografía en vez de taparla. */
.portada__fondo {
  position: absolute;
  inset: 0;
  object-fit: cover;
  width: 100%;
  height: 100%;
  opacity: .90;
  filter: saturate(1.25) contrast(1.08) brightness(1.06);
}

/* Capa 1 — Aurora: manchas de color que dan el aire luminoso. Va en
   `screen`, que aclara en vez de oscurecer. */
.portada::before {
  content: '';
  position: absolute;
  inset: -20%;
  background: var(--aurora);
  mix-blend-mode: screen;
  opacity: .85;
  filter: blur(40px);
  animation: auroraFlota 24s ease-in-out infinite alternate;
}

/* Capa 2 — legibilidad. Solo donde va el texto, y en azul de marca,
   no en negro: la parte alta de la imagen queda limpia.
 *
 * La curva está dibujada sobre la medida, no a ojo: el bloque de texto
 * ocupa del 8 % al 60 % de la altura contando desde abajo. Por eso el
 * velo aguanta denso hasta el 55 % —donde termina el titular— y a
 * partir de ahí se desploma hasta desaparecer en el 80 %. Antes caía
 * de forma pareja y ya valía 0,30 a la altura del titular: protegía
 * poco donde hacía falta y de más donde no.
 *
 * Con esa curva la foto puede ir al 90 % en vez del 78 %. Resultado
 * medido componiendo foto y velo en un lienzo: la portada es un 49 %
 * más clara entre 768 y 1920 px, y el titular conserva el mismo margen
 * de contraste que antes o mejor. */
.portada::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top,
      hsl(224 70% 8% / .90) 0%,
      hsl(224 68% 9% / .72) 30%,
      hsl(224 66% 10% / .48) 55%,
      hsl(224 60% 14% / .04) 70%,
      transparent 80%),
    linear-gradient(to right,
      hsl(224 70% 8% / .52) 0%,
      transparent 58%);
}

/* En pantalla estrecha manda otra física: `cover` recorta la foto a
   una tira vertical, el titular ocupa proporcionalmente mucho más
   alto, y el degradado lateral no ayuda porque no hay ancho que
   recorrer.
 *
 * Medido, el velo de escritorio ahí no llegaba: el titular caía a
 * 2,64:1 y el antetítulo a 1,65:1 —por debajo del mínimo— y eso ya
 * pasaba antes de tocar nada. No se había visto porque el comprobador
 * general no mide el texto que va sobre fotografía.
 *
 * Aquí el velo aprieta. Se pierde brillo, pero en móvil la foto se ve
 * recortada de todos modos y lo que no puede perderse es el texto. */
@media (max-width: 700px) {
  .portada__fondo { opacity: .86; }
  .portada::after {
    background:
      linear-gradient(to top,
        hsl(224 72% 7% / .96) 0%,
        hsl(224 70% 8% / .90) 40%,
        hsl(224 68% 9% / .72) 62%,
        hsl(224 60% 14% / .20) 80%,
        transparent 92%);
  }
}

@keyframes auroraFlota {
  from { transform: translate3d(-3%, -2%, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.12); }
}

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

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

.portada__ante {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-4);
  padding: var(--e-2) var(--e-3);
  background: hsl(0 0% 100% / .1);
  backdrop-filter: blur(8px);
  border: var(--borde) solid hsl(0 0% 100% / .3);
  border-radius: 100px;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* El punto late: señal de «estamos operando», no adorno. */
.portada__punto {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--cian-vivo);
  box-shadow: 0 0 0 0 hsl(187 100% 52% / .7);
  animation: latido 2.4s ease-out infinite;
}

@keyframes latido {
  0%   { box-shadow: 0 0 0 0 hsl(187 100% 52% / .7); }
  70%  { box-shadow: 0 0 0 9px hsl(187 100% 52% / 0); }
  100% { box-shadow: 0 0 0 0 hsl(187 100% 52% / 0); }
}

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

.portada__titulo {
  font-size: var(--t-4xl);
  font-weight: 700;
  line-height: .95;
  letter-spacing: -.045em;
  text-transform: uppercase;
  margin-bottom: var(--e-4);
  text-shadow: 0 2px 30px hsl(224 70% 8% / .5);
}

/* La palabra clave va con el degradado de marca recortado sobre el
   texto. Es la firma visual del sitio: el cian solo aparece aquí y en
   los acentos, así que cuando aparece, significa algo. */
.portada__titulo em {
  font-style: normal;
  background: linear-gradient(100deg, hsl(187 100% 62%) 0%, hsl(199 100% 68%) 55%, hsl(215 100% 74%) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  /* Si el recorte sobre texto no está disponible, el color de reserva
     evita que la palabra quede invisible. */
  -webkit-text-fill-color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .portada__titulo em {
    background: none;
    color: var(--cian-noche);
    -webkit-text-fill-color: currentColor;
  }
}

.portada__entrada {
  font-size: var(--t-lg);
  color: hsl(0 0% 100% / .82);
  max-width: 54ch;
  margin-bottom: var(--e-5);
}

.portada__acciones { display: flex; flex-wrap: wrap; gap: var(--e-3); }

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

.cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--e-5);
}

.cifra { display: grid; gap: var(--e-2); }

/* Número y unidad en la misma línea, alineados por la base y no por la
   caja: con `center` la palabra flotaba a media altura del número, que
   es tres veces más alto. */
.cifra__linea {
  display: flex;
  align-items: baseline;
  gap: .28em;
  flex-wrap: wrap;
}

/* La unidad acompaña, no compite: va en el gris del cuerpo y a un
   tercio del tamaño del número. Si llevara el degradado y el cuerpo
   del número, «4 modos» se leería como una sola palabra larga. */
.cifra__unidad {
  font-family: var(--fuente-titulo);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--tinta-2);
  text-transform: uppercase;
}

.cifra__valor {
  font-family: var(--fuente-titulo);
  font-size: var(--t-3xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.05em;
  font-variant-numeric: tabular-nums;   /* no bailan al contar */
  background: var(--flujo-texto);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .cifra__valor { background: none; color: var(--acento); -webkit-text-fill-color: currentColor; }
}

.cifra__texto {
  font-size: var(--t-sm);
  color: var(--tinta-2);
  padding-top: var(--e-3);
  /* Una línea de color en vez de una gris: cada cifra queda anclada
     a la rejilla por una barra de marca, y la fila se lee como un
     sistema y no como cuatro datos sueltos. */
  border-top: 3px solid transparent;
  border-image: var(--flujo) 1;
}

/* ---------- Tarjetas ---------- */

.tarjeta {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-5);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  overflow: hidden;
  transition: border-color var(--transicion),
              box-shadow var(--transicion),
              translate var(--transicion);
}

/* Barra de marca que crece desde la izquierda al señalar la tarjeta.
   Es la misma idea del degradado del botón: el color aparece cuando
   hay intención, no de entrada. */
.tarjeta::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--flujo);
  scale: 1 0;
  transform-origin: bottom;
  transition: scale var(--transicion-lenta);
}

.tarjeta:hover {
  border-color: transparent;
  box-shadow: var(--sombra-3);
  translate: 0 -4px;
}

.tarjeta:hover::before { scale: 1 1; }

@media (prefers-reduced-motion: reduce) {
  .tarjeta, .tarjeta::before { transition: none; }
  .tarjeta:hover { translate: none; }
}

.tarjeta__num {
  font-family: var(--fuente-mono);
  font-size: var(--t-xs);
  letter-spacing: .1em;
  color: var(--tinta-3);
}

.tarjeta__titulo { font-size: var(--t-xl); }
.tarjeta__texto { font-size: var(--t-sm); color: var(--tinta-2); flex-grow: 1; }

.tarjeta__icono {
  width: 32px; height: 32px;
  color: var(--acento);
  stroke-width: 1.5;
}

.tarjeta--enlace:hover .enlace-flecha svg { translate: 4px 0; }

/* ---------- Modos de transporte ----------
   Cuatro columnas en escritorio, dos en tableta, una en móvil. El
   número de orden ancla cada uno a la rejilla. */

.modos { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--e-4); }

@media (max-width: 1024px) { .modos { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .modos { grid-template-columns: 1fr; } }

/* ---------- Tarjeta de modo con fotografía ----------

   La foto va arriba, recortada a 16:9, con un velo que la funde con
   la tarjeta. Antes eran icono y texto sobre blanco: correcto pero
   plano, y sin nada que distinguiera un modo de otro más que el
   dibujo.

   El icono se superpone sobre la foto, no debajo: así el modo se
   reconoce de un vistazo aunque la imagen tarde en cargar.            */

.modo { padding: 0; overflow: hidden; }

.modo__foto {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--papel-3);
}

.modo__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La foto se acerca despacio al señalar la tarjeta. Se anima
     `scale`, que la GPU compone sin repintar el resto de la página. */
  scale: 1;
  transition: scale 700ms cubic-bezier(.2,0,.2,1), filter var(--transicion);
  filter: saturate(.92);
}

.modo:hover .modo__foto img { scale: 1.07; filter: saturate(1.08); }

/* Velo inferior: funde la foto con el cuerpo de la tarjeta y sostiene
   el icono, que si no quedaría flotando sobre cielo claro. */
.modo__foto::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    hsl(224 62% 9% / .82) 0%,
    hsl(224 62% 9% / .28) 42%,
    hsl(224 62% 9% / .04) 100%);
}

.modo__icono {
  position: absolute;
  left: var(--e-4);
  bottom: var(--e-3);
  z-index: 1;
  width: 34px;
  height: 34px;
  color: #fff;
  stroke-width: 1.6;
  filter: drop-shadow(0 2px 8px hsl(224 70% 6% / .7));
}

/* El número lleva su propia pastilla oscura, y no solo el velo de la
   foto.

   Antes se fiaba del velo, con esta nota: «con 78 % y una sombra fina,
   el peor caso sigue siendo legible». Medido componiendo cada foto con
   el velo encima y buscando el píxel más claro bajo el número, no lo
   era: 3,37:1 sobre F3, 2,12:1 sobre F2 y 3,45:1 sobre F4. Solo F1
   pasaba, con 6,90:1. La razón es que el velo se apaga hacia arriba y
   ahí donde cae el número deja pasar el cielo claro de la foto.

   Con fondo propio el resultado deja de depender de qué se vea en la
   imagen: si mañana se cambia una foto, el número sigue leyéndose. */
.modo__num {
  position: absolute;
  right: var(--e-4);
  bottom: var(--e-3);
  z-index: 1;
  padding: 3px 8px;
  border-radius: var(--radio);
  background: hsl(224 70% 6% / .72);
  backdrop-filter: blur(6px);
  font-family: var(--fuente-mono);
  font-size: var(--t-xs);
  letter-spacing: .12em;
  color: hsl(0 0% 100% / .95);
}

.modo__cuerpo {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-4) var(--e-4) var(--e-5);
  flex-grow: 1;
}

@media (prefers-reduced-motion: reduce) {
  .modo__foto img { transition: none; }
  .modo:hover .modo__foto img { scale: 1; }
}

/* ---------- Galería de operaciones ----------
   Cuatro fotografías reales. La primera ocupa el doble de ancho: sin
   esa jerarquía, cuatro imágenes iguales se leen como una cuadrícula
   de archivo y no como una selección. */

.galeria {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--e-3);
}

/* ---------- Mosaico: una grande y cuatro pequeñas ----------
   La destacada ocupa dos columnas Y DOS FILAS. Solo dos columnas, que
   es como estaba, dejaba media fila vacía a su derecha y las últimas
   piezas caían debajo de ella en vez de completar la retícula.

   El selector va anclado a `.galeria >` a propósito. Suelto, como
   `.galeria__pieza:first-child`, tiene más especificidad que las
   utilidades de tramo (`.t-6`), así que se aplicaba también a
   cualquier figura que fuese el primer hijo de otra rejilla: en la
   sección de mascotas la dejaba en dos columnas de doce, 172 px. */
.galeria--mosaico > .galeria__pieza:first-child {
  grid-column: span 2;
  grid-row: span 2;
  aspect-ratio: auto;   /* la altura la marcan las dos filas */
}

@media (max-width: 900px) {
  .galeria--mosaico > .galeria__pieza:first-child {
    grid-row: span 1;
    aspect-ratio: 4 / 3;
  }
}

.galeria__pieza {
  position: relative;
  margin: 0;
  border-radius: var(--radio-lg);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--papel-3);
}

.galeria__pieza img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  scale: 1;
  transition: scale 700ms cubic-bezier(.2,0,.2,1);
}

.galeria__pieza:hover img { scale: 1.06; }

.galeria__pieza figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--e-5) var(--e-3) var(--e-3);
  font-size: var(--t-sm);
  font-weight: 500;
  color: #fff;
  background: linear-gradient(to top, hsl(224 62% 9% / .88), transparent);
}

.galeria__pie { margin-top: var(--e-4); }

@media (max-width: 900px) {
  .galeria { grid-template-columns: repeat(2, 1fr); }
  .galeria--mosaico > .galeria__pieza:first-child { grid-column: span 2; }
}

@media (max-width: 520px) {
  .galeria { grid-template-columns: 1fr; }
  .galeria--mosaico > .galeria__pieza:first-child { grid-column: auto; }
}

/* ---------- Figura suelta ----------
   Para las que van dentro de una rejilla de doce columnas, no en una
   galería: ahí el tramo lo manda `.t-*` y la figura solo aporta el
   recorte y el pie. */
.figura {
  position: relative;
  margin: 0;
  border-radius: var(--radio-lg);
  overflow: hidden;
  background: var(--papel-3);
}

.figura img { width: 100%; height: 100%; object-fit: cover; display: block; }

.figura figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--e-6) var(--e-4) var(--e-3);
  font-size: var(--t-sm);
  font-weight: 500;
  color: #fff;
  background: linear-gradient(to top, hsl(224 62% 9% / .9), transparent);
}

@media (prefers-reduced-motion: reduce) {
  .galeria__pieza img { transition: none; }
  .galeria__pieza:hover img { scale: 1; }
}

/* ---------- Pastilla de destino ----------
   Era la pieza de la marquesina del inicio, que sustituyó el carrusel.
   Se conserva porque la página de error la usa como enlace rápido. */

.destino {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  /* 44 px de alto: son enlaces reales y en un teléfono hay que poder
     acertarles con el dedo. Con solo el relleno se quedaban en 41. */
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  border: var(--borde) solid var(--linea);
  border-radius: 100px;
  font-size: var(--t-sm);
  color: var(--tinta-2);
  transition: border-color var(--transicion), color var(--transicion), background-color var(--transicion);
}

.destino:hover { background: var(--acento-tenue); }

.destino:hover { border-color: var(--acento); color: var(--tinta); }
.destino__bandera { width: 24px; height: 16px; border-radius: 2px; box-shadow: 0 0 0 1px var(--linea); }


/* ---------- Pie ---------- */

/* Oscuro en los dos temas, con los tokens que no se invierten. Con
   `--tinta` y `--papel` el pie se volvía blanco en tema oscuro. */
.pie {
  background: var(--noche);
  color: var(--sobre-noche);
  padding-block: var(--e-7) var(--e-5);
  --tinta:   var(--sobre-noche);
  --tinta-2: var(--sobre-noche-2);
  --tinta-3: var(--sobre-noche-3);
  --linea:   var(--linea-noche);
  --acento:  var(--acento-noche);
}

.pie__titulo {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tinta-3);
  margin-bottom: var(--e-3);
}

.pie__lista { display: grid; gap: var(--e-2); }
.pie__lista a { font-size: var(--t-sm); color: var(--tinta-2); transition: color var(--transicion); }
.pie__lista a:hover { color: var(--papel); }

.pie__legal {
  margin-top: var(--e-7);
  padding-top: var(--e-4);
  border-top: var(--borde) solid var(--linea);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--e-3);
  font-size: var(--t-xs);
  color: var(--tinta-3);
}

/* ============================================================
   ENTRADA DE LA PORTADA

   Se dispara cuando sube el telón, no al cargar: la portada debe
   leerse como continuación de la misma toma, no como una página
   distinta que aparece debajo.

   Sin cortina —segunda visita de la sesión, o movimiento reducido—
   el JavaScript marca la portada como lista de inmediato y no hay
   espera. Nadie ve nunca una portada vacía.
   ============================================================ */

.portada__contenido > * {
  opacity: 0;
  translate: 0 22px;
}

html.portada-lista .portada__contenido > * {
  animation: portadaEntra 720ms cubic-bezier(.16,.84,.24,1) forwards;
}

/* Escalonado: distintivo, titular, párrafo y botones, en ese orden.
   90 ms entre cada uno; el conjunto entra en poco más de medio
   segundo, que es lo que dura la subida del telón. */
html.portada-lista .portada__contenido > *:nth-child(1) { animation-delay: 60ms; }
html.portada-lista .portada__contenido > *:nth-child(2) { animation-delay: 150ms; }
html.portada-lista .portada__contenido > *:nth-child(3) { animation-delay: 240ms; }
html.portada-lista .portada__contenido > *:nth-child(4) { animation-delay: 330ms; }

@keyframes portadaEntra { to { opacity: 1; translate: 0 0; } }

@media (prefers-reduced-motion: reduce) {
  .portada__contenido > * { opacity: 1; translate: none; }
  html.portada-lista .portada__contenido > * { animation: none; }
}

/* Sin JavaScript la clase nunca llega, así que la portada se muestra
   tal cual: nunca se deja contenido invisible por no poder animarlo. */
html:not(.js-listo) .portada__contenido > * { opacity: 1; translate: none; }

/* ---------- Indicador de bajar ----------
   La portada ocupa casi toda la pantalla; sin esto nada sugiere que
   hay más abajo. */
.bajar {
  position: absolute;
  left: 50%;
  bottom: var(--e-4);
  z-index: 2;
  translate: -50% 0;
  display: grid;
  justify-items: center;
  gap: var(--e-1);
  font-size: var(--t-xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .6);
  transition: color var(--transicion);
}

.bajar:hover { color: #fff; }

.bajar__punta {
  width: 22px;
  height: 22px;
  animation: bajaPunta 2.2s cubic-bezier(.4,0,.2,1) infinite;
}

@keyframes bajaPunta {
  0%, 100% { translate: 0 0;    opacity: .5; }
  50%      { translate: 0 6px;  opacity: 1; }
}

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

@media (max-height: 640px) { .bajar { display: none; } }

/* ---------- Barra de progreso de lectura ---------- */
.progreso {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: 110;
  pointer-events: none;
  background: transparent;
}

.progreso__valor {
  display: block;
  height: 100%;
  width: 0;
  background: var(--flujo);
  box-shadow: 0 0 10px hsl(199 100% 55% / .7);
}

/* ---------- Botones flotantes ----------
   WhatsApp siempre a mano, y volver arriba cuando ya se ha bajado.
   Cuatro pantallas de recorrido sin atajo de vuelta se hacen largas. */

.flotantes {
  position: fixed;
  right: var(--e-4);
  bottom: var(--e-4);
  z-index: 90;
  display: grid;
  justify-items: center;
}

.flotante {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: var(--borde) solid transparent;
  cursor: pointer;
  transition: translate var(--transicion), box-shadow var(--transicion),
              opacity var(--transicion), visibility var(--transicion);
}

.flotante:hover { translate: 0 -3px; }
.flotante svg { width: 24px; height: 24px; }

/* El verde oficial de WhatsApp, #25D366, con el glifo en blanco: es su
   botón tal cual, el que la gente reconoce sin leer nada.
 *
 * Estuvo un tiempo en el ámbar de la marca. Se vuelve al verde por
 * decisión del cliente.
 *
 * El aro verde oscuro no es decoración: el relleno claro sobre una
 * página blanca da 1,77:1, y sin él el borde del botón se perdería.
 * El aro da 3,67:1 contra el papel y deja el contorno definido en los
 * dos temas. */
/* En hexadecimal y no en HSL: es un color de marca ajeno, con un valor
   exacto que hay que poder comparar de un vistazo con el de WhatsApp.
   Convertido a HSL salía #25D466, un punto de verde de más. */
.flotante--wa {
  background: #25D366;
  border-color: #128C4A;
  color: #fff;
  box-shadow: 0 6px 20px hsl(142 70% 40% / .42);
}

.flotante--wa:hover {
  background: #1FBE5A;
  box-shadow: 0 10px 26px hsl(142 70% 38% / .55);
}

/* El logotipo llena el botón, como en el de WhatsApp.
 *
 * A los 24 px del resto quedaba un dibujo pequeño perdido en un disco
 * verde: apenas el 6 % del círculo era tinta blanca. A 36 px ocupa el
 * 69 % del ancho y el 17 % del área, con 2,7 px de aire hasta el
 * borde. Medido rasterizando el trazado sobre el disco, no a ojo.
 *
 * No sube más porque la marca oficial llena su lienzo de lado a lado,
 * sin el margen que traía el dibujo anterior: a 37 px la burbuja ya
 * roza el filo del botón.
 *
 * La flecha de «volver arriba» se queda en 24: es un trazo, no un
 * logotipo, y al ampliarla se vería basta. */
.flotante--wa svg { width: 36px; height: 36px; }

.flotante--arriba {
  background: var(--papel);
  border-color: var(--linea);
  color: var(--tinta-2);
  box-shadow: var(--sombra-2);
  opacity: 0;
  visibility: hidden;
  /* Fuera del flujo, apoyado sobre el borde superior del contenedor.
   *
   * `visibility: hidden` seguiría ocupando su sitio en la rejilla, y
   * ahora que va ENCIMA ese hueco reservado empujaría el botón de
   * WhatsApp 52 px hacia arriba mientras no se ha desplazado la
   * página.
   *
   * La primera solución fue animar la altura de 0 a 52. Funcionaba,
   * pero animar `height` obliga al navegador a recalcular la
   * distribución en cada fotograma y se nota el tirón. Sacándolo del
   * flujo no reserva nada, no hay nada que animar, y lo único que
   * cambia es la opacidad. */
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--e-2));
  transition: opacity var(--transicion), visibility var(--transicion),
              translate var(--transicion);
  translate: 0 6px;
}

.flotante--arriba.es-visible {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
}
.flotante--arriba:hover { color: var(--acento); border-color: var(--acento); }

/* ---------- Latido del botón de WhatsApp ----------
   Un aro que se expande y se desvanece cada tres segundos. No mueve el
   botón ni cambia su tamaño: lo que late es un pseudoelemento detrás,
   así que el objetivo no se desplaza bajo el dedo justo cuando alguien
   va a pulsarlo.

   Tres segundos y no uno: a ritmo rápido deja de ser una señal y pasa
   a ser un parpadeo que molesta mientras se lee la página. */
.flotante--wa::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid #25D366;
  animation: latidoWa 3s ease-out infinite;
  pointer-events: none;
}

@keyframes latidoWa {
  0%   { transform: scale(1);    opacity: .75; }
  70%  { transform: scale(1.55); opacity: 0; }
  100% { transform: scale(1.55); opacity: 0; }
}

/* El aro se dibuja fuera del botón, así que el disco no puede recortar
   lo que le sobresale. */
.flotante--wa { position: relative; overflow: visible; }

@media (max-width: 560px) {
  .flotantes { right: var(--e-3); bottom: var(--e-3); }
  .flotante { width: 48px; height: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  .flotante, .flotante:hover { transition: none; translate: none; }
  /* Quien pide menos movimiento no quiere un aro latiendo en la
     esquina de forma permanente. El botón sigue ahí, quieto. */
  .flotante--wa::after { animation: none; opacity: 0; }
}

/* ---------- Entrada al hacer scroll ----------
   Se anima `translate` y `opacity`, nunca `width`/`height`: esas dos
   obligan al navegador a recalcular la página en cada fotograma.

   Sin JavaScript el contenido se ve igual: la clase solo se aplica
   cuando el script confirma que puede observar la entrada. */

.entra { opacity: 0; translate: 0 20px; }

html.js-listo .entra {
  transition: opacity var(--transicion-lenta), translate var(--transicion-lenta);
}

html.js-listo .entra.es-visible { opacity: 1; translate: 0 0; }

@media (prefers-reduced-motion: reduce) {
  .entra { opacity: 1; translate: none; transition: none; }
}


/* ============================================================
   PANTALLA DE CARGA

   CONCEPTO
   No es un girador genérico: es la operación de la empresa contada en
   cuatro segundos. El emblema se dibuja solo bajo un barrido de
   radar; después la ruta multimodal avanza encendiendo barco, avión,
   camión y tren mientras un punto de carga la recorre dejando estela;
   por último el nombre se revela letra a letra y el telón sube.

   LÍNEA DE TIEMPO (ms desde que se activa)
        0 → 1000   el anillo de luz se traza alrededor
      180 → 1330   el logo oficial cierra el foco: de desenfocado y
                   grande a nítido y a tamaño
      700 → 1600   entra el halo; después respira en bucle
     1180 → 2000   primera pasada del destello especular
     2300 → 3400   segunda pasada, más tenue y lenta
     2900 → 3680   fogonazo de cierre al completarse la ruta
     1250 → 3100   la ruta avanza y el punto la recorre
     1500, 1950, 2400, 2850   se enciende cada modo
     1620, 2070, 2520, 2970   sale la onda de cada modo
     2800 → 3910   el nombre, letra a letra (26 letras a 26 ms)
     3430 → 3950   el rótulo
      150 → 3800   la barra se llena
     4000           sube el telón

   Nada puede terminar después de los 4000 ms o se cortaría a media
   entrada. Lo último en acabar es el rótulo, a 3950. Si se cambia la
   duración, hay que cambiarla también en `activarCargando()` de
   `gjg.js`, donde está el temporizador que cierra.

   TRES DECISIONES QUE NO SON DE ESTILO

   1. Se muestra según la clase `con-cortina` que pone un script EN
      LÍNEA en la cabecera, antes del primer pintado. Antes lo decidía
      el archivo externo y se alcanzaba a ver medio segundo de la
      portada antes de que cayera el telón.

   2. Oculta por defecto: si no hay JavaScript, la clase nunca se pone
      y no hay cortina. Un fallo del script no puede dejar el sitio
      tapado por algo que nadie puede quitar.

   3. Se muestra UNA VEZ por sesión. Cuatro segundos en cada una de
      las quince páginas dejarían de ser una bienvenida para
      convertirse en un peaje.
   ============================================================ */

.cargando {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  place-items: center;
  background: var(--noche);
  overflow: hidden;
  transition: opacity 700ms cubic-bezier(.4,0,.2,1),
              translate 800ms cubic-bezier(.65,0,.35,1),
              visibility 800ms;
}

/* La clase la pone el script de la cabecera, así que la cortina ya
   está pintada en el primer fotograma: no hay destello de la portada. */
html.con-cortina .cargando { display: grid; }

/* Se bloquea el desplazamiento desde el mismo momento. Si se hiciera
   con JavaScript, entre el pintado y la ejecución la rueda del ratón
   ya podría mover la página por detrás del telón. */
html.con-cortina { overflow: hidden; }

/* El telón sube, no se desvanece: sugiere que la página estaba
   detrás, no que aparece de la nada. */
.cargando.ha-terminado {
  opacity: 0;
  translate: 0 -100%;
  visibility: hidden;
  pointer-events: none;
}

/* Aurora: el mismo recurso de la portada, para que el paso de la
   cortina a la página sea de continuidad y no de corte. */
.cargando::before {
  content: '';
  position: absolute;
  inset: -25%;
  background: var(--aurora);
  opacity: .95;
  filter: blur(55px);
  animation: cargandoAurora 7s ease-in-out infinite alternate;
}

@keyframes cargandoAurora {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 1%, 0) scale(1.12); }
}

/* Retícula de plano de operaciones. Muy tenue: se percibe, no se mira. */
.cargando__malla {
  position: absolute;
  inset: -10%;
  background-image:
    linear-gradient(hsl(0 0% 100% / .05) 1px, transparent 1px),
    linear-gradient(90deg, hsl(0 0% 100% / .05) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 35%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 35%, transparent 78%);
  animation: mallaCorre 22s linear infinite;
}

@keyframes mallaCorre { to { background-position: 56px 56px; } }

.cargando__caja {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--e-4);
  padding-inline: var(--e-4);
  text-align: center;
}

/* ============================================================
   ACTO 1 · Emblema
   ============================================================ */

.emblema {
  position: relative;
  width: clamp(104px, 24vw, 148px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  margin-bottom: var(--e-3);
}

/* ---------- El logo oficial ----------

   TRATAMIENTO
   Tirón de foco: entra desenfocado y un 22 % más grande, y cierra a
   nítido y a tamaño. Es lo que hace una cámara al enfocar, y funciona
   porque el ojo lee «esto se está revelando» antes de reconocer qué
   es. Se anima `filter` y `scale`, las dos compuestas por la GPU.

   El disco recorta en círculo: el logo es un emblema redondo dentro de
   una imagen cuadrada, y sin el recorte se verían las esquinas.        */

.emblema__disco {
  position: relative;
  grid-area: 1 / 1;
  width: 82%;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  opacity: 0;
  scale: 1.26;
  rotate: -7deg;
  filter: blur(18px) saturate(.45) brightness(1.35);
  animation: logoEnfoca 1250ms cubic-bezier(.16,.86,.22,1) 180ms forwards;
}

/* El tirón de foco, en cuatro tiempos:

     desenfocado, grande, girado y sobreexpuesto   →  como un plano
     que aún no ha entrado en foco;
     a mitad de recorrido ya se reconoce la forma;
     al 82 % pasa ligeramente de largo en la escala —el «rebase» que
     hace una lente al asentar— y vuelve;
     termina nítido, recto y con la saturación un punto por encima.

   El giro de 7° es lo que convierte un zoom en un gesto: sin él la
   entrada se lee como una imagen que crece, no como una insignia que
   se coloca en su sitio. */
@keyframes logoEnfoca {
  0%   { opacity: 0; scale: 1.26; rotate: -7deg;   filter: blur(18px) saturate(.45) brightness(1.35); }
  45%  { opacity: 1; }
  82%  {             scale: .985; rotate: .8deg;   filter: blur(0)    saturate(1.1)  brightness(1.06); }
  100% { opacity: 1; scale: 1;    rotate: 0deg;    filter: blur(0)    saturate(1.05) brightness(1); }
}

.emblema__logo { width: 100%; height: 100%; object-fit: cover; }

/* Destello especular: una banda de luz que cruza el emblema en
   diagonal cuando acaba de enfocar. Es el reflejo sobre metal, y es
   lo que separa «apareció una imagen» de «apareció una insignia». */
.emblema__brillo {
  position: absolute;
  inset: -30%;
  background: linear-gradient(100deg,
    transparent 38%,
    hsl(0 0% 100% / .16) 46%,
    hsl(0 0% 100% / .55) 50%,
    hsl(0 0% 100% / .16) 54%,
    transparent 62%);
  translate: -130% 0;
  /* Dos pasadas: una ancha y rápida al terminar de enfocar, y otra
     más tenue y lenta después. Una sola se lee como un efecto; dos,
     con ritmo distinto, se leen como luz real moviéndose sobre metal. */
  animation: brilloCruza 820ms cubic-bezier(.3,0,.2,1) 1180ms forwards,
             brilloSegundo 1100ms cubic-bezier(.4,0,.3,1) 2300ms forwards;
}

@keyframes brilloCruza   { to { translate: 130% 0; } }
@keyframes brilloSegundo {
  from { translate: -130% 0; opacity: .45; }
  to   { translate: 130% 0;  opacity: .45; }
}

/* Halo que respira detrás del emblema: le da peso y separa el logo
   del fondo sin necesidad de un borde duro. */
.emblema__halo {
  position: absolute;
  inset: -18%;
  border-radius: 50%;
  background: radial-gradient(circle,
    hsl(199 100% 60% / .38) 0%,
    hsl(199 100% 60% / .12) 45%,
    transparent 70%);
  opacity: 0;
  animation: haloEntra 900ms ease-out 700ms forwards,
             haloRespira 3.2s ease-in-out 1600ms infinite alternate;
}

@keyframes haloEntra   { to { opacity: 1; } }
@keyframes haloRespira { from { scale: 1; opacity: 1; } to { scale: 1.08; opacity: .6; } }

/* Barrido de radar: un sector cónico que gira detrás del emblema. Es
   el guiño de «seguimiento de carga» y lo que da vida a la espera. */
.emblema__radar {
  position: absolute;
  inset: -14%;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    hsl(187 100% 60% / .55) 0deg,
    hsl(187 100% 60% / .12) 26deg,
    transparent 62deg,
    transparent 360deg);
  mask-image: radial-gradient(circle, transparent 42%, #000 46%, #000 96%, transparent 100%);
  -webkit-mask-image: radial-gradient(circle, transparent 42%, #000 46%, #000 96%, transparent 100%);
  opacity: 0;
  animation: radarAparece 700ms ease-out 250ms forwards,
             radarGira 2.6s linear 250ms infinite;
}

@keyframes radarAparece { to { opacity: 1; } }
@keyframes radarGira { to { rotate: 360deg; } }

/* Anillo de luz que se traza alrededor del logo. Empieza ANTES que la
   imagen a propósito: lleva el ojo al punto exacto donde va a
   aparecer el emblema, que es lo que hace que la entrada se sienta
   preparada y no casual.

   Se dibuja con `stroke-dashoffset`, la forma más barata de animar un
   trazo: no obliga a recalcular geometría en cada fotograma.
   Se gira −90° para que empiece arriba y no a las tres en punto. */
.emblema__anillo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  rotate: -90deg;
}

.em-borde {
  stroke: url(#degradadoEmblema);
  stroke-linecap: round;
  fill: none;
  stroke-width: 2.5;
  stroke-dasharray: 415;
  stroke-dashoffset: 415;
  animation: trazar 1000ms cubic-bezier(.65,0,.35,1) forwards;
}

@keyframes trazar { to { stroke-dashoffset: 0; } }

/* ============================================================
   ACTO 2 · La ruta
   ============================================================ */

.cargando__ruta {
  width: min(390px, 84vw);
  height: auto;
  overflow: visible;
}

.ruta__base {
  stroke: hsl(0 0% 100% / .14);
  stroke-width: 2;
  stroke-linecap: round;
}

/* Estela: el mismo trazo, más grueso y difuminado, que va justo por
   delante del de color. Da la sensación de que la línea deja rastro. */
.ruta__estela {
  stroke: hsl(187 100% 62% / .35);
  stroke-width: 9;
  stroke-linecap: round;
  filter: blur(6px);
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: trazar 1850ms cubic-bezier(.65,0,.35,1) 1250ms forwards;
}

.ruta__avance {
  stroke: url(#degradadoRuta);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: trazar 1850ms cubic-bezier(.65,0,.35,1) 1250ms forwards;
}

.ruta__carga {
  fill: #fff;
  opacity: 0;
  animation: cargaAparece 200ms ease-out 1250ms forwards,
             cargaViaja 1850ms cubic-bezier(.65,0,.35,1) 1250ms forwards;
}

@keyframes cargaAparece { to { opacity: 1; } }
@keyframes cargaViaja   { to { transform: translateX(300px); } }

/* Cada hito arranca apagado y pequeño; se enciende al llegar la
   línea. Los retardos están calculados sobre la duración del trazo,
   no puestos a ojo: 1250 ms de inicio más un cuarto de 1850 por cada
   estación. */
.ruta__hito {
  opacity: .2;
  transform-origin: center;
  scale: .72;
  animation: hitoEnciende 560ms cubic-bezier(.34,1.56,.64,1) forwards;
}

.ruta__hito:nth-of-type(1) { animation-delay: 1500ms; }
.ruta__hito:nth-of-type(2) { animation-delay: 1950ms; }
.ruta__hito:nth-of-type(3) { animation-delay: 2400ms; }
.ruta__hito:nth-of-type(4) { animation-delay: 2850ms; }

@keyframes hitoEnciende { to { opacity: 1; scale: 1; } }

/* Onda que sale del disco justo cuando se enciende. Hereda el retardo
   de su hito sumándole el tiempo que tarda en aparecer. */
.hito__pulso {
  fill: none;
  stroke: hsl(187 100% 62%);
  stroke-width: 2;
  opacity: 0;
  transform-origin: center;
  animation: pulsoSale 900ms cubic-bezier(.2,.8,.3,1) forwards;
}

.ruta__hito:nth-of-type(1) .hito__pulso { animation-delay: 1620ms; }
.ruta__hito:nth-of-type(2) .hito__pulso { animation-delay: 2070ms; }
.ruta__hito:nth-of-type(3) .hito__pulso { animation-delay: 2520ms; }
.ruta__hito:nth-of-type(4) .hito__pulso { animation-delay: 2970ms; }

@keyframes pulsoSale {
  0%   { opacity: .9; scale: .55; }
  100% { opacity: 0;  scale: 2.1; }
}

.hito__disco {
  fill: var(--noche);
  stroke: hsl(0 0% 100% / .22);
  stroke-width: 1.5;
}

.ruta__hito .hito__icono {
  stroke: var(--cian-noche);
  stroke-width: 1.7;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============================================================
   ACTO 3 · El nombre
   ============================================================ */

.cargando__marca {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  font-family: var(--fuente-titulo);
  font-size: clamp(.78rem, 2.3vw, .95rem);
  font-weight: 500;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .7);
  margin: 0;
}

.cargando__marca span {
  opacity: 0;
  translate: 0 10px;
  animation: letraEntra 460ms cubic-bezier(.4,0,.2,1) forwards;
}

/* Escalonado por letra, calculado en vez de escrito veintiseis veces.
   Cada letra lleva su indice en `--i` desde el HTML.

   Con 26 letras a 26 ms, el barrido dura 650 ms: la ultima empieza a
   3450 ms y termina a 3910, justo antes de que el telon suba a los
   4000. Antes empezaba a 3650 y se cortaba a media entrada. */
.cargando__marca span {
  animation-delay: calc(2800ms + var(--i, 0) * 26ms);
}

@keyframes letraEntra { to { opacity: 1; translate: 0 0; } }

/* Las siglas van en blanco pleno y algo más gruesas: son la marca. */
.cargando__marca .es-marca { color: #fff; font-weight: 700; }

.cargando__rotulo {
  font-size: clamp(.68rem, 2vw, .78rem);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .42);
  opacity: 0;
  animation: letraEntra 520ms ease-out 3430ms forwards;   /* acaba a 3950ms */
}

/* ============================================================
   Barra
   ============================================================ */

.cargando__barra {
  display: block;
  width: min(200px, 54vw);
  height: 2px;
  margin-top: var(--e-2);
  border-radius: 99px;
  background: hsl(0 0% 100% / .12);
  overflow: hidden;
}

.cargando__barra i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: var(--flujo);
  box-shadow: 0 0 12px hsl(187 100% 60% / .8);
  animation: barraLlena 3650ms cubic-bezier(.32,.72,.35,1) 150ms forwards;
}

@keyframes barraLlena { to { width: 100%; } }

/* ============================================================
   Fogonazo de cierre

   Cuando la ruta llega al último modo, un destello blanco brevísimo
   recorre la pantalla. Es el punto final de la secuencia: marca que
   la operación se completó, justo antes de que suba el telón.

   Va en un pseudoelemento del contenedor y con `pointer-events: none`
   para que no intercepte nada.
   ============================================================ */
.cargando::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 60% 50% at 50% 42%,
    hsl(190 100% 88% / .85) 0%,
    hsl(199 100% 70% / .35) 38%,
    transparent 72%);
  opacity: 0;
  animation: fogonazo 780ms cubic-bezier(.2,.7,.3,1) 2900ms forwards;
}

@keyframes fogonazo {
  0%   { opacity: 0;   scale: .92; }
  18%  { opacity: .55; }
  100% { opacity: 0;   scale: 1.06; }
}

/* ============================================================
   Movimiento reducido
   Quien lo tenga activado no ve la cortina: el JavaScript ni siquiera
   la enciende. Esto es la segunda red, por si el ajuste cambia con la
   página ya abierta.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .cargando { display: none !important; }
  .cargando::before, .cargando__malla, .emblema__radar,
  .em-borde, .emblema__disco, .emblema__brillo, .emblema__halo,
  .ruta__avance, .ruta__estela, .ruta__hito, .hito__pulso, .ruta__carga,
  .cargando__marca span, .cargando__rotulo, .cargando__barra i {
    animation: none;
  }
}

/* En pantallas bajas se recorta el aire para que la secuencia entera
   quepa sin desplazamiento. */
@media (max-height: 620px) {
  .cargando__caja { gap: var(--e-3); }
  .emblema { width: clamp(80px, 18vw, 100px); margin-bottom: 0; }
  .cargando__rotulo { display: none; }
}


/* ============================================================
   PÁGINAS INTERIORES

   Todo lo que no es el inicio: servicios, recursos, legales y error.
   Comparten cuatro piezas —cabecera, prosa, lista de datos y
   acordeón— y con eso se arman las catorce.

   La cabecera interior es deliberadamente más baja que la portada del
   inicio: quien llega aquí ya decidió entrar, y una portada a pantalla
   completa en cada página sería un peaje antes del contenido.
   ============================================================ */

/* ---------- Cabecera de página interior ---------- */

.cabezal {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--e-8) + var(--e-4)) var(--e-7);
  background: var(--noche);
  color: var(--sobre-noche);

  /* Redefine sus tokens, como la portada y el pie: es una superficie
     oscura en los dos temas, no una que siga al tema. */
  --tinta:   var(--sobre-noche);
  --tinta-2: var(--sobre-noche-2);
  --tinta-3: var(--sobre-noche-3);
  --linea:   hsl(0 0% 100% / .3);
  --acento:  var(--acento-noche);
}

/* La foto se ve, igual que en la portada del inicio.
 *
 * Iba al 38 % bajo un velo que llegaba al 95 %. Medida la pila
 * completa —color base, foto y velo— sobre un lienzo, la luminancia
 * media de estas cabeceras era de 0,011 a 0,017, mientras que la del
 * inicio es 0,090: entre cinco y ocho veces más oscuras. La fotografía
 * estaba ahí sin verse, y el cliente lo notó.
 *
 * Ahora comparten el tratamiento de `.portada__fondo`. El margen
 * existía: ningún texto de estas cabeceras bajaba de 7,2:1 cuando el
 * mínimo exigido es 4,5:1. */
.cabezal__fondo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .78;
  filter: saturate(1.25) contrast(1.08) brightness(1.06);
}

/* ---------- Cabecera con foto que no es panorámica ----------
 *
 * `cover` recorta lo que sobra para llenar la banda. Con una foto
 * apaisada eso no se nota, pero con una de 800×600 en una banda de
 * 1900 hay que ampliarla 2,4 veces: la imagen pierde nitidez y el
 * recorte se come la parte de arriba y la de abajo. En una foto de
 * personas eso significa caras enormes y cortadas.
 *
 * Aquí la foto se muestra entera (`contain`) y apoyada a la derecha,
 * donde el velo lateral es más fino. Detrás va la misma imagen
 * ampliada y desenfocada, que rellena el resto de la banda: evita las
 * franjas negras, que delatan una foto mal medida, y el desenfoque
 * disimula el aumento porque nadie busca detalle en un fondo borroso.
 *
 * Es la técnica de los reproductores de vídeo cuando el vídeo no
 * llena la pantalla. */
.cabezal--ajustada .cabezal__fondo {
  object-fit: contain;
  object-position: 78% center;
}

.cabezal__telon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .5;
  /* La escala evita que el desenfoque deje un halo claro en los
     bordes al difuminar contra el vacío. */
  transform: scale(1.2);
  filter: blur(32px) saturate(1.4);
}

/* En pantalla estrecha la banda ya es casi tan alta como ancha, así
   que la proporción de la foto encaja y no hace falta el telón. */
@media (max-width: 700px) {
  .cabezal--ajustada .cabezal__fondo { object-fit: cover; object-position: center; }
  .cabezal__telon { display: none; }
}

/* El velo protege abajo y suelta arriba.
 *
 * El título grande y la entradilla viven en la mitad inferior, y son
 * los que fijan el límite: miden entre 3,7:1 y 4,6:1, el mismo margen
 * que el título de la portada del inicio. Por eso el 88 % de abajo no
 * se toca.
 *
 * Arriba solo queda la miga, que ya lleva su propio cristal detrás y
 * no depende de la foto. Ahí el velo baja al 10 % y la fotografía se
 * ve casi limpia, que es lo que se pedía. */
.cabezal::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top,
      hsl(224 70% 8% / .88) 0%,
      hsl(224 66% 10% / .60) 45%,
      hsl(224 60% 14% / .30) 78%,
      hsl(224 60% 14% / .12) 100%),
    linear-gradient(to right,
      hsl(224 70% 8% / .55) 0%,
      transparent 64%);
}

/* Aurora: manchas de color en `screen`, que aclara en vez de
   oscurecer. Sube del 50 % al 78 % para acompañar a la foto. */
.cabezal::before {
  content: '';
  position: absolute;
  inset: -30%;
  background: var(--aurora);
  opacity: .78;
  filter: blur(60px);
  mix-blend-mode: screen;
}

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

.cabezal__titulo {
  font-size: var(--t-3xl);
  line-height: 1.02;
  letter-spacing: -.035em;
  text-transform: uppercase;
  margin-block: var(--e-3);
}

.cabezal__entrada {
  font-size: var(--t-lg);
  color: hsl(0 0% 100% / .8);
  max-width: 58ch;
}

/* ---------- Miga de navegación ---------- */

/* La miga vive en lo más alto de la banda, que es justo donde el velo
   es más ligero. Al aclarar la fotografía, en las páginas cuya imagen
   tiene cielo despejado ahí arriba —ferrocarril, embalaje— el tramo
   actual caía a 2,9:1.

   Se resuelve con un cristal propio detrás, no oscureciendo otra vez
   la foto: así el texto deja de depender de qué haya en la imagen, y
   la fotografía se sigue viendo. Es la misma pieza de vidrio que usa
   el antetítulo de la portada del inicio. */
.miga {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--radio-lg);
  background: hsl(224 72% 7% / .62);
  backdrop-filter: blur(8px);
  border: var(--borde) solid hsl(0 0% 100% / .14);
  font-size: var(--t-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .62);
}

.miga a { color: hsl(0 0% 100% / .78); transition: color var(--transicion); }
.miga a:hover { color: #fff; }
.miga [aria-current] { color: var(--acento-noche); }

/* ---------- Prosa ----------
   Para bloques de texto largo. Limita el ancho y da ritmo vertical:
   sin esto, un párrafo de sesenta palabras cruzaba la pantalla entera
   y el ojo perdía el renglón al saltar de línea. */

.prosa { max-width: var(--ancho-texto); }
.prosa > * + * { margin-top: var(--e-3); }
.prosa > * + h2, .prosa > * + h3 { margin-top: var(--e-6); }

.prosa h2 { font-size: var(--t-xl); }
.prosa h3 { font-size: var(--t-lg); }
.prosa p, .prosa li { color: var(--tinta-2); }
.prosa strong { color: var(--tinta); font-weight: 600; }

/* Los enlaces de dentro de un párrafo van subrayados; los botones no.
   Sin la exclusión, un `.btn` colocado dentro de `.prosa` salía azul y
   subrayado sobre su propio fondo: `.prosa a` tiene más especificidad
   que `.btn--brasa`. */
.prosa a:not(.btn) {
  color: var(--acento);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.prosa ul { display: grid; gap: var(--e-2); }

.prosa ul li {
  position: relative;
  padding-left: var(--e-4);
}

.prosa ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .68em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--acento);
}

/* ---------- Lista de datos en dos columnas ----------
   Para ventajas, restricciones, servicios incluidos. Un patrón que
   repiten casi todas las interiores. */

.datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--e-3);
}

.dato {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: start;
  padding: var(--e-4);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  background: var(--papel);
  transition: border-color var(--transicion);
}

.dato:hover { border-color: var(--acento); }

/* Tarjeta sin icono.
 *
 * `.dato` reparte su contenido en dos columnas —marca e información—
 * contando con que la primera la ocupa el icono. Donde no hay icono,
 * el título caía en esa primera columna y el texto en la segunda: el
 * título quedaba en una tira estrecha a la izquierda y el texto en
 * otra a la derecha, partido en renglones de tres palabras. Es lo que
 * desordenaba la clasificación por tonelaje. */
.dato--llano { grid-template-columns: minmax(0, 1fr); }

/* Dos por fila, en vez de las que quepan.
 *
 * Con cuatro elementos, el reparto automático deja tres arriba y uno
 * solo abajo, y esa fila coja se lee como un descuido. Dos y dos
 * forman un cuadro. */
.datos--pares { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Una por fila, para listas cortas dentro de una columna estrecha. */
.datos--columna { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 620px) {
  .datos--pares { grid-template-columns: minmax(0, 1fr); }
}

.dato__marca {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radio);
  background: var(--acento-tenue);
  color: var(--acento);
}

.dato__marca svg { width: 19px; height: 19px; }
/* `display: block` porque en varias tarjetas estas dos piezas son
   `<span>` dentro de otro `<span>`, y como elementos en línea el texto
   seguía al título en el mismo renglón: se leía «Embalaje y seguridad
   Guacales de madera…» como una sola frase. Donde ya son `<h3>` y
   `<p>` no cambia nada, porque esos son bloques de por sí. */
.dato__titulo {
  display: block;
  font-size: var(--t-base);
  font-weight: 600;
  margin-bottom: var(--e-1);
}

.dato__texto {
  display: block;
  font-size: var(--t-sm);
  color: var(--tinta-2);
}

/* ---------- Comparativa a tres columnas ----------
   Ventajas / desventajas / cuándo conviene. Publicar las tres juntas
   es lo que convierte una página de servicio en una herramienta de
   decisión en vez de en un folleto. */

.balanza {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--e-4);
  align-items: stretch;
}

.columna {
  display: flex;
  flex-direction: column;
  padding: var(--e-5);
  border-radius: var(--radio-lg);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-top: 3px solid var(--acento);
}

.columna--pro    { border-top-color: var(--bien); }
.columna--contra { border-top-color: var(--alerta); }
.columna--cuando { border-top-color: var(--acento); }

.columna__cabecera {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-4);
  font-family: var(--fuente-titulo);
  font-size: var(--t-lg);
}

.columna--pro    .columna__cabecera svg { color: var(--bien); }
.columna--contra .columna__cabecera svg { color: var(--alerta); }
.columna--cuando .columna__cabecera svg { color: var(--acento); }
.columna__cabecera svg { width: 22px; height: 22px; flex-shrink: 0; }

.columna ul { display: grid; gap: var(--e-3); }

.columna li {
  position: relative;
  padding-left: var(--e-4);
  font-size: var(--t-sm);
  color: var(--tinta-2);
}

.columna li strong { color: var(--tinta); font-weight: 600; }

/* El signo se dibuja desde el CSS: escrito en el HTML, un lector de
   pantalla leería «más» o «menos» delante de cada frase. */
.columna li::before {
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 700;
  line-height: 1.6;
}

.columna--pro    li::before { content: '+'; color: var(--bien); }
.columna--contra li::before { content: '−'; color: var(--alerta); }
.columna--cuando li::before { content: '›'; color: var(--acento); }

/* ---------- Tabla ----------
   Se desplaza dentro de su caja; la página nunca. Una tabla de cinco
   columnas no cabe en 375 px por mucho que se encoja la letra. */

.tabla-caja {
  overflow-x: auto;
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  background: var(--papel);
  -webkit-overflow-scrolling: touch;
}

.tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
  min-width: 620px;
}

.tabla thead th {
  position: sticky;
  top: 0;
  background: var(--papel-2);
  color: var(--tinta);
  text-align: left;
  font-weight: 600;
  padding: var(--e-3) var(--e-4);
  white-space: nowrap;
  border-bottom: 2px solid var(--linea);
}

.tabla tbody th, .tabla tbody td {
  padding: var(--e-3) var(--e-4);
  border-bottom: var(--borde) solid var(--linea-suave);
  color: var(--tinta-2);
  vertical-align: top;
}

.tabla tbody th {
  text-align: left;
  font-weight: 700;
  color: var(--acento);
  white-space: nowrap;
}

.tabla tbody tr:last-child th, .tabla tbody tr:last-child td { border-bottom: 0; }
.tabla tbody tr:hover th, .tabla tbody tr:hover td { background: var(--papel-2); }

.tabla__nota { display: block; font-size: var(--t-xs); color: var(--tinta-3); }

/* ---------- Acordeón ----------
   `<details>` nativo: funciona sin JavaScript, es accesible por
   teclado de serie y el navegador ya gestiona el estado. */

.acordeon { display: grid; gap: var(--e-2); }

.pliegue {
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  background: var(--papel);
  overflow: hidden;
  transition: border-color var(--transicion);
}

.pliegue[open] { border-color: var(--acento); }

.pliegue summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
  padding: var(--e-4);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  min-height: 56px;
}

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

.pliegue summary::after {
  content: '';
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-right: 2px solid var(--acento);
  border-bottom: 2px solid var(--acento);
  rotate: 45deg;
  transition: rotate var(--transicion);
}

.pliegue[open] summary::after { rotate: -135deg; }

.pliegue__cuerpo {
  padding: 0 var(--e-4) var(--e-4);
  font-size: var(--t-sm);
  color: var(--tinta-2);
}

@media (prefers-reduced-motion: reduce) {
  .pliegue summary::after { transition: none; }
}

/* ---------- Aviso destacado ---------- */

.aviso {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  padding: var(--e-4);
  border-radius: var(--radio-lg);
  border: var(--borde) solid var(--linea);
  border-left: 4px solid var(--acento);
  background: var(--papel-2);
}

.aviso--alerta { border-left-color: var(--alerta); }
.aviso--bien   { border-left-color: var(--bien); }

.aviso__icono { width: 24px; height: 24px; color: var(--acento); }
.aviso--alerta .aviso__icono { color: var(--alerta); }
.aviso--bien   .aviso__icono { color: var(--bien); }

.aviso__titulo { font-weight: 600; margin-bottom: var(--e-1); }
.aviso p { font-size: var(--t-sm); color: var(--tinta-2); }

@media (max-width: 560px) {
  .aviso { grid-template-columns: 1fr; }
}

/* ---------- Lista de pasos ----------
   Se usa sobre fondo oscuro en el inicio y sobre claro en las
   interiores. La variante `--claro` es la de fondo claro; sin ella,
   los pasos heredaban el tratamiento oscuro y quedaban invisibles. */

.pasos-lista {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--e-3);
  counter-reset: paso;
}

.paso {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: start;
  padding: var(--e-4);
  border-radius: var(--radio-lg);
  background: hsl(0 0% 100% / .05);
  border: var(--borde) solid hsl(0 0% 100% / .1);
}

.paso--claro {
  background: var(--papel);
  border-color: var(--linea);
}

.paso__num {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  flex-shrink: 0;
  font-family: var(--fuente-titulo);
  font-size: var(--t-base);
  font-weight: 600;
  /* Color fijo, no del tema: el disco lleva el degradado de marca y su
     texto tiene que ser oscuro siempre, o en tema oscuro se aclararía
     y quedaría ilegible sobre el cian. */
  color: hsl(224 70% 10%);
  background: var(--flujo);
}

/* ---------- Vídeo ----------
   Siempre con `poster` y `preload="none"`: el archivo pesa megabytes
   y nadie debe descargarlo por el hecho de abrir la página. Se carga
   cuando el visitante pulsa, no antes.

   El `aspect-ratio` reserva el hueco desde el primer pintado, así la
   página no da un salto cuando el vídeo termina de medirse. */
.video {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radio-lg);
  background: var(--noche);
  border: var(--borde) solid var(--linea);
  display: block;
  /* El texto de reserva —el que ve quien no puede reproducir el
     vídeo— hereda el color del tema, y sobre el fondo oscuro del
     reproductor quedaba en 1,06:1: invisible justo para quien más lo
     necesita. Se fija claro, que el fondo es oscuro en ambos temas. */
  color: var(--sobre-noche);
  text-align: center;
  padding: var(--e-4);
}

/* ---------- Botón de reproducción ----------
   El vídeo trae los controles del navegador, pero su botón de play es
   una pieza de doce píxeles en la esquina: sobre una imagen de portada
   no se lee como «esto se puede reproducir». Encima va un disco grande
   y centrado, como el de Instagram o TikTok.

   Se muestra SOLO cuando el guion lo enciende (`.video-caja--listo`).
   Sin JavaScript no aparece, y quedan los controles nativos, que sí
   funcionan solos. Un botón que no hace nada es peor que ninguno. */

.video-caja { position: relative; display: grid; }

.video__play {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  place-items: center;
  width: clamp(56px, 13%, 84px);
  aspect-ratio: 1;
  border: 0;
  border-radius: 50%;
  background: var(--flujo-macizo);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 8px 30px hsl(224 80% 12% / .5);
  transition: transform var(--transicion), box-shadow var(--transicion);
}

.video-caja--listo .video__play { display: grid; }

.video__play:hover {
  transform: scale(1.08);
  box-shadow: 0 12px 38px hsl(224 80% 12% / .62);
}

/* El triángulo se desplaza un pelo a la derecha: centrado por su caja
   parece descentrado, porque su masa está a la izquierda. */
.video__play svg {
  width: 42%;
  height: 42%;
  margin-left: 8%;
}

/* Halo que late, para que el disco se note sin animar el vídeo. */
.video__play::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid hsl(0 0% 100% / .55);
  animation: latido 2.4s ease-out infinite;
}

@keyframes latido {
  0%   { transform: scale(1);    opacity: .7; }
  70%  { transform: scale(1.25); opacity: 0; }
  100% { transform: scale(1.25); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .video__play::after { animation: none; opacity: .5; }
  .video__play:hover  { transform: none; }
}

/* ---------- Lema de cierre de sección ---------- */
.resena-lema {
  margin-top: var(--e-6);
  text-align: center;
  font-family: var(--fuente-titulo);
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  font-style: italic;
  color: var(--acento);
}

/* ---------- Bloque partido ----------
   Fotografía a sangre por un lado y texto por el otro, sin márgenes
   que los separen. Se usa cuando la imagen tiene que mandar: un
   servicio que se entiende mirando, no leyendo.

   La imagen NO va dentro de la caja centrada del sitio a propósito:
   llegar hasta el borde de la pantalla es lo que le da presencia. El
   texto sí respeta el ancho de lectura. */

.bloque-partido {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  background: var(--papel-2);
}

.bloque-partido__medio {
  margin: 0;
  position: relative;
  min-height: 420px;
}

.bloque-partido__medio img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bloque-partido__texto {
  display: grid;
  align-content: center;
  padding: var(--seccion-y) var(--margen);
}

/* El texto se limita en ancho y se pega al lado de la imagen, para que
   no quede una tira de letra cruzando media pantalla. */
.bloque-partido__texto > * { max-width: 52ch; }

@media (max-width: 900px) {
  .bloque-partido { grid-template-columns: 1fr; }
  .bloque-partido__medio { min-height: 300px; }
  .bloque-partido__texto { padding-block: var(--e-6); }
}

/* ---------- Nota al pie de sección ----------
   Para la letra pequeña que matiza un dato: de dónde sale la cifra, qué
   varía según el caso. Se distingue del cuerpo sin gritar. */

.nota {
  max-width: 68ch;
  padding-left: var(--e-3);
  border-left: 2px solid var(--linea);
  font-size: var(--t-sm);
  line-height: 1.6;
  /* --tinta-3 daba 4,24:1 sobre el fondo de las secciones alternas.
     Un tono menos claro cumple en las dos y sigue leyendose como
     secundario frente al cuerpo. */
  color: var(--tinta-2);
}

.nota strong { color: var(--tinta); font-weight: 600; }

/* ---------- Índice de anclas ----------
   Para páginas largas de consulta. Deja ver de un vistazo qué hay
   dentro sin obligar a recorrerla entera. */

.indice {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
}

.indice a {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  border-radius: 100px;
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  color: var(--tinta-2);
  font-size: var(--t-sm);
  transition: border-color var(--transicion), color var(--transicion);
}

.indice a:hover { border-color: var(--acento); color: var(--tinta); }
.indice a svg { width: 18px; height: 18px; color: var(--acento); }

/* Al saltar desde el índice, el título no debe quedar bajo la cabecera
   fija. `scroll-margin-top` reserva ese hueco. */
[id] { scroll-margin-top: calc(72px + var(--e-4)); }

/* ---------- Lista larga de términos ----------
   Treinta y cinco entradas cortas. En una columna serían un muro; en
   columnas se leen de un vistazo. */

.lista-larga {
  columns: 3 240px;
  column-gap: var(--e-5);
  list-style: none;
  padding: 0;
  margin: 0;
}

.lista-larga li {
  break-inside: avoid;        /* que ninguna se parta entre columnas */
  position: relative;
  padding: var(--e-2) 0 var(--e-2) var(--e-4);
  font-size: var(--t-sm);
  line-height: 1.4;
  color: var(--tinta-2);
  border-bottom: var(--borde) solid var(--linea-suave);
}

.lista-larga li::before {
  content: '×';
  position: absolute;
  left: var(--e-1);
  top: var(--e-2);
  font-weight: 700;
  color: var(--alerta);
}

/* Lista compacta a dos columnas, dentro de tarjeta o aviso */
.lista-doble {
  columns: 2 180px;
  column-gap: var(--e-4);
  list-style: none;
  padding: 0;
  margin: var(--e-2) 0 0;
}

.lista-doble li {
  break-inside: avoid;
  position: relative;
  padding: var(--e-1) 0 var(--e-1) var(--e-3);
  font-size: var(--t-sm);
  color: var(--tinta-2);
}

.lista-doble li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .85em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--acento);
}

/* ---------- Glosario ---------- */

.glosario { display: grid; margin: 0; }

.glosario__item {
  display: grid;
  grid-template-columns: minmax(150px, 210px) 1fr;
  gap: var(--e-4);
  padding: var(--e-3) 0;
  border-bottom: var(--borde) solid var(--linea-suave);
}

.glosario__item:last-child { border-bottom: 0; }

.glosario dt {
  font-family: var(--fuente-titulo);
  font-size: var(--t-base);
  color: var(--acento);
  line-height: 1.3;
}

.glosario dd {
  /* Sin tope, la definicion se estiraba a 900 px: unos 110 caracteres
     por linea, donde el ojo pierde el renglon al volver a la izquierda. */
  max-width: 68ch;
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--tinta-2);
}

.glosario dd strong { color: var(--tinta); font-weight: 600; }

/* En estrecho el término va encima: a dos columnas la definición
   quedaría en una tira de cuatro palabras por línea. */
@media (max-width: 640px) {
  .glosario__item { grid-template-columns: 1fr; gap: var(--e-1); }
}

/* ---------- Clase numerada ----------
   Para las nueve clases IATA. Compacta a propósito: son etiquetas de
   referencia, no tarjetas de venta. */

.clases {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: var(--e-3);
}

.clase {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: start;
  padding: var(--e-3) var(--e-4);
  border: var(--borde) solid var(--linea);
  border-left: 3px solid var(--alerta);
  border-radius: var(--radio-lg);
  background: var(--papel);
}

.clase__num {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radio);
  font-family: var(--fuente-titulo);
  font-size: var(--t-base);
  color: var(--alerta);
  background: hsl(0 72% 45% / .1);
}

.clase__titulo { font-size: var(--t-sm); font-weight: 600; margin-bottom: 2px; }
.clase__texto { font-size: var(--t-xs); color: var(--tinta-3); line-height: 1.45; }

/* ---------- Página de error ---------- */

.error {
  display: grid;
  place-items: center;
  min-height: 70vh;
  text-align: center;
  padding-block: var(--e-8);
}

.error__codigo {
  font-family: var(--fuente-titulo);
  font-size: clamp(5rem, 22vw, 12rem);
  font-weight: 700;
  line-height: .9;
  letter-spacing: -.06em;
  background: var(--flujo-texto);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .error__codigo { background: none; color: var(--acento); -webkit-text-fill-color: currentColor; }
}


/* ============================================================
   COTIZADOR

   Va en su propio archivo porque es la pieza más grande del sitio y
   la única con formulario. Mezclarla con los componentes generales
   haría 02-componentes.css inmanejable.

   Consume las variables de 01-cimientos como todo lo demás: no
   inventa ni un color ni una medida.
   ============================================================ */

.cotizador {
  display: grid;
  gap: var(--e-4);
  padding: var(--e-5);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-top: 3px solid transparent;
  border-image: var(--flujo) 1;
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-2);
}

/* `border-image` anula el redondeo en todos los navegadores, así que
   sobre fondo oscuro la línea de marca se dibuja aparte y las esquinas
   se conservan. */
.seccion--tinta .cotizador,
.seccion--aurora .cotizador {
  background: var(--noche-2);
  border-color: var(--linea-noche);
  --tinta:   var(--sobre-noche);
  --tinta-2: var(--sobre-noche-2);
  --tinta-3: var(--sobre-noche-3);
  /* Más claro que el `--linea` general del tema oscuro: aquí hay
     casillas y un botón de contorno sobre un panel muy oscuro, y a
     30 % de luminosidad el borde daba 1,73:1 contra el fondo. Un
     control cuyo contorno no se ve deja de leerse como control. */
  --linea:   hsl(213 30% 52%);
  --papel:   var(--noche);
  --papel-2: var(--noche-2);
  --acento:  var(--acento-noche);

  /* El asterisco de campo obligatorio, en su variante clara. Este
     panel es oscuro en LOS DOS temas, asi que el rojo oscuro que vale
     sobre papel aqui se hunde: medido daba 2,12:1. */
  --alerta-texto: hsl(4 90% 76%);
}

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

.cotizador__cabecera {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: start;
}

.cotizador__marca {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radio);
  background: var(--acento-tenue);
  color: var(--acento);
}

.cotizador__marca svg { width: 20px; height: 20px; }

.cotizador__titulo {
  font-family: var(--fuente-titulo);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.2;
}

.cotizador__pie {
  margin-top: var(--e-1);
  font-size: var(--t-sm);
  color: var(--tinta-2);
  max-width: 60ch;
}

/* ---------- Campos ----------
   Dos por fila en escritorio, uno en móvil. El ancho mínimo de 220 px
   es el punto por debajo del cual «Ciudad y país de salida» deja de
   caber en el marcador de posición. */

.cotizador__campos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--e-3);
}

.campo { display: grid; gap: 6px; grid-column: 1 / -1; }
.campo--medio { grid-column: auto; }

.campo label {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-2);
}

.campo__obligatorio { color: var(--alerta-texto); }

.campo input,
.campo select,
.campo textarea {
  width: 100%;
  /* 44 px de alto: por debajo, en un móvil se falla el campo y se
     acaba tocando el de al lado. */
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  font: inherit;
  font-size: var(--t-sm);
  color: var(--tinta);
  background: var(--papel-2);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio);
  transition: border-color var(--transicion), background var(--transicion);
}

.campo textarea { resize: vertical; min-height: 66px; }

.campo input::placeholder,
.campo textarea::placeholder { color: var(--tinta-3); }

.campo input:focus,
.campo select:focus,
.campo textarea:focus {
  outline: 2px solid var(--acento-vivo);
  outline-offset: 1px;
  border-color: var(--acento);
}

/* El campo que falta se marca en rojo Y con el aviso de arriba: el
   color por sí solo no le dice nada a quien no lo distingue. */
.campo input[aria-invalid="true"],
.campo textarea[aria-invalid="true"] {
  border-color: var(--alerta);
  background: var(--alerta-tenue, var(--papel-2));
}

/* ---------- Calculadora ---------- */

.cotizador__calc {
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio);
  background: var(--papel-2);
}

.cotizador__calc > summary {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  cursor: pointer;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--tinta);
  list-style: none;
}

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

/* Triángulo propio: el del navegador cambia de forma en cada uno. */
.cotizador__calc > summary::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 6px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: rotate var(--transicion);
}

.cotizador__calc[open] > summary::before { rotate: 90deg; }

.cotizador__opcional {
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  /* --tinta-3 da 4,24:1 sobre el panel claro del cotizador, por debajo
     del 4,5:1 que pide un texto de este tamaño. Un tono menos claro
     cumple y sigue leyéndose como secundario. */
  color: var(--tinta-2);
}

.calc {
  display: grid;
  gap: var(--e-3);
  padding: 0 var(--e-3) var(--e-3);
}

.calc__unidad {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-3);
  border: 0;
  padding: 0;
  margin: 0;
}

.calc__unidad legend {
  float: left;
  width: 100%;
  margin-bottom: var(--e-2);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-2);
}

.calc__unidad label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-size: var(--t-sm);
  color: var(--tinta-2);
  cursor: pointer;
}

.calc__unidad input { width: 16px; height: 16px; accent-color: hsl(var(--acento-h) 100% 42%); }

.calc__tabla { display: grid; gap: 6px; }

.calc__encabezado,
.calc__fila {
  display: grid;
  grid-template-columns: 46px repeat(4, 1fr) 82px 44px;
  gap: 6px;
  align-items: center;
}

.calc__encabezado {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-2);
}

.calc__fila input {
  width: 100%;
  min-height: 44px;
  padding: var(--e-1) var(--e-2);
  font: inherit;
  font-size: var(--t-sm);
  text-align: center;
  color: var(--tinta);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio);
}

.calc__fila input:focus { outline: 2px solid var(--acento-vivo); outline-offset: 1px; }

/* En escritorio la etiqueta de cada casilla se oculta a la vista: la
   cabecera de la tabla ya dice qué es cada columna, y enseñar las dos
   cosas era repetir «Largo, Ancho, Alto, Cant.» dos veces seguidas.
   Sigue ahí para quien usa lector de pantalla. */
.calc__etq {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.calc__num {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--tinta-2);
  text-align: center;
}

.calc__sub {
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  color: var(--tinta-2);
  text-align: right;
}

.calc__quitar {
  display: grid;
  place-items: center;
  /* 44 px y no 38: por debajo se falla el botón con el dedo y se
     acaba tocando la casilla de al lado, que borra un bulto sin
     querer. */
  width: 44px;
  height: 44px;
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio);
  background: none;
  color: var(--tinta-3);
  cursor: pointer;
  transition: color var(--transicion), border-color var(--transicion);
}

.calc__quitar:hover:not(:disabled) { color: var(--alerta); border-color: var(--alerta); }
.calc__quitar:disabled { opacity: .3; cursor: not-allowed; }
.calc__quitar svg { width: 15px; height: 15px; }

.calc__anadir { justify-self: start; min-height: 44px; padding: var(--e-2) var(--e-4); }

.calc__total {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-5);
  padding: var(--e-3);
  border-radius: var(--radio);
  background: var(--noche);
  color: var(--sobre-noche);
}

.calc__total > div { display: flex; align-items: baseline; gap: 6px; }

.calc__cifra {
  font-family: var(--fuente-titulo);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--cian-noche);
}

.calc__unidad-txt { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--sobre-noche-2); }

/* En estrecho la tabla de seis columnas no cabe: cada bulto pasa a ser
   una ficha con sus campos etiquetados. Encogerla habría dejado casillas
   de 30 px, imposibles de rellenar con el dedo. */
@media (max-width: 720px) {
  .calc__encabezado { display: none; }

  .calc__fila {
    grid-template-columns: repeat(2, 1fr) 44px;
    gap: var(--e-2);
    padding: var(--e-3);
    border: var(--borde) solid var(--linea);
    border-radius: var(--radio);
    background: var(--papel);
  }

  .calc__num { grid-column: 1 / -1; text-align: left; }
  .calc__sub { grid-column: 1 / 3; text-align: left; }
  .calc__quitar { grid-row: -2; }

  /* Sin cabecera de tabla, la etiqueta vuelve a la vista: nadie
     sabría si esa casilla es el largo o el alto. */
  .calc__fila label { display: grid; gap: 4px; }

  .calc__etq {
    position: static;
    width: auto; height: auto;
    margin: 0;
    clip-path: none;
    font-size: var(--t-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--tinta-2);
  }
}

/* ---------- Aviso de validación ---------- */

.cotizador__aviso {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  padding: var(--e-3);
  border-radius: var(--radio);
  border-left: 3px solid var(--alerta);
  background: var(--papel-2);
  font-size: var(--t-sm);
  color: var(--tinta);
}

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

.cotizador__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-3) var(--e-4);
}

.cotizador__enviar { flex-shrink: 0; }

.cotizador__legal {
  font-size: var(--t-xs);
  color: var(--tinta-3);
  max-width: 44ch;
}

.cotizador__legal a { color: var(--acento); text-decoration: underline; text-underline-offset: 2px; }

/* ============================================================
   VARIANTE COMPACTA

   En Inicio y en las cuatro páginas de modo, el formulario entero
   metido en cinco de doce columnas quedaba estrecho, altísimo y
   pesaba más que el mensaje que lo acompañaba.

   Aquí manda otra idea: se ve la fila que de verdad decide una
   cotización —de dónde, a dónde y qué— y el resto espera plegado.
   Quien solo pasaba no encuentra un muro de campos; quien quiere
   cotizar tiene tres casillas y un botón delante.

   Es el patrón de los buscadores de vuelos, y funciona por lo mismo:
   pedir poco de entrada y ampliar solo si hace falta.
   ============================================================ */

/* La cabecera sobra: el titular de la sección ya dice de qué va, y
   repetirlo dentro del recuadro es decirlo dos veces seguidas. */
.cotizador--barra .cotizador__cabecera { display: none; }

/* Los tres campos en una fila. El mínimo de 190 px es el ancho por
   debajo del cual «Ciudad y país de salida» deja de caber; más
   estrecho, prefiere apilarse. */
.cotizador--barra .cotizador__esencial {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--e-3);
}

/* `.campo` ocupa la fila entera por omisión, que es lo correcto en el
   formulario largo. Aquí hay que devolverle la colocación automática o
   los tres campos se apilan uno bajo otro, cada uno a todo lo ancho,
   que es justo lo que se venía a evitar. */
.cotizador--barra .cotizador__esencial .campo { grid-column: auto; }

/* El botón NO va dentro de esa fila.
 *
 * Lo intenté con `display: contents` sobre las acciones para subirlo a
 * la rejilla de los campos, y lo que hizo fue promoverlo a la rejilla
 * del FORMULARIO —que es otra— e inventarse cuatro columnas: los
 * campos quedaron de 92 px apilados y el botón suelto a media altura.
 *
 * Una fila propia es más simple, no depende de que dos rejillas
 * distintas cuadren, y deja la acción claramente separada de lo que
 * hay que rellenar. */
.cotizador--barra .cotizador__acciones {
  display: flex;
  flex-wrap: wrap-reverse;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
}

.cotizador--barra .cotizador__legal { max-width: 52ch; }

/* ---------- El pliegue de «más detalles» ---------- */

.cotizador__mas {
  border-top: var(--borde) solid var(--linea);
  padding-top: var(--e-3);
}

.cotizador__mas > summary {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  min-height: 44px;
  cursor: pointer;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--acento);
  list-style: none;
}

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

.cotizador__mas > summary::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 6px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: rotate var(--transicion);
}

.cotizador__mas[open] > summary::before { rotate: 90deg; }

.cotizador__mas > *:not(summary) { margin-top: var(--e-3); }

/* En la variante completa —Contacto y Embalaje— el pliegue no tiene
   sentido: allí el formulario ES la sección, y esconder la mitad
   obligaría a un clic para nada. Se queda abierto y sin resorte. */
.cotizador--completo .cotizador__mas { border-top: 0; padding-top: 0; }
.cotizador--completo .cotizador__mas > summary { display: none; }

/* ---------- Centrado ----------
   Para cuando el formulario va solo en su sección, sin columna de
   texto al lado que lo equilibre. */
.cotizador-centro {
  max-width: 860px;
  margin-inline: auto;
}


/* ============================================================
   CARRUSEL DE DESTINOS

   Cuatro tarjetas por vista que avanzan de una en una: entra una por
   la derecha y sale la del extremo izquierdo.

   Sustituye a la marquesina continua anterior. Aquella nunca paraba y
   no dejaba leer un destino concreto; esta se detiene lo suficiente
   para que el ojo lo registre, y se para del todo al pasar el cursor.
   ============================================================ */

.carrusel { position: relative; }

.carrusel__marco { overflow: hidden; }

/* Sin separación entre tarjetas: es una tira continua de imágenes, no
   una fila de fichas. El límite entre una y otra lo marca una línea
   fina, no un hueco. */
.carrusel__pista {
  display: flex;
  gap: 0;
  /* Sin esto, al reordenar las tarjetas el navegador reparte el
     espacio sobrante y el paso deja de medir lo mismo cada vez. */
  will-change: transform;
}

/* Cuántas caben a la vez. Se declara como variable porque el guion
   necesita el mismo número para calcular el paso, y tenerlo en un solo
   sitio evita que CSS y JavaScript discrepen. */
.carrusel { --por-vista: 4; }

@media (max-width: 1080px) { .carrusel { --por-vista: 3; } }
@media (max-width: 780px)  { .carrusel { --por-vista: 2; } }
@media (max-width: 520px)  { .carrusel { --por-vista: 1; } }

.destino-tarjeta {
  position: relative;
  flex: 0 0 calc(100% / var(--por-vista));
  display: block;
  overflow: hidden;
  background: var(--noche);
  /* La línea que separa una tarjeta de la siguiente. Va por dentro
     (`inset`) para no sumar ancho: con `border` cada tarjeta mediría un
     píxel más y el paso del carrusel dejaría de cuadrar. */
  box-shadow: inset -1px 0 0 hsl(0 0% 100% / .22);
}

/* 4:3. Ni panorámica ni cuadrada: con cuatro a la vista en 1920 px
   cada tarjeta mide 480 de ancho, y a 4:3 la banda queda en 360 de
   alto. Es la proporción en la que ni se ven estiradas a lo ancho ni
   se comen media pantalla de alto. */
.destino-tarjeta img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: scale var(--transicion);
}

.destino-tarjeta:hover img { scale: 1.04; }

/* Velo solo en la franja de abajo, que es donde va el texto. Arriba la
   fotografía queda limpia. */
.destino-tarjeta::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    hsl(224 72% 5% / .92) 0%,
    hsl(224 72% 5% / .62) 22%,
    hsl(224 72% 5% / .12) 45%,
    transparent 62%);
  pointer-events: none;
}

.destino-tarjeta__nombre,
.destino-tarjeta__bandera { position: absolute; z-index: 1; }

/* Abajo a la izquierda. */
.destino-tarjeta__nombre {
  left: var(--e-4);
  bottom: var(--e-4);
  right: 68px;
  font-family: var(--fuente-titulo);
  font-size: var(--t-lg);
  font-weight: 700;
  line-height: 1.15;
  color: #fff;
  text-shadow: 0 1px 3px hsl(224 72% 5% / .7);
}

/* Abajo a la derecha, en 3:2 exacto —36 × 24— que es la proporción del
   lienzo con que están dibujadas. A 22 × 15 quedaban aplastadas un 2 %,
   que en una bandera de franjas se nota. */
.destino-tarjeta__bandera {
  right: var(--e-4);
  bottom: var(--e-4);
  width: 36px;
  height: 24px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px hsl(0 0% 100% / .55), 0 2px 6px hsl(224 72% 5% / .5);
}

@media (prefers-reduced-motion: reduce) {
  .destino-tarjeta img { transition: none; }
  .destino-tarjeta:hover img { scale: 1; }
}

/* ---------- Mandos ----------
   Van sobre la propia tira, pegados a los bordes, no en una barra
   debajo. Una fila de botones colgando bajo el carrusel es el patrón
   de hace quince años: ocupa alto, separa el control de lo que
   controla y obliga a mirar a otro sitio para moverlo.

   Aquí el mando está donde la mano ya lo busca: en el borde por el que
   entra o sale la imagen. */

.carrusel__boton {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: var(--borde) solid hsl(0 0% 100% / .32);
  border-radius: 50%;
  /* Cristal: deja ver la fotografía por debajo en vez de taparla con
     un disco opaco, y el desenfoque garantiza que la flecha se lea sea
     cual sea la parte de la imagen que le toque detrás. */
  /* El cristal a .42 dejaba la flecha en 2,82:1 sobre la foto más
     clara de las diez —la fachada blanca de Santo Domingo—, por debajo
     del 3:1 que necesita un icono para identificarse. A .60 pasa sin
     dejar de verse la imagen por detrás. */
  background: hsl(224 72% 8% / .60);
  backdrop-filter: blur(10px);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transicion), background var(--transicion),
              border-color var(--transicion);
}

.carrusel__boton svg { width: 22px; height: 22px; }

[data-carrusel-atras]    { left: var(--e-4); }
[data-carrusel-adelante] { right: var(--e-4); }

/* Aparecen al acercarse y al llegar con el tabulador. Mientras nadie
   los busca, la tira se ve limpia. */
.carrusel:hover .carrusel__boton,
.carrusel:focus-within .carrusel__boton { opacity: 1; }

.carrusel__boton:hover {
  background: hsl(224 72% 8% / .82);
  border-color: hsl(0 0% 100% / .6);
}

/* En pantalla táctil no hay cursor que acercar, así que se quedan
   siempre a la vista: si no, no habría forma de pasar de tarjeta. */
@media (hover: none) {
  .carrusel__boton { opacity: 1; }
}

/* Sin JavaScript no hay a quién obedecer: los botones se esconden y
   la tira queda como una lista que se desplaza con el dedo. */
.carrusel:not(.carrusel--listo) .carrusel__boton { display: none; }

.carrusel:not(.carrusel--listo) .carrusel__marco {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.carrusel:not(.carrusel--listo) .destino-tarjeta { scroll-snap-align: start; }
