/* =========================================================
   Supply Chain de México — estilos personalizados
   Complementan al Tailwind compilado en build (public/css/tw-home.css).
   Aquí van: keyframes, overlay del hero, scroll-reveal, estado del nav.
   ========================================================= */

/* Fuentes auto-hospedadas (public/fonts/), variables de Google: cada woff2 cubre
   el eje de peso 100–900, así que un solo @font-face por familia sirve para los
   3 pesos que usa el sitio (antes: 2 saltos de red a fonts.googleapis.com /
   fonts.gstatic.com; ahora: 1 salto al propio dominio, con preload en el <head>). */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600 800;
  font-display: swap;
  src: url('../fonts/montserrat-latin-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/inter-latin-var.woff2') format('woff2');
}

:root {
  --brand-blue: #303E63;
  --brand-blue-dark: #232E4B;
  --brand-red: #BE4B48;
  --brand-red-dark: #A03B39;
  --brand-navy: #151E38;
  --brand-light: #F4F6FA;
  /* Azul del LOGO (muestreado del PNG oficial: #303E63) = base de toda la paleta */
  --logo-blue: #303E63;
  --bg-navy-rgb: 9, 17, 38;   /* #091126 — azul profundo (matiz del logo) para mayor contraste */
  --ease-out-soft: cubic-bezier(.22, 1, .36, 1);
}

/* ==========================================================
   Transición entre páginas (View Transitions nativas, MPA).
   Sin JS: funciona en cualquier navegación same-origin, incluido
   el home estático. Donde no hay soporte, la navegación es la
   normal de siempre (degradación silenciosa).
   Crossfade puro a propósito: el navegador aplica plus-lighter al
   par old/new, así que añadir desplazamiento daría bordes fantasma.
   DUPLICADO en src/styles/global.css: mantener sincronizado.
   ========================================================== */
@view-transition { navigation: auto; }

/* Las <img> van envueltas en <picture> para servir AVIF/WebP con fallback.
   display:contents saca al wrapper del layout, así la <img> sigue resolviendo
   h-full / absolute inset-0 contra el mismo contenedor que antes del cambio.
   Sin esto, `h-full` mediría contra un <picture> de altura automática. */
picture { display: contents; }

::view-transition-old(root) { animation: vt-fade-out .20s linear both; }
::view-transition-new(root) { animation: vt-fade-in .28s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes vt-fade-out { to   { opacity: 0; } }
@keyframes vt-fade-in  { from { opacity: 0; transform: scale(1.012); }
                         to   { opacity: 1; transform: scale(1); } }

/* El logo del header es el elemento compartido: se transforma de una
   página a otra en vez de desaparecer y reaparecer. */
.vt-logo { view-transition-name: site-logo; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  .vt-logo { view-transition-name: none; }
}

/* Tipografía base (también declarada en Tailwind) para evitar
   parpadeo si el CDN tarda en cargar (FOUC). */
/* El color del canvas: evita el destello BLANCO entre navegaciones y en el
   rebote de overscroll de iOS. Va detrás de .page-bg (z-index:-1). */
html { scroll-behavior: smooth; background-color: #080F26; }
body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: #1A2133;
  -webkit-font-smoothing: antialiased;
  background: transparent;
}

/* ==========================================================
   Fondo del sitio: gradiente azul del logo + UN spotlight.
   Sin patrones, sin objetos flotantes, sin blur: sólo luz.
   El gradiente base es ESTÁTICO; lo único que se mueve es la
   respiración lenta del haz (24 s).
   OJO: este bloque está DUPLICADO en src/styles/global.css.
   Si cambia aquí, cambia allá.
   ========================================================== */
.page-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  background:
    /* 2. Profundidad: el suelo se hunde en casi-negro azulado */
    radial-gradient(120% 78% at 50% 112%, rgba(4, 8, 20, .92), transparent 62%),
    /* 1. Cuerpo: familia del azul del logo (#303E63). Desciende de forma
       monótona: el punto más claro es ARRIBA, para que el haz mande.
       (El ancla terracota vive ahora en ::after, para poder respirar.) */
    linear-gradient(176deg, #0E1A40 0%, #101C44 20%, #0C1734 52%, #09122A 76%, #060A18 100%);
}

/* SPOTLIGHT: haz ancho y suave que ilumina la franja alta del viewport.
   Como .page-bg es fixed, cada sección pasa por debajo de la luz al subir
   a la parte alta de la pantalla. Núcleo brillante + lavado ancho = cono. */
.page-bg::before {
  content: '';
  position: absolute;
  top: -14vh;
  left: 50%;
  width: 170vw;
  height: 92vh;
  transform: translate3d(-50%, 0, 0);
  transform-origin: 50% 0%;
  background:
    /* núcleo del haz */
    radial-gradient(36% 76% at 50% 0%,
      rgba(170, 198, 255, .17) 0%,
      rgba(140, 172, 240, .10) 34%,
      rgba(104, 136, 210, .04) 58%,
      transparent 78%),
    /* lavado ancho: le da la forma de cono que se abre hacia abajo */
    radial-gradient(72% 100% at 50% -6%,
      rgba(104, 136, 210, .12) 0%,
      rgba(80, 108, 180, .05) 40%,
      rgba(58, 82, 148, .018) 66%,
      transparent 82%);
  will-change: opacity, transform;
  animation: spot-breathe 24s ease-in-out infinite;
}

/* Respiración de la luz: sólo opacity + transform (compositable).
   Amplitud deliberadamente baja: debe leerse como luz viva, nunca como objeto. */
@keyframes spot-breathe {
  0%, 100% { opacity: .88; transform: translate3d(-50%, 0, 0) scale(1); }
  50%      { opacity: 1;   transform: translate3d(-48.6%, 1.2vh, 0) scale(1.05); }
}

/* ANCLA TERRACOTA: el halo de marca vive en ::after para poder respirar
   en el compositor (SOLO transform + opacity). 18s alternate contra los
   24s del haz: nunca sincronizan (ciclo común 72s). Amplitud deliberada-
   mente corta: es una nota de color que respira, jamás un objeto.
   Duplicado en src/styles/global.css. */
.page-bg::after {
  content: '';
  position: absolute;
  right: -30vw;
  bottom: -30vh;
  width: 110vw;
  height: 100vh;
  background: radial-gradient(50% 42% at 72% 78%,
    rgba(190, 75, 72, .13), transparent 70%);
  opacity: .9;                 /* estado de reposo (reduced-motion) */
  transform-origin: 72% 78%;
  will-change: transform, opacity;
  animation: warm-breathe 18s ease-in-out infinite alternate;
}
@keyframes warm-breathe {
  from { opacity: .8; transform: scale(1); }
  to   { opacity: 1;  transform: scale(1.1); }
}

/* Grain sutil sobre el fondo: elimina el banding de los gradientes.
   Vive en z-index:-1 (después del .page-bg en el DOM) → nunca toca
   imágenes ni contenido. */
.page-grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

h1, h2, h3, .font-heading {
  font-family: 'Montserrat', system-ui, sans-serif;
}

/* ---------- Header / navegación ----------
   Barra BLANCA flotante con esquinas redondeadas; el azul del fondo se ve alrededor. */
#site-header {
  background: transparent;
  box-shadow: none;
  padding: 14px 16px 0;
  transition: box-shadow .3s ease;
}
#site-header > div {
  background-color: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 22px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .28);
  height: 5rem;
}
@media (min-width: 1024px) { #site-header > div { height: 5.5rem; } }
#site-header.nav-scrolled > div { box-shadow: 0 16px 40px rgba(0, 0, 0, .38); }
/* Enlaces e iconos en navy sobre la barra blanca */
#site-header .nav-link,
#site-header .brand-text { color: var(--brand-navy); }
#site-header #menu-toggle { color: var(--brand-navy); }
/* Logo vertical (original) a color, directo sobre el header blanco */
.brand-logo {
  height: 50px;
  width: auto;
  display: block;
}
@media (min-width: 1024px) { .brand-logo { height: 60px; } }
/* Footer (fondo navy): logo siempre en blanco */
/* Footer: mismo logo a color que el header */
.footer-logo {
  height: 92px;
  width: auto;
  display: block;
}
#site-header .nav-link {
  position: relative;
  transition: color .2s ease;
}
#site-header .nav-link::after {
  content: '';
  position: absolute;
  left: 0; bottom: -4px;
  width: 0; height: 2px;
  background: var(--brand-red);
  transition: width .25s ease;
}
#site-header .nav-link:hover::after { width: 100%; }

/* ---------- Hero (video de la operación + overlay moderado) ---------- */
/* El video se enmascara abajo para fundirse con el fondo general. El desplazamiento
   vertical sigue usando --hero-par, de modo que conserva el parallax existente. */
.hero-media {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  --hero-par: 0px;   /* punto de partida fiable para el scrub de GSAP */
  background: var(--bg-navy);
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}
.hero-video {
  position: absolute;
  inset: -6%;
  width: 112%;
  max-width: none; /* Evita que el reset de Tailwind lo limite y descubra el borde derecho. */
  height: 112%;
  display: block;
  object-fit: cover;
  object-position: center;
  filter: brightness(1.08) contrast(1.04) saturate(1.06);
  transform: translate3d(0, var(--hero-par, 0px), 0);
  scale: 1.06;
  animation: hero-kenburns 24s ease-in-out infinite alternate;
  will-change: transform, scale;
}
@keyframes hero-kenburns {
  from { scale: 1.06; }
  to   { scale: 1.16; }
}
/* Fuera de viewport (toggle por IntersectionObserver, §21 de main.js): el hero
   sigue con min-h-screen, así que casi siempre está visible al cargar, pero si
   el usuario se queda leyendo más abajo esto detiene el Ken Burns en CPU. */
.hero-media.anim-offscreen .hero-video { animation-play-state: paused; }
.hero-overlay {
  background: linear-gradient(100deg,
    rgba(var(--bg-navy-rgb), .82) 0%,
    rgba(var(--bg-navy-rgb), .63) 46%,
    rgba(var(--bg-navy-rgb), .38) 100%);
  /* Misma máscara: el overlay también se desvanece abajo → blend al .page-bg */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}

/* Video editorial sin texto, colocado después de Nuestra Operación. */
.operation-reel {
  position: relative;
}
.operation-reel__frame {
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 1.25rem;
  background: #050A18;
  box-shadow: 0 28px 70px rgba(0,0,0,.34);
}
.operation-reel__video {
  width: 100%;
  aspect-ratio: 16 / 9;
  display: block;
  object-fit: cover;
  object-position: center;
  transform: scale(1.015);
  background: #050A18;
}

.op-bg--dock { object-position: center 45%; }

/* ---------- Marquee de capacidades ---------- */
.marquee {
  display: flex;
  flex-direction: column;
  gap: 2.25rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.marquee__row { overflow: hidden; }
.marquee__track {
  display: flex;
  align-items: center;
  gap: 3.5rem;
  width: max-content;
  animation: mq-left 60s linear infinite;
}
.marquee__track--rev { animation-name: mq-right; animation-duration: 70s; }
/* Solo pausa al pasar el mouse en dispositivos con puntero real: en touch, un tap
   activa :hover sin un mouseout que lo quite después, y la animación se queda
   pausada para siempre tras el primer toque. */
@media (hover: hover) and (pointer: fine) {
  .marquee:hover .marquee__track { animation-play-state: paused; }
}
/* Fuera de viewport (toggle por IntersectionObserver, §21 de main.js): misma
   pausa que al pasar el mouse, para no gastar CPU con la sección fuera de vista. */
#clientes-alianzas.anim-offscreen .marquee__track { animation-play-state: paused; }
.marquee__item { flex: 0 0 auto; }
/* Logos de clientes a color sobre chip blanco (como estaba antes) */
.marquee__item img {
  height: 38px;
  width: auto;
  max-width: 150px;
  object-fit: contain;
  background: #ffffff;
  padding: 10px 16px;
  border-radius: 12px;
  box-shadow: 0 4px 14px rgba(0,0,0,.18);
  transition: transform .3s ease, box-shadow .3s ease;
}
.marquee__item img:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(0,0,0,.28); }
.marquee__capability {
  display: inline-flex;
  align-items: center;
  min-height: 58px;
  padding: 10px 22px;
  border: 1px solid rgba(27, 39, 71, .10);
  border-radius: 12px;
  background: #F4F6FA;
  color: #1B2747;
  box-shadow: 0 2px 8px rgba(27, 39, 71, .06);
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: .875rem;
  font-weight: 700;
  white-space: nowrap;
  transition: transform .3s ease, box-shadow .3s ease;
}
.marquee__capability:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(27, 39, 71, .16);
}
@keyframes mq-left  { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes mq-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@media (min-width: 1024px) { .marquee__item img { height: 46px; max-width: 180px; } }

/* ---------- Scroll reveal ---------- */
[data-reveal].reveal-pending {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .55s var(--ease-out-soft), transform .55s var(--ease-out-soft);
  transition-delay: var(--delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Respaldo de legibilidad: el contenido nunca debe depender de GSAP o de
   IntersectionObserver para poder leerse. `!important` también neutraliza
   estados inline incompletos si una animación externa falla a media carga. */
[data-reveal],
[data-reveal].reveal-pending,
.hero-title .wi,
.hl-h2 .h2l-in {
  opacity: 1 !important;
  transform: none !important;
}

/* ---------- Botón flotante de WhatsApp ---------- */
.wa-float {
  box-shadow: 0 8px 24px rgba(37, 211, 102, .45);
}
.wa-float::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background: #25D366;
  opacity: .6;
  z-index: -1;
  animation: wa-pulse 2.2s ease-out infinite;
}
@keyframes wa-pulse {
  0%   { transform: scale(1);   opacity: .55; }
  70%  { transform: scale(1.6); opacity: 0; }
  100% { transform: scale(1.6); opacity: 0; }
}

/* ---------- Tarjetas de servicio: icono cambia a rojo en hover ---------- */
.service-card:hover .service-icon {
  background-color: var(--brand-red);
  color: #ffffff;
}

/* ---------- Diferenciadores: borde rojo al hover ---------- */
.diferenciador-card:hover {
  border-color: rgba(190, 75, 72, 0.35);
}

/* ---------- Industrias: overlay gradient ---------- */
.industry-card .overlay-tag { transition: transform .3s ease; }
.industry-card:hover .overlay-tag { transform: translateY(-2px); }

/* Logos de clientes adaptados a las tarjetas de industria. */
.industry-brand {
  position: absolute;
  z-index: 2;
  top: auto;
  right: .85rem;
  bottom: .75rem;
  width: 7.75rem;
  min-width: 7.75rem;
  height: 2.75rem;
  padding: .42rem .7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  border: 1px solid rgba(255,255,255,.58);
  border-radius: .7rem;
  background: rgba(255,255,255,.94);
  box-shadow: 0 8px 22px rgba(5,10,24,.2);
  backdrop-filter: blur(8px);
}
.industry-brand img {
  display: block;
  width: auto;
  max-width: 6.5rem;
  max-height: 1.8rem;
  object-fit: contain;
}
.industry-brand--pair img { max-width: 3.25rem; max-height: 1.65rem; }
.industry-brand--square img { max-width: 2.4rem; max-height: 2.4rem; border-radius: 50%; }

/* (Los .trust-badge se definen más abajo, en el bloque de "sellos que se
   estampan": tenerlos declarados dos veces hacía competir dos transiciones.) */

/* ---------- Location cards (cobertura) ---------- */
.location-card { transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.location-card:hover { transform: translateY(-2px); }

/* ---------- Accesibilidad: skip link ---------- */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 100;
  background: var(--brand-navy);
  color: #fff;
  padding: .75rem 1.25rem;
  border-radius: 0 0 .5rem 0;
}
.skip-link:focus { left: 0; }

/* ==========================================================
   Mapa de cobertura — pines HTML proyectados sobre el SVG
   ========================================================== */
.mexico-map-wrapper {
  position: relative;
  width: 100%;
}
.mexico-map-wrapper > img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 16px;
  -webkit-user-drag: none;
  user-select: none;
}

/* Capa de líneas de flujo (HQ → cada pin) */
.map-flows {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.map-flow {
  stroke: var(--brand-red);
  stroke-width: 1.2;
  opacity: 0;
  stroke-dasharray: 6 6;
  stroke-linecap: round;
}
.map-in .map-flow {
  animation: flow-draw .9s ease-out forwards, flow-dash 1.1s linear infinite 1s;
  animation-delay: var(--flow-delay, 0ms), calc(var(--flow-delay, 0ms) + .9s);
}
@keyframes flow-draw {
  from { opacity: 0; }
  to   { opacity: .42; }
}
@keyframes flow-dash {
  to { stroke-dashoffset: -24; }
}

/* Capa de pines (HTML absoluto) */
.map-pins { position: absolute; inset: 0; }
.map-pin {
  position: absolute;
  width: 16px; height: 16px;
  margin: 0; padding: 0;
  transform: translate(-50%, -50%) scale(0);
  background: transparent; border: 0; cursor: pointer;
  opacity: 0;
}
.map-in .map-pin {
  animation: pin-pop .5s cubic-bezier(.34,1.56,.64,1) forwards;
  animation-delay: var(--pin-delay, 0ms);
}
@keyframes pin-pop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.map-pin-dot {
  position: absolute; inset: 4px;
  border-radius: 50%;
  background: var(--brand-red);
  box-shadow: 0 0 0 2px rgba(255,255,255,.85), 0 2px 6px rgba(0,0,0,.4);
  transition: transform .18s ease;
  z-index: 2;
}
.map-pin-ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid var(--brand-red);
  opacity: 0;
}
.map-in .map-pin-ring {
  animation: pin-radar 2.6s ease-out infinite;
  animation-delay: calc(var(--pin-delay, 0ms) + .5s);
}
/* Fuera de viewport (toggle por IntersectionObserver, §21 de main.js): pausa los
   11 anillos radar en loop cuando el mapa de cobertura no está en pantalla. */
#mexico-map.anim-offscreen .map-pin-ring { animation-play-state: paused; }
@keyframes pin-radar {
  0%   { opacity: .6; transform: scale(1); }
  70%  { opacity: 0;  transform: scale(2.6); }
  100% { opacity: 0;  transform: scale(2.6); }
}
.map-pin:hover .map-pin-dot,
.map-pin:focus-visible .map-pin-dot { transform: scale(1.4); }
.map-pin:focus-visible { outline: none; }

/* HQ (Querétaro): blanco con borde rojo + halo */
.map-pin-hq { width: 22px; height: 22px; z-index: 5; }
.map-pin-hq .map-pin-dot {
  inset: 5px;
  background: #fff;
  box-shadow: 0 0 0 3px var(--brand-red), 0 0 18px 4px rgba(190,75,72,.55);
}
.map-pin-hq .map-pin-ring { border-color: #fff; }

/* ---------- Map tooltip ---------- */
.map-tooltip {
  position: fixed;
  background: var(--brand-navy);
  color: #fff;
  font-size: .72rem;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 5px 12px;
  border-radius: 6px;
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .18s ease, transform .18s ease;
  border: 1px solid rgba(190, 75, 72, .45);
  z-index: 9999;
  box-shadow: 0 4px 16px rgba(0,0,0,.35);
}
.map-tooltip.visible {
  opacity: 1;
  transform: translateY(0);
}
.map-tooltip::after {
  content: '';
  position: absolute;
  bottom: -5px; left: 50%;
  transform: translateX(-50%);
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid var(--brand-navy);
}

/* ---------- Section label: línea roja animada ---------- */
.section-label {
  position: relative;
  display: inline-block;
}
.section-label::after {
  content: '';
  position: absolute;
  left: 0; bottom: -3px;
  height: 2px;
  width: 0;
  background: var(--brand-red);
  transition: width .55s cubic-bezier(.22,1,.36,1) .15s;
}
.section-label.is-visible::after { width: 100%; }

/* ---------- Cards "Por qué elegirnos": número decorativo ---------- */
.dif-card {
  position: relative;
  overflow: hidden;
}
.dif-number {
  position: absolute;
  top: -12px;
  right: 10px;
  font-size: 7rem;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 800;
  color: var(--brand-red);
  opacity: .07;
  line-height: 1;
  pointer-events: none;
  user-select: none;
  transition: opacity .3s ease;
}
.dif-card:hover .dif-number { opacity: .12; }

/* ---------- Certificaciones: sellos que se estampan ----------
   Aterrizan desde una escala mayor con una curva seca, uno tras otro,
   y a COLOR PLENO (antes se quedaban al 75% = descoloridos). */
.trust-badge {
  opacity: 0;
  transform: scale(1.14);
  transition: transform .42s cubic-bezier(.2, .9, .25, 1),
              opacity .28s ease-out;
}
.trust-badge.is-visible {
  opacity: 1;
  transform: scale(1);
}
.trust-badge.is-visible:hover {
  opacity: 1;
  transform: translateY(-3px);
}
/* Cascada de estampado: 70 ms por sello (0 → .42s) */
.trust-badge:nth-child(1) { transition-delay: 0s; }
.trust-badge:nth-child(2) { transition-delay: .07s; }
.trust-badge:nth-child(3) { transition-delay: .14s; }
.trust-badge:nth-child(4) { transition-delay: .21s; }
.trust-badge:nth-child(5) { transition-delay: .28s; }
.trust-badge:nth-child(6) { transition-delay: .35s; }
.trust-badge:nth-child(7) { transition-delay: .42s; }

/* ==========================================================
   FASE 3 — Fondo animado + Canvas partículas
   ========================================================== */

/* ---------- Stats section ---------- */
.stats-animated-bg {
  /* Transparente: deja ver el fondo global continuo (.page-bg) en vez de un azul propio */
  background: transparent !important;
}

/* Texto del hero por encima del overlay */
#inicio .relative.z-10 { z-index: 10; }

/* ---------- Nosotros: foto lateral ---------- */
.nosotros-photo {
  border-radius: 1rem;
  overflow: hidden;
  min-height: 400px;
}
.nosotros-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* #nosotros con foto de fondo ligeramente difuminada y bordes fundidos.
   La máscara vive en el CONTENEDOR para que el fundido no se mueva. */
.nosotros-bg {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
}
.nosotros-bg img {
  filter: blur(3px);
  transform: scale(1.06);            /* evita bordes vacíos por el blur */
  object-position: center 42%;       /* mantiene visibles los rostros del equipo */
}
/* Clientes: foto de logística de fondo con bordes difuminados (sin división) */
.clientes-bg {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
}
.clientes-bg img {
  --par: 0px;        /* punto de partida fiable para el scrub de GSAP */
  filter: blur(2px);
  /* Parallax por variable (--par la fija JS) + sobre-escala para el blur y el recorrido */
  transform: translate3d(0, var(--par, 0px), 0) scale(1.12);
  will-change: transform;
}

/* Tarjetas en vidrio NAVY (mismo color que el fondo de la foto) */
#nosotros .dif-card {
  background: rgba(var(--bg-navy-rgb), .58) !important;
  border-color: rgba(255,255,255,0.16) !important;
}

/* ---------- Trust logos: solo imágenes, sin cuadros de color ---------- */
.trust-logo-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 74px;
  width: 100% !important;
  max-width: 210px;
  padding: 10px 18px;
  background: #fff;
  border-radius: 10px;
  border: 1px solid rgba(21,30,56,.08);
  box-shadow: 0 2px 8px rgba(0,0,0,.06);
  transition: box-shadow .2s ease, transform .2s ease;
}
.trust-badge:hover .trust-logo-wrap {
  box-shadow: 0 6px 20px rgba(0,0,0,.12);
  transform: translateY(-2px);
}
/* Refuerzo explícito: el cliente reportó el fondo de C-TPAT distinto al de ISO 9001.
   Por especificidad de ID, esta regla gana sobre cualquier otra que toque
   .trust-logo-wrap (incluida html.dark #clientes-alianzas .trust-logo-wrap más abajo
   en este archivo), así que queda garantizado #fff pase lo que pase en la cascada. */
#trust-logo-ctpat { background: #fff !important; }
/* Golpe del estampado: la sombra se asienta al aterrizar el sello */
.trust-badge.is-visible .trust-logo-wrap {
  box-shadow: 0 8px 22px rgba(0, 0, 0, .18);
}
.trust-logo-wrap img {
  max-height: 56px;
  max-width: 170px;
  width: auto;
  object-fit: contain;
}

.trust-grid .trust-badge {
  min-height: 170px;
  padding: 1.5rem 1.25rem;
  justify-content: center;
  border: 1px solid rgba(27,39,71,.1);
  border-radius: 1rem;
  background: rgba(244,246,250,.72);
  box-shadow: 0 10px 28px rgba(27,39,71,.08);
}
.trust-grid .trust-badge > p { max-width: 18rem; line-height: 1.45; }

/* El logo oficial de Supply Chain Worldwide usa blanco y verde, por lo que
   conserva su fondo corporativo oscuro dentro de la fila de alianzas. */
.trust-logo-wrap--scww {
  background: #FFFFFF;
}
.trust-logo-wrap--scww img {
  max-height: 52px;
  max-width: 150px;
}

/* ==========================================================
   FASE 5 — Gradiente líquido (mesh) en secciones blancas
   ========================================================== */

/* Fondo de gradiente líquido animado: dos capas de gradientes
   radiales sobreescaladas que rotan en sentidos opuestos →
   color suave que fluye sin parar. Tints muy bajos: el texto
   sobre blanco/brand-light permanece legible. */
/* (El antiguo .mesh-bg por sección se eliminó: el fondo ahora es global
   y continuo vía .page-bg. La clase .mesh-bg ya no se usa en el HTML.) */

/* ---------- Nueva sección transporte: cards foto-overlay ---------- */
.transport-card { cursor: default; }
.transport-card img { transition: transform 0.7s cubic-bezier(.22,1,.36,1); }
.transport-card:hover img { transform: scale(1.06); }

/* ==========================================================
   Sección "Nuestra Operación" — bloques con FOTO DE FONDO
   (texto encima, overlay direccional translúcido)
   ========================================================== */

/* ==========================================================
   Línea de proceso: raíl vertical que se dibuja con el scroll
   + nodos numerados que se encienden al entrar cada bloque.
   El canalón se crea con padding-left en el propio stack; las
   3 variables de abajo son el ÚNICO sitio donde se ajusta la
   geometría (canalón, posición del raíl y tamaño del nodo).
   ========================================================== */
.op-stack {
  --op-gutter: 2.5rem;    /* ancho del canalón izquierdo */
  --op-spine-x: .875rem;  /* centro del raíl, desde el borde del stack */
  --op-node: 1.75rem;     /* diámetro del nodo */
  position: relative;
  padding-left: var(--op-gutter);
}
@media (min-width: 1024px) {
  .op-stack { --op-gutter: 4rem; --op-spine-x: 1.5rem; --op-node: 2.5rem; }
}

.op-spine {
  position: absolute;
  left: var(--op-spine-x);
  top: 0; bottom: 0;
  width: 2px;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, .13);
  border-radius: 2px;
}
.op-spine__fill {
  position: absolute;
  inset: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--brand-red), #D2625E);
  box-shadow: 0 0 12px rgba(190, 75, 72, .45);
  transform-origin: 50% 0;
  /* Por defecto DIBUJADA: sin JS, sin GSAP o con reduced-motion se ve completa. */
  transform: scaleY(1);
}

/* Nodo numerado: pseudo-elemento del bloque → se auto-posiciona con él
   (los bloques tienen alturas distintas) y no altera su caja ni su área
   visible para el IntersectionObserver. */
.op-block::before {
  content: attr(data-step);
  position: absolute;
  left: calc(var(--op-spine-x) - var(--op-node) / 2 - var(--op-gutter));
  top: 50%;
  transform: translateY(-50%);
  width: var(--op-node);
  height: var(--op-node);
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 800;
  font-size: .7rem;
  color: rgba(255, 255, 255, .55);
  background: #0B1330;                        /* opaco: tapa el raíl por detrás */
  border: 2px solid rgba(255, 255, 255, .16);
  transition: background-color .5s var(--ease-out-soft),
              border-color .5s var(--ease-out-soft),
              color .5s var(--ease-out-soft),
              box-shadow .5s var(--ease-out-soft);
}
@media (min-width: 1024px) { .op-block::before { font-size: .82rem; } }

/* Se enciende con la MISMA clase que ya usan clip-reveal y check-draw:
   la añaden tanto el batch de GSAP como el IntersectionObserver de respaldo. */
.op-block.is-visible::before {
  background: var(--brand-red);
  border-color: #D2625E;
  color: #fff;
  box-shadow: 0 0 0 4px rgba(190, 75, 72, .18), 0 0 18px rgba(190, 75, 72, .45);
}

/* El clip vive en .op-clip (wrapper interno), NUNCA en el propio .op-block:
   Chromium calcula área visible cero para elementos con clip-path total y el
   IntersectionObserver del reveal jamás dispararía. */
.op-clip {
  min-height: 460px;
  clip-path: inset(0 100% 0 0 round 16px);
  will-change: clip-path;
}
.op-block--r .op-clip { clip-path: inset(0 0 0 100% round 16px); }
.op-block.is-visible .op-clip {
  animation: clip-reveal 1s var(--ease-out-soft) .05s forwards;
}
@keyframes clip-reveal {
  to { clip-path: inset(0 0 0 0 round 16px); }
}

/* Foto de fondo: el parallax con scrub lo conduce GSAP (main.js §20c).
   No declarar aquí transform ni transition: perseguirían al scrub. */

/* Overlay direccional: fuerte del lado del texto → translúcido del lado
   abierto, para que la foto SE VEA pero el texto lea perfecto. */
.op-overlay {
  background: linear-gradient(90deg,
    rgba(var(--bg-navy-rgb), .94) 0%,
    rgba(var(--bg-navy-rgb), .82) 34%,
    rgba(var(--bg-navy-rgb), .38) 66%,
    rgba(var(--bg-navy-rgb), .14) 100%);
}
.op-block--r .op-overlay {
  background: linear-gradient(270deg,
    rgba(var(--bg-navy-rgb), .94) 0%,
    rgba(var(--bg-navy-rgb), .82) 34%,
    rgba(var(--bg-navy-rgb), .38) 66%,
    rgba(var(--bg-navy-rgb), .14) 100%);
}
/* Móvil: overlay vertical (texto legible a todo lo ancho) */
@media (max-width: 1023px) {
  .op-clip { min-height: 0; }
  .op-overlay, .op-block--r .op-overlay {
    background: linear-gradient(180deg,
      rgba(var(--bg-navy-rgb), .60) 0%,
      rgba(var(--bg-navy-rgb), .88) 100%);
  }
}

/* Bullets: palomita que se dibuja en cascada */
.op-check path {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
}
.op-block.is-visible .op-check path {
  animation: check-draw .45s ease-out forwards;
  animation-delay: var(--cd, .5s);
}
@keyframes check-draw { to { stroke-dashoffset: 0; } }

/* ==========================================================
   FASE 7 — Botón toggle de tema + Modo oscuro (overrides)
   ========================================================== */

/* (Modo oscuro eliminado: tema azul único. El toggle ya no existe.) */

/* --- Tema base (texto claro, tarjetas oscuras) sobre el fondo azul --- */
html.dark body { background: transparent; color: #C7CEE0; }
/* Liquid glass: tarjetas/superficies translúcidas con desenfoque */
html.dark .bg-white {
  background-color: rgba(255,255,255,0.09) !important;
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
}
html.dark .bg-brand-light {
  background-color: rgba(255,255,255,0.07) !important;
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
}
/* Secciones del cuerpo transparentes → se ve el fondo azul continuo */
#servicios, #soluciones-transporte, #nosotros, #stats, #cobertura,
#industrias, #clientes, #cta-final { background: transparent !important; }
.stats-animated-bg { background: transparent !important; animation: none !important; }
/* Nosotros y Clientes llevan foto de fondo con overlay azul del logo +
   máscaras para fundirse sin cortes con el fondo continuo. Stats lleva la
   red logística SVG (.stats-net) como fondo. */

/* ==========================================================
   RED LOGÍSTICA = lienzo de todo el sitio.
   Antes vivía dentro de #stats (una sola banda). Ahora es una
   capa fixed detrás de TODO, en el home y en las 42 internas.
   Los valores (color, grosor, opacidad) son los MISMOS de la
   banda de cifras: es la referencia que aprobó el usuario.
   Geometría: cada tile mide 33.34% de alto y como mínimo
   1280px de ancho. La relación alto/ancho tiene que quedar
   POR DEBAJO de 420/1440 = .2917 para que `slice` recorte en
   VERTICAL (se come los márgenes vacíos del motivo) en vez de
   en horizontal (que dejaría bandas muertas en las juntas).
   DUPLICADO en src/styles/global.css: mantener sincronizado.
   ========================================================== */
.net-bg {
  position: fixed;
  inset: 0;
  z-index: -1;              /* mismo plano que .page-bg; pinta después por orden de DOM */
  pointer-events: none;
  overflow: hidden;         /* recorta el ancho mínimo en móvil → cero scroll lateral */
  transform: translateZ(0); /* capa compositada propia: el repintado del guion
                               no invalida la página y el scroll no la re-rasteriza */
  backface-visibility: hidden;
}
.net-tile {
  position: absolute;
  left: 50%;
  display: block;
  width: 100%;
  width: max(100%, 1280px);  /* el min-width mantiene el aspecto bajo el umbral en móvil */
  height: 33.34%;            /* .34 y no .33: evita costuras de subpíxel */
  transform: translateX(-50%);
}
.net-tile:nth-child(1) { top: 0; }
.net-tile:nth-child(2) { top: 33.33%; transform: translateX(-50%) scaleY(-1); }
.net-tile:nth-child(3) { top: 66.66%; transform: translateX(-50%) scaleX(-1); }

.net-line {
  fill: none;
  stroke: rgba(125, 152, 225, .24);
  stroke-width: 1.3;
  stroke-dasharray: 7 7;
  stroke-linecap: round;
  animation: net-dash 1.633s linear infinite;
}
.net-node { fill: rgba(125, 152, 225, .5); }
.net-node--hub { fill: rgba(190, 75, 72, .65); }
.net-particle {
  fill: #D2625E;   /* terracota del logo, cálido */
  opacity: .85;
  filter: drop-shadow(0 0 5px rgba(210, 98, 94, .8));
}
/* 28 = 2×(7+7): bucle EXACTO. El viejo flow-dash iba a -24 con dasharray
   7 7 → 1.71 periodos = un salto cada 1.4s (imperceptible de pasada, un tic
   como fondo permanente). 1.633s conserva la MISMA velocidad lineal
   (24/1.4 = 28/1.633 = 17.14 u/s). flow-dash se queda intacto para .map-flow. */
@keyframes net-dash { to { stroke-dashoffset: -28; } }
/* En móvil sólo el primer tile lleva partículas: 5 en vez de 15. */
@media (max-width: 640px) { .net-tile:nth-child(n+2) .net-particle { display: none; } }
.stats-panel {
  position: relative;
  z-index: 10;
  padding: 1.75rem 1.25rem;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 22px;
  background: rgba(var(--bg-navy-rgb), .88);
  box-shadow: 0 18px 45px rgba(0,0,0,.28);
  -webkit-backdrop-filter: blur(18px) saturate(125%);
          backdrop-filter: blur(18px) saturate(125%);
}
.stat-item {
  padding: .75rem;
}

/* Mapa de cobertura: panel oscuro translúcido para que resalte sobre el azul */
/* Footer en glass BLANCO igual que el header (el logo a color resalta igual de bien) */
.footer-glass {
  background: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
          backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 22px;
  box-shadow: 0 12px 34px rgba(0,0,0,.28);
}
/* Texto oscuro sobre el glass blanco (gana al tema oscuro global) */
.footer-glass p,
.footer-glass li,
.footer-glass a,
.footer-glass span { color: #3B445B !important; }
.footer-glass h3 { color: var(--brand-navy) !important; }
.footer-glass a:hover { color: var(--brand-red) !important; }
.footer-glass .border-t { border-color: rgba(21,30,56,.14) !important; }
.contact-map-photo img {
  height: 15rem;
  object-position: center 58%;
}
@media (min-width: 1024px) {
  .contact-map-photo img { height: 17rem; }
}
.quote-details summary::-webkit-details-marker { display: none; }
.quote-details summary {
  position: relative;
  padding-right: 3rem;
}
.quote-details summary::after {
  content: "+";
  position: absolute;
  right: 1rem;
  top: 1.15rem;
  width: 1.65rem;
  height: 1.65rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--brand-red);
  color: #fff;
  font-family: var(--font-heading);
  font-weight: 800;
  line-height: 1;
}
.quote-details[open] summary::after { content: "−"; }
.quote-details__body {
  border-top: 1px solid rgba(27,39,71,.10);
}
/* Botones sociales sobre fondo claro */
/* ---------- Redes sociales ----------
   Sobre el lienzo azul van en TERRACOTA MACIZO: es el único acento sólido
   del tema oscuro, por eso se ve al primer golpe de vista. #D2625E es el
   mismo terracota de las partículas de la red del fondo → rima visual.
   Glifo navy sobre terracota = 4.91:1; chip contra el lienzo = 4.75:1
   (WCAG 1.4.11 pide 3:1 para UI no textual).
   DUPLICADO en src/styles/global.css: mantener sincronizado. */
.social-chip {
  background: var(--brand-red);
  color: #FFFFFF;
  border: 1px solid #8A3230;
  transition: background-color .22s ease, color .22s ease, transform .22s ease;
}
.social-chip:hover,
.social-chip:focus-visible {
  background: var(--brand-red);   /* #BE4B48 */
  color: #FFFFFF;
  transform: translateY(-2px);
}

/* Todos los medios de contacto comparten el rojo de los iconos del footer. */
.contact-icon {
  background: var(--brand-red);
  color: #FFFFFF;
  border: 1px solid #8A3230;
}

/* Botones sociales del footer: sobre el glass BLANCO, así que el terracota
   profundo (#BE4B48) es el que lee; el filete #8A3230 le da borde contra el
   panel claro. Blanco sobre #BE4B48 = 4.90:1. El !important del color es
   obligatorio: `.footer-glass a { color:#3B445B !important }` gana si no. */
.footer-glass .footer-social {
  background: var(--brand-red);
  color: #FFFFFF !important;
  border: 1px solid #8A3230;
  transition: background-color .22s ease, transform .22s ease;
}
.footer-glass .footer-social:hover,
.footer-glass .footer-social:focus-visible {
  background: var(--brand-red-dark) !important;   /* #A03B39 */
  color: #FFFFFF !important;
  transform: translateY(-2px);
}

/* Panel oscuro detrás del mapa (en un wrapper aparte para NO desfasar los pines).
   Fondo SÓLIDO (no translúcido): el spotlight/halo animado de .page-bg no debe
   filtrarse a través del panel y confundirse con el mapa. */
.map-panel {
  background: rgb(var(--bg-navy-rgb));
  border-radius: 22px;
  padding: 1rem 1.25rem;
  box-shadow: 0 12px 40px rgba(0,0,0,.3);
  overflow: hidden;
}
/* #mexico-map: contiene img + pines en la MISMA caja (sin padding) → alineados */

/* Cobertura: mapa y listado a la par. Lerma abre el listado como sede destacada;
   las otras 12 ubicaciones forman pares completos, sin tarjeta huérfana. */
.coverage-layout {
  display: grid;
  gap: 1.5rem;
  align-items: stretch;
}
.coverage-map,
.coverage-list {
  min-width: 0;
}
.coverage-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .65rem;
  align-content: start;
}
.location-card--principal {
  grid-column: 1 / -1;
  min-height: 170px;
  padding: 1.5rem;
  background:
    linear-gradient(135deg, rgba(190,75,72,.34), rgba(190,75,72,.14)),
    rgba(255,255,255,.08);
  border: 2px solid rgba(210, 98, 94, .9);
  box-shadow: 0 18px 38px rgba(0,0,0,.28);
}
.location-card--standard {
  min-height: 88px;
  padding: .75rem .6rem;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.12);
}
@media (min-width: 1024px) {
  .coverage-layout {
    grid-template-columns: minmax(0, 1.2fr) minmax(360px, .8fr);
  }
  .map-panel {
    height: 100%;
    display: flex;
    align-items: center;
  }
}
@media (max-width: 639px) {
  .coverage-list { grid-template-columns: 1fr; }
  .location-card--principal { grid-column: auto; }
}

/* ==========================================================
   Filtro de ubicación (cobertura): aislar un solo pin+tarjeta
   ========================================================== */
.location-card,
.map-pin { -webkit-tap-highlight-color: transparent; }

/* Pines y rutas: elementos posicionados en absoluto → se pueden desvanecer
   sin afectar el layout. !important es obligatorio: .map-in .map-pin y
   .map-in .map-flow corren una animación con fill:forwards que, en la
   cascada, gana a una regla normal — sin !important el pin/ruta "reaparece"
   en cuanto termina la transición de ocultamiento. */
.map-pin--hidden {
  opacity: 0 !important;
  transform: translate(-50%, -50%) scale(.4) !important;
  pointer-events: none;
  transition: opacity .22s ease, transform .22s ease;
}
.map-pin--selected .map-pin-dot { transform: scale(1.3); }

.map-route--hidden {
  opacity: 0 !important;
  transition: opacity .2s ease;
}

/* Tarjetas: display:none (sin transición) — a diferencia de los pines, viven
   en un CSS grid; si solo se atenuara la opacidad, la sobreviviente dejaría
   un hueco vacío al lado en vez de ocupar la fila. */
.location-card--hidden { display: none; }
.coverage-list--filtered .location-card:not(.location-card--hidden) {
  grid-column: 1 / -1;
}
.location-card--selected {
  border-color: #fff;
  box-shadow: 0 12px 28px rgba(0,0,0,.35), 0 0 0 2px rgba(255,255,255,.5);
}
.location-card--principal:hover,
.location-card--principal:focus-visible {
  border-color: #fff;
  box-shadow: 0 22px 46px rgba(0,0,0,.32), 0 0 0 2px rgba(255,255,255,.35);
}

/* Botón "ver todas": visible solo con filtro activo. */
.coverage-reset-btn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: #fff;
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.25);
  border-radius: 999px;
  padding: .5rem 1.1rem;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 700;
  font-size: .8rem;
  letter-spacing: .02em;
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, transform .2s ease;
}
.coverage-reset-btn:hover,
.coverage-reset-btn:focus-visible {
  background: rgba(255,255,255,.18);
  border-color: var(--brand-red);
  transform: translateY(-1px);
}
.coverage-reset-btn[hidden] { display: none; }

/* Utilidad de accesibilidad: visualmente oculto, disponible para lectores
   de pantalla (no existe sr-only compilado en tw-home.css hoy). */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Servicios: 4 tarjetas en flex centrado → una sola fila llena a ≥1024px
   (25% cada una + 3 gaps de 24px = 100%), y 2+2 en el rango 640-1023px. */
#servicios .service-card { width: 100%; }
@media (min-width: 640px)  { #servicios .service-card { width: calc(50% - 12px); } }
@media (min-width: 1024px) { #servicios .service-card { width: calc(25% - 18px); } }

/* Header: el azul de marca aplica en ambos modos (ver bloque base #site-header).
   No se sobreescribe el fondo en dark; el logo/nav/iconos ya van a color/blanco. */
html.dark #mobile-menu { background: #1B2747; border-color: rgba(255,255,255,.08); }
html.dark #mobile-menu a { color: #E6EDF6 !important; border-color: rgba(255,255,255,.07) !important; }

/* --- Texto: oscuro → claro --- */
html.dark .text-brand-navy { color: #EAEEF9 !important; }
html.dark .text-brand-charcoal,
html.dark [class*="text-brand-charcoal/"] { color: #BFC9D8 !important; }

/* --- Bordes --- */
html.dark [class*="border-brand-gray-soft"],
html.dark [class*="border-brand-light"] { border-color: rgba(255,255,255,.10) !important; }

/* --- Componentes "liquid glass" (vidrio translúcido) --- */
html.dark .service-card,
html.dark .dif-card,
html.dark .industry-card,
html.dark .op-card,
html.dark form#contact-form {
  background-color: rgba(255,255,255,0.09) !important;
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.16) !important;
}
html.dark .location-card { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
html.dark input,
html.dark textarea,
html.dark select {
  background-color: rgba(255,255,255,0.06) !important;
  color: #EAF1F9 !important;
  border-color: rgba(255,255,255,.20) !important;
}
html.dark input::placeholder,
html.dark textarea::placeholder { color: #6F7E8F !important; }
html.dark .quote-details {
  background-color: rgba(255,255,255,.06) !important;
  border-color: rgba(255,255,255,.16) !important;
}
html.dark .quote-details__body {
  border-top-color: rgba(255,255,255,.10) !important;
}
/* Chips de logos de certificación: se mantienen claros para que los logos lean */
html.dark .trust-logo-wrap { background: #F1F4F8; }
/* Sombras un poco más profundas en oscuro */
html.dark .shadow-lg, html.dark .shadow-md, html.dark .shadow-xl { box-shadow: 0 10px 30px rgba(0,0,0,.5) !important; }

/* Mapa: en oscuro el SVG navy ya combina; el contenedor mantiene su sección navy */

/* ---------- Respeta usuarios con movimiento reducido ---------- */
/* ==========================================================
   FASE 14 — Animaciones nuevas (hero, hover de tarjetas, brillo CTA)
   ========================================================== */

/* Hero: indicador de scroll (chevron con rebote) */
.hero-scroll {
  position: absolute;
  bottom: 22px; left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  color: #fff;
  opacity: .85;
  animation: hero-bounce 1.8s ease-in-out infinite;
}
.hero-scroll:hover { opacity: 1; }
@keyframes hero-bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(8px); }
}

/* Hero: entrada del texto más marcada (slide más largo) */
#inicio [data-reveal] { transform: translateY(44px); transition-duration: .85s; }
#inicio [data-reveal].is-visible { transform: translateY(0); }

/* Hero: reveal del H1 palabra por palabra con máscara (estilo editorial).
   JS envuelve cada palabra en .w > .wi; sin JS el H1 queda estático visible. */
.hero-title .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: .08em;   /* evita cortar descendentes (g, y, j) */
  margin-bottom: -.08em;
}
.hero-title .wi {
  display: inline-block;
  transform: translateY(112%);
  animation: word-up .75s var(--ease-out-soft) forwards;
  animation-delay: var(--wd, 0ms);
}
@keyframes word-up { to { transform: translateY(0); } }

/* H2 de sección: reveal línea a línea con máscara (main.js §20f).
   El estado oculto lo pone SOLO GSAP (yPercent): sin GSAP no hay split y
   el h2 queda estático — nunca texto invisible. El h2 se vuelve columna
   flex mientras está partido para que los márgenes negativos de las
   máscaras no colapsen (net-cero exacto, sin saltos de layout). */
.hl-h2.is-split { display: flex; flex-direction: column; }
.h2l {
  overflow: hidden;
  padding: .12em 0;      /* aire para descendentes/ascendentes con line-height compacto */
  margin: -.12em 0;
}
.h2l-in { display: block; }

/* Barra roja superior de las service cards: se dibuja de izquierda a
   derecha DESPUÉS de que aterrice la cortina de la foto (la barra vive
   dentro del contenedor clipado; antes de .45s la taparía la cortina). */
.card-bar {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .6s var(--ease-out-soft) .45s;
}
.service-card.is-visible .card-bar { transform: scaleX(1); }

/* Tarjetas de transporte: cortina direccional alternada (1,3: izq→der;
   2,4: der→izq). El clip vive en el wrapper interno .transport-clip,
   NUNCA en el propio article[data-reveal] (trampa de área cero del
   IntersectionObserver — mismo patrón que .op-clip). Reusa el keyframe
   clip-reveal: sólo declara `to`, sirve para ambas direcciones, y su
   radio 16px coincide con rounded-2xl. */
.transport-clip {
  clip-path: inset(0 100% 0 0 round 16px);
  will-change: clip-path;
}
.transport-card:nth-of-type(even) .transport-clip {
  clip-path: inset(0 0 0 100% round 16px);
}
.transport-card.is-visible .transport-clip {
  animation: clip-reveal 1s var(--ease-out-soft) .05s forwards;
}

/* Hero: subrayado rojo que se dibuja bajo la frase clave */
.hero-hl {
  background-image: linear-gradient(90deg, rgba(190,75,72,.9), rgba(190,75,72,.9));
  background-repeat: no-repeat;
  background-position: 0 94%;
  background-size: 0% .09em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
  animation: hl-draw .9s var(--ease-out-soft) 1.2s forwards;
}
@keyframes hl-draw { to { background-size: 100% .09em; } }

/* Hover unificado en tarjetas: elevación + brillo (sobre el glass) */
.service-card, .dif-card, .industry-card, .transport-card, .location-card {
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.service-card:hover, .dif-card:hover, .industry-card:hover, .transport-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 20px 44px rgba(0,0,0,.38), 0 0 0 1px rgba(125,149,217,.55);
}
.location-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 28px rgba(0,0,0,.35), 0 0 0 1px rgba(190,75,72,.5);
}

/* ==========================================================
   Micro-interacciones premium
   ========================================================== */

/* Barra de progreso de lectura (JS fija --sp entre 0 y 1) */
#scroll-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 3px;
  z-index: 60;
  background: linear-gradient(90deg, var(--brand-red), #D2625E);
  transform: scaleX(var(--sp, 0));
  transform-origin: 0 50%;
  pointer-events: none;
}

/* Header fijo: siempre visible, solo se compacta al hacer scroll.
   Ya no se oculta al bajar (se retiró .nav-hidden junto con su lógica en main.js §1). */
#site-header {
  transition: box-shadow .3s ease;
}
#site-header > div { transition: height .3s ease, box-shadow .3s ease; }
#site-header.nav-scrolled > div { height: 4.25rem; }
@media (min-width: 1024px) { #site-header.nav-scrolled > div { height: 4.75rem; } }
.brand-logo { transition: height .3s ease; }
#site-header.nav-scrolled .brand-logo { height: 42px; }
@media (min-width: 1024px) { #site-header.nav-scrolled .brand-logo { height: 50px; } }

/* Scrollspy: enlace de la sección visible queda marcado */
#site-header .nav-link.active { color: var(--brand-red); }
#site-header .nav-link.active::after { width: 100%; }

/* Spotlight en tarjetas: luz radial que sigue al cursor (JS fija --mx/--my) */
.service-card, .industry-card { position: relative; }
.service-card::after,
.dif-card::after,
.industry-card::after,
.transport-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity .35s ease;
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgba(125, 152, 225, .18), transparent 65%);
}
.service-card:hover::after,
.dif-card:hover::after,
.industry-card:hover::after,
.transport-card:hover::after { opacity: 1; }

/* Flechas de CTA que avanzan al hover */
.cta-arrow { transition: transform .25s var(--ease-out-soft); }
a:hover .cta-arrow,
button:hover .cta-arrow { transform: translateX(4px); }

/* Botones magnéticos (JS mueve el transform; aquí solo el retorno suave) */
.magnetic { transition: transform .2s ease-out; will-change: transform; }

/* Contadores odómetro: dígitos que ruedan verticalmente */
.odo-digit {
  display: inline-block;
  height: 1em;
  line-height: 1em;
  overflow: hidden;
  /* inline-block con overflow hidden asienta su caja en el baseline:
     se compensa el descenso para alinear con los sufijos (+, %, /7) */
  vertical-align: -0.15em;
}
.odo-col {
  display: block;
  transition: transform 1.6s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--od, 0ms);
}
.odo-col > span {
  display: block;
  height: 1em;
  line-height: 1em;
}

/* Mapa: partículas de luz que viajan del HQ a cada pin */
.map-particle {
  fill: #fff;
  opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255, 255, 255, .9));
}
.map-in .map-particle { opacity: .9; }
/* HQ: glow rojo pulsante más intenso */
.map-in .map-pin-hq .map-pin-dot { animation: hq-glow 2.6s ease-in-out infinite; }
@keyframes hq-glow {
  0%, 100% { box-shadow: 0 0 0 3px var(--brand-red), 0 0 14px 3px rgba(190,75,72,.45); }
  50%      { box-shadow: 0 0 0 3px var(--brand-red), 0 0 26px 8px rgba(190,75,72,.8); }
}

/* Imágenes de tarjetas: reveal en cortina al entrar en viewport */
.service-card > div:first-child,
.industry-card > div:first-child {
  clip-path: inset(0 100% 0 0);
}
.service-card.is-visible > div:first-child,
.industry-card.is-visible > div:first-child {
  animation: clip-reveal-sq .8s var(--ease-out-soft) .15s forwards;
}
@keyframes clip-reveal-sq { to { clip-path: inset(0 0 0 0); } }

/* Botones CTA: destello (sweep) que recorre al hover */
.btn-shine { position: relative; overflow: hidden; }
.btn-shine::after {
  content: '';
  position: absolute;
  top: 0; left: -130%;
  width: 55%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.45), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
}
.btn-shine:hover::after { animation: btn-sweep .8s ease; }
@keyframes btn-sweep { from { left: -130%; } to { left: 140%; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .wa-float::before, .map-pulse, .map-dot-hq circle:first-child { animation: none; }
  .hero-scroll { animation: none !important; }
  .btn-shine::after { display: none !important; }
  .stats-animated-bg { animation: none; }
  .page-bg, .page-bg::before, .page-bg::after { animation: none !important; }
  .page-bg::before, .page-bg::after { will-change: auto !important; }
  .transport-card img { transition: none !important; }
  .hero-media::before { animation: none !important; }
  .hero-title .wi { transform: none !important; animation: none !important; }
  .hero-hl { background-size: 100% .09em; animation: none !important; }
  .op-clip { clip-path: none !important; animation: none !important; }
  /* (.op-bg ya no lleva transform/transition en CSS; con reduced-motion GSAP
     ni siquiera se inicializa, así que la foto queda estática por sí sola.) */
  .op-check path { stroke-dashoffset: 0 !important; animation: none !important; }
  .op-block::before { transition: none !important; }
  .trust-badge { transition: none !important; transform: none !important; }
  .h2l-in { transform: none !important; }
  .transport-clip { clip-path: none !important; animation: none !important; }
  .card-bar { transform: none !important; transition: none !important; }
  .service-card > div:first-child,
  .industry-card > div:first-child { clip-path: none !important; animation: none !important; }
  .map-particle { display: none !important; }
  .map-pin--hidden,
  .map-route--hidden { transition: none !important; }
  .net-particle { display: none !important; }
  .net-line { animation: none !important; }
  .map-in .map-pin-hq .map-pin-dot { animation: none !important; }
  .odo-col { transition: none !important; }
  #site-header { transition: none !important; }
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; }
}

/* =========================================================
   Bloque en claro: CLIENTES + CERTIFICACIONES/ALIANZAS
   ---------------------------------------------------------
   El sitio corre en tema oscuro permanente (<html class="dark">), pero este
   bloque va en BLANCO para que los logos de clientes y los sellos de
   certificación —piezas oscuras pensadas para fondo claro— se lean bien.
   Va al final del archivo a propósito: tiene que ganarle a los overrides de
   `html.dark` que están más arriba, y por eso repite su especificidad.
   ========================================================= */
#clientes-alianzas {
  /* Opaco, no translúcido: .net-bg es position:fixed y se transparentaría. */
  background: #FFFFFF;
}
/* La sección hija está forzada a `transparent !important` en el bloque de
   "Secciones del cuerpo transparentes"; aquí no hay que revertirlo porque el
   blanco lo aporta el contenedor padre. */

/* --- Texto: revertir el aclarado de html.dark --- */
html.dark #clientes-alianzas .text-brand-navy { color: #1B2747 !important; }
html.dark #clientes-alianzas .text-brand-navy\/70 { color: rgba(27, 39, 71, .70) !important; }
html.dark #clientes-alianzas .text-brand-charcoal,
html.dark #clientes-alianzas [class*="text-brand-charcoal/"] { color: rgba(31, 41, 55, .72) !important; }

/* Subrayado animado de los h2 (.hl-h2) y label de sección: el rojo de marca
   funciona igual sobre blanco, no se toca. */

/* --- Chips de logos de clientes ---
   Sobre fondo oscuro eran blancos y destacaban solos. Sobre blanco desaparecían,
   así que pasan a un gris muy claro con borde sutil — mismo criterio que ya
   usaba .trust-logo-wrap para los sellos. */
#clientes-alianzas .marquee__item img {
  background: #F4F6FA;
  border: 1px solid rgba(27, 39, 71, .10);
  box-shadow: 0 2px 8px rgba(27, 39, 71, .06);
}
#clientes-alianzas .marquee__item img:hover {
  box-shadow: 0 8px 22px rgba(27, 39, 71, .16);
}

/* --- Sellos de certificación --- */
html.dark #clientes-alianzas .trust-logo-wrap {
  background: #FFFFFF;
  border: 1px solid rgba(27, 39, 71, .10);
}

#clientes-alianzas .trust-logo-wrap--carriers {
  gap: 8px;
  background: #FFFFFF;
  flex-direction: column;
}
/* Reemplaza a .carrier-logo / .carrier-logo--dhl / .carrier-logo--fedex, que
   recreaban tipográficamente los logos de DHL y FedEx: se retiró para no
   nombrar paqueterías específicas sin alianza confirmada. */
#clientes-alianzas .carrier-generic-label {
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: .7rem;
  font-weight: 700;
  color: #303E63;
  text-align: center;
  line-height: 1.15;
}

/* El resumen y las leyendas bajo cada certificación usan el azul de marca. */
html.dark #clientes-alianzas .trust-summary,
html.dark #clientes-alianzas .trust-badge > p {
  color: #303E63 !important;
}
