/* ==========================================================================
   Helios by Congenia — Landing de conversión
   Mobile-first. Todos los valores de color/tipografía vienen de theme.css.
   No hardcodear hex acá: si falta un color, se agrega al theme.
   ========================================================================== */

/* --------------------------------------------------------------- Reset --- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  font-weight: var(--fw-body-light);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-body-light);
  background-color: var(--surface-base);
  -webkit-font-smoothing: antialiased;
  /* clip y no hidden: `overflow-x: hidden` convierte al body en contenedor de
     scroll y rompe el position:sticky de las tarjetas apiladas de la sección
     de objeciones. `clip` recorta igual pero no crea scroll container.
     hidden queda como fallback para navegadores sin soporte de clip. */
  overflow-x: hidden;
  overflow-x: clip;
}

img, video, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul, ol { list-style: none; }

:focus-visible {
  outline: 2px solid var(--c-gris-acero);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--c-petroleo);
  color: var(--c-blanco);
  padding: 12px 20px;
}
.skip-link:focus { left: 8px; top: 8px; }

/* ----------------------------------------------------------- Tipografía -- */
h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: var(--fw-title);
  line-height: var(--lh-title);
  letter-spacing: var(--ls-title);
  color: var(--text-strong-light);
}

/* ------------------------------------------------------------- Layout ---- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container-narrow { max-width: var(--container-narrow); }

@media (min-width: 768px) {
  .container { padding-inline: var(--gutter-lg); }
}

.section {
  position: relative;
  padding-block: var(--section-py);
  overflow: hidden;
  /* Compensa el header sticky al navegar por anclas */
  scroll-margin-top: var(--header-h);
}
/* El hero arranca en el borde superior de la página: no necesita compensar
   el header, que va montado encima. */
.hero { scroll-margin-top: 0; }
.section-light { background: var(--surface-base); }
.section-alt { background: var(--surface-alt); }
.section-dark { background: var(--surface-dark); color: var(--text-body-dark); }
.section-dark h1, .section-dark h2, .section-dark h3 { color: var(--text-strong-dark); }
.section-dark.topo-texture { color: var(--c-gris-claro); }
.section-dark.topo-texture > .container { position: relative; z-index: 1; }

.section-head { max-width: 760px; margin-bottom: clamp(36px, 5vw, 56px); }

.eyebrow {
  font-family: var(--font-body);
  font-weight: var(--fw-body-medium);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-gris-azulado);
  margin-bottom: 14px;
}
.eyebrow-dark { color: var(--text-muted-dark); }

.section-title { font-size: var(--fs-h2); margin-bottom: 18px; }
.section-lead {
  font-size: var(--fs-lead);
  max-width: 62ch;
}
/* Bajadas de varios párrafos: el reset deja los <p> sin margen, así que la
   separación entre bajadas consecutivas se declara acá. */
.section-lead + .section-lead { margin-top: 0.9em; }
/* Peso declarado y no el <strong> del navegador: el UA pide "bolder" (700) y
   Poppins no se carga en ese peso, así que el remarcado quedaba a merced del
   fallback del font matching. 600 es el semibold de texto del sistema
   tipográfico, el mismo que usan el resto de los énfasis del cuerpo. */
.section-lead strong { font-weight: var(--fw-body-strong); }
.section-dark .section-lead { color: var(--text-body-dark); }

/* Los CTA de cierre de sección van centrados en todas las secciones: son el
   punto de salida del bloque, no una continuación de la columna de texto. */
.section-cta {
  margin-top: clamp(36px, 5vw, 52px);
  text-align: center;
}

/* ------------------------------------------------------------ Botones ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-body);
  font-weight: var(--fw-body-medium);
  font-size: 0.95rem;
  line-height: 1;
  text-align: center;
  padding: 15px 26px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition: background-color var(--t-base), color var(--t-base),
              box-shadow var(--t-base), border-color var(--t-base),
              transform var(--t-fast);
}
.btn:active { transform: scale(0.98); }
.btn-sm { padding: 11px 20px; font-size: 0.875rem; }
.btn-lg { padding: 17px 30px; font-size: 1rem; }

.btn-primary {
  background-color: var(--c-petroleo);
  color: var(--c-blanco);
  box-shadow: var(--shadow-cta);
}
.btn-primary:hover {
  background-color: var(--c-gris-azulado);
  box-shadow: var(--shadow-cta-hover);
}

/* Outline sobre fondo oscuro (hero) */
.btn-outline-light {
  border-color: rgba(255, 255, 255, 0.45);
  color: var(--c-blanco);
  background-color: rgba(255, 255, 255, 0.06);
}
.btn-outline-light:hover {
  border-color: var(--c-blanco);
  background-color: rgba(255, 255, 255, 0.14);
}

/* Sólido claro sobre secciones petróleo */
.btn-light {
  background-color: var(--c-blanco);
  color: var(--c-petroleo);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}
.btn-light:hover { background-color: var(--c-gris-casi-puro); }

.link-btn {
  font-weight: var(--fw-body-medium);
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: opacity var(--t-base);
}
.link-btn:hover { opacity: 0.75; }

/* ------------------------------------------------------------- Header ---- */
/* fixed y no sticky: sobre el hero el header va transparente y tiene que
   montarse encima del video, no empujarlo hacia abajo. La compensación de
   altura la hace el padding-top del propio hero. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background-color: rgba(255, 255, 255, 0.94);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--border-subtle);
  transition: background-color var(--t-base), border-color var(--t-base),
              backdrop-filter var(--t-base);
}

/* Estado sobre el hero: sin fondo, sin borde y todo el contenido en blanco. */
.site-header.is-transparent {
  background-color: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
}

.header-inner {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

/* El único lockup disponible es vertical (roseta sobre el wordmark), así que
   el alto del header lo define el logo. No se recompone ni se deforma: el
   manual lo prohíbe explícitamente. */
.header-logo { position: relative; display: block; }
.header-logo img {
  /* 42 y no 50: al lado del wordmark de Congenia el lockup de Helios se
     comía el header. Bajarlo achica la roseta y acerca el alto de la
     palabra "Helios" al de "CONGENIA", que es lo que se compara a simple
     vista. */
  height: 42px;
  width: auto;
  transition: opacity var(--t-base);
}
.header-logo .logo-light {
  position: absolute;
  inset: 0;
  opacity: 0;
}
.site-header.is-transparent .logo-light { opacity: 1; }
.site-header.is-transparent .logo-dark { opacity: 0; }

/* --- Co-branding Helios | Congenia ---------------------------------------
   Helios manda (es la marca de la landing) y Congenia firma al lado, más
   chica, como endoso. La separación es una línea de 1px del alto del
   wordmark de Helios, no del logo entero: así no compite con la roseta. */
.header-brands {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.brand-sep {
  flex: none;
  width: 1px;
  height: 25px;
  background-color: rgba(21, 52, 64, 0.20);
  transition: background-color var(--t-base);
}
.site-header.is-transparent .brand-sep {
  background-color: rgba(255, 255, 255, 0.40);
}

/* El wordmark de Congenia es una tira de 10:1: la altura la define el ancho
   que tolera el header, no el alto del logo de Helios. 13px de alto ya son
   ~133px de ancho. */
.header-congenia {
  position: relative;
  display: block;
  flex: none;
}
.header-congenia img {
  display: block;
  /* La tira es de 10,24:1, así que cada px de alto son ~10px de ancho: es el
     ancho, y no el alto, lo que hace que Congenia se vea desproporcionado al
     lado de Helios. 9px ≈ 92px de ancho, lo que entra cómodo a 320px junto
     al lockup de Helios y el botón de menú de 44px. */
  height: 9px;
  width: auto;
  transition: opacity var(--t-base);
}
.header-congenia .logo-light {
  position: absolute;
  inset: 0;
  opacity: 0;
}

@media (min-width: 400px) {
  .header-congenia img { height: 10px; }
}

@media (min-width: 560px) {
  .header-brands { gap: 16px; }
}

.header-nav { display: none; }
.header-nav a {
  font-size: 1.02rem;
  font-weight: var(--fw-body);
  color: var(--text-body-light);
  padding: 8px 0;
  border-bottom: 2px solid transparent;
  transition: color var(--t-base), border-color var(--t-base);
}
.header-nav a:hover {
  color: var(--c-petroleo);
  border-bottom-color: var(--c-gris-acero);
}

/* Sobre el hero petróleo, el CTA petróleo desaparece: pasa a outline claro,
   el mismo criterio que el botón secundario del hero. */
.site-header.is-transparent .header-nav a { color: var(--c-blanco); }
.site-header.is-transparent .header-nav a:hover {
  color: var(--c-blanco);
  border-bottom-color: rgba(255, 255, 255, 0.7);
}
.site-header.is-transparent .header-cta {
  background-color: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.45);
  color: var(--c-blanco);
  box-shadow: none;
}
.site-header.is-transparent .header-cta:hover {
  background-color: var(--c-blanco);
  color: var(--c-petroleo);
  border-color: var(--c-blanco);
}
.site-header.is-transparent .nav-toggle span { background-color: var(--c-blanco); }

/* Escala propia y no --fs de .btn-sm: el CTA del header tiene que pesar lo
   mismo que los links de al lado, que subieron a 1.02rem. */
.header-cta {
  display: none;
  font-size: 0.98rem;
  padding: 13px 24px;
}

.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* stretch explícito: Chrome fuerza align-items:center en <button>, y sin
     esto las barras (spans vacíos) quedan con width 0 e invisibles. */
  align-items: stretch;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 2px;
  background-color: var(--c-petroleo);
  transition: transform var(--t-base), opacity var(--t-base);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.header-nav-mobile {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 8px var(--gutter) 24px;
  border-top: 1px solid var(--border-subtle);
  background-color: var(--surface-base);
}
.header-nav-mobile.is-open { display: flex; }
.header-nav-mobile a {
  padding: 14px 0;
  font-size: 1.05rem;
  font-weight: var(--fw-body);
  color: var(--text-body-light);
  border-bottom: 1px solid var(--border-subtle);
}
.header-nav-mobile .btn { margin-top: 16px; border-bottom: none; color: var(--c-blanco); }

@media (min-width: 992px) {
  .nav-toggle, .header-nav-mobile { display: none !important; }
  .header-nav { display: flex; gap: 28px; }
  .header-cta { display: inline-flex; }
}

/* --------------------------------------------------------------- Hero ---- */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  /* svh y no vh: en mobile, vh mide la ventana con la barra de URL retraída,
     así que al cargar el hero queda más alto que la pantalla. El vh de arriba
     queda como fallback para navegadores sin svh. */
  min-height: 100vh;
  min-height: 100svh;
  /* El header es fixed y va transparente acá arriba: el padding superior
     suma su alto para que el título no quede debajo de la navegación. */
  padding-top: calc(var(--header-h) + clamp(56px, 9vw, 104px));
  padding-bottom: clamp(56px, 9vw, 104px);
  background-color: var(--c-petroleo);
  overflow: hidden;
}

.hero-media { position: absolute; inset: 0; z-index: 0; }
.hero-media-poster,
.hero-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Baja la saturación del material para que no compita con la paleta fría */
  filter: grayscale(38%) saturate(72%) brightness(0.92);
}
.hero-media video { z-index: 1; opacity: 0; transition: opacity 0.9s ease-out; }
.hero-media video.is-ready { opacity: 1; }

.hero-media-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(100deg,
      rgba(21, 52, 64, 0.96) 0%,
      rgba(21, 52, 64, 0.90) 34%,
      rgba(21, 52, 64, 0.62) 66%,
      rgba(21, 52, 64, 0.78) 100%);
}

.hero-inner { position: relative; z-index: 3; }
.hero-content { max-width: 680px; }

.hero-title {
  font-size: var(--fs-h1);
  font-weight: var(--fw-title-strong);
  color: var(--text-strong-dark);
  margin-bottom: 22px;
  text-wrap: balance;
}

.hero-lead {
  font-size: var(--fs-lead);
  color: var(--text-body-dark);
  max-width: 56ch;
  margin-bottom: 34px;
}

.hero-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
}

.hero-microcopy {
  font-size: var(--fs-small);
  color: var(--text-muted-dark);
}

/* ------------------------------------------------- Entrada del hero ---- */
/* Fade + translateY corto, escalonado por bloque (título → bajada → botones
   → microcopy). No es stagger letra por letra, que el manual descarta: son
   cuatro piezas entrando en orden de lectura.

   Va bajo .js igual que los reveals: si el JS no corre, el hero se ve
   completo desde el primer paint en vez de quedar en opacity 0. */
.js .hero-media { animation: hero-media-in 1.1s ease-out both; }

.js .hero-content > * {
  opacity: 0;
  transform: translateY(16px);
  animation: hero-in 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
.js .hero-title { animation-delay: 0.12s; }
.js .hero-lead { animation-delay: 0.24s; }
.js .hero-actions { animation-delay: 0.36s; }
.js .hero-microcopy { animation-delay: 0.46s; }

@keyframes hero-in {
  to { opacity: 1; transform: none; }
}
@keyframes hero-media-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .js .hero-media,
  .js .hero-content > * {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

/* Alineado a la izquierda a propósito: abajo a la derecha lo tapa la burbuja
   flotante de WhatsApp. */
.hero-disclaimer {
  position: absolute;
  left: var(--gutter);
  bottom: 12px;
  z-index: 3;
  font-size: 0.72rem;
  color: rgba(242, 242, 242, 0.62);
}

@media (min-width: 560px) {
  .hero-actions { flex-direction: row; flex-wrap: wrap; align-items: center; }
}
@media (min-width: 768px) {
  .hero-disclaimer { left: var(--gutter-lg); }
}

/* -------------------------------------------- 3 · Problema / objeción ---- */
/* Sección pineada con un mazo de tarjetas.

     .objections-pin    → alto largo: es el recorrido de scroll de la secuencia
       .objections-stage → sticky, ocupa la pantalla y queda quieto
         .objection-stack → la ranura donde las tarjetas se superponen

   El layout apilado se activa sólo con .is-pinned, que agrega initObjections()
   en main.js. Sin JS o con prefers-reduced-motion no se agrega y la sección
   queda en flujo normal: las tres tarjetas una debajo de la otra, legibles.

   clip y no hidden en la sección: hidden la haría contenedor de scroll y el
   sticky del stage dejaría de funcionar. */
.objections { overflow: clip; }

.objections-head { max-width: 720px; }

.objection-stack {
  margin-top: clamp(28px, 4vw, 48px);
  display: grid;
  gap: clamp(20px, 3vw, 32px);
}

/* --------------------------------------------------- Tarjeta (base) ---- */
.objection-card {
  position: relative;
  /* Recorta el numeral y el grafismo, que sangran por los bordes. */
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: clamp(260px, 38vh, 380px);
  padding: clamp(28px, 3.6vw, 52px);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--t-base);
}
.objection-card:hover { box-shadow: var(--shadow-card-hover); }

.objection-body {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 14px;
  width: 100%;
}

/* Numeral como marca de agua: enorme, calado y muy transparente, sangrando
   por la esquina inferior izquierda. Es textura, no dato — por eso queda
   detrás del texto y fuera del árbol de accesibilidad. */
.objection-num {
  position: absolute;
  left: -0.06em;
  bottom: -0.26em;
  z-index: 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-title-strong);
  font-size: clamp(6rem, 14vw, 12rem);
  line-height: 0.78;
  color: rgba(21, 52, 64, 0.07);
  pointer-events: none;
  user-select: none;
}
/* Con soporte de text-stroke queda sólo el contorno; si no, el relleno suave
   de arriba cumple la misma función. */
@supports (-webkit-text-stroke: 1px currentColor) {
  .objection-num {
    color: transparent;
    -webkit-text-stroke: 2px rgba(21, 52, 64, 0.14);
  }
}

.objection-quote {
  font-size: clamp(1.2rem, 1.1vw + 0.86rem, 1.75rem);
  font-weight: var(--fw-title);
  color: var(--c-petroleo);
  text-wrap: balance;
}

/* Una respuesta puede ser de varios párrafos: van juntos en este bloque para
   que .objection-body siga teniendo dos hijos (pregunta | respuesta) y no se
   desarme la grilla de dos columnas de >=900px. */
.objection-answers {
  display: grid;
  gap: 12px;
}

.objection-answer {
  position: relative;
  padding-left: 30px;
  color: var(--text-body-light);
  max-width: 54ch;
}
.objection-answer:not(:first-child)::before { content: none; }
.objection-answer::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 18px;
  height: 18px;
  background-color: var(--c-gris-acero);
  -webkit-mask: url("../icons/arrow-right-light.svg") no-repeat center / contain;
  mask: url("../icons/arrow-right-light.svg") no-repeat center / contain;
  transition: background-color var(--t-base), transform var(--t-base);
}
.objection-card:hover .objection-answer::before {
  background-color: var(--c-petroleo);
  transform: translateX(3px);
}

/* ------------------------------------------- Tarjeta (las tres caras) ---- */
/* 01 — clara y limpia. */
.objection-card-light {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
}

/* 02 — petróleo. Invierte todos los colores del contenido. */
.objection-card-dark {
  background: var(--surface-dark);
  border: 1px solid rgba(255, 255, 255, 0.10);
}
.objection-card-dark .objection-quote { color: var(--c-blanco); }
.objection-card-dark .objection-answer { color: var(--text-body-dark); }
.objection-card-dark .objection-answer::before { background-color: var(--c-gris-claro); }
.objection-card-dark:hover .objection-answer::before { background-color: var(--c-blanco); }
.objection-card-dark .objection-num { color: rgba(255, 255, 255, 0.06); }
@supports (-webkit-text-stroke: 1px currentColor) {
  .objection-card-dark .objection-num {
    color: transparent;
    -webkit-text-stroke-color: rgba(255, 255, 255, 0.18);
  }
}
/* La textura topográfica hereda currentColor: acá tiene que ser el claro. */
.objection-card-dark { color: var(--c-gris-claro); }

/* 03 — clara con el recorte del panel adentro. */
.objection-card-art {
  background:
    linear-gradient(112deg,
      var(--c-blanco) 0%,
      var(--c-blanco) 40%,
      var(--c-gris-casi-puro) 100%);
  border: 1px solid var(--border-subtle);
}
.objection-art {
  position: absolute;
  z-index: 0;
  right: -7%;
  bottom: -26%;
  width: min(420px, 58%);
  height: auto;
  opacity: 0.14;
  transform: rotate(-7deg);
  pointer-events: none;
  user-select: none;
}

@media (min-width: 900px) {
  /* La duda a la izquierda, lo que la responde a la derecha. El padding
     izquierdo le deja lugar al numeral para que no pise el texto. */
  .objection-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: center;
    gap: clamp(24px, 3vw, 48px);
    padding-left: clamp(80px, 9vw, 170px);
  }
  .objection-answer { padding-left: 34px; }
}

/* ----------------------------------------------- Secuencia pineada ---- */
/* Todo lo de acá abajo sólo aplica con JS: es el modo apilado. */
.objections.is-pinned .objections-pin {
  /* Una pantalla de arranque + ~0,85 por cada tarjeta que entra después. */
  height: calc(100vh + 2 * 85vh);
}

.objections.is-pinned .objections-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: flex;
  align-items: center;
  /* El header es fixed y va encima: este padding evita que le tape el título. */
  padding-top: var(--header-h);
  /* Recorta las tarjetas que todavía no entraron. */
  overflow: hidden;
}

.objections.is-pinned .objections-inner { width: 100%; }

/* Las tarjetas se superponen en la misma ranura: todas comparten una única
   celda de grilla. Antes iban en absolute sobre una ranura de alto fijo y la
   tarjeta con más texto se recortaba; así la ranura mide lo que mide la
   tarjeta más alta y el min-height iguala a las más cortas. */
.objections.is-pinned .objection-stack {
  position: relative;
  display: grid;
  grid-template-areas: "mazo";
}
.objections.is-pinned .objection-card {
  grid-area: mazo;
  min-height: clamp(260px, 38vh, 380px);
  will-change: transform;
}

/* ------------------------------------------------ 4 · Cómo funciona ---- */
/* El parque 3D arriba, a todo el ancho del contenedor, y los tres pasos
   debajo en tres columnas. La vista aérea necesita ancho: en la caja de media
   columna que tenía antes el parque no se leía como parque. */
.park-block {
  display: grid;
  gap: clamp(22px, 3vw, 34px);
  padding: clamp(14px, 2vw, 22px);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border-subtle-dark);
  border-radius: var(--radius-lg);
}

.park-visual { display: grid; gap: 16px; }

/* El fondo del contenedor es el mismo color que el fondo de la escena WebGL,
   así el canvas aparece sin salto de tono mientras carga. */
.park-viewport {
  position: relative;
  width: 100%;
  /* Cuadrado en mobile: en 4:3 el predio entero entraba tan chico que las
     filas no se distinguían. En desktop se abre a 16:9. */
  aspect-ratio: 1 / 1;
  max-height: 78vh;
  border-radius: var(--radius);
  overflow: hidden;
  background: #102a34;
  isolation: isolate;
}

/* Barrido suave mientras se descargan three.js y el .glb: sin esto el hueco
   se lee como un bloque roto. Desaparece con el primer frame renderizado. */
.park-viewport::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(255, 255, 255, 0) 20%,
    rgba(255, 255, 255, 0.06) 50%,
    rgba(255, 255, 255, 0) 80%);
  background-size: 250% 100%;
  animation: park-sweep 1.8s ease-in-out infinite;
}
.park-viewport.is-ready::before { content: none; }

@keyframes park-sweep {
  from { background-position: 150% 0; }
  to { background-position: -50% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .park-viewport::before { animation: none; }
}

.park-canvas {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.9s ease-out;
  touch-action: pan-y;
}
.park-viewport.is-ready .park-canvas { opacity: 1; }

/* Foto real del parque cuando no hay WebGL o falla el CDN de three.js: la
   sección no depende del 3D para explicarse. */
.park-fallback {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Etiqueta HTML proyectada sobre el canvas (la posición la calcula park.js).
   Va en HTML y no como sprite para que use la tipografía del sistema. */
.park-tag {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -100%);
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--c-blanco);
  color: var(--c-petroleo);
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: var(--fw-body-strong);
  line-height: 1;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease-out;
  box-shadow: 0 4px 14px rgba(21, 52, 64, 0.35);
}
.park-tag::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -5px;
  width: 8px;
  height: 8px;
  transform: translateX(-50%) rotate(45deg);
  background: inherit;
}

/* Controles de zoom sobre el canvas, abajo a la izquierda. Los inyecta
   park.js junto con el resto de los controles: sin WebGL no queda un botón
   muerto sobre la foto de reemplazo. Aparecen recién con el primer frame, para
   que no floten sobre el rectángulo vacío mientras carga la escena. A la
   izquierda y no a la derecha por la burbuja fija de WhatsApp, que en mobile
   se le monta encima al llegar el visor al pie de la pantalla. */
.park-zoom {
  position: absolute;
  left: clamp(10px, 1.5vw, 16px);
  bottom: clamp(10px, 1.5vw, 16px);
  z-index: 2;
  display: grid;
  gap: 6px;
  opacity: 0;
  transition: opacity 0.6s ease-out;
}
.park-viewport.is-ready .park-zoom { opacity: 1; }

.park-zoom button {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(242, 242, 242, 0.28);
  border-radius: var(--radius-sm);
  /* Vidrio sobre el petróleo del render: el botón se despega del fondo sin
     tapar el parque. */
  background: rgba(16, 42, 52, 0.6);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--c-blanco);
  font-family: var(--font-body);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.25s ease-out, border-color 0.25s ease-out;
}
.park-zoom button:hover {
  background: rgba(16, 42, 52, 0.88);
  border-color: rgba(242, 242, 242, 0.5);
}
.park-zoom button:focus-visible {
  outline: 2px solid var(--c-blanco);
  outline-offset: 2px;
}
/* En el tope de acercamiento o alejamiento el click no cambiaría nada y se
   leería como un botón roto. */
.park-zoom button[disabled] {
  opacity: 0.32;
  cursor: default;
}

/* --------------------------------------------------------- Los pasos --- */
.steps {
  display: grid;
  gap: 16px;
  list-style: none;
  counter-reset: none;
}

/* Tarjetas quietas a propósito: antes cada una reencuadraba la cámara del 3D
   al pasar el mouse y se marcaba como activa. El parque se movía solo mientras
   se leía el paso, así que el movimiento ahora lo maneja el usuario en el
   visor y estas tarjetas son solo texto. */
.step {
  position: relative;
  padding: clamp(18px, 2vw, 22px);
  border: 1px solid var(--border-subtle-dark);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.03);
}

.step-marker {
  position: relative;
  width: 46px;
  height: 46px;
  margin-bottom: 14px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-subtle-dark);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.05);
}
/* La roseta como marcador de paso, en versión simplificada y baja opacidad:
   el manual permite reusar el módulo, no el isotipo como textura. */
.step-marker img { position: absolute; opacity: 0.22; width: 30px; height: 30px; }
.step-num {
  position: relative;
  font-family: var(--font-heading);
  font-weight: var(--fw-title-strong);
  font-size: 1.25rem;
  color: var(--c-blanco);
}
/* Sale de --fs-h3 y va a su propia escala: con el h3 del sistema el título
   del paso quedaba casi del mismo cuerpo que el párrafo de abajo y los tres
   pasos se leían como un bloque de texto corrido. */
.step-title {
  font-size: clamp(1.15rem, 0.6vw + 1rem, 1.35rem);
  margin-bottom: 8px;
}
.step p { color: var(--text-body-dark); font-size: var(--fs-small); }

.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (min-width: 900px) {
  .park-viewport { aspect-ratio: 16 / 9; }
  .steps { grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 24px); }
}

/* --------------------------------- Fondo de sección con imagen (parallax) - */
/* La foto va detrás de un overlay claro: se lee la textura del parque sin
   tocar el contraste del texto ni de las tarjetas. El desplazamiento lo aplica
   main.js sobre .section-bg-img (transform), no background-attachment: fixed,
   que iOS ignora y además fuerza repintados caros. */
.has-bg-media { position: relative; isolation: isolate; }
.has-bg-media > .container { position: relative; z-index: 1; }

.section-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}

.section-bg-img {
  position: absolute;
  /* Más alta que la sección: el sobrante es el recorrido del parallax, así la
     imagen nunca deja ver el borde al desplazarse. */
  top: -14%;
  left: 0;
  width: 100%;
  height: 128%;
  object-fit: cover;
  /* Mismo tratamiento frío que el resto de las fotos de la landing. */
  filter: grayscale(42%) saturate(72%);
  will-change: transform;
}

/* Overlay en gris casi puro (el fondo propio de .section-alt) con una apertura
   hacia la derecha: ahí no hay texto y se ve mejor la foto. */
.section-bg-overlay {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg,
      rgba(242, 242, 242, 0.94) 0%,
      rgba(242, 242, 242, 0.88) 42%,
      rgba(242, 242, 242, 0.66) 100%);
}

/* ------------------------------------------------ 5 · Diferenciadores ---- */
/* La bajada de esta sección son cuatro párrafos y con el ancho de lectura
   estándar (760px de .section-head, 62ch de .section-lead) quedaba una
   columna angosta contra media sección vacía. Acá se estira hasta el ancho
   del bloque de tarjetas de abajo. */
#diferenciadores .section-head { max-width: none; }
#diferenciadores .section-lead { max-width: 92ch; }

.diff-grid { display: grid; gap: 20px; }
.diff-card {
  display: flex;
  flex-direction: column;
  padding: 30px 26px;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.diff-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); }
.diff-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: 20px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
}
.diff-title { font-size: var(--fs-h3); margin-bottom: 12px; }
.diff-kicker {
  /* auto: alinea el refuerzo al pie de la tarjeta, aunque los párrafos
     tengan largos distintos */
  margin-top: auto;
  padding-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border-subtle);
  font-weight: var(--fw-body-strong);
  color: var(--c-petroleo);
}

@media (min-width: 900px) {
  .diff-grid { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}

/* ------------------------------------------------------- 6 · Proceso ---- */
.proof-layout { display: grid; gap: 32px; }

.proof-list { display: grid; gap: 24px; }
.proof-item { padding-left: 18px; border-left: 2px solid var(--c-gris-acero); }
.proof-title { font-size: var(--fs-h3); margin-bottom: 8px; }

/* ------------------------------------------------------------ Carrusel --- */
/* Arrastrable y en loop infinito (clones de la primera y la última slide,
   ver initCarousel en main.js). Sin JS queda la primera imagen visible y el
   scroll horizontal nativo como salida: nunca un bloque vacío. */
.carousel { position: relative; }

.carousel-viewport {
  overflow: hidden;
  border-radius: var(--radius);
  /* Sin JS el track no se transforma; el viewport permite deslizarlo. */
  overflow-x: auto;
  scrollbar-width: none;
}
.carousel.is-live .carousel-viewport { overflow-x: hidden; }
.carousel-viewport::-webkit-scrollbar { display: none; }

.carousel-track {
  display: flex;
  /* La transición la maneja el JS para poder desactivarla en el salto de
     loop; acá solo se declara el estado base. */
  will-change: transform;
}
.carousel.is-dragging .carousel-track { cursor: grabbing; }
.carousel.is-live .carousel-track { cursor: grab; touch-action: pan-y; }

.carousel-slide { flex: 0 0 100%; min-width: 100%; }
.carousel-slide img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  /* Mismo tratamiento que el resto de las fotos de la landing. */
  filter: grayscale(30%) saturate(80%);
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: none;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  color: var(--c-petroleo);
  background: rgba(255, 255, 255, 0.88);
  box-shadow: var(--shadow-card);
  transition: background-color var(--t-base), transform var(--t-fast);
}
.carousel.is-live .carousel-btn { display: grid; }
.carousel-btn:hover { background: var(--c-blanco); }
.carousel-btn:active { transform: translateY(-50%) scale(0.94); }
.carousel-btn svg { width: 20px; height: 20px; }
.carousel-prev { left: 12px; }
.carousel-next { right: 12px; }

.carousel-dots {
  display: none;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
}
.carousel.is-live .carousel-dots { display: flex; }
.carousel-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
  background: var(--c-gris-claro);
  transition: background-color var(--t-base), transform var(--t-base);
}
.carousel-dot[aria-selected="true"] {
  background: var(--c-petroleo);
  transform: scale(1.25);
}

@media (min-width: 900px) {
  .proof-layout { grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; }
}

/* ----------------------------------------------------- 7 · Preguntas ---- */
/* El ícono va desaturado a propósito: el original es de paleta cálida y el
   manual prohíbe colores fuera de la familia de marca. Con esta corrección
   entra en la gama fría sin perder la forma. */
.faq-mark {
  width: 64px;
  height: auto;
  margin-bottom: 18px;
  filter: grayscale(55%) saturate(85%) hue-rotate(-8deg);
}

/* Dos columnas independientes (.faq-col) en vez de una grilla de dos columnas
   con las nueve tarjetas sueltas: en esa grilla el alto de cada fila lo fijaba
   la tarjeta más alta, así que una pregunta de dos líneas abría un hueco en la
   tarjeta de al lado. Apilando por columna, cada una arranca donde termina la
   anterior y no queda ningún espacio muerto. */
.faq { display: grid; gap: 12px; }
.faq-col { display: grid; gap: 12px; align-content: start; }

@media (min-width: 900px) {
  .faq {
    grid-template-columns: repeat(2, 1fr);
    align-items: start;
    gap: 14px 20px;
  }
  .faq-col { gap: 14px; }
}

.faq-item {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px;
  cursor: pointer;
  list-style: none;
  transition: background-color var(--t-base);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { background: var(--surface-alt); }

.faq-item summary h3 {
  font-family: var(--font-body);
  font-weight: var(--fw-body-strong);
  font-size: var(--fs-h3);
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--c-petroleo);
}

/* Chevron que rota 180°, sin rebote */
.faq-item summary::after {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--c-gris-acero);
  border-bottom: 2px solid var(--c-gris-acero);
  transform: rotate(45deg);
  transition: transform var(--t-base);
}
.faq-item[open] summary::after { transform: rotate(-135deg); }

.faq-body { padding: 0 22px 22px; max-width: 68ch; }

/* ------------------------------------------------------ 8 · Contacto ---- */
.form-shell {
  padding: clamp(24px, 4vw, 36px);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border-subtle-dark);
  border-radius: var(--radius-lg);
}

.lead-form { display: grid; gap: 20px; }

.field { display: flex; flex-direction: column; gap: 7px; }
.field-full { grid-column: 1 / -1; }

.field label {
  font-size: var(--fs-small);
  font-weight: var(--fw-body-medium);
  color: var(--c-blanco);
}
.req { color: var(--c-gris-claro); }

.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 1rem; /* 16px: evita el zoom automático de iOS al enfocar */
  font-weight: var(--fw-body-light);
  color: var(--c-petroleo);
  background: var(--c-blanco);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 13px 14px;
  width: 100%;
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.field textarea { resize: vertical; min-height: 110px; line-height: 1.55; }
.field select { appearance: none; cursor: pointer; }
.field select:invalid { color: var(--c-gris-acero); }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--c-gris-acero);
  box-shadow: 0 0 0 3px rgba(112, 132, 140, 0.35);
}

.field-hint {
  font-size: 0.8rem;
  color: var(--text-muted-dark);
}

.field-error {
  font-size: 0.8rem;
  font-weight: var(--fw-body-medium);
  /* Blanco sobre petróleo: 13:1. No se usa un rojo porque está fuera de la
     paleta del manual; el error se señala con borde + texto. */
  color: var(--c-blanco);
  min-height: 0;
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--c-blanco);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
}

.form-foot {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
}
.form-alt { font-size: var(--fs-small); color: var(--text-body-dark); }

.form-status {
  grid-column: 1 / -1;
  font-size: var(--fs-small);
  font-weight: var(--fw-body-medium);
  color: var(--c-blanco);
}
.form-status:empty { display: none; }

@media (min-width: 700px) {
  .lead-form { grid-template-columns: 1fr 1fr; gap: 20px 24px; }
  .form-foot { flex-direction: row; align-items: center; gap: 24px; }
}

/* -------------------------------------------------------- 9 · Footer ---- */
.site-footer {
  background: var(--c-gris-azulado);
  color: var(--text-body-dark);
  padding-top: clamp(48px, 6vw, 72px);
}

.footer-inner {
  display: grid;
  gap: 34px;
  padding-bottom: 40px;
}

/* El lockup con la firma "By: Congenia" necesita más alto que el logotipo
   solo: la firma es tipografía chica dentro del arte y por debajo de ~110px
   deja de leerse. */
.footer-brand img { height: 120px; width: auto; }

.footer-h {
  font-family: var(--font-body);
  font-weight: var(--fw-body-strong);
  font-size: var(--fs-small);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-blanco);
  margin-bottom: 14px;
}

.footer-list { display: grid; gap: 9px; font-size: var(--fs-small); }

/* Ícono + dato: el ícono no se encoge y el texto largo (el email) puede
   cortar sin meterse debajo del ícono. */
.footer-contact li {
  display: grid;
  grid-template-columns: 18px 1fr;
  align-items: start;
  gap: 10px;
}
.footer-ico {
  width: 18px;
  height: 18px;
  /* Alinea el ícono con la primera línea de texto, no con el tope de la caja. */
  margin-top: 0.15em;
  color: var(--c-gris-claro);
}
.footer-contact a { overflow-wrap: anywhere; }

.footer-list a { transition: color var(--t-base); }
.footer-list a:hover { color: var(--c-blanco); }

/* Marca visible de dato pendiente: se ve en pantalla y es grepeable. Hoy no
   queda ninguno en el HTML; la clase se conserva para el próximo. */
.pending {
  font-weight: var(--fw-body-strong);
  color: var(--c-blanco);
  border-bottom: 1px dashed rgba(255, 255, 255, 0.5);
}

/* Una sola línea centrada: firma de copyright + crédito de agencia. */
.footer-bottom {
  padding-block: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  text-align: center;
  font-size: 0.78rem;
  color: rgba(242, 242, 242, 0.72);
}
.footer-bottom a {
  color: var(--c-blanco);
  transition: opacity var(--t-base);
}
.footer-bottom a:hover { opacity: 0.75; }
.footer-sep {
  display: inline-block;
  margin-inline: 6px;
  color: rgba(242, 242, 242, 0.35);
}

/* En mobile la línea del pie queda centrada justo debajo de la burbuja
   flotante de WhatsApp: este aire evita que el crédito quede tapado. */
@media (max-width: 759px) {
  .footer-bottom { padding-bottom: 88px; }
}

@media (min-width: 760px) {
  .footer-inner { grid-template-columns: 1.3fr 1.2fr 1fr; gap: 40px; }
}

/* ------------------------------------------------- Reveal al scrollear --- */
/* Solo se oculta si hay JS (la clase .js la pone un script en el <head>).
   Sin JS, todo el contenido queda visible: nunca un hero en blanco. */
.js .reveal {
  opacity: 0;
  transform: translateY(var(--reveal-y));
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
}
