:root {
  --ink: #18201f;
  --muted: #5c6763;
  --line: #d8ddd9;
  --paper: #ffffff; /* fondo de página: hero y Servicios van en blanco; el mint queda en paneles (Proceso) y tarjetas */
  --mint-soft: #eaf2ee; /* verde claro de superficies (tono medio del degradado mint) */
  --white: #ffffff;
  --mint: #dbeee5;
  --beige: #f7f5ef; /* beige cálido (fondo original de la página): hoy fondo del footer */
  --green: #256b55;
  --green-dark: #154737;
  --green-deep: #0f2e24; /* verde más profundo de la paleta: fondo del footer */
  --coral: #c95f44;
  --gold: #c9a34e;
  --shadow: 0 18px 50px rgba(24, 32, 31, 0.16);

  /* Acentos derivados de la paleta */
  --glow: #7cf0b5; /* verde brillante de acento (focus, eyebrows y enlaces sobre oscuro) */
  --green-soft: #2f8568;

  /* Radios (lenguaje redondeado) */
  --radius-section: 36px;
  --radius-card: 22px;
  --radius-md: 16px;
  --radius-pill: 999px;

  /* Sombras suaves modernas (tintadas de verde) */
  --shadow-sm: 0 4px 16px rgba(24, 32, 31, 0.06);
  --shadow-card: 0 12px 32px rgba(24, 32, 31, 0.08);
  --shadow-card-hover: 0 22px 48px rgba(37, 107, 85, 0.18);
  --shadow-glow: 0 0 0 1px rgba(124, 240, 181, 0.35), 0 16px 40px rgba(37, 107, 85, 0.28);

  /* Gradientes reutilizables */
  --grad-green: linear-gradient(135deg, var(--green) 0%, var(--green-dark) 100%);
  --grad-green-vivid: linear-gradient(120deg, var(--green-soft), var(--green) 55%, var(--green-dark));
  --grad-line: linear-gradient(90deg, var(--green), var(--glow) 50%, var(--gold));
  --grad-dark: linear-gradient(160deg, #1c3b32, var(--green-dark) 55%, #0f2e24);
  /* Degradado claro (mint): fondo por defecto de section.panel .section-inner
     (hoy cada panel lo sobrescribe) */
  --grad-mint: linear-gradient(160deg, #f7f9f8 0%, #eaf2ee 55%, var(--mint) 100%);

  /* Movimiento (firma de easing premium, una sola curva para toda la página) */
  --ease-premium: cubic-bezier(0.22, 1, 0.36, 1);

  /* Material de vidrio reutilizable */
  --glass-blur: blur(14px);
  --glass-border: 1px solid rgba(255, 255, 255, 0.4);

  /* Layout / grilla */
  --grid-color: rgba(124, 240, 181, 0.06);
  /* Gap lateral compartido: marco del hero y padding-inline de section.panel,
     para que la tarjeta del hero alinee con los paneles blancos */
  --frame-gap: clamp(12px, 3vw, 28px);
  /* Respiro de fondo bajo la tarjeta del hero. Se resta al min-height del hero y
     se suma como padding-bottom del .hero-shell (misma cantidad): la tarjeta
     termina antes sin desplazar la sección siguiente. El botón flotante de
     WhatsApp también se ancla sobre este valor para quedar dentro del recuadro. */
  --hero-bottom-gap: clamp(24px, 4vh, 48px);
  /* Paneles anchos pero siempre menores al hero: inset extra sobre el frame-gap
     (0 por debajo de ~800px de viewport, crece hasta 56px) + tope en pantallas
     grandes. Panel = hero − 2×inset hasta el cap. */
  --panel-max: 1480px;
  --panel-inset: clamp(0px, 4vw - 32px, 56px);
  /* Alto efectivo de la barra fija (logo 44 + padding 8×2 = 60; entre 981 y 1139px
     el logo baja a 36 y manda el min-height de 60): lo consumen los offsets del
     hero, el scroll-padding de html (anclas y foco) y el sticky de Planes. En móvil
     el override de .site-header lo mantiene en 60. */
  --header-h: 60px;

  --font-display: "Manrope", Inter, ui-sans-serif, system-ui, sans-serif;

  color-scheme: light;
  font-family:
    Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
    sans-serif;
}

* {
  box-sizing: border-box;
}

/* Red anti-desbordamiento horizontal: `clip` (no `hidden`) no crea contenedor
   de scroll, así no interfiere con Lenis, ScrollTrigger ni el sticky de Planes.
   Neutraliza cualquier transform en X que se salga del viewport en móvil. */
html,
body {
  overflow-x: clip;
}

/* La barra fija tapa el borde superior: con scroll-padding-top el navegador deja el
   foco de Tab/Shift+Tab (y cualquier scrollIntoView) debajo de ella; antes, volviendo
   con Shift+Tab, el control enfocado quedaba tapado. Las anclas también lo suman
   (nativas y Lenis, que lee el scroll-padding-top de html). */
html {
  scroll-padding-top: var(--header-h, 60px);
}

/* El CTA fijo de WhatsApp tapa el borde inferior: cada control reserva su alto debajo
   de sí (scroll-margin y no scroll-padding-bottom en html: así el navegador hace el
   scroll mínimo en vez de centrar todo lo que cae en esa franja). En escritorio el CTA
   es una píldora en la esquina derecha y los botones del hero nunca quedan debajo: sin
   reserva para ellos (con ella, el primer Tab a "Solicitar propuesta" scrolleaba ~300px
   en laptops). Mismo bottom que .whatsapp-cta + su alto real (--cta-h, lo publica
   script.js) + aire. */
:is(main, .site-footer) :is(a[href], button, input, select, textarea, summary):not(.hero *, .whatsapp-cta) {
  scroll-margin-bottom: calc(var(--hero-bottom-gap) + 48px + var(--cta-h, 58px));
}

html:not(.lenis) {
  scroll-behavior: smooth;
}

/* Lenis (smooth scroll por JS): neutraliza el smooth nativo solo mientras Lenis conduce */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
}

img,
svg {
  display: block;
}

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

/* Reveals al scroll: los estados iniciales ocultos viven SOLO en animations.js (gsap.set,
   dentro del guard). Sin JS o sin CDN la página renderiza completa y visible por defecto.
   Los atributos data-reveal del HTML quedan como hooks de selección para GSAP. */

/* Fix de descenders para las máscaras de línea de SplitText (h2 usa line-height:1) */
.split-line {
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

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

.button:focus-visible {
  outline-color: var(--glow);
  box-shadow: var(--shadow-glow);
}

/* Solo lectores de pantalla / outline del documento: sin huella visual */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--green-dark);
  color: var(--white);
  font-weight: 800;
  border-radius: 4px;
  transform: translateY(-150%);
  transition: transform 160ms ease;
}

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

/* Header de barra completa: arriba del todo es invisible (transparente, sin borde —
   se funde con el fondo de la página; la tarjeta del hero comienza DEBAJO).
   Al scrollear (.is-elevated, >24px) aparece la barra de vidrio full-width. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40; /* sobre el CTA fijo de WhatsApp (30): el menú abierto lo cubre */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 60px;
  padding: 8px clamp(16px, 2.5vw, 28px);
  border: 0;
  border-bottom: 1px solid transparent;
  color: var(--ink);
  background: transparent;
  transition:
    background 180ms ease,
    border-color 180ms ease,
    box-shadow 180ms ease;
}

.site-header.is-elevated,
.site-header.nav-open {
  /* Translúcido: deja ver el contenido detrás; el blur mantiene la legibilidad */
  background: rgba(255, 255, 255, 0.55);
  border-bottom-color: rgba(216, 221, 217, 0.6);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.brand {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}

.brand-logo {
  display: block;
  flex: 0 1 auto;
  min-width: 0; /* red de seguridad: si el nav no cupiera, cede el logo (contain lo escala) */
  height: 44px;
  aspect-ratio: 1462 / 358; /* = viewBox de logo-residentia.svg */
  max-width: min(300px, 66vw);
  background: url("./logo-residentia.svg") left center / contain no-repeat;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: 0.92rem;
  font-weight: 650;
}

.site-nav a {
  opacity: 0.86;
}

.site-nav a:hover {
  opacity: 1;
}

/* CTA del header: botón compacto para que la barra no crezca (manda el logo de 44px) */
.site-nav .nav-cta {
  min-height: 42px;
  padding: 10px 20px;
  opacity: 1;
  font-size: 0.88rem;
}

/* 981–1139px: el logo horizontal (4.1:1) + 6 enlaces + 2 CTA no caben a tamaño
   completo; logo a 36px y nav algo más compacto (de paso, entre 981 y ~1010px un
   CTA ya no pasa a 2 líneas). Desde 1140px todo vuelve a 44px. Sin nowrap a
   propósito: con letra grande del navegador el nav se parte en vez de recortarse. */
@media (min-width: 981px) and (max-width: 1139px) {
  .brand-logo {
    height: 36px;
  }

  .site-nav {
    gap: 16px;
    font-size: 0.86rem;
  }

  .site-nav .nav-cta {
    gap: 8px;
    padding: 10px 14px;
    font-size: 0.82rem;
  }
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: var(--radius-md);
  color: inherit;
  background: transparent;
  cursor: pointer;
}

.nav-toggle svg {
  width: 21px;
  height: 21px;
}

/* Íconos inline del toggle: hamburguesa con el menú cerrado, "x" abierto */
.nav-toggle .nav-icon-close,
.site-header.nav-open .nav-toggle .nav-icon-open {
  display: none;
}

.site-header.nav-open .nav-toggle .nav-icon-close {
  display: block;
}

/* La tarjeta del hero comienza debajo de la barra fija (--header-h) + 12px de
   gap, nunca detrás del header */
.hero-shell {
  padding: calc(var(--header-h) + 12px) var(--frame-gap) var(--hero-bottom-gap);
  /* Fondo blanco: la tarjeta del hero flota sobre el blanco de la página
     (mismo blanco que Servicios). El mint queda en los paneles (Proceso) y en
     las tarjetas de Servicios. */
  background: var(--paper);
}

.hero {
  position: relative;
  display: grid;
  /* Tarjeta redondeada que llena el primer viewport: header + gap (12) +
     respiro fijo (12) + margen inferior --hero-bottom-gap (reservado como
     padding-bottom del shell). svh evita el salto de la barra de URL en móvil. */
  min-height: calc(100vh - var(--header-h) - 24px - var(--hero-bottom-gap));
  min-height: calc(100svh - var(--header-h) - 24px - var(--hero-bottom-gap));
  grid-template-columns: minmax(0, 1fr);
  align-items: end;
  overflow: hidden;
  padding: 64px clamp(18px, 5vw, 70px) 56px;
  border-radius: var(--radius-section);
  /* clip-path además del overflow: la capa compositada del <video> puede
     escaparse del clip por subpíxeles (transform fraccional post-pin) y asomar
     como hairline oscura en el borde inferior; clip-path sí recorta capas GPU */
  clip-path: inset(0 round var(--radius-section));
  color: var(--white);
}

.hero-media {
  position: absolute;
  /* Headroom superior: cubre el parallax de salida (GSAP baja la capa hasta
     yPercent 20 de un elemento al 126% del hero = 25.2%) y el translateY del
     Ken Burns sin exponer bordes */
  inset: -26% 0 0;
  overflow: hidden;
}

/* MI2 — el poster (primer frame del video) vive en una capa propia con Ken Burns
   lento: es el fallback instantáneo (LCP) mientras el video baja, y el hero
   completo cuando no hay JS, hay reduced-motion o la red no da (hero-video.js) */
.hero-media::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("./administracion-edificios-condominios-lima.jpg");
  background-position: center;
  background-size: cover;
  will-change: transform;
  backface-visibility: hidden;
  animation: heroKenBurns 24s ease-in-out infinite alternate;
}

/* Video de fondo (aéreo de Lima; hero-video.js lo inyecta solo con motion OK y
   red decente). Como hijo real de .hero-media pinta sobre el poster ::before y
   bajo el degradado ::after por orden de árbol. */
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 700ms ease;
}

.hero.video-live .hero-video {
  opacity: 1;
}

/* Con el video corriendo, el Ken Burns del poster solo quemaría GPU */
.hero.video-live .hero-media::before {
  animation-play-state: paused;
}

/* Lavado verde al scroll-out (patrón glyphic.bio). Reposo transparente POR DISEÑO:
   es una capa de efecto, no contenido oculto — GSAP la scrubbea en initHeroScrollOut.
   Sobre la media (z1), bajo el contenido (z2). */
.hero-wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: var(--green-dark);
  opacity: 0;
}

/* El degradado oscuro queda por encima de la imagen, fijo (no se mueve con el zoom) */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(12, 26, 23, 0.74),
    rgba(12, 26, 23, 0.44) 48%,
    rgba(12, 26, 23, 0.16)
  );
}

@keyframes heroKenBurns {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.06) translateY(-1.5%);
  }
}

.hero-content {
  position: relative;
  z-index: 2;
  width: min(760px, 100%);
  padding-bottom: clamp(72px, 24vh, 260px);
}

/* MI1 — coreografía de entrada on-load: el texto sube en cascada */
@keyframes riseIn {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Fallback sin GSAP: la cascada CSS solo corre si animations.js no tomó el control */
html:not(.gsap-on) .hero-content > * {
  animation: riseIn 0.7s var(--ease-premium) both;
}

html:not(.gsap-on) .hero-content > *:nth-child(1) { animation-delay: 0s; }
html:not(.gsap-on) .hero-content > *:nth-child(2) { animation-delay: 0.09s; }
html:not(.gsap-on) .hero-content > *:nth-child(3) { animation-delay: 0.18s; }
html:not(.gsap-on) .hero-content > *:nth-child(4) { animation-delay: 0.27s; }

/* Gate anti-FOUC: mientras se decide el motor (motion-pending) o cuando GSAP dirige
   (gsap-on), la entrada del hero queda oculta; GSAP la hace visible vía estilos inline.
   Debe ir DESPUÉS de las reglas de animación (misma especificidad, gana el orden). */
html.motion-pending .hero-content > *,
html.gsap-on .hero-content > * {
  visibility: hidden;
  /* GSAP no usa animaciones CSS, así que no interfiere con los tweens. */
  animation: none !important;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 12px;
  color: var(--coral);
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: uppercase;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1,
h2,
h3,
.pstep-dot {
  font-family: var(--font-display);
  letter-spacing: -0.01em;
}

h1 {
  margin-bottom: 18px;
  font-size: clamp(2.5rem, 6vw, 4.6rem);
  line-height: 1.04;
  letter-spacing: 0;
}

h2 {
  margin-bottom: 14px;
  font-size: clamp(1.61rem, 3.62vw, 3.43rem);
  line-height: 1.05; /* bloque apilado de 2-3 filas (los <br> en el markup fuerzan el stack) */
  letter-spacing: 0;
  text-wrap: balance; /* equilibra el eventual re-wrap de un segmento en móviles angostos */
}

/* El h2 de la columna angosta de Contacto (~435px) no puede llegar al tope global:
   "Conversemos" excedería la columna y las máscaras de línea de SplitText lo
   recortarían. Tope menor solo en desktop; ≤980px la grilla colapsa a 1 columna y
   manda el clamp global/móvil. */
@media (min-width: 981px) {
  .contact-copy h2 {
    font-size: clamp(1.61rem, 3.62vw, 2.82rem);
  }
}

h3 {
  margin-bottom: 10px;
  font-size: 1.08rem;
  line-height: 1.2;
}

p {
  color: var(--muted);
  line-height: 1.65;
}

/* Eyebrow del hero sobre la foto: blanco (el coral base no lee bien sobre el
   lavado; antes usaba --glow como los eyebrows de panel-dark) */
.hero-eyebrow {
  color: var(--white);
}

.hero-copy {
  max-width: 660px;
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(1.12rem, 2vw, 1.45rem);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.button {
  display: inline-flex;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  padding: 12px 24px;
  font-weight: 800;
  line-height: 1;
  transition:
    transform 200ms var(--ease-premium),
    background 200ms var(--ease-premium),
    border-color 200ms var(--ease-premium),
    box-shadow 240ms var(--ease-premium);
}

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

/* MI4 — gleam especular que barre una vez al hover + asentamiento al pulsar */
.button.primary {
  position: relative;
  overflow: hidden;
}

.button.primary::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    115deg,
    transparent 40%,
    rgba(255, 255, 255, 0.32) 50%,
    transparent 60%
  );
  transform: translateX(-130%);
  transition: transform 0.6s var(--ease-premium);
}

.button.primary:hover::after {
  transform: translateX(130%);
}

.button:active {
  transform: translateY(0) scale(0.99);
}

.button svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

.button.primary {
  color: var(--white);
  background: var(--grad-green-vivid);
}

.button.primary:hover {
  box-shadow: var(--shadow-glow);
}

.button.secondary {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.54);
  background: rgba(255, 255, 255, 0.08);
}

/* Variante para superficies claras (header): contorno verde, relleno al hover */
.button.ghost {
  color: var(--green);
  border-color: var(--green);
  background: transparent;
}

.button.ghost:hover {
  background: var(--mint-soft);
}

section {
  padding: clamp(64px, 9vw, 116px) clamp(18px, 5vw, 70px);
}

.band {
  background: var(--mint-soft);
}

/* --- Patrón de secciones en contenedor redondeado (claro / oscuro) --- */
section.panel {
  padding-block: clamp(20px, 4vw, 44px);
  padding-inline: calc(var(--frame-gap) + var(--panel-inset));
}

.section-inner {
  max-width: var(--panel-max);
  margin-inline: auto;
}

/* Destino de las anclas: el header fijo ya lo descuenta el scroll-padding-top de
   html; esto es el aire de 12px sobre la sección (nativo, reduced-motion y Lenis,
   que suma ambos: 60 + 12 = 72px bajo el borde superior) */
#servicios,
#planes,
#proceso,
#cobertura,
#faq,
#contacto {
  scroll-margin-top: 12px;
}

section.panel .section-inner {
  border-radius: var(--radius-section);
  padding: clamp(36px, 6vw, 80px) clamp(24px, 5vw, 64px);
  background: var(--grad-mint);
  box-shadow: var(--shadow-card);
}

/* Cobertura va plana sobre el fondo blanco: sin tarjeta mint */
.coverage.panel .section-inner {
  background: none;
  box-shadow: none;
  border-radius: 0;
}

/* --- Cobertura: marquee de distritos en dos direcciones -------------------
   Bucle infinito en CSS puro (independiente del scroll y de GSAP): cada fila
   duplica los 10 distritos y se anima translateX 0 <-> -50% con margin-right
   uniforme, de modo que el -50% cae EXACTO en el borde (sin salto). Las
   tarjetas son opacas (foto), no llevan backdrop-filter animado. El bloque
   marquee es decorativo; el fallback accesible / reduced-motion es .coverage-sr. */
.coverage-marquee {
  --coverage-speed: 55s;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 20px);
  margin-top: 0;
  /* full-bleed: la banda ocupa todo el ancho del viewport, de borde a borde */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.coverage-viewport {
  overflow: hidden;
  contain: layout paint style;
}

.coverage-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation-duration: var(--coverage-speed);
  animation-timing-function: linear; /* velocidad constante: nada de ease en un marquee */
  animation-iteration-count: infinite;
}
.coverage-track--ltr { animation-name: coverage-ltr; } /* fila 1: izquierda -> derecha */
.coverage-track--rtl { animation-name: coverage-rtl; } /* fila 2: derecha -> izquierda */

@keyframes coverage-ltr {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}
@keyframes coverage-rtl {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.coverage-card {
  position: relative;
  flex: 0 0 auto;
  width: clamp(240px, 26vw, 360px);
  aspect-ratio: 3 / 1; /* banner bajo y ancho */
  margin: 0 clamp(12px, 1.4vw, 22px) 0 0; /* margin-right uniforme -> loop exacto */
  border-radius: var(--radius-card);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  background: var(--mint-soft); /* placeholder mientras carga la foto */
}

.coverage-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Lavado verde sobre la foto (mismo tono que el hero, pero más suave / menos oscuro) */
.coverage-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(12, 26, 23, 0.72),
    rgba(12, 26, 23, 0.42) 48%,
    rgba(12, 26, 23, 0.16)
  );
}

/* píldora de vidrio con el nombre (blanco translúcido sólido: sin blur por frame) */
.coverage-name {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: var(--shadow-sm);
  color: var(--green-dark);
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1;
}
.coverage-name svg {
  width: 15px;
  height: 15px;
  color: var(--green);
}

/* Lista real para lectores de pantalla; se vuelve visible (grid estático) en reduced-motion */
.coverage-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  list-style: none;
}

@media (max-width: 980px) {
  .coverage-marquee { --coverage-speed: 42s; }
  .coverage-card { width: clamp(210px, 52vw, 300px); }
  .coverage-name { padding: 6px 11px; font-size: 0.8rem; }
}

@media (max-width: 760px) {
  .coverage-marquee { --coverage-speed: 34s; }
  .coverage-card { width: clamp(190px, 70vw, 260px); }
  .coverage-name { font-size: 0.76rem; }
  .coverage-name svg { width: 13px; height: 13px; }
}

/* Reduced-motion: el barrido global congela el track recortado, así que lo ocultamos
   y mostramos la lista real como grid estático con los 10 distritos. */
@media (prefers-reduced-motion: reduce) {
  .coverage-marquee { display: none; }
  .coverage-sr {
    position: static;
    width: auto;
    height: auto;
    margin: clamp(24px, 3vw, 40px) 0 0;
    padding: 0;
    clip: auto;
    clip-path: none;
    white-space: normal;
    overflow: visible;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: center;
  }
  .coverage-sr li {
    display: inline-flex;
    align-items: center;
    padding: 10px 16px;
    border-radius: var(--radius-pill);
    background: var(--white);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-card);
    color: var(--green-dark);
    font-weight: 600;
  }
}

section.panel.panel-dark .section-inner {
  position: relative;
  isolation: isolate; /* contiene el z-index de la grilla sin tocar los hijos */
  /* PM2 — contiene el glow a la deriva dentro del panel redondeado. `clip` no crea
     contenedor de scroll (con `hidden` el sticky de .contact-copy nunca pegaba);
     `hidden` queda de respaldo para navegadores sin `clip` (Safari < 16). */
  overflow: hidden;
  overflow: clip;
  color: var(--white);
  background: var(--grad-dark);
  box-shadow: 0 24px 60px rgba(15, 46, 36, 0.35);
}

/* PM2 — glow verde suave que deriva detrás del contenido de los paneles oscuros */
section.panel.panel-dark .section-inner::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -8%;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(35% 40% at 30% 20%, rgba(124, 240, 181, 0.14), transparent 70%);
  filter: blur(20px);
  animation: glow-drift 30s ease-in-out infinite alternate;
}

@keyframes glow-drift {
  from {
    transform: translate3d(-3%, -2%, 0);
  }
  to {
    transform: translate3d(7%, 5%, 0);
  }
}

/* Grilla sutil SOLO en paneles oscuros — gradientes, sin imágenes.
   z-index:-1 la deja sobre el fondo pero debajo del contenido (preserva sticky). */
section.panel.panel-dark .section-inner::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 0%, #000 35%, transparent 80%);
  mask-image: radial-gradient(ellipse at 50% 0%, #000 35%, transparent 80%);
}

section.panel-dark p {
  color: rgba(255, 255, 255, 0.82);
}

section.panel-dark .eyebrow {
  color: var(--glow);
}

@media (max-width: 760px) {
  section.panel {
    padding-block: 14px;
    padding-inline: 10px;
  }

  section.panel .section-inner {
    border-radius: 24px;
    padding: 28px 18px;
  }
}

.section-heading {
  max-width: 760px;
}

.services {
  background: var(--paper);
}

/* Contexto de apilado propio para el tríptico. Sin overflow:hidden: las tarjetas
   "flotan" y su sombra + el pop/tilt del hover no deben recortarse. */
.services .section-inner {
  position: relative;
  isolation: isolate;
}

/* Servicios sin panel: fondo blanco de la sección (vence a section.panel). */
section.services.panel .section-inner {
  background: transparent;
  box-shadow: none;
}

/* --- Barra superior: título de la sección --- */
.services-topbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
  flex-wrap: wrap;
}

/* --- Tríptico estático: 3 tarjetas "flotantes" (foto arriba + copy) --- */
.services-viewport {
  margin-top: clamp(28px, 4vw, 48px);
}

/* Grid 3-up */
.services-rail {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.6vw, 36px);
  align-items: start;
}

/* Tarjeta "flotante": SIN caja, SIN borde, SIN relleno. Solo la foto (con sombra)
   + texto directamente sobre el fondo blanco de la sección. La perspectiva vive
   aquí para que su hija .service-media se incline en 3D en el hover (el efecto
   afecta SOLO a la foto, no al texto). */
.service-slide {
  position: relative;
  display: flex;
  flex-direction: column;
  background: transparent;
  perspective: 1100px;
}

/* Marco de foto 4:5 (proporción nativa): redondeado + sombra flotante; overflow
   oculto para contener el zoom + parallax. margin:0 resetea el margen por defecto
   del <figure> (1em 40px) que, si no, desplazaba la foto ~40px a la derecha,
   desalineada de su texto. El tilt/pop del hover se aplica a ESTE marco. */
.service-media {
  position: relative;
  width: 100%;
  margin: 0;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.4s var(--ease-premium);
  will-change: transform;
}

.service-media:hover {
  box-shadow: var(--shadow-card-hover);
}

/* Chromium pierde el clip de border-radius+overflow sobre hijos compuestos
   mientras el marco anima en 3D (hover tilt): las esquinas flashean cuadradas.
   clip-path fuerza la ruta de máscara del compositor, que no flashea. Como
   clip-path recorta también el box-shadow propio, la sombra pasa a un ::before
   del slide que calca la caja 4:5 de la foto (perspective en .service-slide ya
   crea stacking context → z-index:-1 la deja justo debajo). Solo desktop (en
   móvil el marco es 4:3 y no hay hover) y solo bajo .gsap-on: el fallback CSS
   puro conserva su sombra original. */
@media (min-width: 981px) {
  html.gsap-on .service-media {
    clip-path: inset(0 round var(--radius-card));
    box-shadow: none;
  }

  html.gsap-on .service-slide::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    transition: box-shadow 0.4s var(--ease-premium);
    pointer-events: none;
  }

  html.gsap-on .service-slide:has(.service-media:hover)::before {
    box-shadow: var(--shadow-card-hover);
  }
}

.service-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  will-change: transform;
}

/* RR.HH. (3ª tarjeta): la foto es un retrato de persona; anclamos el encuadre
   hacia arriba para que el recorte no corte la cara. */
.service-slide:nth-child(3) .service-media img {
  object-position: center 20%;
}

/* Lavado verde oscuro sutil sobre la foto: mismo tono casi-negro del hero
   (#0c1a17 = rgba(12,26,23)) pero a baja opacidad. */
.service-media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(160deg, rgba(12, 26, 23, 0.26), rgba(12, 26, 23, 0.06));
}

/* Copy: texto directamente sobre el blanco, alineado a los bordes de la foto
   (padding lateral mínimo + respiro arriba entre foto y texto). */
.service-copy {
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 1.6vw, 24px) 2px 0;
}

/* Fallback SIN GSAP: la FOTO (no el texto) se eleva + hace zoom por CSS (inerte
   bajo html.gsap-on, que es cuando GSAP escribe el transform inline de la foto). */
html:not(.gsap-on) .service-media {
  transition: transform 0.3s var(--ease-premium), box-shadow 0.4s var(--ease-premium);
}

html:not(.gsap-on) .service-media:hover {
  transform: translateY(-6px);
}

html:not(.gsap-on) .service-media img {
  transition: transform 0.6s var(--ease-premium);
}

html:not(.gsap-on) .service-media:hover img {
  transform: scale(1.06);
}

.service-badge {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: 20px;
  border-radius: var(--radius-md);
  background: var(--grad-green);
  box-shadow: var(--shadow-glow);
}

.service-badge svg {
  width: 26px;
  height: 26px;
  color: var(--white);
}

.service-copy h3 {
  margin-bottom: 10px;
  font-size: clamp(1.25rem, 1.4vw, 1.55rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.service-summary {
  margin: 0 0 20px;
  color: var(--muted);
  font-size: clamp(1rem, 1.1vw, 1.15rem);
  line-height: 1.55;
}

.service-list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.service-list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  color: var(--ink);
  font-size: clamp(0.95rem, 1vw, 1.05rem);
  line-height: 1.5;
}

.service-list svg {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--green);
}

/* Desplegable "Ver detalle (+N)" (nativo, accesible por teclado/tap y sin JS;
   el chevron gira al abrir). No cambia la altura de la sección en modo pin
   (section-inner de altura fija + viewport overflow:hidden). */
.service-more {
  margin-top: 14px;
}

.service-more summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 2px;
  color: var(--green);
  font-weight: 700;
  font-size: 0.85rem;
}

.service-more summary::-webkit-details-marker {
  display: none;
}

.service-more summary::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -2px);
  transition: transform 0.3s var(--ease-premium);
}

.service-more[open] summary::after {
  transform: rotate(-135deg);
}

.service-more[open] summary {
  margin-bottom: 12px;
}

.service-more .service-list {
  margin-top: 4px;
}

/* --- Planes ("Gestión a la medida"): sticky stack tipo Guesty ---------------
   Apilado 100% CSS: cada tarjeta es sticky bajo el header fijo y la siguiente
   la cubre al scrollear (orden de pintado DOM, sin z-index); la última no tiene
   recorrido sticky restante y cierra la sección sin hacks. Funciona sin GSAP,
   con Lenis (anima el scroll nativo) y con reduced-motion (sticky no es
   animación: movimiento 1:1 con el scroll). */

/* Plano sobre el fondo blanco, como Servicios y Proceso (especificidad (0,3,1)
   para vencer a section.panel .section-inner). Las fotos oscuras full-bleed de
   las tarjetas ya dan el peso visual; un panel mint sería tarjeta-en-tarjeta. */
section.plans.panel .section-inner {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

/* Énfasis del negocio: la recomendación de rangos es visible siempre */
.plans-note {
  max-width: 62ch;
  margin: 0;
}

.plans-stack {
  display: grid;
  gap: clamp(16px, 2.5vw, 28px);
  margin-top: clamp(28px, 4vw, 48px);
  isolation: isolate;
}

.plan-card {
  position: sticky;
  top: calc(var(--header-h) + 16px); /* mismo contrato que las anclas */
  display: flex;
  overflow: hidden; /* recorta la foto; sticky solo se rompe por overflow en ancestros */
  min-height: min(560px, calc(100svh - var(--header-h) - 48px)); /* cabe bajo el header */
  border-radius: var(--radius-section);
  color: var(--white);
  box-shadow: var(--shadow-card);
}

.plan-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Overlay de contraste sobre la foto: casi-negro verde del hero (#0c1a17),
   más denso a la izquierda (donde vive el texto en desktop) */
.plan-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(12, 26, 23, 0.78),
    rgba(12, 26, 23, 0.46) 55%,
    rgba(12, 26, 23, 0.66)
  );
}

.plan-content {
  position: relative;
  z-index: 1; /* sobre el overlay ::after */
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: clamp(24px, 4vw, 72px);
  width: 100%;
  padding: clamp(24px, 4vw, 56px);
}

.plan-head h3 {
  margin: 0;
  max-width: 18ch;
  font-size: clamp(1.6rem, 2.6vw, 2.6rem);
  line-height: 1.08;
}

.plan-tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 0;
  padding: 0;
}

/* Pills transparentes sobre foto (patrón Guesty: rango de deptos + nombre del plan) */
.plan-tags li {
  padding: 9px 16px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.plan-body {
  display: grid;
  gap: 22px;
  max-width: 46ch;
  align-content: start;
}

.plan-body p {
  margin: 0;
  color: rgba(255, 255, 255, 0.9);
  font-size: clamp(1rem, 1.25vw, 1.18rem);
  line-height: 1.6;
}

.plan-body .button {
  justify-self: start;
}

/* --- Proceso ("Cómo trabajamos") --- */
/* Plano sobre el fondo blanco (sin tarjeta mint), como Servicios. Especificidad
   (0,3,1) para vencer a section.panel .section-inner (--grad-mint + shadow + radius). */
section.process.panel .section-inner {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

/* --- Proceso: timeline horizontal de 4 pasos (onboarding) --- */
.process .steps {
  position: relative;
  list-style: none;
  margin: clamp(36px, 5vw, 56px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(16px, 3vw, 32px);
}

.steps-line {
  position: absolute;
  top: 32px; /* mitad del círculo de 64px */
  left: 12%;
  right: 12%;
  z-index: 0; /* detrás de los círculos */
  height: 3px;
  border-radius: 999px;
  background: rgba(37, 107, 85, 0.18);
  overflow: hidden;
}

/* Estado por defecto: línea dibujada al 100% (sin JS todo es visible).
   El scrub de GSAP la conduce con scaleX/scaleY desde animations.js. */
.steps-line-fill {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--green);
}

.pstep {
  position: relative;
  z-index: 1; /* sobre la línea conectora */
  display: grid;
  justify-items: center;
  text-align: center;
  padding: 0 6px;
}

.pstep-dot {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin-bottom: 20px;
  border-radius: var(--radius-pill);
  color: var(--white);
  background: var(--grad-green-vivid);
  box-shadow: var(--shadow-glow);
  font-size: 1.5rem;
  font-weight: 700;
}

.pstep h3 {
  margin-bottom: 8px;
}

.pstep p {
  margin: 0;
  font-size: 0.95rem;
}

/* Responsive: apilado vertical con conector vertical */
@media (max-width: 980px) {
  .process .steps {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .steps-line {
    top: 0;
    bottom: 0;
    left: 32px;
    right: auto;
    width: 3px;
    height: auto;
  }
  .pstep {
    grid-template-columns: 64px minmax(0, 1fr);
    justify-items: start;
    text-align: left;
    column-gap: 18px;
    padding: 14px 0;
  }
  .pstep-dot {
    margin-bottom: 0;
    grid-row: span 2;
  }
}

.contact .section-inner {
  display: grid;
  grid-template-columns: minmax(280px, 0.8fr) minmax(300px, 1fr);
  gap: clamp(30px, 7vw, 92px);
  align-items: start;
}

/* Sticky solo donde existe `overflow: clip`: con el respaldo `hidden` del panel oscuro
   (Safari < 16) el sticky nunca pega y solo bajaba el copy 110px; ahí queda estático,
   alineado con el formulario. */
@supports (overflow: clip) {
  .contact-copy {
    position: sticky;
    top: 110px;
  }
}

.contact-copy p {
  max-width: 52ch; /* legibilidad con paneles anchos */
}

.contact-lines {
  display: grid;
  gap: 12px;
  margin-top: 28px;
}

.contact-lines a {
  display: inline-flex;
  width: fit-content;
  align-items: center;
  gap: 10px;
  color: var(--white);
  font-weight: 800;
  transition:
    color 200ms var(--ease-premium),
    transform 200ms var(--ease-premium);
}

.contact-lines a:hover {
  color: var(--glow);
  transform: translateX(2px);
}

.contact-lines svg {
  color: var(--glow);
}

.contact-lines svg {
  width: 19px;
  height: 19px;
}

.contact-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  padding: clamp(24px, 3vw, 36px);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
  box-shadow: var(--shadow-card-hover);
}

/* El formulario es una tarjeta blanca dentro del panel oscuro:
   forzamos texto oscuro para que no herede el blanco de section.panel-dark p */
section.panel-dark .contact-form p {
  color: var(--muted);
}

/* …salvo la línea de estado/errores del envío, que va en verde oscuro (la regla de
   arriba, más específica que .contact-form .form-status, la dejaba gris) */
section.panel-dark .contact-form .form-status {
  color: var(--green-dark);
}

/* Foco visible sobre el panel oscuro: el anillo verde global (#256b55) queda en
   ~1.8:1 sobre el degradado; el verde brillante supera de lejos el 3:1 */
section.panel-dark .contact-copy a:focus-visible {
  outline-color: var(--glow);
}

.form-head {
  grid-column: 1 / -1;
  margin-bottom: 2px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}

.form-head h3 {
  margin-bottom: 6px;
  color: var(--ink);
  font-size: 1.4rem;
}

.form-head p {
  margin: 0;
  font-size: 0.95rem;
}

label {
  display: block;
  color: var(--green-dark);
  font-size: 0.84rem;
  font-weight: 850;
  letter-spacing: 0.01em;
}

label > input,
label > textarea,
label > select {
  margin-top: 8px;
}

.req {
  color: var(--coral);
  font-weight: 900;
}

input,
textarea,
select {
  width: 100%;
  border: 1px solid #cbd2cc;
  border-radius: var(--radius-md);
  padding: 13px 14px;
  color: var(--ink);
  background: var(--white);
  font: inherit;
  font-weight: 500;
  transition:
    border-color 140ms ease,
    box-shadow 140ms ease;
}

input::placeholder,
textarea::placeholder {
  color: #9aa6a0;
  font-weight: 400;
}

select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23256b55' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 42px;
}

select:invalid {
  color: #9aa6a0;
  font-weight: 400;
}

textarea {
  resize: vertical;
  min-height: 110px;
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(37, 107, 85, 0.16);
}

.wide {
  grid-column: 1 / -1;
}

.contact-form .button.primary {
  margin-top: 4px;
}

.form-note {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
}

.contact-form .form-status {
  grid-column: 1 / -1;
  min-height: 22px;
  margin: 0;
  color: var(--green-dark);
  font-weight: 750;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(12, 26, 23, 0.55);
  backdrop-filter: blur(4px);
  animation: modal-fade 160ms ease;
}

.modal-overlay[hidden] {
  display: none;
}

.modal {
  position: relative;
  width: min(440px, 100%);
  padding: 40px 32px 32px;
  border-radius: 18px;
  background: var(--white);
  box-shadow: var(--shadow);
  text-align: center;
  animation: modal-pop 200ms ease;
}

.modal-icon {
  display: inline-grid;
  width: 72px;
  height: 72px;
  place-items: center;
  margin-bottom: 18px;
  border-radius: 999px;
  background: var(--green);
  box-shadow: 0 10px 24px rgba(37, 107, 85, 0.32);
}

.modal h3 {
  margin-bottom: 10px;
  color: var(--ink);
  font-size: 1.5rem;
}

.modal p {
  margin-bottom: 26px;
  font-size: 0.98rem;
}

.modal .button.modal-ok {
  width: 100%;
}

.modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  background: transparent;
  cursor: pointer;
  transition: background 140ms ease;
}

.modal-close:hover {
  background: var(--mint-soft);
}

.modal-close svg {
  width: 20px;
  height: 20px;
}

@keyframes modal-fade {
  from {
    opacity: 0;
  }
}

@keyframes modal-pop {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.97);
  }
}

/* ============ FAQ: acordeón editorial sobre blanco (referencia Guesty) ============ */
.faq {
  background: var(--paper);
}

/* Sin tarjeta mint: la sección va plana sobre el blanco (vence a section.panel) */
section.faq.panel .section-inner {
  background: transparent;
  box-shadow: none;
}

.faq-heading {
  max-width: 920px;
  margin-bottom: clamp(28px, 5vw, 56px);
}

.faq-list {
  border-bottom: 1px solid rgba(24, 32, 31, 0.14);
}

.faq-item {
  border-top: 1px solid rgba(24, 32, 31, 0.14);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(18px, 3vw, 26px) 4px;
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary h3 {
  margin: 0;
  font-size: clamp(0.9rem, 1.45vw, 1.18rem);
  font-weight: 650;
  line-height: 1.35;
  transition: color 180ms ease;
}

.faq-item summary:hover h3 {
  color: var(--green);
}

/* Indicador +/−: dos barras; la vertical rota a horizontal al abrir (queda el −) */
.faq-icon {
  position: relative;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
}

.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 2px;
  background: var(--ink);
  translate: -50% -50%;
  transition: rotate 320ms var(--ease-premium);
}

.faq-icon::after {
  rotate: 90deg;
}

.faq-item[open] .faq-icon::after {
  rotate: 0deg;
}

/* overflow:hidden permite a animations.js animar la altura al abrir/cerrar */
.faq-answer {
  overflow: hidden;
}

.faq-answer p {
  max-width: 70ch;
  margin: 0;
  padding: 0 4px clamp(20px, 3vw, 28px);
  color: var(--muted);
  line-height: 1.65;
}

.faq-answer a {
  color: var(--green);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============ Footer claro (beige) — fila única + copyright (referencia Guesty) ============ */
.site-footer {
  position: relative;
  padding: clamp(36px, 6vw, 60px) clamp(18px, 5vw, 70px) 18px;
  color: var(--ink);
  background: var(--beige); /* beige cálido original de la página */
  font-size: 0.92rem;
}

.site-footer a {
  color: var(--ink);
  font-weight: 650;
}

/* Fila única: logo (izq) · columnas Nav/Contacto (centro) · redes (der) */
.footer-main {
  display: flex;
  align-items: flex-start; /* logo, títulos de columna y redes alineados arriba */
  justify-content: space-between;
  gap: clamp(28px, 5vw, 64px);
  padding-bottom: clamp(28px, 4vw, 40px);
}

.footer-logo img {
  display: block;
  width: min(190px, 48vw);
  height: auto;
}

/* Columnas de enlaces con títulos pequeños (bloque central de la fila) */
.footer-cols {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: clamp(28px, 5vw, 64px);
}

.footer-col {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: 12px;
}

/* Enlaces de Navegación en 2 sub-columnas (4 + 2): el título queda arriba a ancho
   completo y el bloque de enlaces baja su altura ~a la mitad. Solo aplica a
   Navegación (Contacto no lleva este wrapper), así que Contacto queda intacto. */
.footer-nav-links {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(4, auto);
  justify-items: start;
  column-gap: clamp(24px, 4vw, 48px);
  row-gap: 12px;
}

/* Títulos de columna como <p> (no encabezados: no ensucian el outline H2) */
.footer-col-title {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.footer-col a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  line-height: 1.4;
  transition: color 160ms ease;
}

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

.footer-col svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

.social-links {
  display: flex;
  gap: 14px;
}

.social-links a {
  display: inline-flex;
  width: 42px;
  height: 42px;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(24, 32, 31, 0.28);
  border-radius: 999px;
  transition:
    background 180ms ease,
    color 180ms ease,
    border-color 180ms ease;
}

.social-links a:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--beige);
}

.social-links svg {
  display: block;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}

.social-links a[aria-label="Facebook"] svg {
  transform: translateX(1px);
}

.social-links a[aria-label="LinkedIn"] svg {
  transform: translateX(0.5px);
}

/* Razón social + RUC (izq.) y copyright (der.); si no caben lado a lado, el copyright
   baja a su propia línea en vez de partir ambos textos en dos */
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 6px 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(24, 32, 31, 0.14);
}

.footer-bottom span {
  margin: 0;
  color: var(--muted);
  font-weight: 600;
  line-height: 1.55;
  font-size: 0.82rem;
}

.whatsapp-cta {
  position: fixed;
  right: clamp(16px, 3vw, 44px);
  /* Sube sobre el margen inferior del hero (--hero-bottom-gap) para quedar
     dentro del recuadro al tope de la página; ~28px de holgura interna. */
  bottom: calc(var(--hero-bottom-gap) + 40px);
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.whatsapp-cta > span:first-child {
  display: inline-flex;
  min-height: 38px;
  align-items: center;
  padding: 8px 16px;
  border-radius: 999px;
  color: var(--ink);
  background: var(--white);
  font-weight: 500;
  /* La pastilla blanca necesita borde+sombra propios: flota también sobre
     fondos claros (secciones blancas y el footer beige) */
  border: 1px solid rgba(24, 32, 31, 0.1);
  box-shadow: var(--shadow-sm);
}

.whatsapp-icon {
  display: inline-grid;
  width: 58px;
  height: 58px;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 999px;
  background: #22d466;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
}

.whatsapp-icon svg {
  display: block;
  width: 32px;
  height: 32px;
  transform: translate(0.5px, 0.5px);
}

@media (max-width: 980px) {
  /* Footer: la fila única no cabe en tablet → apilar logo / columnas / redes */
  .footer-main {
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(28px, 4vw, 40px);
  }

  /* Servicios: carrusel horizontal 1-a-1 con snap (patrón Guesty). Full-bleed
     respecto al viewport (mismo truco que .coverage); --rail-edge repone el
     gutter real (section.panel + .section-inner) para que la 1ª tarjeta alinee
     con el heading. El desktop (grid 3-up) no se toca. */
  .services-rail {
    --rail-edge: calc(var(--frame-gap) + var(--panel-inset) + clamp(24px, 5vw, 64px));
    display: flex;
    gap: 16px;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    padding-inline: var(--rail-edge);
    /* respiro vertical: overflow-x:auto convierte el rail en scroll container y
       recortaría la sombra de .service-media; el margin-block lo compensa para
       no alterar el ritmo vertical */
    padding-block: 8px 24px;
    margin-block: -8px -24px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--rail-edge);
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .services-rail::-webkit-scrollbar {
    display: none;
  }

  .service-slide {
    flex: 0 0 auto;
    /* 73vw estilo Guesty; min para phones angostos, cap para tablets (a 980px,
       73vw serían 715px) — el cap deja siempre peek de la siguiente */
    width: clamp(250px, 73vw, 440px);
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }

  /* Foto más baja que el 4:5 de desktop: foto + copy entran juntos en pantalla */
  .service-media {
    aspect-ratio: 4 / 3;
  }

  /* Planes: tarjeta en columna (head arriba, copy + CTA abajo) */
  .plan-content {
    flex-direction: column;
    justify-content: space-between;
  }

  .plan-card {
    top: calc(var(--header-h) + 10px);
    min-height: min(620px, calc(100svh - var(--header-h) - 24px));
  }

  .plan-body {
    max-width: none;
  }

  .whatsapp-cta {
    margin-left: auto;
  }

  .contact .section-inner {
    grid-template-columns: 1fr;
  }

  .contact-copy {
    position: static;
  }

  /* Navegación colapsada (hamburguesa + dropdown) desde tablet hacia abajo.
     Antes vivía solo en ≤760px; se sube a ≤980px para que el rango apretado
     761–980 (6 enlaces + 2 CTAs en línea) también colapse. */
  .nav-toggle {
    display: grid;
  }

  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    grid-template-columns: 1fr;
    gap: 0;
    padding: 8px 16px 16px;
    /* Pantallas bajas (teléfono en horizontal): el menú no cabe y se desplaza dentro
       de sí mismo. Con el dedo es scroll nativo; con mouse/trackpad, script.js le pone
       data-lenis-prevent mientras está abierto para que Lenis le deje la rueda. */
    max-height: calc(100vh - var(--header-h));
    max-height: calc(100svh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Opaco a propósito: con alpha (aunque sea 0.98) el compositor deja ver
       las capas GPU del hero (video/texto) a través del panel */
    background: var(--paper);
    border: 1px solid rgba(216, 221, 217, 0.6);
    border-top: 0;
    border-inline: 0; /* barra full-width: sin bordes laterales en el dropdown */
    transform: translateZ(0);
  }

  .site-header.nav-open .site-nav {
    display: grid;
  }

  .site-nav a {
    padding: 14px 0;
    color: var(--ink);
    border-top: 1px solid var(--line);
  }

  /* En el dropdown el CTA vuelve a ser botón (no fila de menú) */
  .site-nav .nav-cta {
    margin-top: 12px;
    padding: 12px 20px;
    color: var(--white);
    border-top: 0;
    justify-content: center;
  }

  /* El ghost conserva su verde sobre el dropdown claro (la regla anterior fuerza blanco) */
  .site-nav .nav-clients {
    color: var(--green);
    border: 1px solid var(--green);
  }
}

/* Pantallas bajas con el menú abierto: se oculta el CTA fijo de WhatsApp, que el borde
   del dropdown cortaba a la mitad (≈533–600px de alto) o tapaba entero (horizontal).
   En pantallas más altas sigue visible debajo del menú. Al cerrar el menú vuelve. */
@media (max-width: 980px) and (max-height: 640px) {
  .site-header.nav-open ~ .site-footer .whatsapp-cta {
    visibility: hidden;
  }
}

@media (max-width: 760px) {
  :root {
    /* En móvil manda el .nav-toggle (44px), no el logo (40): 44 + padding 8×2 = 60 */
    --header-h: 60px;
  }

  /* ≤760px los gutters son fijos (section.panel 10px + .section-inner 18px):
     el rail del carrusel de servicios alinea con 28px */
  .services-rail {
    --rail-edge: 28px;
  }

  /* Radio menor en móvil, a juego con .section-inner (24px) */
  .plan-card {
    border-radius: 24px;
  }

  .site-header {
    min-height: 50px;
    padding: 8px 16px;
  }

  .brand-logo {
    height: 40px;
    max-width: 230px;
  }

  /* barra móvil full-width (--header-h 60) + gap (8) */
  .hero-shell {
    padding-top: calc(var(--header-h) + 8px);
  }

  .hero {
    min-height: auto;
    padding: 40px 18px 48px;
    border-radius: 24px;
    clip-path: inset(0 round 24px);
  }

  /* En móvil el degradado oscuro es más fuerte y vertical; la imagen sigue en ::before */
  .hero-media::after {
    background: linear-gradient(
      180deg,
      rgba(12, 26, 23, 0.72),
      rgba(12, 26, 23, 0.38)
    );
  }

  .hero-content {
    padding-bottom: 0;
  }

  section {
    padding: 58px 18px;
  }

  h1 {
    font-size: clamp(2rem, 8.5vw, 3rem);
  }

  h2 {
    font-size: clamp(1.61rem, 8.86vw, 2.46rem);
  }

  .button {
    width: 100%;
  }

  .contact-form {
    grid-template-columns: 1fr;
  }

  /* Abajo se reserva la franja del CTA fijo de WhatsApp (bottom 56 + su alto real +
     12 de respiro): al final de la página ya no tapa la barra legal. El alto lo
     publica script.js en --cta-h (la pastilla crece con la letra grande del
     teléfono); sin JS vale el alto base de 58px. */
  .site-footer {
    padding: 32px 18px calc(56px + var(--cta-h, 58px) + 12px);
  }

  .footer-cols {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .footer-logo img {
    width: min(170px, 56vw);
  }

  .footer-bottom {
    flex-direction: column;
    gap: 6px;
    padding-right: 0;
  }

  .whatsapp-cta {
    right: 8px;
    bottom: 56px;
    width: calc(100% - 36px);
    justify-content: space-between;
    margin-top: 24px;
  }

  /* El CTA ocupa todo el ancho: reservan todos los controles, hero incluido (en
     celulares bajos sus botones quedan debajo del CTA al cargar). Mismo bottom de 56px */
  :is(main, .site-footer) :is(a[href], button, input, select, textarea, summary):not(.whatsapp-cta) {
    scroll-margin-bottom: calc(56px + var(--cta-h, 58px) + 8px);
  }

  .whatsapp-cta > span:first-child {
    min-width: 0;
    flex: 1;
  }
}

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

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

  /* PM4 — la coreografía de entrada del hero descansa en su estado final (sin parpadeo).
     visibility vence también al gate motion-pending/gsap-on. */
  .hero-content > * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    visibility: visible !important;
  }

  /* Capas atmosféricas: profundidad estática, sin deriva ni respiración */
  .hero-media::before,
  section.panel.panel-dark .section-inner::after {
    animation: none !important;
    transform: none !important;
  }

  /* Servicios: sin hover-transform ni zoom (cubre el combo sin-GSAP +
     reduced-motion, donde el fallback html:not(.gsap-on) sí dispararía). */
  .service-media,
  .service-media img {
    transition: none !important;
  }

  html:not(.gsap-on) .service-media:hover,
  html:not(.gsap-on) .service-media:hover img {
    transform: none !important;
  }
}
