/* ==========================================================================
   arasaIT — Sistema de diseño
   --------------------------------------------------------------------------
   Modo oscuro por defecto. El claro se activa con [data-theme="light"] en <html>.
   Sin build, sin framework: CSS vanilla con custom properties.

   Índice
   01. Reset y base
   02. Tokens (oscuro por defecto + override claro)
   03. Utilidades de superficie: cristal, brillos, "on-dark"
   04. Layout: container, secciones, encabezados
   05. Botones
   06. Header, navegación y toggle de tema
   07. Hero
   08. Servicios
   09. Cómo trabajamos
   10. Banda de equipo
   11. Proyectos
   12. Cierre de contacto
   13. Páginas internas: encabezado, listas, casos y paneles
   14. Formulario de contacto
   15. Footer
   16. Responsive
   17. Accesibilidad y movimiento reducido
   ========================================================================== */

/* ==========================================================================
   01. Reset y base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  background: var(--bg);
  color: var(--text);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Las fotos se sirven en webp directo (sin <picture> ni fallback png): los
   png originales quedan en el repo como fuente pero no se referencian, para
   no arrastrar 10 MB a la imagen de producción. */
img,
svg {
  display: block;
  max-width: 100%;
}

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

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

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  margin: 0;
  color: var(--text-strong);
  letter-spacing: -0.025em;
  line-height: 1.1;
}

p {
  margin: 0;
}

/* ==========================================================================
   02. Tokens — modo oscuro (default)
   ========================================================================== */

:root {
  color-scheme: dark;

  /* Tipografía */
  --font-display: "Archivo", system-ui, -apple-system, Segoe UI, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, -apple-system, Segoe UI, sans-serif;

  /* Marca — el teal sale del isotipo, no se toca */
  --brand: #11b9b7;
  --brand-strong: #16cfcc;
  --brand-deep: #0e9c9a;
  --brand-ink: #03201f;
  --blue: #2563eb;

  /* Fondo y texto */
  --bg: #070b0e;
  --bg-deep: #0a1218;
  --text: #ecf1f3;
  --text-strong: #ffffff;
  --text-muted: rgba(236, 241, 243, 0.72);
  --text-soft: rgba(236, 241, 243, 0.66);
  --text-dim: rgba(236, 241, 243, 0.5);

  /* Acentos de texto sobre el fondo del tema */
  --accent: #4fe3dd;
  --icon: #7ff0ea;

  /* Cristal — el sello del diseño.
     El inset superior es lo que lo hace leer como vidrio. */
  --glass-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.035));
  --glass-border: rgba(255, 255, 255, 0.14);
  --glass-inset: rgba(255, 255, 255, 0.18);
  --glass-shadow: 0 24px 60px rgba(0, 0, 0, 0.42);
  --glass-blur: 20px;

  /* Cristal secundario (chips, botón fantasma) */
  --glass-soft-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.05));
  --glass-soft-border: rgba(255, 255, 255, 0.18);
  --glass-soft-inset: rgba(255, 255, 255, 0.2);

  /* Marco de imagen */
  --frame-border: rgba(255, 255, 255, 0.14);
  --frame-shadow: 0 34px 80px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  --hairline: rgba(255, 255, 255, 0.1);
  /* Línea que separa secciones. Más clara que el hairline de las cards:
     tiene que leerse a todo el ancho contra el fondo de página. */
  --divider: rgba(255, 255, 255, 0.14);
  /* Cantos del zócalo separador. En oscuro el relieve lo hace el canto
     iluminado de arriba: la sombra se pierde contra el fondo. */
  --divider-hi: rgba(255, 255, 255, 0.24);
  --divider-lo: rgba(255, 255, 255, 0.04);
  --divider-shadow: rgba(0, 0, 0, 0.5);

  /* Pastilla de icono */
  --icon-tile-bg: linear-gradient(145deg, rgba(17, 185, 183, 0.3), rgba(17, 185, 183, 0.1));
  --icon-tile-border: rgba(255, 255, 255, 0.16);
  --check-bg: rgba(17, 185, 183, 0.18);
  --check-border: rgba(17, 185, 183, 0.45);

  /* Fondos de sección alternativa */
  --alt-bg: transparent;
  --alt-pattern: none;

  /* Campos de formulario */
  --input-bg: rgba(255, 255, 255, 0.06);
  --input-border: rgba(255, 255, 255, 0.16);
  --input-placeholder: rgba(236, 241, 243, 0.42);

  /* Radios */
  --r-sm: 9px;
  --r-md: 11px;
  --r-lg: 18px;
  --r-xl: 22px;

  /* Ritmo */
  --gutter: clamp(20px, 4vw, 56px);
  --section-y: clamp(56px, 6vw, 84px);
  --grid-gap: clamp(16px, 2vw, 22px);
  --max-w: 1328px;
  --header-h: 72px;
}

[data-theme="light"] {
  color-scheme: light;

  --bg: #f7f9fa;
  --bg-deep: #eef4f6;
  --text: #0b1015;
  --text-strong: #0b1015;
  --text-muted: #4e565b;
  --text-soft: #4e565b;
  --text-dim: #6b7378;

  --accent: #0a7f7c;
  --icon: #0a7f7c;

  --glass-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.94), rgba(255, 255, 255, 0.6));
  --glass-border: rgba(255, 255, 255, 0.85);
  --glass-inset: rgba(255, 255, 255, 1);
  --glass-shadow: 0 22px 50px rgba(11, 16, 21, 0.1);

  --glass-soft-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.55));
  --glass-soft-border: rgba(11, 16, 21, 0.1);
  --glass-soft-inset: rgba(255, 255, 255, 1);

  --frame-border: rgba(255, 255, 255, 0.8);
  --frame-shadow: 0 34px 80px rgba(11, 16, 21, 0.24);
  --hairline: rgba(11, 16, 21, 0.08);
  --divider: rgba(11, 16, 21, 0.14);
  /* En claro es al revés: el brillo de arriba casi no se ve contra el fondo
     y el relieve lo sostiene la sombra de abajo. */
  --divider-hi: rgba(255, 255, 255, 0.95);
  --divider-lo: rgba(11, 16, 21, 0.05);
  --divider-shadow: rgba(11, 16, 21, 0.13);

  --icon-tile-bg: linear-gradient(145deg, rgba(17, 185, 183, 0.22), rgba(17, 185, 183, 0.08));
  --icon-tile-border: rgba(17, 185, 183, 0.25);
  --check-bg: rgba(17, 185, 183, 0.14);
  --check-border: rgba(17, 185, 183, 0.4);

  --input-bg: #ffffff;
  --input-border: rgba(11, 16, 21, 0.16);
  --input-placeholder: #7b8287;

  /* Las secciones alternas del modo claro llevan la trama de puntos */
  --alt-bg: #f1f6f7;
  --alt-pattern: radial-gradient(circle, rgba(11, 16, 21, 0.075) 1.1px, transparent 1.1px),
    linear-gradient(180deg, rgba(247, 249, 250, 0.55) 0%, rgba(233, 243, 244, 0.55) 100%);
}

/* ==========================================================================
   03. Utilidades de superficie
   ========================================================================== */

/* Ámbito "siempre oscuro": hero, banda de equipo, footer y header sobre el hero.
   Mantiene el contraste correcto aunque el tema global sea claro. */
.on-dark {
  --text: #ecf1f3;
  --text-strong: #ffffff;
  --text-muted: rgba(236, 241, 243, 0.78);
  --text-soft: rgba(236, 241, 243, 0.7);
  --text-dim: rgba(236, 241, 243, 0.55);
  --accent: #4fe3dd;
  --icon: #7ff0ea;
  --glass-soft-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.05));
  --glass-soft-border: rgba(255, 255, 255, 0.18);
  --glass-soft-inset: rgba(255, 255, 255, 0.2);
  --hairline: rgba(255, 255, 255, 0.1);
  --divider: rgba(255, 255, 255, 0.14);
  --divider-hi: rgba(255, 255, 255, 0.24);
  --divider-lo: rgba(255, 255, 255, 0.04);
  --divider-shadow: rgba(0, 0, 0, 0.5);
  color: var(--text);
}

.glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-inset);
}

/* Manchas de iluminación radiales. Se posicionan fuera del borde de la
   sección; la sección recorta con overflow:hidden. */
.glow {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  z-index: 0;
}

.glow--teal {
  background: radial-gradient(circle, rgba(17, 185, 183, 0.18), rgba(17, 185, 183, 0) 65%);
}

.glow--blue {
  background: radial-gradient(circle, rgba(37, 99, 235, 0.2), rgba(37, 99, 235, 0) 65%);
}

[data-theme="light"] .glow--teal {
  background: radial-gradient(circle, rgba(17, 185, 183, 0.15), rgba(17, 185, 183, 0) 62%);
}

[data-theme="light"] .glow--blue {
  background: radial-gradient(circle, rgba(37, 99, 235, 0.12), rgba(37, 99, 235, 0) 62%);
}

/* Imagen a sangre: <picture> absoluta con object-fit cover.
   Se usa <img> en vez de background-image para poder servir webp con <source>. */
.bleed-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.bleed-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* ==========================================================================
   04. Layout
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  overflow: hidden;
  padding-block: var(--section-y);
}

.section > .container {
  position: relative;
  z-index: 1;
}

/* Zócalo separador entre secciones. Es pseudo-elemento y no border porque un
   border no admite degradado ni sombra propia. El degradado vertical le da el
   relieve de moldura: canto iluminado arriba, núcleo al medio, canto en sombra
   abajo. La sombra va SIEMPRE hacia abajo: hacia arriba la recortaría el
   overflow: hidden de la sección anterior.
   Hermano adyacente: la primera sección de cada página no lleva zócalo. */
main > section + section::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(
    180deg,
    var(--divider-hi) 0%,
    var(--divider) 50%,
    var(--divider-lo) 100%
  );
  box-shadow: 0 2px 4px -1px var(--divider-shadow);
  pointer-events: none;
  z-index: 3;
}

.section--alt {
  background-color: var(--alt-bg);
  background-image: var(--alt-pattern);
  background-size: 22px 22px, auto;
}

.section-head {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 720px;
}

.section-head--split {
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  max-width: none;
}

.eyebrow {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

h1 {
  font-size: clamp(2.1rem, 1.15rem + 3.4vw, 3.625rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.03em;
}

h2 {
  font-size: clamp(1.75rem, 1.25rem + 1.8vw, 2.375rem);
  font-weight: 700;
  line-height: 1.12;
}

h3 {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.lead {
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  line-height: 1.6;
  color: var(--text-muted);
}

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

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

.section-head + .grid-3,
.section-head + .grid-2,
.section-head + .split,
.section-head + .case-list,
.section-head + .contact-layout {
  margin-top: clamp(24px, 3vw, 32px);
}

.link-accent {
  font-size: 0.906rem;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
}

.link-accent:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ==========================================================================
   05. Botones
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 14px 26px;
  border-radius: var(--r-md);
  font-size: 0.97rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.btn-primary {
  background: linear-gradient(145deg, var(--brand-strong), var(--brand-deep));
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 14px 34px rgba(17, 185, 183, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.32);
  color: var(--brand-ink);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 18px 40px rgba(17, 185, 183, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.38);
}

.btn-glass {
  background: var(--glass-soft-bg);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  border: 1px solid var(--glass-soft-border);
  box-shadow: inset 0 1px 0 var(--glass-soft-inset);
  color: var(--text-strong);
}

.btn-glass:hover {
  transform: translateY(-1px);
}

.btn-sm {
  min-height: 42px;
  padding: 10px 20px;
  font-size: 0.875rem;
  border-radius: var(--r-sm);
}

/* ==========================================================================
   06. Header, navegación y toggle de tema
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.05);
  -webkit-backdrop-filter: blur(22px);
  backdrop-filter: blur(22px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  transition: background 0.25s ease, border-color 0.25s ease;
}

/* Al scrollear más allá del hero el header adopta los colores del tema */
.site-header.is-solid {
  --text: #ecf1f3;
  --text-strong: #ffffff;
  --text-muted: rgba(236, 241, 243, 0.72);
  background: rgba(7, 11, 14, 0.72);
  border-bottom-color: rgba(255, 255, 255, 0.1);
}

[data-theme="light"] .site-header.is-solid {
  --text: #0b1015;
  --text-strong: #0b1015;
  --text-muted: #4e565b;
  --accent: #0a7f7c;
  --glass-soft-bg: linear-gradient(145deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.55));
  --glass-soft-border: rgba(11, 16, 21, 0.12);
  --glass-soft-inset: rgba(255, 255, 255, 1);
  background: rgba(247, 249, 250, 0.78);
  border-bottom-color: rgba(11, 16, 21, 0.08);
  color: var(--text);
}

.site-header > .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

/* Lockup de marca: isotipo + texto tipeado en Archivo.
   No se usa el logo completo escalado: se ve borroso. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.brand img {
  width: 34px;
  height: 34px;
}

.brand-word {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-strong);
}

.brand-word span {
  color: var(--accent);
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.4vw, 34px);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.4vw, 34px);
}

.nav-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: color 0.18s ease;
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--text-strong);
}

/* CTA y selector de idioma duplicados: sólo aparecen dentro del panel móvil.
   En desktop el idioma vive en .header-actions, al lado del toggle de tema. */
.nav-cta-item,
.nav-lang-item {
  display: none;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.theme-toggle {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
  background: var(--glass-soft-bg);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--glass-soft-border);
  box-shadow: inset 0 1px 0 var(--glass-soft-inset);
  color: var(--text-strong);
  transition: transform 0.18s ease;
}

.theme-toggle:hover {
  transform: translateY(-1px);
}

.theme-toggle .icon-moon {
  display: none;
}

.theme-toggle .icon-sun {
  display: block;
}

/* En claro mostramos la luna (acción: pasar a oscuro) */
[data-theme="light"] .theme-toggle .icon-sun {
  display: none;
}

[data-theme="light"] .theme-toggle .icon-moon {
  display: block;
}

/* Selector de idioma: el cliente pidió texto ES · PT · EN, no banderas
   (una bandera no representa un idioma: ¿portugués es Brasil o Portugal?).
   Misma píldora de cristal que el toggle de tema, para que lean como un par. */
.lang-switch {
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 4px;
  border-radius: var(--r-sm);
  background: var(--glass-soft-bg);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--glass-soft-border);
  box-shadow: inset 0 1px 0 var(--glass-soft-inset);
}

.lang-switch__btn {
  position: relative;
  /* 44px de alto real: el área táctil es todo el botón, no sólo el texto */
  min-width: 38px;
  min-height: 44px;
  padding: 0 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  transition: color 0.18s ease, background 0.18s ease;
}

/* El "·" entre opciones: es separador visual, no contenido */
.lang-switch__btn + .lang-switch__btn {
  margin-left: 8px;
}

.lang-switch__btn + .lang-switch__btn::before {
  content: "·";
  position: absolute;
  left: -6px;
  /* Hereda el color del botón en vez de usar --text-dim: ese token no se
     redefine ni en el header sólido claro ni en el panel móvil claro, y el
     separador quedaba blanco sobre fondo claro (invisible). */
  color: inherit;
  opacity: 0.45;
  pointer-events: none;
}

.lang-switch__btn:hover {
  color: var(--text-strong);
}

.lang-switch__btn[aria-pressed="true"] {
  color: var(--text-strong);
  background: rgba(17, 185, 183, 0.24);
  box-shadow: inset 0 0 0 1px rgba(17, 185, 183, 0.5);
}

[data-theme="light"] .site-header.is-solid .lang-switch__btn[aria-pressed="true"] {
  background: rgba(17, 185, 183, 0.16);
  box-shadow: inset 0 0 0 1px rgba(14, 156, 154, 0.55);
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  border-radius: var(--r-sm);
  background: var(--glass-soft-bg);
  border: 1px solid var(--glass-soft-border);
  box-shadow: inset 0 1px 0 var(--glass-soft-inset);
}

.nav-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

body.nav-open .nav-toggle span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

body.nav-open .nav-toggle span:nth-child(2) {
  opacity: 0;
}

body.nav-open .nav-toggle span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ==========================================================================
   07. Hero
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  min-height: clamp(620px, 76vh, 820px);
  display: flex;
  align-items: center;
  margin-top: calc(var(--header-h) * -1);
  padding-top: calc(var(--header-h) + clamp(48px, 8vh, 96px));
  padding-bottom: clamp(56px, 9vh, 110px);
  /* Fondo propio para la franja que queda detrás del header (ver
     .hero__media): sin esto, en tema claro esa franja se vería blanca. */
  background: #070b0e;
}

.hero .container {
  position: relative;
  z-index: 1;
}

/* La foto arranca DEBAJO del header sticky. La persona de la foto tiene muy
   poco aire sobre la cabeza (empieza al 7,5% del alto), así que con la imagen
   a sangre desde y=0 la cabeza siempre cae dentro de la franja del header y se
   ve mutilada. Bajando el origen del media, la cabeza entra completa y con
   aire. El corte coincide exactamente con el borde inferior del header, que
   además lo tapa apenas se scrollea. */
.hero__media {
  top: var(--header-h);
}

.hero__media img {
  object-position: 72% 0%;
}

/* Hero de proyectos (09.webp): composición inversa a la del home — la persona
   ocupa la mitad derecha del cuadro y el aire oscuro está en el tercio
   izquierdo. En desktop y tablet el recorte es VERTICAL (la caja es más
   panorámica que la foto), así que el 72% de arriba no tiene efecto acá y el
   encuadre base sirve tal cual. El reencuadre sólo hace falta en mobile, donde
   el recorte pasa a ser horizontal (ver el bloque de 640px). */

/* Scrim horizontal: oscurece la izquierda para que se lea el texto */
.hero__scrim-x {
  background: linear-gradient(
    90deg,
    rgba(7, 11, 14, 0.97) 0%,
    rgba(7, 11, 14, 0.9) 30%,
    rgba(7, 11, 14, 0.4) 62%,
    rgba(7, 11, 14, 0.12) 100%
  );
}

/* Scrim vertical: ya no funde nada con el fondo de la página. Sólo oscurece la
   franja de arriba, que es la que queda debajo del header sticky. El hero
   termina con borde neto en los dos temas y la transición la marca la línea
   separadora de sección. */
.hero__scrim-y {
  background: linear-gradient(180deg, rgba(7, 11, 14, 0.6) 0%, rgba(7, 11, 14, 0) 22%);
}

.hero__glow {
  left: -220px;
  top: -160px;
  width: 760px;
  height: 760px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 590px;
}

.hero__copy .lead {
  max-width: 500px;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 6px;
}

/* ==========================================================================
   08. Servicios
   ========================================================================== */

.section--services {
  display: flex;
  flex-direction: column;
}

/* Textura de fondo (04) solo en modo oscuro */
.services__texture {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.services__texture img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.3;
}

.services__texture .scrim {
  background: linear-gradient(180deg, var(--bg) 0%, rgba(7, 11, 14, 0.7) 35%, rgba(7, 11, 14, 0.86) 100%);
}

[data-theme="light"] .services__texture {
  display: none;
}

.services__glow-a {
  left: 58%;
  top: -180px;
  width: 700px;
  height: 700px;
}

.services__glow-b {
  left: -160px;
  top: 120px;
  width: 620px;
  height: 620px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 28px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-inset);
}

.card p {
  font-size: 0.906rem;
  line-height: 1.6;
  color: var(--text-soft);
}

.icon-tile {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 13px;
  background: var(--icon-tile-bg);
  border: 1px solid var(--icon-tile-border);
  color: var(--icon);
  flex: 0 0 auto;
}

.icon-tile svg {
  stroke: currentColor;
}

/* ==========================================================================
   09. Cómo trabajamos
   ========================================================================== */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 4vw, 56px);
}

.split--narrow-media {
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
}

.frame {
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--frame-border);
  box-shadow: var(--frame-shadow);
}

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

.frame--wide img {
  aspect-ratio: 16 / 10;
}

.frame--portrait img {
  aspect-ratio: 1 / 1;
  object-position: center 25%;
}

.split__copy {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.split__copy p {
  font-size: 1.03rem;
  line-height: 1.65;
  color: var(--text-muted);
  max-width: 560px;
}

.check-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 4px;
}

.check-list li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text);
}

.check-list .check {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--check-bg);
  border: 1px solid var(--check-border);
  color: var(--icon);
}

.process__glow {
  left: -200px;
  top: 40px;
  width: 680px;
  height: 680px;
}

/* ==========================================================================
   10. Banda de equipo (foto a sangre, texto sin card)
   ========================================================================== */

/* La banda es un BLOQUE SIEMPRE OSCURO con bordes netos, igual que el hero.
   Antes fundía con var(--bg) arriba y abajo: en tema claro ese degradado de
   blanco a foto oscura dejaba dos franjas grises embarradas. Con fondo propio
   y corte limpio se lee como un bloque deliberado sobre la página clara, y el
   scrim pasa a trabajar solo para el contraste del texto, no para disimular
   un empalme.

   El alto va atado al ancho del viewport y no a vh: la foto es 16:9 y la
   banda medía ~3,8:1, así que object-fit: cover tenía que ampliarla más del
   doble y se comía media escena. Con min(58vw, 720px) la relación queda en
   ~2:1 a 1440px: se ve el 92% del alto de la foto y el recorte se lo lleva el
   borde inferior (el escritorio), que no tiene información. */
.band {
  position: relative;
  overflow: hidden;
  min-height: min(58vw, 720px);
  display: flex;
  align-items: flex-end;
  padding-block: clamp(40px, 4vw, 52px);
  background: #070b0e;
}

.band .container {
  position: relative;
  z-index: 1;
}

/* Borde superior a ras: la primera coronilla arranca al 3,5% del alto de la
   imagen, cualquier desplazamiento hacia abajo corta cabezas. */
.band__media img {
  object-position: center top;
}

/* Un único scrim para los dos temas. Oscurece el tercio inferior —donde vive
   el texto y donde la foto solo tiene escritorio— y deja limpio el tercio
   superior, que es donde están las tres caras. */
.band__scrim-y {
  background: linear-gradient(
    180deg,
    rgba(7, 11, 14, 0.45) 0%,
    rgba(7, 11, 14, 0.12) 15%,
    rgba(7, 11, 14, 0.06) 38%,
    rgba(7, 11, 14, 0.5) 60%,
    rgba(7, 11, 14, 0.86) 80%,
    rgba(7, 11, 14, 0.94) 100%
  );
}

.band__scrim-x {
  background: linear-gradient(90deg, rgba(7, 11, 14, 0.62) 0%, rgba(7, 11, 14, 0.18) 45%, rgba(7, 11, 14, 0) 75%);
}

.band__glow {
  left: -180px;
  bottom: -220px;
  width: 700px;
  height: 700px;
}

.band__copy {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 700px;
}

.band__copy h2 {
  font-size: clamp(1.8rem, 1.2rem + 2vw, 2.5rem);
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.55);
}

.band__copy p {
  font-size: 1.06rem;
  line-height: 1.65;
  color: var(--text-muted);
  max-width: 620px;
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.55);
}

/* --------------------------------------------------------------------------
   Variante "equipo" (.band--team, solo nosotros.html)

   La foto del equipo real (10.webp, 1672x941, 16:9) no tolera NINGÚN recorte:
   son ocho personas que llegan a los cuatro bordes del cuadro —las cabezas de
   la fila de atrás arrancan al 3% del alto y las personas de las puntas tocan
   los bordes laterales—. Con el `object-fit: cover` de .band, a 1440px la
   banda queda en ~2:1 contra una foto de 1,78:1 y se come ~11% vertical:
   justo las coronillas. Y como acá no hay zona muerta abajo (antes era el
   escritorio), el texto encima taparía gente.

   Solución: la imagen deja de ir a sangre con recorte y entra ENTERA en su
   propia relación, con el texto DEBAJO sobre el fondo oscuro de la banda.
   Se usa .band.band--team (especificidad 0,2,0) para ganarle también a las
   reglas de .band del media query de 1024px, que viven más abajo en el
   archivo.
   -------------------------------------------------------------------------- */
.band.band--team {
  display: block;
  min-height: 0;
  padding-block: 0 clamp(36px, 5vw, 60px);
}

/* La media pasa a estar EN FLUJO (no absoluta): es ella la que da el alto de
   la banda, así el contenedor respeta el 16:9 exacto de la foto a cualquier
   ancho. El tope de 2100px evita escalar la foto más allá de ~25% en
   pantallas muy anchas (a 2100px ya mide 1181px de alto). */
.band--team .band__media {
  position: relative;
  inset: auto;
  width: 100%;
  /* height: auto es obligatorio: el media query de 1024px le fija 520px a
     .band__media y ahí la caja quedaba más baja que la foto (el texto se
     montaba sobre el borde inferior). Acá el alto lo da la imagen. */
  height: auto;
  max-width: 2100px;
  margin-inline: auto;
}

.band--team .band__media img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: fill;
  object-position: center;
}

/* El texto ya no va encima de la foto: los dos scrims sobran. La foto corta
   en seco contra el fondo de la banda, sin degradado que disimule el empalme. */
.band--team .band__scrim-x,
.band--team .band__scrim-y {
  display: none;
}

.band--team .container {
  padding-top: clamp(24px, 3vw, 40px);
}

/* ==========================================================================
   11. Proyectos
   ========================================================================== */

.projects__glow-a {
  left: 55%;
  top: -140px;
  width: 760px;
  height: 760px;
}

.projects__glow-b {
  left: -180px;
  bottom: -200px;
  width: 660px;
  height: 660px;
}

.project-card {
  padding: 0;
  overflow: hidden;
  gap: 0;
}

.project-card__media {
  position: relative;
  border-bottom: 1px solid var(--hairline);
}

.project-card__media img {
  width: 100%;
  height: 186px;
  object-fit: cover;
}

/* Card sin foto: pastilla de icono sobre el mismo alto, para que la grilla
   mantenga el ritmo. */
.project-card__art {
  height: 186px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--hairline);
  background: var(--icon-tile-bg);
}

.project-card__art .icon-tile {
  width: 64px;
  height: 64px;
  border-radius: 18px;
}

.project-card__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 22px;
}

.project-card__kicker {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.project-card h3 {
  font-size: 1.19rem;
}

.project-card p {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--text-soft);
}

/* ==========================================================================
   12. Cierre de contacto
   ========================================================================== */

.contact__glow {
  right: -180px;
  top: -120px;
  width: 720px;
  height: 720px;
}

.contact-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 6px;
}

.contact-actions .muted {
  font-size: 0.97rem;
  color: var(--text-dim);
}

.contact-actions .muted a:hover {
  color: var(--accent);
}

/* ==========================================================================
   13. Páginas internas: encabezado, listas, casos y paneles
   --------------------------------------------------------------------------
   Las páginas interiores no llevan foto a sangre arriba (salvo Proyectos):
   arrancan con un encabezado sobrio y el header ya sólido. Por eso NO llevan
   [data-header-watch]: sin ese nodo, main.js le pone .is-solid de entrada.
   ========================================================================== */

.page-head {
  padding-top: calc(var(--section-y) + 12px);
  padding-bottom: clamp(32px, 4vw, 48px);
}

.page-head__inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  max-width: 780px;
}

/* En interiores el h1 no compite con el del home */
.page-head h1 {
  font-size: clamp(1.95rem, 1.2rem + 2.5vw, 3rem);
}

.page-head .lead {
  max-width: 680px;
}

/* --------------------------------------------------------------------------
   Variante a dos columnas: sólo donde el encabezado lleva imagen de apoyo
   (hoy, servicios.html). Reusa el sistema .split / .frame de "Cómo trabajamos".
   Las páginas sin imagen siguen usando .page-head a una columna, intactas.
   -------------------------------------------------------------------------- */

.page-head--split {
  padding-bottom: clamp(40px, 4.5vw, 60px);
}

/* El texto manda: un poco más de aire que la columna de la imagen, porque el
   h1 de interiores es largo. */
.page-head__split {
  grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr);
}

/* Dentro de la grilla la columna ya acota el ancho de medida. */
.page-head--split .page-head__inner,
.page-head--split .page-head .lead {
  max-width: none;
}

.page-head__glow {
  right: -200px;
  top: -320px;
  width: 720px;
  height: 720px;
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.812rem;
  color: var(--text-dim);
}

.breadcrumb a {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
}

.breadcrumb a:hover {
  color: var(--accent);
}

/* En el hero el interlineado general es más aireado: el breadcrumb se pega
   un poco más al eyebrow para que lean como un bloque. */
.hero__copy .breadcrumb {
  margin-bottom: -10px;
}

/* Datos de trayectoria. Por pedido del cliente no se muestran cantidades de
   proyectos ni métricas: sólo años y ubicación, que no cambian. */
.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--grid-gap);
  margin-top: 12px;
  width: 100%;
}

.stat {
  flex: 1 1 210px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 22px;
}

.stat b {
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--text-strong);
}

.stat span {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-soft);
}

/* Viñetas dentro de una card de servicio o de un caso */
.card-list {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 2px;
}

.card-list li {
  position: relative;
  padding-left: 18px;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--text-soft);
}

.card-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--icon);
}

/* Valor / diferencial: icono a la izquierda, texto a la derecha */
.feature-item {
  flex-direction: row;
  align-items: flex-start;
  gap: 16px;
  padding: 24px;
}

.feature-item__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.feature-item h3 {
  font-size: 1.06rem;
}

/* Caso destacado: captura real + copy. Alterna el lado con --flip. */
.case-list {
  display: flex;
  flex-direction: column;
  gap: clamp(44px, 5vw, 76px);
}

.case {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 4vw, 56px);
}

.case--flip .case__media {
  order: 2;
}

.case__copy {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.case__copy h3 {
  font-size: clamp(1.35rem, 1.1rem + 0.9vw, 1.75rem);
}

.case__copy p {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text-muted);
}

.case__copy .card-list li {
  font-size: 0.906rem;
  color: var(--text-muted);
}

/* Captura de sistema: 16:10 nativo, anclada arriba para que se lea la
   barra lateral y el encabezado del ERP. */
.frame--shot img {
  aspect-ratio: 16 / 10;
  object-position: left top;
}

.project-card__media--shot img {
  object-position: left top;
}

/* Panel de cierre con CTA */
.cta-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 3vw, 40px);
  padding: clamp(28px, 4vw, 44px);
}

.cta-panel__copy {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 620px;
}

.cta-panel p {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-muted);
}

/* La banda de foto a sangre también cierra páginas interiores con un CTA */
.band__copy .btn {
  align-self: flex-start;
  margin-top: 8px;
}

/* ==========================================================================
   14. Formulario de contacto
   ========================================================================== */

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(24px, 3vw, 40px);
}

.info-card,
.form-card {
  padding: clamp(24px, 3vw, 34px);
}

.info-card > h2,
.form-card > h2 {
  font-size: clamp(1.4rem, 1.15rem + 0.8vw, 1.75rem);
}

.info-card > p {
  margin-top: 10px;
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.info-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 26px;
}

.info-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.info-item .icon-tile {
  width: 42px;
  height: 42px;
  border-radius: 12px;
}

.info-item__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.info-item h3 {
  font-size: 1rem;
}

/* El cargo es contenido, no decoración: va con --text-muted.
   Con --text-dim en tema claro queda en 4.4:1, por debajo del mínimo. */
.info-item .role {
  font-size: 0.812rem;
  line-height: 1.4;
  color: var(--text-muted);
  margin-top: 2px;
}

.info-item p {
  font-size: 0.906rem;
  line-height: 1.55;
  color: var(--text-soft);
  margin-top: 4px;
}

.info-item a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  font-size: 0.906rem;
  line-height: 1.5;
  color: var(--text-muted);
  word-break: break-word;
}

.info-item a:hover {
  color: var(--accent);
}

.info-card .social-row {
  margin-top: 26px;
}

/* En tema claro el cristal de la card ya es claro: los chips sociales
   (pensados para el footer oscuro) necesitan su propio borde. */
[data-theme="light"] .info-card .social-row a {
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.5));
  border-color: rgba(11, 16, 21, 0.12);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 1);
  color: var(--text);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 22px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

.field--full {
  grid-column: 1 / -1;
}

.field label {
  font-size: 0.812rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 46px;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 0.94rem;
  line-height: 1.5;
  color: var(--text-strong);
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--r-md);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.field textarea {
  min-height: 140px;
  resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--input-placeholder);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(17, 185, 183, 0.22);
}

.form-card .btn {
  margin-top: 20px;
}

.form-note {
  margin-top: 12px;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.form-status {
  display: none;
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-size: 0.875rem;
  line-height: 1.5;
}

.form-status.show {
  display: block;
}

.form-status.success {
  background: var(--check-bg);
  border: 1px solid var(--check-border);
  color: var(--accent);
}

.form-status.error {
  background: rgba(239, 83, 80, 0.16);
  border: 1px solid rgba(239, 83, 80, 0.45);
  color: #ffb3ad;
}

[data-theme="light"] .form-status.error {
  background: rgba(198, 40, 40, 0.1);
  border-color: rgba(198, 40, 40, 0.35);
  color: #a3221c;
}

/* ==========================================================================
   15. Footer
   ========================================================================== */

.site-footer {
  position: relative;
  overflow: hidden;
  padding-block: clamp(44px, 5vw, 56px);
  background: linear-gradient(180deg, #070b0e 0%, #0a1218 45%, #08141a 100%);
}

.site-footer::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0));
  z-index: 1;
}

.site-footer .container {
  position: relative;
  z-index: 1;
}

.footer__glow-a {
  left: -120px;
  bottom: -280px;
  width: 780px;
  height: 780px;
  background: radial-gradient(circle, rgba(17, 185, 183, 0.26), rgba(17, 185, 183, 0) 62%);
}

.footer__glow-b {
  right: -160px;
  bottom: -220px;
  width: 700px;
  height: 700px;
  background: radial-gradient(circle, rgba(37, 99, 235, 0.22), rgba(37, 99, 235, 0) 62%);
}

.footer-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: clamp(28px, 4vw, 56px);
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 330px;
}

.footer-brand p {
  font-size: 0.906rem;
  line-height: 1.6;
  color: var(--text-soft);
}

.footer-cols {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(32px, 5vw, 72px);
}

.footer-col {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.footer-col h4 {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.footer-col a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  font-size: 0.906rem;
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 260px;
}

.footer-col a:hover {
  color: var(--accent);
}

.social-row {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 4px;
}

.social-row a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: var(--r-sm);
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.05));
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
  font-size: 0.812rem;
  font-weight: 500;
  color: var(--text);
}

.social-row a:hover {
  color: var(--accent);
}

.footer-bottom {
  margin-top: clamp(32px, 4vw, 48px);
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.812rem;
  color: var(--text-dim);
}

/* ==========================================================================
   16. Responsive
   --------------------------------------------------------------------------
   Los artboards son de 1440px fijos. Breakpoints elegidos:
   1024px -> el nav colapsa y las grillas de 3 pasan a 2
    640px -> una sola columna, hero apilado, header compacto
   ========================================================================== */

@media (max-width: 1024px) {
  :root {
    --header-h: 64px;
  }

  .nav-toggle {
    display: flex;
  }

  /* Menú móvil: panel de cristal desplegable. Conserva los hooks
     .nav-toggle / .nav-links / body.nav-open que ya usaba main.js */
  .nav-links {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 12px var(--gutter) 20px;
    background: rgba(7, 11, 14, 0.94);
    -webkit-backdrop-filter: blur(22px);
    backdrop-filter: blur(22px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
  }

  [data-theme="light"] .nav-links {
    background: rgba(247, 249, 250, 0.97);
    border-bottom-color: rgba(11, 16, 21, 0.1);
    box-shadow: 0 24px 60px rgba(11, 16, 21, 0.18);
  }

  [data-theme="light"] .nav-links a {
    color: #4e565b;
  }

  [data-theme="light"] .nav-links a:hover,
  [data-theme="light"] .nav-links a[aria-current="page"] {
    color: #0b1015;
  }

  body.nav-open .nav-links {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
  }

  .nav-links a {
    display: flex;
    min-height: 48px;
    font-size: 1rem;
    border-bottom: 1px solid var(--hairline);
  }

  .nav-cta-item {
    display: block;
    margin-top: 14px;
  }

  /* En el header ya no entra: a 390px compiten marca + idioma + tema +
     hamburguesa. El selector pasa al panel desplegable, a ancho completo. */
  .header-actions .lang-switch {
    display: none;
  }

  .nav-lang-item {
    display: block;
    margin-top: 14px;
  }

  .nav-lang-item .lang-switch {
    width: 100%;
    height: 48px;
  }

  .nav-lang-item .lang-switch__btn {
    flex: 1;
  }

  /* El panel móvil tiene fondo claro propio aunque el header siga
     transparente sobre el hero: ahí los tokens "on-dark" dejarían el
     texto blanco sobre blanco. Mismo criterio que .nav-links a. */
  [data-theme="light"] .nav-lang-item .lang-switch {
    background: linear-gradient(145deg, rgba(11, 16, 21, 0.06), rgba(11, 16, 21, 0.02));
    border-color: rgba(11, 16, 21, 0.12);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  }

  [data-theme="light"] .nav-lang-item .lang-switch__btn {
    color: #4e565b;
  }

  [data-theme="light"] .nav-lang-item .lang-switch__btn:hover,
  [data-theme="light"] .nav-lang-item .lang-switch__btn[aria-pressed="true"] {
    color: #0b1015;
  }

  [data-theme="light"] .nav-lang-item .lang-switch__btn[aria-pressed="true"] {
    background: rgba(17, 185, 183, 0.16);
    box-shadow: inset 0 0 0 1px rgba(14, 156, 154, 0.55);
  }

  .nav-cta-item a,
  .nav-links li:last-child a {
    border-bottom: 0;
  }

  .nav-cta-item .btn {
    width: 100%;
    color: var(--brand-ink);
  }

  .header-cta {
    display: none;
  }

  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .split,
  .split--narrow-media,
  .page-head__split {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  /* Apilado, el encabezado recupera su medida de lectura: primero el título,
     la imagen debajo. */
  .page-head--split .page-head__inner {
    max-width: 780px;
  }

  .page-head--split .page-head .lead {
    max-width: 680px;
  }

  /* Apiladas, las imágenes del split ocupan todo el ancho y se comen la
     sección: las limitamos. */
  .frame--wide {
    max-width: 620px;
  }

  .frame--portrait {
    max-width: 320px;
  }

  .frame--portrait img {
    aspect-ratio: 4 / 3;
  }

  .section-head--split {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }

  /* Caso destacado y contacto: la captura pasa arriba y el copy debajo */
  .case,
  .case--flip {
    grid-template-columns: minmax(0, 1fr);
    gap: 26px;
  }

  .case--flip .case__media {
    order: 0;
  }

  .contact-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Banda apilada: la foto ocupa una caja propia arriba y el texto va debajo,
     sobre el fondo oscuro de la banda. Abajo de 1024px el rectángulo es
     demasiado angosto para meter el texto encima sin pisar caras, y con
     object-fit: cover el recorte se volvía lateral (perdía a las personas de
     los costados). La foto se funde hacia el fondo del bloque, así que no hay
     corte visible entre foto y texto. */
  .band {
    min-height: 0;
    align-items: stretch;
    padding-top: calc(min(62vw, 520px) + clamp(26px, 4vw, 38px));
    padding-bottom: clamp(36px, 6vw, 52px);
  }

  .band__media,
  .band__scrim-y {
    bottom: auto;
    height: min(62vw, 520px);
  }

  .band__scrim-y {
    background: linear-gradient(
      180deg,
      rgba(7, 11, 14, 0.4) 0%,
      rgba(7, 11, 14, 0) 24%,
      rgba(7, 11, 14, 0) 58%,
      rgba(7, 11, 14, 0.72) 90%,
      #070b0e 100%
    );
  }

  /* El texto ya no va sobre la foto: el oscurecido lateral solo la ensuciaba */
  .band__scrim-x {
    display: none;
  }
}

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

  /* Reencuadre del hero en mobile.
     El recorte vertical de una foto 16:9 a 390px deja una franja angosta:
     apuntamos al 62% horizontal, que es donde está la persona, y le damos
     aire arriba (padding-top) para que su cara quede libre de texto.
     El scrim deja de ser horizontal y pasa a ser vertical: claro arriba
     (se ve la persona) y oscuro abajo (se lee el texto apilado). */
  .hero {
    min-height: 0;
    align-items: flex-end;
    padding-top: calc(var(--header-h) + 220px);
    padding-bottom: clamp(48px, 8vh, 72px);
  }

  .hero__media img {
    object-position: 62% 0%;
  }

  /* Sólo el hero de proyectos (09.webp). A 390px entra apenas el 30% del ancho
     de la foto, y la cabeza de la operadora ocupa del 59% al 82%: con el 62%
     compartido la ventana cae en 43–73% y le parte la cara por el borde
     derecho. Corriendo el origen al 80% la ventana pasa a 56–86% y la cabeza
     entra entera, con aire de los dos lados. El aire oscuro de la izquierda de
     la foto se pierde, pero en mobile el texto ya no se apoya ahí: el scrim
     deja de ser horizontal y se vuelve vertical (oscuro abajo). */
  .hero__media--ops img {
    object-position: 80% 0%;
  }

  .hero__scrim-x {
    background: linear-gradient(
      180deg,
      rgba(7, 11, 14, 0.45) 0%,
      rgba(7, 11, 14, 0.16) 20%,
      rgba(7, 11, 14, 0.58) 38%,
      rgba(7, 11, 14, 0.9) 54%,
      rgba(7, 11, 14, 0.95) 100%
    );
  }

  /* En mobile el scrim-x ya es vertical y oscurece arriba y abajo: el scrim-y
     sólo aportaba el fundido contra el fondo de página, que se eliminó. */
  .hero__scrim-y {
    background: none;
  }

  .hero__copy {
    gap: 16px;
  }

  .hero-actions .btn {
    width: 100%;
  }

  .card {
    padding: 22px;
  }

  .footer-cols {
    flex-direction: column;
    gap: 24px;
  }

  .contact-actions .btn {
    width: 100%;
  }

  .contact-actions .muted {
    width: 100%;
  }

  .grid-2 {
    grid-template-columns: minmax(0, 1fr);
  }

  .form-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .stat {
    flex: 1 1 100%;
  }

  .cta-panel {
    flex-direction: column;
    align-items: flex-start;
  }

  .cta-panel .btn,
  .band__copy .btn {
    width: 100%;
  }

  .form-card .btn {
    width: 100%;
  }

  .feature-item {
    padding: 22px;
  }
}

/* ==========================================================================
   17. Accesibilidad y movimiento reducido
   ========================================================================== */

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

[data-theme="light"] .on-dark :focus-visible,
.on-dark :focus-visible {
  outline-color: #7ff0ea;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: 8px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--r-sm);
  background: var(--brand);
  color: #03201f;
  font-weight: 600;
  transform: translateY(-200%);
  transition: transform 0.2s ease;
}

.skip-link:focus {
  transform: translateY(0);
}

[hidden] {
  display: none !important;
}

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

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   18. Asistente (widget de chat)

   El marcado lo genera js/chat.js, no está en los HTML. Todo se resuelve con
   los tokens del sistema: no hay un solo color literal nuevo acá, así que el
   widget hereda claro/oscuro sin una sola regla duplicada por tema.

   z-index 80: por encima del header (50) para que el panel abierto no quede
   partido, y por debajo del skip-link (100), que siempre tiene que ganar.
   ========================================================================== */

.chat {
  position: fixed;
  right: clamp(16px, 3vw, 28px);
  bottom: clamp(16px, 3vw, 28px);
  z-index: 80;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}

/* --------------------------------------------------------------------------
   Lanzador
   -------------------------------------------------------------------------- */
.chat__launcher {
  width: 56px;
  height: 56px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--brand-strong), var(--brand-deep));
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 14px 34px rgba(17, 185, 183, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.32);
  color: var(--brand-ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.chat__launcher:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 40px rgba(17, 185, 183, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.38);
}

.chat__launcher svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Con el panel abierto el ícono gira apenas: señal de que el botón ahora
   cierra, sin cambiar el glifo. */
.chat.is-open .chat__launcher {
  transform: rotate(8deg) scale(0.94);
}

/* --------------------------------------------------------------------------
   Panel

   `isolation: isolate` crea un contexto de apilado propio para que el fondo
   opaco del ::before (z-index -1) se quede DENTRO del panel en vez de irse
   detrás del contenido de la página.
   -------------------------------------------------------------------------- */
.chat__panel {
  position: relative;
  isolation: isolate;
  width: min(380px, calc(100vw - 32px));
  height: min(560px, calc(100vh - 140px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-inset);
}

/* El cristal necesita una base opaca debajo: sin ella el texto del sitio se
   lee POR DETRÁS de la conversación y las dos cosas se vuelven ilegibles. */
.chat__panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--bg);
  opacity: 0.94;
}

.chat__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 14px 16px;
  border-bottom: 1px solid var(--hairline);
}

.chat__avatar {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 50%;
  background: var(--icon-tile-bg);
  border: 1px solid var(--icon-tile-border);
}

.chat__identity {
  min-width: 0;
  flex: 1;
}

.chat__title {
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--text-strong);
}

.chat__subtitle {
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--text-dim);
}

.chat__close {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  color: var(--text-muted);
  transition: background 0.18s ease, color 0.18s ease;
}

.chat__close:hover {
  background: var(--input-bg);
  color: var(--text-strong);
}

.chat__close svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* --------------------------------------------------------------------------
   Conversación
   -------------------------------------------------------------------------- */
.chat__log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.chat__msg {
  display: flex;
  max-width: 100%;
}

.chat__msg--yo {
  justify-content: flex-end;
}

.chat__bubble {
  max-width: 85%;
  padding: 10px 13px;
  border-radius: var(--r-md);
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text);
  /* Una respuesta puede traer una URL larga: sin esto desborda la burbuja. */
  overflow-wrap: anywhere;
}

.chat__msg--bot .chat__bubble {
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-bottom-left-radius: 4px;
}

.chat__msg--yo .chat__bubble {
  background: linear-gradient(145deg, var(--brand-strong), var(--brand-deep));
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
  color: var(--brand-ink);
  border-bottom-right-radius: 4px;
}

.chat__msg--error .chat__bubble {
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  color: var(--text-muted);
  font-size: 0.85rem;
}

.chat__bubble p + p,
.chat__bubble p + .chat__list,
.chat__bubble .chat__list + p {
  margin-top: 8px;
}

.chat__list {
  padding-left: 18px;
  list-style: disc;
}

.chat__list li + li {
  margin-top: 4px;
}

/* Tres puntos mientras el modelo todavía no mandó el primer token. */
.chat__typing {
  display: inline-block;
  width: 34px;
  height: 8px;
  background-image: radial-gradient(circle, currentColor 3px, transparent 3px);
  background-size: 13px 8px;
  background-repeat: repeat-x;
  opacity: 0.45;
  animation: chat-typing 1.1s ease-in-out infinite;
}

@keyframes chat-typing {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.7;
  }
}

/* --------------------------------------------------------------------------
   Entrada
   -------------------------------------------------------------------------- */
.chat__form {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 14px 0;
}

.chat__input {
  flex: 1;
  min-width: 0;
  min-height: 42px;
  max-height: 120px;
  padding: 11px 13px;
  border-radius: var(--r-sm);
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  line-height: 1.45;
  resize: none;
}

.chat__input::placeholder {
  color: var(--input-placeholder);
}

.chat__input:focus {
  outline: none;
  border-color: var(--brand-strong);
}

.chat__send {
  width: 42px;
  height: 42px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  background: linear-gradient(145deg, var(--brand-strong), var(--brand-deep));
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
  color: var(--brand-ink);
  transition: opacity 0.18s ease;
}

.chat__send svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chat__send:disabled,
.chat__input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chat__note {
  padding: 8px 14px 12px;
  font-size: 0.71rem;
  line-height: 1.4;
  color: var(--text-dim);
}

/* --------------------------------------------------------------------------
   Mobile: el panel pasa a ocupar la pantalla. Con 380px fijos el chat tapaba
   el sitio a medias, que es lo peor de los dos mundos.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .chat {
    right: 14px;
    bottom: 14px;
  }

  .chat__panel {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
    border-radius: 0;
  }

  .chat__panel::before {
    opacity: 1;
    border-radius: 0;
  }

  /* Con el panel a pantalla completa el lanzador sobra, y encima taparía el
     campo de texto. El cierre queda en la cabecera. */
  .chat.is-open .chat__launcher {
    display: none;
  }

  /* La barra del navegador en iOS no entra en el 100%. */
  .chat__note {
    padding-bottom: calc(12px + env(safe-area-inset-bottom));
  }
}
