/* ============================================================
   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;

  /* Solo para la declaracion espiritual del cierre de «Nosotros»: es un
     texto de otra naturaleza que el resto del sitio y el cliente lo
     queria con voz propia. Se carga unicamente en esa pagina.

     Si no llegara a cargarse cae en serifas del sistema, que conservan
     el aire de inscripcion; una de palo seco lo dejaria igual que el
     resto y se perderia la intencion. */
  --fuente-declara: 'Cormorant Garamond', 'Georgia', 'Times New Roman', 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); }

/* Centra en su fila una columna de la rejilla de doce.

   Las clases `t-*` fijan cuantas columnas ocupa un bloque, pero lo
   colocan siempre al principio de la fila. Con `t-8` quedaban cuatro
   columnas vacias a la derecha y el bloque se leia descolgado.

   Se centra moviendo el TRAMO de columnas, no con `justify-self`:
   `justify-self: center` hace que el bloque se encoja a su contenido
   —medido, el acordeon pasaba de 8 columnas a 420 px— en vez de
   conservar su ancho y cambiar de sitio.

   Por debajo de 900 px las clases `t-*` ya ocupan la fila entera, asi
   que aqui no hay nada que centrar y la regla se retira: dejarla
   pondria el bloque a partir de la tercera columna de una rejilla que
   a esas alturas solo tiene una. */
@media (min-width: 901px) {
  .t-6.t--centro  { grid-column: 4 / span 6; }
  .t-8.t--centro  { grid-column: 3 / span 8; }
  .t-10.t--centro { grid-column: 2 / span 10; }
}

/* Encabezado centrado, para las secciones que llevan debajo un bloque
   estrecho tambien centrado. `justify-items` ademas de `text-align`
   porque el antetitulo y el filete que lo acompaña son elementos de
   rejilla: sin eso se estiran a todo lo ancho y el filete aparece
   pegado a la izquierda aunque su texto vaya centrado. */
.enc--centro {
  justify-items: center;
  text-align: center;
}

.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); }
}

/* La barra ocupa el ANCHO COMPLETO de la ventana, no la caja centrada
   del resto del sitio.

   Lleva la clase `.env`, que limita a `--ancho-max` y centra con
   margenes automaticos. Eso esta bien para el contenido —una columna de
   texto de borde a borde no se lee—, pero en la cabecera dejaba la
   marca y el interruptor flotando hacia el centro, con un vacio grande
   a cada lado en pantallas anchas. Una cabecera se ancla a los bordes.

   Se anula el ancho maximo y el centrado, y se conserva el margen
   lateral: pegados al canto del cristal quedarian incomodos de pulsar
   en movil, donde el pulgar llega justo al borde. */
.cabecera__barra {
  /* Rejilla de tres columnas, no `space-between`.

     Con `space-between` el menu quedaba a la derecha del centro real:
     reparte el hueco SOBRANTE por igual, y como la marca ocupa mucho
     mas que el interruptor, los dos huecos son iguales entre si pero el
     bloque central no cae centrado en la barra.

     Con las dos columnas de los lados a `1fr` da igual lo que midan la
     marca y el interruptor: ambas reservan lo mismo y la del medio cae
     en el eje de la ventana. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--e-4);
  height: 72px;
  max-width: none;
  margin-inline: 0;
  padding-inline: var(--e-5);
}

/* Cada bloque va anclado a SU columna, por numero.

   Colocarlos por orden de aparicion no vale: un elemento con
   `display: none` no ocupa celda, asi que al esconderse el menu de
   escritorio el grupo de acciones se corria a la columna del medio y el
   interruptor se quedaba plantado a 244 px del borde derecho. Con el
   numero puesto, la columna vacia se queda vacia. */
.cabecera__barra > .marca { grid-column: 1; }
.cabecera__barra > .menu--escritorio { grid-column: 2; }

.cabecera__acciones {
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: var(--e-2);
}

@media (max-width: 560px) {
  .cabecera__barra { padding-inline: var(--e-3); }
}

.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);
  /* Un 25 % arriba y luego un 15 % abajo, a peticion del cliente:
     1,25 x 0,85 = 1,0625. Se deja la cuenta hecha y no encadenada,
     para que se lea de un vistazo lo que acaba midiendo.

     Va como multiplicacion y no saltando al escalon siguiente de la
     escala porque esta es fluida: los escalones no guardan entre si una
     razon fija, asi que saltar uno daria una proporcion distinta segun
     el ancho de la ventana. */
  font-size: calc(var(--t-sm) * 1.0625);
  font-weight: 600;
  letter-spacing: -.01em;
}
.marca__cola {
  /* Misma cuenta que el nombre sobre los 11 px de partida:
     11 x 1,25 x 0,85 = 11,6875. */
  font-size: 11.6875px;
  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. */
/* El bloque de marca —pildora y titulo— va CENTRADO y arriba, sobre
   el cielo; la frase de apoyo se queda abajo a la izquierda, sobre el
   agua. Son las dos unicas zonas de la fotografia sin nada que tapar.

   El color del texto NO sigue al tema. La fotografia es la misma en
   claro y en oscuro, asi que un texto que se aclarara con el tema
   quedaria blanco sobre cielo blanco: medido, blanco sobre el pixel mas
   claro de esa franja da 1,41:1 y azul marino da 12,91:1. Los tonos van
   fijos, no heredados. */
.portada {
  position: relative;
  display: grid;
  align-items: start;
  min-height: min(88vh, 780px);
  /* Arriba, una ficha menos que abajo: sube el bloque de marca 32 px
     sin sacarlo del aclarado del cielo, que alcanza el 40 % del alto. */
  padding-block: var(--e-7) var(--e-8);
  overflow: hidden;
  background: var(--papel);

  --tinta:   hsl(224 72% 11%);
  --tinta-2: hsl(224 34% 23%);
  --tinta-3: hsl(224 22% 34%);
  --linea:   hsl(224 45% 18% / .30);
  --acento:  hsl(224 100% 34%);
  color: var(--tinta);
}

/* La flecha de bajar vive abajo del todo, sobre la carretera. Ahi el
   texto va CLARO, al reves que el resto de la portada, porque el asfalto
   es la franja mas oscura de la foto.

   Pero no basta con eso: por el centro de la calzada pasan las lineas
   blancas de la senalizacion, y blanco sobre blanco daba 1,29:1. Lleva
   pastilla propia, como la miga de pan de las paginas interiores, para
   que deje de importar que le toque debajo. */
.portada .bajar,
.portada .bajar span { color: hsl(0 0% 100% / .95); }

.portada .bajar {
  padding: var(--e-2) var(--e-3);
  border-radius: 100px;
  background: hsl(224 72% 7% / .66);
  backdrop-filter: blur(7px);
}

/* 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%;

  /* Opaca del todo y con su color de siempre. Ya no hace falta bajarle
     la opacidad: nada se apoya encima que necesite fondo. */
  opacity: 1;
  filter: saturate(1.14) contrast(1.05);
}

/* 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. */
/* Dos zonas de texto, dos asentados, y nada en medio.

   Arriba, un aclarado suave del cielo: iguala la luz de la franja donde
   van la pildora y la primera linea, que el cielo tiene degradado
   propio. Discreto a proposito —el anterior iba al 62 % y se leia como
   neblina sobre el puerto.

   Abajo a la izquierda, un vineteado de esquina para la frase. Elipse
   definida en porcentajes de la propia caja, y no una diagonal: una
   diagonal cambia de angulo con la proporcion de la pantalla y cubria
   bien en escritorio dejando la frase al descubierto en movil. Sube
   hasta la mitad del alto porque la frase acaba de subir 32 px.

   Entre las dos no hay nada: el barco, el tren, los camiones, el avion
   y las montanas se ven tal cual salieron de la camara. */
.portada::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(62% 40% at 50% 20%,
      hsl(0 0% 100% / .34) 0%,
      hsl(0 0% 100% / .22) 46%,
      transparent 78%),
    radial-gradient(112% 50% at 4% 100%,
      hsl(224 76% 4% / .90) 0%,
      hsl(224 75% 4% / .80) 26%,
      hsl(224 74% 5% / .56) 46%,
      hsl(224 72% 6% / .26) 66%,
      transparent 86%),
    linear-gradient(to bottom,
      hsl(202 65% 97% / .50) 0%,
      hsl(202 60% 96% / .32) 22%,
      hsl(202 55% 95% / .12) 36%,
      transparent 48%);
}

/* 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. */
/* En vertical el texto ocupa mas altura porque la columna es estrecha
   y todo parte en mas lineas: medido, el bloque llega al 54 % del alto
   frente al 46 % de escritorio. El aclarado tiene que bajar otro tanto.

   Se puede permitir sin coste: con la foto recortada a lo ancho, en
   movil se ve la franja CENTRAL —mar y puerto— y no el casco del barco,
   que queda fuera del recorte por la izquierda. */
/* En vertical manda otra fisica: `cover` recorta la foto a una tira,
   el titular ocupa proporcionalmente mucho mas alto y un vineteado de
   esquina no llega al extremo derecho de un texto que ya ocupa casi
   todo el ancho. */
@media (max-width: 820px) {
  /* Tambien a la mitad, por lo mismo. */
  .portada__titulo { font-size: calc(var(--t-2xl) * .8); }

  .portada__entrada {
    left: var(--e-4);
    bottom: var(--e-8);
    /* Mismo criterio que en escritorio: el tope se elige por el numero
       de lineas, no por el ancho. */
    max-width: 34ch;
    font-size: calc(var(--t-base) * .95);
  }

  .portada::after {
    background:
      /* BANDA de abajo, no vineteado de esquina, por lo dicho arriba. */
      linear-gradient(to top,
        hsl(224 76% 4% / .88) 0%,
        hsl(224 75% 4% / .76) 12%,
        hsl(224 74% 5% / .52) 24%,
        hsl(224 72% 6% / .22) 36%,
        transparent 48%),
      radial-gradient(98% 38% at 50% 22%,
        hsl(0 0% 100% / .66) 0%,
        hsl(0 0% 100% / .46) 46%,
        transparent 80%),
      linear-gradient(to bottom,
        hsl(202 65% 97% / .62) 0%,
        hsl(202 62% 96% / .48) 26%,
        hsl(202 58% 95% / .28) 44%,
        transparent 58%);
  }
}

/* Centrado. El cielo es una franja ancha y vacía de lado a lado
   —medido, ocupación de 2 a 7 sobre 100 en todo el tercio superior— así
   que un bloque centrado cae justo donde no hay nada que tapar, y de
   paso queda simétrico respecto del avión y del barco, que están en los
   extremos opuestos. */
/* Alineado a la IZQUIERDA y con la columna corta.

   Centrado, el bloque crecia hacia los dos lados a la vez y acababa
   cruzando el hero de lado a lado: lo que tapaba la flota ya no era el
   velo, eran las letras. Anclado a un lado crece en una sola direccion
   y se le puede poner tope. */
/* Alineado a la IZQUIERDA de verdad.

   El intento anterior le puso `max-width` y se quedo centrado igual:
   este bloque lleva tambien la clase `.env`, que es el contenedor del
   sitio y centra con margenes automaticos. Poner un ancho maximo sin
   anular ese centrado no lo mueve de sitio, solo lo estrecha, y el
   resultado fue una columna fina justo en mitad del encuadre.

   El tope de ancho va en los HIJOS y no aqui, para que el contenedor
   conserve su margen lateral y el bloque quede a plomo con el logotipo
   de la cabecera. */
.portada__contenido {
  position: relative;
  z-index: 1;
  text-align: center;
}

.portada__ante {
  display: inline-flex;
  margin-inline: auto;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-4);
  padding: var(--e-2) var(--e-3);

  /* Cristal CLARO con tinta oscura, ahora que la portada es una
     superficie clara. La píldora oscura de antes servía cuando el texto
     iba en blanco sobre la fotografía velada; aquí sería una mancha. */
  background: hsl(0 0% 100% / .62);
  backdrop-filter: blur(8px);
  border: var(--borde) solid hsl(224 45% 18% / .18);
  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.

   Hay dos: uno abre la píldora y el otro separa los dos oficios, en el
   sitio donde antes había un punto medio «·». Un separador tipográfico
   no dice nada; el mismo punto que late a los dos lados convierte la
   píldora en una fila de señales encendidas.

   Van en AZUL OSCURO y no en el cian de la marca. El cian sobre la
   píldora clara medía 1,86:1 y a 7 px de diámetro se perdía: un objeto
   gráfico necesita 3:1 para considerarse visible, y el punto es todo
   objeto gráfico, no lleva texto que lo respalde.

   El segundo punto se separa del texto por los dos lados; el primero
   solo por la derecha, porque a su izquierda ya está el borde de la
   píldora. */
.portada__punto {
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--acento);
  box-shadow: 0 0 0 0 hsl(224 100% 34% / .55);
  animation: latido 2.4s ease-out infinite;
}

/* Cada oficio va con su punto en una caja propia. Antes eran cuatro
   piezas sueltas en la misma linea, y una linea no se puede partir por
   donde a uno le convenga: al estrecharse, «Agente de carga» rompia por
   la mitad y el punto se quedaba huerfano arriba. En cajas, el salto
   solo puede ocurrir ENTRE oficios. */
.portada__oficio {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  white-space: nowrap;
}

@keyframes latido {
  0%   { box-shadow: 0 0 0 0 hsl(224 100% 34% / .55); }
  70%  { box-shadow: 0 0 0 9px hsl(224 100% 34% / 0); }
  100% { box-shadow: 0 0 0 0 hsl(224 100% 34% / 0); }
}

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

/* Más pequeño y más denso, buscando el aire de las iniciales del logo:
   allí las letras son pesadas, muy juntas y en caja alta. No se imita
   el cromado —ninguna tipografía web lo haría sin parecer una calcomanía
   de los noventa— pero sí el peso y la compresión.

   SIN resplandor. Se probó uno blanco, para imitar el filo de las letras
   del logo, y arruinaba la palabra en degradado: «TRANSPORTE» tiene el
   relleno transparente —su color sale de un degradado recortado a la
   letra— y en el orden de pintado del navegador la sombra va POR ENCIMA
   del fondo del elemento. Resultado: se veía la sombra blanca y no el
   degradado, y la palabra salía plateada y casi transparente.

   No hace falta: el título mide 11,5:1 contra el cielo. */
/* A cuerpo de titular, no de valla publicitaria.

   Llego a 2,25 veces la escala, y a ese tamano la segunda linea media
   mas del 80 % del ancho del hero, justo por encima del barco y del
   puerto. Ningun velo arregla eso: lo que tapaba la flota no era el
   fondo del texto, era el texto.

   A 1,35 la columna cabe en el cielo despejado de la izquierda y la
   fotografia respira alrededor. */
/* A cuerpo de titular, no de valla publicitaria.

   Llego a 2,25 veces la escala, y a ese tamano la segunda linea medía
   mas del 80 % del ancho del hero por encima del barco y del puerto.
   Ningun velo arregla eso: lo que tapaba la flota no era el fondo del
   texto, era el texto.

   El tope en `ch` lo parte en dos lineas siempre, y a 1,35 la columna
   se queda holgadamente a la izquierda de la locomotora. */
/* La mitad de lo que llego a medir.

   Subio dos veces un 50 % hasta 2,25 veces la escala, y a ese cuerpo la
   segunda linea bajaba hasta el 49 % del alto: cruzaba el barco y el
   puerto, y ahi la tinta oscura media 1,11:1 contra los contenedores.
   Ningun velo arregla eso, porque lo que tapaba la flota no era el
   fondo del texto sino el texto.

   A 1,125 el titular entero se queda en la franja de cielo despejado. */
.portada__titulo {
  font-size: calc(var(--t-2xl) * 1.125);
  font-weight: 700;
  line-height: .92;
  letter-spacing: -.055em;
  text-transform: uppercase;
  margin-bottom: var(--e-3);
}

/* La segunda linea va de la MISMA TINTA que la primera: el titular es
   uno solo, no dos piezas pegadas.

   Estuvo en blanco con filete oscuro, y ese apano tenia sentido cuando
   el titulo media 2,25 veces la escala y la linea bajaba hasta el 49 %
   del alto: cruzaba cielo, agua, el casco del barco y el puerto, y
   ningun color plano servia para todo el recorrido. Reducido el titulo
   a la mitad, la linea se queda entera sobre cielo despejado, y ahi el
   blanco era justo lo peor que se podia elegir: medido, el relleno daba
   1,27:1 y la palabra se leia como un contorno hueco. En tinta oscura
   mide 13,4:1.

   El `span` se queda aunque ya no lleve color propio: es lo que fuerza
   el corte de linea sin depender de donde caiga el ancho. */
.portada__linea2 { color: inherit; }

.portada__titulo em { font-style: normal; color: inherit; }


/* La frase de apoyo, anclada al rincon inferior IZQUIERDO.

   Sale del flujo del bloque centrado a proposito: colgada del titulo
   crecia hacia abajo y acababa cruzando el puerto y la proa. Anclada al
   rincon se queda quieta, y con `max-width` corto no alcanza ni al
   barco, que ocupa la mitad izquierda por encima, ni al tren, que entra
   por el centro.

   La posicion se gobierna con DOS propiedades y nada mas: `left`
   separa del borde izquierdo y `bottom` levanta desde el borde
   inferior. Ahora mismo 48 px y 96 px.

   Los topes no son esteticos, son de contraste, y estan MEDIDOS a
   1280x820 barriendo las dos propiedades de ocho en ocho pixeles:

     left   hasta  88 px -> 3,16   |  a 96 px cae a 2,83
     bottom hasta 200 px -> 3,26   |  a 208 px cae a 1,54

   Por la derecha el freno es la barandilla del puente, que es gris
   claro; por arriba, el casco del barco. Dentro de esa caja hay agua
   abierta y se puede mover con libertad. Fuera hace falta reforzar
   antes el vineteado de `.portada::after`.

   Va en BLANCO —al reves que el titulo, que cae sobre cielo claro—
   porque aqui el fondo es mar profundo y el contraste lo pone el propio
   oceano.

   Va con la MISMA TIPOGRAFIA que el titular y en CAJA ALTA, para que el
   rincon hable con la misma voz que el centro. Estuvo manuscrita: era
   la tercera tipografia de la portada y sonaba a algo pegado aparte.

   El ancho maximo esta calculado para que caiga en TRES lineas. Crece
   hacia arriba antes que hacia los lados a proposito: a lo ancho
   alcanzaria la locomotora, y hacia arriba solo hay agua abierta.

   Interlinea holgada e interletrado abierto porque la caja alta corrida
   se lee peor que la mixta: sin ese aire las tres lineas se apelmazan
   en un bloque macizo. */
.portada__entrada {
  position: absolute;
  left: var(--e-6);
  bottom: var(--e-8);
  z-index: 2;
  /* 34ch es el valor exacto en que la frase cae en tres lineas: medido,
     de 32ch para abajo salen cuatro o mas, y de 34 para arriba la caja
     crece pero el texto ya no —la linea mas larga se queda en 342 px,
     el 27 % del hero, muy a la izquierda de la locomotora. */
  max-width: 34ch;
  margin: 0;
  text-align: left;
  font-family: var(--fuente-titulo);
  font-weight: 600;
  font-size: calc(var(--t-base) * 1.05);
  line-height: 1.65;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: hsl(0 0% 100% / .97);

  /* El contraste va en las LETRAS, no en una mancha detras. El primer
     intento puso una elipse oscura bajo el texto y se veia lo que era:
     un circulo pegado encima de la fotografia. Estas cuatro sombras se
     cinen al perfil de cada letra —de muy cerrada a muy abierta—, asi
     que oscurecen justo lo que hay pegado al trazo y se deshacen en el
     agua sin dibujar ninguna forma. */
  text-shadow:
    0 1px 2px hsl(224 74% 4% / .95),
    0 2px 6px hsl(224 74% 4% / .85),
    0 0 16px  hsl(224 72% 5% / .75),
    0 0 34px  hsl(224 72% 6% / .55);
}
.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;
}

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

/* ---------- Pilares de mision y vision ----------
   La declaracion formal arriba y debajo los cuatro puntos que la
   desglosan, tal como los redacto el cliente.

   Van con MARCA y no con numero. Un 01/02/03 diria que hay un orden y
   que el primero pesa mas; estos cuatro son facetas de lo mismo y se
   leen en cualquier orden. La numeracion tiene que decir algo cierto
   del contenido o sobra.

   Tampoco se reutiliza `.dato`, que trae borde y fondo propios: dentro
   de una tarjeta daria caja dentro de caja. Aqui basta una hairline
   que separe la declaracion del desglose. */

.tarjeta__declara {
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--tinta);
}

/* La vision llego entrecomillada del cliente y se publica asi: es una
   declaracion literal, no una descripcion nuestra. Las comillas van en
   el CSS y no en el texto para que no las lea dos veces un lector de
   pantalla ni estorben al copiar. */
.tarjeta__declara--cita { font-style: italic; }
.tarjeta__declara--cita::before { content: '\201C'; }
.tarjeta__declara--cita::after  { content: '\201D'; }

.pilares__ante {
  display: block;
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: var(--borde) solid var(--linea);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  /* `--tinta-3` daba 4,51:1 sobre la tarjeta clara: pasa por dos
     centesimas, que es no pasar. A 13 px conviene margen. */
  color: var(--tinta-2);
}

.pilares {
  display: grid;
  gap: var(--e-3);
  margin: var(--e-3) 0 0;
}

.pilar {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  column-gap: var(--e-2);
}

/* Rombo pequeno, no vineta redonda: la redonda se confunde con una
   lista corriente y aqui cada punto es un titular con su desarrollo. */
.pilar::before {
  content: '';
  grid-row: 1;
  width: 7px;
  height: 7px;
  margin-top: .45em;
  border-radius: 1px;
  rotate: 45deg;
  background: var(--pilar-marca, var(--acento));
}

.pilar__nombre {
  grid-column: 2;
  font-size: var(--t-sm);
  font-weight: 650;
  color: var(--tinta);
}

/* `dd` trae 40 px de sangria por defecto del navegador; sin quitarla
   el texto no cuadraba con su titulo. */
.pilar__texto {
  grid-column: 2;
  margin: 2px 0 0;
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--tinta-2);
}

/* Rotulo de sub-bloque dentro de una seccion.

   `.enc__ante` es el rotulo de la seccion entera y va en color de
   marca; repetirlo dos veces dentro de la misma seccion competiria con
   el de arriba. Este es su hermano callado: mismo tamano y espaciado,
   tinta secundaria. */
.sub-rotulo {
  display: block;
  margin-bottom: var(--e-3);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tinta-2);
}

/* Lista de compromisos: mismo rombo que los pilares de mision y
   vision, para que se lean como de la misma familia. */
.marcas {
  list-style: none;
  padding: 0;
  margin: var(--e-3) 0 0;
  display: grid;
  gap: var(--e-2);
}

.marcas li {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  column-gap: var(--e-2);
  font-size: var(--t-sm);
  color: var(--tinta-2);
}

.marcas li::before {
  content: '';
  width: 7px;
  height: 7px;
  margin-top: .45em;
  border-radius: 1px;
  rotate: 45deg;
  background: var(--acento);
}

/* Cierre de la declaracion. Es la unica frase del apartado que habla
   en primera persona del proposito entero, asi que se saca de la
   rejilla y se le da aire: no compite con los seis valores, los
   remata. */
.cierre-valores {
  margin-top: var(--e-6);
  padding: var(--e-6);
  border-radius: var(--radio-lg);
  border-top: 3px solid transparent;
  border-image: var(--flujo) 1;
  background: var(--papel);
  box-shadow: var(--sombra-1);
  text-align: center;
}

/* El rotulo, un 50 % sobre la escala y a peticion del cliente. Se
   escribe como multiplicacion sobre `--t-xs` y no saltando al escalon
   siguiente porque la escala es fluida: los escalones no guardan entre
   si una razon fija, asi que saltar uno daria una proporcion distinta
   segun el ancho de la ventana.

   El peso ya era 700 y ahi se queda; a este cuerpo por fin se le nota.
   Va acotado a `.cierre-valores` para no mover los demas `.sub-rotulo`
   del sitio, que son varios. */
.cierre-valores .sub-rotulo { font-size: calc(var(--t-xs) * 1.5); }

.cierre-valores__texto {
  max-width: 62ch;
  margin-inline: auto;
  /* Tipografia propia, distinta a la del resto del sitio.

     Es una garamond de contraste alto, cortada para cuerpos grandes.
     Frente a la caligrafica que estuvo antes gana en dos cosas: se lee
     como una inscripcion y no como una firma, que es el registro que
     pide una declaracion de principios; y no se cansa, porque las
     letras siguen siendo formas romanas normales y no trazos
     enlazados.

     Va GRANDE a proposito. Esta familia tiene la altura de x muy baja
     y las astas muy finas: al cuerpo del texto corriente se lee gris y
     apagada, y solo a partir de unos 30 px muestra el contraste de
     trazo para el que esta dibujada. El peso 500 en vez del 400 es por
     lo mismo.

     En cursiva porque es una cita de intencion, no una descripcion. */
  font-family: var(--fuente-declara);
  font-style: italic;
  font-weight: 500;
  font-size: calc(var(--t-lg) * 1.5);
  line-height: 1.45;
  letter-spacing: .005em;
  color: var(--tinta);
}


/* ============================================================
   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 de muestra ----------
   Para una fotografia que no es telon de fondo sino el ASUNTO de la
   pagina: el montaje de servicios, donde tienen que verse los cuatro
   modos de transporte.

   `cover` recortaba el 42 % del alto —medido: la caja es de 1265x413 y
   la foto necesita 706 px de alto para entrar entera— y se comia el
   avion por arriba y los camiones por abajo. Con `contain` no se
   recorta nada; lo que sobra a los lados lo rellena el telon
   desenfocado, que es la propia foto ampliada, de modo que el color
   del borde siempre casa.

   El alto sale de la proporcion de la imagen, no de un numero fijo:
   asi entra completa en cualquier ancho. El tope evita que en un
   monitor muy ancho el cabezal se coma la pantalla entera. */
.cabezal--muestra {
  display: grid;
  align-content: end;
  min-height: min(calc((100vw - var(--e-4)) / 1.79), 660px);
  padding-block: var(--e-7) var(--e-6);
}

.cabezal--muestra .cabezal__fondo {
  object-fit: contain;
  object-position: center top;
  opacity: .92;
}

.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); }

/* La columna se centra en la banda en vez de pegarse a la izquierda.

   El tope de medida de `.prosa` sigue mandando —unos 730 px, que es lo
   que se puede leer sin perder el renglon al volver— asi que liberar
   las columnas de la derecha no ensancha el texto: solo deja aire. Sin
   centrar, ese aire se acumulaba todo a un lado y el bloque parecia
   descolgado.

   El rotulo y el titulo van centrados; los parrafos NO. Centrar linea
   a linea deja el margen izquierdo en zigzag, y el ojo necesita ese
   borde recto para encontrar donde empieza el renglon siguiente. Con
   siete parrafos seguidos la diferencia no es de gusto: se nota al
   leer. */
.prosa--centro { margin-inline: auto; }

.prosa--centro > .enc__ante {
  display: block;
  text-align: center;
}

.prosa--centro > h2 { text-align: center; }
.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;
}

/* El nombre de la fila va en tinta normal, no en el color de acento.

   En azul y en negrita se leia como un enlace —siete seguidos en
   columna, todos del color con el que el sitio marca lo pulsable— y no
   lo es: es la cabecera de la fila. Lo que tiene que hacer es destacar
   sobre el resto de celdas, y para eso basta el peso. */
.tabla tbody th {
  text-align: left;
  font-weight: 600;
  color: var(--tinta);
  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); }

/* Mismo caso que la unidad: texto pequeno, asi que no puede ir en
   `--tinta-3`. Se usa en la tabla de camiones para el numero de ejes. */
.tabla__nota { display: block; font-size: var(--t-xs); color: var(--tinta-2); }

/* ---------- 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);
  font-weight: 600;
  /* En tinta y no en el color de acento, por lo mismo que las cabeceras
     de fila de las tablas: una columna de terminos azules se lee como
     una lista de enlaces. */
  color: var(--tinta);
  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; }
}

/* ---------- Tarjeta de servicio con fotografia ----------
   Variante de `.dato` para el bloque de servicios: la foto arriba y
   debajo el icono, el titulo y la explicacion.

   El relleno se quita de la tarjeta y se pasa al cuerpo, porque la
   foto tiene que llegar hasta el borde; el `overflow: hidden` es lo
   que hace que respete las esquinas redondeadas.

   Las fotos van todas a 16:10 y recortadas al mismo tamano desde el
   origen: si cada una llegara con su proporcion, las tarjetas de una
   misma fila quedarian desiguales. */
.dato--ilustrada {
  grid-template-columns: minmax(0, 1fr);
  padding: 0;
  overflow: hidden;
}

.dato__foto {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  /* Sin el filtro, seis fotos de origenes distintos se pelean entre
     ellas. Bajando un punto la saturacion y subiendo algo el contraste
     se parecen mas a una serie que a un collage. */
  filter: saturate(.94) contrast(1.04);
  transition: scale 600ms cubic-bezier(.2, 0, .2, 1);
  scale: 1;
}

/* Solo la de embalaje es un enlace; se acerca al senalarla para que se
   note que lleva a alguna parte. */
a.dato--ilustrada:hover .dato__foto,
a.dato--ilustrada:focus-visible .dato__foto { scale: 1.05; }

.dato__cuerpo {
  display: grid;
  gap: var(--e-1);
  padding: var(--e-4);
}

.dato--ilustrada .dato__marca { margin-bottom: var(--e-2); }

@media (prefers-reduced-motion: reduce) {
  .dato__foto { transition: none; }
  a.dato--ilustrada:hover .dato__foto { scale: 1; }
}

/* ---------- Rueda de servicios ----------
   Una tarjeta a la vez, grande, girando sola cada diez segundos.

   Se eligio rueda y no una pila de seis tarjetas largas porque el
   cliente queria el desarrollo COMPLETO de cada servicio: puestas una
   debajo de otra, seis bloques de ese tamano empujan el resto de la
   pagina fuera de la vista y nadie llega al final. Girando, cada una
   se lee entera en su sitio.

   El mecanismo es el mismo del carrusel de paises —mismo guion, mismos
   atributos `data-`— pero con clases propias para no heredar su
   maquetacion de cuatro por vista. */

.rueda { position: relative; }
.rueda__marco { overflow: hidden; border-radius: var(--radio-lg); }

.rueda__pista {
  display: flex;
  gap: 0;
  /* `stretch` para que todas midan lo mismo de alto: con textos de
     distinta longitud, si cada una se ajustara a su contenido el marco
     daria un salto en cada giro. */
  align-items: stretch;
  will-change: transform;
}

.servicio {
  flex: 0 0 100%;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  background: var(--papel);
  border: var(--borde) solid var(--linea);
  border-radius: var(--radio-lg);
  overflow: hidden;
}

.servicio__foto {
  width: 100%;
  height: 100%;
  min-height: 260px;
  object-fit: cover;
  filter: saturate(.94) contrast(1.04);
}

.servicio__cuerpo {
  display: grid;
  align-content: start;
  gap: var(--e-3);
  padding: var(--e-6);
}

.servicio__titulo {
  font-family: var(--fuente-titulo);
  font-size: var(--t-xl);
  line-height: 1.2;
}

.servicio__entrada { color: var(--tinta-2); }

.servicio__enlace {
  justify-self: start;
  margin-top: var(--e-1);
}

/* ---------- Mandos ---------- */

.rueda__boton {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: var(--borde) solid var(--linea);
  border-radius: 50%;
  background: var(--papel);
  color: var(--tinta);
  box-shadow: var(--sombra-2);
  cursor: pointer;
  transition: border-color var(--transicion), color var(--transicion);
}

.rueda__boton:hover { border-color: var(--acento); color: var(--acento); }
.rueda__boton svg { width: 20px; height: 20px; }
.rueda__boton--atras    { left: calc(var(--e-4) * -1); }
.rueda__boton--adelante { right: calc(var(--e-4) * -1); }

/* Sin JavaScript no hay giro, asi que las flechas no harian nada: se
   ocultan hasta que el guion declara la rueda lista, y mientras tanto
   el marco se puede arrastrar de lado como una tira normal. */
.rueda:not(.carrusel--listo) .rueda__boton { display: none; }
.rueda:not(.carrusel--listo) .rueda__marco {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.rueda:not(.carrusel--listo) .servicio { scroll-snap-align: start; }

.rueda__puntos {
  display: flex;
  justify-content: center;
  gap: var(--e-2);
  margin-top: var(--e-4);
}

/* El punto mide 10 px pero el boton 44: el area de pulsacion tiene que
   ser comoda en un movil aunque la marca sea pequena. */
.punto {
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.punto::before {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--linea);
  transition: background var(--transicion), width var(--transicion);
}

.punto:hover::before { background: var(--tinta-3); }

.punto.es-actual::before {
  width: 26px;
  border-radius: 5px;
  background: var(--acento);
}

@media (max-width: 820px) {
  .servicio { grid-template-columns: minmax(0, 1fr); }
  .servicio__foto { min-height: 0; aspect-ratio: 16 / 9; }
  .servicio__cuerpo { padding: var(--e-5); }
  /* Pegadas al borde interior: fuera del marco se salen de la pantalla. */
  .rueda__boton--atras    { left: var(--e-2); }
  .rueda__boton--adelante { right: var(--e-2); }
}

@media (prefers-reduced-motion: reduce) {
  .rueda__pista { transition: none !important; }
}


/* ---------- Panel de servicios de una via ----------
   Sustituye a un `.aviso` con una lista a dos columnas.

   Aquella version tenia dos problemas de composicion. Uno, siete
   elementos repartidos en dos columnas dan cuatro y tres, asi que la
   segunda columna terminaba antes y dejaba un hueco muerto justo en el
   centro del panel. Y dos, a partir de unos 1200 px el bloque ocupaba
   media caja y la mitad derecha se quedaba vacia, porque `columns` no
   reparte el ancho sobrante: lo deja al final.

   La rejilla `auto-fit` reparte el ancho entre tantas columnas como
   quepan, de modo que las fichas ocupan la caja entera a cualquier
   tamano y el unico hueco posible es el de la ultima fila. Ademas cada
   servicio gana una linea de explicacion: siete nombres sueltos
   obligaban a adivinar que es una plataforma o un reefer. */
.oferta {
  padding: var(--e-5);
  border-radius: var(--radio-lg);
  border: var(--borde) solid var(--linea);
  background: var(--papel-2);
}

.oferta__enc {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-bottom: var(--e-4);
}

/* El icono en pastilla propia y no suelto sobre el fondo: suelto se
   confundia con las vinetas de la lista, que eran del mismo color. */
.oferta__marca {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radio-md);
  background: var(--acento);
  color: var(--sobre-acento);
}
.oferta__marca svg { width: 22px; height: 22px; }

.oferta__ante {
  margin: 0;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--acento);
}

.oferta__titulo {
  margin: 0;
  font-family: var(--fuente-titulo);
  font-size: var(--t-lg);
  font-weight: 600;
  letter-spacing: -.01em;
}

.oferta__rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--e-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.oferta__ficha {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-2);
  align-items: start;
  padding: var(--e-3);
  border-radius: var(--radio-md);
  border: var(--borde) solid var(--linea-suave);
  background: var(--papel);
}

.oferta__visto {
  width: 16px;
  height: 16px;
  margin-top: 3px;   /* a la altura de la mayuscula, no de la caja */
  color: var(--acento);
}

.oferta__nombre {
  display: block;
  font-size: var(--t-sm);
  font-weight: 600;
}

.oferta__nota {
  display: block;
  margin-top: 2px;
  font-size: var(--t-xs);
  line-height: 1.5;
  /* `--tinta-3` sobre `--papel` da 4,51:1 en tema claro. Pasa el 4,5
     por dos centesimas, que es lo mismo que no pasar: cualquier ajuste
     posterior del papel lo tumba. Un escalon mas de tinta lo deja con
     margen de sobra. */
  color: var(--tinta-2);
}

/* Separado por un filete: es una nota al pie, no un servicio mas. */
.oferta__pie {
  display: flex;
  align-items: start;
  gap: var(--e-2);
  margin: var(--e-4) 0 0;
  padding-top: var(--e-3);
  border-top: var(--borde) solid var(--linea);
  font-size: var(--t-sm);
  color: var(--tinta-2);
}
.oferta__pie svg { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--acento); }

@media (max-width: 560px) {
  .oferta { padding: var(--e-4); }
  .oferta__enc { margin-bottom: var(--e-3); }
}

/* ---------- Dos columnas emparejadas fila a fila ----------
   Para bloques que se leen en paralelo: cada tarjeta de la izquierda
   frente a la que le corresponde de la derecha.

   Con dos columnas independientes —que es como estaba— cada pila crece
   por su cuenta: la de la izquierda llegaba a 695 px y la de la derecha
   a 545, de modo que la tercera tarjeta de un lado quedaba a la altura
   de la cuarta del otro y sobraba un hueco al pie. La comparacion,
   que es justo para lo que sirve poner dos listas en paralelo, no se
   podia hacer.

   `subgrid` es lo que lo resuelve sin tocar el marcado: las dos
   columnas y las dos pilas heredan las FILAS del contenedor, asi que
   cada fila mide lo que su pareja mas alta y ambos lados van al paso.

   Sin soporte de `subgrid` el bloque se queda en dos columnas
   independientes, que es exactamente como estaba antes: se pierde el
   emparejado, no la lectura. */
.pareja {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Una fila para los rotulos y una por cada pareja de tarjetas. */
  grid-template-rows: auto repeat(4, auto);
  column-gap: var(--e-5);
  row-gap: var(--e-3);
}

.pareja__col {
  display: grid;
  grid-row: 1 / -1;
  grid-template-rows: subgrid;
}

/* El envoltorio de cada pila tambien hereda las filas. Se conserva
   —en vez de sacar las tarjetas al nivel de arriba— porque a la derecha
   es un <ol> y sacarlas de el convertiria una lista numerada en cuatro
   parrafos sueltos para quien navega con lector de pantalla. */
.pareja .datos--columna,
.pareja .pasos-lista {
  display: grid;
  grid-row: 2 / -1;
  grid-template-rows: subgrid;
  /* Sin `gap` propio a proposito: una subrejilla hereda el hueco entre
     filas del contenedor. Ponerselo aqui —aunque fuera cero— lo anula,
     y las tarjetas quedaban pegadas unas a otras. */
  margin: 0;
  padding: 0;
}

/* Las tarjetas estiran hasta el alto de su fila: si una pareja va
   despareja de texto, las dos cajas siguen midiendo lo mismo. */
.pareja .dato,
.pareja .paso { height: 100%; }

.pareja .sub-rotulo { margin-bottom: var(--e-2); }

@media (max-width: 820px) {
  /* En vertical no hay dos columnas que comparar: cada pila vuelve a
     ser una pila normal y el emparejado sobra. */
  .pareja { grid-template-columns: 1fr; grid-template-rows: none; row-gap: var(--e-6); }
  .pareja__col { grid-row: auto; grid-template-rows: none; }
  .pareja .datos--columna,
  .pareja .pasos-lista { grid-row: auto; grid-template-rows: none; gap: var(--e-3); }
}


/* ---------- Fichas de contenedor ISO ----------
   Sustituyen a una tabla de seis columnas.

   La tabla era la herramienta equivocada para este dato. Seis columnas
   repartidas en 1.140 px dejaban cada cifra a 200 px de la siguiente,
   de modo que leer una fila entera —que es lo unico que se hace aqui:
   mirar UN contenedor— obligaba a recorrer el ancho completo de la
   pantalla. Una tabla sirve para comparar columna contra columna; aqui
   lo que se compara son piezas enteras.

   En ficha, cada contenedor cabe de una ojeada y siete de ellas ocupan
   dos filas en vez de una franja de 600 px de alto. Y las tres medidas
   interiores van juntas en una sola linea, «5,90 x 2,35 x 2,39 m», que
   es como se escriben y se dicen en el oficio. */
.isos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--e-3);
}

.iso {
  display: grid;
  align-content: start;
  gap: var(--e-3);
  padding: var(--e-4);
  border-radius: var(--radio-lg);
  border: var(--borde) solid var(--linea);
  background: var(--papel);
}

.iso__enc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
}

.iso__nombre {
  margin: 0;
  font-family: var(--fuente-titulo);
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -.01em;
  white-space: nowrap;
}

/* La familia como distintivo y no como columna: dice de un vistazo si
   es seco, refrigerado o especial sin gastar una fila de datos. */
.iso__familia {
  flex: none;
  padding: 2px var(--e-2);
  border-radius: 100px;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .04em;
  background: var(--papel-2);
  border: var(--borde) solid var(--linea);
  color: var(--tinta-2);
}
.iso__familia--frio     { color: var(--cian-texto); border-color: currentColor; }
.iso__familia--especial { color: var(--acento); border-color: currentColor; }

.iso__datos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e-2) var(--e-3);
  margin: 0;
  padding-top: var(--e-3);
  border-top: var(--borde) solid var(--linea-suave);
}

/* Las tres medidas ocupan las dos columnas: partidas quedaban en dos
   lineas y se perdia la lectura seguida «largo por ancho por alto». */
.iso__dato--ancho { grid-column: 1 / -1; }

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

.iso__dato dd {
  margin: var(--e-1) 0 0;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--tinta);
  /* Digitos de ancho fijo: sin esto muchas tipografias dan al 1 menos
     ancho que al 0 y las cifras de fichas contiguas no cuadran. */
  font-variant-numeric: tabular-nums;
}

.iso__medida { white-space: nowrap; }

.iso__unidad {
  font-weight: 400;
  color: var(--tinta-2);
}


/* ---------- Mision y Vision, emparejadas por filas ----------
   Las dos tarjetas tienen las mismas cinco piezas —icono, titulo,
   declaracion, rotulo y lista— pero la declaracion de la mision ocupa
   seis lineas y la de la vision cuatro. Como cada tarjeta se maquetaba
   por su cuenta, el rotulo «Componentes fundamentales» caia dos lineas
   mas abajo que «Elementos y metas», y con el todo lo que venia
   detras: el filete, la lista y cada pilar.

   Con `subgrid` las dos heredan las FILAS del contenedor, asi que cada
   fila mide lo que la mas alta de las dos y las cinco piezas van al
   paso. La declaracion mas corta simplemente deja aire debajo, que es
   lo que se quiere: el hueco cae en el sitio donde no molesta.

   Sin soporte de `subgrid` las tarjetas se quedan como estaban, cada
   una a su altura: se pierde el emparejado, no la lectura. */
.mv {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Icono, titulo, declaracion, rotulo y los cuatro pilares: la lista
     no se trata como una fila unica sino como cuatro, para que tambien
     cada pilar quede frente al suyo. Un pilar de dos lineas en un lado
     desplazaba a todos los de abajo en ese lado. */
  grid-template-rows: repeat(8, auto);
  gap: var(--hueco);
}

.mv > .tarjeta {
  display: grid;
  grid-row: 1 / -1;
  grid-template-rows: subgrid;
  /* El hueco propio se conserva en `--e-3`, que es el que ya tenia la
     tarjeta cuando era `flex`. Sin declararlo heredaria el del
     contenedor, que es mayor, y las cinco piezas se separarian. */
  row-gap: var(--e-3);
}

/* La lista hereda a su vez las cuatro ultimas filas. El margen superior
   se conserva porque el hueco entre el rotulo y la lista lo daba el, no
   la rejilla. */
.mv .pilares {
  grid-row: 5 / -1;
  grid-template-rows: subgrid;
  row-gap: var(--e-3);
}

@media (max-width: 820px) {
  /* En una sola columna no hay pareja que emparejar. */
  .mv { grid-template-columns: 1fr; grid-template-rows: none; }
  .mv > .tarjeta { grid-row: auto; grid-template-rows: none; }
  .mv .pilares { grid-row: auto; grid-template-rows: none; }
}


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


/* =====================================================================
   VISTA MOVIL
   =====================================================================

   Todo lo de este archivo vive dentro de `@media (max-width: 820px)`.
   No es una convencion: es la garantia de que el escritorio no se puede
   ver afectado por nada de lo que se escriba aqui. Si alguna regla
   necesitara salir de la consulta de medios, deja de pertenecer a este
   archivo y se va a la hoja del componente.

   La hoja se llama `06-` porque el generador concatena por orden
   alfabetico: al ir la ultima, gana los empates de especificidad sin
   tener que recurrir a `!important` ni a selectores retorcidos.

   El movil no es el escritorio estrechado. Cambian tres cosas: se
   apunta con el dedo y no con un raton de un pixel, se mira una
   pantalla que cabe en la mano, y se navega con el pulgar mientras se
   sostiene el aparato. Lo que sigue responde a esas tres.
   ===================================================================== */

@media (max-width: 820px) {

  /* ---------- Tipografia ----------
     Medido en las diez paginas principales: habia texto de cuerpo por
     debajo de 14 px —el aviso legal del cotizador, los antetitulos, las
     descripciones de clase de mercancia—. En una pantalla que se
     sostiene a 30 cm de la cara eso es ilegible para bastante gente, y
     ademas iOS hace zoom automatico al enfocar un campo de formulario
     con letra menor de 16 px, lo que descoloca la pagina entera. */
  .enc__ante,
  .oferta__ante,
  .pilares__ante,
  .tabla__nota,
  .clase__texto,
  .cotizador__legal,
  .dato__texto,
  .iso__dato dt,
  .oferta__nota {
    font-size: max(14px, var(--t-xs));
  }

  /* 16 px es el umbral por debajo del cual iOS amplia la pagina al
     enfocar. No es preferencia: es lo que evita el salto.

     Se nombra el contenedor `.campo` a proposito. Los campos del
     cotizador llevan `font: inherit` desde `.campo input`, que con dos
     partes de selector gana a un `input` a secas por mucho que esta
     hoja vaya la ultima; heredaban 14,19 px y el zoom saltaba igual. */
  input, select, textarea,
  .campo input, .campo select, .campo textarea,
  .calc__fila input {
    font-size: max(16px, var(--t-base));
  }

  /* ---------- Objetivos tactiles ----------
     La yema del dedo cubre unos 9 mm. Los controles SUELTOS —botones,
     enlaces de navegacion, resumenes de acordeon— se llevan a 44 px de
     alto minimo.

     Los enlaces DENTRO de un parrafo se quedan como estan: un enlace en
     linea no puede medir 44 px de alto sin romper la interlinea del
     texto que lo rodea, y el remedio seria peor. */
  .menu a,
  .pie a,
  .btn,
  .enlace-flecha,
  .pliegue summary,
  .carrusel__boton,
  .carrusel__punto,
  .tema-boton {
    min-height: 44px;
  }

  .menu a,
  .pie a,
  .enlace-flecha {
    display: flex;
    align-items: center;
  }

  /* Los puntos del carrusel son de 8 px a la vista, pero se pulsan en
     un area de 44: el area tactil se agranda con un pseudoelemento y no
     con relleno, para no separar los puntos entre si. */
  .carrusel__punto {
    position: relative;
    min-width: 44px;
  }
  .carrusel__punto::after {
    content: '';
    position: absolute;
    inset: -14px;
  }

  /* ---------- Respuesta al toque ----------
     En una pantalla tactil no hay `hover`: el dedo no sobrevuela, toca.
     Sin una respuesta al pulsar, la interfaz parece muerta durante los
     300 ms que tarda en llegar la pagina siguiente.

     `active` con una escala minima es la respuesta mas barata que
     existe: no ocupa red, no espera a JavaScript y se siente inmediata.
     `touch-action: manipulation` quita el retardo que algunos
     navegadores dejan para distinguir el doble toque de ampliacion. */
  a, button, summary, .tarjeta, .dato, .iso, .servicio {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  .btn:active,
  .tarjeta:active,
  .dato:active,
  .iso:active,
  .oferta__ficha:active,
  .destino-tarjeta:active {
    scale: .985;
    transition: scale 90ms ease-out;
  }

  .pliegue summary:active { background: var(--papel-2); }

  /* ---------- Entrada escalonada ----------
     La animacion de entrada ya existia, pero disparaba todos los
     elementos de un grupo a la vez, y a la vez es como no animar: se ve
     un bloque que aparece, no una secuencia.

     Escalonados unos 70 ms, el ojo sigue el orden de lectura. Se corta
     en el sexto porque a partir de ahi el ultimo tardaria casi medio
     segundo en aparecer y se percibe como lentitud, no como ritmo.

     El desplazamiento es mayor que en escritorio —28 px frente a 20— y
     entra ademas desde una escala ligeramente menor: en una pantalla
     pequena un recorrido corto no se aprecia. */
  .entra { translate: 0 28px; scale: .985; }
  html.js-listo .entra.es-visible { translate: 0 0; scale: 1; }

  html.js-listo .entra:nth-child(2)  { transition-delay: 70ms; }
  html.js-listo .entra:nth-child(3)  { transition-delay: 140ms; }
  html.js-listo .entra:nth-child(4)  { transition-delay: 210ms; }
  html.js-listo .entra:nth-child(5)  { transition-delay: 280ms; }
  html.js-listo .entra:nth-child(n+6) { transition-delay: 350ms; }

  /* ---------- Tablas convertidas en fichas ----------
     Las dos tablas que quedan —tipos de camion e incoterms— tienen
     cuatro y cinco columnas. En 390 px eso obliga a un desplazamiento
     lateral dentro de la pagina: medido, la tabla ocupa 620 px en una
     caja de 349. Y un desplazamiento lateral dentro de una pagina que
     ya se desplaza en vertical es de las cosas que peor se manejan con
     el pulgar, porque el gesto se confunde con el de la pagina.

     Cada fila pasa a ser una ficha. El nombre de la columna, que en la
     tabla vivia en la cabecera, se escribe ahora dentro de cada celda
     leyendolo del atributo `data-titulo`. La cabecera se oculta, pero
     NO con `display: none`: se aparta de la vista conservandola para
     los lectores de pantalla, que siguen anunciando la tabla con su
     estructura. */
  .tabla-caja {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: none;
  }

  .tabla { min-width: 0; }

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

  .tabla,
  .tabla tbody,
  .tabla tbody tr,
  .tabla tbody th,
  .tabla tbody td { display: block; }

  .tabla tbody tr {
    margin-bottom: var(--e-3);
    padding: var(--e-4);
    border: var(--borde) solid var(--linea);
    border-radius: var(--radio-lg);
    background: var(--papel);
  }

  .tabla tbody th {
    padding: 0 0 var(--e-3);
    margin-bottom: var(--e-2);
    border-bottom: var(--borde) solid var(--linea);
    font-size: var(--t-base);
    white-space: normal;
  }

  .tabla tbody td {
    padding: var(--e-2) 0 0;
    border: 0;
  }

  /* El rotulo va ENCIMA del dato y no a su lado: «Para que sirve» lleva
     dos lineas de texto detras, y en dos columnas el dato se quedaba en
     una tira de 150 px. */
  .tabla tbody td::before {
    content: attr(data-titulo);
    display: block;
    margin-bottom: 2px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tinta-2);
  }

  /* Sin rotulo en la cabecera no hay nada que escribir. */
  .tabla tbody td:not([data-titulo])::before { content: none; }

  .tabla tbody tr:hover th,
  .tabla tbody tr:hover td { background: none; }

  /* ---------- Ritmo vertical ----------
     Las paginas largas llegan a 13.000 px en movil. Parte de eso es
     contenido y no se toca, pero el aire entre secciones estaba
     calculado para una pantalla ancha: en vertical, el mismo hueco se
     lee como un vacio y obliga a arrastrar de mas. */
  .seccion { padding-block: calc(var(--seccion-y) * .72); }
  .enc { margin-bottom: var(--e-5); }

  @media (prefers-reduced-motion: reduce) {
    html.js-listo .entra { transition-delay: 0ms !important; }
    .btn:active,
    .tarjeta:active,
    .dato:active,
    .iso:active,
    .oferta__ficha:active,
    .destino-tarjeta:active { scale: none; }
  }
}

/* La etiqueta de los flotantes y la accion de cotizar solo existen en
   la barra inferior, que es cosa de movil. En escritorio se retiran del
   todo para no tocar nada de lo que ya estaba. */
.flotante__texto { display: none; }
.flotante--cotiza { display: none; }

@media (max-width: 820px) {

  /* ---------- Barra de acciones inferior ----------
     Los dos circulos de la esquina inferior derecha funcionan en
     escritorio, donde el puntero llega a cualquier punto sin esfuerzo.
     En un movil sostenido con una mano, la esquina superior queda fuera
     del alcance del pulgar y la inferior derecha es justo donde la mano
     tapa la pantalla.

     La franja inferior completa es la zona comoda, asi que las dos
     acciones que importan —escribir por WhatsApp y pedir cotizacion—
     pasan a una barra que la ocupa entera. Y con etiqueta: un icono
     suelto obliga a interpretar, y aqui no sobra el sitio.

     `env(safe-area-inset-bottom)` es el hueco de la barra gestual de
     los telefonos sin boton de inicio. Sin ese relleno, la barra queda
     por debajo del indicador del sistema y se pulsa mal. */
  .flotantes {
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    gap: var(--e-2);
    padding: var(--e-2) var(--e-3);
    padding-bottom: calc(var(--e-2) + env(safe-area-inset-bottom, 0px));
    background: hsl(from var(--papel) h s l / .82);
    backdrop-filter: blur(16px) saturate(1.2);

    /* Sin filete. Una linea de un pixel corta la pantalla en dos y es
       justo lo que delata a una barra pegada encima; una sombra hacia
       arriba separa igual y deja que el contenido se desvanezca por
       debajo del cristal. */
    border-top: 0;
    box-shadow: 0 -1px 0 hsl(from var(--tinta) h s l / .06),
                0 -12px 28px hsl(from var(--tinta) h s l / .07);
  }

  /* Forma de pastilla y volumen propio.

     El sitio trabaja con `--radio-lg: 4px`, un radio casi recto que le
     va bien a tarjetas y paneles grandes: a ese tamano una esquina muy
     redondeada se lee como decoracion. Pero en un boton de 50 px de
     alto el mismo radio deja una caja practicamente cuadrada, y con un
     color plano y un filete de un pixel alrededor el resultado es el de
     un control de sistema operativo antiguo.

     Aqui van a pastilla completa. El radio deja de competir con nada
     porque iguala a la mitad del alto: la forma es la del propio boton,
     no una esquina recortada.

     El volumen lo dan tres capas y ninguna es un borde: una luz interior
     de un pixel arriba, que simula el canto iluminado; una sombra corta
     y opaca que lo asienta; y una larga y difusa, teñida del color del
     propio boton en vez de gris, que es lo que lo separa de la barra
     sin dibujar una linea. */
  .flotante--wa,
  .flotante--cotiza {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    gap: var(--e-2);
    width: auto;
    height: 50px;
    border: 0;
    border-radius: 999px;
    font-weight: 600;
    letter-spacing: .01em;
    transition: box-shadow 140ms ease-out, translate 140ms ease-out;
  }

  .flotante--wa {
    /* Degradado muy corto, de arriba abajo. No se busca un efecto:
       una superficie perfectamente plana a este tamaño se ve impresa,
       y dos tonos separados por un 8 % de luminosidad bastan para que
       parezca material. */
    /* El verde mas claro que admite el rotulo en BLANCO.

       Aqui hay un tira y afloja real, y conviene dejarlo escrito. El
       boton se pidio primero mas claro y luego mas claro todavia, hasta
       el 43,6 % de luminosidad (#15C966), que es practicamente el verde
       de marca de WhatsApp. Pero sobre ese tono el blanco mide 2,19:1 y
       no hay tamano de letra que lo arregle: el minimo mas permisivo de
       la norma es 3,0.

       Con el rotulo a 19 px en negrita —que es lo que rebaja el minimo
       de 4,5 a 3,0— el tono mas claro posible en blanco es el 34,8 % de
       luminosidad, que da 3,4:1. Se elige ese y no el que da 3,0 justo
       porque pasar por centesimas es no pasar: cualquier retoque
       posterior del degradado lo tumbaria.

       Queda mas apagado que el #15C966 anterior. Es el precio de las
       letras blancas, y son dos cosas que no pueden darse a la vez. */
    background: linear-gradient(180deg, #11A051 0%, #0E8A46 100%);
    color: #fff;
    box-shadow:
      inset 0 1px 0 hsl(0 0% 100% / .35),
      0 1px 2px hsl(147 65% 18% / .28),
      0 8px 20px hsl(147 72% 40% / .42);
  }

  .flotante--cotiza {
    background: linear-gradient(180deg, hsl(224 100% 48%) 0%, hsl(224 100% 35%) 100%);
    color: #fff;
    box-shadow:
      inset 0 1px 0 hsl(0 0% 100% / .25),
      0 1px 2px hsl(224 80% 15% / .3),
      0 8px 20px hsl(224 90% 33% / .4);
  }

  /* ---------- El pulso, adaptado a la pastilla ----------

     El aro de llamada estaba pensado para el disco de 52 px: un
     pseudoelemento con `border-radius: 50%` que crece con
     `transform: scale(1.55)`.

     Sobre una pastilla de 170x50 esas dos cosas fallan a la vez. El
     radio del 50 % en una caja rectangular no da un rectangulo
     redondeado, da una ELIPSE. Y `scale` multiplica los dos ejes por
     igual, asi que la elipse se estira otros 60 px a lo ancho por cada
     20 de alto: sale el ovalo desmesurado que rodeaba al boton.

     La forma correcta de expandir un contorno respetando la silueta es
     el `spread` de una sombra: crece el mismo numero de pixeles por los
     cuatro lados y sigue el radio del elemento, sea circulo, pastilla o
     rectangulo. Con el radio heredado, el pulso es una pastilla que se
     ensancha y se apaga, no un aro que se deforma.

     Se anima solo `box-shadow`, que el navegador resuelve al pintar sin
     rehacer la maquetacion. */
  .flotante--wa::after {
    border: 0;
    border-radius: inherit;
    animation: pulsoPastilla 3s ease-out infinite;
  }

  @keyframes pulsoPastilla {
    0%   { box-shadow: 0 0 0 0    hsl(147 81% 55% / .55); }
    65%  { box-shadow: 0 0 0 12px hsl(147 81% 55% / 0); }
    100% { box-shadow: 0 0 0 12px hsl(147 81% 55% / 0); }
  }

  /* Mientras se pulsa, el pulso se calla: dos movimientos a la vez en
     el mismo objeto se leen como un fallo. */
  .flotante--wa:active::after { animation: none; }

  /* Al pulsar se hunde: la sombra larga se recoge y el boton baja un
     pixel. Es la misma idea que el `active` del resto, pero aqui hace
     falta ademas apagar la sombra, o el boton pareceria flotar mientras
     se aplasta. */
  .flotante--wa:active,
  .flotante--cotiza:active {
    translate: 0 1px;
    box-shadow:
      inset 0 1px 0 hsl(0 0% 100% / .2),
      0 1px 3px hsl(224 80% 15% / .32);
  }

  /* 19 px y peso 700 no son una decision tipografica suelta: es lo que
     convierte al rotulo en «texto grande» a efectos de contraste y
     permite el verde claro del boton de WhatsApp. Por debajo de 18,66
     px en negrita, el minimo vuelve a 4,5 y ese verde ya no valdria.

     Se aplica a los dos botones para que la barra tenga una sola voz;
     el de cotizar va sobrado de contraste en cualquier caso. */
  .flotante__texto {
    display: inline;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: .01em;
  }

  .flotante--wa svg,
  .flotante--cotiza svg { width: 20px; height: 20px; }

  /* «Volver arriba» NO entra en la barra: aparece y desaparece segun el
     desplazamiento, y dentro de una fila haria saltar de sitio a los
     otros dos botones cada vez. Se queda como disco, flotando justo
     encima de la barra. */
  .flotante--arriba {
    position: absolute;
    right: var(--e-3);
    bottom: calc(100% + var(--e-2));
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    box-shadow: 0 1px 2px hsl(from var(--tinta) h s l / .12),
                0 8px 22px hsl(from var(--tinta) h s l / .16);
  }

  /* El contenido termina por encima de la barra. Sin esto, el pie de
     pagina queda debajo y sus enlaces son inalcanzables.

     Medido: la barra ocupa 65 px —48 de boton mas relleno y filete—,
     asi que 64 se quedaba corto por un pixel y el ultimo enlace del pie
     seguia debajo. Van 80 para dejar aire, no para ajustar. */
  body { padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }

  /* ---------- Menu en panel deslizante ----------
     Era un desplegable que empujaba el contenido hacia abajo: aparecia
     de golpe, sin transicion, y con la lista larga de servicios dejaba
     la pagina dando un salto.

     Como panel a pantalla completa gana tres cosas: entra con
     movimiento, asi que se entiende de donde sale; ocupa el alto
     disponible, de modo que los enlaces se reparten en objetivos
     grandes; y se puede cerrar tocando fuera. */
  .menu-movil {
    display: grid;
    position: fixed;
    inset: 0;
    z-index: 120;
    align-content: start;
    gap: 2px;
    padding: var(--e-3) var(--e-4);
    padding-top: calc(72px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(var(--e-6) + env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--papel);
    border-top: 0;

    /* Cerrado: fuera de la pantalla y sin recibir toques. La
       visibilidad se anima con retardo para que el panel no desaparezca
       antes de terminar de salir. */
    visibility: hidden;
    translate: 0 -100%;
    transition: translate var(--transicion), visibility 0s linear var(--transicion-ms, .28s);
  }

  .menu-movil[data-abierto] {
    visibility: visible;
    translate: 0 0;
    transition: translate var(--transicion), visibility 0s;
  }

  .menu-movil .menu__enlace { padding: var(--e-3) var(--e-3); min-height: 52px; }

  /* Con el panel abierto se congela el fondo. `position: fixed` sobre
     el cuerpo es lo unico que lo detiene de verdad en iOS; `overflow:
     hidden` alli no basta. */
  html[data-menu-abierto] body {
    position: fixed;
    inset: 0;
    width: 100%;
    overflow: hidden;
  }

  /* La barra inferior estorba con el menu abierto: son dos capas de
     navegacion a la vez. */
  html[data-menu-abierto] .flotantes { display: none; }

  /* La cabecera suelta su desenfoque mientras el menu esta abierto.

     No es estetica: `backdrop-filter` convierte al elemento en bloque
     contenedor de sus descendientes `position: fixed`. El panel vive
     dentro de la cabecera, asi que su `inset: 0` se resolvia contra
     ella y no contra la ventana: medido, quedaba en 390x120 en lugar de
     390x844, con los enlaces recortados dentro de una tira.

     Se declara por partida doble a proposito. `:has()` mira el estado
     real del panel y funciona aunque la marca de la raiz no llegue a
     ponerse; el atributo de la raiz cubre a los navegadores que aun no
     entienden `:has()`. Con el panel encima, el desenfoque de la
     cabecera no se ve de todos modos. */
  .cabecera:has(#menu-movil[data-abierto]),
  html[data-menu-abierto] .cabecera { backdrop-filter: none; }

  /* ---------- La pildora del hero, en dos lineas ----------
     En horizontal los dos oficios caben seguidos. En 390 px no: medido,
     la linea rompia sola y dejaba «AGENTE DE / CARGA» partido, con el
     punto de la segunda senal arriba y su texto abajo.

     Apilados, cada oficio ocupa su renglon con su punto a la izquierda,
     que es ademas como se leen: dos señales encendidas, una por cada
     cosa que hace la empresa.

     La pildora deja de ser una capsula y pasa a caja redondeada: un
     radio de 100 px sobre un bloque de dos lineas dibuja los laterales
     como semicirculos enormes y se come el espacio del texto. */
  .portada__ante {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .35em;
    border-radius: var(--radio-lg);
    padding: var(--e-3) var(--e-4);
    text-align: left;
  }

  /* ---------- Barra de progreso ----------
     Mas gruesa que en escritorio. A 3 px sobre una pantalla que se mira
     a un palmo, y sostenida en la mano, sencillamente no se ve. */
  .progreso { height: 4px; }

  /* ---------- Margenes seguros ----------
     Los telefonos con muesca recortan los bordes laterales en
     horizontal. El contenedor del sitio suma ese recorte a su margen
     propio para que ningun texto quede bajo la esquina redondeada. */
  .env {
    padding-left: max(var(--margen), env(safe-area-inset-left, 0px));
    padding-right: max(var(--margen), env(safe-area-inset-right, 0px));
  }

  @media (prefers-reduced-motion: reduce) {
    .menu-movil { transition: none; }
    .flotante--wa::after { animation: none; box-shadow: none; }
  }
}
