/* ── Tokens: paleta CLARA oficial de THE LAB RE (branding-lab-re.html) ──
   Mismos valores exactos que se usaron en el video de venta, para que la
   landing y el video se lean como la misma pieza. */
:root {
  --bg: #eef1ee;
  --card: #ffffff;
  --ink: #16211f;
  --sub: #48575c;
  --signal-dark: #16665b;
  --line: rgba(20, 48, 56, 0.18);
  --line-strong: rgba(20, 48, 56, 0.32);
  --signal: #1f8f80;
  --signal-ink: #ffffff;
  /* El verde señal oscurecido lo MÍNIMO para que el texto blanco encima
     llegue a 4.5:1 (AA). #1f8f80 con blanco da 3.96:1 y no pasa; #178070 da
     4.82:1 y a simple vista es el mismo verde. Se usa SOLO como fondo bajo
     texto blanco: barras, avatares y puntos decorativos siguen con
     --signal, porque ahí no hay texto que leer. */
  --signal-fondo: #178070;
  --redline: #b8551f;
  --blueprint: #143038;
  /* La mono es el ACENTO TÉCNICO del Brand Kit, no una segunda voz de texto.
     Úsala solo en: el wordmark, números, y rótulos cortos en mayúsculas.
     Prosa, controles y etiquetas de formulario van SIEMPRE en la sans.
     Repartida por todos lados, la página parece tener muchas tipografías
     teniendo solo dos -- que es justo lo que pasaba antes del 31/08. */

  --font-sans: "IBM Plex Sans", -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  --header-h: 76px;
}
/* Los controles de formulario NO heredan la familia tipográfica del body:
   es un comportamiento por defecto del navegador, no un olvido del CSS. Sin
   esta regla, cualquier <button> sin familia propia cae en Arial y rompe la
   uniformidad. Lo encontró la medición del 31/08: un solo botón (el de cerrar
   la ficha flotante) salía en Arial. */
button, input, select, textarea { font-family: inherit; }


@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 400;
  src: url("assets/fonts/IBMPlexSans-400.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 500;
  src: url("assets/fonts/IBMPlexSans-500.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 600;
  src: url("assets/fonts/IBMPlexSans-600.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 700;
  src: url("assets/fonts/IBMPlexSans-700.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-weight: 400;
  src: url("assets/fonts/IBMPlexMono-400.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-weight: 500;
  src: url("assets/fonts/IBMPlexMono-500.woff2") format("woff2");
  font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }
/* ── OJO: aquí NO va `overflow-x: hidden`. ──────────────────────────────
   Lo tenían html y body. Hacía dos daños a la vez:
   1. `overflow-x: hidden` convierte al documento en contenedor de scroll, y
      eso ANULA `position: sticky` en todos sus descendientes. El teléfono
      del bloque de Argo no se anclaba y nada en el CSS de ese bloque lo
      explicaba -- se veía como un sticky "que no funciona".
   2. Escondía cualquier desborde real en vez de dejarlo salir a la vista.
   Comprobado el 02/09 a 390, 768 y 1440px con el `hidden` retirado:
   scrollWidth == clientWidth en los tres, cero elementos desbordados. O sea
   que no estaba tapando nada; estaba rompiendo algo. Si algún día aparece
   un desborde de verdad, se arregla el elemento culpable, no se tapa aquí.
   (Misma decisión que ya se tomó en argo-landing.) ── */
html { color-scheme: light; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }

.wrap {
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 24px;
}

/* ── Logo: los 3 módulos reales del Brand Kit, nunca recreados de memoria ── */
.marca { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.marca svg { width: 30px; height: 30px; flex: none; }
.marca-tipo { font-weight: 600; font-size: 15px; letter-spacing: 0.02em; color: var(--ink); line-height: 1.1; }
.marca-tipo small {
  display: block; font-family: var(--font-mono); font-weight: 400;
  font-size: 10px; letter-spacing: 0.09em; color: var(--sub); margin-top: 3px;
}

/* ── Botón WhatsApp: única acción de conversión de toda la página ── */
.btn-wa {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--signal-fondo); color: var(--signal-ink);
  font-family: var(--font-sans); font-weight: 600; font-size: 15px;
  padding: 13px 22px; border-radius: 999px; text-decoration: none;
  border: 1px solid var(--signal); white-space: nowrap;
  transition: background-color 0.15s ease, transform 0.1s ease;
}
.btn-wa:hover { background: #197a6d; }
.btn-wa:active { transform: translateY(1px); }
.btn-wa svg { width: 18px; height: 18px; flex: none; }
.btn-wa:focus-visible { outline: 2px solid var(--blueprint); outline-offset: 3px; }

/* ── Header fijo ── */
.site-header {
  /* position:fixed, NO sticky+margen-negativo. La combinación anterior
     (sticky + margin-top negativo en .hero para que el header "flotara"
     encima) producía un bug de renderizado real -- confirmado con Chrome
     headless en perfil limpio, dos veces, no era un artefacto de la
     captura. fixed saca al header del flujo normal del todo, así que el
     hero puede empezar justo en el borde superior sin ningún truco. */
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  height: var(--header-h);
  display: flex; align-items: center;
  background: rgba(20, 48, 56, 0.55);
  backdrop-filter: blur(10px) saturate(1.1);
  border-bottom: 1px solid rgba(233, 241, 239, 0.14);
  transition: background-color 0.2s ease;
}
.site-header .marca-tipo { color: #f4f8f7; }
.site-header .marca-tipo small { color: #9fc3bd; }
.site-header .marca svg rect[stroke] { stroke: #f4f8f7; }
/* Fuera del hero (scrolleado a otra sección clara) el header pasa a versión
   clara -- lo activa script.js con la misma IntersectionObserver del hero. */
.site-header.on-light {
  background: rgba(238, 241, 238, 0.88);
  border-bottom-color: var(--line);
}
.site-header.on-light .marca-tipo { color: var(--ink); }
.site-header.on-light .marca-tipo small { color: var(--sub); }
.site-header.on-light .marca svg rect[stroke] { stroke: var(--ink); }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.header-derecha { display: flex; align-items: center; gap: 18px; }

/* ── Selector de idioma: mismo patrón que la referencia (bandera/botón
   arriba a la derecha), pero en el lenguaje del Brand Kit -- mono, sin
   bandera de país (el mercado es bilingüe, no "de otro país"). ── */
.lang-switch {
  display: flex; align-items: center; border: 1px solid rgba(233, 241, 239, 0.28);
  border-radius: 20px; padding: 3px; gap: 2px;
}
.site-header.on-light .lang-switch { border-color: var(--line-strong); }
.lang-btn {
  font-family: var(--font-sans); font-size: 12px; letter-spacing: 0.06em;
  padding: 5px 11px; border-radius: 16px; border: none; background: transparent;
  color: #cfe3df; cursor: pointer; transition: background-color 0.15s ease, color 0.15s ease;
}
.site-header.on-light .lang-btn { color: var(--sub); }
.lang-btn[aria-pressed="true"] { background: var(--signal-fondo); color: #ffffff; }
.lang-btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.btn-wa--header { padding: 10px 18px; font-size: 14px; }
.btn-wa--header .btn-wa-full { display: inline; }
@media (max-width: 560px) {
  .btn-wa--header .btn-wa-full { display: none; }
}

/* ── Footer -- en TODAS las páginas y landings (pedido de Marcos, 29/08). ── */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.site-footer {
  background: var(--blueprint); color: #cfe3df; padding-block: 64px 28px;
}
.footer-grid {
  display: grid; grid-template-columns: 1.3fr 0.8fr 1fr; gap: 56px;
}
.footer-col-tit {
  font-family: var(--font-sans); font-size: 12px; letter-spacing: 0.12em;
  text-transform: uppercase; color: #5fd8c8; margin: 0 0 18px;
}
.footer-marca .marca-tipo { color: #f4f8f7; }
.footer-marca .marca-tipo small { color: #8fb3ae; }
.footer-blurb { font-size: 14.5px; color: #a9c4bf; max-width: 34ch; margin: 18px 0 20px; }
.footer-contacto {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
  font-size: 14px; color: #dcece8; text-decoration: none;
}
.footer-contacto svg { width: 16px; height: 16px; flex: none; color: #5fd8c8; }
.footer-contacto:hover { color: #5fd8c8; }

.footer-links { display: flex; flex-direction: column; }
.footer-links a {
  display: block; color: #a9c4bf; text-decoration: none; font-size: 14.5px;
  padding: 6px 0; transition: color 0.15s ease;
  position: relative; width: fit-content;
}
.footer-links a::after {
  content: ''; position: absolute; left: 0; bottom: 3px; height: 1px; width: 0;
  background: #5fd8c8; transition: width 0.25s ease;
}
.footer-links a:hover { color: #5fd8c8; }
.footer-links a:hover::after { width: 100%; }

.footer-news-sub { font-size: 13.5px; color: #a9c4bf; margin: 0 0 16px; }
.footer-news-form { display: flex; gap: 0; border: 1px solid rgba(233,241,239,0.22); border-radius: 3px; overflow: hidden; }
.footer-news-form input {
  flex: 1; min-width: 0; background: rgba(233,241,239,0.06); border: none;
  padding: 12px 14px; color: #f4f8f7; font-family: var(--font-sans); font-size: 14px;
}
.footer-news-form input::placeholder { color: #7c9995; }
.footer-news-form input:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; }
.footer-news-form button {
  flex: none; background: var(--signal-fondo); color: #fff; border: none;
  padding: 0 18px; font-family: var(--font-sans); font-weight: 600; font-size: 13.5px;
  cursor: pointer; transition: background-color 0.15s ease;
}
.footer-news-form button:hover { background: #197a6d; }

.footer-legal {
  margin-top: 48px; padding-top: 22px; border-top: 1px solid rgba(233,241,239,0.14);
  font-family: var(--font-sans); font-size: 12px; color: #7c9995;
}

@media (max-width: 860px) {
  .footer-grid { grid-template-columns: 1fr; gap: 40px; }
}

/* ── Ficha flotante -- mismo patrón que la referencia, en el lenguaje del
   sistema (tarjeta de 1px, sin sombra decorativa de más). ── */
.ficha-flotante {
  position: fixed; right: 20px; bottom: 20px; z-index: 50;
  width: 280px; background: var(--card); border: 1px solid var(--line-strong);
  border-radius: 4px; padding: 18px 20px 20px;
  box-shadow: 0 18px 40px -14px rgba(20,48,56,0.28);
}
.ficha-cerrar {
  position: absolute; top: 10px; right: 10px; width: 24px; height: 24px;
  border: none; background: none; color: var(--sub); font-size: 14px;
  cursor: pointer; line-height: 1;
}
.ficha-cerrar:hover { color: var(--ink); }
.ficha-tit { font-weight: 600; font-size: 14.5px; color: var(--ink); margin: 0 0 4px; }
.ficha-sub { font-size: 13px; color: var(--sub); margin: 0 0 14px; }
.ficha-tel {
  display: flex; align-items: center; gap: 8px; text-decoration: none;
  color: var(--signal); font-weight: 600; font-size: 15px;
}
.ficha-tel svg { width: 18px; height: 18px; }
.ficha-flotante.oculta { display: none; }
@media (max-width: 480px) {
  .ficha-flotante { left: 16px; right: 16px; width: auto; bottom: 16px; }
}

/* ── Hero -- sin foto de equipo (no existen todavía). El lenguaje de
   dibujo técnico hace el trabajo que haría una fotografía: el logo de 3
   módulos como pieza central, ampliado, sobre el fondo Blueprint. ── */
/* ── Fondos fotográficos (02/09) ───────────────────────────────────────
   Elegidos por Marcos sobre la alternativa de dibujo técnico: skyline de
   Atlanta en el hero (foto tomada DESDE MABLETON — metro Atlanta, el
   mercado real) y calle suburbana lavada en "A laboratory". Son las dos
   estrategias de los competidores: Taylor pone foto a sangre en el hero,
   Organization Plus lava una foto hasta convertirla en textura.

   ⚠️ LOS NOMBRES LLEVAN VERSIÓN (`-v1-`) A PROPÓSITO. `server.js` manda
   `max-age=31536000, immutable` a .jpg y .webp, así que un navegador que ya
   bajó la foto NO la vuelve a pedir nunca. Para cambiar la imagen hay que
   SUBIR EL NÚMERO, jamás sobrescribir el archivo: quien ya la tenga en
   caché seguiría viendo la vieja durante un año.

   El velo de 0.90→0.94 sobre --blueprint no es decoración: sin él, el
   titular blanco y el teal pierden contraste contra la foto. Es justo el
   fallo que tiene taylortransactions.com, donde su coral sobre la foto
   apenas se lee. ── */
.hero {
  padding-block: calc(var(--header-h) + 80px) 90px;
  --hero-foto: url("assets/img/hero-skyline-v1-1920.jpg");
  background:
    radial-gradient(1100px 620px at 18% -10%, rgba(95, 216, 200, 0.14), transparent 62%),
    radial-gradient(900px 700px at 88% 100%, rgba(31, 143, 128, 0.10), transparent 58%),
    linear-gradient(rgba(20, 48, 56, 0.68), rgba(20, 48, 56, 0.78)),
    var(--hero-foto) center / cover no-repeat,
    var(--blueprint);
  color: #e9f1ef; text-align: center;
}
/* En teléfono no tiene sentido bajar 1920px de ancho: la mitad del archivo
   se descarta al recortar. */
/* En pantalla estrecha la foto apaisada se recorta tanto que el skyline se
   sale del encuadre y el hero vuelve a verse liso -- medido a 390px. Se
   sirve un recorte propio, casi cuadrado y centrado en las torres, y se
   afloja un punto el velo porque a 390px hay menos texto compitiendo. */
@media (max-width: 900px) {
  .hero {
    --hero-foto: url("assets/img/hero-skyline-v1-alto.jpg");
    background:
      radial-gradient(1100px 620px at 18% -10%, rgba(95, 216, 200, 0.14), transparent 62%),
      radial-gradient(900px 700px at 88% 100%, rgba(31, 143, 128, 0.10), transparent 58%),
      linear-gradient(rgba(20, 48, 56, 0.72), rgba(20, 48, 56, 0.82)),
      var(--hero-foto) center / cover no-repeat,
      var(--blueprint);
  }
}
/* WebP donde se pueda (~35% menos peso), JPEG donde no. El @supports va
   DESPUÉS a propósito: un navegador que no entienda image-set() se queda
   con el JPEG de arriba en vez de quedarse sin fondo. */
@supports (background-image: image-set(url("a.webp") type("image/webp"))) {
  .hero {
    --hero-foto: image-set(
      url("assets/img/hero-skyline-v1-1920.webp") type("image/webp"),
      url("assets/img/hero-skyline-v1-1920.jpg") type("image/jpeg"));
  }
  @media (max-width: 900px) {
    .hero {
      --hero-foto: image-set(
        url("assets/img/hero-skyline-v1-alto.webp") type("image/webp"),
        url("assets/img/hero-skyline-v1-alto.jpg") type("image/jpeg"));
    }
  }
}
.hero-plano { display: flex; justify-content: center; margin-bottom: 8px; }
.plano-svg { width: min(92vw, 440px); height: auto; overflow: visible; }

/* ── Pase de cuatro escenas ──
   Todas centradas en x=200, el mismo eje del logo que queda fijo abajo: eso
   es lo que mantiene la composición simétrica escena a escena.

   El trazo usa pathLength="1" en el HTML, que normaliza CUALQUIER forma
   (línea, rect, círculo, path) a un largo virtual de 1 -- así
   stroke-dasharray:1 + stroke-dashoffset:1→0 la dibuja sin calcular el largo
   real de cada trazo a mano. Se ve trazada con regla, no fundida. */
.tz {
  fill: none; stroke: #e9f1ef; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: traza 0.55s ease forwards;
}
.tz-signal { stroke: #5fd8c8; stroke-width: 1.4; }
/* Los iconos de servicio vienen de un lienzo de 24x24 y se escalan x4.6 para
   entrar en el hero, así que el trazo se escala con ellos. Se compensa aquí
   (1.6 / 4.6) en vez de con vector-effect="non-scaling-stroke": ese atributo
   hace que stroke-dasharray se mida en píxeles de pantalla y rompe el trazado
   con pathLength -- las figuras salían a medio dibujar. */
.esc-icono .tz { stroke-width: 0.35; }
.esc-icono .tz-signal { stroke-width: 0.31; }
.tz-cota { stroke: #7fd9c8; stroke-width: 1.1; }
.tz-logo { stroke: #e9f1ef; }
.logo-lleno { fill: #5fd8c8; stroke: none; opacity: 0; animation: aparece 0.3s ease forwards; animation-delay: 0.5s; }
.cap {
  fill: #7fa8a2; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em;
  opacity: 0; animation: aparece 0.3s ease forwards;
}
.cap-cota { fill: #9fc3bd; letter-spacing: 0.03em; font-size: 12px; }
@keyframes traza { to { stroke-dashoffset: 0; } }
@keyframes aparece { to { opacity: 1; } }

/* Cada escena entra, se sostiene y sale; la 4 (la casa) no sale nunca --
   es donde termina el trabajo. Ventanas de 1.45 s: "pase rápido". */
.esc { opacity: 1; }
/* ── El pase, en bucle infinito ──────────────────────────────────────
   Las siete escenas rotan sin parar: los seis servicios (1s cada uno) y la
   casa, que se sostiene 2s porque es el desenlace y merece más aire.
   Ciclo completo: 8s.

   Todas comparten la MISMA duración de 8s y se separan por animation-delay.
   Eso es lo que las mantiene sincronizadas ciclo tras ciclo: si cada una
   tuviera su propia duración, se irían desfasando con el tiempo.

   El trazo también se rehace en cada vuelta -- por eso `traza-ciclo` en vez
   del `traza` de una sola pasada: cada escena se vuelve a dibujar con regla,
   que es la gracia del pase. */
.esc-1, .esc-2, .esc-3, .esc-4, .esc-5, .esc-6 {
  opacity: 0; animation: esc-ciclo 8s linear infinite;
}
@keyframes esc-ciclo {
  0%, 11%     { opacity: 1; }
  12.5%, 100% { opacity: 0; }
}
.esc-7 { opacity: 0; animation: esc-ciclo-casa 8s linear infinite; animation-delay: 6s; }
@keyframes esc-ciclo-casa {
  0%, 23%   { opacity: 1; }
  25%, 100% { opacity: 0; }
}

.esc-1 { animation-delay: 0s; }
.esc-2 { animation-delay: 1s; }
.esc-3 { animation-delay: 2s; }
.esc-4 { animation-delay: 3s; }
.esc-5 { animation-delay: 4s; }
.esc-6 { animation-delay: 5s; }

/* El trazo se dibuja en el primer 6% del ciclo (~0.5s) y se queda dibujado
   hasta que la escena se apaga. */
.esc .tz { animation: traza-ciclo 8s linear infinite; }
@keyframes traza-ciclo {
  0%        { stroke-dashoffset: 1; }
  6%, 100%  { stroke-dashoffset: 0; }
}
.esc-1 .tz { animation-delay: 0s; }
.esc-2 .tz { animation-delay: 1s; }
.esc-3 .tz { animation-delay: 2s; }
.esc-4 .tz { animation-delay: 3s; }
.esc-5 .tz { animation-delay: 4s; }
.esc-6 .tz { animation-delay: 5s; }
.esc-7 .tz { animation-delay: 6s; }
/* Las cotas de la casa entran DESPUÉS de que está dibujada: primero se
   construye, después se acota. Es el orden de un plano real. */
.esc-7 .tz-tarde { animation: traza-ciclo 8s linear infinite; animation-delay: 6.5s; }

.esc .cap { animation: cap-ciclo 8s linear infinite; }
@keyframes cap-ciclo {
  0%, 4%    { opacity: 0; }
  8%, 100%  { opacity: 1; }
}
.esc-1 .cap { animation-delay: 0s; }
.esc-2 .cap { animation-delay: 1s; }
.esc-3 .cap { animation-delay: 2s; }
.esc-4 .cap { animation-delay: 3s; }
.esc-5 .cap { animation-delay: 4s; }
.esc-6 .cap { animation-delay: 5s; }
.esc-7 .cap { animation-delay: 6.2s; }

/* Con movimiento reducido no hay pase: se muestra directo el resultado (la
   casa) y el logo, sin animar nada. */
@media (prefers-reduced-motion: reduce) {
  .tz { animation: none; stroke-dashoffset: 0; }
  .cap, .logo-lleno { animation: none; opacity: 1; }
  .esc-1, .esc-2, .esc-3, .esc-4, .esc-5, .esc-6 { animation: none; opacity: 0; }
  .esc-7 { animation: none; opacity: 1; }
}

.hero-h1 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(32px, 5vw, 58px);
  line-height: 1.12; letter-spacing: -0.01em; margin: 0 auto 22px; max-width: 18ch;
  color: #f4f8f7;
}
.hero-h1 em { font-style: normal; color: #5fd8c8; font-weight: 500; }
.hero-sub {
  font-size: 18px; color: #b7cbc7; max-width: 52ch; margin: 0 auto 36px;
}
.hero-servicios {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 8px;
  margin: 0 0 38px; font-family: var(--font-sans); font-size: 12.5px;
  letter-spacing: 0.04em; color: #cfe3df;
}
.hero-servicios span {
  border: 1px solid rgba(233,241,239,0.22); border-radius: 20px; padding: 7px 14px;
}
.hero-ctas { display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }

/* Entrada del hero al cargar. */
@keyframes hero-entra { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
.hero-marca    { animation: hero-entra 0.7s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0s; }
.hero-h1       { animation: hero-entra 0.7s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.1s; }
.hero-sub      { animation: hero-entra 0.7s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.2s; }
.hero-servicios{ animation: hero-entra 0.7s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.3s; }
.hero-ctas     { animation: hero-entra 0.7s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.4s; }
@media (prefers-reduced-motion: reduce) {
  .hero-marca, .hero-h1, .hero-sub, .hero-servicios, .hero-ctas { animation: none; }
}

/* ── Quiénes somos ── */
.quienes {
  padding-block: 96px 100px; background: var(--bg);
  position: relative; overflow: hidden;
  --lab-foto: url("assets/img/calle-v1-1920.jpg");
}
/* La foto entra desvanecida DESDE LA DERECHA y muere antes de llegar al
   texto: la columna izquierda quedaba en blanco bajo el titular y es la que
   se llena, sin tocar la legibilidad de la derecha. */
.quienes::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--lab-foto) center / cover no-repeat;
  opacity: 0.22; filter: grayscale(0.42);
  -webkit-mask-image: linear-gradient(to left, #000 20%, transparent 78%);
          mask-image: linear-gradient(to left, #000 20%, transparent 78%);
}
.quienes > * { position: relative; z-index: 1; }
@media (max-width: 900px) {
  .quienes { --lab-foto: url("assets/img/calle-v1-960.jpg"); }
  /* A una columna el texto ocupa todo el ancho: si la foto siguiera
     entrando por la derecha quedaría DEBAJO del párrafo. Se desvanece
     desde abajo y baja de intensidad. */
  .quienes::after {
    opacity: 0.14;
    -webkit-mask-image: linear-gradient(to top, #000 26%, transparent 82%);
            mask-image: linear-gradient(to top, #000 26%, transparent 82%);
  }
}
@supports (background-image: image-set(url("a.webp") type("image/webp"))) {
  .quienes {
    --lab-foto: image-set(
      url("assets/img/calle-v1-1920.webp") type("image/webp"),
      url("assets/img/calle-v1-1920.jpg") type("image/jpeg"));
  }
  @media (max-width: 900px) {
    .quienes {
      --lab-foto: image-set(
        url("assets/img/calle-v1-960.webp") type("image/webp"),
        url("assets/img/calle-v1-960.jpg") type("image/jpeg"));
    }
  }
}
.quienes-grid {
  display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 72px; align-items: start;
}
.quienes-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(28px, 3.4vw, 42px);
  color: var(--ink); margin: 0 0 6px; line-height: 1.1;
}
/* El contenedor en sí no se anima -- solo dispara el observer y da el
   nth-child delay a sus hijos. Sin esto, se sumaban dos fundidos (el del
   contenedor + el de cada párrafo) y se sentía doble y lento. */
.quienes-cuerpo[data-reveal] { opacity: 1; transform: none; transition: none; }

.quienes-cuerpo p, .quienes-cuerpo .chips-disciplina {
  font-size: 17px; color: var(--sub); line-height: 1.65; margin: 0 0 20px;
  opacity: 0; transform: translateY(20px);
  transition: opacity 0.6s cubic-bezier(0.16,1,0.3,1), transform 0.6s cubic-bezier(0.16,1,0.3,1);
}
.quienes-cuerpo.is-visible p, .quienes-cuerpo.is-visible .chips-disciplina {
  opacity: 1; transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .quienes-cuerpo p, .quienes-cuerpo .chips-disciplina { transition: none; opacity: 1; transform: none; }
}
.quienes-cuerpo strong { color: var(--ink); font-weight: 600; }
.chips-disciplina {
  display: flex; gap: 0; align-items: center; margin-top: 28px;
  font-family: var(--font-sans); font-size: 13px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--signal);
}
.chips-disciplina span:not(.chip-sep) {
  border: 1px solid var(--line-strong); padding: 9px 16px;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.chips-disciplina span:not(.chip-sep):hover {
  border-color: var(--signal);
}
.chip-sep { color: var(--line-strong); padding: 0 2px; }

@media (max-width: 860px) {
  .quienes-grid { grid-template-columns: 1fr; gap: 32px; }
  .chips-disciplina { flex-wrap: wrap; gap: 8px; }
  .chip-sep { display: none; }
}

/* ── Servicios -- pestañas + subselección (el protocolo de cada
   servicio). Barra de progreso en 1px, no la barra gruesa de la referencia
   -- mismo lenguaje de línea fina que el resto del sistema. ── */
.servicios { padding-block: 20px 100px; background: var(--bg); }
.servicios-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: var(--ink); margin: 0 0 46px; max-width: 34ch;
}

.serv-tabs {
  display: flex; flex-wrap: wrap; gap: 4px 28px; margin-bottom: 10px;
}
.serv-tab {
  font-family: var(--font-sans); font-size: 13px; letter-spacing: 0.03em;
  background: none; border: none; padding: 10px 0; color: var(--sub);
  cursor: pointer; white-space: nowrap; transition: color 0.15s ease, transform 0.15s ease;
}
.serv-tab:hover { color: var(--ink); transform: translateY(-1px); }
.serv-panel { transition: opacity 0.2s ease; }
.serv-panel.cambiando { opacity: 0; }
.serv-tab.is-activo { color: var(--ink); font-weight: 600; }
.serv-tab:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.serv-progreso { height: 1px; background: var(--line-strong); margin-bottom: 44px; position: relative; }
.serv-progreso-fill {
  position: absolute; top: -1px; left: 0; height: 3px; width: 16.666%;
  background: var(--signal); transition: left 0.25s ease, width 0.25s ease;
}

.serv-panel {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  border: 1px solid var(--line-strong);
}
/* ── Foto por servicio (02/09) ─────────────────────────────────────────
   El bloque oscuro del panel lleva detrás una foto distinta para cada
   servicio, y cambia al pulsar la pestaña. La elige el CSS por
   `[data-serv]` -- el JS solo escribe el atributo, no toca estilos.

   Se eligió este bloque y no una tarjeta nueva por una razón de contenido:
   la referencia que trajo Marcos (taylortransactions.com) enseña 3
   servicios con solo el nombre; aquí hay 6 servicios con 3 pasos cada uno.
   Copiar sus tarjetas obligaba a tirar ese contenido. Aquí la foto entra
   donde el fondo YA era oscuro, y los tres pasos se quedan en blanco.

   Nombres con `-v1-` por lo mismo que las otras: `immutable` un año. */
.serv-desc {
  position: relative; overflow: hidden;
  background: var(--blueprint); color: #e9f1ef; padding: 40px 44px;
}
/* DOS capas y no una: la foto va en ::before para poder filtrarla, y el velo
   en ::after. En una sola capa el `filter` habría afectado también al
   degradado del velo. Sin desaturar, las seis no se leían como un conjunto:
   Listing salía verde brillante, Social Media azul intenso y Technology en
   arcoíris — seis mundos de color distintos dentro de la misma sección. */
.serv-desc::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--serv-foto, none) center / cover no-repeat;
  filter: grayscale(0.62) contrast(1.04);
  animation: serv-foto-entra 0.45s ease both;
}
.serv-desc::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(rgba(20, 48, 56, var(--serv-velo-a, 0.78)),
                              rgba(20, 48, 56, var(--serv-velo-b, 0.86)));
}
/* Fundido corto al cambiar de pestaña: sin él la foto salta de golpe y se
   lee como un fallo de carga. */
@keyframes serv-foto-entra { from { opacity: 0; } to { opacity: 1; } }
.serv-desc > * { position: relative; z-index: 2; }

.serv-desc[data-serv="tc"]      { --serv-foto: url("assets/img/serv-tc-v1.jpg"); }
.serv-desc[data-serv="ofertas"] { --serv-foto: url("assets/img/serv-ofertas-v1.jpg"); }
.serv-desc[data-serv="listing"] { --serv-foto: url("assets/img/serv-listing-v1.jpg"); }
.serv-desc[data-serv="va"]      { --serv-foto: url("assets/img/serv-va-v1.jpg"); }
.serv-desc[data-serv="rrss"]    { --serv-foto: url("assets/img/serv-rrss-v1.jpg"); }
.serv-desc[data-serv="leadgen"] { --serv-foto: url("assets/img/serv-leadgen-v1.jpg"); }
/* El código a color es la foto más clara y más ruidosa de las seis: con el
   velo por defecto el párrafo se quedaba en 4.51, justo en el mínimo y sin
   margen. Solo esta lleva el velo un punto más alto. */
.serv-desc[data-serv="tech"]    { --serv-foto: url("assets/img/serv-tech-v1.jpg");
                                  --serv-velo-a: 0.84; --serv-velo-b: 0.90; }

@supports (background-image: image-set(url("a.webp") type("image/webp"))) {
  .serv-desc[data-serv="tc"]      { --serv-foto: image-set(url("assets/img/serv-tc-v1.webp") type("image/webp"), url("assets/img/serv-tc-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="ofertas"] { --serv-foto: image-set(url("assets/img/serv-ofertas-v1.webp") type("image/webp"), url("assets/img/serv-ofertas-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="listing"] { --serv-foto: image-set(url("assets/img/serv-listing-v1.webp") type("image/webp"), url("assets/img/serv-listing-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="va"]      { --serv-foto: image-set(url("assets/img/serv-va-v1.webp") type("image/webp"), url("assets/img/serv-va-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="rrss"]    { --serv-foto: image-set(url("assets/img/serv-rrss-v1.webp") type("image/webp"), url("assets/img/serv-rrss-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="leadgen"] { --serv-foto: image-set(url("assets/img/serv-leadgen-v1.webp") type("image/webp"), url("assets/img/serv-leadgen-v1.jpg") type("image/jpeg")); }
  .serv-desc[data-serv="tech"]    { --serv-foto: image-set(url("assets/img/serv-tech-v1.webp") type("image/webp"), url("assets/img/serv-tech-v1.jpg") type("image/jpeg")); }
}
@media (prefers-reduced-motion: reduce) { .serv-desc::before { animation: none; } }
.serv-icono {
  display: block; width: 36px; height: 36px; margin-bottom: 18px;
  animation: icono-entra 0.4s cubic-bezier(0.16,1,0.3,1) both; animation-delay: 0.1s;
}
.serv-icono svg {
  width: 100%; height: 100%; fill: none; stroke: #5fd8c8;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
@keyframes icono-entra { from { opacity: 0; transform: scale(0.7) rotate(-8deg); } to { opacity: 1; transform: scale(1) rotate(0); } }
@media (prefers-reduced-motion: reduce) { .serv-icono { animation: none; } }
.serv-desc-tit { font-size: 22px; font-weight: 600; margin: 0 0 16px; color: #f4f8f7; }
.serv-desc-p { font-size: 15.5px; color: #b7cbc7; line-height: 1.6; margin: 0; }

.serv-pasos { background: var(--card); padding: 40px 44px; display: flex; flex-direction: column; gap: 26px; }
.serv-paso { display: flex; gap: 16px; }
.serv-paso-num {
  font-family: var(--font-mono); font-size: 12px; color: var(--signal);
  border: 1px solid var(--line-strong); border-radius: 50%; width: 26px; height: 26px;
  flex: none; display: flex; align-items: center; justify-content: center;
}
.serv-paso-tit { font-weight: 600; font-size: 15px; color: var(--ink); margin: 0 0 4px; }
.serv-paso-desc { font-size: 14px; color: var(--sub); margin: 0; line-height: 1.5; }

@media (max-width: 860px) {
  .serv-panel { grid-template-columns: 1fr; }
  .serv-desc, .serv-pasos { padding: 30px 26px; }
}

/* ── Animaciones y transiciones -- pedido de Marcos (29/08). Revelado al
   entrar en pantalla (una sola vez, no en bucle) + transiciones de hover en
   todo lo interactivo. Respeta prefers-reduced-motion: si el sistema lo
   pide, el JS marca todo visible de una vez sin animar nada. ── */
[data-reveal] {
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.16,1,0.3,1), transform 0.7s cubic-bezier(0.16,1,0.3,1);
}
[data-reveal].is-visible { opacity: 1; transform: translateY(0); }

/* Escalonado dentro de un grupo -- cada hijo entra un poco después del
   anterior, en vez de todos a la vez (se ve como una sola pieza inerte). */
[data-reveal-group] > *:nth-child(1) { transition-delay: 0ms; }
[data-reveal-group] > *:nth-child(2) { transition-delay: 90ms; }
[data-reveal-group] > *:nth-child(3) { transition-delay: 180ms; }
[data-reveal-group] > *:nth-child(4) { transition-delay: 270ms; }
[data-reveal-group] > *:nth-child(5) { transition-delay: 360ms; }
[data-reveal-group] > *:nth-child(6) { transition-delay: 450ms; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { transition: none !important; }
}

/* Entrada de la ficha flotante -- antes aparecía de golpe con display:none
   → block; ahora se desliza y aparece. Cuelga de .visible, no del elemento:
   la ficha ya no entra al cargar la página (ver el bloque del final). */
.ficha-flotante.visible {
  animation: ficha-entra 0.5s cubic-bezier(0.16,1,0.3,1) both;
}
@keyframes ficha-entra {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .ficha-flotante.visible { animation: none; opacity: 1; }
}

/* ══════════════════ Nav del header ══════════════════ */
.site-nav { display: flex; align-items: center; gap: 28px; }
.site-nav a {
  font-size: 14px; color: #cfe3df; text-decoration: none;
  transition: color 0.15s ease;
}
.site-header.on-light .site-nav a { color: var(--sub); }
.site-nav a:hover { color: #5fd8c8; }
.site-header.on-light .site-nav a:hover { color: var(--signal); }
@media (max-width: 980px) { .site-nav { display: none; } }

/* ── La puerta del cliente que ya trabaja con nosotros ──
   Pastilla HUECA a propósito: el botón verde de WhatsApp es la acción
   principal (captar clientes nuevos) y esto no puede competir con él. Un
   agente que ya es cliente lo busca; uno nuevo lo ignora -- y de paso le
   dice que aquí hay clientes de verdad. */
.btn-portal {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 7px 13px 7px 11px; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--ink);
  font-size: 13.5px; font-weight: 500; text-decoration: none; white-space: nowrap;
  transition: border-color .16s ease, background-color .16s ease;
}
.btn-portal svg { width: 16px; height: 16px; flex: none; }
.btn-portal:hover { border-color: var(--signal); background: rgba(31,143,128,.07); }
.btn-portal:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
/* Sobre el hero oscuro el header es translúcido: la pastilla se aclara. */
.site-header .btn-portal { color: #e9f1ef; border-color: rgba(233,241,239,.34); }
.site-header .btn-portal:hover { border-color: #5fd8c8; background: rgba(95,216,200,.12); }
.site-header.on-light .btn-portal { color: var(--ink); border-color: var(--line-strong); }
.site-header.on-light .btn-portal:hover { border-color: var(--signal); background: rgba(31,143,128,.07); }

/* ══════════════════ Hero: badge, typewriter, stats ══════════════════ */
/* El relleno translúcido NO es estético: es lo que deja bajar el velo de la
   foto sin sacar a esta píldora de AA. Medido contra el píxel de fondo más
   claro que le toca: sin relleno da 3.63 (falla), con él 6.2. Aclarar el
   texto en vez de rellenar habría exigido irse casi al blanco y perder el
   tono apagado que distingue la píldora del titular. */
.hero-badge {
  display: inline-flex; align-items: center; gap: 9px; margin: 0 0 26px;
  border: 1px solid rgba(95,216,200,0.35); border-radius: 20px; padding: 7px 16px;
  background: rgba(9, 24, 28, 0.74);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.05em; color: #9fc3bd;
}
.hero-badge-punto { width: 6px; height: 6px; border-radius: 50%; background: #5fd8c8; flex: none; }

.hero-typewriter {
  min-height: 34px; margin: 0 auto 10px; font-family: var(--font-mono);
  /* #e28a5c daba 3.89 sobre la foto con el velo nuevo (AA pide 4.5 a 17px).
     #f6b391 da 5.6 en escritorio y 4.7 a 390px, y sigue leyéndose
     naranja. Medido con las cajas de línea reales del texto. */
  font-size: 17px; color: #f6b391;
}
.hero-type-caret {
  display: inline-block; width: 2px; height: 17px; background: #f6b391;
  margin-left: 2px; vertical-align: -3px; animation: type-parpadeo 0.9s steps(1) infinite;
}
@keyframes type-parpadeo { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .hero-type-caret { animation: none; } }

.hero-stats {
  display: flex; justify-content: center; gap: 0; margin: 44px 0 10px;
  border: 1px solid rgba(233,241,239,0.14); border-radius: 4px; overflow: hidden;
}
.hero-stat {
  flex: 1; padding: 22px 18px; text-align: center;
  border-left: 1px solid rgba(233,241,239,0.14);
}
.hero-stat:first-child { border-left: none; }
.hero-stat b {
  display: block; font-family: var(--font-sans); font-weight: 600; font-size: 26px;
  color: #5fd8c8; margin-bottom: 4px;
}
.hero-stat span {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em;
  color: #8fb3ae; text-transform: uppercase;
}
@media (max-width: 760px) {
  .hero-stats { flex-wrap: wrap; }
  .hero-stat { flex: 1 1 50%; border-left: none; border-top: 1px solid rgba(233,241,239,0.14); }
  .hero-stat:nth-child(1), .hero-stat:nth-child(2) { border-top: none; }
}

/* ══════════════════ Proceso: 4 pasos ══════════════════ */
.proceso { padding-block: 96px 100px; background: var(--blueprint); color: #e9f1ef; }
.proceso-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: #f4f8f7; margin: 0 0 14px; max-width: 34ch;
}
.proceso-sub { font-size: 16px; color: #b7cbc7; max-width: 60ch; margin: 0 0 48px; }
.proceso-pasos { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: rgba(233,241,239,0.14); }
.proceso-paso { background: var(--blueprint); padding: 26px 24px; }
.proceso-paso-n { font-family: var(--font-mono); font-size: 12px; color: #5fd8c8; letter-spacing: 0.08em; }
.proceso-paso-tit { font-size: 17px; font-weight: 600; color: #f4f8f7; margin: 10px 0 8px; }
.proceso-paso-d { font-size: 13.5px; color: #a9c4bf; line-height: 1.55; margin: 0; }
@media (max-width: 860px) { .proceso-pasos { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .proceso-pasos { grid-template-columns: 1fr; } }

/* ══════════════════ Cobertura ══════════════════ */
.cobertura { padding-block: 96px 100px; background: var(--bg); }
.cobertura-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: var(--ink); margin: 0 0 14px; max-width: 34ch;
}
.cobertura-sub { font-size: 16px; color: var(--sub); max-width: 60ch; margin: 0 0 44px; }
.cobertura-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.cobertura-card { border: 1px solid var(--line-strong); background: var(--card); padding: 30px 32px; }
.cobertura-cod { display: block; font-family: var(--font-sans); font-weight: 700; font-size: 34px; color: var(--signal); margin-bottom: 10px; }
.cobertura-tit { font-size: 18px; font-weight: 600; color: var(--ink); margin: 0 0 10px; }
.cobertura-d { font-size: 14.5px; color: var(--sub); line-height: 1.6; margin: 0; }
@media (max-width: 700px) { .cobertura-grid { grid-template-columns: 1fr; } }

/* ══════════════════ Precios ══════════════════ */
.precios { padding-block: 96px 60px; background: var(--blueprint); color: #e9f1ef; }
.precios-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: #f4f8f7; margin: 0 0 14px; max-width: 36ch;
}
.precios-sub { font-size: 16px; color: #b7cbc7; max-width: 62ch; margin: 0 0 46px; }
.precios-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: start; }
.precio-card {
  border: 1px solid rgba(233,241,239,0.18); background: #163338; padding: 30px 28px;
  display: flex; flex-direction: column; position: relative;
}
.precio-card--destacada { border-color: #5fd8c8; }
.precio-chip {
  position: absolute; top: -13px; left: 28px; background: #5fd8c8; color: #0d2320;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 3px;
}
.precio-plan { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.08em; color: #5fd8c8; text-transform: uppercase; }
.precio-tit { font-size: 19px; font-weight: 600; color: #f4f8f7; margin: 8px 0 22px; }
.precio-monto { font-family: var(--font-sans); font-weight: 700; font-size: 38px; color: #f4f8f7; margin: 0 0 16px; }
/* Sin cifra, el monto pasa a ser una invitación a preguntar. A 38px una
   frase de tres palabras se desborda de la tarjeta, así que baja de tamaño
   y toma la forma de un enlace: sigue siendo la línea que más pesa dentro
   de la tarjeta, pero ya no compite con el titular. */
.precio-monto--pedir {
  display: inline-block; font-size: 19px; line-height: 1.3; color: #5fd8c8;
  text-decoration: none; border-bottom: 1px solid rgba(95,216,200,0.45);
  padding-bottom: 2px; transition: color 0.15s ease, border-color 0.15s ease;
}
.precio-monto--pedir:hover, .precio-monto--pedir:focus-visible {
  color: #8ce8db; border-bottom-color: #8ce8db;
}
.precio-monto span { font-family: var(--font-sans); font-weight: 400; font-size: 15px; color: #8fb3ae; }
.precio-d { font-size: 14px; color: #a9c4bf; line-height: 1.55; margin: 0 0 24px; }
.precio-lista { list-style: none; margin: 0 0 28px; padding: 0; flex: 1; }
.precio-lista li {
  font-size: 13.5px; color: #cfe3df; padding: 8px 0 8px 20px; position: relative;
  border-top: 1px solid rgba(233,241,239,0.10);
}
.precio-lista li::before { content: "+"; position: absolute; left: 0; color: #5fd8c8; }
.precio-btn {
  display: block; text-align: center; padding: 12px; border: 1px solid rgba(233,241,239,0.3);
  color: #e9f1ef; text-decoration: none; font-weight: 600; font-size: 14px; border-radius: 999px;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.precio-btn:hover { border-color: #5fd8c8; }
.precio-btn--p { background: #5fd8c8; color: #0d2320; border-color: #5fd8c8; }
.precio-btn--p:hover { background: #4ec4b4; }
.precios-nota { font-family: var(--font-sans); font-size: 12px; color: #7c9995; margin-top: 32px; }
@media (max-width: 900px) { .precios-grid { grid-template-columns: 1fr; } }

/* ══════════════════ Equipo ══════════════════ */
.equipo { padding-block: 96px 100px; background: var(--bg); }
.equipo-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: var(--ink); margin: 0 0 14px; max-width: 40ch;
}
.equipo-sub { font-size: 16px; color: var(--sub); max-width: 60ch; margin: 0 0 44px; }
.equipo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.equipo-card { border: 1px solid var(--line-strong); background: var(--card); padding: 28px; }
.equipo-card--pendiente { border-style: dashed; }
.equipo-avatar {
  display: flex; align-items: center; justify-content: center; width: 48px; height: 48px;
  border-radius: 50%; background: var(--signal-fondo); color: #fff; font-weight: 600; font-size: 16px;
  margin-bottom: 18px;
}
.equipo-avatar--pendiente { background: none; border: 1px dashed var(--line-strong); color: var(--sub); }
.equipo-nombre { font-size: 17px; font-weight: 600; color: var(--ink); margin: 0 0 4px; }
.equipo-rol { font-family: var(--font-sans); font-size: 12px; letter-spacing: 0.04em; color: var(--signal); margin: 0 0 14px; }
.equipo-bio { font-size: 14px; color: var(--sub); line-height: 1.6; margin: 0; }
@media (max-width: 860px) { .equipo-grid { grid-template-columns: 1fr; } }

/* ══════════════════ Preguntas frecuentes ══════════════════ */
.preguntas { padding-block: 96px 100px; background: var(--blueprint); color: #e9f1ef; }
.preguntas-h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: clamp(26px, 3vw, 36px);
  color: #f4f8f7; margin: 0 0 44px; max-width: 40ch;
}
.pregunta { border: 1px solid rgba(233,241,239,0.16); background: #0d2126; margin-bottom: 10px; }
.pregunta-btn {
  width: 100%; display: flex; justify-content: space-between; align-items: center;
  gap: 16px; background: none; border: none; padding: 20px 22px; cursor: pointer;
  font-family: var(--font-sans); font-size: 15.5px; font-weight: 600; color: #e9f1ef; text-align: left;
}
.pregunta-icono {
  flex: none; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  color: #5fd8c8; font-size: 18px; transition: transform 0.2s ease;
}
.pregunta[data-abierta] .pregunta-icono { transform: rotate(45deg); }
.pregunta-resp {
  max-height: 0; overflow: hidden; transition: max-height 0.3s ease;
}
.pregunta-resp p { margin: 0; padding: 0 22px 22px; font-size: 14.5px; color: #b7cbc7; line-height: 1.6; }
@media (prefers-reduced-motion: reduce) { .pregunta-icono, .pregunta-resp { transition: none; } }

/* ══════════════════ Contacto ══════════════════ */
.contacto { padding-block: 96px 110px; background: var(--bg); }
.contacto-caja {
  display: grid; grid-template-columns: 1fr 1.3fr; gap: 0;
  border: 1px solid var(--line-strong); background: var(--card);
}
.contacto-izq { padding: 44px 40px; background: var(--blueprint); color: #e9f1ef; }
.contacto-h2 { font-size: clamp(24px, 2.6vw, 32px); font-weight: 400; margin: 0 0 16px; color: #f4f8f7; }
.contacto-sub { font-size: 14.5px; color: #b7cbc7; line-height: 1.6; margin: 0 0 30px; }
.contacto-datos p { font-size: 14px; color: #cfe3df; margin: 0 0 10px; }
.contacto-datos span:first-child { color: #8fb3ae; font-family: var(--font-sans); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; margin-right: 6px; }
.contacto-datos a { color: #5fd8c8; text-decoration: none; }
.contacto-datos a:hover { text-decoration: underline; }

.contacto-form { padding: 44px 40px; display: grid; grid-template-columns: 1fr 1fr; gap: 18px 20px; align-content: start; }
.contacto-campo { display: flex; flex-direction: column; gap: 7px; }
.contacto-campo--full { grid-column: 1 / -1; }
.contacto-campo label { font-family: var(--font-sans); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--sub); }
.contacto-campo input, .contacto-campo select, .contacto-campo textarea {
  border: 1px solid var(--line-strong); background: var(--bg); padding: 10px 12px;
  font-family: var(--font-sans); font-size: 14px; color: var(--ink); border-radius: 3px;
}
.contacto-campo input:focus-visible, .contacto-campo select:focus-visible, .contacto-campo textarea:focus-visible {
  outline: 2px solid var(--signal); outline-offset: 1px;
}
/* Consentimiento de SMS. La casilla y su texto rompen la retícula de campos
   a propósito: no es un dato más que se rellena, es algo que se lee y se
   decide. Por eso el texto va en minúscula y a tamaño legible, y no con la
   etiqueta en versalitas de los demás campos. */
.contacto-consent { gap: 6px; }
.contacto-check {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  font-family: var(--font-sans); font-size: 13px; line-height: 1.5;
  color: var(--sub); text-transform: none; letter-spacing: 0;
}
.contacto-check input {
  flex: none; width: 16px; height: 16px; margin-top: 2px;
  accent-color: var(--signal); cursor: pointer;
}
.contacto-check input:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.contacto-legal { margin: 0; font-family: var(--font-sans); font-size: 12px; color: var(--sub); padding-left: 26px; }
.contacto-legal a { color: var(--sub); text-decoration: underline; text-underline-offset: 2px; }
.contacto-legal a:hover { color: var(--signal-dark); }

.contacto-btn { grid-column: 1 / -1; justify-self: start; border: none; cursor: pointer; }
@media (max-width: 900px) {
  .contacto-caja { grid-template-columns: 1fr; }
  .contacto-form { grid-template-columns: 1fr; }
}

/* ── Franja de 5: las etiquetas ya no caben en una línea como cuando eran 4,
   así que se ajusta el tamaño y se deja que envuelvan parejo. ── */
.hero-stats--cinco .hero-stat { padding: 20px 14px; }
.hero-stats--cinco .hero-stat b { font-size: 23px; }
.hero-stats--cinco .hero-stat span {
  font-size: 10.5px; line-height: 1.45; display: block; text-transform: none;
  letter-spacing: 0.02em;
}
@media (max-width: 1080px) {
  .hero-stats--cinco { flex-wrap: wrap; }
  .hero-stats--cinco .hero-stat {
    flex: 1 1 33.333%; border-left: 1px solid rgba(233,241,239,0.14);
    border-top: 1px solid rgba(233,241,239,0.14);
  }
  .hero-stats--cinco .hero-stat:nth-child(-n+3) { border-top: none; }
  .hero-stats--cinco .hero-stat:nth-child(3n+1) { border-left: none; }
}
@media (max-width: 620px) {
  .hero-stats--cinco .hero-stat { flex: 1 1 50%; }
  .hero-stats--cinco .hero-stat:nth-child(-n+3) { border-top: 1px solid rgba(233,241,239,0.14); }
  .hero-stats--cinco .hero-stat:nth-child(3n+1) { border-left: 1px solid rgba(233,241,239,0.14); }
  .hero-stats--cinco .hero-stat:nth-child(-n+2) { border-top: none; }
  .hero-stats--cinco .hero-stat:nth-child(odd) { border-left: none; }
}

/* El enlace a Argo no es un ancla de esta página sino OTRA página, así que se
   separa del resto del menú con una línea y el punto de la marca. Sin esa
   señal, quien lo pulsa cree que va a bajar a una sección y termina en un
   sitio distinto. */
.nav-argo {
  position: relative; padding-left: 18px; margin-left: 6px;
  border-left: 1px solid var(--line);
}
.nav-argo::before {
  content: ""; position: absolute; left: 8px; top: 50%;
  width: 5px; height: 5px; margin-top: -2.5px;
  background: var(--signal);
}

/* Cierra la sección de proceso. Va centrada y en el verde de marca porque es
   la única afirmación de la página sobre lo que garantizamos -- y es sobre el
   proceso, no sobre un resultado que no controlamos. */
.proceso-garantia {
  margin: 34px auto 0; max-width: 620px; text-align: center;
  font-size: 16px; line-height: 1.55; color: var(--signal);
  padding-top: 26px; border-top: 1px solid var(--line);
}

/* ── Bloque de Argo ────────────────────────────────────────────────────
   Va antes de Precios para que el costo se compare contra todo lo que
   incluye. El chat es una MUESTRA estática: la demo interactiva vive en
   /argo/ y es la razón para hacer clic, así que aquí no se duplica. */
.argo-bloque { padding: 92px 0; border-top: 1px solid var(--line); }
.argo-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.argo-eyebrow {
  font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--signal-dark, #16665b); margin: 0 0 14px; font-weight: 600;
}
.argo-h2 { font-size: clamp(26px, 3vw, 34px); line-height: 1.18; margin: 0 0 18px; letter-spacing: -0.01em; }
.argo-p { font-size: 16px; line-height: 1.62; color: var(--sub, #48575c); margin: 0 0 26px; max-width: 46ch; }
.argo-link {
  display: inline-block; font-weight: 600; font-size: 15px; text-decoration: none;
  color: var(--signal-dark, #16665b); border-bottom: 1px solid currentColor; padding-bottom: 2px;
  transition: opacity 0.15s ease;
}
.argo-link:hover { opacity: 0.7; }


@media (max-width: 900px) {
  .argo-wrap { grid-template-columns: 1fr; gap: 34px; }
  .argo-p { max-width: none; }
}

/* ── El teléfono del bloque de Argo ────────────────────────────────────
   Rehecho el 02/09 con el mismo lenguaje que la landing de /argo/, para que
   las dos páginas se lean como un solo producto: chasis en contorno, isla
   dinámica, barra de estado mono e indicador de "escribiendo…".

   UNA diferencia deliberada con /argo/: allí el hero es oscuro y el chasis
   va claro con halo; aquí la sección es clara, así que el chasis va OSCURO.
   El aparato tiene que contrastar con lo que hay detrás, no repetir un color.

   El fondo del chat usa el tono real de WhatsApp pero NO su patrón de
   garabatos: ese dibujo es obra de Meta y esta página es pública (en el
   video interno sí se autorizó, aquí no). ── */

/* La columna del teléfono se ancla mientras se recorre la sección. Sin esto
   el teléfono pasaba de largo en 0,73 pantallas y la única prueba de que
   Argo existe se veía menos que cualquier otra sección de la página. */
/* El bloque sticky NO puede ser el propio elemento del grid: un elemento
   pegajoso se mueve dentro de SU BLOQUE CONTENEDOR, y el de un hijo del grid
   es su área de rejilla. Con `align-items: start` esa área medía lo mismo que
   el teléfono y el recorrido era CERO -- medido: se soltaba y se iba por
   arriba de la pantalla a los 263px. La columna estira a lo alto de la fila
   (stretch) y lo pegajoso es el envoltorio de dentro. */
.argo-wrap { align-items: stretch; }
.argo-col { display: flex; flex-direction: column; }
/* La perspectiva va en el padre DIRECTO del que rota (.at-marco). Aquí ese
   padre es además el elemento `sticky` — `perspective` no crea bloque
   contenedor para sí mismo, así que el anclaje se conserva (comprobado). */
.argo-fijo {
  position: sticky; top: calc(var(--header-h) + 34px);
  perspective: 1400px; perspective-origin: 50% 42%;
}

/* Mismo 3D que el teléfono de /argo/ (ver la nota larga allí): perspectiva en
   el padre, capas separadas en Z y un motor de resortes en el JS. Aquí el
   chasis es OSCURO sobre sección clara, así que el brillo es más tenue: sobre
   un objeto oscuro un reflejo fuerte se lee como un fallo, no como cristal. */
.at-marco {
  --rx: 0deg; --ry: 0deg; --lift: 0px;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx)) rotateY(var(--ry)) translateZ(var(--lift));
  will-change: transform;
  position: relative;
  width: 100%; max-width: 320px; margin-inline: auto;
  padding: 9px; border-radius: 44px;
  background: linear-gradient(155deg, #2b4a52, #14252b 46%, #1d3b42);
  box-shadow:
    inset 0 1px 0 rgba(233, 241, 239, 0.14),
    0 30px 60px -24px rgba(20, 48, 56, 0.55),
    0 0 0 1px rgba(20, 48, 56, 0.14);
}
.at-pantalla {
  position: relative; border-radius: 36px; overflow: hidden; background: #fff;
  display: flex; flex-direction: column;
  /* Al inclinarse, el borde del chasis pasa por delante y se ve el grosor:
     eso es lo que hace que se lea como objeto y no como imagen torcida. */
  transform: translateZ(13px);
}
.at-marco::after {
  content: ""; position: absolute; inset: 0; border-radius: 44px;
  pointer-events: none; z-index: 3; transform: translateZ(19px);
  background: radial-gradient(
    56% 42% at calc(50% + var(--gx, 0px)) calc(0% + var(--gy, 0px)),
    rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.04) 44%, transparent 70%);
  opacity: var(--glare, 0);
}
.at-isla {
  position: absolute; z-index: 3; top: 8px; left: 50%; transform: translateX(-50%);
  width: 78px; height: 21px; border-radius: 13px; background: #0d1416;
}
.at-status {
  display: flex; justify-content: space-between; align-items: center;
  min-height: 30px; padding: 8px 19px 4px;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--ink);
}
.at-ic { display: flex; align-items: center; gap: 5px; color: var(--ink); }
.at-ic svg { fill: currentColor; }
.at-ic-s { width: 14px; height: 9px; }
.at-ic-w { width: 13px; height: 9px; }
.at-ic-b { width: 21px; height: 9px; }
.at-inicio {
  width: 108px; height: 4px; border-radius: 3px;
  background: rgba(22, 33, 31, 0.28); margin: 2px auto 7px; flex: none;
}
.at-cab {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 16px 11px; border-bottom: 1px solid rgba(20,48,56,0.10);
}
.at-av { width: 30px; height: 30px; border-radius: 50%; background: var(--signal); flex: none; }
.at-quien { display: flex; flex-direction: column; line-height: 1.2; }
.at-quien b { font-size: 14px; color: var(--ink); font-weight: 500; }
.at-quien small { font-size: 10.5px; color: var(--sub); margin-top: 1px; }
.at-quien small.escribiendo { color: var(--signal); }

.at-chat {
  /* Alto atado a la ventana, no fijo. Con 316px clavados, en un portátil de
     720px el teléfono medía 620 de 720 y el sticky se quedaba sin recorrido:
     medido, los tiempos 3 y 4 se encendían con el aparato ya suelto. */
  height: clamp(214px, 33vh, 320px); overflow-y: auto; padding: 14px 12px;
  background-color: #efeae2;
  background-image: radial-gradient(rgba(20, 48, 56, 0.06) 1px, transparent 1px);
  background-size: 14px 14px;
  display: flex; flex-direction: column; gap: 8px; justify-content: flex-end;
  scroll-behavior: smooth; scrollbar-width: none;
}
.at-chat::-webkit-scrollbar { display: none; }

.at-msj {
  max-width: 86%; flex: none; padding: 8px 12px; border-radius: 10px;
  font-size: 14px; line-height: 1.45; color: #16211f;
  box-shadow: 0 1px 1px rgba(20, 48, 56, 0.06);
}
.at-lead { background: #ffffff; border-top-left-radius: 3px; align-self: flex-start; transform-origin: bottom left; }
.at-argo { background: #d6f2e5; border-top-right-radius: 3px; align-self: flex-end; transform-origin: bottom right; }

/* ── El guion. Regla de oro: SIN JavaScript los cuatro mensajes se ven
   completos. La clase .guion la pone el JS al arrancar, y sólo entonces se
   ocultan -- así un fallo del script deja la conversación entera a la vista
   en vez de un teléfono vacío. ── */
.at-chat.guion .at-msj { display: none; }
.at-chat.guion .at-msj.visible { display: block; animation: at-entra 0.5s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes at-entra {
  0%   { opacity: 0; transform: translateY(12px) scale(0.94); }
  62%  { opacity: 1; transform: translateY(-2px) scale(1.012); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.at-typing {
  align-self: flex-start; display: flex; align-items: center; gap: 5px;
  width: max-content; flex: none; padding: 11px 13px;
  background: #fff; border-radius: 10px; border-top-left-radius: 3px;
  box-shadow: 0 1px 1px rgba(20, 48, 56, 0.06);
  transform-origin: bottom left;
  animation: at-entra 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.at-typing i { display: block; width: 6px; height: 6px; border-radius: 50%; background: #9aa8a5;
  animation: at-punto 1.15s ease-in-out infinite; }
.at-typing i:nth-child(2) { animation-delay: 0.16s; }
.at-typing i:nth-child(3) { animation-delay: 0.32s; }
@keyframes at-punto {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.42; }
  30%           { transform: translateY(-4px); opacity: 1; }
}

.at-barra {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  background: #fff; font-size: 13.5px; color: #9aa8a5;
}
.at-barra i { margin-left: auto; width: 26px; height: 26px; border-radius: 50%; background: var(--signal); flex: none; }

/* ── Los cuatro tiempos, en la columna de texto ────────────────────────
   El padding generoso NO es decorativo: es lo que le da recorrido al sticky.
   Sin altura suficiente en esta columna el teléfono no tiene dónde anclarse
   y `position: sticky` no hace nada. ── */
/* La cola de abajo NO es aire decorativo: alarga el recorrido del sticky
   para que el CUARTO tiempo se encienda con el teléfono todavía anclado.
   Sin ella, la última frase ("tú retomas") llegaba justo cuando el aparato
   ya se estaba yendo por detrás del encabezado. */
.argo-txt { padding-bottom: clamp(40px, 13vh, 140px); }

/* Línea de tiempo: une los cuatro puntos. Sin ella, cuatro filas separadas
   por bordes horizontales se leen como una tabla vacía, no como una
   secuencia. */
.argo-pasos { list-style: none; margin: 30px 0 30px; padding: 0; position: relative; }
.argo-pasos::before {
  content: ""; position: absolute; left: 3px; top: 12px; bottom: 12px;
  width: 1px; background: var(--line);
}
.argo-paso {
  display: grid; grid-template-columns: 128px 1fr; gap: 18px; align-items: baseline;
  /* La altura en vh es lo que le da recorrido al sticky Y lo que hace que
     cada tiempo tenga su propio momento de scroll. En px la sección se
     quedaba en 0,86 pantallas y el teléfono apenas se anclaba. */
  /* El suelo en px importa en ventanas bajas: sólo con vh, a menos alto la
     sección encoge a la vez que el teléfono y el recorrido no aparece. */
  align-content: center; min-height: max(118px, 15vh); position: relative;
  padding-block: 18px; border-top: 1px solid var(--line);
  opacity: 0.4; transition: opacity 0.4s ease;
}
.argo-paso:last-child { border-bottom: 1px solid var(--line); }
.argo-paso.activo { opacity: 1; }
.ap-t {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--signal-dark); font-weight: 500;
  position: relative; padding-left: 16px;
}
/* El punto marca cuál de los cuatro tiempos está sonando ahora mismo. */
.ap-t::before {
  content: ""; position: absolute; left: 0; top: 0.42em;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--line-strong); transition: background-color 0.4s ease, box-shadow 0.4s ease;
}
.argo-paso.activo .ap-t::before {
  background: var(--signal); box-shadow: 0 0 0 4px rgba(31, 143, 128, 0.16);
}
.ap-d { font-size: 17px; line-height: 1.5; color: var(--ink); }

.argo-pie { margin: 16px 0 0; font-size: 13.5px; color: var(--sub); font-style: italic; text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .at-marco { --rx: 0deg !important; --ry: 0deg !important; --lift: 0px !important; }
  .at-marco::after { opacity: 0 !important; }
  .at-chat.guion .at-msj.visible, .at-typing, .at-typing i { animation: none; }
  .at-chat { scroll-behavior: auto; }
  .argo-paso { opacity: 1; }
}

/* Bajo 900px el grid es de una columna: anclar el teléfono arriba se comería
   el 60% de una pantalla de 844px mientras se lee el texto de debajo. Se
   suelta, y el guion se dispara al entrar el teléfono en pantalla. */
@media (max-width: 900px) {
  .argo-fijo { position: static; }
  .argo-paso { grid-template-columns: 1fr; gap: 6px; min-height: 0; padding-block: 17px; opacity: 1; }
  .ap-d { font-size: 15px; }
}

/* El precio, ahora que hay cifra */
.precio-monto { display: flex; align-items: baseline; gap: 2px; }
.precio-monto .pm-cifra { font-family: var(--font-sans); font-weight: 700; font-size: 38px; color: #f4f8f7; }
.precio-monto .pm-unidad { font-family: var(--font-sans); font-weight: 400; font-size: 15px; color: #8fb3ae; }
/* La oferta incluida es un extra, no una característica más: va aparte de la
   lista y en el verde de marca para que se vea antes que los puntos. */
.precio-bonus {
  margin: -6px 0 16px; font-size: 13.5px; line-height: 1.4;
  color: #5fd8c8; font-weight: 600;
}
/* El sistema automatizado encabeza las tres listas: es lo único que ningún
   otro coordinador ofrece. */
.pf-sistema { color: #e9f1ef; font-weight: 500; }
.pf-sistema::before { color: #5fd8c8; }
/* Las dos promesas transversales (respuesta en 15 min y, en B/C, el
   seguimiento de Argo) encabezan las listas y se destacan del resto: son lo
   que ningún otro coordinador ofrece. */
.pf-rapido, .pf-argo, .pf-diligencia { color: #e9f1ef; font-weight: 500; }
.pf-rapido::before, .pf-argo::before, .pf-diligencia::before { color: #5fd8c8; }

/* "Próximamente" no puede verse como una función más: va apagado y en
   redonda pequeña. Un plan que promete algo que aún no existe tiene que
   decirlo donde se lee, no en una nota al pie. */
.pf-pronto {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: #9fb8b4;
  border: 1px solid rgba(233,241,239,0.22); border-radius: 999px;
  vertical-align: middle; font-weight: 400;
}
/* La línea de Argo Transactions se apaga respecto a las demás: se ofrece,
   pero no compite con lo que ya se entrega hoy. */
.pf-argo { color: #b7cbc7; font-weight: 400; }
.pf-argo b { color: #e9f1ef; font-weight: 600; }

/* ── Encabezado en teléfono ──────────────────────────────────────────────
   En una pantalla de 390px el logo con su subtítulo, el conmutador y el
   botón se aprietan. El subtítulo del wordmark es lo primero que sobra: la
   marca se reconoce igual sin él.
   NOTA de medición: para probar 390px de verdad hay que usar
   Emulation.setDeviceMetricsOverride por CDP -- `--window-size=390` da un
   viewport de 500 y hace creer que hay un desbordamiento que no existe. */
@media (max-width: 560px) {
  .marca-tipo small { display: none; }
  .header-derecha { gap: 10px; }
  .site-header .wrap { gap: 10px; }
  .lang-switch { flex: none; }
  .marca { min-width: 0; overflow: hidden; }
}
/* Rompe las 7 pantallas de scroll que había entre el CTA del hero y el
   siguiente. Va justo después de explicar el proceso: es el momento en que
   el agente ya entiende qué compra. */
.proceso-cta {
  display: flex; align-items: center; justify-content: center; gap: 22px;
  flex-wrap: wrap; margin: 34px auto 0; text-align: center;
}
.proceso-cta p { margin: 0; font-size: 16.5px; color: var(--ink); font-weight: 500; }

/* ── El hero en teléfono ─────────────────────────────────────────────────
   El SVG es 400×260, así que a 92vw se comía casi toda la primera pantalla
   de un iPhone y empujaba el titular fuera de vista: lo primero que veía un
   agente era un dibujo a medio trazar sobre fondo oscuro. La medición en
   escritorio no lo mostraba.
   En móvil el titular manda; la animación acompaña, no ocupa. */
@media (max-width: 700px) {
  .plano-svg { width: min(64vw, 260px); }
  .hero-plano { margin-bottom: 2px; }
}

/* ── Ficha flotante: ahora entra tarde ───────────────────────────────────
   Salía al abrir la página. En el teléfono eso significaba que lo primero
   que veía un agente, encima del hero, era una tarjeta pidiéndole que
   escribiera -- antes de saber qué se le ofrece. Ahora aparece cuando ya
   pasó el hero, que es cuando la pregunta "¿tienes dudas?" tiene sentido.
   `visibility` además de `opacity` para que no sea un blanco de clic
   invisible mientras está oculta. ── */
.ficha-flotante { opacity: 0; visibility: hidden; }
.ficha-flotante.visible { visibility: visible; }

/* ── Botón fijo de WhatsApp (solo teléfono) ──────────────────────────────
   Del hero al formulario hay ~5 pantallas sin ninguna acción posible. En
   escritorio eso lo cubre la ficha flotante; en el teléfono la ficha ocupa
   el ancho completo y tapa el contenido, así que ahí se apaga y queda este
   botón: la conversión a un toque durante todo el scroll.
   Color de marca (--signal), no el verde de WhatsApp, para que no compita
   con la paleta ni parezca un widget pegado de un tercero. ── */
.wa-fab { display: none; }
@media (max-width: 700px) {
  .ficha-flotante { display: none; }
  /* El encabezado es fijo, así que su botón de WhatsApp ya se veía siempre:
     con el flotante encima quedaban DOS círculos verdes idénticos en
     pantalla. Se retira el del encabezado y la acción baja a la zona del
     pulgar -- arriba a la derecha, en una pantalla de 844 px de alto, hay
     que cambiar de agarre para llegar. El encabezado queda con el logo y
     el conmutador de idioma, que es lo que ahí sí gana. */
  .btn-wa--header { display: none; }
  .wa-fab {
    display: flex; align-items: center; justify-content: center;
    position: fixed; right: 16px; z-index: 60;
    /* safe-area: en iPhone con barra de gestos, 16px cae debajo de ella */
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--signal-fondo); color: var(--signal-ink);
    border: 1px solid var(--signal);
    box-shadow: 0 12px 28px -8px rgba(20, 48, 56, 0.55);
    text-decoration: none;
    transition: transform .1s ease, background-color .15s ease;
  }
  .wa-fab svg { width: 28px; height: 28px; }
  .wa-fab:active { transform: translateY(1px); background: #197a6d; }
  .wa-fab:focus-visible { outline: 2px solid var(--blueprint); outline-offset: 3px; }
}

/* ── Acción del panel de servicios ───────────────────────────────────────
   Hasta ahora los seis servicios solo describían. "Ofertas" es el único que
   tiene una puerta de entrada real y automatizada — el formulario del TC
   System — así que es el único que lleva botón. Va al final de la columna
   blanca, después de los tres pasos: primero se entiende el servicio, luego
   se actúa. Abre en pestaña nueva porque sale a otro dominio (Apps Script)
   y no queremos que el agente pierda la página. ── */
.serv-cta {
  align-self: flex-start; margin-top: 4px;
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600; color: var(--signal);
  text-decoration: none; padding: 11px 20px; border-radius: 999px;
  border: 1px solid var(--signal);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.serv-cta::after { content: "→"; font-weight: 400; }
.serv-cta:hover { background: var(--signal-fondo); color: var(--signal-ink); }
.serv-cta:focus-visible { outline: 2px solid var(--blueprint); outline-offset: 3px; }

/* ── "Envíanos tu oferta", la segunda acción del flotante ────────────────
   En escritorio vive DENTRO de la ficha, bajo el teléfono y separada por una
   línea: el teléfono sigue siendo la acción principal y esta no compite. ── */
.ficha-oferta {
  display: flex; align-items: center; gap: 6px;
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line);
  font-size: 13.5px; font-weight: 600; color: var(--signal); text-decoration: none;
}
.ficha-oferta::after { content: "→"; font-weight: 400; }
.ficha-oferta:hover { color: var(--signal-dark); }
.ficha-oferta:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

/* En teléfono la ficha está apagada (ver el bloque de arriba), así que la
   acción viaja sola, apilada ENCIMA del botón de WhatsApp -- debajo no cabe,
   ahí está el borde de la pantalla. Píldora con texto y no un círculo con
   icono: un documento suelto no dice "mandar una oferta". Y va en claro
   sobre borde verde para que el círculo lleno siga siendo el principal. */
.oferta-fab { display: none; }
@media (max-width: 700px) {
  /* Solo después del hero, igual que la ficha: en 390 px esta píldora mide
     casi todo el ancho y tapaba el titular desde que cargaba. */
  body.pasado-hero .oferta-fab { opacity: 1; visibility: visible; }
  .oferta-fab {
    opacity: 0; visibility: hidden; transition: opacity .3s ease;
    display: inline-flex; align-items: center; gap: 7px;
    position: fixed; right: 16px; z-index: 60;
    bottom: calc(16px + 56px + 10px + env(safe-area-inset-bottom, 0px));
    height: 38px; padding: 0 14px; border-radius: 999px;
    background: var(--card); color: var(--signal);
    border: 1px solid var(--signal); text-decoration: none;
    font-size: 13px; font-weight: 600; white-space: nowrap;
    box-shadow: 0 8px 20px -8px rgba(20, 48, 56, 0.45);
    transition: transform .1s ease;
  }
  .oferta-fab svg { width: 17px; height: 17px; flex: none; }
  .oferta-fab:active { transform: translateY(1px); }
  .oferta-fab:focus-visible { outline: 2px solid var(--blueprint); outline-offset: 3px; }
}

/* ── Segundo CTA del hero: enviar oferta ─────────────────────────────────
   Es la zona más visible de toda la página -- lo primero que se ve al
   cargar, antes de cualquier scroll. Va en contorno, no relleno: WhatsApp
   sirve para cualquier consulta y tiene que seguir leyéndose como la
   acción principal; esta es la vía rápida para quien YA sabe que va a
   mandar una oferta y no quiere escribir primero. */
.btn-oferta {
  display: inline-flex; align-items: center; gap: 10px;
  background: transparent; color: #e9f1ef;
  font-family: var(--font-sans); font-weight: 600; font-size: 15px;
  padding: 12px 22px; border-radius: 999px; text-decoration: none;
  border: 1px solid rgba(233, 241, 239, 0.4); white-space: nowrap;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.btn-oferta:hover { border-color: #5fd8c8; background: rgba(95, 216, 200, 0.08); }
.btn-oferta svg { width: 17px; height: 17px; flex: none; }
.btn-oferta:focus-visible { outline: 2px solid #5fd8c8; outline-offset: 3px; }

/* ── Formulario de contacto: aviso y campo trampa ────────────────────────
   El campo trampa NO va con display:none ni type="hidden": los bots que
   valen algo saltean lo oculto de esa forma. Se saca de la vista con
   posición absoluta, que para un bot que lee el DOM sigue siendo un campo
   normal y visible. */
.contacto-trampa {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}
.contacto-msg {
  margin: 10px 0 0; font-size: 13.5px; line-height: 1.5; min-height: 20px;
  color: var(--sub);
}
.contacto-msg--ok { color: var(--senal, #1f8f80); font-weight: 600; }
.contacto-msg--error { color: #c0392b; }
.contacto-btn[disabled] { opacity: .6; cursor: wait; }
