/* Inter, variable — un solo archivo cubre todos los pesos (100-900) */
@font-face {
  font-family: 'Inter';
  src: url('../assets/fonts/Inter-Variable.woff2') format('woff2-variations'),
       url('../assets/fonts/Inter-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* =========================================================
   Alter Collective — hoja de estilos compartida
   Un solo archivo CSS para todo el sitio: cualquier cambio
   de color, tipografía o espaciado aquí se refleja en TODAS
   las páginas que lo importan.
   ========================================================= */

:root {
  --bg: #0a0a0a;
  --bg-alt: #121212;
  --bg-card: #1a1a1a;
  --fg: #f5f3ee;
  --muted: #a3a3a0;
  --border: rgba(245, 243, 238, 0.12);

  --accent-green: #05E455;
  --accent-gold: #eab308;
  --accent-orange: #f97316;
  --accent-red: #b91c1c;

  /* Degradados de marca, tomados de la press de credenciales */
  --grad-gold: linear-gradient(135deg, #F2C230 0%, #A66A00 100%);
  --grad-green: linear-gradient(135deg, #00A85E 0%, #003D14 100%);
  --grad-orange: linear-gradient(135deg, #EC9517 0%, #6B3A12 100%);

  /* Gradiente de TEXTO (no de panel) para la tagline, tal como en la press */
  --text-grad-green: linear-gradient(90deg, #05E455 0%, #C8FCE8 100%);
  --text-grad-green-orange: linear-gradient(90deg, #05E455 0%, #f97316 100%);
  /* 2026-09-15 (ronda 25): el cliente pidió que el H1 del hero se viera
     "menos verde" -- este degradado es mucho más blanco/cálido, con el
     verde de marca solo como acento al final, en vez del verde neón que
     usa --text-grad-green en el resto del sitio (que ahí sí debe seguir
     tan verde como está). Úsalo solo en el H1 del hero, no reemplaces
     --text-grad-green globalmente. */
  --text-grad-hero-soft: linear-gradient(90deg, #f5f3ee 0%, #cdeedd 55%, #6fd39c 100%);

  --font-display: 'Inter', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Segoe UI', sans-serif;

  --max-width: 1160px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  position: relative;
  /* 2026-09-15 (ronda 36): necesario para que el slider de "Unidades de
     Negocio" (.unit-scroller) pueda romper el ancho de .container y
     extenderse a todo el viewport (ver esa regla) sin generar scroll
     horizontal de la página por el técnica de 100vw + left:50%. */
  overflow-x: hidden;
}

/* =========================================================
   Fondo animado tipo "blueprint" -- vive en TODO el sitio, pero
   DETRÁS de todo el contenido real (z-index: 0, generado antes que
   el resto de los hijos de <body> -- las secciones con fondo sólido
   propio, negro o gris, lo tapan por completo y se ven exactamente
   igual que antes; el efecto solo asoma en los huecos sin fondo
   propio, como la barra de navegación). pointer-events:none en
   ambas capas: nunca bloquean clics ni hovers reales.
   1) body::before -- la rejilla (líneas finas cada 32px + líneas
      más marcadas cada 160px, muy transparentes -- predomina el
      negro, no se ven líneas blancas "al 100"). Se desplaza
      levemente con el scroll (parallax sutil, via --bg-scroll,
      actualizada por js/bg-effects.js).
   2) body::after -- dos manchas de luz suaves (dorado + naranja,
      antes verdes -- 2026-09-15: el cliente pidió bajarle al verde
      del sitio) que se desplazan solas en loop (tipo "circuito"),
      sin depender del mouse -- animación CSS pura, para dar movimiento.
   ========================================================= */
:root {
  --bg-scroll: 0px;
}
body::before {
  content: '';
  position: fixed;
  inset: 0;
  /* z-index NEGATIVO a propósito: en CSS, un elemento posicionado con
     z-index 0/auto pinta POR ENCIMA del contenido estático no
     posicionado (la mayoría de las <section> del sitio), sin importar
     el orden en el HTML -- así que para quedar realmente detrás de
     TODO (incluidas las secciones con fondo sólido) hace falta
     z-index negativo, no 0. */
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(245, 243, 238, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(245, 243, 238, 0.025) 1px, transparent 1px),
    linear-gradient(rgba(245, 243, 238, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(245, 243, 238, 0.05) 1px, transparent 1px);
  background-size: 32px 32px, 32px 32px, 160px 160px, 160px 160px;
  background-position:
    0 calc(-1 * var(--bg-scroll)),
    0 calc(-1 * var(--bg-scroll)),
    0 calc(-1 * var(--bg-scroll)),
    0 calc(-1 * var(--bg-scroll));
}
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    radial-gradient(circle, rgba(234, 179, 8, 0.16), transparent 70%),
    radial-gradient(circle, rgba(249, 115, 22, 0.13) , transparent 70%);
  background-size: 46vw 46vw, 38vw 38vw;
  background-position: 12% 22%, 82% 72%;
  animation: bg-circuit-drift 28s ease-in-out infinite;
}
@keyframes bg-circuit-drift {
  0%   { background-position: 12% 22%, 82% 72%; }
  33%  { background-position: 68% 15%, 22% 78%; }
  66%  { background-position: 82% 68%, 15% 18%; }
  100% { background-position: 12% 22%, 82% 72%; }
}
@media (prefers-reduced-motion: reduce) {
  body::before { background-position: 0 0, 0 0, 0 0, 0 0; }
  body::after { animation: none; }
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.1;
  margin: 0 0 0.5em 0;
  text-transform: uppercase;
}

/* La tagline de portada: mayúsculas y bold como el resto de los títulos del sitio, pero notablemente más grande (tamaño definido inline en el h1), para que sea el elemento más fuerte del hero */
.hero-tagline {
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-weight: 800;
  line-height: 1.05;
  /* 2026-09-15 (ronda 27): el cliente reportó que la última letra de "BY"
     y el punto final de "CHOICE." se veían cortados -- el tracking negativo
     tan agresivo (-0.06em) hacía que el trazo del último carácter de cada
     palabra sobresaliera del box del <span class="word">, y el .hero
     padre tiene overflow:hidden. Se bajó el tracking a -0.03em (sigue
     "pegado" pero ya no corta) y se les da un colchón extra a la derecha. */
  padding-right: 0.08em;
}
.hero-tagline .word { padding-right: 0.03em; }

p { margin: 0 0 1em 0; color: var(--muted); }

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

img { max-width: 100%; display: block; }

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
}

.eyebrow {
  display: inline-block;
  position: relative;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--accent-green);
  margin-bottom: 14px;
  padding-left: 20px;
}
/* Variantes de color -- para no repetir siempre el verde de marca */
.eyebrow.eyebrow-gold { color: var(--accent-gold); }
.eyebrow.eyebrow-orange { color: var(--accent-orange); }

/* Punto "en vivo" antes del texto: un punto fijo + un anillo que se
   expande y se desvanece en loop, para llamar la atención. Usa
   currentColor, así que hereda el color del eyebrow automáticamente
   (verde / dorado / naranja / blanco sobre fondos de color). */
.eyebrow::before,
.eyebrow::after {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
}
.eyebrow::before {
  animation: eyebrow-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes eyebrow-ping {
  0% { transform: translateY(-50%) scale(1); opacity: 0.65; }
  75%, 100% { transform: translateY(-50%) scale(3.2); opacity: 0; }
}

.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: 15px;
  padding: 14px 28px;
  border-radius: 999px;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.btn-primary {
  background: var(--text-grad-green);
  color: #06210f !important;
}

.btn-outline {
  border: 1px solid var(--border);
  color: var(--fg);
}

.btn:hover { transform: translateY(-2px); opacity: 0.92; }


/* ---------- Texto con degradado (títulos de unidad, como en la press) ---------- */
.grad-text {
  background-image: var(--title-grad, var(--text-grad-green));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Logo (texto real, no imagen) ---------- */
.logo {
  display: flex;
  align-items: center;
}
.logo img {
  height: 34px;
  width: auto;
  display: block;
  object-fit: contain;
}

/* ---------- Header / navegación ---------- */
/* 2026-09-15 (ronda 10): bug real encontrado al implementar el
   auto-hide del navbar -- el sticky estaba puesto en el <header> de
   adentro, pero su padre es <div id="site-header"></div>, que
   nav.js llena con innerHTML y por lo tanto mide EXACTAMENTE lo
   mismo de alto que el header (ningun contenido extra). position:
   sticky solo "engancha" mientras el sticky tiene lugar dentro de SU
   PROPIO padre -- si el padre mide igual que el hijo, en cuanto se
   hace scroll mas alla de esa altura (unos 80-90px) el padre entero
   ya quedo arriba de la pantalla y el sticky se va con el (deja de
   verse el navbar apenas se baja un poco). Esto NO tiene que ver con
   el efecto de esconder/mostrar nuevo -- ya pasaba antes, solo que
   nadie lo habia notado porque nunca se probo bajar y quedarse ahi.
   Fix: el position:sticky se mueve al DIV de afuera (#site-header),
   que si es hijo directo de <body> (alto real de toda la pagina) --
   ahi sticky tiene todo el espacio del documento para "engancharse".
   El <header> de adentro se queda solo con el look visual (fondo,
   blur, borde). La clase .nav-hidden tambien se mueve al div de
   afuera, porque es la caja que realmente esta en position:sticky. */
#site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  transition: transform 0.35s ease;
}
#site-header.nav-hidden {
  transform: translateY(-100%);
}
header.site-header {
  background: rgba(10, 10, 10, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 16px 24px;
  max-width: var(--max-width);
  margin: 0 auto;
}

nav.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
}

nav.nav-links a {
  position: relative;
  z-index: 0;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--fg);
  padding: 8px 14px;
  border-radius: 999px;
  transition: color 0.35s ease 0.05s;
}
/* 2026-09-15 (ronda 14): hover "relleno de color" pedido por el cliente --
   un ::before del tamano del link, oculto detras del texto (z-index:-1),
   que crece de scaleX(0) a scaleX(1) con transform-origin a la DERECHA,
   asi el relleno visualmente avanza de derecha a izquierda. El texto
   cambia a negro (--bg) con un pequeno delay para que se lea sobre el
   verde una vez que el relleno ya cubrio esa zona. */
nav.nav-links a::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--text-grad-green);
  border-radius: 999px;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.35s ease;
}
nav.nav-links a:hover {
  color: var(--bg);
  transition: color 0.2s ease 0.1s;
}
nav.nav-links a:hover::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  nav.nav-links a::before { transition: none; }
  nav.nav-links a { transition: none; }
}
/* 2026-09-15 (ronda 30): indicador de página activa -- un punto verde
   debajo del label (no choca con el relleno de hover, que es un efecto
   aparte y momentáneo). En mobile, el link activo se pone verde y su
   borde inferior también, para que se note en la lista vertical. */
nav.nav-links a.active { color: var(--accent-green); }
nav.nav-links a.active::after {
  content: '';
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-green);
}
.mobile-nav a.active { color: var(--accent-green); border-bottom-color: var(--accent-green); }

.nav-dropdown { position: relative; }

.nav-dropdown-menu {
  display: none;
  position: absolute;
  top: calc(100% + 18px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px;
  min-width: 240px;
  box-shadow: 0 20px 40px rgba(0,0,0,0.4);
}

.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
  display: block;
}

.nav-dropdown-menu a {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 13px;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.nav-dropdown-menu a:hover { background: rgba(255,255,255,0.06); }

.nav-cta { margin-left: 8px; }

.menu-toggle {
  display: none;
  background: none;
  border: none;
  color: var(--fg);
  font-size: 26px;
  cursor: pointer;
}

.mobile-nav {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 0 24px 20px;
}
.mobile-nav a {
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
  font-size: 15px;
}
.mobile-nav.open { display: flex; }

/* 2026-09-17 (ronda 40): "Unidades de Negocio" como acordeon en el menu
   mobile -- antes las 6 paginas de servicio eran links sueltos entre
   "Unidades de Negocio" y "Asi lo hacemos", sin nada que las agrupara
   visualmente como subpaginas. .mobile-nav-toggle envuelve el link
   normal + un boton de flecha; .mobile-nav-submenu arranca colapsado
   (max-height:0) y se abre con la clase .open en .mobile-nav-group
   (puesta por JS al hacer click, o de entrada si la pagina actual es
   una de servicio). El link "Unidades de Negocio" en si sigue
   navegando normal -- solo la flecha (o el resto del boton, fuera del
   link) abre/cierra el submenu, ver js/nav.js. */
.mobile-nav-group { display: flex; flex-direction: column; }
.mobile-nav-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 0;
  margin: 0;
  width: 100%;
  cursor: pointer;
  color: var(--fg);
  font: inherit;
  text-align: left;
}
.mobile-nav-toggle a {
  flex: 1;
  border-bottom: none;
  padding: 12px 4px;
}
.mobile-nav-chevron {
  flex-shrink: 0;
  margin-right: 4px;
  color: var(--muted);
  transition: transform 0.25s ease;
}
.mobile-nav-group.open .mobile-nav-chevron { transform: rotate(180deg); }
.mobile-nav-submenu {
  display: flex;
  flex-direction: column;
  max-height: 0;
  overflow: hidden;
  padding-left: 16px;
  border-left: 1px solid var(--border);
  margin-left: 4px;
  transition: max-height 0.3s ease;
}
.mobile-nav-group.open .mobile-nav-submenu { max-height: 480px; }
.mobile-nav-submenu a {
  padding: 10px 4px;
  border-bottom: none;
  font-size: 13.5px;
  color: var(--muted);
}
.mobile-nav-submenu a:last-child { padding-bottom: 12px; }
.mobile-nav-submenu a.active { color: var(--accent-green); }
@media (prefers-reduced-motion: reduce) {
  .mobile-nav-submenu, .mobile-nav-chevron { transition: none; }
}

@media (max-width: 860px) {
  nav.nav-links { display: none; }
  .menu-toggle { display: block; }
  /* 2026-09-17 (ronda 39): "estirar el menu al ancho de la pagina" --
     en mobile solo quedan 2 items visibles en .nav-bar (el logo y el
     boton de hamburguesa), y space-around les agrega un margen extra
     hacia afuera (la mitad del espacio que deja entre ellos) ademas del
     padding del contenedor -- eso es lo que los alejaba de las orillas
     reales de la pantalla. space-between reparte el espacio SOLO entre
     los items, asi que cada uno queda pegado a su lado del padding, mas
     cerca de la orilla real de la pantalla. */
  .nav-bar { justify-content: space-between; padding: 16px 16px; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding: 10rem 3rem 3rem;
  min-height: 50rem;
  background: #0a0a0a;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
}

.hero.hero-home {
  background-image:
    linear-gradient(100deg, rgba(6,10,8,0.94) 0%, rgba(6,10,8,0.55) 45%, rgba(6,10,8,0.85) 100%),
    url('assets/images/hero-bg.jpg');
  background-size: cover;
  background-position: center 35%;
}

.hero-gradient-blob {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(60% 60% at 15% 20%, rgba(5,228,85,0.35), transparent 60%),
    radial-gradient(55% 55% at 85% 30%, rgba(242,194,48,0.28), transparent 60%),
    radial-gradient(60% 60% at 75% 85%, rgba(107,58,18,0.35), transparent 60%);
  filter: blur(40px);
}

.hero.hero-home .hero-gradient-blob { opacity: 0.55; mix-blend-mode: screen; }

.hero-content {
  position: relative;
  z-index: 1;
  max-width: var(--max-width);
  width: 100%;
  margin: 0;
}

.hero h1 {
  font-size: clamp(40px, 6vw, 76px);
  max-width: 900px;
}

.hero .lede {
  font-size: 19px;
  max-width: 560px;
  color: var(--muted);
}

.hero-actions {
  display: flex;
  gap: 16px;
  margin-top: 32px;
  flex-wrap: wrap;
}

/* Variante de hero para páginas de servicio. El background-image (foto de
   la unidad) se define inline en cada página, pero ya NO directamente en
   `.hero` (que sería full-bleed, ancho completo del viewport) -- 2026-09-15:
   ahora vive en `.hero-visual`, una caja contenida al mismo max-width que
   el resto del sitio y con el mismo radius de 20px que el carrusel de
   "6 unidades" -- mismo fix, mismo motivo (evitar que la foto se pixelee
   al estirarse de más). */
.hero.hero-service h1 { font-size: clamp(34px, 5vw, 56px); }
.hero.hero-service {
  display: block;
  align-items: unset;
  justify-content: unset;
  min-height: unset;
  background: #0a0a0a;
  /* 2026-09-15 (ronda 7): el cliente marco que la caja de la foto (.hero-visual)
     quedaba pegada al fondo de esta seccion -- 144px de espacio negro arriba
     (padding-top: 9rem) contra 0px abajo (padding-bottom: 0), haciendo que la
     siguiente seccion empezara justo donde termina la foto, sin respiro. Fix:
     el mismo padding arriba y abajo para que el marco quede uniforme. */
  padding: 9rem 2rem 9rem;
}
.hero-visual {
  position: relative;
  max-width: var(--max-width);
  margin: 0 auto;
  min-height: 34rem;
  border-radius: 20px;
  overflow: hidden;
  background-size: cover;
  background-position: center 35%;
  display: flex;
  /* 2026-09-15: antes "flex-end" empujaba el contenido al borde inferior,
     dejando todo el espacio libre arriba -- el cliente pidió que el
     espaciado quedara igual en cada lado (padding parejo, que ya era
     3rem) y el contenido centrado verticalmente dentro de la caja. */
  align-items: center;
  justify-content: flex-start;
  padding: 3rem;
}
@media (max-width: 760px) {
  .hero-visual { padding: 2rem 1.5rem; min-height: 28rem; }
}

/* 2026-09-15 (ronda 6): el cliente marco el hero de unidad como "deforme" --
   el texto quedaba flotando en una caja de ancho completo (1064px) sobre
   una foto sin tratamiento suficiente, dejando gran parte de la imagen
   (arriba y a la derecha) sin ningun elemento de diseno, como si el texto
   estuviera pegado en una esquina de una foto cruda. Fix: se acota el
   ancho del bloque de texto para que se lea como una columna intencional
   (no "toda la caja"), y el degradado (definido inline por pagina, ver
   HTML) se reforzo para cubrir mejor arriba/abajo tambien, no solo
   izquierda-a-derecha -- ver comentario junto al degradado en cada HTML. */
.hero.hero-service .hero-content { max-width: 640px; }
/* 2026-09-15 (ronda 11): Contacto y "Asi lo hacemos" reusan .hero.hero-service
   pero sin .hero-visual (no tienen foto de fondo detras, solo el blob de
   gradiente) -- el acotamiento a 640px de arriba era para que el texto se
   leyera como columna sobre una foto sin tratar, no aplica aqui. El cliente
   pidio que el hero de estas dos paginas quede a la misma medida que el
   resto del contenido (.container, max-width var(--max-width) = 1160px). */
/* 2026-09-15 (ronda 12): con el max-width restaurado a 1160px (ronda 11)
   seguia sin alinear con el resto del contenido -- .hero-content por
   default tiene margin:0 (pegado a la izquierda dentro del padding de
   la seccion .hero, que es full-bleed), mientras que .container (usado
   por el resto de la pagina) se centra con margin:0 auto. En viewports
   anchos eso deja el texto del hero pegado a la izquierda mientras el
   formulario/contenido de abajo queda centrado con márgenes grandes a
   los lados -- exactamente lo que el cliente marco con el recuadro rojo
   en su captura. Fix: mismo centrado (margin:0 auto) y mismo padding
   interno (0 24px, igual que .container) para que el borde izquierdo
   del texto quede pixel a pixel alineado con el resto del contenido. */
.hero.hero-service.hero-plain .hero-content {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
}

.unit-logo {
  height: 6rem;
  width: 100%;
  margin-bottom: 20px;
  object-fit: contain;
  object-position: left center;
  display: block;
}

/* ---------- Hero mosaic (video) — variante de hero de la home, 2026-09-14 ---------- */
.hero.hero-mosaic {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  padding: 9rem 0 0;
  min-height: unset;
  overflow: hidden;
  /* 2026-09-17 (ronda 41): "esta muy estirado" -- en mobile el hueco
     entre el navbar y el H1 se sentia excesivo. Reducido a la mitad
     (9rem -> 4.5rem) solo en mobile, ver media query mas abajo. */
  /* Glow dorado/amarillo detrás del título -- pedido del cliente: "que no
     se vea TAN VERDE TODO". El H1 es verde (grad-text), asi que el fondo
     necesita un tono realmente contrastante (amarillo/dorado, no solo un
     insinuado) para que exista contraste de color de verdad, no nada mas
     "menos verde". 2026-09-15 (ronda 21): se subio la opacidad de 0.20 a
     0.5 y se agrando/repartio el glow (dos elipses en vez de una) para
     que el amarillo se note en la parte de arriba Y se extienda hacia
     abajo, detras del segundo bloque de texto tambien. */
  background:
    radial-gradient(ellipse 1300px 780px at 50% -10%, rgba(234,179,8,0.5), transparent 62%),
    radial-gradient(ellipse 1100px 560px at 50% 68%, rgba(234,179,8,0.28), transparent 65%),
    #0a0a0a;
}

/* ---------- Animación del título del hero de home (2026-09-15) ----------
   Entrada suave (fade + slide up) al cargar, más un brillo lento y sutil
   que recorre el degradado del texto en loop -- nada invasivo. */
/* 2026-09-15 (ronda 6, corregido): revelado palabra por palabra con blur.
   IMPORTANTE -- el degradado (background-clip:text) no puede quedar solo
   en el <h1> exterior: una vez el texto vive dentro de <span class="word">
   hijos, el h1 ya no tiene texto propio que recortar y el degradado no
   pinta nada (el texto de los spans queda transparente sin fondo, o sea
   invisible). Por eso cada .word lleva su propia copia del degradado
   (via la misma variable --title-grad) y su propio background-clip:text.
   Cada palabra brilla de forma independiente en vez de un solo degradado
   corrido en toda la frase -- efecto ligeramente distinto al original
   pero el texto vuelve a ser visible. */
.hero.hero-mosaic .hero-tagline .word {
  display: inline-block;
  background-image: var(--title-grad, var(--text-grad-green));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  background-size: 200% auto;
  opacity: 0;
  filter: blur(14px);
  transform: translateY(18px);
  animation: wordReveal 0.9s cubic-bezier(.22,.68,0,1.01) forwards,
             heroTitleShine 7s ease-in-out 1.7s infinite alternate;
}
@keyframes wordReveal {
  to { opacity: 1; filter: blur(0); transform: translateY(0); }
}
@keyframes heroTitleShine {
  from { background-position: 0% 50%; }
  to { background-position: 100% 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .hero.hero-mosaic .hero-tagline .word { animation: none; opacity: 1; filter: none; transform: none; }
}

/* ---------- Flashes de cámara en el hero de home (2026-09-15) -----------
   Alusión sutil a celebridades/prensa: destellos blancos tipo flash de
   cámara fotográfica, en loop, sin depender del mouse. Viven en una capa
   absoluta detrás de todo el contenido del hero (z-index 0; el texto y
   el mosaico de video ya tienen z-index 1, ver más abajo). No invasivo:
   opacidad baja, tamaño chico, y cada uno con su propio timing para que
   no destellen todos a la vez. */
.camera-flashes {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.camera-flashes .flash {
  position: absolute;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.25) 40%, transparent 72%);
  opacity: 0;
  animation-name: camFlash;
  animation-iteration-count: infinite;
  animation-timing-function: ease-out;
}
.camera-flashes .flash-1 { top: 12%; left: 10%;  width: 70px;  height: 70px;  animation-duration: 5.2s; animation-delay: 0s; }
.camera-flashes .flash-2 { top: 22%; left: 82%;  width: 100px; height: 100px; animation-duration: 6.4s; animation-delay: -1.4s; }
.camera-flashes .flash-3 { top: 68%; left: 18%;  width: 80px;  height: 80px;  animation-duration: 7.1s; animation-delay: -3.2s; }
.camera-flashes .flash-4 { top: 78%; left: 74%;  width: 60px;  height: 60px;  animation-duration: 4.6s; animation-delay: -2.1s; }
.camera-flashes .flash-5 { top: 8%;  left: 48%;  width: 55px;  height: 55px;  animation-duration: 6.9s; animation-delay: -4.6s; }
.camera-flashes .flash-6 { top: 52%; left: 92%;  width: 75px;  height: 75px;  animation-duration: 5.8s; animation-delay: -0.6s; }
.camera-flashes .flash-7  { top: 35%; left: 32%; width: 65px;  height: 65px;  animation-duration: 6.1s; animation-delay: -5.3s; }
.camera-flashes .flash-8  { top: 88%; left: 42%; width: 85px;  height: 85px;  animation-duration: 5.5s; animation-delay: -2.8s; }
.camera-flashes .flash-9  { top: 5%;  left: 78%; width: 60px;  height: 60px;  animation-duration: 7.4s; animation-delay: -1.1s; }
.camera-flashes .flash-10 { top: 45%; left: 6%;  width: 95px;  height: 95px;  animation-duration: 6.7s; animation-delay: -4.0s; }
.camera-flashes .flash-11 { top: 62%; left: 58%; width: 55px;  height: 55px;  animation-duration: 5.0s; animation-delay: -3.6s; }
.camera-flashes .flash-12 { top: 30%; left: 96%; width: 70px;  height: 70px;  animation-duration: 6.9s; animation-delay: -0.2s; }
@keyframes camFlash {
  0%   { opacity: 0; transform: scale(0.6); }
  2%   { opacity: 0.55; transform: scale(1.15); }
  8%   { opacity: 0; transform: scale(1.3); }
  100% { opacity: 0; transform: scale(1.3); }
}
@media (prefers-reduced-motion: reduce) {
  .camera-flashes .flash { animation: none; opacity: 0; }
}
.hero.hero-mosaic .hero-content {
  padding: 0 3rem 48px;
  text-align: center;
  max-width: 900px;
  margin: 0 auto;
}
@media (max-width: 640px) {
  .hero.hero-mosaic { padding-top: 4.5rem; }
  /* 2026-09-17 (ronda 41): en mobile el H1 ("Different by choice.")
     usaba el mismo clamp con piso fijo (56px, puesto inline en
     index.html) que en desktop -- en una pantalla angosta ese piso ya
     no cabe en el ancho del contenedor y el titulo terminaba partido en
     3 lineas ("Different" / "by" / "choice.") en vez de las 2 lineas
     grandes que Bruno referencio ("DIFFERENT" / "BY CHOICE.", como ya
     se ve en desktop). Se fuerza un tamano fluido en vw (sin piso fijo)
     que escala con el viewport y siempre deja "by" y "choice." en la
     misma linea -- el !important es necesario porque el tamano base
     viene de un font-size inline en el HTML, que le gana a cualquier
     regla de clase sin el. Tambien se reduce el padding lateral del
     hero (3rem -> 16px) para darle mas ancho disponible al texto. */
  .hero.hero-mosaic .hero-content { padding-left: 16px; padding-right: 16px; }
  .hero.hero-mosaic .hero-tagline { font-size: 16vw !important; }
}
.hero.hero-mosaic .hero-content .lede { margin-left: auto; margin-right: auto; }
/* El segundo bloque de texto (debajo del mosaico) no debe quedar en una
   columna angosta de 560px -- el cliente pidió que se distribuya a todo
   el ancho del hero. */
.hero.hero-mosaic .hero-content-lower .lede { max-width: none; }

/* ---------- Typewriter en el lede del hero (2026-09-15) ------------------
   Cursor tipo bloque que parpadea, en el mismo color que el texto (usa
   currentColor, así hereda el color inline del <p>). Sigue parpadeando
   después de que termina de "escribirse" el texto. */
.typewriter-lede .tw-cursor {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  margin-left: 3px;
  background: currentColor;
  vertical-align: text-bottom;
  animation: tw-blink 0.9s step-end infinite;
}
@keyframes tw-blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .typewriter-lede .tw-cursor { animation: none; opacity: 1; }
}
.hero.hero-mosaic .hero-actions { justify-content: center; }

.mosaic-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  align-items: end;
  gap: 6px;
  padding: 0 0 64px;
  line-height: 0;
}
@media (min-width: 901px) {
  .mosaic-grid { perspective: 1400px; }
}
.mosaic-grid .cell {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #000;
  border-radius: 16px;
  box-shadow: 0 18px 36px rgba(0,0,0,0.4);
}
.mosaic-grid video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 2026-09-15: se quitó el scaleX(-1) en .flip -- los videos duplicados 
   traen subtítulos quemados en el video y al espejearlos se veían al
   revés. La clase .flip queda sin efecto (se puede borrar del HTML
   cuando se quiera, no rompe nada dejarla). */

/* 2026-09-15 (ronda 20): coverflow real (perspectiva 3D, rotateY) pedido
   con imagen de referencia puntual -- reemplaza el arco 2D "media luna"
   de la ronda 10. Cada celda rota sobre su borde interior (el que mira
   hacia el centro), asi el borde exterior se aleja de la camara y se ve
   mas angosto -- el efecto trapezoide real de coverflow, no solo un giro
   plano. Simetrico celda a celda (1<->6, 2<->5, 3<->4). Solo en desktop. */
@media (min-width: 901px) {
  .mosaic-grid { gap: 0; }
  .mosaic-grid .cell { transition: transform 0.4s ease; }
  .mosaic-grid .cell:nth-child(1) { transform: rotateY(48deg) scale(0.82); transform-origin: right center; z-index: 1; }
  .mosaic-grid .cell:nth-child(2) { transform: rotateY(28deg) scale(0.9);  transform-origin: right center; z-index: 2; }
  .mosaic-grid .cell:nth-child(3) { transform: rotateY(9deg)  scale(0.97); transform-origin: right center; z-index: 3; }
  .mosaic-grid .cell:nth-child(4) { transform: rotateY(-9deg) scale(0.97); transform-origin: left center;  z-index: 3; }
  .mosaic-grid .cell:nth-child(5) { transform: rotateY(-28deg) scale(0.9); transform-origin: left center;  z-index: 2; }
  .mosaic-grid .cell:nth-child(6) { transform: rotateY(-48deg) scale(0.82); transform-origin: left center; z-index: 1; }
}
@media (max-width: 900px) {
  .mosaic-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 480px) {
  .mosaic-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- "Behind the Scenes" (home + Media House) -------------------
   2026-09-15: el cliente pidió invertir la jerarquía -- "Behind the Scenes"
   pasa a ser el texto más grande, "Lo que no ves en cámara" queda mediano,
   y la descripción queda chica. Reutiliza el layout de .featured-flex
   (texto a la izquierda ocupando la mayor parte del ancho, video angosto
   a la derecha) que había quedado libre al quitar "Conecta con tu
   audiencia" de la home. */
.bts-huge {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 0.95;
  font-size: clamp(40px, 6vw, 88px);
  margin-bottom: 20px;
}
.bts-subtitle {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  font-size: clamp(18px, 2vw, 24px);
  color: var(--fg);
  margin-bottom: 14px;
}
.bts-desc {
  font-size: 14px;
  color: var(--muted);
  max-width: 460px;
  margin-bottom: 0;
}

/* ---------- Featured video ("Conecta con tu audiencia") ---------- */
.featured-wrap { background: var(--bg-alt); padding: 64px 0; }
.featured-flex {
  display: flex;
  align-items: center;
  gap: 56px;
  flex-wrap: wrap;
}
.featured-text { flex: 1 1 360px; }
.featured-video {
  flex: 0 0 auto;
  width: 300px;
  aspect-ratio: 9 / 16;
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
  background: #000;
  margin: 0 auto;
}
.featured-video video { width: 100%; height: 100%; object-fit: cover; display: block; }


/* ---------- Secciones genéricas ---------- */
section { padding: 90px 0; }
section.alt { background: var(--bg-alt); }
section.cta-wrap { padding: 0; background: none; }

.section-head { max-width: 640px; margin-bottom: 56px; }
.section-head h2 { font-size: clamp(28px, 4vw, 42px); }
/* 2026-09-15 (ronda 24): el cliente pidió que las descripciones de sección
   (el <p> debajo del h2, en "Reel", "¿Qué problema solucionamos?", "6
   unidades", etc.) se vean en blanco, no gris. Se escopea a .section-head p
   en vez de tocar la regla global "p { color: var(--muted) }" -- esa regla
   global la siguen usando textos que sí deben quedarse grises (footer,
   captions de testimonios, tarjetas muted) en otras partes del sitio. */
.section-head p { color: var(--fg); }

/* 2026-09-15 (ronda 27): el cliente pidió que el título "¿Qué problema
   solucionamos?" se viera más grande -- se escopea a #problema para no
   cambiar el tamaño del resto de los títulos de sección del sitio. */
#problema .section-head h2 { font-size: clamp(34px, 5.2vw, 56px); }
#problema .section-head { max-width: 760px; }

/* ---------- "¿Qué problema solucionamos?" -- diagrama de flujo (2026-09-15,
   ronda 23). Texto aprobado tal cual por el cliente. El diagrama traduce el
   boceto ASCII que mandó (reto -> objetivo+presupuesto -> Alter Collective
   -> se abre en las 6 unidades reales -> converge en comparamos
   alternativas -> mejor solución -> implementamos -> resultados) a la
   línea gráfica del sitio: nodos tipo pill oscuros, flechas verticales
   sutiles, y las 6 unidades coloreadas con el mismo acento que ya tiene
   cada una en el resto del sitio (ver "Sistema de color de acento"). */
.problem-flow {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 8px;
}
.flow-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 24px 38px;
  text-align: center;
  max-width: 420px;
}
/* 2026-09-15 (ronda 26): el cliente pidió que el diagrama no se sintiera
   "estilizado" -- cada etapa ahora trae un título corto (grande, bold,
   caracteres pegados) MÁS una descripción de una línea que explica qué
   pasa realmente en ese paso, en vez de ser solo una palabra suelta tipo
   label decorativo. */
.flow-node-title {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(19px, 2.2vw, 25px);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--fg);
}
.flow-node-desc {
  display: block;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}
.flow-node-big { padding: 30px 42px; }
/* 2026-09-15 (ronda 28): el cliente corrigió el tratamiento de "Resultados
   + optimización" -- no quería sólido verde con texto negro, sino el
   MISMO patrón que ya usa "Mejor solución" (fondo oscuro + borde de
   color): borde verde, relleno verde traslúcido, texto y check en verde
   (el color del borde), en vez de fondo sólido. */
.flow-node-result {
  flex-direction: row;
  align-items: center;
  gap: 16px;
  text-align: left;
  max-width: none;
  background: rgba(5, 228, 85, 0.10);
  border-color: var(--accent-green);
  box-shadow: 0 14px 32px rgba(5, 228, 85, 0.18);
}
.flow-node-result .flow-node-title,
.flow-node-result .flow-node-desc { color: var(--accent-green); }
.flow-node-result .flow-node-title { white-space: nowrap; }
.flow-node-result-text { display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.flow-check { flex-shrink: 0; align-self: center; }
.flow-node-brand {
  background: var(--grad-green);
  border: none;
  padding: 34px 68px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 2026-09-15 (rondas 27 y 28): el cliente pidió que Alter Collective se
     viera con más impacto visual que el resto de los nodos. En la ronda 27
     solo se le quitó el max-width -- pero como es flex-column centrado,
     sin un ancho mínimo explícito el recuadro seguía midiendo lo mismo
     (o menos) que los nodos de texto largo de al lado. Ahora tiene un
     min-width mayor al max-width de cualquier otro nodo (420px), para que
     SIEMPRE se vea más ancho que los demás, sin importar el texto vecino. */
  max-width: none;
  min-width: 480px;
  box-shadow: 0 20px 44px rgba(5, 228, 85, 0.28);
}
.flow-node-brand img {
  height: 64px;
  width: auto;
  display: block;
}
.flow-node-highlight {
  border-color: var(--accent-gold);
  box-shadow: 0 14px 32px rgba(234, 179, 8, 0.18);
}
/* 2026-09-15 (ronda 29): "Tu reto" abre el diagrama con un tinte rojo muy
   sutil (no chillon) para marcar visualmente que es la dificultad de
   partida -- el mismo lenguaje de borde+relleno translucido que ya usan
   "Mejor solucion" (dorado) y "Resultados" (verde), aqui en rojo apagado,
   de forma que el diagrama narre un arco de color rojo -> verde. */
.flow-node-problem {
  background: rgba(185, 28, 28, 0.08);
  border-color: rgba(185, 28, 28, 0.4);
  box-shadow: 0 14px 32px rgba(185, 28, 28, 0.12);
}
/* 2026-09-15 (ronda 25): las líneas del diagrama "corren" como un riel de
   luz/electricidad (variable --rail-delay por elemento, puesta inline en
   el HTML según su posición en el flujo) para guiar visualmente al
   visitante en el orden del proceso. Respeta prefers-reduced-motion.
   2026-09-15 (ronda 26): se le quitó la punta de flecha (::after) -- el
   cliente pidió que solo se vieran los rieles, sin triángulo, por estética. */
.flow-arrow {
  width: 2px;
  height: 34px;
  background-color: rgba(245, 243, 238, 0.22);
  background-image: linear-gradient(180deg, transparent 0%, var(--accent-green) 50%, transparent 100%);
  background-size: 100% 240%;
  background-repeat: no-repeat;
  background-position: 0 -240%;
  position: relative;
  animation: rail-pulse-v 2.4s linear infinite;
  animation-delay: var(--rail-delay, 0s);
}
/* 2026-09-15 (ronda 26): las 6 "categorías" del diagrama (antes .service-card
   repetidas, antes de eso cajas .flow-unit planas) ahora viven dentro de UN
   solo marco redondeado (.flow-units-wrap) con el mismo corner-radius que el
   resto del sitio (20px, igual que .service-card y el carrusel) -- el
   cliente pidió que las 4 esquinas del bracket dejaran de verse como piezas
   sueltas y se sintieran una sola forma cerrada. Ya no hay bracket-lines ni
   ticks por tarjeta (eran 4 esquinas independientes); el borde del marco
   hace ese trabajo de encerrar el bloque completo. */
.flow-units-wrap {
  position: relative;
  width: 100%;
  max-width: 1160px;
  border: 1px solid rgba(245, 243, 238, 0.18);
  border-radius: 20px;
  background: rgba(245, 243, 238, 0.02);
  padding: 56px 40px;
  overflow: hidden;
  isolation: isolate;
}
/* 2026-09-15 (ronda 27): "más movimiento espectral dentro del recuadro" --
   dos brillos verdes muy tenues, desenfocados, que flotan lento dentro del
   marco (mismo lenguaje que las "luces verdes que se mueven solas" del
   fondo blueprint del sitio, ver glosario), detrás de los tags/logos
   (z-index 0, los .problem-cat quedan en 1 gracias a `isolation:isolate`
   + que son elementos normales en flujo, se pintan encima). */
.flow-units-wrap::before,
.flow-units-wrap::after {
  content: '';
  position: absolute;
  width: 340px;
  height: 340px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(5, 228, 85, 0.22), transparent 70%);
  filter: blur(50px);
  pointer-events: none;
  z-index: 0;
}
.flow-units-wrap::before { top: -120px; left: -80px; animation: spectral-drift-1 14s ease-in-out infinite; }
.flow-units-wrap::after { bottom: -120px; right: -80px; animation: spectral-drift-2 17s ease-in-out infinite; }
@keyframes spectral-drift-1 {
  0%, 100% { transform: translate(0, 0); opacity: 0.6; }
  50% { transform: translate(120px, 60px); opacity: 1; }
}
@keyframes spectral-drift-2 {
  0%, 100% { transform: translate(0, 0); opacity: 0.6; }
  50% { transform: translate(-100px, -50px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .flow-units-wrap::before,
  .flow-units-wrap::after { animation: none; }
}
/* 2026-09-15 (ronda 26): cada unidad se representa como una "categoría"
   (tag tipo vidrio esmerilado / liquid glass + logo debajo) en vez de
   repetir la .service-card completa que ya se ve más abajo en
   "6 unidades" -- ver renderProblemUnits() en js/nav.js. */
.flow-units {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 28px;
}
.problem-cat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-decoration: none;
  transition: transform 0.2s ease;
}
.problem-cat:hover { transform: translateY(-3px); }
.cat-tag {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  padding: 12px 26px;
  border-radius: 999px;
  color: var(--fg);
  background: linear-gradient(135deg, rgba(245, 243, 238, 0.16), rgba(245, 243, 238, 0.04));
  border: 1px solid rgba(245, 243, 238, 0.25);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 10px 24px rgba(0, 0, 0, 0.28);
}
.cat-tag-gold { color: var(--accent-gold); border-color: rgba(234, 179, 8, 0.35); box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 10px 24px rgba(234, 179, 8, 0.16); }
.cat-tag-green { color: var(--accent-green); border-color: rgba(5, 228, 85, 0.3); box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 10px 24px rgba(5, 228, 85, 0.14); }
.cat-tag-orange { color: var(--accent-orange); border-color: rgba(249, 115, 22, 0.32); box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 10px 24px rgba(249, 115, 22, 0.16); }
.cat-logo { height: 52px; width: auto; max-width: 100%; object-fit: contain; display: block; }
@keyframes rail-pulse-v {
  from { background-position: 0 -240%; }
  to { background-position: 0 240%; }
}
@media (prefers-reduced-motion: reduce) {
  .flow-arrow { animation: none; background-position: 0 0; }
}
@media (max-width: 900px) {
  .flow-units { grid-template-columns: repeat(3, 1fr); }
  .flow-units-wrap { padding: 40px 24px; }
  .cat-logo { height: 44px; }
}
@media (max-width: 560px) {
  .flow-units { grid-template-columns: repeat(2, 1fr); gap: 28px 16px; }
  .flow-units-wrap { padding: 32px 16px; border-radius: 16px; }
  .cat-logo { height: 38px; }
  .flow-node { padding: 18px 22px; max-width: 100%; }
  .flow-node-big { padding: 20px 22px; }
  .flow-node-brand { padding: 20px 32px; min-width: 0; width: 100%; }
  .flow-node-brand img { height: 40px; }
  /* 2026-09-17 (ronda 39): "Resultados + optimizacion" se desbordaba en
     mobile -- .flow-node-result usa flex-direction:row + text-align:left
     + white-space:nowrap en el titulo (pensado para desktop, donde el
     nodo tiene espacio de sobra), y en una pantalla angosta ese texto
     nunca cabe en una sola linea junto al icono, se sale del recuadro.
     En mobile pasa a columna: icono centrado arriba, texto centrado
     debajo, con wrap normal. */
  .flow-node-result {
    flex-direction: column;
    text-align: center;
    align-items: center;
    gap: 10px;
  }
  .flow-node-result .flow-node-title { white-space: normal; }
  .flow-node-result-text { align-items: center; }
}

/* Texto de cierre del diagrama, debajo del marco completo -- mensaje
   inspirado en el que traía el boceto original del cliente ("Un reto.
   Múltiples caminos. Una solución."), adaptado a la línea gráfica del
   sitio en vez de copiado tal cual. */
.problem-flow-closing {
  text-align: center;
  max-width: 720px;
  margin: 40px auto 0;
  font-size: clamp(16px, 2vw, 19px);
  line-height: 1.6;
  color: var(--fg);
}
.problem-flow-closing strong {
  display: inline-block;
  margin-top: 6px;
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.01em;
  font-size: clamp(18px, 2.4vw, 23px);
}

/* 2026-09-15 (ronda 30): "Así lo hacemos" -- el cliente pidió una
   propuesta visual distinta a .service-card para presentar las 6
   unidades ahí (sin descripción, solo logo) que no se sintiera repetitiva
   frente a las tarjetas que ya usan la home y "Unidades de Negocio".
   Son mosaicos de vidrio con un resplandor de color detrás del logo (el
   acento propio de cada unidad) que crece al hover -- mismo lenguaje
   "liquid glass" que ya usan las categorías del diagrama de arriba, pero
   en un formato más grande y sin texto, pensado para verse como una
   vitrina de marcas. */
/* 2026-09-15 (ronda 31): a pedido del cliente, la vitrina de unidades de
   "Así lo hacemos" pasó de grid estático a un carrusel infinito (mismo
   mecanismo que el marquee de "Aliados" en la home: el set de tarjetas se
   triplica y el track recorre exactamente 1/3 de su ancho en loop) para
   darle movimiento a la página. Las tarjetas .unit-tile no cambiaron de
   diseño -- solo se adaptaron a ancho fijo para funcionar en una fila que
   se desplaza en vez de una grilla estática. */
.unit-marquee {
  position: relative;
  overflow: hidden;
  width: 100%;
}
.unit-marquee::before,
.unit-marquee::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100px;
  z-index: 2;
  pointer-events: none;
}
.unit-marquee::before { left: 0; background: linear-gradient(90deg, var(--bg) 0%, transparent 100%); }
.unit-marquee::after { right: 0; background: linear-gradient(270deg, var(--bg) 0%, transparent 100%); }
.unit-track {
  display: flex;
  align-items: center;
  gap: 20px;
  width: max-content;
  /* 2026-09-15 (ronda 32): "reverse" para que el recorrido se sienta de
     izquierda a derecha (con las mismas keyframes que ya usaba). */
  animation: unit-marquee-scroll 40s linear infinite reverse;
}
.unit-marquee:hover .unit-track { animation-play-state: paused; }
@keyframes unit-marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-33.3334%); }
}
@media (prefers-reduced-motion: reduce) {
  .unit-track { animation: none; }
}
.unit-track .unit-tile { flex: 0 0 280px; }
@media (max-width: 560px) {
  .unit-track .unit-tile { flex-basis: 220px; }
}
.unit-tile {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 10;
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(245,243,238,0.05), rgba(245,243,238,0.015));
  border: 1px solid var(--border);
  overflow: hidden;
  isolation: isolate;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.unit-tile::before {
  content: '';
  position: absolute;
  inset: -50%;
  background: radial-gradient(circle at 50% 55%, var(--tile-glow) 0%, transparent 62%);
  opacity: 0.32;
  z-index: 0;
  transition: opacity 0.4s ease, transform 0.6s ease;
}
.unit-tile img {
  position: relative;
  z-index: 1;
  height: 56px;
  width: auto;
  filter: drop-shadow(0 10px 22px rgba(0,0,0,0.4));
  transition: transform 0.35s ease;
}
.unit-tile:hover {
  transform: translateY(-6px);
  border-color: var(--tile-border);
  box-shadow: 0 20px 40px var(--tile-shadow);
}
.unit-tile:hover::before { opacity: 0.6; transform: scale(1.15); }
.unit-tile:hover img { transform: scale(1.08); }
.unit-tile-gold { --tile-glow: rgba(234, 179, 8, 0.55); --tile-border: rgba(234, 179, 8, 0.4); --tile-shadow: rgba(234, 179, 8, 0.16); }
.unit-tile-green { --tile-glow: rgba(5, 228, 85, 0.55); --tile-border: rgba(5, 228, 85, 0.4); --tile-shadow: rgba(5, 228, 85, 0.16); }
.unit-tile-orange { --tile-glow: rgba(249, 115, 22, 0.55); --tile-border: rgba(249, 115, 22, 0.4); --tile-shadow: rgba(249, 115, 22, 0.16); }
@media (max-width: 560px) {
  .unit-tile { aspect-ratio: 16 / 9; }
}

/* ---------- Scroller grande de unidades (Unidades de Negocio) ---------- */
/* 2026-09-15 (ronda 35): en reposo la tarjeta se ve como los mosaicos de
   "Así lo hacemos" (.unit-tile) -- vidrio oscuro + resplandor radial del
   color de esa unidad, sin foto -- y la foto real solo se revela al
   pasar el mouse (o el foco de teclado), con un fundido cruzado entre el
   glow de color y la foto. La descripción SÍ va visible (se había
   quitado en la ronda 34 y el cliente pidió regresarla), junto con el
   logo -- ahora más grande -- alineados en flex hacia abajo a la
   izquierda. Las flechas (mismo lenguaje visual que .carousel-arrow, ya
   usado en la home) hacen scrollBy de un ancho de tarjeta con su propia
   animación en JS (ver js/unit-scroller.js). */
.unit-scroller {
  /* 2026-09-15 (ronda 36): rompe el ancho de .container -- el cliente
     marco que el slider se sentia "cortado" al mismo ancho que el resto
     del contenido. Tecnica de "full-bleed" a base de margin (NO de
     transform/left): un ancho de 100vw con margen izquierdo/derecho
     negativo que compensa exactamente la diferencia entre el ancho del
     viewport y el ancho del contenedor -- asi el slider ocupa todo el
     viewport sin importar el max-width/padding de .container que lo
     envuelve. Importante: este elemento tambien lleva la clase .reveal,
     y .reveal.in-view define su propio "transform" (translateY) con mas
     especificidad que esta regla -- el primer intento uso
     transform:translateX para el full-bleed y esa regla lo pisaba por
     completo en cuanto la seccion entraba en pantalla (el slider
     quedaba descentrado hacia la derecha). Con margin no hay conflicto
     posible con transform. Se le deja el mismo padding lateral de 24px
     que ya usa .container, para que las flechas y la primera/ultima
     tarjeta respeten el mismo margen visual que el resto del sitio en
     vez de quedar pegadas al borde del navegador. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  box-sizing: border-box;
  padding: 0 24px;
  /* 2026-09-15 (ronda 37): las flechas ya NO van a los costados de las
     tarjetas -- ahi le "robaban" ancho al track (el track se encogia
     para dejarles espacio a las flechas + el gap, y en pantallas donde
     no sobraba espacio la ultima tarjeta terminaba recortada justo
     donde arrancaba la flecha). Ahora .unit-scroller es una columna: el
     track ocupa el 100% del ancho completo (full-bleed) y las flechas
     viven debajo, centradas, en su propia fila (.unit-scroll-controls). */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 24px;
}
@media (max-width: 640px) {
  .unit-scroller { padding: 0 16px; }
}
.unit-scroll-track {
  display: flex;
  width: 100%;
  gap: 20px;
  overflow-x: auto;
  /* 2026-09-15 (ronda 34): SIN scroll-snap y SIN scroll-behavior:smooth.
     Con snap activo, Chrome interrumpe el scrollBy suave y solo avanza
     unos px antes de "reencajar". Con scroll-behavior:smooth en el
     elemento, CUALQUIER cambio de scrollLeft (incluida una asignación
     directa) se vuelve asíncrono/encolado, y si además scrollBy() pide
     behavior:'smooth' el navegador puede simplemente no completar la
     animación (se queda en 0). La animación suave de las flechas ahora
     la hace el propio JS (ver js/unit-scroller.js) con
     requestAnimationFrame, así que aquí el scroll debe quedar instantáneo. */
  scroll-behavior: auto;
  padding: 4px 4px 10px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.unit-scroll-track::-webkit-scrollbar { display: none; }
.unit-big-card {
  position: relative;
  flex: 0 0 340px;
  aspect-ratio: 3 / 4;
  border-radius: 22px;
  background: linear-gradient(180deg, rgba(245,243,238,0.05), rgba(245,243,238,0.015));
  border: 1px solid var(--border);
  overflow: hidden;
  isolation: isolate;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 28px;
  transition: transform 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
.unit-big-card::before {
  /* resplandor de color en reposo, mismo lenguaje que .unit-tile */
  content: '';
  position: absolute;
  inset: -50%;
  background: radial-gradient(circle at 50% 62%, var(--reel-glow) 0%, transparent 62%);
  opacity: 0.4;
  z-index: 0;
  transition: opacity 0.5s ease, transform 0.6s ease;
}
.unit-big-card::after {
  /* foto real, oculta hasta el hover/foco, con degradado oscuro para
     que el texto siga siendo legible encima */
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10,10,10,0.05) 30%, rgba(10,10,10,0.92) 100%), var(--reel-image);
  background-size: cover;
  background-position: center;
  opacity: 0;
  z-index: 0;
  transition: opacity 0.5s ease;
}
.unit-big-card:hover,
.unit-big-card:focus-visible {
  transform: translateY(-6px);
  border-color: var(--reel-border);
  box-shadow: 0 20px 40px var(--reel-shadow);
}
.unit-big-card:hover::before,
.unit-big-card:focus-visible::before { opacity: 0; transform: scale(1.15); }
.unit-big-card:hover::after,
.unit-big-card:focus-visible::after { opacity: 1; }
.unit-big-card-gold { --reel-glow: rgba(234, 179, 8, 0.55); --reel-border: rgba(234, 179, 8, 0.4); --reel-shadow: rgba(234, 179, 8, 0.16); }
.unit-big-card-green { --reel-glow: rgba(5, 228, 85, 0.55); --reel-border: rgba(5, 228, 85, 0.4); --reel-shadow: rgba(5, 228, 85, 0.16); }
.unit-big-card-orange { --reel-glow: rgba(249, 115, 22, 0.55); --reel-border: rgba(249, 115, 22, 0.4); --reel-shadow: rgba(249, 115, 22, 0.16); }
.unit-big-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
.unit-big-logo {
  height: 76px;
  width: auto;
  max-width: 85%;
  object-fit: contain;
  filter: drop-shadow(0 4px 16px rgba(0,0,0,0.55));
}
.unit-big-desc {
  font-size: 1.05rem;
  line-height: 1.35;
  margin: 0;
  color: rgba(255,255,255,0.85);
  max-width: 94%;
}
.unit-scroll-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.unit-scroll-arrow {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(10,10,10,0.6);
  border: 1px solid rgba(255,255,255,0.25);
  color: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
  z-index: 2;
}
.unit-scroll-arrow:hover { background: rgba(10,10,10,0.85); }
@media (max-width: 900px) {
  .unit-big-card { flex-basis: 280px; }
  .unit-big-logo { height: 62px; }
}
@media (max-width: 560px) {
  .unit-big-card { flex-basis: 230px; padding: 20px; }
  .unit-big-logo { height: 48px; }
  .unit-big-desc { font-size: 0.9rem; }
  .unit-scroll-arrow { width: 38px; height: 38px; font-size: 16px; }
}


/* ---------- Grid de servicios (home) ---------- */
.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

@media (max-width: 900px) {
  .services-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .services-grid { grid-template-columns: 1fr; }
}

.service-card {
  display: block;
  background: var(--grad-green);
  border: none;
  border-radius: 20px;
  padding: 30px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  box-shadow: 0 12px 30px rgba(0,0,0,0.35);
}
.service-card:hover {
  transform: translateY(-4px) scale(1.01);
  box-shadow: 0 18px 40px rgba(0,0,0,0.45);
}
.service-card.card-gold { background: var(--grad-gold); }
.service-card.card-green { background: var(--grad-green); }
.service-card.card-orange { background: var(--grad-orange); }

/* Variante de alto contraste: para unidades cuyo logo (dorado/naranja)
   se perdía sobre un fondo del mismo color. Fondo neutro + borde de
   acento en vez de degradado del mismo tono que el logo. */
.service-card.card-neutral { background: var(--bg-card); border: 1px solid var(--border); }
.service-card.card-accent-gold { border-color: rgba(234, 179, 8, 0.4); box-shadow: 0 12px 30px rgba(234, 179, 8, 0.10); }
.service-card.card-accent-orange { border-color: rgba(249, 115, 22, 0.4); box-shadow: 0 12px 30px rgba(249, 115, 22, 0.10); }

/* 2026-09-15: se quitó el centrado de #unidades/#related-units -- el
   cliente pidió que TODAS las tarjetas de unidad (sin excepción, en
   cualquier página) queden alineadas arriba a la izquierda, con el mismo
   padding interior. El .service-card base ya es block + padding:30px
   uniforme; centrar el contenido como bloque además desalineaba
   verticalmente tarjetas con distinta cantidad de texto (una tarjeta
   corta quedaba "flotando" al medio, una larga pegada arriba). */

/* 2026-09-15: se quitó el aspect-ratio 3/4 de ".card-vertical" -- el cliente
   pidió que TODAS las tarjetas de unidad tuvieran el mismo diseño y tamaño
   (como en la imagen de referencia que compartió), sin la variante "alta"
   que tenían Celebrities & PR / Media House / Producción de Eventos. La
   clase sigue en el HTML por si se necesita en el futuro, pero ya no aplica
   ningún estilo distinto. */
.service-card .num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: rgba(255,255,255,0.75);
  margin-bottom: 14px;
  display: block;
}
.service-card h3 { font-size: 20px; margin-bottom: 10px; color: #fff; }
.service-card p { font-size: 1.2rem; line-height: 1.3; margin: 0; color: rgba(255,255,255,0.85); }
.service-card .card-logo { height: 68px; width: auto; max-width: 100%; margin-bottom: 14px; display: block; object-fit: contain; }
/* #related-units ahora usa el mismo tamaño de tarjeta grande que #unidades (ver reglas arriba) */

/* ---------- Carrusel de unidades (home) ---------- */
/* 2026-09-15: el carrusel dejó de ser full-bleed (ancho completo del
   viewport) -- eso forzaba a las imágenes de fondo a estirarse mucho más
   de su resolución real y se veían pixeladas. Ahora vive contenido dentro
   del mismo max-width que el resto del sitio, con el mismo radius de 20px
   que las demás tarjetas/imágenes grandes. */
.carousel {
  max-width: var(--max-width);
  margin: 28px auto 0;
  padding: 0 24px;
}
.carousel-inner {
  position: relative;
  width: 100%;
  height: 560px;
  overflow: hidden;
  border-radius: 20px;
}
.carousel-track {
  display: flex;
  height: 100%;
  transition: transform 0.6s cubic-bezier(0.65, 0, 0.35, 1);
}
.carousel-slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: flex-end;
}
.carousel-slide::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.25) 55%, rgba(0,0,0,0.05) 100%);
}
.carousel-content {
  position: relative;
  z-index: 2;
  padding: 48px 56px;
  max-width: 560px;
}
.carousel-content .eyebrow { color: #fff; opacity: 0.8; }
.carousel-logo {
  height: 6rem;
  width: 100%;
  object-fit: contain;
  object-position: left center;
  display: block;
  margin-bottom: 16px;
  filter: drop-shadow(0 2px 10px rgba(0,0,0,0.45));
}
.carousel-content p {
  color: rgba(255,255,255,0.88);
  margin-bottom: 24px;
  font-size: 15px;
  max-width: 460px;
}
.btn-carousel {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: 13px;
  padding: 13px 26px;
  border-radius: 999px;
  background: #fff;
  color: #0a0a0a;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.btn-carousel:hover { transform: translateY(-2px); opacity: 0.9; }
.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(10,10,10,0.55);
  border: 1px solid rgba(255,255,255,0.25);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
}
.carousel-arrow:hover { background: rgba(10,10,10,0.8); }
.carousel-arrow.prev { left: 20px; }
.carousel-arrow.next { right: 20px; }
.carousel-dots {
  position: absolute;
  bottom: 22px;
  right: 32px;
  z-index: 3;
  display: flex;
  gap: 8px;
}
.carousel-dots button {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.6);
  background: transparent;
  padding: 0;
  cursor: pointer;
}
.carousel-dots button.active { background: #fff; }
@media (max-width: 760px) {
  .carousel-inner { height: 460px; }
  .carousel-content { padding: 32px 24px; }
  .carousel { padding: 0 20px; }
  /* 2026-09-17 (ronda 39): en mobile las flechas quedaban encima del
     texto/logo de la tarjeta (el contenido usa casi todo el ancho
     disponible en pantallas angostas) -- se quitan y en su lugar el
     carrusel ya responde a swipe con el dedo (ver js/carousel.js), que
     es como cualquier usuario de celular espera navegarlo de por si. */
  .carousel-arrow { display: none; }
}

/* ---------- Bloques de categorías (páginas de servicio) ---------- */
.category-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 20px;
}

.category-card {
  background: var(--title-grad, var(--grad-green));
  border: none;
  border-radius: 20px;
  padding: 28px;
  box-shadow: 0 12px 30px rgba(0,0,0,0.3);
}

.category-card h3 {
  font-size: 15px;
  letter-spacing: 0.04em;
  margin-bottom: 16px;
  color: #fff;
}

.category-card ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.category-card li {
  font-size: 15px;
  color: rgba(255,255,255,0.92);
  padding-left: 18px;
  position: relative;
}

.category-card li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
}

/* ---------- Categorías con imagen + lista de íconos (páginas de servicio) ---------- */
.feature-row {
  display: flex;
  align-items: center;
  gap: 56px;
  padding: 56px 0;
  border-bottom: 1px solid var(--border);
}
.feature-row:last-child { border-bottom: none; }
.feature-row.reverse { flex-direction: row-reverse; }
.feature-media {
  flex: 0 0 42%;
  aspect-ratio: 4 / 3;
  border-radius: 20px;
  overflow: hidden;
  position: relative;
  background: var(--bg-card);
}
.feature-media img.feature-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.feature-media.feature-media-grad {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}
.feature-media-logo {
  width: 68%;
  max-height: 45%;
  object-fit: contain;
  filter: drop-shadow(0 2px 10px rgba(0,0,0,0.35));
}
.feature-content { flex: 1 1 auto; min-width: 0; }
.feature-content h3 {
  font-size: clamp(20px, 2.6vw, 26px);
  margin-bottom: 22px;
}
.icon-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.icon-list.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 28px;
}
.icon-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  color: var(--fg);
}
.icon-list .icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--accent-green);
}
@media (max-width: 760px) {
  .feature-row, .feature-row.reverse {
    flex-direction: column;
    gap: 28px;
    padding: 36px 0;
  }
  .feature-media { flex-basis: auto; width: 100%; }
  .icon-list.two-col { grid-template-columns: 1fr; }
}

/* ---------- Bento de datos y argumentos (home) ---------- */
.bento-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1.1fr;
  gap: 20px;
}
.bento-card {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 32px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color 0.3s ease;
}
.bento-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(480px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,0.16), transparent 45%);
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.bento-card:hover::after { opacity: 1; }
.bento-card:hover { border-color: rgba(255,255,255,0.22); }
.bento-card h3 {
  font-size: clamp(20px, 2.4vw, 26px);
  line-height: 1.2;
  margin-bottom: 14px;
}
.bento-card p {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
}
.bento-card .bento-link {
  margin-top: auto;
  padding-top: 18px;
  font-size: 14px;
  font-weight: 700;
  color: var(--accent-green);
}
.bento-fact { justify-content: space-between; }
.bento-fact .eyebrow-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.bento-fact .arrow-badge {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--bg-alt);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--fg);
}
.bento-fact .fact-number {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(48px, 6vw, 72px);
  line-height: 1;
  margin: 24px 0 14px;
}
.bento-fact .fact-number sup {
  font-size: 0.4em;
  font-weight: 700;
  vertical-align: super;
}
.bento-image {
  position: relative;
  padding: 0;
  overflow: hidden;
  min-height: 260px;
  grid-row: span 1;
}
.bento-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.bento-image::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.75) 100%);
}
.bento-image .bento-image-content {
  position: relative;
  z-index: 1;
  margin-top: auto;
  padding: 20px 28px;
  color: #fff;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(3px);
}
.bento-image .bento-image-content h3 { color: #fff; }
.bento-image .bento-image-content .bento-link { color: var(--accent-green); }
.bento-process { grid-column: span 2; }
.bento-process-inner {
  display: flex;
  gap: 40px;
  align-items: center;
  flex-wrap: wrap;
}
.bento-process-text { flex: 1 1 260px; }
.bento-process .roadmap { flex: 1 1 320px; padding-top: 20px; }
.bento-process .roadmap-step .node { width: 44px; height: 44px; font-size: 13px; }
.bento-process .roadmap-step h3 { font-size: 13px; margin: 0; }
@media (max-width: 900px) {
  .bento-grid { grid-template-columns: 1fr 1fr; }
  .bento-image { grid-column: span 2; }
  .bento-process { grid-column: span 2; }
}
@media (max-width: 640px) {
  .bento-grid { grid-template-columns: 1fr; }
  .bento-image, .bento-process { grid-column: span 1; }
  .bento-process-inner { flex-direction: column; align-items: stretch; }
}

/* ---------- Animación al hacer scroll (Unidades de Negocio) ---------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.in-view { opacity: 1; transform: translateY(0); }
.services-grid .reveal:nth-child(2) { transition-delay: 0.08s; }
.services-grid .reveal:nth-child(3) { transition-delay: 0.16s; }
.services-grid .reveal:nth-child(4) { transition-delay: 0.24s; }
.services-grid .reveal:nth-child(5) { transition-delay: 0.32s; }
.services-grid .reveal:nth-child(6) { transition-delay: 0.4s; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Grid de logos (ecosistema, La Agencia) ---------- */
.logo-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 16px;
}
.logo-grid a {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 16px;
  min-height: 120px;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.logo-grid a:hover { transform: translateY(-3px); border-color: rgba(255,255,255,0.3); }
.logo-grid img { height: 56px; width: auto; max-width: 100%; object-fit: contain; display: block; }
@media (max-width: 900px) { .logo-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px) { .logo-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Roadmap / proceso (Cómo trabajamos) ---------- */
.roadmap {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  position: relative;
  gap: 12px;
  padding-top: 8px;
}
.roadmap::before {
  content: '';
  position: absolute;
  top: 29px;
  left: 4%;
  right: 4%;
  height: 2px;
  background: var(--border);
  z-index: 0;
}
.roadmap::after {
  content: '';
  position: absolute;
  top: 29px;
  left: 4%;
  right: 4%;
  height: 2px;
  background: linear-gradient(90deg, var(--accent-green), var(--accent-gold), var(--accent-orange), var(--accent-green));
  z-index: 0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.6s cubic-bezier(0.65, 0, 0.35, 1);
}
.roadmap.in-view::after { transform: scaleX(1); }
.roadmap-step {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  flex: 1;
  gap: 14px;
}
.roadmap-step .node {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--bg-card);
  border: 2px solid var(--accent-green);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 18px;
  color: var(--accent-green);
}
.roadmap-step:nth-child(2) .node { border-color: var(--accent-gold); color: var(--accent-gold); }
.roadmap-step:nth-child(3) .node { border-color: var(--accent-orange); color: var(--accent-orange); }
.roadmap-step:nth-child(4) .node { border-color: var(--accent-green); color: var(--accent-green); }
.roadmap-step h3 {
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg);
  margin: 0;
}
@media (max-width: 700px) {
  .roadmap { flex-direction: column; align-items: flex-start; gap: 28px; }
  .roadmap::before { display: none; }
  .roadmap::after { display: none; }
  .roadmap-step { flex-direction: row; text-align: left; }
}

/* ---------- Franja de logos / clientes ---------- */
/* 2026-09-15 (ronda 10): el cliente pidio mas espacio entre los grupos
   de logos (Medios / Clubes deportivos) -- se sube de 36px a 72px. */
.logo-group + .logo-group { margin-top: 72px; }
.logo-group-label {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0.7;
  margin-bottom: 18px;
}
.logo-group { text-align: center; }
.logo-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 40px;
  opacity: 0.85;
}
.logo-strip img {
  height: 48px;
  width: auto;
  max-width: 180px;
  object-fit: contain;
}

/* ---------- Marquee infinito de logos (Aliados, home) ---------- */
.logo-marquee {
  position: relative;
  overflow: hidden;
  width: 100%;
}
.logo-marquee::before,
.logo-marquee::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 120px;
  z-index: 2;
  pointer-events: none;
}
.logo-marquee::before { left: 0; background: linear-gradient(90deg, var(--bg-alt) 0%, transparent 100%); }
.logo-marquee::after { right: 0; background: linear-gradient(270deg, var(--bg-alt) 0%, transparent 100%); }
.logo-track {
  display: flex;
  align-items: center;
  gap: 56px;
  width: max-content;
  opacity: 0.85;
  animation: logo-marquee-scroll 32s linear infinite;
}
.logo-track-reverse { animation-direction: reverse; animation-duration: 36s; }
.logo-track img {
  height: 48px;
  width: auto;
  max-width: 180px;
  object-fit: contain;
  flex-shrink: 0;
}
.logo-marquee:hover .logo-track { animation-play-state: paused; }
@media (max-width: 640px) {
  .logo-marquee::before,
  .logo-marquee::after {
    width: 36px;
  }
}
@keyframes logo-marquee-scroll {
  /* El track ahora repite el set base 3 veces (ver HTML) para que el
     carrusel nunca se quede sin logos que mostrar en pantallas anchas
     -- el loop sigue siendo del ancho exacto de UN set (33.3334% del
     track total de 3 copias), así que la velocidad no cambia. */
  from { transform: translateX(0); }
  to { transform: translateX(-33.3334%); }
}
@media (prefers-reduced-motion: reduce) {
  .logo-track { animation: none; }
}

/* ---------- CTA final ---------- */
.cta-band {
  position: relative;
  background-image:url('assets/images/hero-bg.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 0;
  padding: 8rem;
  aspect-ratio: 1800 / 688;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0;
  overflow: hidden;
  isolation: isolate;
  width: 100%;
}
@media (max-width: 760px) {
  /* 2026-09-17 (rondas 39 y 40): en mobile el bloque de texto+boton
     (centrado verticalmente) ocupaba casi todo el alto de la seccion,
     dejando muy poco margen hacia abajo -- los iconos que "caen" y se
     asientan cerca del borde inferior (bottom: 6%-26% del alto de la
     seccion, puesto inline por icono en el HTML) terminaban superpuestos
     con el boton y el texto. Subir solo el min-height (ronda 39, a
     620px) no fue suficiente -- el rango de 6%-26% sigue siendo un
     porcentaje amplio del alto total, asi que los iconos con mayor
     porcentaje (20%-26%) seguian llegando hasta la altura del boton.
     Ronda 40: ademas de subir el min-height a 720px, se fuerza un
     bottom fijo y chico (3%) para TODOS los iconos en mobile -- quedan
     alineados en una sola fila cerca del borde inferior, muy por debajo
     del boton, en vez de escalonados en un rango que en pantallas
     angostas invade el bloque de texto. */
  .cta-band { padding: 4rem 2rem; aspect-ratio: auto; min-height: 720px; }
  .cta-icon { bottom: 3% !important; }
}
.cta-band::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.69);
  z-index: 0;
}
.cta-band > * { position: relative; z-index: 1; }
/* Los flashes y los iconos que caen viven DETRAS del texto (z-index:0),
   pero la regla de arriba pone z-index:1 a TODO hijo directo -- esta
   regla mas especifica (dos clases) le gana y los mantiene atras. */
.cta-band > .camera-flashes,
.cta-band > .cta-icons { position: absolute; z-index: 0; }
/* 2026-09-15 (ronda 14): el cliente pidio texto mas grande en el CTA
   final -- subio de clamp(26-40px) a clamp(32-56px), y el boton gano su
   propio tamano (antes heredaba el .btn generico de 15px/14px 28px). */
.cta-band h2 { font-size: clamp(40px, 6vw, 88px); color: #ffffff; }
/* 2026-09-15 (ronda 16): subtitulo/hook nuevo debajo del titulo del CTA,
   pedido por el cliente. */
.cta-band .cta-sub {
  font-size: clamp(16px, 2vw, 19px);
  color: var(--muted);
  max-width: 520px;
  margin: 14px auto 0;
}
.cta-band .btn { margin-top: 16px; }
.cta-band .btn-primary { font-size: 18px; padding: 18px 40px; }

/* ---------- CTA: iconos que caen y se asientan (favicon de Alter) ----------
   2026-09-15 (ronda 14): a pedido del cliente, tomando como referencia una
   imagen con iconos cayendo desde arriba y deteniendose en la parte de
   abajo de la seccion al entrar en el viewport -- en vez de caras felices,
   se usa el favicon de Alter. Se dispara una sola vez por pagina via
   IntersectionObserver (misma infraestructura que .reveal/.roadmap, ver
   js/reveal.js -- se agrego ".cta-band" a la lista de selectores que
   observa). Cada icono tiene su propia posicion/tamano/delay/rotacion
   final puestos inline en el HTML (mas simple que 12 clases nuevas). */
.cta-icons {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.cta-icon {
  position: absolute;
  border-radius: 22%;
  opacity: 0;
  box-shadow: 0 10px 24px rgba(0,0,0,0.35);
  transform: translateX(-50%) translateY(-420px) rotate(0deg);
}
.cta-band.in-view .cta-icon {
  animation-name: ctaIconDrop;
  animation-duration: 0.9s;
  animation-timing-function: cubic-bezier(.17,.89,.32,1.4);
  animation-fill-mode: forwards;
}
@keyframes ctaIconDrop {
  0%   { opacity: 0; transform: translateX(-50%) translateY(-420px) rotate(0deg); }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) rotate(var(--rot, 0deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .cta-icon { animation: none !important; opacity: 1; transform: translateX(-50%); }
}

/* ---------- Testimoniales: espacios reservados, sin contenido de relleno ---------- */
.testimonial-slot {
  border: 1px dashed var(--border);
  border-radius: 16px;
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 180px;
  justify-content: center;
  color: var(--muted);
}
.testimonial-slot .quote-mark { font-size: 32px; color: var(--accent-green); opacity: 0.5; line-height: 1; }
.testimonial-slot p { font-size: 14px; line-height: 1.6; margin: 0; }

/* Tarjetas de muestra — contenido de ejemplo, marcado como tal, mientras llegan los testimonios reales */
.testimonial-card {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 200px;
}
.testimonial-card .quote-mark { font-size: 32px; color: var(--accent-green); opacity: 0.6; line-height: 1; }
.testimonial-card p.quote { font-size: 14px; line-height: 1.6; margin: 0; color: var(--fg); flex: 1; }
.testimonial-card .testimonial-author { font-size: 13px; color: var(--muted); }
.testimonial-card .testimonial-author strong { color: var(--fg); display: block; font-size: 14px; }
.testimonial-tag {
  position: absolute;
  top: 16px;
  right: 16px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-gold);
  border: 1px solid rgba(234, 179, 8, 0.4);
  border-radius: 999px;
  padding: 4px 10px;
}

/* ---------- Footer ---------- */
footer.site-footer {
  border-top: 1px solid var(--border);
  padding: 56px 24px 32px;
  margin-top: 40px;
  position: relative;
  overflow: hidden;
}
.footer-watermark {
  display: block;
  width: 90%;
  max-width: 1400px;
  margin: 40px auto 0;
  opacity: 0.06;
  user-select: none;
  pointer-events: none;
}
.footer-grid {
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 32px;
}
.footer-col h4 {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  color: var(--muted);
  margin-bottom: 14px;
}
.footer-col a, .footer-col p { display: block; font-size: 14px; margin-bottom: 8px; }
.footer-bottom {
  max-width: var(--max-width);
  margin: 32px auto 0;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
/* 2026-09-15 (ronda 30): link a la política de privacidad, ubicación
   estándar (footer, junto al copyright), solo texto. */
.footer-bottom-links { display: inline-flex; align-items: center; gap: 8px; }
.footer-bottom-links a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.footer-bottom-links a:hover { color: var(--fg); }
.footer-bottom-sep { opacity: 0.5; }
.footer-social {
  display: flex;
  gap: 12px;
  margin-top: 16px;
}
.footer-social-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--fg);
  transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.footer-social-link:hover {
  border-color: var(--accent-green);
  color: var(--accent-green);
  transform: translateY(-2px);
}

/* ---------- Galería de imágenes ---------- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 140px;
  grid-auto-flow: dense;
  gap: 14px;
}
.gallery-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 14px;
}
.gallery-grid .tall { grid-row: span 2; }
.gallery-grid .wide { grid-column: span 2; }
.gallery-grid img { cursor: zoom-in; }
.gallery-grid video {
  width: 100%;
  height: 100%;
  object-fit: fill;
  border-radius: 14px;
  background: #000;
  display: block;
}
.gallery-grid-full { grid-auto-rows: 200px; }
@media (max-width: 760px) {
  .gallery-grid-full { grid-auto-rows: 160px; }
}

/* ---------- Venue grid (Estadio Banorte / Estadio BBVA) ---------- */
.venue-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
.venue-grid figure {
  margin: 0;
  position: relative;
  border-radius: 14px;
  overflow: hidden;
}
.venue-grid img {
  width: 100%;
  height: 320px;
  object-fit: cover;
  display: block;
}
.venue-grid figcaption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 16px 20px;
  background: linear-gradient(to top, rgba(0,0,0,0.75), transparent);
  color: #fff;
  font-weight: 600;
  font-size: 0.95rem;
}
@media (max-width: 760px) {
  .venue-grid { grid-template-columns: 1fr; }
  .venue-grid img { height: 220px; }
}
.venue-video-grid { margin-top: 20px; }
.venue-video {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: #0a0a0a;
}
.venue-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- Scroll-video (video que crece a pantalla completa al hacer scroll) ---------- */
.scroll-video-section {
  position: relative;
  height: 280vh;
}
.scroll-video-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #050505;
}
.scroll-video-frame {
  --p: 0;
  --small-w: min(680px, 86vw);
  --small-h: calc(var(--small-w) * 9 / 16);
  position: relative;
  width: calc(var(--small-w) + (100vw - var(--small-w)) * var(--p));
  height: calc(var(--small-h) + (100vh - var(--small-h)) * var(--p));
  max-width: 100vw;
  max-height: 100vh;
  border-radius: calc(20px * (1 - var(--p)));
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, calc(0.55 * (1 - var(--p))));
}
.scroll-video-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: #0a0a0a;
}
.scroll-video-sound {
  position: absolute;
  bottom: 24px;
  right: 24px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(10, 10, 10, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(8px);
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.scroll-video-frame.is-full .scroll-video-sound {
  opacity: 1;
  pointer-events: auto;
}
.scroll-video-sound svg { width: 22px; height: 22px; }
.scroll-video-sound .icon-unmuted { display: none; }
.scroll-video-sound.is-unmuted .icon-muted { display: none; }
.scroll-video-sound.is-unmuted .icon-unmuted { display: block; }
@media (max-width: 760px) {
  .scroll-video-section { height: 220vh; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-video-frame { transition: none; }
}

/* ---------- Lightbox (galería a pantalla completa) ---------- */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(6, 6, 6, 0.92);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 40px;
  cursor: zoom-out;
}
.lightbox-overlay.open { display: flex; }
.lightbox-overlay img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.lightbox-close {
  position: absolute;
  top: 24px;
  right: 28px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: rgba(255,255,255,0.06);
  color: var(--fg);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

@media (max-width: 760px) {
  .gallery-grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 160px; }
}

/* ---------- Bloque de video / reel ---------- */
.reel-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
}
.reel-video-wrap {
  position: relative;
  flex: 0 1 260px;
  width: 260px;
  max-width: 100%;
  min-width: 0;
  border-radius: 20px;
  overflow: hidden;
  aspect-ratio: 9 / 16;
  background: #000;
  box-shadow: 0 12px 30px rgba(0,0,0,0.35);
}
@media (max-width: 480px) {
  .reel-video-wrap { flex-basis: 220px; width: 220px; }
}
.reel-video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------- Manifiesto ---------- */
.manifesto p {
  font-size: clamp(20px, 3vw, 28px);
  color: var(--fg);
  line-height: 1.5;
  font-weight: 500;
}

/* ---------- Unidades relacionadas (páginas de servicio) ---------- */
/* #related-units ahora usa el grid de 3 columnas estándar de .services-grid */

/* ---------- Logos de unidad en el footer ---------- */
.footer-col-units {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 22px;
  row-gap: 16px;
  max-width: 260px;
}
.footer-logo-link {
  display: block;
  margin-bottom: 0;
  opacity: 0.9;
  transition: opacity 0.15s ease;
}
.footer-logo-link:hover { opacity: 1; }
.footer-logo-link img {
  height: 30px;
  width: auto;
  object-fit: contain;
}
