/* =========================================================
   ELEVATE MARKETING CO. — sistema visual
   Light editorial. Sistema del díptico impreso. Sin frameworks.
   ========================================================= */

:root{
  --cream:#F5EDD8;
  --paper:#FFFDF6;
  --gold:#B9975B;
  /* Fondo de hover de superficies doradas (botones, dock WA). Distinto de
     --golddeep: ese token se oscurecio para pasar contraste de TEXTO chico
     sobre fondo claro, pero aqui lleva texto --ink encima y necesita
     quedarse mas claro para no acercarse al color del texto (con
     --golddeep el hover caia a 3.52:1 ink-sobre-fondo, reprobaba AA). */
  --gold-hover:#A5854D;
  --golddeep:#81683C;
  --ink:#141310;
  --body:#6E6754;
  --line:#D9C9A4;
  --ongold:#3A2F1B;
  --espresso:#3E2E1F;

  --gold-rgb: 185,151,91;
  --ink-rgb: 20,19,16;

  --font-sans:'Work Sans', sans-serif;
  --font-mono:'Space Mono', monospace;

  --ease: cubic-bezier(.16,1,.3,1);
  --nav-h: 72px;

  /* Ritmo vertical entre secciones: una sola fuente de verdad. */
  --section-gap: clamp(2.5rem, 6vw, 4rem);

  /* Sistema de z-index: cada capa vive en su propio orden de magnitud
     para que nunca haya que adivinar quien va encima de quien. */
  --z-decorative: 0;
  --z-content: 10;
  --z-nav: 100;
  --z-atmosphere: 200;
  --z-cursor: 300;
  --z-preloader: 1000;
  --z-skiplink: 1100;
}

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

/* NO overflow-x:hidden aqui en html (aunque body si lo tiene, ver abajo):
   cualquier overflow (aunque sea solo en un eje) en un ancestro convierte
   a ESE ancestro en su propio contenedor de scroll segun spec CSS, y eso
   rompe position:sticky para todo lo que viva adentro — asi fue como el
   nav dejo de seguir al bajar. body ya traia overflow-x:hidden desde
   antes de esta sesion sin romper el sticky, asi que se queda solo ahi. */
html{ scroll-behavior: smooth; }

/* overscroll-behavior-x en vez de mas overflow-x: esto SI es seguro con
   position:sticky (no convierte a nadie en contenedor de scroll, solo
   apaga el rebote elastico/gesto de swipe horizontal de iOS). Con el
   desborde real ya resuelto (nav + dock en rondas anteriores), lo que
   quedaba sintiendose como "se mueve hacia los lados" es probablemente
   ese rebote nativo del telefono al deslizar de mas — esto lo apaga. */
body{
  margin:0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  overscroll-behavior-x: none;
}

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

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

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

h1,h2,h3,h4,p{ margin:0; }

.skip-link{
  position:absolute; left:-9999px; top:0;
  background: var(--gold); color:var(--ink); padding: 0.75em 1em;
  z-index: var(--z-skiplink);
}
.skip-link:focus{ left: 1rem; top: 1rem; }

:focus-visible{
  outline: 2px solid var(--golddeep);
  outline-offset: 3px;
}

.section{
  position: relative;
  padding: var(--section-gap) clamp(1.5rem, 6vw, 4rem);
  overflow: hidden;
}

/* ---------- kickers / microcopy ---------- */
.kicker{
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--golddeep);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  margin-bottom: 1.25rem;
}

.microcopy{
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--body);
  letter-spacing: 0.02em;
}

.num{
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--golddeep);
  font-size: 1rem;
  display:block;
  margin-bottom: 1rem;
}

.section-title{
  font-family: var(--font-sans);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.98;
  font-size: clamp(2rem, 6vw, 4rem);
  color: var(--ink);
  max-width: 18ch;
  text-wrap: balance;
}
.fade-text{ opacity: 0.5; }

.arrow{ display:inline-block; color: var(--gold); transition: transform 0.25s var(--ease); }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;
  align-items:center;
  gap: 0.5em;
  font-family: var(--font-sans);
  font-weight: 700;
  border-radius: 999px;
  padding: 0.9em 1.6em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.2s var(--ease), background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.btn:hover .arrow{ transform: translateX(4px); }
.btn--gold{ background: var(--gold); color: var(--ink); }
/* La flecha es dorada por defecto (contraste sobre crema), pero dentro de
   un boton de fondo dorado queda invisible: aqui hereda el mismo ink del
   texto del boton. */
.btn--gold .arrow{ color: inherit; }
.btn--gold:hover{ background: var(--gold-hover); }
.btn--outline{ background: transparent; color: var(--ink); border-color: var(--line); }
.btn--outline:hover{ border-color: var(--gold); background: rgba(var(--gold-rgb), 0.08); }
.btn--lg{ font-size: 1.05rem; padding: 1.1em 2em; }
.btn--nav{ font-size: 0.85rem; padding: 0.7em 1.3em; }
.btn__wa-icon{ flex-shrink: 0; }

/* ---------- decorative ---------- */
.deco-plus{
  position:absolute;
  top: 16px; right: 16px;
  width: clamp(40px, 6vw, 80px);
  height: auto;
  z-index: var(--z-decorative);
}
/* Centerpiece decorativo del hero en desktop: grande, centrado
   verticalmente, sobre el lado derecho. El translateY(-50%) es fallback
   puro-CSS (sin JS/GSAP se queda centrado igual, principio rector);
   motion.js reemplaza esto con su propio yPercent:-50 antes de animar
   rotacion/escala, porque GSAP toma control total de `transform` en
   cuanto anima cualquier propiedad de transform — un translateY via CSS
   se perderia en cuanto GSAP escriba su propio rotation. */
.hero__halftone{
  position:absolute;
  top: 50%;
  right: clamp(-2rem, 1vw, 3rem);
  transform: translateY(-50%);
  width: clamp(420px, 42vw, 760px);
  height: auto;
  opacity: 0.6;
  z-index: var(--z-decorative);
  pointer-events:none;
}

/* =========================================================
   NAV
   ========================================================= */
.nav{
  position: sticky;
  top:0;
  z-index: var(--z-nav);
  background: rgba(245,237,216,0.7);
  border-bottom: 1px solid transparent;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease), backdrop-filter 0.3s var(--ease);
}
.nav.is-scrolled{
  background: rgba(245,237,216,0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom-color: var(--line);
}
.nav__inner{
  max-width: 1400px;
  min-height: var(--nav-h);
  margin: 0 auto;
  padding: 1rem clamp(1.25rem, 5vw, 3rem);
  display:grid;
  /* En mobile .nav__links esta display:none (solo aparece en 1024px+),
     asi que 3 columnas fijas dejaban al boton cayendo en la columna del
     medio con una tercera columna vacia a su derecha — nunca quedaba
     pegado al borde. 2 columnas hasta que el link central existe de
     verdad.
     minmax(0,1fr) en vez de auto: con "auto auto" ninguna columna cede
     espacio, asi que cuando el boton "Hablemos" crecio (se le agrego el
     icono de WhatsApp) el total ya no cabia en pantallas chicas y el nav
     entero se desbordaba hacia la derecha — arrastrando a toda la pagina
     a poder hacer scroll horizontal. Con 1fr el logo cede el espacio que
     le sobra al boton antes de desbordar. */
  grid-template-columns: minmax(0, 1fr) auto;
  align-items:center;
  gap: 1rem;
  transition: padding 0.3s var(--ease), min-height 0.3s var(--ease);
}
@media (min-width: 1024px){
  .nav__inner{ grid-template-columns: 1fr auto 1fr; justify-content: normal; }
}
/* Al bajar, la nav se compacta: menos padding vertical, mismo contenido. */
.nav.is-scrolled .nav__inner{
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}
/* min-width:0 en vez del auto por defecto de los items de grid: sin esto,
   la columna minmax(0,1fr) de arriba no puede de verdad achicar el logo
   por debajo de su tamaño de contenido y el desborde vuelve a pasar. */
.nav__logo{ display:flex; align-items:center; justify-self:start; min-width: 0; }
.nav__logo img{
  height: 48px;
  width: auto;
  object-fit: contain;
  transition: height 0.3s var(--ease);
}
.nav.is-scrolled .nav__logo img{ height: 40px; }

@media (min-width: 768px){
  .nav__logo img{ height: 60px; }
  .nav.is-scrolled .nav__logo img{ height: 50px; }
}
.nav__links{
  display:none;
  position: relative;
  justify-self:center;
  gap: 2rem;
  font-family: var(--font-mono);
  font-size: 0.85rem;
}
.nav__links a{ position:relative; color: var(--ink); transition: color 0.2s; padding-bottom: 6px; }
.nav__links a:hover{ color: var(--golddeep); }
.nav__links a.is-active{ color: var(--golddeep); }
.nav__links a.nav__link--accent{ color: var(--golddeep); font-weight: 700; }
.nav__links a.nav__link--accent:hover,
.nav__links a.nav__link--accent.is-active{ color: var(--gold); }
.nav__indicator{
  position:absolute;
  left:0; bottom:0;
  height: 2px;
  width: 0;
  background: var(--gold);
  border-radius: 2px;
  opacity: 0;
  pointer-events: none;
}
.nav .btn--nav{ justify-self:end; }

@media (min-width: 1024px){
  .nav__links{ display:flex; }
}

/* =========================================================
   HERO
   ========================================================= */
.hero{
  display:flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  position: relative;
  overflow: hidden;
  /* svh (small viewport height) en vez de dvh: dvh se recalcula EN VIVO
     mientras haces scroll (la barra de direccion del navegador mobile se
     colapsa/expande), asi que el hero cambiaba de alto a medio gesto y
     todo se reacomodaba visualmente — se sentia como que "todo se mueve".
     svh se queda fijo al caso mas chico (barra siempre visible): un poco
     menos de aire cuando el navegador esconde su barra, pero nunca se
     mueve durante el scroll. */
  min-height: 100svh;
  padding: 2rem clamp(1.5rem, 6vw, 4rem) 1.75rem;
  background: var(--cream);
}
/* Vuelve a ocupar la pantalla completa a proposito: el cliente pidio mas
   aire y que el marquee no se vea de entrada, solo al empezar a bajar. */
/* Con ScrollSmoother activo, #smooth-wrapper queda position:fixed cubriendo
   todo el viewport (tecnica estandar de GSAP) y sale del flujo normal. El
   nav vive FUERA de ese wrapper, asi que deja de "empujar" al hero hacia
   abajo: el hero empieza a pintarse desde arriba del todo, debajo del nav
   semitransparente, y todo lo de arriba (kicker, decorativos) queda tapado.
   motion.js marca <html class="has-smoother"> solo cuando el smoother
   realmente arranca — aqui le devolvemos al hero el espacio del nav. */
html.has-smoother .hero{
  padding-top: var(--nav-h);
}
@media (min-width: 768px){
  html.has-smoother .hero{ padding-top: calc(var(--nav-h) + 1rem); }
}
/* padding-right reserva el espacio del .deco-plus (clamp 40-80px, a 16px
   del borde) para que "GUADALAJARA" nunca corra debajo del "+" dorado. */
.hero__kicker{ margin-bottom: 2rem; padding-right: clamp(64px, 18vw, 110px); }

/* Los decorativos son position:absolute y por spec pintan después que los
   estáticos dentro del stacking context de .hero — sin esto, tapan el texto. */
.hero__kicker, .hero__title, .hero__subtitle, .hero__problema, .hero__cta, .hero__microcopy, .hero__quicklinks{
  position: relative;
  z-index: var(--z-content);
}

.hero__title{
  color: var(--ink);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.92;
  font-size: clamp(2rem, 7vw, 4.5rem);
  margin: 0 0 2.5rem;
}
/* Mascara para el reveal por lineas: el propio elemento ya es visible por
   defecto (fallback sin JS). motion.js oculta y anima solo si GSAP carga
   y el usuario no pidio prefers-reduced-motion. */
.hero-line{ display:block; overflow:hidden; }
.hero-line__inner{ display:block; }
.hero__title em{ font-style: normal; color: var(--gold); }

.hero__subtitle{
  color: var(--body);
  max-width: 580px;
  font-size: 1.05rem;
  line-height: 1.45;
  margin-bottom: 1.25rem;
}
.hero__problema{
  color: var(--golddeep);
  font-weight: 600;
  font-size: clamp(1.05rem, 2.1vw, 1.3rem);
  max-width: 640px;
  margin-bottom: 2.5rem;
}
.hero__microcopy{ color: var(--body); margin-top: 0.75rem; }
/* En mobile el CTA se ve mejor centrado (mas natural para el pulgar);
   en desktop se queda alineado a la izquierda con el resto del texto
   editorial del hero. */
@media (max-width: 767px){
  .hero__cta{ align-self: center; }
  .hero__quicklinks{ align-self: center; justify-content: center; }
  /* En mobile, centrar verticalmente dentro de min-height:100dvh dejaba un
     hueco enorme entre el nav y el kicker (el bloque de texto no llena la
     pantalla). Arranca desde arriba en vez de centrado. */
  /* El marquee tiene que quedar pegado justo debajo de los quicklinks, sin
     hueco — nada de forzar al hero a ocupar la pantalla completa (eso fue
     lo que causaba el hueco: el contenido real es mas corto que un
     viewport completo, y con min-height al tamaño de pantalla completa
     ese sobrante quedaba como aire muerto ANTES del marquee). Alto natural,
     el que pida el contenido — el marquee sigue siendo lo primero visible
     sin scroll porque el contenido de por si ya cabe en un viewport. */
  .hero{ justify-content: flex-start; min-height: 0; }
  html.has-smoother .hero{ padding-top: calc(var(--nav-h) + 2rem); }
  /* El halftone (grande y centrado en desktop, ver regla base) se ve
     amontonado/fuera de lugar en el hero angosto de mobile — se quita
     ahi, en desktop sigue igual. */
  .hero__halftone{ display: none; }
  /* La flecha "sigue bajando" vive dentro del hero solo en desktop; en
     mobile el cliente pidio que fuera DESPUES del marquee (ver
     .hero-scrollcue-mobile mas abajo), no encima. */
  .scroll-indicator{ display: none; }
}

/* Version mobile de la flecha "sigue bajando": vive fuera del hero, justo
   despues del marquee (ver comentario en index.html) — oculta en desktop,
   donde sigue existiendo .scroll-indicator dentro del hero. */
.hero-scrollcue-mobile{ display: none; }
@media (max-width: 767px){
  .hero-scrollcue-mobile{
    display: flex;
    justify-content: center;
    padding: 0.75rem 0 0.5rem;
    color: var(--gold);
    font-size: 1.3rem;
    background: var(--cream);
    animation: bounceStatic 2s ease-in-out infinite;
  }
}
@keyframes bounceStatic{
  0%, 100%{ transform: translateY(0); }
  50%{ transform: translateY(8px); }
}

/* Etiquetas puramente visuales, no navegacion — a proposito no llevan a
   ningun lado (decision explicita: no sacar al visitante del hero antes
   de que lea la propuesta). <ul aria-hidden>, no <nav>/<a>, para no
   prometerle "navegacion" a un lector de pantalla que no existe. */
.hero__quicklinks{
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1rem;
  list-style: none;
  padding: 0;
}
/* <ul aria-hidden> a proposito, no <nav>/<a>: son etiquetas puramente
   visuales (el usuario pidio que no naveguen), asi que no llevan estado
   :hover — eso implicaria una interactividad que no existe. */
.hero__quicklinks li{
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--golddeep);
  border: 1px solid rgba(var(--gold-rgb), 0.4);
  border-radius: 999px;
  padding: 0.4em 0.9em;
}

.scroll-indicator{
  position:absolute;
  left: 50%;
  bottom: 2rem;
  transform: translateX(-50%);
  color: var(--gold);
  font-size: 1.5rem;
  animation: bounce 2s ease-in-out infinite;
}
@keyframes bounce{
  0%,100%{ transform: translate(-50%, 0); }
  50%{ transform: translate(-50%, 8px); }
}

/* =========================================================
   MARQUEE
   ========================================================= */
.marquee{
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  /* Bug conocido de iOS Safari: overflow:hidden a veces NO recorta a un
     hijo con transform + will-change (justo lo que es .marquee__track,
     animado sin parar) — el navegador lo promueve a su propia capa y esa
     capa se puede seguir "sintiendo" mas ancha que el contenedor aunque
     visualmente se vea recortada, permitiendo scroll horizontal real de
     la pagina. contain:paint es la garantia moderna de que nada pinta
     fuera de esta caja, cierra ese hueco. */
  contain: paint;
  white-space: nowrap;
  padding: 1.1rem 0;
}
.marquee__track{
  display: inline-flex;
  align-items:center;
  animation: marqueeScroll 32s linear infinite;
  will-change: transform;
}
.marquee__item{
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(0.8rem, 2vw, 1.05rem);
  color: var(--ink);
  padding: 0 1rem;
}
.marquee__item:nth-child(10n+3),
.marquee__item:nth-child(10n+7){ color: var(--golddeep); }
.marquee__sep{ color: var(--gold); padding: 0 0.5rem; }

/* En mobile queda pegado al fondo del hero (ver .hero min-height arriba):
   alto fijo de 48px en vez del padding en rem, para que el descuento que
   le hacemos al hero sea exacto y no ande adivinando por breakpoint. */
@media (max-width: 767px){
  .marquee{ height: 48px; padding: 0; display: flex; align-items: center; }
}

@keyframes marqueeScroll{
  from{ transform: translateX(0); }
  to{ transform: translateX(-50%); }
}

/* =========================================================
   PROBLEMA — golpe 1: stacking cards
   ========================================================= */
.problema{ background: var(--cream); }
/* El hueco hacia Metodo se sentia mucho mas grande que el que hay entre
   el marquee y "TE SUENA FAMILIAR" (la referencia que se pidio igualar):
   la seccion suma su padding-bottom normal (--section-gap) + el
   margin-top del scrollcue + el padding-top de Metodo — se recorta el
   primero aqui, el segundo abajo en .problema__scrollcue, y el de
   Metodo en su propia regla. */
.problema{ padding-bottom: clamp(1rem, 2vw, 1.5rem); }
/* position:sticky no funciona si un ancestro recorta overflow — esta
   seccion necesita salirse de la regla general de .section para que el
   stack pueda pinnearse. ScrollSmoother soporta sticky nativamente, asi
   que no hace falta nada especial mas alla de esto. */
.problema{ overflow: visible; }
.problema .section-title{ margin-bottom: 2rem; }

/* position:sticky NO engancha dentro de #smooth-content (ScrollSmoother lo
   mueve con transform). Pinear cada card por separado tampoco (arrancaba
   en la segunda card). Patron actual: UN pin sobre un escenario fijo, las
   3 cards en la misma columna PERO cada una con su propio reposo vertical
   (0 / 60 / 120px, via transform en JS) — asi la de atras de verdad
   asoma arriba en vez de que el texto de las dos se mezcle en el mismo
   sitio (eso pasaba con inset:0 identico en las 3). La card mide menos
   que el escenario (100% - 120px) para que la mas baja (offset 120px)
   quepa completa sin desbordar. */
.problema__stack{
  position: relative;
  height: clamp(580px, 62vh, 740px);
  margin-bottom: 1.5rem;
  overflow: hidden;
}
/* En mobile el asomo crecio a 140px (240px arriba), que le resta ese
   mismo alto a cada card (ver calc(100% - 280px) mas abajo) — sin
   compensarlo aqui la card se queda muy corta para su propio contenido y
   el parrafo se corta justo donde empieza a taparlo la siguiente card.
   Se sube el minimo del stack lo que se le resto a la card, para que el
   alto de contenido disponible se quede igual que antes (con el asomo de
   100px), solo que ahora con mas separacion visual entre cards. */
@media (max-width: 767px){
  .problema__stack{ height: clamp(660px, 66vh, 820px); }
}
.problema__card{
  position: absolute;
  top: 0; left: 0; right: 0;
  height: calc(100% - 120px);
  display:flex;
  flex-direction: column;
  justify-content: center;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 28px;
  /* --paper y --cream (fondo de la seccion) son tonos casi identicos —
     con solo el borde de 1px, el pedazo de card que "asoma" detras de la
     siguiente casi no se distingue del fondo y el stack se ve pegado
     aunque el offset en JS sea correcto. La sombra le da profundidad real:
     ahora se lee como una tarjeta fisica encima de otra, no como dos
     rectangulos del mismo color tocandose. */
  box-shadow: 0 16px 40px -12px rgba(var(--ink-rgb), 0.16);
  padding: clamp(2rem, 5vw, 3.5rem);
  transform-origin: 50% 0%;
  will-change: transform, opacity;
}
.problema__card:nth-child(1){ z-index: 1; }
.problema__card:nth-child(2){ z-index: 2; }
.problema__card:nth-child(3){ z-index: 3; }

/* En mobile motion.js usa un asomo de 140px por card (en vez de 60) para
   que se note el borde de la card de atras — el hueco reservado abajo del
   escenario (100% - Npx) tiene que crecer con el mismo numero: max offset
   = 2 cards * 140px = 280px. */
@media (max-width: 767px){
  .problema__card{ height: calc(100% - 280px); }
}

.problema__num{
  display:block;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--gold);
  font-size: clamp(3rem, 9vw, 5.5rem);
  line-height: 1;
  margin-bottom: 1.25rem;
}
.problema__card h3{
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  font-weight: 700;
  margin-bottom: 0.85rem;
  color: var(--ink);
  max-width: 22ch;
}
.problema__card p{ color: var(--body); line-height: 1.55; font-size: 1.05rem; max-width: 50ch; }

.problema__close{
  color: var(--golddeep);
  font-weight: 600;
  font-size: clamp(1.2rem, 3vw, 1.8rem);
  max-width: 20ch;
}

/* Guia de scroll: el stack de cartas deja bastante aire debajo antes de
   Metodo (necesario para que el pin funcione) y sin nada que lo señale se
   siente como que la pagina termino ahi. Un trazo largo con un chevron,
   msmo lenguaje line-art que los icono de servicio, en vez de una flecha
   de texto suelta. */
.problema__scrollcue{
  display:flex;
  justify-content:center;
  margin-top: clamp(0.75rem, 2vw, 1.25rem);
  color: var(--gold);
}
.problema__scrollcue-arrow{
  width: 28px;
  height: auto;
  animation: scrollcueDrift 2.2s ease-in-out infinite;
}
@keyframes scrollcueDrift{
  0%, 100%{ transform: translateY(0); opacity: 0.55; }
  50%{ transform: translateY(10px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  .problema__scrollcue-arrow{ animation: none; opacity: 0.8; }
}

/* Reduced-motion: columna normal, sin pin ni superposicion — el escenario
   tambien vuelve a alto automatico (las 3 cards ya no comparten el mismo
   cuadro fijo). */
@media (prefers-reduced-motion: reduce){
  .problema__stack{ height: auto; }
  .problema__card{
    position: static;
    height: auto;
    min-height: 0;
    margin-bottom: 1.5rem;
  }
}

/* =========================================================
   METODO — golpe 2: scroll horizontal anclado
   Base (movil / touch / reduced-motion): columna vertical normal, cards
   generosas. Solo se vuelve pista horizontal con hover:hover+pointer:fine
   + min-width — el mismo gate que ya usa el cursor y el fondo vivo, para
   no repetir un cuarto criterio de "es desktop" distinto en el sitio.
   ========================================================= */
.metodo{ background: var(--cream); }
.metodo__pin-stage{ position: relative; }
/* Mismo problema que el hero: al pinnear con ScrollSmoother activo, el
   stage se fija con su borde superior pegado al top real del viewport
   (start:'top top'), detras del nav semitransparente — el kicker y el
   titulo quedaban tapados apenas arrancaba el scroll horizontal. */
html.has-smoother .metodo__pin-stage{ padding-top: calc(var(--nav-h) + 0.25rem); }
/* El padding-top de .section (via --section-gap) queda redundante con el
   de arriba cuando el smoother esta activo — sumados dejaban un hueco
   enorme antes de que arrancara el scroll horizontal. */
html.has-smoother .metodo{ padding-top: 0; }

.metodo__viewport{ margin-top: 1.5rem; }
.metodo__track{
  display:flex;
  flex-direction: column;
  gap: 1.5rem;
}
.metodo__panel{
  position: relative;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: clamp(2rem, 5vw, 3rem);
}
.metodo__panel-num{
  display:block;
  position: relative;
  z-index: var(--z-content);
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: clamp(2.5rem, 6vw, 3.5rem);
  line-height: 1;
  color: var(--gold);
  margin-bottom: 1rem;
}
.metodo__panel h3{
  position: relative;
  z-index: var(--z-content);
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: clamp(1.2rem, 2.5vw, 1.5rem);
  letter-spacing: -0.01em;
  margin-bottom: 0.6rem;
  color: var(--ink);
}
.metodo__panel p{
  position: relative;
  z-index: var(--z-content);
  color: var(--body);
  line-height: 1.55;
  max-width: 42ch;
}

.metodo__progress{ display:none; }

.metodo__arrow{
  position:absolute;
  bottom: 0;
  right: 0;
  width: clamp(120px, 34vw, 480px);
  height: auto;
  opacity: 0.42;
  pointer-events:none;
}

/* ---- desktop + mouse real: pista horizontal ----
   Gateada por .metodo--horizontal, una clase que SOLO motion.js agrega
   despues de armar el pin con exito. Nunca solo por media query: si el
   JS fallara, un layout horizontal sin nada que lo controle dejaria 3 de
   los 4 pasos fuera de la pantalla — contenido real escondido, viola el
   principio rector. El ancho de cada panel lo fija JS via --panel-w
   (100% de .metodo__track no funciona: quedaria relativo a un padre que
   el mismo ya crecio al 400%, multiplicando el ancho en vez de repartirlo). */
.metodo.metodo--horizontal .metodo__viewport{ overflow: hidden; }
.metodo.metodo--horizontal .metodo__track{
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 0;
  width: max-content;
  /* El panel 1 ya no arranca pegado al borde izquierdo del viewport —
     un poco de aire antes para que no se sienta cortado/tapado por el
     borde de la pantalla. */
  padding-left: clamp(1rem, 3vw, 2rem);
}
.metodo.metodo--horizontal .metodo__panel{
  width: var(--panel-w, 100vw);
  flex-shrink: 0;
  min-height: 40vh;
  display:flex;
  flex-direction: column;
  justify-content: center;
  /* Contenido a la derecha: las tarjetas entran deslizandose desde la
     derecha, asi que texto pegado a ese lado se lee primero y se siente
     mas intuitivo que texto a la izquierda (que quedaba "atras"). */
  align-items: flex-end;
  text-align: right;
  border-radius: 0;
  border: none;
  border-left: 1px solid var(--line);
  background: transparent;
  padding: clamp(1.5rem, 4vw, 3rem) clamp(1.75rem, 5vw, 4rem);
}
.metodo.metodo--horizontal .metodo__panel:first-child{ border-left: none; }
.metodo.metodo--horizontal .metodo__panel-num{
  position: absolute;
  top: 0; left: auto; right: clamp(1rem, 4vw, 3rem);
  font-size: clamp(7rem, 16vw, 11rem);
  color: rgba(var(--gold-rgb), 0.14);
  z-index: var(--z-decorative);
  margin: 0;
}
.metodo.metodo--horizontal .metodo__progress{
  display:block;
  position: relative;
  height: 3px;
  background: var(--line);
  border-radius: 2px;
  margin-top: 1.25rem;
  overflow: hidden;
}
.metodo__progress-bar{
  display:block;
  height:100%;
  width:100%;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: 0% 50%;
}

/* Guia de scroll propia para Metodo: el scroll vertical mueve las
   tarjetas horizontalmente, algo que no es obvio hasta que ya lo
   hiciste. Mismo lenguaje visual que la de Problema (chevron + deriva)
   pero con texto explicito porque aqui la confusion es real (bajas y
   se mueve para el lado). Solo quando el pin horizontal esta activo —
   en la version vertical de respaldo no hace falta la aclaracion. */
.metodo__scrollcue{ display:none; }
.metodo.metodo--horizontal .metodo__scrollcue{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:0.4rem;
  /* Antes vivia despues de todo el contenido (kicker+titulo+panel+barra),
     asi que quedaba fuera de la primera pantalla — habia que scrollear
     para verlo, justo lo contrario de lo que deberia hacer una guia de
     "sigue bajando". Anclado al viewport del stage pineado, siempre
     visible desde que arranca la seccion. */
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  color: var(--golddeep);
  z-index: var(--z-content);
}
.metodo__scrollcue-arrow{
  width: 22px;
  height: auto;
  animation: scrollcueDrift 2.2s ease-in-out infinite;
}
.metodo__scrollcue span{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
@media (prefers-reduced-motion: reduce){
  .metodo__scrollcue-arrow{ animation: none; opacity: 0.8; }
}

/* =========================================================
   SERVICIOS
   ========================================================= */
.servicios{ background: var(--paper); }
.servicios .section-title{ margin-bottom: 2rem; }
.servicios__grid{
  display:grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}
.servicio-card{
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 2rem;
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.servicio-card:hover{ border-color: var(--gold); transform: translateY(-4px); }
.servicio-card:hover .arrow{ transform: translateX(4px); }
.servicio-icon{
  width: 52px;
  height: 52px;
  margin-bottom: 1.25rem;
}
.servicio-card h3{
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.75rem;
  color: var(--ink);
}
.servicio-card p{ color: var(--body); line-height: 1.5; margin-bottom: 1.5rem; }
.card-link{ color: var(--golddeep); font-weight: 600; font-family: var(--font-mono); font-size: 0.9rem; }
.card-link .arrow{ color: var(--gold); }

/* Redes Sociales es el servicio estrella de los paquetes — protagonista
   del bento. En movil solo un empujon sutil (mas padding, icono un poco
   mas grande); el peso real de "2 columnas x doble alto" es cosa de
   desktop, ver el media query de abajo. */
.servicio-card--featured{ padding: 2.5rem; }
.servicio-card--featured .servicio-icon{ width: 64px; height: 64px; }
.servicio-card--featured h3{ font-size: 1.5rem; }

@media (min-width: 768px){
  .servicios__grid{ grid-template-columns: repeat(2, 1fr); }
}

/* ---- desktop: bento asimetrico ---- */
@media (min-width: 1024px){
  .servicios__grid{
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: minmax(200px, auto);
    gap: 1.25rem;
  }
  .servicio-card{ display:flex; flex-direction:column; justify-content:center; }
  .servicio-card--featured{
    grid-column: span 2;
    grid-row: span 2;
    padding: 3.5rem;
  }
  .servicio-card--featured .servicio-icon{ width: 84px; height: 84px; margin-bottom: 1.75rem; }
  .servicio-card--featured h3{ font-size: 1.9rem; }
  .servicio-card--featured p{ font-size: 1.05rem; max-width: 46ch; }
  /* Publicidad y Branding compactas, apiladas a la derecha de Redes;
     WhatsApp cierra a ancho completo abajo. */
  .servicios__grid > :nth-child(4){ grid-column: span 3; }
}

/* =========================================================
   CASOS — golpe 3: espresso. El climax de contraste de la pagina, un solo
   bloque oscuro dentro del sistema light (misma logica que la banda
   dorada de Diagnostico). NO es volver al tema dark: es un momento fijo,
   no depende de prefers-color-scheme. Café cálido en vez de negro puro:
   el negro se leía "premium/inalcanzable" para el cliente objetivo
   (PYME de presupuesto bajo-medio).
   ========================================================= */
.casos{
  position: relative;
  padding: 0 0 clamp(2rem, 5vw, 3rem);
  background: var(--espresso);
}
/* Transiciones suaves en los bordes: entra desde el papel de Servicios,
   sale hacia el dorado de Diagnostico — nunca un corte duro. Mas cortas
   que antes (60-110px) para que nunca lleguen a pisar el texto del primer
   o ultimo caso — antes el degradado del fondo alcanzaba a taparle
   contraste a la ultima tarjeta. */
.casos::before,
.casos::after{
  content:'';
  position:absolute;
  left:0; right:0;
  height: clamp(32px, 5vw, 56px);
  z-index: 5;
  pointer-events:none;
}
/* Antes se desvanecian a transparent sobre el fondo solido --espresso: un
   color claro perdiendo opacidad sobre un fondo oscuro no interpola limpio
   (queda un tramo grisaceo/sucio en medio). Gradiente directo a los dos
   colores reales — transicion pareja de menos a mas oscuro. */
/* top:-1px tapa un posible hilo de 1px entre secciones (redondeo de
   subpixel cuando ScrollSmoother mueve el contenido con transform). Parada
   intermedia a mitad de camino en vez de un solo salto de 2 colores —
   se percibe mas como degradado real y menos como dos bloques pegados. */
.casos::before{ top:-1px; background: linear-gradient(to bottom, var(--paper), color-mix(in srgb, var(--paper) 35%, var(--espresso)) 55%, var(--espresso)); }
.casos::after{ bottom:-1px; background: linear-gradient(to top, var(--gold), color-mix(in srgb, var(--gold) 35%, var(--espresso)) 55%, var(--espresso)); }

.casos > .kicker, .casos > .section-title{ padding: 0 clamp(1.5rem, 6vw, 4rem); }
.casos > .kicker{ padding-top: clamp(2.5rem, 6vw, 4.5rem); color: var(--gold); }
.casos > .section-title{ margin-bottom: clamp(2rem, 6vw, 4rem); max-width: 22ch; color: var(--cream); }

.caso{
  position: relative;
  background: transparent;
  padding: clamp(3rem, 8vw, 6rem) clamp(1.5rem, 6vw, 4rem);
  overflow: hidden;
  border-top: 1px solid rgba(var(--gold-rgb), 0.25);
}
.caso:first-of-type{ border-top: none; }

/* Numero fantasma: el minimo del clamp (9rem=144px) ganaba en moviles
   angostos porque 30vw ya no alcanzaba ese piso ahi — el numero terminaba
   mas grande que el propio bloque de texto y se metia en la quote. Bajado
   el minimo y el vw para que crezca proporcional en vez de topar arriba. */
.ghost-num{
  position:absolute;
  right: -0.05em;
  bottom: -0.18em;
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: clamp(4.5rem, 26vw, 22rem);
  color: rgba(var(--gold-rgb), 0.12);
  line-height: 1;
  z-index: var(--z-decorative);
  pointer-events: none;
  user-select: none;
}
.halftone{
  position:absolute;
  top: 1.5rem; right: 1.5rem;
  width: clamp(140px, 18vw, 200px);
  height: auto;
  opacity: 0.35;
  z-index: var(--z-decorative);
  pointer-events:none;
}

.caso__content{ position: relative; z-index: var(--z-content); max-width: 640px; }
.caso__tag{
  font-family: var(--font-mono);
  color: var(--gold);
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-bottom: 1rem;
  font-size: 0.85rem;
}
/* Los contadores son el clímax visual de la seccion — escala mayor que
   en el resto de la pagina (antes 3.5-7rem). */
.caso__metric{
  font-weight: 800;
  font-size: clamp(4.5rem, 15vw, 9rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
.caso__metric-affix{ color: var(--gold); }
.caso__metric-label{
  font-family: var(--font-mono);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gold);
  margin-bottom: 1.5rem;
  font-size: 0.85rem;
}
.caso__facts{ margin-bottom: 1.5rem; }
.caso__facts li{
  color: rgba(245,237,216,0.75);
  padding-left: 1.2em;
  position: relative;
  margin-bottom: 0.4rem;
}
.caso__facts li::before{
  content: '—';
  position:absolute; left:0; color: var(--gold);
}
.caso__quote{
  font-size: 1.1rem;
  font-style: normal;
  color: rgba(245,237,216,0.75);
  border-left: 1px solid rgba(var(--gold-rgb), 0.25);
  padding-left: 1rem;
  margin: 0;
}
.caso__quote cite{
  display:block;
  font-style: normal;
  font-family: var(--font-mono);
  color: rgba(245,237,216,0.55);
  font-size: 0.8rem;
  margin-top: 0.6rem;
}

/* =========================================================
   DIAGNÓSTICO — único bloque sólido dorado de la página
   ========================================================= */
.diagnostico{ background: var(--gold); }
.diagnostico .kicker{ color: var(--ink); }
.diagnostico .section-title{ color: var(--ink); margin-bottom: 2rem; }

.diag-widget{
  max-width: 720px;
}
.diag-progress{
  height: 3px;
  background: rgba(var(--ink-rgb), 0.2);
  border-radius: 2px;
  margin-bottom: 2rem;
  overflow:hidden;
}
.diag-progress__bar{
  display:block;
  height:100%;
  width: 25%;
  background: var(--ink);
  transition: width 0.4s var(--ease);
}
.diag-step__q{
  font-weight: 600;
  font-size: 1.3rem;
  margin-bottom: 1.5rem;
  color: var(--ink);
}
.diag-options{
  display:grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
}
.diag-opt{
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1rem;
  text-align:left;
  background: var(--paper);
  color: var(--ink);
  border: 2px solid transparent;
  border-radius: 4px;
  padding: 1rem 1.25rem;
  cursor:pointer;
  transition: border-color 0.2s var(--ease);
}
.diag-opt:hover{ border-color: var(--ink); }

.diag-result__title{
  font-weight: 800;
  font-size: 1.4rem;
  color: var(--ink);
  margin-bottom: 1rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.diag-result__text{ color: var(--ongold); line-height: 1.6; margin-bottom: 1.75rem; }
.diag-result .btn--gold{ background: var(--ink); color: var(--cream); }
.diag-result .btn--gold:hover{ background: var(--ongold); }
.diag-restart{
  display:block;
  margin-top: 1rem;
  background: none;
  border: none;
  color: var(--ongold);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-decoration: underline;
  cursor:pointer;
}

@media (min-width: 768px){
  .diag-options{ grid-template-columns: repeat(2, 1fr); }
}

/* =========================================================
   PRECIOS
   ========================================================= */
.precios{ background: var(--cream); }
.precios__subtitle{
  color: var(--body);
  max-width: 60ch;
  margin: 1.5rem 0 3rem;
  font-size: 1.05rem;
}
.precios__grid{
  display:grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
.price-card{
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2.25rem 2rem;
}
.price-card--featured{
  border-color: var(--gold);
  border-width: 2px;
  transform: scale(1.0);
}
.price-card__badge{
  position:absolute;
  top: -0.9rem;
  left: 2rem;
  background: var(--cream);
  color: var(--golddeep);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.7rem;
  padding: 0.4em 0.8em;
  border-radius: 999px;
  letter-spacing: 0.03em;
  border: 1px solid var(--line);
}
.price-card h3{
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  color: var(--body);
  margin-bottom: 1rem;
}
.price-card__price{
  font-weight: 800;
  font-size: clamp(2.5rem, 6vw, 3.2rem);
  color: var(--ink);
  margin-bottom: 1.5rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.price-card__price-affix{ color: var(--gold); }
.price-card__price span{
  font-size: 1rem;
  font-weight: 500;
  color: var(--body);
}
.price-card__list{ margin-bottom: 2rem; }
.price-card__list li{
  display:flex;
  align-items: flex-start;
  gap: 0.6em;
  color: var(--body);
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
  line-height: 1.4;
}
.price-card__list li span{ margin-top: 0.15em; }
.price-card__list li span{ color: var(--gold); }
.price-card .btn{ width: 100%; justify-content: center; }

.precios__footnote{ margin-top: 2.5rem; text-align:center; }

@media (min-width: 768px){
  .precios__grid{ grid-template-columns: repeat(3, 1fr); align-items: start; }
  .price-card--featured{ transform: scale(1.03); }
}

/* =========================================================
   MANIFIESTO
   ========================================================= */
.manifiesto{
  background: var(--cream);
  color: var(--ink);
  text-align: left;
}
.manifiesto__title{
  font-family: var(--font-sans);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.98;
  font-size: clamp(2rem, 7vw, 4.5rem);
  max-width: 18ch;
  color: var(--ink);
  margin-bottom: 2rem;
  text-wrap: balance;
}
.manifiesto__divider{
  display:block;
  width: 90px;
  height: auto;
  margin-bottom: 2rem;
}
.manifiesto__text{
  color: var(--body);
  max-width: 42ch;
  font-size: clamp(1.5rem, 2.4vw, 1.75rem);
  font-weight: 500;
  line-height: 1.4;
  margin-bottom: 2rem;
}
.manifiesto__signature{
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--body);
  font-size: 1.2rem;
}

.manifiesto__grid{
  display:grid;
  grid-template-areas: "arlo" "copy";
  gap: 2.5rem;
  align-items:center;
}
@media (min-width: 768px){
  .manifiesto__grid{
    grid-template-columns: 1.15fr 0.85fr;
    grid-template-areas: "copy arlo";
    gap: 3rem;
  }
}
.manifiesto__copy{ grid-area: copy; }
.manifiesto__arlo-wrap{ grid-area: arlo; position: relative; }

/* Chispas de "magia" alrededor de Arlo: mas rapidas que su respiracion
   idle (3s) para que se sientan como algo aparte, revoloteando. */
.manifiesto__sparkle{
  position:absolute;
  width: 30px;
  height: auto;
  opacity: 0.85;
  pointer-events: none;
  z-index: 2;
  animation: sparkleTwinkle 1.6s ease-in-out infinite;
}
.manifiesto__sparkle--1{ top: 0%; left: -6%; width: 42px; animation-duration: 1.5s; animation-delay: 0s; }
.manifiesto__sparkle--2{ top: 8%; right: -2%; width: 60px; animation-duration: 1.9s; animation-delay: 0.4s; }
.manifiesto__sparkle--3{ bottom: 22%; left: -8%; width: 38px; animation-duration: 1.3s; animation-delay: 0.8s; }
.manifiesto__sparkle--4{ bottom: 2%; right: 10%; width: 50px; animation-duration: 1.7s; animation-delay: 1.1s; }
.manifiesto__sparkle--5{ top: 42%; left: -11%; width: 32px; animation-duration: 1.4s; animation-delay: 0.6s; }
.manifiesto__sparkle--6{ top: 28%; right: -9%; width: 44px; animation-duration: 1.8s; animation-delay: 1.5s; }
.manifiesto__sparkle--7{ top: 62%; left: 2%; width: 36px; animation-duration: 1.6s; animation-delay: 0.2s; }
.manifiesto__sparkle--8{ top: -4%; right: 22%; width: 48px; animation-duration: 2s; animation-delay: 1.8s; }

@keyframes sparkleTwinkle{
  0%, 100%{ transform: scale(0.7) rotate(-8deg); opacity: 0.4; }
  50%{ transform: scale(1.08) rotate(8deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  .manifiesto__sparkle{ animation: none; opacity: 0.75; }
}

/* Arlo: entrada, respiracion idle y el destello del collar. Tres capas:
   -wrap recibe SOLO el parallax de scroll (scrub continuo), -inner recibe
   la entrada + el bob de idle (timeline propia). Separarlos evita que dos
   tweens de GSAP se pisen sobre el mismo transform. */
.manifiesto__arlo-inner{
  position: relative;
  width: min(300px, 72vw);
  margin-inline: auto;
}
@media (min-width: 768px){
  .manifiesto__arlo-inner{ width: min(420px, 100%); margin-inline: 0; }
}
.manifiesto__arlo-img{
  width: 100%;
  height: auto;
  display:block;
}
/* Resplandor sobre el dije del collar (no separable del PNG raster).
   Posicion calibrada a ojo contra el asset: ~37% / 51% del recuadro. */
.manifiesto__arlo-glow{
  position:absolute;
  left: 39%;
  top: 52.5%;
  width: 15%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--gold-rgb),0.9) 0%, rgba(var(--gold-rgb),0.35) 45%, rgba(var(--gold-rgb),0) 75%);
  filter: blur(1.5px);
  opacity: 0.32;
  pointer-events:none;
}

/* Guino: mismo truco que el glow, un ovalo superpuesto del color exacto
   del plumaje junto al ojo. scaleY(0) = invisible (ojo abierto, estado
   base sin JS). motion.js lo cierra con un scaleY rapido y periodico. */
.manifiesto__arlo-eyelid{
  position:absolute;
  left: 46.5%;
  top: 18.9%;
  width: 6%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) scaleY(0);
  border-radius: 50%;
  background: #201A1E;
  pointer-events:none;
}

.manifiesto__logo{
  width: clamp(90px, 12vw, 110px);
  height: auto;
  margin-top: 2.5rem;
}

/* =========================================================
   FAQ
   ========================================================= */
.faq{ background: var(--paper); }
.faq__list{ max-width: 780px; }
.faq-item{
  border-bottom: 1px solid var(--line);
  padding: 1.5rem 0;
}
.faq-item summary{
  font-weight: 600;
  font-size: clamp(1.2rem, 2.4vw, 1.45rem);
  cursor: pointer;
  list-style: none;
  display:flex;
  justify-content: space-between;
  align-items:center;
  gap: 1rem;
  color: var(--ink);
}
.faq-item summary::-webkit-details-marker{ display:none; }
.faq-item summary::after{
  content: '+';
  font-family: var(--font-mono);
  font-weight: 400;
  color: var(--gold);
  font-size: 2rem;
  line-height: 1;
  flex-shrink:0;
  transition: transform 0.25s var(--ease);
}
.faq-item[open] summary::after{ content:'—'; }
.faq-item p{
  color: var(--body);
  margin-top: 1rem;
  line-height: 1.6;
  max-width: 65ch;
  font-size: 1.1rem;
}

/* =========================================================
   CTA FINAL
   ========================================================= */
.cta-final{
  background: var(--cream);
  text-align: left;
}
.cta-final__title{
  color: var(--ink);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.96;
  /* Golpe 6: es el cierre de toda la pagina, merece mas peso de statement
     que antes (era el mismo tamaño que un section-title cualquiera). */
  font-size: clamp(2.25rem, 7.5vw, 5rem);
  max-width: 19ch;
  margin-bottom: 2.5rem;
  text-wrap: balance;
}
.cta-final__actions{ margin-bottom: 0.5rem; text-align: center; }
.cta-final__line{
  font-weight: 600;
  color: var(--golddeep);
  font-size: 1.1rem;
  margin-bottom: 0.6rem;
}
.cta-final__line .arrow{ color: var(--gold); }
.cta-final__btn{ display:flex; width: fit-content; margin-inline: auto; }
.cta-final__chevrons{
  position:absolute;
  top: 1.5rem; right: 1.5rem;
  width: clamp(48px, 8vw, 130px);
  aspect-ratio: 520 / 976;
  opacity: 0.32;
  pointer-events:none;
}
/* Tres recortes de la misma imagen (no un trazo SVG inventado del chevron
   raster) para poder revelar cada uno en secuencia al hacer scroll. */
.cta-final__chevron-band{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
}
.cta-final__chevron-band--top{ clip-path: inset(0% 0 66.667% 0); }
.cta-final__chevron-band--mid{ clip-path: inset(33.333% 0 33.333% 0); }
.cta-final__chevron-band--bottom{ clip-path: inset(66.667% 0 0% 0); }

/* =========================================================
   FOOTER
   ========================================================= */
.footer{
  background: var(--cream);
  border-top: 1px solid var(--line);
  padding: 3rem clamp(1.5rem, 6vw, 4rem) 2rem;
}
/* Compensa el dock flotante bajo 1024px para que nunca tape el copyright. */
@media (max-width: 1023px){
  .footer{ padding-bottom: calc(2rem + 96px); }
}
.footer__inner{ max-width: 1400px; margin:0 auto; }
.footer__logo-img{
  width: clamp(100px, 12vw, 120px);
  height: auto;
  margin-bottom: 0.75rem;
}
.footer__tagline{ color: var(--golddeep); margin-bottom: 1.5rem; }
.footer__meta{
  font-family: var(--font-mono);
  color: var(--body);
  font-size: 0.85rem;
  margin-bottom: 1.5rem;
}
.footer__links{
  display:flex;
  gap: 1.5rem;
  margin-bottom: 2rem;
}
.footer__links a{
  font-family: var(--font-mono);
  color: var(--body);
  font-size: 0.85rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
}
.footer__links a:hover{ color: var(--golddeep); border-color: var(--golddeep); }
.footer__copy{
  font-family: var(--font-mono);
  color: var(--body);
  font-size: 0.75rem;
}

/* =========================================================
   DOCK MÓVIL — reemplaza al FAB de WhatsApp bajo 1024px. Única sombra
   permitida en todo el sitio. Arriba de 1024px no existe (display:none):
   el botón "Hablemos" de la nav ya cubre esa función, y un segundo
   flotante dorado ahi competiria con el gesto de cursor y con la nav misma.
   ========================================================= */
.dock{
  display: none;
  position: fixed;
  left: 50%;
  bottom: 16px;
  z-index: var(--z-nav);
  align-items: center;
  /* max-width + gap mas chico: entre "Diagnostico" y "Servicios" (los
     links mas largos ahora) el dock se saliera de pantallas angostas si
     no se aprieta — se centraba con left:50% pero el contenido se
     desbordaba por un lado y se veia descuadrado/no centrado.
     overflow:hidden es la red de seguridad real: max-width limita la CAJA,
     pero sin esto los hijos (flex, sin wrap) podian seguir desbordandose
     MAS ALLA de esa caja. Al ser position:fixed, ese desborde no lo
     detenia el overflow-x:hidden de html/body (eso solo contiene el
     documento normal, no el contenido de un elemento fixed que se sale de
     su propia caja) — asi es como seguia habiendo scroll horizontal en
     toda la pagina aunque el nav ya estuviera arreglado. */
  overflow: hidden;
  max-width: calc(100vw - 16px);
  gap: clamp(0.35rem, 2vw, 0.85rem);
  padding: 0.55rem 0.4rem 0.55rem 0.7rem;
  border-radius: 999px;
  background: rgba(255,253,246,0.9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  box-shadow: 0 8px 28px rgba(var(--ink-rgb), 0.14);
  opacity: 0;
  transform: translate(-50%, 16px);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
@media (max-width: 1023px){ .dock{ display:flex; } }
.dock.is-visible{ opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
/* motion.js toma el control de opacity/transform (slide-up con overshoot)
   y deja de usar la transicion CSS para esas dos, para no pelearse entre si */
.dock--gsap-driven{ transition: none; }

.dock__link{
  font-family: var(--font-mono);
  font-size: clamp(0.62rem, 2.6vw, 0.72rem);
  letter-spacing: 0.02em;
  color: var(--ink);
  white-space: nowrap;
  transition: color 0.2s var(--ease);
}
.dock__link:hover{ color: var(--golddeep); }
.dock__link.is-active{ color: var(--golddeep); }
.dock__link--accent{ color: var(--golddeep); font-weight: 700; }
.dock__link--accent:hover,
.dock__link--accent.is-active{ color: var(--gold); }

.dock__wa{
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--gold);
  display:flex;
  align-items:center;
  justify-content:center;
  transition: background 0.2s var(--ease);
}
.dock__wa:hover{ background: var(--gold-hover); }

/* =========================================================
   REVEAL / SCROLL ANIMATIONS
   ========================================================= */
.reveal{
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal.is-visible{ opacity: 1; transform: translateY(0); }

/* =========================================================
   CURSOR PERSONALIZADO — gesto de firma, solo desktop con mouse
   Oculto por defecto: motion.js solo lo activa (opacity 1 + oculta el
   cursor nativo) si prefers-reduced-motion lo permite, el viewport es
   de escritorio y el dispositivo realmente tiene mouse (hover:hover).
   ========================================================= */
.cursor-dot, .cursor-ring{
  position: fixed;
  top: 0; left: 0;
  border-radius: 50%;
  pointer-events: none;
  z-index: var(--z-cursor);
  opacity: 0;
}
.cursor-dot{
  width: 6px;
  height: 6px;
  background: var(--gold);
}
.cursor-ring{
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--gold);
  transition: width 0.25s var(--ease), height 0.25s var(--ease), background-color 0.25s var(--ease), opacity 0.2s var(--ease);
}
.cursor-ring.is-active{
  width: 54px;
  height: 54px;
  background: rgba(var(--gold-rgb), 0.12);
}
body.has-custom-cursor, body.has-custom-cursor *{ cursor: none !important; }
body.has-custom-cursor .cursor-dot, body.has-custom-cursor .cursor-ring{ opacity: 1; }

/* =========================================================
   PRELOADER — overlay de primera carga. Oculto por defecto (opacity:0,
   visibility:hidden) para que si JS falla NUNCA bloquee el contenido real
   (PRINCIPIO RECTOR). Solo se activa visualmente con reduced-motion en
   "no-preference"; ahi trae su propio timeout de seguridad en CSS puro
   (sin depender de que ningun JS corra) que lo fuerza a desaparecer a
   los 2.5s pase lo que pase. motion.js hace la version coreografiada
   (mas rapida, ~1.4s) y sobreescribe este fallback antes de que dispare.
   ========================================================= */
.preloader{
  position: fixed;
  inset: 0;
  z-index: var(--z-preloader);
  background: var(--cream);
  display:flex;
  align-items:center;
  justify-content:center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference){
  .preloader{
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    animation: preloaderAutoHide 0.01ms 2.5s forwards;
  }
}
@keyframes preloaderAutoHide{
  to{ opacity:0; visibility:hidden; pointer-events:none; }
}
.preloader.is-done{ opacity:0 !important; visibility:hidden !important; pointer-events:none !important; }

.preloader__mark{
  position: relative;
  width: min(200px, 46vw);
  aspect-ratio: 700 / 417;
}
/* =========================================================
   CHATBOT ARLO
   ========================================================= */
.chat-widget{
  position: fixed;
  right: clamp(1rem, 4vw, 1.5rem);
  bottom: clamp(1rem, 4vw, 1.5rem);
  z-index: var(--z-atmosphere);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
/* Oculto mientras el hero esta a la vista (mismo patron que .dock): en el
   primer pantallazo el marquee puede caer justo donde vive este boton
   fijo, y ahi se ve encimado/feo. Aparece hasta que se hace scroll mas
   alla del hero, igual que el dock movil. */
.chat-widget.is-visible{ opacity: 1; transform: translateY(0); pointer-events: auto; }
/* Si el chat ya esta abierto, nunca se esconde aunque el usuario regrese
   al hero con el scroll (evita cerrarle la conversacion en la cara). */
.chat-widget.is-open{ opacity: 1; transform: translateY(0); pointer-events: auto; }

.chat-launcher{
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--gold);
  color: var(--ink);
  border: none;
  border-radius: 999px;
  padding: 0.55rem 1.1rem 0.55rem 0.55rem;
  cursor: pointer;
  box-shadow: 0 10px 30px rgba(var(--ink-rgb), 0.22);
  transition: background 0.2s var(--ease), transform 0.2s var(--ease), padding 0.25s var(--ease);
}
.chat-launcher:hover{ background: var(--gold-hover); transform: translateY(-2px); }
.chat-launcher__avatar{ width: 40px; height: 40px; border-radius: 50%; object-fit: cover; background: var(--paper); flex-shrink: 0; }
.chat-launcher__label{ font-family: var(--font-sans); font-weight: 700; font-size: 0.9rem; white-space: nowrap; }
.chat-launcher__icon--close{ display: none; width: 22px; height: 22px; margin: 0 9px; }
.chat-launcher__badge{
  position: absolute;
  top: -2px;
  right: -2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--espresso);
  color: var(--cream);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--cream);
}
.chat-launcher__badge[hidden]{ display: none; }
.chat-widget.is-open .chat-launcher{ padding: 0.65rem; }
.chat-widget.is-open .chat-launcher__avatar,
.chat-widget.is-open .chat-launcher__label{ display: none; }
.chat-widget.is-open .chat-launcher__icon--close{ display: block; }

@media (max-width: 1023px){
  .chat-widget{ bottom: calc(72px + clamp(0.75rem, 3vw, 1.25rem)); }
}

.chat-panel{
  position: absolute;
  right: 0;
  bottom: calc(100% + 0.85rem);
  width: min(360px, calc(100vw - 2rem));
  max-height: min(70vh, 560px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(var(--ink-rgb), 0.25);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  opacity: 0;
  transform: translateY(12px) scale(0.98);
  transform-origin: bottom right;
  pointer-events: none;
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
.chat-panel:not([hidden]){ opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.chat-panel[hidden]{ display: flex; }

.chat-panel__header{
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.chat-panel__avatar{ width: 34px; height: 34px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.chat-panel__title{ display: flex; flex-direction: column; line-height: 1.25; flex: 1; min-width: 0; }
.chat-panel__title strong{ font-size: 0.95rem; }
.chat-panel__title span{ font-family: var(--font-mono); font-size: 0.68rem; color: var(--body); }
.chat-panel__close{
  background: none; border: none; cursor: pointer; color: var(--body);
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.chat-panel__close svg{ width: 18px; height: 18px; }
.chat-panel__close:hover{ color: var(--ink); }

.chat-panel__messages{
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.chat-msg{
  max-width: 84%;
  padding: 0.55em 0.85em;
  border-radius: 16px;
  font-size: 0.88rem;
  line-height: 1.45;
  white-space: pre-wrap;
}
.chat-msg--bot{
  align-self: flex-start;
  background: var(--cream);
  color: var(--ink);
  border-bottom-left-radius: 4px;
}
.chat-msg--user{
  align-self: flex-end;
  background: var(--espresso);
  color: var(--cream);
  border-bottom-right-radius: 4px;
}
.chat-msg--error{ background: transparent; border: 1px solid var(--line); color: var(--body); }

.chat-typing{
  align-self: flex-start;
  display: flex;
  gap: 0.3rem;
  padding: 0.7em 0.9em;
  background: var(--cream);
  border-radius: 16px;
  border-bottom-left-radius: 4px;
}
.chat-typing span{
  width: 6px; height: 6px; border-radius: 50%; background: var(--body);
  animation: chatTypingBounce 1.1s infinite ease-in-out;
}
.chat-typing span:nth-child(2){ animation-delay: 0.15s; }
.chat-typing span:nth-child(3){ animation-delay: 0.3s; }
@keyframes chatTypingBounce{
  0%, 60%, 100%{ transform: translateY(0); opacity: 0.5; }
  30%{ transform: translateY(-4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  .chat-typing span{ animation: none; opacity: 0.8; }
}

.chat-panel__composer{
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.chat-panel__composer input{
  flex: 1;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.6em 1em;
  font-family: var(--font-sans);
  /* 16px minimo a proposito: por debajo de eso, iOS Safari hace zoom
     automatico de toda la pagina al enfocar el input y no se resetea
     hasta quitar el foco — deja botones fuera de pantalla (el de enviar
     quedaba cortado). Con 16px+ ese auto-zoom no se dispara. */
  font-size: max(0.88rem, 16px);
  background: var(--paper);
  color: var(--ink);
}
.chat-panel__composer input:focus-visible{ outline-offset: 1px; }
.chat-panel__send{
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: 50%;
  border: none;
  background: var(--gold);
  color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.2s var(--ease);
}
.chat-panel__send:hover{ background: var(--gold-hover); }
.chat-panel__send:disabled{ opacity: 0.5; cursor: default; }

.chat-panel__footnote{
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--body);
  text-align: center;
  padding: 0 0.9rem 0.8rem;
  flex-shrink: 0;
}
.chat-panel__footnote .wa-link{ color: var(--golddeep); text-decoration: underline; }

@media (max-width: 480px){
  .chat-panel{ width: calc(100vw - 1.5rem); right: -0.25rem; }
}

.preloader__img{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
}
/* Una sola imagen fuente, recortada dos veces con clip-path: separa
   visualmente el simbolo (arriba) del wordmark (abajo) sin fabricar
   un trazo SVG inventado del logo real. */
.preloader__img--symbol{ clip-path: inset(0% 0% 53% 0%); }
.preloader__img--word{ clip-path: inset(45% 0% 0% 0%); }

/* Fallback sin animacion de dibujo: si por lo que sea el JS de motion.js
   no llega a correr su timeline pero GSAP basico si, o en cualquier
   ejecucion muy temprana, el logo completo ya es visible de una vez. */
@media (prefers-reduced-motion: no-preference){
  .preloader__img{ opacity: 1; }
}

/* =========================================================
   FONDO VIVO — lineas doradas sutiles con parallax de mouse.
   Solo hero + CTA final. Oculto por CSS pura en touch/mobile: no depende
   de JS para desaparecer ahi, el gate hover:hover+pointer:fine+min-width
   ya lo resuelve. motion.js solo le agrega el movimiento, gated ademas
   por prefers-reduced-motion dentro de su propio gsap.matchMedia.
   ========================================================= */
.reactive-lines-mask{
  display:none;
  position:absolute;
  inset:0;
  z-index: var(--z-decorative);
  overflow:hidden;
  pointer-events:none;
}
@media (hover:hover) and (pointer:fine) and (min-width:1024px){
  .reactive-lines-mask{ display:block; }
}
.reactive-lines{
  position:absolute;
  top:-24px; left:-24px;
  width:calc(100% + 48px);
  height:calc(100% + 48px);
  display:block;
}
.reactive-lines line{
  stroke: var(--gold);
  vector-effect: non-scaling-stroke;
}
.reactive-lines line:nth-child(odd){ stroke-opacity:0.08; }
.reactive-lines line:nth-child(even){ stroke-opacity:0.12; }

/* =========================================================
   GRANO — calidez de papel impreso, conecta con el diptico.
   Puramente CSS, sin JS: siempre presente, no depende de motion.js.
   ========================================================= */
.grain{
  position: fixed;
  inset: 0;
  z-index: var(--z-atmosphere);
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* =========================================================
   RESPONSIVE TYPE SCALE ADJUSTMENTS
   ========================================================= */
@media (min-width: 1200px){
  .section{ padding-left: 6rem; padding-right: 6rem; }
}

/* =========================================================
   REDUCED MOTION
   ========================================================= */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  *, *::before, *::after{
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .marquee__track{ animation: none; }
  .reveal{ transform: none; opacity: 1; }
}
