/* ==========================================================================
   Thinkhub — Estilos de la maqueta
   Estructura reescrita con flex/grid. Los VALORES (colores, tamaños, spacing)
   vienen del export de Figma; el LAYOUT es propio para que sea responsive.
   ========================================================================== */

/* --- Reset mínimo --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body, h1, h2, h3, p, figure, ul, ol { margin: 0; padding: 0; }

/* `ol` va junto con `ul`: el navegador le pone `padding-inline-start: 40px` y
   `margin-block: 1em` propios, y las cuatro listas numeradas del sitio
   (`.dif__list`, `.pilares__list`) son grillas que no los quieren. */
ul, ol { list-style: none; }

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

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

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

html { scroll-behavior: smooth; }

/* La navbar es fija, así que un salto a un ancla dejaría el arranque de la
   sección tapado debajo. El margen de scroll la baja lo justo. */
:target { scroll-margin-top: calc(var(--navbar-h) + var(--sp-24)); }

body {
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  color: var(--c-white);
  background: var(--c-dark);
  -webkit-font-smoothing: antialiased;
}

/* --- Utilidades ----------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

.section {
  padding-inline: var(--gutter);
}

.caption {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
}

.caption--orange { color: var(--c-orange); }

/* Saltos de línea que el diseño fuerza sólo en ciertos breakpoints.
   `display:none` sobre un <br> anula el salto. */
.br--nomobile,
.br--notablet { display: inline; }

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

/* --- Botones -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: 10px var(--sp-24);
  font-size: var(--fs-button);
  line-height: var(--lh-button);
  font-weight: var(--fw-medium);
  border-radius: var(--r-button);
  /* El prototipo escala el botón a 1.1 en hover, sin mover ni cambiar opacidad. */
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.btn--primary:hover,
.btn--outline:hover { transform: scale(var(--hover-scale)); }

/* Los links de texto no escalan: bajan a opacidad 0.6. */
.btn--text:hover { opacity: var(--hover-op); }

.btn--primary {
  background: var(--grad-primary);
  color: var(--c-white);
}

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

.btn--text {
  padding: 0;
  color: var(--c-orange);
}

/* Ícono arrow_outward del diseño (extraído del .fig). Va como mask para que
   tome el color del link en vez de tener uno propio. */
.btn--text::after {
  content: '';
  width: 12px;
  height: 12px;
  flex: none;
  background: currentColor;
  -webkit-mask: url('../img/icons/arrow-outward.svg') center / contain no-repeat;
  mask: url('../img/icons/arrow-outward.svg') center / contain no-repeat;
}

/* CTA de dos piezas pegadas: círculo con la flecha + pastilla con el texto.
   El círculo lleva borde naranja y la pastilla borde violeta. La flecha es
   un carácter "↗" (no mask-image): un SVG en mask no pinta al abrir el
   archivo por file://, que es como Juan navega el sitio en local — mismo
   criterio que .caso__cta .arrow en /exitos, cuyo hover (círculo que gira
   45° y se rellena de naranja) es la referencia para este componente.
   OJO: /exitos (.closing-quote__cta) y /caso (.destacado__cta) tienen su
   propia copia de esto, anterior; conviene apuntarlas acá en algún momento. */
.cta-arrow {
  display: inline-flex;
  align-items: center;
  color: var(--c-white);
}

.cta-arrow__icon,
.cta-arrow__label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 42px;
  border-radius: var(--r-button);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.cta-arrow__icon {
  width: 42px;
  border: 1px solid var(--c-orange);
  color: var(--c-orange);
  font-size: 17px;
  line-height: 1;
}

.cta-arrow__icon::before {
  content: '↗';
}

.cta-arrow__label {
  padding-inline: var(--sp-24);
  border: 1px solid var(--c-violet);
  font-size: var(--fs-button);
  line-height: var(--lh-button);
  font-weight: var(--fw-medium);
}

.cta-arrow:hover .cta-arrow__icon {
  transform: scale(var(--hover-scale)) rotate(45deg);
  background: var(--c-orange);
  color: var(--c-dark);
}
.cta-arrow:hover .cta-arrow__label {
  transform: scale(var(--hover-scale));
  border-color: var(--c-orange);
}

/* --- Navbar --------------------------------------------------------------- */
.navbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--navbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: var(--gutter);
  background: var(--surface-navbar);
  backdrop-filter: var(--blur-navbar);
  -webkit-backdrop-filter: var(--blur-navbar);
  color: var(--c-dark);
  /* La variante se cambia en vivo según la banda que quede detrás
     (setupNavbarTone en motion.js): el cambio va cruzado, no de golpe. */
  transition: color var(--dur) var(--ease);
}

/* El logo tiene dos SVG, no un color: el iso queda naranja y lo que cambia es
   la palabra (#212224 ↔ #FFFFFF). Un `filter: invert()` sobre el naranja daría
   azul, así que van los dos apilados y se cruza la opacidad junto con la
   variante de la navbar. */
.navbar__logo {
  position: relative;
  width: 156px;
  height: 42px;
}

/* Miden lo que mida el <a>, que en mobile baja a 135×36. */
.navbar__logo-dark,
.navbar__logo-light {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity var(--dur) var(--ease);
}

.navbar__logo-light { opacity: 0; }

.navbar--light .navbar__logo-dark  { opacity: 0; }
.navbar--light .navbar__logo-light { opacity: 1; }

.navbar__links {
  display: flex;
  align-items: center;
  gap: 44px;
}

.navbar__links a {
  font-size: var(--fs-button);
  line-height: var(--lh-button);
  font-weight: var(--fw-medium);
  transition: opacity var(--dur) var(--ease);
}

.navbar__links a:not(.btn):hover { opacity: var(--hover-op); }

.navbar__toggle { display: none; }

/* --- Navbar claro --------------------------------------------------------
   El componente tiene variantes `Color=Black` (texto #212224) y `Color=White`
   (texto #FFFFFF). La clase del HTML es el estado inicial —y el fallback sin
   JS—, pero a partir de ahí la elige `setupNavbarTone()` mirando qué banda
   tiene detrás: hay páginas que cambian de fondo a mitad (/hablemos arranca
   oscura y termina clara, /nosotros al revés) y una sola variante fija dejaba
   texto blanco sobre `#E8E9DD`. */
.navbar--light { color: var(--c-white); }

.navbar__toggle img { transition: filter var(--dur) var(--ease); }
.navbar--light .navbar__toggle img { filter: invert(1); }

/* --- Header (hero) --------------------------------------------------------
   Fondo = la animación de la maqueta provisoria, a sangre.

   En Figma el frame tiene un fill VIDEO con un GRADIENT_LINEAR encima, y así
   estaba maquetado. Dos problemas: el video del `.fig` es una **captura del
   prototipo** y trae el navbar pintado adentro —se veía un navbar fantasma
   asomando por la derecha, donde el gradiente ya es transparente—, y el
   gradiente tapa el 90% del ancho, así que de la animación no quedaba casi
   nada.

   La maqueta provisoria resuelve las dos: su `hero-bg.gif` es lavanda parejo
   con la trama de puntos, sin navbar y sin gradiente encima. Por eso el
   ::after de overlay ya no está. */
.header {
  position: relative;
  isolation: isolate;
  min-height: var(--header-h);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--sp-56) var(--gutter);
  padding-top: calc(var(--navbar-h) + var(--sp-56));
  color: var(--c-dark);
  background: var(--c-lavender);
  overflow: hidden;
}

.header__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.header__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-120);
}

.header__title {
  max-width: 991px;
  font-size: var(--fs-header);
  line-height: var(--lh-header);
  font-weight: var(--fw-bold);
  /* El diseño usa letterSpacing 0 en todos los textos. No hay tracking. */
  letter-spacing: 0;
}

.header__meta {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--sp-36);
}

/* --- Nosotros ------------------------------------------------------------- */
.about {
  padding-block: var(--sp-100);
  background: var(--c-dark);
}

.about__title {
  font-size: var(--fs-section);
  line-height: var(--lh-section);
  font-weight: var(--fw-bold);
  max-width: 718px;
  margin-bottom: var(--sp-64);
}

.about__grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-72);
  align-items: start;
}

.about__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-64);
  max-width: 820px;
}

.about__media {
  position: relative;
  width: 100%;
  aspect-ratio: 820 / 393;
  border-radius: var(--r-media);
  background: url('../img/home-nosotros.png') center / cover no-repeat;
  isolation: isolate;
}

/* Halo de marca detrás de la foto: naranja arriba-izq, violeta abajo-der. */
.about__media::before {
  content: '';
  position: absolute;
  inset: -10px;
  z-index: -1;
  border-radius: calc(var(--r-media) + 6px);
  background:
    radial-gradient(90% 110% at 10% 15%, var(--c-orange) 0%, transparent 35%),
    radial-gradient(90% 110% at 90% 88%, var(--c-violet) 0%, transparent 35%);
  filter: blur(18px);
  opacity: 0.4;
  pointer-events: none;
}

.about__text {
  font-size: var(--fs-paragraph-l);
  line-height: var(--lh-paragraph-l);
}

/* --- Soluciones ----------------------------------------------------------- */
.solutions {
  padding-block: var(--sp-120) var(--sp-100);
  background: var(--c-light);
  color: var(--c-dark);
  border-radius: var(--r-section) var(--r-section) 0 0;
}

.solutions__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-72);
  margin-bottom: var(--sp-72);
}

.solutions__lead {
  max-width: 654px;
  font-size: var(--fs-solutions);
  line-height: var(--lh-solutions);
  font-weight: var(--fw-medium);
}

/* Cards circulares que se solapan 26px. El solape va entre pares, así que el
   margen negativo tiene que ir sólo en las cards que siguen a otra — con
   `margin: 0 -26px` en todas, cada par se solapaba 52 y los bordes exteriores
   se comían 26 más.
   Desktop: una fila de 3 → 3×420 − 2×26 = 1208px, el mismo ancho de fila que
   tenían las 4 cards de 320 (1202). */
.solutions__list {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  margin-bottom: var(--sp-72);
}

.solutions__list > .solution-card + .solution-card { margin-left: -26px; }

.solution-card {
  position: relative;
  flex: 0 0 var(--card-size);
  width: var(--card-size);
  height: var(--card-size);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: var(--sp-26);
  padding: var(--sp-24);
  text-align: center;
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  background: transparent;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

/* --- Hover ----------------------------------------------------------------
   El aro toma el acento de la marca, que es el que ya trae el propio logo.
   No se rellena la card: los logos son multicolor, así que sobre un fondo
   pleno perderían su color. */
.solution-card:hover,
.solution-card:focus-within { border-color: var(--brand); }

.solution-card--core  { --brand: var(--c-orange); }
.solution-card--cloud { --brand: var(--c-violet); }
.solution-card--smart { --brand: var(--c-violet-deep); }

.solution-card__num {
  color: var(--c-orange);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
}

/* El logo va en % del diámetro, como en la maqueta provisoria, con un tope
   para que en desktop no se estire: ahí manda el tope y en las pantallas
   chicas manda el %. Cada marca tiene su proporción. */
.solution-card__logo {
  width: 74%;
  height: auto;
}

.solution-card--cloud .solution-card__logo { width: 78%; max-width: 245px; }
.solution-card--smart .solution-card__logo { width: 80%; max-width: 252px; }
.solution-card--core  .solution-card__logo { max-width: 230px; }

.solutions__cta { display: flex; justify-content: center; }

/* --- Puntos decorativos --------------------------------------------------- */
.dots {
  padding: var(--sp-100) var(--gutter) 0;
  background: var(--c-light);
}

/* Las filas son SPACE_BETWEEN con ancho fijo: Figma guarda un stackSpacing de 72
   pero NO lo aplica, porque space-between reparte el sobrante. La separación real
   entre centros es ~73.3px en desktop. Poner además `gap: 72px` sumaba al reparto
   y hacía desbordar la fila; por eso la grilla se veía mal. */
.dots__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--sp-36);
}

.dots__row:last-child { margin-bottom: 0; }

.dots__row span {
  flex: none;
  border-radius: 50%;
  background: var(--c-orange);
}

.dots__row--lg span { width: 8px; height: 8px; }
.dots__row--md span { width: 6px; height: 6px; }
.dots__row--sm span { width: 4px; height: 4px; }

/* --- Clientes ------------------------------------------------------------- */
.clients {
  padding-block: var(--sp-100);
  background: var(--c-light);
  color: var(--c-dark);
  text-align: center;
}

/* --- Marquesina de clientes ----------------------------------------------
   En el diseño la tira NO entra en el frame: mide 2254px en 1440 (1.57×), y en
   mobile 1085 en 375 (2.89×). Además en tablet y mobile el contenedor arranca
   en x negativo (−191 y −159), o sea centrado y desbordando por los dos lados.
   Eso es una marquesina, no un wrap.

   Figma no anima esto, así que la velocidad no está en el archivo: se fija en
   px/s (constante entre breakpoints) y la duración se deriva del ancho real de
   la tira, así los tres se mueven al mismo ritmo aparente. */
.clients__viewport {
  overflow: hidden;
  display: flex;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.clients__list {
  flex: none;
  display: flex;
  align-items: center;
  gap: calc(120px * var(--logo-scale));
  padding: calc(80px * var(--logo-scale)) 0;
  padding-inline-end: calc(120px * var(--logo-scale));
  animation: clients-marquee var(--marquee-dur) linear infinite;
}

.clients__viewport:hover .clients__list { animation-play-state: paused; }

@keyframes clients-marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-100%, 0, 0); }
}

/* Cada logo trae su medida del diseño, no una altura común: el equilibrio
   óptico ya viene resuelto ahí. */
.clients__list img {
  width: calc(var(--logo-w) * var(--logo-scale));
  height: auto;
  max-width: 100%;
}

/* Los logos usan el hover secundario (0.4). */
/* Atenuado del resto al apuntar uno (hover secundario, 0.4). Va sobre el
   viewport para que abarque las dos copias de la tira. */
.clients__list li { transition: opacity var(--dur) var(--ease); }
.clients__viewport:hover li { opacity: var(--hover-op-soft); }
.clients__viewport li:hover { opacity: 1; }

.clients__list img[alt="Modelo"]        { --logo-w: 158.35px; }
.clients__list img[alt="Camuzzi"]       { --logo-w: 165.83px; }
.clients__list img[alt="Rappi"]         { --logo-w: 144.42px; }
.clients__list img[alt="UCA"]           { --logo-w: 171.78px; }
.clients__list img[alt="La Serenísima"] { --logo-w: 164.94px; }
.clients__list img[alt="Santander"]     { --logo-w: 165.59px; }
.clients__list img[alt="Naranja X"]     { --logo-w: 165.63px; }
.clients__list img[alt="Sarkany"]       { --logo-w: 165.56px; }

/* --- Casos de éxito ------------------------------------------------------- */
/* `Cases` no tiene padding propio en el diseño: el padding vive en el
   encabezado (120/100) y en cada contenedor de caso. */
.cases {
  position: relative;
  background: var(--c-light);
  color: var(--c-dark);
  /* `overflow: hidden` acá anularía el position:sticky de las cards sin avisar.
     `clip` con overflow-y visible recorta el halo naranja igual pero deja
     funcionar el stack. */
  overflow-x: clip;
  overflow-y: visible;
}


/* El encabezado no es una línea de texto: en el diseño es un bloque de 837px de
   alto (`Case headlines container`, stackPrimarySizing FIXED) con el halo
   adentro y la caption abajo, separados por gap 72. Todo el bloque es
   STICKY_SCROLLS y queda fijo mientras las cards suben por delante.
   Padding: 120/56 arriba y 100 abajo en desktop. */
.cases__head {
  position: sticky;
  top: var(--case-stick-top);
  z-index: 0;
  height: var(--cases-head-h);
  padding: var(--cases-head-pt) 0 var(--cases-head-pb);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  isolation: isolate;
}

/* Halo radial. Es una elipse propia del encabezado, centrada al 50% en los tres
   breakpoints, con dos gradientes radiales superpuestos. El `top` es relativo
   al bloque, no a la sección. */
.cases__halo {
  position: absolute;
  z-index: -1;
  top: var(--halo-top);
  left: 50%;
  width: var(--halo-size);
  height: var(--halo-size);
  transform: translateX(-50%);
  border-radius: 50%;
  background: var(--grad-halo);
  pointer-events: none;
}

/* La caption va ARRIBA, a la altura del padding-top (y=120 en desktop), y
   alineada a la izquierda. La elipse no participa del auto-layout: está
   posicionada por detrás. */
.cases__head > .caption { position: relative; z-index: 1; }

/* --- Stack de casos ------------------------------------------------------
   El encabezado y las 3 cards tienen `scrollBehavior: STICKY_SCROLLS` en el
   .fig: al bajar, cada card se pega y la siguiente sube por encima, apilándose.
   Eso es lo que explican los stackSpacing negativos (-547 de la sección y -300
   del contenedor): no son solapes estáticos, son el recorrido del sticky.

   La separación entre cards salió de medir posiciones absolutas: 131/73/319. */
/* La lista sube 547px sobre el encabezado (stackSpacing -547 de `Cases`): las
   cards arrancan sobre el halo, que queda de fondo mientras se apilan. */
.cases__list {
  position: relative;
  z-index: 1;
  margin-top: calc(var(--cases-overlap) * -1);
  display: flex;
  flex-direction: column;
  gap: var(--case-gap);
}

.case-sticky {
  position: sticky;
  top: var(--case-stick-top);
}

/* Cada card se pega un poco más abajo que la anterior, así queda visible el
   borde superior de las que ya pasaron y se lee como una pila. */
.case-sticky:nth-child(1) { top: var(--case-stick-top); z-index: 1; }
.case-sticky:nth-child(2) { top: calc(var(--case-stick-top) + var(--case-stick-step)); z-index: 2; }
.case-sticky:nth-child(3) { top: calc(var(--case-stick-top) + var(--case-stick-step) * 2); z-index: 3; }

/* Nada de fondo opaco acá: el glass ES el efecto. El halo naranja vive detrás
   del stack justamente para verse difuminado a través de las cards, y taparlo
   con un `--c-light` sólido dejaba la card del mismo color que la sección (o
   sea, invisible) y el halo asomando crudo en los huecos entre cards.
   El `backdrop-filter` de cada card difumina lo que tenga debajo — halo o la
   card anterior — que es como se comporta un vidrio de verdad. */

.case-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-64);
  padding: var(--sp-36) var(--sp-36) var(--sp-60);
  background: var(--surface-glass);
  backdrop-filter: var(--blur-glass);
  -webkit-backdrop-filter: var(--blur-glass);
  border-radius: var(--r-card);
}

.case-card__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-32);
}

.case-card__logo {
  font-size: var(--fs-paragraph-m);
  font-weight: var(--fw-bold);
}

.case-card__grid {
  display: grid;
  grid-template-columns: 240px 240px 360px 320px;
  gap: var(--sp-36);
}

.case-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-28);
}

.case-field__label { opacity: 0.5; }

.case-field__value {
  font-size: var(--fs-paragraph-m);
  line-height: var(--lh-paragraph-m);
}

.case-field__value--sm {
  font-size: var(--fs-paragraph-xs);
  line-height: var(--lh-paragraph-xs);
}

.case-field__kpi {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.case-field__kpi strong {
  font-size: var(--fs-subheader);
  line-height: var(--lh-subheader);
  font-weight: var(--fw-bold);
}

.case-field__kpi span {
  font-size: var(--fs-subtitle);
  line-height: var(--lh-subtitle);
  font-weight: var(--fw-medium);
}

/* --- Imagen de cierre ----------------------------------------------------- */
/* Alto del frame Image por breakpoint: 495 / 275 / 206.

   No es un `cover`: en el diseño la esfera va más grande que el frame y corrida
   hacia arriba, de modo que sólo asoma el casquete y el ápice queda al ~28% del
   alto. Sobre el frame de 1440×495 el bitmap mide 115.31% del ancho (1660px, es
   cuadrado) y arranca en −803px. Como el ancho manda en las dos medidas, ambos
   valores van en vw — `.closing` es full-bleed — y así el encuadre se mantiene
   igual en tablet y mobile aunque cambie `--closing-h`.

   El gradiente de arriba funde la imagen contra el #E8E9DD de la sección. */
.closing {
  height: var(--closing-h);
  background:
    var(--grad-fade-light),
    url('../img/cierre.jpg') center -55.79vw / 115.31vw auto no-repeat;
}


/* --- Footer --------------------------------------------------------------- */
/* El color de texto va explícito, no heredado: /soluciones y las landings son
   páginas claras con footer oscuro, y sin esto el texto quedaba #212224 sobre
   #212224 (invisible). */
.footer {
  padding: var(--sp-100) var(--gutter) var(--sp-56);
  background: var(--c-dark);
  color: var(--c-white);
}

.footer__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-72);
  margin-bottom: var(--sp-100);
}

/* Se escala por ALTURA, no por ancho: las dos variantes del logo tienen
   viewBox distinto (603×162 la oscura, 889×236 la clara), así que fijar el
   ancho daría alturas distintas. */
.footer__logo {
  height: var(--footer-logo-h);
  width: auto;
  max-width: 100%;
}

.footer__nav {
  display: flex;
  flex-direction: column;
  gap: 23px;
  padding-top: var(--sp-32);
}

.footer__nav a {
  font-size: var(--fs-footer-nav);
  line-height: var(--lh-footer-nav);
  font-weight: var(--fw-medium);
  transition: opacity var(--dur) var(--ease);
}

.footer__nav a:hover { opacity: var(--hover-op); }

/* "Hablemos" lleva el gradiente aplicado al texto. */
.footer__nav a.is-gradient {
  background: var(--grad-primary);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.footer__links {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
  padding-top: var(--sp-32);
}

/* En reposo van a 0.6 y el hover los lleva a 1: así está en el prototipo. */
.footer__links a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  font-size: var(--fs-button);
  line-height: var(--lh-button);
  font-weight: var(--fw-medium);
  opacity: var(--hover-op);
  transition: opacity var(--dur) var(--ease);
}

/* Cada link de la columna derecha cierra con el arrow_outward. En el diseño el
   ícono es una caja de 24 con el glifo de 12.08 centrado (no el glifo a 24),
   por eso van el tamaño de la caja y el del mask por separado. Como mask sobre
   currentColor, sigue al color del footer claro sin una segunda copia del SVG. */
.footer__links a::after {
  content: '';
  width: 24px;
  height: 24px;
  flex: none;
  background: currentColor;
  -webkit-mask: url('../img/icons/arrow-outward.svg') center / 12.08px no-repeat;
  mask: url('../img/icons/arrow-outward.svg') center / 12.08px no-repeat;
}

.footer__links a:hover { opacity: 1; }

.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-36);
  color: var(--c-footer-text);
}

/* El legal del diseño es 8px con 1px de tracking, no un caption de 14px. */
.footer__legal {
  font-size: 8px;
  line-height: 8px;
  font-weight: var(--fw-medium);
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* Los íconos vienen en blanco con el hueco en el color del footer. */
.footer__social {
  display: flex;
  gap: var(--sp-24);
}

.footer__social img { width: 24px; height: 24px; }

.footer__social a { transition: opacity var(--dur) var(--ease); }
.footer__social a:hover { opacity: var(--hover-op); }

/* --- Footer claro --------------------------------------------------------
   El componente tiene dos variantes: `Color=Black` (fondo #212224) y
   `Color=White` (fondo #E8E9DD). No es sólo invertir el fondo — cambian tres
   cosas más:
     · el legal pasa de 8px/#C4C6C5 a 14px/#212224
     · los links secundarios pasan a oscuro
     · los íconos sociales intercambian sus DOS colores, no se filtran
   Se usa en /exitos, /nosotros y /hablemos. */
.footer--light {
  background: var(--c-light);
  /* Explícito: el footer no puede heredar el color de texto de la página,
     porque cada una tiene el suyo (/exitos es oscura, /nosotros termina
     oscura, /hablemos claro). Todo lo de adentro parte de acá. */
  color: var(--c-dark);
}

/* El logo NO se invierte con un filtro: `invert()` sobre el naranja da azul.
   La variante clara es otro SVG (iso #FF5800 + wordmark #212224) y se apunta
   desde el `src` de cada página, no desde acá. */

/* Los links heredan `color: inherit` del reset, así que con el color del
   contenedor alcanza — salvo los que tienen color propio. */
.footer--light .footer__nav a,
.footer--light .footer__links a { color: var(--c-dark); }

.footer--light .footer__bottom { color: var(--c-dark); }

/* En la variante clara el legal es 14px en #212224, no 8px en #C4C6C5. */
.footer--light .footer__legal {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: 1px;
  color: var(--c-dark);
}

/* ==========================================================================
   Responsive
   Los paddings y direcciones de flex de acá salen de los frames Tablet (800px)
   y Mobile (375px) del export, no de una escala inventada.
   ========================================================================== */

@media (max-width: 1100px) {
  /* En tablet «Agentes de la transformación» va sin salto. */
  .br--notablet { display: none; }

  /* En tablet la navbar NO es burger: el componente Device=Tablet mantiene los
     4 links con gap 44, igual que desktop. El burger es sólo de mobile. */
  .navbar { padding: 20px var(--gutter); }

  /* Nosotros: 84px 36px */
  .about { padding-block: var(--sp-84); }
  .about__grid { grid-template-columns: 1fr; gap: var(--sp-36); }
  .about__body { gap: var(--sp-56); }

  /* Soluciones: 100px 36px (simétrico, a diferencia de desktop) */
  .solutions { padding-block: var(--sp-100); }

  /* En tablet los 3 círculos siguen en una fila: sólo se achican. */

  /* Clientes: 80px 0 */
  .clients { padding-block: var(--sp-80); }

  .case-card { gap: var(--sp-36); }
  .case-card__grid { grid-template-columns: repeat(2, 1fr); }

  /* Footer: 100px 36px 36px */
  .footer { padding: var(--sp-100) var(--gutter) var(--sp-36); }
  .footer__top { flex-direction: column; gap: var(--sp-56); }

}

@media (max-width: 640px) {
  /* En mobile el titular y la bajada de Nosotros fluyen sin salto forzado. */
  .br--nomobile { display: none; }
  .br--notablet { display: inline; }

  /* Mobile: el logo NO va centrado. En el `.fig` la variante `Device=Mobile`
     es el mismo `SPACE_BETWEEN` que las otras dos — logo a la izquierda contra
     el padding de 24 (x=24) y el burger contra el derecho (x=327 en 375, que
     es 375−24−24). Lo único que cambia respecto de tablet es que los links se
     esconden, aparece el burger y el logo baja de 156×42 a 135×36. */
  .navbar { padding: var(--sp-24); }
  .navbar__links { display: none; }
  .navbar__toggle { display: block; }
  .navbar__logo { width: 135px; height: 36px; }

  /* El header no cambia de reglas acá: alto (--header-h), gap 120 y padding
     56/--gutter ya dan los valores del frame mobile (837px, gap 120, 56px 24px).

     El meta sigue en fila; el diseño oculta la categoría del medio. */
  .header__meta > .caption:nth-child(2) { display: none; }

  /* Nosotros: 64px 24px */
  .about { padding-block: var(--sp-64); }
  .about__body { gap: var(--sp-36); }

  /* Soluciones: 100px 24px. La bajada y el caption se apilan (gap 34). */
  .solutions { padding-block: var(--sp-100); }

  /* En mobile sí es una columna: 3 círculos de 260 con 26 de solape vertical. */
  .solutions__list {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: var(--sp-72);
  }
  .solutions__list > .solution-card + .solution-card {
    margin-left: 0;
    margin-top: -26px;
  }
  .solutions__head {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-34);
  }

  /* En mobile el contenedor de casos tiene gap POSITIVO (+96): las cards no se
     apilan, van separadas y sin sticky. */
  .case-sticky,
  .case-sticky:nth-child(1),
  .case-sticky:nth-child(2),
  .case-sticky:nth-child(3) { position: static; top: auto; }

  /* Case: padding 24, gap 24 */
  .case-card { padding: var(--sp-24); gap: var(--sp-24); }
  .case-card__grid { grid-template-columns: 1fr; gap: var(--sp-28); }
  .case-card__top { flex-direction: column; align-items: flex-start; gap: var(--sp-24); }

  /* Clientes: 44px 0, gap 36 */
  .clients { padding-block: var(--sp-44); }


  /* Footer: 48px 24px 56px, gap interno 64 */
  .footer { padding: var(--sp-48) var(--gutter) var(--sp-56); }
  .footer__top { gap: var(--sp-64); }

  .footer__bottom { flex-direction: column; align-items: flex-start; gap: var(--sp-24); }

}

/* Con movimiento reducido: el video se congela y el stack de casos deja de
   apilarse (las cards pasan a scrollear normalmente). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* El canvas del header se queda: thinkhub-flow dibuja un solo cuadro fijo
     cuando se pide menos movimiento, así que la trama se ve pero no se anima. */

  .cases__head,
  .case-sticky,
  .case-sticky:nth-child(1),
  .case-sticky:nth-child(2),
  .case-sticky:nth-child(3) { position: static; top: auto; }

  /* La marquesina se detiene y la tira queda scrolleable a mano. */
  .clients__list { animation: none; }
  .clients__viewport { overflow-x: auto; }
  .clients__list[aria-hidden="true"] { display: none; }
  /* Ya no hace falta el poster del video viejo: el cuadro fijo del canvas
     hace de imagen estática, y así no se descarga un JPG de más. */
  .header { background: var(--c-lavender); }
}
