/* ==========================================================================
   DRIFT — Estilos principales
   Índice:
   1. Base / tipografía / utilidades
   2. Campo ambiental (profundidad de fondo)
   3. Header
   4. CTA y botones
   5. Menú mobile
   6. Hero
   7. Cabeceras de sección
   8. Proceso — riel
   9. Qué hacemos — filas
   10. Por qué elegirnos
   11. Proyectos
   12. Footer
   13. Página 404
   ========================================================================== */

/* ---------- 1. Base / tipografía / utilidades ---------- */
body {
  position: relative;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  line-height: var(--lh-normal);
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-tight);
}

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-padding);
}

.text-faint { color: var(--color-text-faint); }
.text-muted { color: var(--color-text-muted); }

.skip-link {
  position: fixed;
  top: -60px;
  left: var(--space-sm);
  z-index: 999;
  background: var(--color-accent);
  color: var(--color-bg);
  padding: 0.8em 1.2em;
  border-radius: var(--radius-md);
  transition: top var(--dur-micro) var(--ease-out-soft);
}

.skip-link:focus { top: var(--space-sm); }

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--color-accent-soft);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.noscript-message {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: sans-serif;
  text-align: center;
}

/* ==========================================================================
   2. Campo ambiental — el sistema de profundidad
   Cuatro capas fijas: rejilla técnica, dos campos de luz, barrido y grano.
   Ninguna usa filter:blur sobre un círculo. El "orbe difuminado" es el tell
   visual más repetido de las páginas generadas; acá la luz se construye con
   radial-gradients grandes enmascarados, que además es mucho más barato.
   ========================================================================== */
.field {
  position: fixed;
  inset: 0;
  z-index: var(--z-bg);
  pointer-events: none;
}

.field__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, var(--color-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--color-grid-line) 1px, transparent 1px);
  background-size: clamp(38px, 4vw, 56px) clamp(38px, 4vw, 56px);
  -webkit-mask-image: radial-gradient(ellipse 120% 85% at 50% 0%, #000 5%, transparent 70%);
  mask-image: radial-gradient(ellipse 120% 85% at 50% 0%, #000 5%, transparent 70%);
}

.field__light {
  position: absolute;
  border-radius: 50%;
}

.field__light--a {
  top: -30vh;
  right: -18vw;
  width: 78vw;
  height: 78vw;
  max-width: 1150px;
  max-height: 1150px;
  background: radial-gradient(circle, rgba(var(--color-accent-rgb), 0.15), rgba(var(--color-accent-rgb), 0.05) 42%, transparent 68%);
}

.field__light--b {
  bottom: -34vh;
  left: -22vw;
  width: 66vw;
  height: 66vw;
  max-width: 900px;
  max-height: 900px;
  background: radial-gradient(circle, rgba(var(--color-accent-rgb), 0.085), transparent 66%);
}

.field__scan {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--color-accent-rgb), 0.5) 30%, rgba(var(--color-accent-rgb), 0.5) 70%, transparent);
  opacity: 0.28;
}

.field__grain {
  position: absolute;
  inset: -100px;
  opacity: var(--color-noise-opacity);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* ==========================================================================
   3. Header
   Barra flotante permanente, no una banda a todo lo ancho: el margen lateral
   respecto del viewport y las esquinas redondeadas son el diseño en reposo,
   no un estado de scroll. Al bajar sólo se acerca al borde superior y el
   panel se opaca un poco más — el mismo patrón de antes, adaptado a la
   píldora.
   ========================================================================== */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-header);
  /* Mismo `max-width` + `margin-inline: auto` que `.container` —el sistema
     que usa el resto del sitio—, no una fórmula propia: así el borde del
     logo cae exactamente donde cae el del eyebrow/headline del hero, que
     usa el mismo par de reglas. El padding de acá es sólo el inset de la
     píldora respecto de SU PROPIA caja ya centrada; el 0.9rem de más abajo
     en `.header__inner` es otra cosa —el aire interno de la píldora—. */
  max-width: var(--container-max);
  margin-inline: auto;
  padding: clamp(1.1rem, 2.4vw, 1.75rem) var(--container-padding) 0;
  transition: padding-top var(--dur-ui) var(--ease-premium);
}

.header[data-scrolled="true"] { padding-top: clamp(0.6rem, 1.4vw, 0.9rem); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: rgba(6, 9, 16, 0.55);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  transition: background-color var(--dur-ui) var(--ease-premium),
    border-color var(--dur-ui) var(--ease-premium);
}

.header[data-scrolled="true"] .header__inner {
  background: rgba(6, 9, 16, 0.85);
  border-color: var(--color-border-strong);
}

.header__logo-img {
  height: 21px;
  width: auto;
  transition: opacity var(--dur-micro) var(--ease-out-soft);
}

.header__logo:hover .header__logo-img { opacity: 0.75; }

.header__nav ul {
  display: flex;
  align-items: center;
  gap: clamp(1.4rem, 2.4vw, 2.4rem);
}

.header__nav a {
  position: relative;
  font-size: 0.86rem;
  color: var(--color-text-muted);
  padding-block: var(--space-3xs);
  transition: color var(--dur-micro) var(--ease-out-soft);
}

.header__nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--dur-ui) var(--ease-premium);
}

.header__nav a:hover,
.header__nav a:focus-visible { color: var(--color-text); }

.header__nav a:hover::after,
.header__nav a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.header__nav a[aria-current="page"] {
  color: var(--color-accent-readable);
}

.header__nav a[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.menu-toggle {
  display: none;
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-border);
  /* Más redondeado que --radius-md (4px): la referencia mobile lo muestra
     con esquinas claramente suaves, más cerca de la píldora del header que
     de un botón cuadrado. */
  border-radius: 12px;
  background: rgba(6, 9, 16, 0.55);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: border-color var(--dur-micro) var(--ease-out-soft);
}

.menu-toggle:hover { border-color: var(--color-border-strong); }

.menu-toggle span {
  display: block;
  width: 15px;
  height: 1px;
  background: var(--color-text);
  transition: transform var(--dur-micro) var(--ease-out-soft);
}

.menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3px) rotate(-45deg); }

/* ==========================================================================
   4. CTA y botones
   Filosofía: el efecto vive en la interacción, no en reposo. Borde que se
   enciende, barrido de luz y arrastre del label. Sin glow permanente, sin
   degradado multicolor, sin píldora de 50px.
   ========================================================================== */
.cta-talk {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 0.95rem 1.35rem;
  min-height: 2.9rem;
  border: 1px solid rgba(var(--color-accent-rgb), 0.42);
  border-radius: var(--radius-md);
  background: rgba(var(--color-accent-rgb), 0.09);
  font-family: var(--font-display);
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  isolation: isolate;
  transition: border-color var(--dur-ui) var(--ease-premium),
    background-color var(--dur-ui) var(--ease-premium),
    transform var(--dur-ui) var(--ease-premium);
}

.cta-talk::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, transparent 20%, rgba(var(--color-accent-rgb), 0.5) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform 750ms var(--ease-premium);
}

/* Filo inferior de luz: nace corto y se completa al interactuar. Es el detalle
   que da la sensación de "instrumento encendido" y sobrevive a reduced-motion,
   porque solo cambia opacidad y color. */
.cta-talk::after {
  content: "";
  position: absolute;
  right: 0.65rem;
  bottom: 0;
  left: 0.65rem;
  z-index: 2;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-accent-soft), transparent);
  opacity: 0.35;
  pointer-events: none;
  transform: scaleX(0.2);
  transform-origin: left center;
  transition: transform 420ms var(--ease-premium), opacity var(--dur-ui) var(--ease-premium);
}

.cta-talk:hover::after,
.cta-talk:focus-visible::after { opacity: 1; transform: scaleX(1); }

.cta-talk__label { transition: transform var(--dur-ui) var(--ease-premium); }

.cta-talk__icon {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  background: var(--color-accent-soft);
  -webkit-mask: url("../assets/icons/whatsapp.svg") center / contain no-repeat;
  mask: url("../assets/icons/whatsapp.svg") center / contain no-repeat;
  transition: transform var(--dur-ui) var(--ease-premium),
    background-color var(--dur-ui) var(--ease-premium);
}

.cta-talk:hover,
.cta-talk:focus-visible {
  border-color: var(--color-accent);
  background: rgba(var(--color-accent-rgb), 0.16);
  transform: translateY(-2px);
}

.cta-talk:hover::before,
.cta-talk:focus-visible::before { transform: translateX(120%); }

.cta-talk:hover .cta-talk__label,
.cta-talk:focus-visible .cta-talk__label { transform: translateX(2px); }

.cta-talk:hover .cta-talk__icon,
.cta-talk:focus-visible .cta-talk__icon {
  transform: translateX(3px) rotate(2deg);
  background: var(--color-accent-soft);
}

.cta-talk:active { transform: translateY(0) scale(0.985); }

.cta-talk--header {
  padding: 0.6rem 0.95rem;
  min-height: 2.5rem;
  font-size: 0.78rem;
}
.cta-talk--header .cta-talk__icon { width: 0.9rem; height: 0.9rem; }

/* ---------- 5. Menú mobile ---------- */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-header) - 1);
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2xl);
  padding: 6rem var(--container-padding) var(--space-lg);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity var(--dur-ui) var(--ease-premium),
    transform var(--dur-ui) var(--ease-premium),
    visibility 0s linear var(--dur-ui);
}

.mobile-menu[data-open="true"] {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s, 0s, 0s;
}

.mobile-menu__nav ul { display: flex; flex-direction: column; }
.mobile-menu__nav li { border-bottom: 1px solid var(--color-border); }

.mobile-menu__nav a {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding-block: var(--space-sm);
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 8vw, 2.6rem);
  letter-spacing: var(--ls-tight);
}

.mobile-menu__nav a span {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--color-text-faint);
}

.mobile-menu__footer {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
}

/* ---------- 6. Hero ---------- */
/* ==========================================================================
   Hero — portada editorial con paisaje técnico

   Mobile mantiene su composición propia. Desde 1200px la escena usa el
   paisaje horizontal real como una capa independiente, sin animación ni
   deformación. El texto conserva la prioridad y la sierra emerge desde la
   mitad inferior para sumar profundidad sin convertir el sitio en turismo.
   ========================================================================== */
.hero {
  /* El header mide ~78px y es fixed: este mínimo nunca puede bajar de ahí o
     el contenido quedaría por debajo de la barra en pantallas bajas. */
  --hero-clear: clamp(5.5rem, 8vh, 6.5rem);

  position: relative;
  z-index: var(--z-content);
  min-height: 100vh;
  min-height: 100svh;
  padding-top: var(--hero-clear);
  padding-bottom: clamp(2rem, 6vh, 4rem);
  overflow-x: clip;
  display: flex;
  flex-direction: column;
  isolation: isolate;
}

/* ==========================================================================
   El fondo — cubre TODO el hero, no la columna de la notebook. Por eso vive
   en un elemento propio y no dentro del grid.
   ========================================================================== */
.hero__scene {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Cada asset visual se habilita sólo en el rango que le corresponde. */
.hero__mobile-visual,
.hero__desktop-visual,
.hero__capabilities { display: none; }

/* ---------- Rejilla técnica ----------
   Al 2% de opacidad: sólo deja el recuerdo de la trama y no compite con la
   imagen principal del Hero. */
.hero__ambient {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, rgba(126, 155, 205, 0.02) 1px, transparent 1px) 0 0 / 52px 52px,
    linear-gradient(to bottom, rgba(126, 155, 205, 0.02) 1px, transparent 1px) 0 0 / 52px 52px,
    #000;
}

@media (min-width: 1200px) {
  .hero__desktop-visual {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    background: #000;
  }

  .hero__desktop-visual picture,
  .hero__desktop-visual img {
    display: block;
    width: 100%;
    height: 100%;
  }

  .hero__desktop-visual img {
    object-fit: cover;
    object-position: center bottom;
    filter: saturate(0.9) contrast(1.05);
    user-select: none;
  }

  .hero__desktop-visual::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
      linear-gradient(90deg, rgba(0, 0, 0, 0.96) 0%, rgba(0, 0, 0, 0.82) 31%, rgba(0, 0, 0, 0.3) 58%, transparent 78%),
      linear-gradient(180deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.12) 24%, transparent 45%),
      linear-gradient(0deg, #000 0%, rgba(0, 0, 0, 0.8) 8%, rgba(0, 0, 0, 0.18) 25%, transparent 42%);
  }

  .hero__ambient {
    z-index: 1;
    background:
      linear-gradient(to right, rgba(126, 155, 205, 0.065) 1px, transparent 1px) 0 0 / 52px 52px,
      linear-gradient(to bottom, rgba(126, 155, 205, 0.065) 1px, transparent 1px) 0 0 / 52px 52px;
    -webkit-mask-image: radial-gradient(ellipse 88% 76% at 10% 14%, #000 0%, rgba(0, 0, 0, 0.82) 54%, transparent 100%);
    mask-image: radial-gradient(ellipse 88% 76% at 10% 14%, #000 0%, rgba(0, 0, 0, 0.82) 54%, transparent 100%);
  }

}

/* ==========================================================================
   El grid — la izquierda pesa más que la derecha (1.15fr/.85fr): el texto
   tiene que sentirse protagonista, la notebook secundaria. `fr` y no `%`
   directo porque el `gap` tiene que salir del reparto, no sumarse aparte.
   ========================================================================== */
/* Este grid alinea el bloque de texto con el mismo sistema de contenedor que
   el header, mientras los recursos visuales del Hero viven en su propia capa. */
.hero__grid {
  position: relative;
  z-index: 1;
  flex: 1;
  display: grid;
  align-items: center;
  /* Mismo `max-width` + `margin-inline: auto` + `padding-inline` que
     `.header` y que `.container`: es lo que garantiza que el borde del
     eyebrow/headline caiga exactamente bajo el del logo, sin una fórmula
     de margen propia para el hero. */
  max-width: var(--container-max);
  margin-inline: auto;
  width: 100%;
  padding-inline: var(--container-padding);
}

/* ==========================================================================
   El mensaje
   ========================================================================== */
.hero__inner { min-width: 0; }

.hero__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* La referencia parte el titular en cuatro líneas cortas, no dos largas:
     este ancho es a propósito menor que el texto completo para que
     "Creamos la solución digital" y "que tu negocio necesita" envuelvan
     naturalmente en dos renglones cada uno, sin agregar <br> manuales. */
  max-width: 25rem;
}

.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: clamp(0.7rem, 0.42vw + 0.55rem, 0.86rem);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.hero__eyebrow > span { color: var(--color-accent-readable); }

.hero__title {
  display: flex;
  flex-direction: column;
  gap: 0.02em;
  width: 100%;
  margin-top: clamp(1.1rem, 2.2vh, 1.7rem);
}

.hero__title .reveal-mask > span {
  font-size: var(--fs-hero);
  line-height: 1.07;
  /* La máscara recorta con overflow:hidden y sin esto las descendentes de "g"
     y "q" quedan cortadas contra el borde inferior. */
  padding-bottom: 0.09em;
}

/* Dos <em> independientes, no uno solo envolviendo todo el tramo: en
   desktop "tu negocio necesita" es azul completo, pero en mobile sólo "tu
   negocio" lo es y "necesita" vuelve a blanco (ver css/responsive.css) —
   la referencia de cada tamaño trae su propio corte de color, no el mismo.
   `font-style: normal` porque <em> es semántico acá, no cursiva. */
.hero__title-accent-a,
.hero__title-accent-b {
  color: var(--color-accent);
  font-style: normal;
}

.hero__subtext {
  /* Medido sobre la referencia: la bajada ocupa 26.05em y cae en DOS
     líneas, cortando después de "sistemas". En `em` y no en `ch` porque se
     resuelve contra su propio cuerpo, que es lo que define el corte. */
  max-width: 27em;
  margin-top: clamp(1.2rem, 2.4vh, 1.9rem);
  color: var(--color-text-muted);
  font-size: clamp(0.98rem, 0.42vw + 0.82rem, 1.32rem);
  line-height: 1.58;
}

@media (min-width: 1200px) {
  .hero__content {
    width: clamp(33rem, 37vw, 60rem);
    max-width: clamp(33rem, 37vw, 60rem);
  }

  .hero__title .reveal-mask > span {
    font-size: clamp(3.2rem, min(4.25vw, 7.8vh), 5.35rem);
    line-height: 1.02;
    text-wrap: wrap;
  }

  .hero__subtext { max-width: 36em; }
}

.hero__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(1rem, 2.4vw, 2.5rem);
  margin-top: clamp(1.7rem, 3.6vh, 2.9rem);
}

/* ---------- CTA "Ver proyectos" ----------
   Desktop: texto + línea inferior, sin caja — ver el override a botón
   outlined para <1200px en css/responsive.css. */
.hero__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding-block: 0.55rem;
  font-size: clamp(0.9rem, 0.24vw + 0.82rem, 1.08rem);
  color: var(--color-text-muted);
  transition: color var(--dur-ui) var(--ease-premium),
    border-color var(--dur-ui) var(--ease-premium),
    background-color var(--dur-ui) var(--ease-premium);
}

.hero__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--color-accent);
}

.hero__link-arrow { transition: transform 420ms var(--ease-premium); }
.hero__link:hover,
.hero__link:focus-visible { color: var(--color-text); }
.hero__link:hover .hero__link-arrow,
.hero__link:focus-visible .hero__link-arrow { transform: translateX(4px); }

/* Variante disponible si se necesitara un CTA de WhatsApp dentro del Hero.
   Hoy permanece oculta porque el contacto ya está en el header. */
.hero__whatsapp { display: none; }

/* ==========================================================================
   La escena — notebook + celular, overlay absoluto sobre `.hero` completo
   (ya no adentro de `.hero__grid`: así "right/top/bottom" se miden en % del
   ancho/alto TOTAL del hero, no acotados al contenedor de texto). El
   titular sigue siendo el elemento visual más importante del hero; la
   notebook es el producto principal de la escena, el celular la acompaña
   en primer plano, cerca de su borde derecho.

   Notebook y celular llevan cada uno su propio `width` fijo —ya no se
   deriva el tamaño de uno del otro— pero ambos usan `vw` en su `clamp()`,
   así que escalan juntos de todos modos al cambiar de resolución. Ninguno
   lleva `transform: rotate()`: la inclinación de cada uno ya viene resuelta
   en el propio PNG (fotografiados en ángulo), tocarla acá los deformaría. */

/* Sombras de contacto: medidas sobre el punto de apoyo real de cada foto
   (`magick -trim` sobre el canal alfa: notebook toca a 99.12% de su alto,
   celular a 96.88% del suyo — fotografiadas en ángulo, no de frente) y
   sobre su recorte horizontal real (notebook 2.1%-96.6% de su ancho,
   celular 4.4%-98.8% del suyo). Sólo negro difuso, nada de glow: el brillo
   azul ya lo pone `.hero__desk` por detrás. */

/* ---------- Indicador de scroll ----------
   Independiente del CTA: sólo sugiere que hay más contenido debajo. Muy
   discreto —flecha fina, sin círculo ni fondo— con un rebote lento y corto
   que no compite con nada más del hero. */
.hero__scroll-cue {
  position: absolute;
  left: var(--layout-edge);
  bottom: clamp(1.5rem, 4vh, 2.75rem);
  z-index: 1;
  display: flex;
  color: var(--color-accent);
  opacity: 0.75;
  animation: hero-scroll-cue 2.6s var(--ease-in-out-soft) infinite;
  transition: opacity var(--dur-micro) var(--ease-out-soft);
}

.hero__scroll-cue:hover,
.hero__scroll-cue:focus-visible { opacity: 1; }

@keyframes hero-scroll-cue {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(6px); }
}

/* ---------- Despeje para anchors con header fixed ----------
   El header mide entre ~81px (scrolleado) y ~97px (arriba del todo) según
   viewport — medido en vivo, no a ojo. `scroll-margin-top` cubre el caso
   más alto con margen de sobra, así el título de la sección de destino
   nunca queda tapado al navegar con `scroll-behavior: smooth`
   (css/reset.css). Todas las secciones a las que apunta algún link interno,
   estén o no en el nav del header. */
#inicio,
#proceso,
#que-hacemos,
#proyectos,
#por-que,
#preguntas-frecuentes,
#contacto {
  scroll-margin-top: 6.5rem;
}

/* ---------- 7. Cabeceras de sección ---------- */
.section {
  position: relative;
  z-index: var(--z-content);
  padding-block: var(--section-padding);
  border-top: 1px solid var(--color-border);
}

.section__head {
  margin-bottom: var(--section-head-gap);
  max-width: var(--measure-heading);
}

/* Cabecera reducida: la sección entra directo al contenido y su único
   elemento es la etiqueta, así que el gap se mide desde ahí y no desde un
   titular. Sin esto quedaría el hueco del titular que ya no existe. */
.section__head--compact {
  margin-bottom: clamp(1.75rem, 3.2vw, 3rem);
  max-width: none;
}

.section__head--compact .label { margin-bottom: 0; }

/* El texto vive en el span interno, así que el `text-wrap: balance` que
   reset.css aplica a los <h2> no lo alcanza: sin esto el titular rompe
   dejando una palabra suelta en la última línea en pantallas chicas. */
.section__head h2 > span {
  font-size: var(--fs-display-lg);
  text-wrap: balance;
}

/* La etiqueta puede ser <p> o <h2> según la sección tenga o no titular
   propio: acá se neutraliza lo que heredaría como encabezado. */
h2.label {
  font-weight: 400;
  line-height: 1;
}

.section__lead {
  margin-top: var(--space-md);
  color: var(--color-text-muted);
  max-width: var(--measure-copy);
}

.label {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}

.label::before {
  content: "";
  width: 26px;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-reveal) var(--ease-premium);
}

.label.in-view::before { transform: scaleX(1); }

/* ==========================================================================
   8. Proceso — riel + nodos
   La línea de progreso y las microinteracciones de los íconos se disparan
   una única vez al entrar en viewport (ver js/animations.js) y después
   quedan disponibles por hover. Los keyframes viven en animations.css.
   ========================================================================== */

/* Única cabecera centrada del sitio: es la composición de la referencia y la
   que corresponde a un recorrido simétrico de cinco pasos. El titular ocupa
   1086px en una línea y el contenedor da 1248px, así que entra entero. */
.process .section__head {
  max-width: min(100%, 70rem);
  margin-inline: auto;
  margin-bottom: clamp(3.5rem, 6.5vw, 6rem);
  text-align: center;
}

.process .label { justify-content: center; }

/* Sin el guion de acento: centrado quedaría colgando a la izquierda del
   texto y desbalancearía la cabecera. */
.process .label::before { display: none; }

/* El riel se calcula, no se estima: el número va arriba del nodo, así que la
   altura de la línea es alto-del-número + separación + medio nodo. Con un
   valor a ojo, la línea cruzaba los círculos descentrada. */
.timeline {
  --node: clamp(3.6rem, 5vw, 5rem);
  --num-h: 1.3rem;
  --num-gap: clamp(0.7rem, 1.3vw, 1.1rem);
  --tl-gap: clamp(1rem, 2vw, 2rem);
  --rail: calc(var(--num-h) + var(--num-gap) + var(--node) / 2);

  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--tl-gap);
  position: relative;
}

/* Elemento decorativo fuera del flujo para conservar una lista semántica. */
.timeline__route {
  position: absolute;
  inset: 0;
  list-style: none;
}

.timeline__step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* ---------- El recorrido, en SVG ----------
   La línea no cruza los nodos: una máscara le abre un agujero a cada círculo. */
.process-route {
  position: absolute;
  inset: 0;
  z-index: 5;
  overflow: visible;
  pointer-events: none;
}

.process-route__base,
.process-route__progress {
  fill: none;
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Línea base muy sutil para el tramo todavía no recorrido y azul de marca
   para el avance. */
.process-route__base { stroke: rgba(var(--color-border-rgb), 0.15); }
.process-route__progress { stroke: var(--color-accent); }

.timeline__node {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: var(--node);
  height: var(--node);
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid rgba(var(--color-accent-rgb), 0.45);
  background: var(--color-bg-elevated);
  transition: border-color var(--dur-ui) var(--ease-premium),
    transform var(--dur-ui) var(--ease-premium),
    box-shadow var(--dur-ui) var(--ease-premium);
}

/* Los cinco íconos comparten viewBox, grosor, terminaciones y peso visual:
   son una colección, no cinco dibujos sueltos. */
.process-icon {
  width: 58%;
  height: 58%;
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke var(--dur-ui) var(--ease-premium);
}

.timeline__ring {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(var(--color-accent-rgb), 0.45);
  transition: box-shadow var(--dur-ui) var(--ease-premium);
}

.timeline__step.is-active .timeline__node {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px rgba(var(--color-accent-rgb), 0.09);
}

.timeline__step.is-active .timeline__title { color: var(--color-text); }

/* El nodo escala desde su centro, así que no se despega de la línea. */
.timeline__step:hover .timeline__node,
.timeline__step:focus-within .timeline__node {
  border-color: var(--color-accent);
  transform: scale(1.045);
  box-shadow: 0 0 0 4px rgba(var(--color-accent-rgb), 0.09);
}

.timeline__step:hover .timeline__title,
.timeline__step:focus-within .timeline__title { color: var(--color-text); }

.timeline__step:hover .timeline__num,
.timeline__step:focus-within .timeline__num,
.timeline__step:hover .timeline__body,
.timeline__step:focus-within .timeline__body { opacity: 1; }

/* El número salió de acá: ahora encabeza el paso, arriba del nodo. */
.timeline__body {
  margin-top: var(--space-md);
  opacity: 0.82;
  transition: opacity var(--dur-ui) var(--ease-premium);
}

/* Alto y separación fijos: son los dos sumandos con los que se calcula la
   altura del riel, así que no pueden depender del interlineado heredado. */
.timeline__num {
  display: block;
  height: var(--num-h);
  line-height: var(--num-h);
  margin-bottom: var(--num-gap);
  font-family: var(--font-display);
  font-size: clamp(0.88rem, 1vw, 1rem);
  letter-spacing: 0.08em;
  color: var(--color-accent-readable);
  opacity: 0.85;
  transition: opacity var(--dur-ui) var(--ease-premium);
}

/* El paso alcanzado por el recorrido. */
.timeline__step.is-active .timeline__num { opacity: 1; }
.timeline__step.is-active .timeline__body { opacity: 1; }

/* Punto intermedio del tramo: cae justo en la mitad entre dos nodos —el borde
   de la columna más medio gap—. Es el detalle que hace leer la línea como un
   recorrido y no como un subrayado. */
.timeline__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: var(--rail);
  left: calc(100% + var(--tl-gap) / 2);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: var(--color-border);
}




.timeline__title {
  font-size: var(--fs-display-sm);
  margin-bottom: var(--space-2xs);
  line-height: var(--lh-snug);
}

.timeline__desc {
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
  line-height: 1.55;
}

/* ==========================================================================
   9. Qué hacemos
   Una sola composición en tres columnas, sin contenedor por servicio. Lo que
   separa son dos reglas verticales y el aire — ni borde, ni fondo, ni sombra
   alrededor de ninguno. Las reglas van como `border-left` de las columnas 2 y
   3: caen exactas entre columnas y quedan perfectamente uniformes, sin ningún
   nodo ni punto encima.
   ========================================================================== */
.what-we-do__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
}

/* Sin `gap`: el aire lo pone el padding de cada columna, así la regla cae
   justo en el límite y el hueco a cada lado queda igual. Con gap la línea
   quedaría pegada a un borde y descentrada respecto del canal. */
.svc {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 0;
  padding: clamp(0.5rem, 1.5vw, 1.5rem) clamp(1.25rem, 3.2vw, 3.25rem) 0;
}

/* Un poco por encima de --color-border: a 0.14 de opacidad la regla casi no
   se leía sobre el negro y la composición perdía su estructura. */
.svc + .svc { border-left: 1px solid rgba(var(--color-border-rgb), 0.2); }

.svc__icon {
  display: block;
  width: clamp(2.5rem, 3.5vw, 3.35rem);
  margin-bottom: clamp(1.75rem, 3.6vw, 3.25rem);
}

.svc__icon svg {
  display: block;
  width: 100%;
  height: auto;
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 380ms var(--ease-premium);
}

/* Toda la reacción del hover: dos píxeles. */
.svc:hover .svc__icon svg { transform: translateY(-2px); }

.svc__title {
  font-size: clamp(1.18rem, 1.55vw, 1.5rem);
  font-weight: 600;
  line-height: var(--lh-snug);
  color: var(--color-text);
  max-width: 16ch;
  margin-bottom: clamp(1.5rem, 3.2vw, 2.85rem);
  transition: color 320ms var(--ease-premium);
}

.svc:hover .svc__title { color: var(--color-text); }

.svc__desc {
  max-width: 30ch;
  color: var(--color-text-muted);
  font-size: var(--fs-body-md);
  line-height: 1.75;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

/* Acento de cierre: corto, fino y centrado. Ni botón ni flecha. */
.svc__rule {
  width: 72px;
  height: 2px;
  margin-top: auto;
  background: var(--color-accent);
  transition: width 320ms var(--ease-premium);
}

.svc:hover .svc__rule { width: 88px; }

/* ==========================================================================
   10. Por qué elegirnos
   Composición abierta: ni un contenedor por motivo. La estructura la dan dos
   reglas que se cruzan y parten la zona derecha en cuadrantes — no hay borde,
   fondo ni sombra alrededor de ningún elemento. Los cuatro conceptos se leen
   como partes de una misma pieza y no como cuatro componentes repetidos.
   ========================================================================== */
.reasons__inner {
  display: grid;
  grid-template-columns: minmax(0, 34fr) minmax(0, 66fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 5.5rem);
}

/* ---------- La etiqueta ----------
   Funciona como entrada editorial, no como titular: cuerpo chico, tracking
   ancho y mucho aire alrededor. Es además el encabezado real de la sección. */
.reasons__aside { min-width: 0; }

.reasons__eyebrow {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.5rem);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-text);
}

.reasons__accent { color: var(--color-accent-readable); }

/* La marca va ARRIBA del texto, no en línea: en la referencia el guion se
   apoya sobre la etiqueta y le hace de tope superior. */
.reasons__mark {
  display: block;
  width: 34px;
  height: 1px;
  margin-bottom: clamp(1.1rem, 1.8vw, 1.6rem);
  background: var(--color-accent);
}

/* ==========================================================================
   Los cuatro cuadrantes
   ========================================================================== */
.reasons__grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 3.5vw, 3.5rem);
  row-gap: clamp(2.75rem, 5vw, 4.5rem);
}

/* Regla vertical: se desvanece en las puntas para que no termine en seco. */
.reasons__grid::before {
  content: "";
  position: absolute;
  top: -4%;
  bottom: -4%;
  left: 50%;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--color-border) 18%, var(--color-border) 82%, transparent);
}

/* Regla horizontal: entra un poco en la columna de la etiqueta, como en la
   referencia, y se apaga hacia ese lado. */
.reasons__grid::after {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(-1 * clamp(2rem, 7vw, 8rem));
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-border) 22%, var(--color-border));
}

/* El único punto de luz de la sección, en el cruce. */
.reasons__cross {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: var(--color-accent);
  box-shadow: 0 0 10px 2px rgba(var(--color-accent-rgb), 0.45);
  list-style: none;
}

/* ---------- Cada motivo ---------- */
.reason {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-inline: clamp(0.5rem, 1.5vw, 1.75rem);
}

/* Círculo como marco del ícono: un trazo fino y nada más. Ni relleno azul, ni
   resplandor, ni sombra. */
.reason__icon {
  display: grid;
  place-items: center;
  width: clamp(4.5rem, 6vw, 5.75rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  transition: border-color 320ms var(--ease-premium);
}

.reason:hover .reason__icon { border-color: rgba(var(--color-accent-rgb), 0.4); }

.rico {
  width: 50%;
  height: 50%;
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Línea corta bajo el ícono: crece unos píxeles al pasar el cursor y es la
   única cosa que se mueve del bloque. */
.reason__rule {
  width: 34px;
  height: 1px;
  margin-top: clamp(1.1rem, 1.8vw, 1.5rem);
  margin-bottom: clamp(0.9rem, 1.5vw, 1.25rem);
  background: var(--color-accent);
  transition: width 320ms var(--ease-premium);
}

.reason:hover .reason__rule { width: 46px; }

.reason__title {
  font-size: clamp(1.02rem, 1.2vw, 1.2rem);
  font-weight: 500;
  line-height: var(--lh-snug);
  color: var(--color-text);
  max-width: 18ch;
  transition: color 320ms var(--ease-premium);
}

.reason:hover .reason__title { color: var(--color-text); }

.reason__desc {
  max-width: 30ch;
  margin-top: var(--space-2xs);
  color: var(--color-text-muted);
  font-size: var(--fs-body-sm);
  line-height: 1.72;
  transition: color 320ms var(--ease-premium);
}

.reason:hover .reason__desc { color: var(--color-text); }

/* ==========================================================================
   Microinteracciones de los íconos
   Una por concepto y siempre sobre las PARTES INTERNAS del SVG: el círculo no
   se escala ni se mueve. Van con `transition` y no con `animation` para que se
   repitan cada vez que entra el cursor — una animación CSS no se reinicia si
   su nombre nunca deja de aplicarse.
   ========================================================================== */
.rico :where(g, path, circle) {
  transform-box: fill-box;
  transform-origin: center;
}

/* Objetivo · la flecha entra a la diana */
.tg-core { fill: var(--color-accent); stroke: none; }
.tg-ring { stroke: var(--color-accent); opacity: 0.75; }
.tg-arrow { transition: transform 420ms var(--ease-premium); }
.reason:hover .tg-arrow { transform: translate(-2.5px, 2.5px); }

/* Conversación · los puntos aparecen en orden */
.tk-bubble { stroke: var(--color-accent); opacity: 0.8; }

.tk-dot {
  fill: var(--color-accent);
  stroke: none;
  opacity: 0.28;
  transform: scale(0.7);
  transition: opacity 260ms var(--ease-out-soft), transform 260ms var(--ease-out-soft);
}

.reason:hover .tk-dot { opacity: 1; transform: scale(1); }
.reason:hover .tk-dot:nth-of-type(2) { transition-delay: 100ms; }
.reason:hover .tk-dot:nth-of-type(3) { transition-delay: 200ms; }

/* Acompañamiento · los laterales se acercan al centro */
.tm-side {
  stroke: var(--color-accent);
  opacity: 0.65;
  transition: transform 420ms var(--ease-premium), opacity 420ms var(--ease-premium);
}

.reason:hover .tm-side { opacity: 1; }
.reason:hover .tm-side--l { transform: translateX(2.2px); }
.reason:hover .tm-side--r { transform: translateX(-2.2px); }

/* Claridad · la lámpara se enciende */
.id-glass,
.id-base { stroke: var(--color-accent); }

.id-rays {
  opacity: 0.26;
  transform: scale(0.9);
  transition: opacity 380ms var(--ease-out-soft), transform 380ms var(--ease-premium);
}

.reason:hover .id-rays { opacity: 1; transform: scale(1); }

/* ---------- 11. Proyectos ---------- */
.portfolio__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.75rem, 3vw, 3rem);
}

.project { position: relative; }
.project:nth-child(2n) { margin-top: clamp(0rem, 5vw, 4.5rem); }

.project__frame {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--color-border);
  background: var(--color-bg-elevated);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-ui) var(--ease-premium),
    transform var(--dur-ui) var(--ease-premium);
}

.project__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 55%);
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-premium);
}

.project__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform 900ms var(--ease-premium);
}

.project:hover .project__frame,
.project:focus-within .project__frame {
  border-color: rgba(var(--color-accent-rgb), 0.4);
  transform: translateY(-4px);
}

.project:hover .project__frame img,
.project:focus-within .project__frame img { transform: scale(1.07); }

.project:hover .project__frame::after,
.project:focus-within .project__frame::after { opacity: 1; }

.project__meta {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border);
}

.project__title {
  font-family: var(--font-display);
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

.project__title-num {
  font-family: var(--font-body);
  font-size: 0.75rem;
  color: var(--color-text-faint);
}

.project__category {
  color: var(--color-text-muted);
  font-size: var(--fs-body-sm);
  margin-top: var(--space-3xs);
}

.project__desc {
  color: var(--color-text-faint);
  font-size: var(--fs-body-sm);
  margin-top: var(--space-2xs);
  max-width: 36ch;
}

.project__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: 0.82rem;
  color: var(--color-text-muted);
  white-space: nowrap;
  flex-shrink: 0;
  transition: color var(--dur-micro) var(--ease-out-soft);
}

.project__link svg {
  width: 12px;
  height: 12px;
  transition: transform var(--dur-micro) var(--ease-out-soft);
}

.project:hover .project__link,
.project:focus-within .project__link { color: var(--color-accent-soft); }

.project:hover .project__link svg,
.project:focus-within .project__link svg { transform: translate(2px, -2px); }

/* ==========================================================================
   13. Preguntas frecuentes
   Acordeón de reglas simples. La altura la coordina js/faq.js para que el
   contenido permanezca fuera del árbol accesible mientras está cerrado.
   ========================================================================== */
.faq__inner { max-width: 68rem; }
.faq__head { max-width: 48rem; }

.faq__list {
  border-top: 1px solid var(--color-border-strong);
  border-bottom: 1px solid var(--color-border-strong);
}

.faq__item + .faq__item { border-top: 1px solid var(--color-border); }

.faq__question {
  width: 100%;
  min-height: 5rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.25rem;
  align-items: center;
  gap: var(--space-lg);
  padding-block: 1.4rem;
  color: var(--color-text);
  font-family: var(--font-display);
  font-size: clamp(1.08rem, 1.45vw, 1.35rem);
  font-weight: 500;
  line-height: 1.35;
  transition: color var(--dur-micro) var(--ease-out-soft);
}

.faq__question:hover,
.faq__question:focus-visible { color: var(--color-accent-soft); }

.faq__indicator {
  position: relative;
  width: 1.1rem;
  height: 1.1rem;
  justify-self: end;
}

.faq__indicator::before,
.faq__indicator::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--dur-ui) var(--ease-premium);
}

.faq__indicator::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq__question[aria-expanded="true"] .faq__indicator::after { transform: translate(-50%, -50%) rotate(0); }

.faq__answer {
  height: 0;
  overflow: hidden;
  opacity: 0;
  transition: height var(--dur-ui) var(--ease-premium), opacity var(--dur-ui) var(--ease-premium);
}

.faq__item.is-open .faq__answer { opacity: 1; }

.faq__answer-inner {
  padding: 0 3.25rem 1.65rem 0;
}

.faq__answer p {
  max-width: 68ch;
  color: var(--color-text-muted);
  line-height: var(--lh-relaxed);
}

/* ---------- 14. Footer ---------- */
.footer {
  position: relative;
  z-index: var(--z-content);
  border-top: 1px solid var(--color-border);
  padding-block: var(--space-xl) var(--space-md);
}

.footer__top {
  display: grid;
  grid-template-columns: 1.2fr 0.6fr 1fr;
  align-items: start;
  gap: var(--space-lg);
  padding-bottom: var(--space-xl);
}

.footer__logo-img { height: 23px; width: auto; }

.footer__brand p {
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
  max-width: 30ch;
}

.footer__wordmark {
  margin-top: var(--space-lg);
  max-width: 420px;
  opacity: 0.14;
  overflow: hidden;
}

.footer__wordmark img { width: 100%; height: auto; }

.footer__col h2 {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--color-text-faint);
  margin-bottom: var(--space-sm);
}

.footer__col ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.footer__col a {
  position: relative;
  display: inline-block;
  color: var(--color-text-muted);
  transition: color var(--dur-micro) var(--ease-out-soft),
    transform var(--dur-micro) var(--ease-out-soft);
}

.footer__col a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-ui) var(--ease-premium);
}

.footer__col a:hover,
.footer__col a:focus-visible {
  color: var(--color-text);
  transform: translateX(3px);
}

.footer__col a:hover::after,
.footer__col a:focus-visible::after { transform: scaleX(1); }

.footer__contact-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.footer__contact-channel { color: var(--color-text-muted); }

.footer__contact-data {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-width: 0;
}

.footer__contact-value {
  display: inline-block;
  min-width: 0;
  color: var(--color-text-faint);
  font-size: 0.82rem;
  overflow-wrap: anywhere;
  user-select: all;
}

.footer__copy-button {
  flex-shrink: 0;
  min-height: 2.25rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-family: var(--font-display);
  font-size: 0.72rem;
  line-height: 1;
  transition: color var(--dur-micro) var(--ease-out-soft),
    border-color var(--dur-micro) var(--ease-out-soft),
    transform var(--dur-micro) var(--ease-out-soft);
}

.footer__copy-button:hover,
.footer__copy-button:focus-visible {
  color: var(--color-text);
  border-color: var(--color-accent);
}

.footer__copy-button:active { transform: scale(0.96); }
.footer__copy-button[aria-busy="true"] { cursor: progress; opacity: 0.72; }

.footer__pending-link { color: var(--color-text-muted); }

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-faint);
  font-size: 0.82rem;
}

/* ---------- Toast de copiado ---------- */
.copy-feedback {
  position: fixed;
  right: var(--space-md);
  bottom: var(--space-md);
  z-index: var(--z-overlay);
  max-width: min(24rem, calc(100vw - 2 * var(--space-md)));
  padding: 0.7rem 0.95rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--fs-body-sm);
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.5rem);
  transition: opacity var(--dur-micro) var(--ease-out-soft),
    visibility 0s linear var(--dur-micro),
    transform var(--dur-micro) var(--ease-out-soft);
}

.copy-feedback[data-visible="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.copy-feedback[data-type="error"] { border-color: rgba(255, 107, 107, 0.55); }

/* ---------- 15. Página 404 ---------- */
.error-page__header { border-bottom: 1px solid var(--color-border); }

.error-page__header .container {
  display: flex;
  align-items: center;
  min-height: 4.5rem;
}

.error-page__logo img { width: auto; height: 21px; }

.error-page__main {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  align-items: center;
  min-height: calc(100dvh - 4.5rem);
}

.error-page__content {
  max-width: 48rem;
  padding-block: var(--space-2xl);
}

.error-page__code {
  margin-bottom: var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--color-accent-readable);
}

.error-page__title {
  max-width: 16ch;
  font-size: var(--fs-display-lg);
}

.error-page__description {
  max-width: var(--measure-copy);
  margin-top: var(--space-md);
  color: var(--color-text-muted);
}

.error-page__content .cta-talk { margin-top: var(--space-lg); }
