/* ============================================================
   TeraVolta — rebuild desde cero · Paso 1: navbar + hero + fondo
   Art direction: "Energía en la oscuridad" (dark cinematic).
   Endurecido para iOS (Safari de vidrio / Liquid Glass).
   ============================================================ */

/* Banks & Miles Single Line (K-Type) — familia de marca. Pesos reales por rango
   => sin negrita sintética. woff2 (soporte universal). */
@font-face { font-family:'BanksMiles'; src:url('../assets/fonts/BanksMiles-Regular.woff2') format('woff2'); font-weight:100 400; font-style:normal; font-display:swap; }
@font-face { font-family:'BanksMiles'; src:url('../assets/fonts/BanksMiles-Medium.woff2') format('woff2'); font-weight:500 600; font-style:normal; font-display:swap; }
@font-face { font-family:'BanksMiles'; src:url('../assets/fonts/BanksMiles-Bold.woff2') format('woff2'); font-weight:700 900; font-style:normal; font-display:swap; }
@font-face { font-family:'BanksMiles'; src:url('../assets/fonts/BanksMiles-Italic.woff2') format('woff2'); font-weight:100 400; font-style:italic; font-display:swap; }

/* ---------- tokens de marca (paleta canónica) ---------- */
:root{
  --bg:#06090f;
  --surface:#0b1220;
  --navy:#004a90;
  --navy-l:#2464a0;
  --teal:#02a2b6;
  --teal2:#26afc0;
  --lime:#c3d021;
  --on-accent:#06101a;
  --stale:91,120,154; /* slate apagado: la forma vieja/lenta, NO un error (el rojo se reserva a errores) */
  --txt:rgba(255,255,255,0.92);
  --muted:rgba(255,255,255,0.56);
  --line:rgba(255,255,255,0.10);
  --grad:linear-gradient(104deg,#2464a0 0%,#02a2b6 52%,#c3d021 100%);
  --font-display:'BanksMiles', sans-serif;
  --font-body:'IBM Plex Sans', system-ui, sans-serif;
  /* margen lateral consistente en todo el sitio */
  --gutter:clamp(24px,8vw,104px);
}

*{box-sizing:border-box;margin:0;padding:0}

/* El fondo va en html: overscroll y la franja bajo las barras del browser nunca
   caen al blanco/negro por defecto. color-scheme:dark => Safari 26 usa su vidrio
   oscuro y compone el contenido a través, como apple.com. */
html{scroll-behavior:auto;color-scheme:dark;background:var(--bg)}

/* ---------- Vidrio de Safari 26 (Liquid Glass) — pins por position:fixed ----------
   REGLA REAL, aislada con bisect en device (iPhone, iOS 26) — leer antes de tocar
   cualquier pin:

     El vidrio muere cuando un elemento pineado tapa el viewport ENTERO. Da igual
     el mecanismo. Se probó, con la sección de #porque a 100svh: position:fixed →
     muere; position:sticky → muere; sin animaciones adentro → muere; sin
     will-change → muere; con fondo opaco → muere. Y al revés: sin pin → VIVE, y
     con el MISMO pin cortado unos px antes del borde inferior → VIVE.

   La lectura: iOS 26 sostiene la barra minimizada (la de vidrio) sólo mientras la
   franja de pantalla donde vive la barra tenga contenido que scrollee de verdad. Un
   pin a 100svh se la deja congelada y Safari vuelve a la barra sólida expandida.
   Por eso #stack nunca falló: .scard es 60vh a top:74 y siempre deja página
   moviéndose abajo. Los pins de pantalla completa cortan una "banda viva" al final
   (--liveband). NO subir esos pines a 100svh/100lvh sin re-testear.

   --liveband: EL UMBRAL ESTÁ MEDIDO EN DEVICE, calibrando con ?band=NN sobre
   #porque (iPhone, iOS 26): 40px mantiene el vidrio, 20px lo rompe. O sea que el
   piso real cae entre 20 y 40, y 40 es el primer escalón verificado — el doble del
   último valor que falla. NO BAJARLO. Si alguna vez hay que tocarlo, se recalibra
   en device, no se estima: es una constante empírica del navegador, no de diseño.
   El término 6svh no es decorativo: en pantallas más altas la barra de Safari
   también es más alta, así que la banda acompaña; el clamp la fija en 40 en las
   cortas (iPhone SE) y la topea en 68 en las muy largas. */
:root{--liveband:clamp(40px,6svh,68px)}
/* ---------- (sigue la nota del vidrio) ----------
   NOTA sobre el hallazgo viejo ("el asesino es position:sticky ESPECÍFICAMENTE",
   del sitio astro): el bisect lo desmiente como explicación — a viewport completo
   fixed y sticky mueren igual. Queda SIN VERIFICAR si sticky agrega algún problema
   propio con la banda viva puesta, así que el motor por fixed se mantiene tal cual:
   funciona y está probado. Si algún día se quiere simplificar y volver a sticky
   nativo, hay que testearlo en device primero — no asumir ni una cosa ni la otra.

   EN TÁCTIL (html.tpin, lo pone el motor de glass en main.js con pointer coarse)
   los sticky se neutralizan acá (pasan a relative) y el motor addTpin los clava por
   fixed. En pointer fine no cambia nada: sticky nativo (el vidrio es problema sólo
   de iOS/iPadOS 26). top:auto neutraliza el top del sticky. */
html.tpin .stack-wrap,
html.tpin .stack--mstk .stack-wrap,
html.tpin .porque--pinned .porque__sticky,
html.tpin .porque--vscroll .porque__sticky{position:relative;top:auto}
/* SCROLL ANCHORING vs. los pines por fixed: al conmutar flujo→fixed→absolute por
   frame, Chromium "corrige" el scroll para fijar su nodo-ancla y el reajuste se
   realimenta con la conmutación (te clava en el fondo). Apagarlo en el scroller
   raíz mata el tira y afloja. No-op en Safari; solo táctil. */
html.tpin{overflow-anchor:none}
/* cuando el motor los fija (data-tpin + position:fixed inline) van sobre las
   secciones (z10) pero DEBAJO del header (z40) y del menú (z39). will-change los
   promueve a capa GPU: un fixed con contenido animado adentro sin promover sufre
   el repaint-por-scroll de iOS y traba las animaciones internas. */
html.tpin [data-tpin]{z-index:30;box-sizing:border-box;will-change:transform}
/* el offset de profundidad del apilado desktop (.scard top negativo) desplazaría
   la posición de flujo de cada card y engancharía el pin en un punto distinto.
   En táctil el offset lo da el scale del driver, no el top. */
html.tpin .stack--mstk .scard{top:0}


body{
  font-family:var(--font-body);
  background:var(--bg);
  color:var(--txt);
  -webkit-font-smoothing:antialiased;
  /* clip (no hidden): contiene el desborde horizontal sin volver al body un
     scroll container (que puede impedir que Safari componga tras su barra). */
  overflow-x:hidden;
  overflow-x:clip;
  /* viewport-fit=cover: en apaisado con notch el contenido se compensa a las
     safe areas laterales (el fondo sí llega al borde físico). */
  padding-left:env(safe-area-inset-left,0px);
  padding-right:env(safe-area-inset-right,0px);
}
::selection{background:rgba(2,162,182,0.3)}

/* Scrollbar discreto on-brand, solo con puntero fino. */
@media (pointer:fine){
  ::-webkit-scrollbar{width:11px}
  ::-webkit-scrollbar-track{background:var(--bg)}
  ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:8px;border:3px solid var(--bg)}
  ::-webkit-scrollbar-thumb:hover{background:rgba(2,162,182,.5)}
  html{scrollbar-color:rgba(255,255,255,.18) var(--bg);scrollbar-width:thin}
}

.wrap{width:100%;max-width:1280px;margin:0 auto;padding:0 var(--gutter)}
@media(max-width:680px){.wrap{padding:0 22px}}

.grad-text{color:var(--teal);font-style:normal}
/* ---------- tipografía: display = BanksMiles (marca), body = IBM Plex Sans ----------
   Los títulos y las piezas de marca (números, etiquetas, migas) van en la display; el
   texto corrido, en la de lectura. Sin esta regla los h1–h4 caen al font-family del
   body y la página se ve en IBM Plex: es una sola declaración, así que va acá arriba
   y no repetida en cada componente. */
h1,h2,h3,h4,
.eyebrow,.hpanel--head h2,.hno,.htag,.scard__no,.scard__more,.f108__no,.tstep__no,
.bcol__lbl,.dcrumb,.rnum,.vring__n,.vdash__kpi b,.sc__no,.stepc__num,.callout__eyebrow{
  font-family:var(--font-display);
}
.eyebrow{font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--teal)}
h1{text-wrap:balance}
a:focus-visible,button:focus-visible{outline:2px solid var(--teal);outline-offset:3px;border-radius:6px}

/* ---------- i18n: nodos bilingües conmutados por <html lang> ----------
   Cada texto vive en el HTML en sus dos idiomas con el atributo estándar `lang`.
   El idioma activo se controla en <html lang>; aquí se oculta el que no corresponde.
   Los labels del toggle (.lt) NO llevan atributo lang, así que siempre se ven. */
html[lang="es"] :lang(en){display:none!important}
html[lang="en"] :lang(es){display:none!important}

/* ============================================================
   FONDO — beams (canvas) + veil + vignette. Todo fixed, solo cubre el hero.
   ============================================================ */
/* height 100lvh (viewport GRANDE): cubre la zona de la barra de URL de iOS para
   que su colapso al scrollear no redimensione el canvas (los resizes hacían
   saltar los beams). translateZ promueve la capa (fixed + filter en iOS
   flashea sin esto). blur(12px) CSS = la mitad del "doble blur" del look. */
#energy{position:fixed;inset:0;width:100%;height:100lvh;z-index:0;pointer-events:none;filter:blur(12px);transform:translateZ(0)}

.bg-veil{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(60% 50% at 78% 18%, rgba(2,162,182,0.18), transparent 60%),
    radial-gradient(55% 55% at 12% 30%, rgba(0,74,144,0.22), transparent 62%),
    radial-gradient(45% 40% at 60% 90%, rgba(195,208,33,0.08), transparent 60%);
}
.bg-vignette{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(120% 100% at 50% 0%, transparent 55%, rgba(0,0,0,0.55) 100%)}

/* Vidrio de Safari 26 (iOS/iPadOS): una capa fija full-bleed con filter de GPU
   (#energy) tocando el borde inferior hace que la barra flotante de Safari se
   lea OPACA en vez de translúcida (no compone el contenido detrás). El fix es
   recortar las capas 140px antes del borde + un fade de máscara para que el
   corte no se vea como línea. En un iPhone real esa franja queda OCULTA bajo la
   barra de URL; por eso se limita a teléfonos (max-width:500px): en pantallas
   ≥500px (desktop angosto, tablets, emulador sin barra) la franja se vería como
   una banda negra rota, así que ahí NO se aplica y el fondo va full-bleed. */
@media (pointer:coarse) and (max-width:500px){
  /* Cada capa se recorta 90px antes del borde (la franja que la barra de Safari
     tapa). El fade de máscara es IDÉNTICO en las tres capas (mismo largo, mismo
     punto de arranque) y con un stop intermedio (ease) para que la transición
     sea una sola rampa suave — sin ella, largos de fade distintos apilaban dos
     bordes desfasados que se leían como una línea horizontal tenue en OLED. */
  #energy{height:calc(100lvh - 90px);
    -webkit-mask-image:linear-gradient(#000 calc(100% - 96px),rgba(0,0,0,.5) calc(100% - 45px),transparent);
    mask-image:linear-gradient(#000 calc(100% - 96px),rgba(0,0,0,.5) calc(100% - 45px),transparent)}
  .bg-vignette{background:linear-gradient(to top, rgba(0,0,0,0.10) 0%, rgba(0,0,0,0.18) 9%, transparent 26%)}
  .bg-veil,.bg-vignette{bottom:90px;
    -webkit-mask-image:linear-gradient(#000 calc(100% - 96px),rgba(0,0,0,.5) calc(100% - 45px),transparent);
    mask-image:linear-gradient(#000 calc(100% - 96px),rgba(0,0,0,.5) calc(100% - 45px),transparent)}
}

/* ============================================================
   BOTONES
   ============================================================ */
.btn{display:inline-flex;align-items:center;gap:9px;border-radius:100px;font-weight:600;font-size:15px;text-decoration:none;cursor:pointer;border:0;
  transition:transform .25s ease,box-shadow .25s ease,background-position .45s ease}
.btn-primary{padding:14px 26px;color:var(--on-accent);background:var(--grad);background-size:135% 100%;background-position:0 0;box-shadow:0 8px 28px -14px rgba(2,162,182,0.4)}
.btn-primary:hover{transform:translateY(-2px);background-position:96% 0;box-shadow:0 12px 36px -14px rgba(2,162,182,0.5)}
.btn-ghost{padding:13px 24px;color:var(--txt);background:rgba(255,255,255,0.04);border:1px solid var(--line)}
.btn-ghost:hover{border-color:rgba(255,255,255,0.32);transform:translateY(-2px)}
.btn .arr{transition:transform .25s}
.btn:hover .arr{transform:translateX(4px)}

/* ============================================================
   HEADER
   ============================================================ */
.header{position:fixed;top:0;left:0;right:0;z-index:40;border-bottom:1px solid transparent;
  transition:background .35s ease,border-color .35s ease}
.header.scrolled{background:rgba(6,9,15,.72);border-bottom-color:rgba(255,255,255,.10);
  -webkit-backdrop-filter:blur(16px) saturate(150%)}
@supports (backdrop-filter:blur(1px)){
  .header.scrolled{backdrop-filter:blur(16px) saturate(150%)}
}
/* header fixed = relativo al viewport físico: compensa las safe areas por su
   cuenta (notch en apaisado, viewport-fit=cover). */
.header__in{max-width:1280px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;height:74px;
  padding:0 calc(var(--gutter) + env(safe-area-inset-right,0px)) 0 calc(var(--gutter) + env(safe-area-inset-left,0px))}

.brand{display:flex;align-items:center;gap:12px;text-decoration:none}
.brand .logo-mark{height:34px;width:auto;display:block}
.brand .wm{height:20px;width:auto;display:block;color:#fff}

.nav{display:flex;gap:38px}
.nav a{position:relative;padding:9px 0;color:var(--muted);text-decoration:none;font-size:15px;font-weight:500;transition:color .2s}
.nav a::after{content:"";position:absolute;left:0;right:0;bottom:4px;height:1.5px;border-radius:2px;
  background:linear-gradient(90deg,var(--teal),var(--lime));transform:scaleX(0);transform-origin:left;
  transition:transform .35s cubic-bezier(.22,1,.36,1)}
.nav a:hover{color:#fff}
.nav a:hover::after{transform:scaleX(1)}

.header__cta{display:flex;align-items:center;gap:18px}
.header__cta .btn-primary{padding:11px 22px;font-size:14px}

/* toggle de idioma = un solo link al idioma opuesto (en ES muestra "EN" y viceversa).
   El label activo lo decide el :lang del ancestro; los .lt heredan tipografía/color del toggle. */
.langtoggle{display:inline-flex;align-items:center;padding:9px 8px;line-height:1;text-decoration:none;
  font-size:13px;font-weight:700;letter-spacing:.08em;color:var(--muted);transition:color .2s ease}
.langtoggle:hover{color:#fff}
.langtoggle .lt{display:none}
:lang(es) .langtoggle .lt--en{display:inline}
:lang(en) .langtoggle .lt--es{display:inline}

/* ---------- menú móvil ---------- */
.navtoggle{display:none}
.navtoggle span{display:block;width:22px;height:2px;border-radius:2px;background:#fff;margin:0 auto;transition:transform .3s ease,opacity .2s ease}
.navtoggle.is-open span:nth-child(1){transform:translateY(3.5px) rotate(45deg)}
.navtoggle.is-open span:nth-child(2){transform:translateY(-3.5px) rotate(-45deg)}

/* display:none real al cerrar (vidrio de Safari): un overlay casi opaco cubriendo
   el viewport, aun con opacity:0, es "fuente de tinte" que vuelve la barra una
   placa muerta. El JS togglea .shown alrededor de la transición de .open. */
.mobilemenu{position:fixed;inset:0;z-index:39;background:rgba(6,9,15,.985);opacity:0;visibility:hidden;display:none;
  transition:opacity .4s ease,visibility .4s ease;
  -webkit-backdrop-filter:blur(22px) saturate(140%)}
@supports (backdrop-filter:blur(1px)){
  .mobilemenu{background:rgba(6,9,15,.96);backdrop-filter:blur(22px) saturate(140%)}
}
.mobilemenu.shown{display:block}
.mobilemenu.open{opacity:1;visibility:visible}
.mobilemenu__in{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:6px;padding:0 var(--gutter)}
.mm__link{color:#fff;text-decoration:none;font-weight:800;font-size:clamp(30px,8.5vw,50px);letter-spacing:-.02em;line-height:1.18;padding:8px 0;
  opacity:0;transform:translateY(14px);transition:opacity .5s ease,transform .5s ease,color .2s}
.mobilemenu.open .mm__link{opacity:1;transform:none}
.mobilemenu.open .mm__link:nth-child(1){transition-delay:.06s}
.mobilemenu.open .mm__link:nth-child(2){transition-delay:.12s}
.mobilemenu.open .mm__link:nth-child(3){transition-delay:.18s}
.mm__link:hover{color:var(--teal)}
.mm__cta{margin-top:28px;font-size:16px;padding:15px 32px;opacity:0;transition:opacity .5s ease .24s,transform .25s ease,box-shadow .25s ease}
.mobilemenu.open .mm__cta{opacity:1}
.mm__lang{margin-top:30px;opacity:0;transition:opacity .5s ease .3s}
.mobilemenu.open .mm__lang{opacity:1}

@media(max-width:1024px){
  .nav{display:none}
  .header__cta{display:none}
  .navtoggle{display:inline-flex;flex-direction:column;justify-content:center;gap:5px;width:44px;height:44px;border:0;background:none;cursor:pointer;padding:0;position:relative;z-index:50}
}
@media(max-width:680px){
  .header__in{height:60px}
  .brand .logo-mark{height:25px}
  .brand .wm{height:15px}
  .navtoggle{width:40px;height:40px}
}
@media(prefers-reduced-motion:reduce){
  .mm__link,.mm__cta,.mm__lang{transition:none;opacity:1;transform:none}
  .mobilemenu{transition:none}
}

/* ============================================================
   HERO
   ============================================================ */
/* 100svh + padding-bottom safe-area: en iOS compensa la franja de la barra
   flotante de Safari, para que el pie del frame (CTAs) no quede bajo el vidrio. */
.hero{position:relative;z-index:10;min-height:100svh;display:flex;align-items:center;
  padding-bottom:env(safe-area-inset-bottom,0px)}
.hero__in{padding-top:90px;padding-bottom:120px;max-width:1000px}
.hero h1{
  font-family:var(--font-display);
  font-weight:800;letter-spacing:-0.035em;line-height:0.96;color:#fff;
  font-size:min(clamp(36px,5.4vw,72px),11vh);margin:22px 0 0;
}
.hero h1 .ln{display:block;overflow:hidden;padding-bottom:0.4em;margin-bottom:-0.36em}
.hero h1 .ln > span{display:block}
.hero__sub{margin-top:30px;max-width:50ch;font-size:clamp(17px,1.5vw,21px);line-height:1.6;color:var(--muted);font-weight:400;text-wrap:pretty}
.hero__cta{margin-top:40px;display:flex;gap:16px;flex-wrap:wrap}
@media(min-width:921px) and (max-height:820px){
  .hero__in{padding-top:76px;padding-bottom:90px}
  .hero__sub{margin-top:22px}
  .hero__cta{margin-top:30px}
}
@media(max-width:680px){
  .hero__in{padding-top:76px;padding-bottom:90px}
  .hero__sub{margin-top:22px}
  .hero__cta{margin-top:30px}
}

/* Entrada del hero por CSS puro: se activa con html.anim (que el head pone
   salvo prefers-reduced-motion). Sin JS/animación, el contenido está visible. */
.anim .hero h1 .ln > span{opacity:0;transform:translateY(105%);animation:heroLn 1s cubic-bezier(.22,1,.36,1) forwards}
/* stagger de 2 líneas robusto al bilingüe: el h1 tiene 4 .ln (ES+EN por línea),
   solo una de cada par es visible por :lang. Los hijos 3 y 4 son la 2ª línea. */
.anim .hero h1 .ln:nth-child(3) > span,
.anim .hero h1 .ln:nth-child(4) > span{animation-delay:.22s}
.anim .hero [data-hero]{opacity:0;animation:heroFade .8s ease forwards}
.anim .hero [data-hero="eyebrow"]{animation-delay:.05s}
.anim .hero [data-hero="sub"]{animation-delay:.5s}
.anim .hero [data-hero="cta"]{animation-delay:.7s}
@keyframes heroLn{to{opacity:1;transform:none}}
@keyframes heroFade{to{opacity:1}}
@media(prefers-reduced-motion:reduce){
  .anim .hero h1 .ln>span,.anim .hero [data-hero]{opacity:1;transform:none;animation:none}
}


/* ===== SECCIONES migradas desde teravolta-landing-oficial (manifiesto → footer) ===== */
/* ---------- generic section + scroll reveal ---------- */
.section{position:relative;z-index:10;background:var(--bg);padding:100px 0}
.sec-head{max-width:780px;margin-bottom:60px}
.sec-head h2{font-weight:800;font-size:clamp(30px,4.4vw,62px);line-height:1.04;letter-spacing:-.03em;margin-top:16px;color:#fff}
/* polish tipográfico: balance en titulares (líneas parejas), pretty en prosa (evita huérfanos) */
h1,h2,h3{text-wrap:balance}
.hero__sub,.dhero__sub,.cinfo__sub,.sec-head p,.cta__sub,.dtl__cap,.callout__sub,.enfoque-intro__sub{text-wrap:pretty}
/* reveal por transición CSS (compositor) + clase .is-in vía IntersectionObserver: robusto ante rAF throttled */
.anim [data-reveal]{opacity:0;transform:translateY(28px);transition:opacity .85s cubic-bezier(.22,1,.36,1),transform .85s cubic-bezier(.22,1,.36,1)}
.anim [data-reveal].is-in{opacity:1;transform:none}

/* ---------- manifiesto (text reveal on scroll) ---------- */
.manifesto{position:relative;z-index:10;background:var(--bg)}
.manifesto .wrap{min-height:135vh;display:flex;align-items:center}
/* tablet + móvil: el manifiesto no usa el alto de scrub de desktop (135vh se vuelve una sección casi vacía altísima en portrait) */
@media(max-width:1024px){.manifesto .wrap{min-height:auto;padding:clamp(80px,12vh,120px) var(--gutter)}}
.reveal-words{font-family:'BanksMiles',sans-serif;font-weight:800;letter-spacing:-.03em;line-height:1.08;text-wrap:balance;
  font-size:clamp(30px,5.4vw,80px);max-width:17ch;color:#fff}
.rw{opacity:.15;transition:opacity .15s linear}
.rwg{color:var(--teal)}

/* ---------- bento + spotlight cards (21st.dev) ---------- */
.bento{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:1fr;gap:18px}
.sc{position:relative;overflow:hidden;display:flex;flex-direction:column;border-radius:22px;
  border:1px solid var(--line);background:rgba(255,255,255,.025);padding:30px;text-decoration:none;color:#fff;
  min-height:215px;transition:transform .4s cubic-bezier(.22,1,.36,1),border-color .4s,background .4s}
.sc:hover{transform:translateY(-5px);border-color:rgba(2,162,182,.4);background:rgba(255,255,255,.045)}
.sc::after{content:"";position:absolute;left:0;top:0;height:3px;width:42%;border-radius:3px;transform:scaleX(0);transform-origin:left;
  background:linear-gradient(90deg,var(--teal),var(--lime));transition:transform .5s cubic-bezier(.22,1,.36,1)}
.sc:hover::after{transform:scaleX(1)}
.sc--feature{grid-column:span 2;grid-row:span 2;justify-content:flex-end}
@media(max-width:860px){.bento{grid-template-columns:1fr 1fr}.sc--feature{grid-column:span 2;grid-row:auto}}
@media(max-width:560px){.bento{grid-template-columns:1fr}.sc--feature{grid-column:auto}}
.sc__no{position:relative;font-family:'BanksMiles';font-weight:800;font-size:13px;letter-spacing:.22em;color:var(--teal)}
.sc h3{position:relative;font-weight:800;font-size:19px;line-height:1.16;letter-spacing:-.01em;margin-top:14px}
.sc--feature h3{font-size:clamp(24px,2.5vw,36px);margin-top:auto}
.sc p{position:relative;margin-top:12px;color:var(--muted);font-size:14.5px;line-height:1.55}
.sc--feature p{font-size:16.5px;max-width:42ch}
.sc__more{position:relative;margin-top:20px;font-weight:700;font-size:13.5px;display:inline-flex;align-items:center;gap:7px;color:#fff}
.sc__more i{font-style:normal;color:var(--lime);transition:transform .3s}
.sc:hover .sc__more i{transform:translateX(5px)}
.sc__tag{position:absolute;top:30px;right:30px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;
  color:var(--lime);background:rgba(195,208,33,.12);padding:6px 13px;border-radius:100px}

/* ---------- horizontal showcase (21st.dev "Horizontal Scroll Carousel") ---------- */
.hsec{position:relative;z-index:10;height:460vh;background:var(--bg)}
.hsticky{position:sticky;top:0;height:100vh;display:flex;align-items:center;overflow:hidden}
.htrack{display:flex;gap:28px;padding:0 var(--gutter);will-change:transform}
.hpanel{flex:0 0 64vw;height:62vh;border-radius:24px;border:1px solid var(--line);background:rgba(255,255,255,.025);
  padding:48px 54px;display:grid;grid-template-columns:1fr 1.08fr;gap:40px;align-items:stretch;position:relative;overflow:hidden;
  transition:border-color .5s ease,background .5s ease}
.hpanel.is-active{border-color:rgba(2,162,182,.32);background-color:rgba(255,255,255,.04)}
.hpanel::after{content:"";position:absolute;left:0;top:0;height:3px;width:36%;background:linear-gradient(90deg,var(--teal),var(--lime))}
.hpanel__text{display:flex;flex-direction:column;justify-content:space-between;position:relative;z-index:2;min-width:0}
.hno{position:relative;font-weight:800;font-size:14px;letter-spacing:.22em;color:var(--teal)}
.hpanel h3{position:relative;font-weight:800;font-size:clamp(26px,3vw,46px);line-height:1.05;letter-spacing:-.02em;max-width:14ch}
.hpanel p{position:relative;color:var(--muted);font-size:16.5px;line-height:1.55;max-width:38ch}
.hmore{position:relative;font-weight:700;font-size:14px;color:#fff;display:inline-flex;gap:7px;align-items:center;text-decoration:none;align-self:flex-start}
.hmore i{font-style:normal;color:var(--lime);transition:transform .3s}
.hmore:hover i{transform:translateX(5px)}
.hpanel__head{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.htag{font-size:12.5px;font-weight:600;letter-spacing:.01em;color:var(--lime);display:inline-flex;align-items:center;gap:9px}
.htag::before{content:"";width:18px;height:2px;border-radius:2px;background:var(--lime)}

/* ---- right-side visuals (21st.dev "Animated Card Diagram / Card 1 / Geometric") recolored ---- */
.hpanel__viz{position:relative;border-radius:18px;overflow:hidden;background:rgba(8,12,20,.5);border:1px solid var(--line);min-width:0}
/* La viz del carrusel es SIEMPRE cuadrada: el lado = el menor entre el ancho de la columna (100%)
   y la altura útil del panel (62vh − padding vertical), así el SVG nunca se recorta ni se estira,
   sin importar el ancho de la ventana. Centrada dentro de su celda. No afecta a los héroes de subpágina. */
.hpanel .hpanel__viz{aspect-ratio:1/1;width:min(100%,62vh - 96px);align-self:center;justify-self:center;max-height:100%}
.hviz__grid{position:absolute;inset:0;background-image:linear-gradient(to right,rgba(2,162,182,.10) 1px,transparent 1px),linear-gradient(to bottom,rgba(2,162,182,.10) 1px,transparent 1px);background-size:22px 22px;background-position:center;
  -webkit-mask-image:radial-gradient(ellipse 60% 60% at 50% 45%,#000 55%,transparent 100%);mask-image:radial-gradient(ellipse 60% 60% at 50% 45%,#000 55%,transparent 100%);opacity:.7}
.hviz__glow{position:absolute;inset:0;background:radial-gradient(ellipse 60% 55% at 50% 38%,rgba(2,162,182,.18),transparent 70%);opacity:.5;transition:opacity .6s}
.hpanel.is-active .hviz__glow{opacity:1}

/* 01 informe */
.vdoc{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:11px;padding:34px 38px}
.vdoc__bar{display:flex;gap:7px;margin-bottom:8px}
.vdoc__bar span{height:9px;border-radius:4px;background:linear-gradient(90deg,var(--teal),var(--teal2))}
.vdoc__bar span:nth-child(1){width:34px}.vdoc__bar span:nth-child(2){width:18px;background:var(--lime)}.vdoc__bar span:nth-child(3){width:24px;opacity:.5}
.vdoc__lines{display:flex;flex-direction:column;gap:11px}
.vdoc__lines span{height:8px;border-radius:5px;background:rgba(255,255,255,.14);width:0;transition:width .7s cubic-bezier(.22,1,.36,1)}
.vdoc__badge{align-self:flex-start;margin-top:10px;font-size:12px;font-weight:700;color:var(--on-accent);background:var(--grad);padding:5px 12px;border-radius:100px;opacity:0;transform:translateY(8px);transition:all .5s ease .5s}
.anim .hpanel.is-active .vdoc__lines span{width:var(--w)}
.anim .hpanel.is-active .vdoc__badge{opacity:1;transform:none}

/* 01 informe — SVG "captura en terreno → informe completo" (reemplaza al mock .vdoc en esta card) */
.vrep{position:absolute;inset:0}
.vrep svg{display:block;width:100%;height:100%}
/* primitivas de animación gatilladas por .hpanel.is-active (home) / .dviz.live (subpágina) */
.vrep__draw{stroke-dasharray:var(--len,300);stroke-dashoffset:var(--len,300);transition:stroke-dashoffset 1.1s cubic-bezier(.22,1,.36,1) var(--d,0s)}
.vrep__wipe{opacity:0;transform:scaleX(0);transform-box:fill-box;transform-origin:left center;transition:transform .7s cubic-bezier(.22,1,.36,1) var(--d,0s),opacity .5s ease var(--d,0s)}
.vrep__pop{opacity:0;transform:scale(0);transform-box:fill-box;transform-origin:center;transition:transform .55s cubic-bezier(.34,1.56,.64,1) var(--d,0s),opacity .4s ease var(--d,0s)}
.vrep__fade{opacity:0;transition:opacity .6s ease var(--d,0s)}
.vrep__spark{opacity:0}
.vrep__pulse{opacity:0}
.vrep__sealglow{opacity:0}
.anim .hpanel.is-active .vrep__draw,.anim .dviz.live .vrep__draw{stroke-dashoffset:0}
.anim .hpanel.is-active .vrep__wipe,.anim .dviz.live .vrep__wipe{opacity:1;transform:scaleX(1)}
.anim .hpanel.is-active .vrep__pop,.anim .dviz.live .vrep__pop{opacity:1;transform:scale(1)}
.anim .hpanel.is-active .vrep__fade,.anim .dviz.live .vrep__fade{opacity:1}
.anim .hpanel.is-active .vrep__flow,.anim .dviz.live .vrep__flow{animation:vrepFlow 1s linear .9s infinite}
.anim .hpanel.is-active .vrep__spark,.anim .dviz.live .vrep__spark{animation:vrepSpark 2.4s cubic-bezier(.5,0,.5,1) 1.1s infinite}
.anim .hpanel.is-active .vrep__pulse,.anim .dviz.live .vrep__pulse{animation:vrepPulse 2s ease-out 1.5s infinite}
.anim .hpanel.is-active .vrep__sealglow,.anim .dviz.live .vrep__sealglow{animation:vrepSeal 2.6s ease-in-out 1.7s infinite}
@keyframes vrepFlow{to{stroke-dashoffset:-16}}
@keyframes vrepSpark{0%{opacity:0;transform:translateX(0)}12%{opacity:1}80%{opacity:1}100%{opacity:0;transform:translateX(37px)}}
@keyframes vrepPulse{0%{opacity:.9;transform:scale(1);transform-box:fill-box;transform-origin:center}70%,100%{opacity:0;transform:scale(3.4);transform-box:fill-box;transform-origin:center}}
@keyframes vrepSeal{0%,100%{opacity:.18}50%{opacity:.4}}

/* 02 automatización */
/* menos tareas repetitivas — "horas ahorradas" ring + checklist */
.vauto{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:52px;padding:0 44px}
.vmetric{display:flex;flex-direction:column;align-items:center;gap:16px}
.vring{position:relative;width:158px;height:158px;flex:0 0 158px}
.vring svg{width:158px;height:158px;transform:rotate(-90deg)}
.vring circle{fill:none;stroke-width:7}
.vring__t{stroke:rgba(255,255,255,.09)}
.vring__p{stroke:url(#vringg);stroke-dasharray:251;stroke-dashoffset:251;stroke-linecap:round;transition:stroke-dashoffset 1.5s cubic-bezier(.22,1,.36,1);filter:drop-shadow(0 0 5px rgba(2,162,182,.4))}
.vring__n{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff}
.vring__num{display:inline-block;min-width:1.3em;text-align:center;font-weight:800;font-size:46px;line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.vring__n i{font-style:normal;font-weight:700;font-size:21px;color:var(--teal2);margin-left:2px;transform:translateY(.58em)}
.vmetric__cap{margin:0;font-size:12px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);opacity:0;transform:translateY(6px);transition:opacity .6s ease,transform .6s ease}
.vtasks{list-style:none;display:flex;flex-direction:column;gap:18px;min-width:0}
.vtasks li{display:flex;align-items:center;gap:13px;font-size:15.5px;font-weight:500;color:rgba(255,255,255,.8);opacity:0;transform:translateX(12px);transition:opacity .5s ease,transform .5s cubic-bezier(.22,1,.36,1)}
.vchk{width:24px;height:24px;border-radius:8px;border:1.5px solid rgba(2,162,182,.55);background:rgba(2,162,182,.07);position:relative;flex:0 0 24px;transition:background .4s ease,border-color .4s ease,box-shadow .4s ease}
.vchk::after{content:"";position:absolute;left:50%;top:45%;width:6px;height:11px;border:solid #fff;border-width:0 2.5px 2.5px 0;transform:translate(-50%,-50%) rotate(45deg) scale(0);transition:transform .4s cubic-bezier(.34,1.56,.64,1)}
/* móvil: la viz estaba pensada para un panel ancho; achicar para que las tareas no se corten */
@media(max-width:900px){
  .vauto{gap:24px;padding:0 18px}
  .vring,.vring svg{width:112px;height:112px}
  .vring{flex:0 0 112px}
  .vring__num{font-size:34px}.vring__n i{font-size:16px}
  .vmetric{gap:11px}.vmetric__cap{font-size:10.5px;letter-spacing:.1em}
  .vtasks{gap:13px}
  .vtasks li{font-size:13px;gap:10px}
  .vchk{width:21px;height:21px;flex:0 0 21px}
}
.anim .hpanel.is-active .vring__p,.anim .dviz.live .vring__p{stroke-dashoffset:0}
.anim .hpanel.is-active .vmetric__cap,.anim .dviz.live .vmetric__cap{opacity:1;transform:none;transition-delay:1.3s}
.anim .hpanel.is-active .vtasks li,.anim .dviz.live .vtasks li{opacity:1;transform:none}
.anim .hpanel.is-active .vtasks li:nth-child(1),.anim .dviz.live .vtasks li:nth-child(1){transition-delay:.35s}
.anim .hpanel.is-active .vtasks li:nth-child(2),.anim .dviz.live .vtasks li:nth-child(2){transition-delay:.7s}
.anim .hpanel.is-active .vtasks li:nth-child(3),.anim .dviz.live .vtasks li:nth-child(3){transition-delay:1.05s}
.anim .hpanel.is-active .vchk::after,.anim .dviz.live .vchk::after{transform:translate(-50%,-50%) rotate(45deg) scale(1)}
.anim .hpanel.is-active .vtasks li .vchk,.anim .dviz.live .vtasks li .vchk{background:var(--teal);border-color:var(--teal);box-shadow:0 0 14px -3px rgba(2,162,182,.7)}
.anim .hpanel.is-active .vtasks li:nth-child(1) .vchk,.anim .dviz.live .vtasks li:nth-child(1) .vchk{transition-delay:.55s}
.anim .hpanel.is-active .vtasks li:nth-child(2) .vchk,.anim .dviz.live .vtasks li:nth-child(2) .vchk{transition-delay:.9s}
.anim .hpanel.is-active .vtasks li:nth-child(3) .vchk,.anim .dviz.live .vtasks li:nth-child(3) .vchk{transition-delay:1.25s}
.anim .hpanel.is-active .vtasks li:nth-child(1) .vchk::after,.anim .dviz.live .vtasks li:nth-child(1) .vchk::after{transition-delay:.65s}
.anim .hpanel.is-active .vtasks li:nth-child(2) .vchk::after,.anim .dviz.live .vtasks li:nth-child(2) .vchk::after{transition-delay:1s}
.anim .hpanel.is-active .vtasks li:nth-child(3) .vchk::after,.anim .dviz.live .vtasks li:nth-child(3) .vchk::after{transition-delay:1.35s}

/* 03 indicadores */
.vdash{position:absolute;inset:0;padding:30px 34px;display:flex;flex-direction:column;justify-content:flex-end}
.vdash__kpi{position:absolute;top:26px;left:34px;display:flex;flex-direction:column}
.vdash__kpi b{font-weight:800;font-size:30px;letter-spacing:-.02em;color:var(--teal)}
.vdash__kpi span{font-size:12px;color:var(--muted)}
.vdash__line{position:absolute;left:0;right:0;top:34%;width:100%;height:66%}
.vdash__area{fill:rgba(2,162,182,.12)}
.vdash__stroke{fill:none;stroke:var(--teal);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:600;stroke-dashoffset:600;transition:stroke-dashoffset 1.3s ease}
.vbars{display:flex;align-items:flex-end;gap:9px;height:42%}
.vbars span{flex:1;height:6%;border-radius:5px 5px 0 0;background:linear-gradient(180deg,var(--teal),rgba(38,175,192,.35));transition:height .7s cubic-bezier(.22,1,.36,1)}
.vbars span:nth-child(6){background:linear-gradient(180deg,var(--lime),rgba(195,208,33,.3))}
.anim .hpanel.is-active .vdash__stroke{stroke-dashoffset:0}
.anim .hpanel.is-active .vbars span{height:var(--h)}
.anim .hpanel.is-active .vbars span:nth-child(1){transition-delay:.05s}
.anim .hpanel.is-active .vbars span:nth-child(2){transition-delay:.1s}
.anim .hpanel.is-active .vbars span:nth-child(3){transition-delay:.15s}
.anim .hpanel.is-active .vbars span:nth-child(4){transition-delay:.2s}
.anim .hpanel.is-active .vbars span:nth-child(5){transition-delay:.25s}
.anim .hpanel.is-active .vbars span:nth-child(6){transition-delay:.3s}
.anim .hpanel.is-active .vbars span:nth-child(7){transition-delay:.35s}

/* 04 información */
.vsearch{position:absolute;inset:0;display:flex;flex-direction:column;gap:14px;padding:30px 34px;justify-content:center}
.vsearch__bar{display:flex;align-items:center;gap:10px;padding:12px 15px;border-radius:12px;background:rgba(255,255,255,.05);border:1px solid var(--line)}
.vsearch__bar svg{width:18px;height:18px;color:var(--teal);flex:0 0 18px}
.vsearch__q{font-size:14px;color:#fff;white-space:nowrap;overflow:hidden;width:0;transition:width .9s steps(18,end)}
.vcaret{width:1.5px;height:16px;background:var(--lime);opacity:0;animation:vblink 1s step-end infinite}
@keyframes vblink{50%{opacity:0}0%,100%{opacity:1}}
.vresults{list-style:none;display:flex;flex-direction:column;gap:12px}
/* proyectos en curso — barras de progreso por etapa */
.vproj{display:flex;flex-direction:column;gap:10px;padding:13px 15px;border-radius:12px;background:rgba(255,255,255,.03);border:1px solid var(--line);opacity:0;transform:translateY(10px);transition:opacity .5s ease,transform .5s cubic-bezier(.22,1,.36,1)}
.vproj--done{--c:var(--teal);--c2:var(--teal2);--p:100%}
.vproj--prog{--c:var(--lime);--c2:#dbe24f;--p:56%}
.vproj--todo{--c:#62727a;--c2:#808f97;--p:12%}
.vproj__head{display:flex;align-items:center;gap:9px}
.vproj__dot{width:9px;height:9px;border-radius:50%;background:var(--c);box-shadow:0 0 8px -1px var(--c);flex:0 0 9px}
.vproj__head b{font-size:12px;font-weight:600;letter-spacing:.01em;color:rgba(255,255,255,.82)}
.vproj__track{position:relative;height:7px;border-radius:5px;background:rgba(255,255,255,.08);overflow:visible}
.vproj__track i{position:relative;display:block;height:100%;width:0;border-radius:5px;background:linear-gradient(90deg,var(--c2),var(--c));transition:width 1.1s cubic-bezier(.22,1,.36,1)}
.vproj__track i::after{content:"";position:absolute;right:0;top:50%;width:11px;height:11px;border-radius:50%;background:var(--c);transform:translate(50%,-50%);box-shadow:0 0 0 3px rgba(10,15,20,.55),0 0 12px -1px var(--c);opacity:0;transition:opacity .4s ease}
.vproj--prog .vproj__track i::after{animation:vpulse 1.9s ease-in-out infinite 2.1s}
@keyframes vpulse{0%,100%{box-shadow:0 0 0 3px rgba(10,15,20,.55),0 0 10px -1px var(--c)}50%{box-shadow:0 0 0 3px rgba(10,15,20,.55),0 0 17px 2px var(--c)}}
.vstages{display:flex;justify-content:space-between;font-size:10px;letter-spacing:.02em;color:var(--muted);opacity:0;transform:translateY(6px);transition:opacity .5s ease,transform .5s ease}
.vstages span:nth-child(2){text-align:center}.vstages span:last-child{text-align:right}
.anim .hpanel.is-active .vsearch__q,.anim .dviz.live .vsearch__q{width:132px}
.anim .hpanel.is-active .vcaret,.anim .dviz.live .vcaret{opacity:1}
.anim .hpanel.is-active .vproj,.anim .dviz.live .vproj{opacity:1;transform:none}
.anim .hpanel.is-active .vproj:nth-child(1),.anim .dviz.live .vproj:nth-child(1){transition-delay:.85s}
.anim .hpanel.is-active .vproj:nth-child(2),.anim .dviz.live .vproj:nth-child(2){transition-delay:1s}
.anim .hpanel.is-active .vproj:nth-child(3),.anim .dviz.live .vproj:nth-child(3){transition-delay:1.15s}
.anim .hpanel.is-active .vproj__track i,.anim .dviz.live .vproj__track i{width:var(--p)}
.anim .hpanel.is-active .vproj:nth-child(1) .vproj__track i,.anim .dviz.live .vproj:nth-child(1) .vproj__track i{transition-delay:1.15s}
.anim .hpanel.is-active .vproj:nth-child(2) .vproj__track i,.anim .dviz.live .vproj:nth-child(2) .vproj__track i{transition-delay:1.35s}
.anim .hpanel.is-active .vproj:nth-child(3) .vproj__track i,.anim .dviz.live .vproj:nth-child(3) .vproj__track i{transition-delay:1.55s}
.anim .hpanel.is-active .vproj__track i::after,.anim .dviz.live .vproj__track i::after{opacity:1;transition-delay:1.5s}
.anim .hpanel.is-active .vstages,.anim .dviz.live .vstages{opacity:1;transform:none;transition-delay:1.75s}

/* 05 a medida */
.vfit{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.vfit__p{position:absolute;border-radius:10px;transition:all .8s cubic-bezier(.22,1,.36,1);will-change:transform,opacity}
.vfit__p--1{width:70px;height:70px;background:rgba(2,162,182,.18);border:1.5px solid var(--teal);transform:translate(-70px,-44px) rotate(-12deg);opacity:0}
.vfit__p--2{width:70px;height:70px;background:rgba(38,175,192,.16);border:1.5px solid var(--teal2);transform:translate(72px,-30px) rotate(14deg);opacity:0}
.vfit__p--3{width:70px;height:70px;background:rgba(195,208,33,.14);border:1.5px solid var(--lime);transform:translate(-60px,54px) rotate(10deg);opacity:0}
.vfit__p--key{width:74px;height:74px;background:var(--grad);box-shadow:0 12px 40px -10px rgba(2,162,182,.55);transform:translate(120px,60px) rotate(24deg) scale(.6);opacity:0;z-index:1}
.vfit__check{position:absolute;left:50%;top:50%;width:150px;height:150px;transform:translate(calc(-50% - 14px),-50%) scale(.85);opacity:0;pointer-events:none;z-index:2}
.vfit__check path{fill:none;stroke:#fff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:35;stroke-dashoffset:35;filter:drop-shadow(0 2px 7px rgba(0,0,0,.3))}
/* solución a medida: assemble the 2×2 grid → the gradient tile consumes the rest → white checkmark slides + draws in */
.anim .hpanel.is-active .vfit__p--1,.anim .dviz.live .vfit__p--1{animation:vfit-tl 2.7s cubic-bezier(.22,1,.36,1) forwards}
.anim .hpanel.is-active .vfit__p--2,.anim .dviz.live .vfit__p--2{animation:vfit-tr 2.7s cubic-bezier(.22,1,.36,1) forwards}
.anim .hpanel.is-active .vfit__p--3,.anim .dviz.live .vfit__p--3{animation:vfit-bl 2.7s cubic-bezier(.22,1,.36,1) forwards}
.anim .hpanel.is-active .vfit__p--key,.anim .dviz.live .vfit__p--key{animation:vfit-key 2.7s cubic-bezier(.22,1,.36,1) forwards}
.anim .hpanel.is-active .vfit__check,.anim .dviz.live .vfit__check{animation:vfit-check-in .55s cubic-bezier(.34,1.56,.64,1) 2.05s forwards}
.anim .hpanel.is-active .vfit__check path,.anim .dviz.live .vfit__check path{animation:vfit-check-draw .6s ease 2.1s forwards}
@keyframes vfit-tl{0%{transform:translate(-70px,-44px) rotate(-12deg);opacity:0}30%{transform:translate(-38px,-38px) rotate(0);opacity:1}48%{transform:translate(-38px,-38px) rotate(0);opacity:1}70%{transform:translate(-18px,-18px) rotate(0) scale(.8);opacity:0}100%{transform:translate(-18px,-18px) rotate(0) scale(.8);opacity:0}}
@keyframes vfit-tr{0%{transform:translate(72px,-30px) rotate(14deg);opacity:0}30%{transform:translate(38px,-38px) rotate(0);opacity:1}48%{transform:translate(38px,-38px) rotate(0);opacity:1}70%{transform:translate(18px,-18px) rotate(0) scale(.8);opacity:0}100%{transform:translate(18px,-18px) rotate(0) scale(.8);opacity:0}}
@keyframes vfit-bl{0%{transform:translate(-60px,54px) rotate(10deg);opacity:0}30%{transform:translate(-38px,38px) rotate(0);opacity:1}48%{transform:translate(-38px,38px) rotate(0);opacity:1}70%{transform:translate(-18px,18px) rotate(0) scale(.8);opacity:0}100%{transform:translate(-18px,18px) rotate(0) scale(.8);opacity:0}}
@keyframes vfit-key{0%{transform:translate(120px,60px) rotate(24deg) scale(.6);opacity:0}10%{opacity:0}32%{transform:translate(38px,38px) rotate(0) scale(1);opacity:1}48%{transform:translate(38px,38px) rotate(0) scale(1);opacity:1}78%{transform:translate(0,0) rotate(0) scale(2);opacity:1}100%{transform:translate(0,0) rotate(0) scale(2);opacity:1}}
@keyframes vfit-check-in{0%{transform:translate(calc(-50% - 14px),-50%) scale(.85);opacity:0}100%{transform:translate(-50%,-50%) scale(1);opacity:1}}
@keyframes vfit-check-draw{to{stroke-dashoffset:0}}

.hpanel--head{flex:0 0 40vw;border:none;background:none;display:flex;flex-direction:column;justify-content:center;padding-left:4px;overflow:visible}
.hpanel--head.is-active{background:none;border:none}
.hpanel--head::after{display:none}
.hpanel--head h2{font-weight:800;font-size:clamp(30px,4vw,58px);line-height:1.05;letter-spacing:-.03em;margin-top:14px;color:#fff}
.hpanel--head__sub{margin-top:18px;color:var(--muted);font-size:17px;line-height:1.6;max-width:34ch}
.hpanel--head .eyebrow{position:relative}
/* carrusel horizontal -> stack vertical en móvil (mejor en touch que el scroll-jacking pineado).
   El JS del carrusel no corre en ≤900px (guard por innerWidth), y el transform inline se anula con !important. */
/* carrusel horizontal -> rail swipeable con scroll-snap en móvil (21st.dev mobile pattern, touch-native, liviano).
   El JS del carrusel desktop no corre (guard innerWidth>900); en móvil main.js agrega dots + reveal + dispara vizzes. */
@media(max-width:1024px){
  .hsec{height:auto}
  .hsticky{position:static;height:auto;display:block;overflow:visible}
  /* overflow-y:hidden EXPLÍCITO. `overflow-x:auto` sola no deja el otro eje en
     `visible`: el cómputo lo sube a `auto`, y como las tarjetas aún no reveladas
     están en translateY(20px) contra 4px de padding-bottom, el rail quedaba con 16px
     de scroll VERTICAL propio — el "scroll independiente dentro de la tarjeta". El
     padding-bottom:24px deja aire para que ese translate no se clipee al revelarse. */
  .htrack{flex-direction:row;flex-wrap:nowrap;gap:14px;transform:none!important;
    overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;padding:8px var(--gutter) 24px;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  .htrack::-webkit-scrollbar{display:none}
  .hpanel,.hpanel--head{flex:0 0 min(85vw,430px);width:min(85vw,430px);height:auto;scroll-snap-align:center}
  .hpanel{grid-template-columns:1fr;grid-template-rows:auto 1fr;gap:16px}
  /* Cuadrado EXACTO e IDÉNTICO en las 5 tarjetas: lado = ancho útil de la tarjeta, y
     como las 5 miden lo mismo (flex-basis fijo + mismo padding), los 5 cuadrados son
     iguales. Atado SÓLO al ancho a propósito: cualquier término de alto de viewport
     (vh/innerHeight/svh) lo vuelve a acoplar a la barra del navegador, que colapsa y
     expande en pleno scroll — de ahí venía el cuadrado que cambiaba de tamaño solo.
     El ancho no se mueve durante el scroll, así que esto es estable por construcción.
     Que la tarjeta pueda pasarse del alto de pantalla es aceptado: la página scrollea. */
  .hpanel .hpanel__viz{display:block;aspect-ratio:1/1;order:-1;justify-self:center;align-self:start;
    width:100%;height:auto;max-width:100%;min-height:0}
  .hpanel{opacity:0;transform:translateY(20px);transition:opacity .55s cubic-bezier(.22,1,.36,1),transform .55s cubic-bezier(.22,1,.36,1)}
  .hpanel.in{opacity:1;transform:none}
}
@media(max-width:1024px) and (prefers-reduced-motion:reduce){.hpanel{opacity:1;transform:none}}
/* nav del rail (mobile + tablet): flechas prev/next + dots. Solo se ven en ≤1024 (en desktop manda el scroll horizontal). */
.hdots{display:none}
.hnav{display:none}
@media(max-width:1024px){
  .hnav{display:flex;align-items:center;justify-content:center;gap:clamp(12px,4vw,18px);margin-top:22px}
  .hnav__btn{width:46px;height:46px;flex:0 0 46px;border-radius:50%;display:grid;place-items:center;color:#fff;cursor:pointer;
    border:1px solid rgba(255,255,255,.14);background:linear-gradient(160deg,rgba(255,255,255,.08),rgba(255,255,255,.02));
    -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);box-shadow:0 6px 18px -9px rgba(0,0,0,.65);
    transition:transform .25s cubic-bezier(.22,1,.36,1),border-color .25s ease,background .25s ease,box-shadow .25s ease,opacity .25s ease}
  .hnav__btn svg{width:21px;height:21px;display:block}
  .hnav__btn:not(:disabled):hover{border-color:rgba(2,162,182,.6);background:linear-gradient(160deg,rgba(2,162,182,.16),rgba(255,255,255,.03));box-shadow:0 0 0 1px rgba(2,162,182,.3),0 8px 22px -8px rgba(2,162,182,.5)}
  .hnav__btn:not(:disabled):active{transform:scale(.92)}
  .hnav__btn:disabled{opacity:.3;cursor:default;box-shadow:none}
  /* pista de deslizamiento: la flecha "siguiente" late suavemente mientras haya más tarjetas (se apaga al llegar al final) */
  .hnav__btn--next:not(:disabled){border-color:rgba(2,162,182,.42);animation:hnavPulse 2.6s ease-in-out infinite}
  .hdots{display:flex;justify-content:center;gap:8px;margin:0}
  .hdot{width:7px;height:7px;border-radius:50%;border:0;padding:0;background:rgba(255,255,255,.22);cursor:pointer;transition:background .3s ease,width .3s ease}
  .hdot.is-active{width:22px;border-radius:4px;background:var(--grad)}
}
@keyframes hnavPulse{0%,100%{box-shadow:0 0 0 0 rgba(2,162,182,0),0 6px 18px -9px rgba(0,0,0,.65)}50%{box-shadow:0 0 0 5px rgba(2,162,182,.10),0 0 18px -2px rgba(2,162,182,.5)}}
@media(prefers-reduced-motion:reduce){.hnav__btn--next{animation:none}}

/* ---- ajustes de vizzes dentro del carrusel cuadrado en móvil/tablet (solo #resolvemos, no subpáginas) ---- */
@media(max-width:1024px){
  /* menos tareas: apilar anillo + checklist en vertical para que la lista no se recorte a lo ancho */
  .hpanel .vauto{flex-direction:column;gap:20px;padding:18px 20px}
  .hpanel .vtasks{gap:14px}
  /* la información: compactar para que la barra de búsqueda + los 3 proyectos entren completos en el cuadrado */
  .hpanel .vsearch{gap:10px;padding:22px 22px}
  .hpanel .vresults{gap:9px}
  .hpanel .vproj{padding:10px 13px;gap:8px}
  .hpanel .vstages{font-size:9px}
  /* una solución: un poco más pequeña (el diagrama llenaba demasiado la tarjeta) */
  .hpanel .vfit{transform:scale(.82)}
}
/* ============================================================
   MÓVIL ≤560px — reestructura de "Menos tareas" (vauto) y "La información" (vsearch)
   Problema: en el cuadrado (que se encoge con la pantalla) su contenido tenía altura ~fija y se
   recortaba arriba/abajo. Antes intenté un transform:scale con calc(100vw/px) — división longitud/longitud
   que NO tiene soporte fiable en navegadores móviles, así que no hacía nada.
   Solución robusta: dimensionar cada pieza con clamp()+vw (soporte universal). El tamaño baja de forma
   fluida con el ancho, así TODO queda visible y proporcionado entre 320 y 560px, con las animaciones intactas.
   ============================================================ */
@media(max-width:560px){
  /* menos padding lateral -> el cuadrado de la viz gana ancho (y por tanto alto, al ser 1:1) */
  .hpanel{padding:26px 20px}
  .hpanel .vfit{transform:scale(.78)}

  /* --- menos tareas: anillo + checklist, todo fluido --- */
  .hpanel .vauto{gap:clamp(10px,3vw,18px);padding:clamp(10px,3vw,16px)}
  .hpanel .vmetric{gap:clamp(6px,1.6vw,12px)}
  .hpanel .vring,.hpanel .vring svg{width:clamp(64px,21vw,104px);height:clamp(64px,21vw,104px)}
  .hpanel .vring{flex-basis:auto}
  .hpanel .vring__num{font-size:clamp(24px,7.4vw,36px)}
  .hpanel .vring__n i{font-size:clamp(12px,3.4vw,17px)}
  .hpanel .vmetric__cap{font-size:clamp(9px,2.5vw,11px);letter-spacing:.08em}
  .hpanel .vtasks{gap:clamp(9px,2.6vw,15px)}
  .hpanel .vtasks li{font-size:clamp(12px,3.4vw,15px);gap:clamp(8px,2.4vw,12px)}
  .hpanel .vchk{width:clamp(18px,5vw,22px);height:clamp(18px,5vw,22px);flex-basis:clamp(18px,5vw,22px)}

  /* --- la información: barra de búsqueda + 3 proyectos, compactos --- */
  .hpanel .vsearch{gap:clamp(7px,2vw,11px);padding:clamp(12px,3.4vw,20px);justify-content:center}
  .hpanel .vsearch__bar{padding:clamp(8px,2.4vw,12px) clamp(10px,3vw,14px)}
  .hpanel .vsearch__bar svg{width:clamp(14px,4vw,18px);height:clamp(14px,4vw,18px);flex:0 0 auto}
  .hpanel .vsearch__q{font-size:clamp(11px,3.2vw,14px)}
  .hpanel .vresults{gap:clamp(7px,2vw,11px)}
  .hpanel .vproj{padding:clamp(8px,2.4vw,13px) clamp(11px,3vw,15px);gap:clamp(6px,1.8vw,9px)}
  .hpanel .vproj__head b{font-size:clamp(11px,3.1vw,13px)}
  .hpanel .vstages{font-size:clamp(8px,2.3vw,10px)}
  .hpanel .vstages span{white-space:nowrap}
}
/* teléfonos angostos: las etiquetas de etapa se aprietan; la barra de progreso (color + posición) ya
   comunica el estado, así que las ocultamos para que los 3 proyectos entren holgados y prolijos */
@media(max-width:420px){
  .hpanel .vstages{display:none}
}

/* ---------- NUESTRO ENFOQUE — stacking cards (21st.dev "Stacking / Glass Cards") ---------- */
.enfoque{position:relative;z-index:10;background:var(--bg)}
.enfoque-intro{padding:120px var(--gutter) 40px;display:flex;flex-direction:column;justify-content:center}
.enfoque-intro h2{font-weight:800;font-size:clamp(34px,5vw,72px);line-height:1.02;letter-spacing:-.03em;margin-top:16px;max-width:14ch;color:#fff}
.enfoque-intro__sub{margin-top:20px;color:var(--muted);font-size:clamp(16px,1.5vw,19px);max-width:40ch}
.stack-wrap{height:100vh;position:sticky;top:0;display:flex;align-items:center;justify-content:center}
.scard{position:relative;top:calc(-5vh + var(--i)*30px);width:80%;max-width:1040px;height:60vh;border-radius:26px;padding:0;transform-origin:top center;will-change:transform}
.scard__bdr{position:absolute;inset:0;border-radius:26px;padding:1.5px;pointer-events:none;
  background:conic-gradient(from 140deg,transparent 0deg,var(--teal) 70deg,rgba(2,162,182,.4) 130deg,transparent 200deg,rgba(195,208,33,.45) 280deg,transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
.scard__in{position:relative;height:100%;border-radius:24px;
  /* base var(--bg) OPACA: en el apilado la tarjeta de adelante cubre a la de
     atrás; con fondo translúcido (.94) se veía el texto de la de atrás (ghosting).
     El base opaco lo elimina.
     SIN backdrop-filter: el stack anima scale por scroll y el blur fuerza
     re-render por frame (28% de frames >33ms medidos en el sitio astro); además,
     una superficie translúcida+blur pineada es justo lo que rompe el vidrio de
     Safari 26. El fondo .97 sobre página oscura rinde igual a costo cero. */
  background:linear-gradient(150deg,rgba(18,26,40,.97),rgba(8,12,20,.97)),var(--bg);
  border:1px solid rgba(255,255,255,.06);
  --pad:clamp(34px,4vw,58px);padding:var(--pad);display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:stretch;overflow:hidden}
.scard__body{position:relative;z-index:2;display:flex;flex-direction:column;justify-content:space-between;min-width:0}
.scard__no{position:relative;font-weight:800;font-size:14px;letter-spacing:.2em;color:var(--teal)}
.scard h3{position:relative;font-weight:800;font-size:clamp(26px,3.2vw,48px);line-height:1.03;letter-spacing:-.02em;max-width:15ch}
.scard p{position:relative;color:var(--muted);font-size:clamp(15px,1.4vw,18px);line-height:1.55;max-width:42ch}
/* kicker editorial (no es link: la sección "enfoque" es explicativa, no navega a subpáginas) */
.scard__more{position:relative;font-weight:600;font-size:13.5px;color:var(--lime);display:inline-flex;align-items:center;gap:12px}
.scard__more::before{content:"";width:26px;height:2px;border-radius:2px;background:var(--grad);flex:0 0 auto}

/* ---- enfoque visuals (21st.dev card-diagram patterns) recolored ---- */
/* la viz de cada tarjeta de enfoque es SIEMPRE cuadrada: lado = el menor entre el ancho de columna (100%)
   y el alto útil de la tarjeta (60vh − 2·padding), centrada en su celda. --pad se hereda de .scard__in. */
.scard__viz{position:relative;border-radius:18px;overflow:hidden;background:rgba(8,12,20,.5);border:1px solid var(--line);min-width:0;
  aspect-ratio:1/1;width:min(100%,calc(60vh - 2*var(--pad)));align-self:center;justify-self:center;max-height:100%}
/* 01 terreno — radar sweep over map (21st.dev "LoadingRadar") */
.vradar{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.vradar__ring{position:absolute;width:64%;aspect-ratio:1;border-radius:50%;border:1px solid rgba(2,162,182,.16)}
.vradar__ring--2{width:42%;border-color:rgba(2,162,182,.22)}
.vradar__ring--3{width:20%;border-color:rgba(2,162,182,.3)}
.vradar__sweep{position:absolute;width:64%;aspect-ratio:1;border-radius:50%;
  background:conic-gradient(from 0deg,rgba(2,162,182,0) 0deg,rgba(2,162,182,0) 300deg,rgba(2,162,182,.06) 320deg,rgba(2,162,182,.4) 358deg,rgba(2,162,182,0) 360deg);
  animation:vsweep 4s linear infinite}
@keyframes vsweep{to{transform:rotate(360deg)}}
.vradar__pin{position:absolute;width:14px;height:14px;border-radius:50%;background:var(--grad);box-shadow:0 0 18px 3px rgba(2,162,182,.6);z-index:3}
.vradar__blip{position:absolute;left:var(--x);top:var(--y);width:9px;height:9px;margin:-4.5px;border-radius:50%;background:var(--teal);box-shadow:0 0 10px rgba(2,162,182,.6);opacity:.2;animation:vblip 4s ease-out infinite;animation-delay:var(--bd)}
.vradar__blip--lime{background:var(--lime);box-shadow:0 0 10px rgba(195,208,33,.6)}
@keyframes vblip{0%,72%{opacity:.16;transform:scale(.7)}82%{opacity:1;transform:scale(1.35)}100%{opacity:.16;transform:scale(.7)}}
/* 02 datos — entropy: chaos -> order (21st.dev "Entropy"), canvas driven en main.js */
.ventropy{position:absolute;inset:0;width:100%;height:100%;display:block}
/* 03 ia — WebGL orb (21st.dev "voice-powered-orb" / ogl), reacciona a scroll + hover; main.js */
.vorb{position:absolute;inset:0;width:100%;height:100%;display:block}
/* CSS fallback si el navegador no tiene WebGL disponible */
@property --tvangle{syntax:"<angle>";inherits:false;initial-value:0deg}
.vorb-fallback{display:none;position:absolute;inset:0;align-items:center;justify-content:center}
.vorb-fallback.on{display:flex}
.vorb-fallback span{width:66%;aspect-ratio:1;border-radius:50%;overflow:hidden;position:relative;
  background:
    conic-gradient(from calc(var(--tvangle) * 1.2) at 30% 65%,var(--lime) 0deg,transparent 45deg 315deg,var(--lime) 360deg),
    conic-gradient(from calc(var(--tvangle) * -1.5) at 65% 75%,var(--teal) 0deg,transparent 90deg 270deg,var(--teal) 360deg),
    conic-gradient(from calc(var(--tvangle) * 0.8) at 70% 35%,var(--navy-l) 0deg,transparent 60deg 300deg,var(--navy-l) 360deg),
    radial-gradient(ellipse 120% 80% at 40% 60%,var(--navy) 0%,transparent 55%);
  filter:blur(15px) contrast(1.7) saturate(1.3);animation:tvrotate 16s linear infinite}
@keyframes tvrotate{to{--tvangle:360deg}}
/* enfoque en móvil/tablet (≤1024): el apilado de 100vh sticky es patrón SOLO-DESKTOP.
   En pantallas chicas cada wrap de 100vh dejaba 300-560px de negro y los bordes de las
   cards previas asomaban. Acá: flujo normal en columna, y el JS (modo mstk) reintroduce
   el apilado limpio. transform:none neutraliza el driver de scale si la ventana cruzó el
   breakpoint con el driver ya armado. */
@media(max-width:1024px){
  .stack-wrap{height:auto;position:static;display:block;padding:0 var(--gutter)}
  .stack-wrap + .stack-wrap{margin-top:16px}
  .scard{top:0;width:100%;max-width:640px;height:auto;margin:0 auto}
  .scard__in{grid-template-columns:1fr;gap:24px}
  /* viz en banda (no cuadrada): acota el alto de la tarjeta para que las tres queden
     EXACTAMENTE en el min-height del apilado móvil → la de adelante cubre por completo
     a la de atrás. Una viz cuadrada (460px) desborda ese presupuesto y las tarjetas
     quedan de alturas distintas (asoman los bordes).
     width:100% + justify-self:stretch son OBLIGATORIOS: la regla de desktop centra la
     viz cuadrada (justify-self:center), y un grid item centrado con width:auto se
     dimensiona a max-content — que acá es CERO, porque todo lo que vive adentro de la
     viz (radar, canvas, grid, glow) es position:absolute. La caja colapsaba a una
     línea vertical de 0px de ancho. */
  .scard__viz{display:block;aspect-ratio:auto;width:100%;height:230px;max-height:none;order:-1;
    justify-self:stretch;align-self:stretch}
  /* aire entre la intro ("Tres pasos…") y la primera tarjeta: sin esto la tarjeta
     sticky (top:74) se pega al borde inferior del texto de la intro. */
  .stack{padding-top:24px;padding-bottom:10px}
  /* apilado LIMPIO móvil/tablet (.stack--mstk, lo arma el JS con animaciones activas):
     cada tarjeta se pega al MISMO top y con alturas uniformes, así la siguiente cubre
     POR COMPLETO a la anterior. El driver JS encoge y atenúa a la cubierta. Sin JS /
     reduced-motion no existe la clase: columna simple, todo visible. */
  .stack--mstk .stack-wrap{position:sticky;top:74px}
  .stack--mstk .scard{min-height:min(78svh,560px);display:flex;flex-direction:column;justify-content:center}
  .stack--mstk .scard__in{flex:1 0 auto}
}

/* ---------- RESULTADOS — counters ---------- */
.results .sec-head{margin-bottom:48px}
.rgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
@media(max-width:780px){.rgrid{grid-template-columns:1fr;gap:14px}}
.rstat{padding:38px 34px;border-radius:22px;border:1px solid var(--line);background:rgba(255,255,255,.025);position:relative;overflow:hidden}
.rstat::after{content:"";position:absolute;left:0;top:0;height:3px;width:34%;background:linear-gradient(90deg,var(--teal),var(--lime))}
.rnum{display:block;font-weight:800;font-size:clamp(44px,5.6vw,76px);line-height:1.08;letter-spacing:-.03em;color:var(--teal);font-variant-numeric:tabular-nums}
.rstat p{margin-top:18px;color:var(--muted);font-size:15.5px;line-height:1.5;max-width:26ch}
.rnote{margin-top:30px;color:rgba(255,255,255,.58);font-size:13px;letter-spacing:.02em}

/* ---------- POR QUÉ — Feature 108: la tarjeta cambia con el scroll + click ----------
   BASE = sección normal en flujo (acordeón por click). NADA de height:300vh ni sticky
   acá: el pin es OPT-IN y lo arma el JS poniendo .porque--pinned (desktop) o
   .porque--vscroll (móvil). Sin JS, con reduced-motion, o en tablet táctil apaisada,
   la sección no pinea y no deja scroll muerto. Un `height:300vh` + `position:sticky`
   incondicionales eran, además, el asesino del vidrio de Safari 26 en iOS.
   SIN overflow:hidden en el pin: crea una capa de composición bajo el header (rompe
   el vidrio) y clipea el SVG de los dioramas. */
.porque{position:relative;z-index:10;background:var(--bg);padding:100px 0}
.porque__sticky{position:relative}
.porque .wrap{position:relative;z-index:1;width:100%}
/* PINNED — scroll-driven por los 6 diferenciales. Los gates van TAMBIÉN acá, no sólo
   en el JS, y deben coincidir EXACTO con gate() en main.js:
   · >900   → en tablet apaisada táctil el scroll-jacking pensado para rueda se siente roto
   · >420px de alto → con la clase armada a una altura que no banca el pin, los 300vh
     + sticky clipean contenido (zoom de Windows achica el viewport en vivo)
   · pointer:fine → el pin sticky rompe el vidrio de Safari 26 en táctil */
@media(min-width:901px) and (min-height:421px) and (pointer:fine){
  .porque--pinned{height:300vh;padding:0}
  .porque--pinned .porque__sticky{position:sticky;top:0;min-height:100vh;display:flex;align-items:center}
}
.sec-head--center{margin-left:auto;margin-right:auto;text-align:center;max-width:760px}
/* "por qué" — panel de detalle + grilla de categorías (layout tipo Vault) */
.why2{display:grid;grid-template-columns:1.05fr 1.5fr;gap:18px;align-items:stretch}
@media(max-width:900px){.why2{grid-template-columns:1fr}}
.why2__detail{position:relative;overflow:hidden;border-radius:24px;border:1px solid var(--line);
  background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(255,255,255,.012));
  padding:40px 38px;display:flex;flex-direction:column;min-height:440px}
.why2__detail::after{content:"";position:absolute;left:50%;bottom:-32%;width:130%;height:64%;transform:translateX(-50%);pointer-events:none;
  background:radial-gradient(ellipse at center,rgba(2,162,182,.22),rgba(0,74,144,.13) 42%,transparent 72%)}
.why2__detail h3{position:relative;font-weight:800;font-size:clamp(30px,3.4vw,48px);letter-spacing:-.02em;line-height:1.05;color:#fff;margin-bottom:auto;max-width:12ch}
/* keyword chips del panel "por qué": pill outline fina con punto de acento teal.
   IMPORTANTE: el chip es SÓLO el wrapper .why2__tags>span; los <span lang> internos son
   i18n (texto plano, uno oculto por :lang) → si el selector fuera .why2__tags span pintaría
   un pill DENTRO del pill (el "fondo sobre fondo" que se veía feo). Por eso va con >span. */
.why2__tags{position:relative;display:flex;flex-wrap:wrap;gap:9px 10px;margin-top:26px}
.why2__tags > span{display:inline-flex;align-items:center;gap:8px;
  font-size:clamp(12.5px,.3vw + 11.6px,14px);font-weight:500;letter-spacing:.005em;line-height:1.1;
  color:rgba(255,255,255,.82);background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.1);
  padding:7px 15px 7px 13px;border-radius:100px;white-space:nowrap;
  transition:border-color .3s ease,background .3s ease,color .3s ease}
.why2__tags > span::before{content:"";flex:0 0 auto;width:5px;height:5px;border-radius:50%;
  background:var(--teal);box-shadow:0 0 7px rgba(2,162,182,.55)}
.why2__tags > span:hover{background:rgba(2,162,182,.09);border-color:rgba(2,162,182,.34);color:#fff}
.why2__grid{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:1fr;gap:18px}
@media(max-width:560px){.why2__grid{grid-template-columns:1fr 1fr}}
.why2__cell{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:15px;
  border-radius:20px;border:1px solid var(--line);background:rgba(255,255,255,.025);padding:26px 14px;min-height:148px;
  cursor:pointer;font:inherit;text-align:center;transition:transform .3s cubic-bezier(.22,1,.36,1),border-color .3s,background .3s}
.why2__cell:hover{transform:translateY(-3px)}
.why2__cell:hover>span:last-child{color:rgba(255,255,255,.9)}
.why2__cell>span:last-child{font-weight:600;font-size:15px;line-height:1.25;color:var(--muted);transition:color .3s}
.why2__ic{display:inline-flex;align-items:center;justify-content:center;width:58px;height:58px;border-radius:50%;
  border:1px solid var(--line);color:var(--muted);transition:color .3s,border-color .3s}
.why2__ic svg{width:26px;height:26px;stroke-linecap:round;stroke-linejoin:round}
.why2__cell.is-active{background:linear-gradient(var(--surface),var(--surface)) padding-box,linear-gradient(135deg,var(--navy-l),var(--teal) 55%,var(--lime)) border-box;border:1.5px solid transparent}
/* glow inferior: aparece y "sube" tanto en hover como en seleccionada */
.why2__cell::after{content:"";position:absolute;left:50%;bottom:0;width:80%;height:50%;transform:translateX(-50%) translateY(14px);pointer-events:none;border-radius:0 0 19px 19px;opacity:0;transition:opacity .45s ease,transform .5s cubic-bezier(.22,1,.36,1);
  background:radial-gradient(ellipse at center bottom,rgba(2,162,182,.34),rgba(0,74,144,.14) 52%,transparent 72%)}
.why2__cell:hover::after,.why2__cell.is-active::after{opacity:1;transform:translateX(-50%) translateY(0)}
.why2__cell.is-active .why2__ic{color:var(--teal);border-color:rgba(2,162,182,.55)}
.why2__cell.is-active>span:last-child{color:#fff}
@media(max-width:900px){.why2__detail{min-height:240px}}

/* ---------- POR QUÉ — Feature 108 (21st.dev): tabs (col izq) + panel animado (col der), un ítem por diferencial ----------
   Cada .f108__item es display:contents: su .f108__tab cae en la columna 1 (fila = su índice) y su .f108__panel
   ocupa la columna 2 abarcando las 6 filas. Los 6 paneles se apilan en la misma celda y se muestran por visibility,
   así el grid dimensiona la tarjeta con el panel MÁS ALTO y no salta de tamaño entre diferenciales. */
.f108{display:grid;grid-template-columns:.82fr 1.45fr;grid-auto-rows:min-content;gap:10px 18px;align-items:start}
.f108__item{display:contents}
.f108__tab{position:relative;overflow:hidden;display:flex;align-items:center;gap:13px;width:100%;text-align:left;cursor:pointer;font:inherit;
  border-radius:16px;border:1px solid var(--line);background:rgba(255,255,255,.025);color:var(--muted);
  padding:15px 18px;transition:border-color .3s,background .3s,color .3s,transform .3s;grid-column:1}
/* fill de progreso del segmento en curso, en el borde inferior del tab activo (lo setea el driver de scroll vía --seg) */
.f108__tab::after{content:"";position:absolute;left:0;bottom:0;height:2px;width:100%;
  background:linear-gradient(90deg,var(--teal),var(--lime));transform-origin:left;
  transform:scaleX(var(--seg,0));opacity:0;transition:opacity .3s ease}
.f108__item.is-active .f108__tab::after{opacity:.9}
.f108__item:nth-child(1) .f108__tab{grid-row:1}
.f108__item:nth-child(2) .f108__tab{grid-row:2}
.f108__item:nth-child(3) .f108__tab{grid-row:3}
.f108__item:nth-child(4) .f108__tab{grid-row:4}
.f108__item:nth-child(5) .f108__tab{grid-row:5}
.f108__item:nth-child(6) .f108__tab{grid-row:6}
.f108__tab:hover{transform:translateX(3px);color:#fff}
.f108__tab>span[lang]{font-weight:600;font-size:15.5px}
.f108__ic{flex:0 0 38px;width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  border:1px solid var(--line);color:var(--muted);transition:color .3s,border-color .3s,background .3s}
.f108__ic svg{width:20px;height:20px;stroke-linecap:round;stroke-linejoin:round}
.f108__item.is-active .f108__tab{background:linear-gradient(var(--surface),var(--surface)) padding-box,linear-gradient(135deg,var(--navy-l),var(--teal) 55%,var(--lime)) border-box;border:1.5px solid transparent;color:#fff}
.f108__item.is-active .f108__ic{color:var(--teal);border-color:rgba(2,162,182,.5);background:rgba(2,162,182,.1)}
.f108__panel{position:relative;overflow:hidden;border-radius:24px;border:1px solid var(--line);
  background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(255,255,255,.012));
  grid-column:2;grid-row:1/7;
  display:none;grid-template-columns:1.2fr .8fr;gap:24px;padding:clamp(28px,3vw,46px);min-height:380px}
.f108__item.is-active .f108__panel{display:grid;animation:f108fade .65s cubic-bezier(.22,1,.36,1)}
@keyframes f108fade{from{opacity:0}to{opacity:1}}
/* desktop: los 6 paneles renderizados y apilados (col2/fila1-6), ocultos por visibility → celda del alto del más alto */
@media(min-width:901px){
  .f108__panel{display:grid;visibility:hidden;align-self:stretch}
  .f108__item.is-active .f108__panel{visibility:visible}
}
/* entrada orquestada del contenido del panel (solo con animaciones activas) */
.anim .f108__item.is-active .f108__text>*{animation:f108up .7s cubic-bezier(.22,1,.36,1) backwards}
.anim .f108__item.is-active .f108__text>*:nth-child(2){animation-delay:.09s}
.anim .f108__item.is-active .f108__text>*:nth-child(3){animation-delay:.18s}
.anim .f108__item.is-active .f108__text>*:nth-child(4){animation-delay:.27s}
@keyframes f108up{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .f108__item.is-active .f108__panel,.anim .f108__item.is-active .f108__text>*{animation:none}
}
.f108__text{display:flex;flex-direction:column;justify-content:center;position:relative;z-index:1;min-width:0}
.f108__no{font-weight:700;font-size:13px;letter-spacing:.2em;color:var(--teal)}
.f108__text h3{font-weight:800;font-size:clamp(26px,3vw,40px);letter-spacing:-.02em;line-height:1.05;color:#fff;margin-top:10px}
.f108__text p{margin-top:16px;color:var(--muted);font-size:16px;line-height:1.6;max-width:44ch}
.f108 .why2__tags{margin-top:22px}
.f108__viz{position:relative;display:grid;place-items:center;min-width:0;padding:8px}
.f108__viz::after{content:"";position:absolute;width:78%;aspect-ratio:1;border-radius:50%;pointer-events:none;z-index:-1;
  background:radial-gradient(circle,rgba(2,162,182,.16),rgba(0,74,144,.08) 50%,transparent 70%)}
/* acordeón ≤900: tab arriba, panel se expande debajo del tab activo */
@media(max-width:900px){
  .f108{display:flex;flex-direction:column;gap:10px;align-items:stretch}
  .f108__item{display:block}
  .f108__tab{padding:14px 16px}
  .f108__tab>span[lang]{font-size:14.5px}
  .f108__tab .f108__chev{margin-left:auto;flex:0 0 18px;width:18px;height:18px;color:var(--muted);transition:transform .3s}
  .f108__item.is-active .f108__chev{transform:rotate(180deg);color:var(--teal)}
  .f108__panel{grid-template-columns:1fr;min-height:0;margin-top:8px;padding:22px 18px}
  .f108__viz{height:178px;order:-1}
  .f108__viz svg{max-height:178px}
}
@media(min-width:901px){.f108__chev{display:none}}

/* ===== "Por qué" móvil (≤900): VERTICAL scroll card-swap — migrado de la versión Astro =====
   Al scrollear hacia abajo, la tarjeta actual se DESVANECE y la siguiente aparece EN SU LUGAR
   (crossfade en z, una a la vez). El pin mide 100svh − --liveband (banda viva, ver abajo), SIN overflow:hidden
   — clipearía el SVG del card); el largo de scroll y los targets del cambio de tarjeta los dan
   los .pq-step invisibles que arma el JS. La tarjeta activa la decide un IntersectionObserver con
   la "línea" al centro del viewport (rootMargin -50%/-50%): nada de leer el scroll por frame → suave
   en iOS. Los .pq-dots son el progreso al costado. Sólo se activa con .porque--vscroll (lo pone el JS
   cuando hay IO y no hay reduced-motion); si no, queda el acordeón por click de arriba. */
@media(max-width:900px){
  .porque--vscroll{padding:0}
  /* layout en COLUMNA, título arriba (fijo) + la tarjeta llena el resto (justify-content:flex-start
     para que la tarjeta no se desborde sobre el título). overflow:visible: el height + overflow:hidden
     del sticky base clipearía el SVG del diorama. */
  /* --safe-b (congelado por el motor de glass) y NO env() en vivo: en iOS 26 el
     env(safe-area-inset-bottom) RESPIRA cuando la barra de Safari colapsa/expande en
     pleno scroll, y el padding del pin latía frame a frame. */
  /* ===== BANDA VIVA: por qué el pin NO llega al borde inferior =====================
     Hallazgo del bisect en device (iOS 26, iPhone), aislado con flags ?g= :
       · ?g=plain (sin pin)                    → vidrio VIVO
       · ?g=nopin (vscroll entero, sin pin)    → vidrio VIVO
       · ?g=shortpin (pin que corta antes)     → vidrio VIVO
       · fixed / sticky / sin animación / sin will-change / sin fondo, TODOS a 100svh
                                               → vidrio MUERTO
     O sea: no es el mecanismo del pin (fixed y sticky mueren igual), ni el repintado,
     ni la promoción a capa GPU, ni cómo se pinta el fondo. Es la GEOMETRÍA: mientras
     un elemento pineado tapa el viewport ENTERO, la franja de pantalla donde vive la
     barra de Safari se queda sin contenido que scrollee, y Safari sale del estado
     "barra minimizada de vidrio" y vuelve a la barra sólida expandida.
     El apilado (#stack) nunca tuvo el bug por esto mismo y no por suerte: .scard es
     60vh a top:74, así que su borde inferior queda ~250px sobre la barra y ahí abajo
     siempre hay página moviéndose.
     Entonces el pin corta --liveband antes del final. La animación no se toca: la
     tarjeta se sigue pineando, sigue cambiando con el scroll y sigue con sus dots.
     El VALOR sale de --liveband (arriba, con la nota del umbral medido): es constante
     del navegador, no de diseño, así que vive en un solo lugar y lo comparten todos
     los pins de pantalla completa del sitio.
     `height` fija (no min-height): el motor de pins mide offsetHeight para el spacer,
     y un alto determinista le da la misma medida en flujo y pineado. */
  /* --pqvizh: TOPE del diorama, no su alto. El valor se elige para que el diorama mida
     LO MISMO en las 6 tarjetas: todas llevan 5-6 tags → 3 filas de chips, así que el
     bloque de texto pesa parecido en todas y con 22svh el tope entra en la más apretada
     sin que el minmax tenga que recortarlo. Uniforme = el crossfade entre tarjetas no
     cambia de caja. El minmax(0,…) queda igual como válvula: si algún texto crece (i18n,
     una tag nueva), cede el diorama y nunca el texto.
     El 17svh sale del PEOR caso real, medido sobre el contenido: título de 1 línea (los
     6 lo son), copy de hasta 4 líneas (el más largo son 115 caracteres) y 3 filas de
     chips. Con eso el bloque de texto pide ~240px y el tope del diorama es lo que sobra.
     Si se agrega una tag o se alarga un copy, revisar acá antes que tocar la banda. */
  .porque--vscroll{--pqvizh:clamp(100px,17svh,158px)}
  .porque--vscroll .porque__sticky{position:sticky;top:0;height:calc(100svh - var(--liveband));display:flex;
    flex-direction:column;justify-content:flex-start;align-items:stretch;overflow:visible;
    padding:78px 0 32px}
  .porque--vscroll .wrap{width:100%;flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
  .porque--vscroll .sec-head{margin-bottom:16px;flex:0 0 auto}
  .porque--vscroll .sec-head h2{font-size:clamp(24px,6.4vw,30px)}
  /* área de tarjetas: las 6 apiladas en z, CADA UNA del alto del slot (tamaño uniforme) */
  .porque--vscroll .f108{flex:1 1 auto;min-height:0;position:relative;display:block}
  .porque--vscroll .f108__tab{display:none}
  .porque--vscroll .f108__item{position:absolute;inset:0;display:flex;align-items:stretch;
    opacity:0;visibility:hidden;transition:opacity .5s cubic-bezier(.22,1,.36,1);pointer-events:none}
  .porque--vscroll .f108__item.is-active{opacity:1;visibility:visible;pointer-events:auto}
  /* panel = alto del slot. GRID de 2 filas: viz arriba + texto debajo.
     grid (no flex): en WebKit el flex-column colapsaba la fila del viz a 0.
     CARD: fondo neutro + sombra suave neutra.
     Filas `minmax(0,--pqvizh) auto` y NO `auto auto`: el pin ahora es --liveband más
     corto (ver arriba), así que la tarjeta ya no puede medir lo que quiera — con
     `auto` la de texto más largo se pasaba del slot y `overflow:hidden` le comía las
     tags, que es justo lo que se veía cortado antes.
       · minmax(0,--pqvizh) → el diorama mide lo MISMO en las 6 tarjetas mientras haya
         lugar (uniformidad), y es lo primero que cede si una tarjeta aprieta.
       · auto en el texto → se sirve PRIMERO y a su alto real, así que el texto nunca
         se recorta; el sobrante se lo queda la fila del viz hasta --pqvizh.
     height:100% (no auto): las 6 tarjetas miden igual, así el crossfade no cambia de
     caja entre una y otra. */
  .porque--vscroll .f108__panel{display:grid!important;grid-template-rows:minmax(0,var(--pqvizh)) auto;
    visibility:visible!important;width:100%;height:100%;min-height:0;gap:14px;margin-top:0;
    padding:14px 14px 18px;position:relative;overflow:hidden;border:1px solid var(--line);border-radius:24px;
    background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(255,255,255,.012));
    box-shadow:0 24px 60px -34px rgba(0,0,0,.7)}
  .porque--vscroll .f108__panel::before,.porque--vscroll .f108__item.is-active .f108__panel{animation:none}
  /* MEDIA: el diorama SVG va CONTENIDO en un cuadro redondeado tintado. Antes flotaba pegado
     al borde superior y se veía "muy on top"; acá queda enmarcado, centrado y con menos peso.
     VIDRIO DE SAFARI 26 — el marco pinta (border-radius + border + gradientes) pero NO recorta:
     este es el único elemento del pin que corre una animación de compositor (vscrollVizIn:
     opacity+scale con fill `both`, más abajo en @media pointer:coarse). Un fill que persiste deja
     el elemento promovido a capa GPU PARA SIEMPRE; un `overflow:hidden` REDONDEADO encima obliga a
     WebKit a respaldar esa capa con una máscara aparte, anidada dentro del pin position:fixed. Esa
     capa extra es la "capa de composición bajo el header" que mata el vidrio (ver nota en .porque).
     Clip promovido = vidrio muerto; clip estático = inofensivo (lo prueba .f108__panel, que recorta
     redondeado y sigue vivo porque tiene animation:none). Por eso el recorte baja a .wviz. */
  /* el alto lo manda la fila del grid (minmax(0,--pqvizh)), no el elemento: así el
     diorama puede ceder si la tarjeta aprieta, en vez de desbordar y recortarse. */
  .porque--vscroll .f108__viz{grid-row:1;order:0;position:relative;height:auto;min-height:0;padding:0;
    border-radius:18px;display:grid;place-items:center;border:1px solid rgba(255,255,255,.07);
    background:radial-gradient(115% 120% at 50% 0%,rgba(2,162,182,.15),transparent 62%),
      linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.008))}
  .porque--vscroll .f108__viz::after{display:none}
  /* el recorte real, sobre el wrapper INTERNO: en táctil .wviz es 100% estático (todas sus
     animaciones internas están apagadas en @media pointer:coarse), así que nunca se promueve y su
     clip no genera capa. inset:8px lo mantiene por dentro del borde del marco → las esquinas
     redondeadas del marco quedan siempre limpias, aunque el <svg> pinte con overflow:visible. */
  .porque--vscroll .f108__viz > .wviz{overflow:hidden;border-radius:12px}
  .porque--vscroll .f108__viz svg{max-width:100%;max-height:100%;width:auto;height:auto}
  /* nº de tarjeta ("01"): SÓLO en desktop. En móvil se oculta — estorbaba el diseño y no
     hace falta (los pill dots de abajo ya indican en qué tarjeta estás). */
  .porque--vscroll .f108__no{display:none}
  /* SIN min-height:0 — acá estaba el recorte de las tags. Con min-height:0 el mínimo
     automático de la fila `auto` se anula, así que la fila podía quedar MÁS CORTA que su
     contenido: el grid le daba al diorama sus --pqvizh completos y lo que sobraba del
     texto se lo comía el overflow:hidden de la tarjeta (justo la última fila de chips).
     Con el mínimo automático intacto la fila de texto se sirve SIEMPRE a su alto real y
     el diorama es el que cede (minmax(0,…)): el texto nunca se recorta, por definición.
     Y con la fila garantizada ≥ contenido, justify-content:center vuelve a ser seguro
     (ya no puede desbordar por arriba): en las tarjetas holgadas centra el bloque, en las
     justas es un no-op. */
  .porque--vscroll .f108__text{grid-row:2;display:flex;flex-direction:column;justify-content:center}
  .porque--vscroll .f108__text h3{font-size:clamp(23px,5.9vw,29px);margin-top:0}
  .porque--vscroll .f108__text p{font-size:15px;margin-top:10px;line-height:1.45}
  /* CHIPS — las 6 tarjetas llevan 5 o 6 tags, o sea SIEMPRE 3 filas: no es un caso raro,
     es el caso normal, y el bloque se dimensiona para eso. Escala propia del breakpoint,
     un punto más compacta que la de escritorio (12.5px, padding 6/11, punto de 4px) para
     que las 3 filas entren con aire de sobra en vez de justo. El interlineado de la
     píldora se fija con line-height, no con padding vertical suelto: así la altura de
     fila es predecible y las 3 filas tienen ritmo parejo. */
  .porque--vscroll .f108 .why2__tags{margin-top:12px;gap:7px 8px}
  .porque--vscroll .f108 .why2__tags > span{padding:6px 11px;font-size:12.5px;line-height:1.35;gap:7px}
  .porque--vscroll .f108 .why2__tags > span::before{width:4px;height:4px}
  /* pasos de scroll invisibles: dan el largo de scroll y son los targets del IO. margin-top -70svh
     arranca el paso 0 ~20svh antes del centro → la 1ra tarjeta ya está activa al pinearse (sin
     instante en blanco); padding-bottom 50svh le da a la última el mismo dwell (58svh c/u). */
  .porque--vscroll .pq-track{position:relative;margin-top:-70svh;padding-bottom:50svh;pointer-events:none}
  .porque--vscroll .pq-step{height:58svh}
  /* progreso: mismos "pill dots" horizontales que el indicador de #resolvemos (.hdots/.hdot):
     centrados abajo, el activo se ensancha a una píldora con el gradiente de marca. */
  /* SIN --safe-b: el pin ya no llega al borde inferior (corta --liveband antes), así que
     la safe area del home indicator queda MUY por debajo. Sumarla acá sólo empujaba los
     dots hacia adentro de la tarjeta. 8px sobre el padding-bottom de 32 del pin. */
  .porque--vscroll .pq-dots{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);
    display:flex;flex-direction:row;justify-content:center;gap:8px;z-index:5}
  .porque--vscroll .pq-dots button{width:7px;height:7px;border-radius:50%;border:0;padding:0;cursor:pointer;
    background:rgba(255,255,255,.22);transition:background .3s ease,width .3s ease}
  .porque--vscroll .pq-dots button.is-active{width:22px;border-radius:4px;background:var(--grad)}
  /* WhyViz: sólo la tarjeta activa anima (las .wv-* están gateadas global por .anim → sin esto
     correrían las 6 al cargar). Al activarse pasa de none→la definida y arranca de cero. */
  .anim .porque--vscroll .f108__item:not(.is-active) .f108__viz *{animation:none!important}
}
/* TÁCTIL: las animaciones SVG (stroke-dasharray/dashoffset, filtros) NO se aceleran por compositor en
   Safari iOS → re-rasterizan en el main thread cada frame (jitter al scrollear), peor dentro del pin.
   Fix: en táctil la WhyViz NO anima por dentro — muestra la ilustración FINAL estática (dashoffset:0) y
   se revela con opacity+scale del CONTENEDOR (.f108__viz es un div → transform/opacity van por GPU).
   El pointer fine (desktop en ventana angosta) conserva la animación de trazos. */
@media(pointer:coarse){
  .porque--vscroll .f108__viz *{animation:none!important;stroke-dashoffset:0!important}
  /* fill `backwards`, NO `both`: el estado final de vscrollVizIn (opacity:1, transform:none) YA es
     el estado por defecto del elemento, así que `forwards` no aporta nada visual y sí un costo —
     un fill que persiste mantiene el elemento promovido a capa de compositor INDEFINIDAMENTE. Con
     `backwards` la capa se suelta al terminar el revelado y el pin vuelve a ser una sola capa
     plana en reposo, que es el estado en el que el vidrio de Safari 26 se mantiene vivo.
     El `from` (opacity:0/scale .95) se sigue aplicando antes de arrancar: eso es `backwards`. */
  .anim .porque--vscroll .f108__item.is-active .f108__viz{animation:vscrollVizIn .5s cubic-bezier(.22,1,.36,1) backwards}
}
@keyframes vscrollVizIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:none}}

/* ---------- wviz: dioramas SVG animados de "Por qué" (uno por diferencial) ----------
   Estados finales visibles sin .anim; las animaciones one-shot corren con .anim y se re-disparan
   al re-montarse el panel (display:none→grid) en cada activación. Reutiliza wvDash/wvDrop/wvPop/wvFade. */
.wviz{position:absolute;inset:8px}
.wviz svg{position:absolute;left:50%;top:50%;translate:-50% -50%;width:min(100%,330px);height:100%;overflow:visible}
.wv-contour,.wv-street{stroke:rgba(2,162,182,.16);stroke-width:1.5}
.wv-track{stroke:rgba(255,255,255,.13);stroke-width:3}
.wv-frame{stroke:rgba(255,255,255,.18);stroke-width:1.5;fill:rgba(255,255,255,.02)}
.wv-fold{stroke:rgba(255,255,255,.18);stroke-width:1.5}
.wv-docline{stroke:rgba(255,255,255,.2);stroke-width:3}
.wv-dot{fill:var(--lime)}
/* trazos que se dibujan (pathLength=1) */
.wv-route{stroke:var(--teal);stroke-width:2.5;stroke-dasharray:1;stroke-dashoffset:0}
.anim .wv-route{stroke-dashoffset:1;animation:wvDash 1.5s cubic-bezier(.45,.05,.25,1) .15s forwards}
.wv-link{stroke:var(--teal);stroke-width:2;stroke-dasharray:1;stroke-dashoffset:0}
.anim .wv-link{stroke-dashoffset:1;animation:wvDash .9s cubic-bezier(.45,.05,.25,1) 1.05s forwards}
/* pins */
.wv-pinshape{fill:rgba(2,162,182,.18);stroke:var(--teal);stroke-width:2}
.wv-pinshape--lime{fill:rgba(195,208,33,.15);stroke:var(--lime)}
.wv-pincore{fill:#fff;stroke:none}
.wv-pin{transform-box:fill-box;transform-origin:50% 100%}
.anim .wviz--terreno .wv-pin{animation:wvDrop .55s cubic-bezier(.22,1,.36,1) 1.65s backwards}
.anim .wviz--cerca .wv-pin--a{animation:wvDrop .5s cubic-bezier(.22,1,.36,1) .15s backwards}
.anim .wviz--cerca .wv-pin--b{animation:wvDrop .5s cubic-bezier(.22,1,.36,1) .45s backwards}
.wv-ripple{stroke:var(--teal);stroke-width:1.5;opacity:0;transform-box:fill-box;transform-origin:center}
.wviz--cerca .wv-ripple{stroke:var(--lime)}
.anim .wv-ripple{animation:wvRipple 2.6s ease-out infinite}
.anim .wv-ripple--1{animation-delay:1.6s}
.anim .wv-ripple--2{animation-delay:2.9s}
.anim .wviz--terreno .wv-ripple--1{animation-delay:2.3s}
.anim .wviz--terreno .wv-ripple--2{animation-delay:3.6s}
@keyframes wvRipple{0%{transform:scale(.35);opacity:.75}70%{opacity:.12}100%{transform:scale(2.4);opacity:0}}
/* sliders (medida) */
.wv-mark{stroke:rgba(195,208,33,.5);stroke-width:2}
.wv-thumb{fill:var(--bg);stroke:var(--teal);stroke-width:2.5;transform-box:fill-box}
.anim .wv-thumb--1{animation:wvTh1 1.15s cubic-bezier(.45,.05,.25,1) .25s backwards}
.anim .wv-thumb--2{animation:wvTh2 1.15s cubic-bezier(.45,.05,.25,1) .45s backwards}
.anim .wv-thumb--3{animation:wvTh3 1.15s cubic-bezier(.45,.05,.25,1) .65s backwards}
@keyframes wvTh1{from{transform:translateX(0)}80%{transform:translateX(99px)}to{transform:translateX(96px)}}
@keyframes wvTh2{from{transform:translateX(0)}80%{transform:translateX(-99px)}to{transform:translateX(-96px)}}
@keyframes wvTh3{from{transform:translateX(0)}80%{transform:translateX(55px)}to{transform:translateX(52px)}}
.wv-thumb--1{transform:translateX(96px)}
.wv-thumb--2{transform:translateX(-96px)}
.wv-thumb--3{transform:translateX(52px)}
/* check compartido */
.wv-check circle{stroke:var(--lime);stroke-width:2;fill:rgba(195,208,33,.1)}
.wv-check path{stroke:var(--lime);stroke-width:2.5}
.wv-check{transform-box:fill-box;transform-origin:center}
.anim .wv-check{animation:wvPop .5s cubic-bezier(.22,1,.36,1) 1.95s backwards}
.anim .wv-check path{stroke-dasharray:1;stroke-dashoffset:1;animation:wvDash .35s ease-out 2.2s forwards}
.anim .wviz--resultados .wv-check{animation-delay:3.05s}
.anim .wviz--resultados .wv-check path{animation-delay:3.3s}
/* flujo ia */
.wv-chip rect{stroke:rgba(255,255,255,.22);stroke-width:1.5;fill:rgba(255,255,255,.03)}
.wv-chip path,.wv-chip circle{stroke:rgba(255,255,255,.4);stroke-width:1.5}
.wv-chip{transform-box:fill-box;transform-origin:center}
.anim .wv-chip--1{animation:wvFade .5s ease .1s backwards}
.anim .wv-chip--2{animation:wvFade .5s ease .25s backwards}
.anim .wv-chip--3{animation:wvFade .5s ease .4s backwards}
.wv-flow{stroke:rgba(2,162,182,.55);stroke-width:1.8;stroke-dasharray:5 8}
.anim .wv-flow{animation:wvFlow 1.1s linear infinite}
@keyframes wvFlow{to{stroke-dashoffset:-26}}
.wv-port{fill:rgba(2,162,182,.85);stroke:none}
.wv-core{stroke:var(--teal);stroke-width:2;fill:rgba(2,162,182,.12)}
.wv-coredot{fill:var(--teal);stroke:none}
.wv-corehalo{stroke:rgba(2,162,182,.25);stroke-width:1.5;transform-box:fill-box;transform-origin:center}
.anim .wv-corehalo{animation:wvHalo 2.4s ease-in-out infinite}
@keyframes wvHalo{0%,100%{transform:scale(.92);opacity:.4}50%{transform:scale(1.08);opacity:1}}
.wv-out rect{stroke:rgba(195,208,33,.55);stroke-width:1.5;fill:rgba(195,208,33,.05)}
.wv-out>path{stroke:rgba(255,255,255,.35);stroke-width:2.5;stroke-linecap:round}
.wv-out g circle{stroke:var(--lime);stroke-width:2;fill:rgba(195,208,33,.12)}
.wv-out g path{stroke:var(--lime);stroke-width:2.5}
.wv-out{transform-box:fill-box;transform-origin:center}
.anim .wv-out{animation:wvPop .55s cubic-bezier(.22,1,.36,1) .95s backwards}
/* resultados */
.wv-glyph circle,.wv-glyph path{stroke:rgba(91,120,154,.85);stroke-width:2}
.wv-glyph--zap path{stroke:var(--lime);fill:rgba(195,208,33,.12)}
.wv-bar{stroke-width:10}
.wv-bar--antes{stroke:rgba(91,120,154,.5);stroke-dasharray:1;stroke-dashoffset:0}
.anim .wv-bar--antes{stroke-dashoffset:1;animation:wvDash 1.1s cubic-bezier(.45,.05,.25,1) .2s forwards}
.wv-bar--ahora{stroke:var(--teal);stroke-dasharray:1;stroke-dashoffset:0}
.anim .wv-bar--ahora{stroke-dashoffset:1;animation:wvDash .9s cubic-bezier(.45,.05,.25,1) 1.45s forwards}
.wv-delta{stroke:rgba(195,208,33,.45);stroke-width:1.5;stroke-dasharray:1;stroke-dashoffset:0}
.anim .wv-delta{stroke-dashoffset:1;animation:wvDash .7s ease-in-out 2.4s forwards}
.wviz--resultados .wv-check circle{fill:var(--bg)}
/* discreción */
.wv-redact{fill:rgba(2,162,182,.3);transform-box:fill-box;transform-origin:left center}
.anim .wv-redact--1{animation:wvWipe .6s cubic-bezier(.22,1,.36,1) .5s backwards}
.anim .wv-redact--2{animation:wvWipe .6s cubic-bezier(.22,1,.36,1) .75s backwards}
@keyframes wvWipe{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.wv-lock rect{stroke:var(--teal);stroke-width:2;fill:rgba(2,162,182,.12)}
.wv-lock>circle:not(.wv-lockglow){fill:var(--teal);stroke:none}
.wv-shackle{stroke:var(--teal);stroke-width:2;transform-box:fill-box;transform-origin:center bottom}
.anim .wv-shackle{animation:wvShackle .45s cubic-bezier(.22,1,.36,1) 1.2s backwards}
@keyframes wvShackle{from{transform:translateY(-7px)}to{transform:none}}
.wv-lockglow{stroke:none;fill:rgba(2,162,182,.1);transform-box:fill-box;transform-origin:center}
.anim .wv-lockglow{animation:wvHalo 3s ease-in-out 1.6s infinite}
@media(prefers-reduced-motion:reduce){
  .wviz *,.anim .wviz *{animation:none!important;stroke-dashoffset:0!important}
}


/* ===== CTA + FOOTER + reduced-motion ===== */
/* ---------- CONTACTO — CTA con líneas animadas (21st.dev "Animated Background Lines") ---------- */
.cta{position:relative;z-index:10;padding:clamp(96px,13vh,150px) 0;display:flex;align-items:center;justify-content:center;
  background:var(--bg);overflow:hidden;text-align:center;border-top:1px solid var(--line)}
.cta__grid{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(rgba(2,162,182,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(2,162,182,.05) 1px,transparent 1px);
  background-size:54px 54px;mask-image:radial-gradient(70% 60% at 50% 50%,#000,transparent 80%)}
.cta__lines{position:absolute;inset:0;z-index:1;pointer-events:none}
.cta__lines span{position:absolute;left:0;width:100%;height:1px;overflow:hidden}
.cta__lines span:nth-child(1){top:18%}.cta__lines span:nth-child(2){top:36%}.cta__lines span:nth-child(3){top:54%}
.cta__lines span:nth-child(4){top:72%}.cta__lines span:nth-child(5){top:88%}
.cta__lines span::after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;
  background:linear-gradient(90deg,transparent 0%,var(--teal) 35%,var(--lime) 50%,var(--teal) 65%,transparent 100%);
  transform:translateX(-100%);animation:ctaLine 7s linear infinite}
.cta__lines span:nth-child(2n)::after{animation-direction:reverse;animation-delay:2.2s;animation-duration:8.5s}
.cta__lines span:nth-child(3n)::after{animation-delay:1.2s;animation-duration:9s}
@keyframes ctaLine{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
.cta__in{position:relative;z-index:2;max-width:860px}
/* SCRIM difuso detrás del bloque de texto: opaco (color de fondo) en el núcleo y desvaneciéndose a
   transparente en los bordes. Se sitúa ENTRE las líneas animadas y el texto, así las líneas se disuelven
   al acercarse al texto (cobertura total cerca de los glifos) pero sin caja/borde visible. */
.cta__in::before{content:"";position:absolute;z-index:-1;inset:-20% -16%;pointer-events:none;
  background:
    radial-gradient(ellipse 58% 56% at 50% 50%,rgba(6,9,15,.98),rgba(6,9,15,.96) 44%,rgba(6,9,15,.78) 66%,rgba(6,9,15,.4) 84%,transparent 100%),
    radial-gradient(ellipse 46% 30% at 50% 30%,rgba(6,9,15,.95),transparent 100%)}
.cta h2{font-weight:800;font-size:clamp(34px,6vw,86px);line-height:1.02;letter-spacing:-.035em;margin-top:18px;color:#fff}
.cta__shift{display:inline-block}
.cta__sub{margin:26px auto 0;max-width:46ch;color:var(--muted);font-size:clamp(16px,1.5vw,19px);line-height:1.6}
/* Halo oscuro y difuminado detrás del texto del CTA: las líneas animadas pasan por DEBAJO de los
   glifos y el texto se lee con claridad. Capas apiladas (tenue+definida y amplia+difusa) para un
   contraste notable sin bordes duros. text-shadow estático = sin coste de rendimiento. */
.cta h2{text-shadow:0 2px 6px rgba(0,0,0,.55),0 0 22px rgba(6,9,15,.95),0 0 44px rgba(6,9,15,.85),0 0 72px rgba(6,9,15,.7)}
.cta .eyebrow,.cta__sub{text-shadow:0 1px 4px rgba(0,0,0,.55),0 0 14px rgba(6,9,15,.92),0 0 28px rgba(6,9,15,.8)}
.btn-lg{margin-top:38px;padding:18px 38px;font-size:17px}
/* botón "Hablemos": sombra difuminada (elevación oscura + glow del gradiente) para que resalte sobre el fondo animado */
.cta .btn-lg{box-shadow:0 14px 40px -10px rgba(0,0,0,.55),0 8px 30px -8px rgba(2,162,182,.45),0 0 48px -14px rgba(195,208,33,.4)}
.cta .btn-lg:hover{box-shadow:0 18px 48px -10px rgba(0,0,0,.6),0 12px 38px -8px rgba(2,162,182,.55),0 0 60px -12px rgba(195,208,33,.5)}

/* ---------- FOOTER ---------- */
.footer{position:relative;z-index:10;background:var(--bg);border-top:1px solid var(--line);padding:64px 0 40px}
/* Footer (21st.dev "Footer 2") — grid con brand col-span + columnas de links */
.footer__in{display:grid;grid-template-columns:2.2fr 1fr 1fr 1.3fr;gap:40px}
@media(max-width:820px){.footer__in{grid-template-columns:1fr 1fr;gap:32px}}
@media(max-width:480px){.footer__in{grid-template-columns:1fr}}
.footer__brand{max-width:320px}
.footer__brand .brand{margin-bottom:16px}
.footer__brand p{color:var(--muted);font-size:14.5px;line-height:1.55}
.footer__nav{display:flex;flex-direction:column;gap:12px}
.footer__nav a{display:inline-block;padding:6px 0;color:var(--muted);text-decoration:none;font-size:14.5px;transition:color .2s}
.footer__nav a:hover{color:#fff}
.footer__contact{display:flex;flex-direction:column;gap:12px}
.footer__contact a{color:var(--txt);text-decoration:none;font-size:14.5px;transition:color .2s}
.footer__contact a:hover{color:var(--teal)}
.footer__contact span{color:var(--muted);font-size:14.5px}
.footer__base{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-top:48px;padding-top:24px;border-top:1px solid var(--line);color:rgba(255,255,255,.58);font-size:12.5px;letter-spacing:.02em}

@media(prefers-reduced-motion:reduce){
  .cta__lines span::after,.cta__shift{animation:none}
  /* show decorative panel visuals in their final state (no motion) */
  .vdoc__lines span{width:var(--w)!important}
  .vdoc__badge{opacity:1!important;transform:none!important}
  .vrep__draw{stroke-dashoffset:0!important}
  .vrep__wipe,.vrep__pop{opacity:1!important;transform:none!important}
  .vrep__fade{opacity:1!important}
  .vrep__spark,.vrep__pulse,.vrep__flow{animation:none!important}
  .vrep__sealglow{animation:none!important;opacity:.24!important}
  .vring__p{stroke-dashoffset:0!important}
  .vmetric__cap{opacity:1!important;transform:none!important}
  .vtasks li{opacity:1!important;transform:none!important}
  .vchk{background:var(--teal)!important;border-color:var(--teal)!important}
  .vchk::after{transform:translate(-50%,-50%) rotate(45deg) scale(1)!important}
  .vdash__stroke{stroke-dashoffset:0!important}
  .vbars span{height:var(--h)!important}
  .vsearch__q{width:132px!important}.vcaret{animation:none;opacity:1}
  .vproj{opacity:1!important;transform:none!important}
  .vproj__track i{width:var(--p)!important}
  .vproj__track i::after{opacity:1!important;animation:none!important}
  .vstages{opacity:1!important;transform:none!important}
  .vfit__p--1,.vfit__p--2,.vfit__p--3{opacity:0!important}
  .vfit__p--key{transform:translate(0,0) scale(2)!important;opacity:1!important}
  .vfit__check{transform:translate(-50%,-50%) scale(1)!important;opacity:1!important}
  .vfit__check path{stroke-dashoffset:0!important}
  .vradar__sweep{animation:none}.vradar__blip{animation:none;opacity:.85}
  .vorb-fallback span{animation:none}
  .qcard--feat::before,.qr,.qviz--mod span,.qc,.qorbit,.qviz--bars i,.qviz--globe svg{animation:none}
}

@media(prefers-reduced-motion:reduce){
  .anim .hero h1 .ln>span,.anim .hero [data-hero]{opacity:1;transform:none;animation:none}
  .anim [data-reveal]{opacity:1;transform:none;transition:none}
  .dtl__bar{transform:none!important;transition:none}.dtl__tag{opacity:1;transition:none}
  .rw{opacity:1}
  .scrollcue .rail::after{animation:none}
}

/* ============================================================================
   NOSOTROS (subpágina) — portado de teravolta-landing-oficial + HeroViz.astro
   Mantiene las primitivas compartidas (.section, .sec-head, .eyebrow, .dviz.live,
   .vradar, .hviz__grid/glow, .vorb) ya definidas arriba; aquí solo lo que falta.
   ============================================================================ */

/* ---------- hero de subpágina ---------- */
.dhero{position:relative;z-index:10;min-height:100svh;display:flex;align-items:center;padding:104px 0 64px}
.dhero__in{display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:center;width:100%}
@media(max-width:920px){.dhero__in{grid-template-columns:1fr;gap:38px}}
.dcrumb{display:inline-flex;align-items:center;gap:8px;padding:6px 0;color:var(--muted);font-size:13px;font-weight:500;text-decoration:none;transition:color .2s}
.dcrumb:hover{color:#fff}
.dcrumb i{font-style:normal;color:var(--lime)}
/* eyebrow de subpágina: etiqueta limpia con línea de acento (sin píldora) */
.dhead .eyebrow{margin-top:20px;display:flex;align-items:center;gap:12px}
.dhead .eyebrow::before{content:"";width:26px;height:2px;border-radius:2px;background:var(--grad);flex:0 0 auto}
.dhero h1{font-weight:800;letter-spacing:-.035em;line-height:1.0;color:#fff;font-size:clamp(38px,5.6vw,82px);margin-top:14px}
.dhero__sub{margin-top:24px;max-width:46ch;font-size:clamp(16px,1.4vw,20px);line-height:1.6;color:var(--muted)}
.dhero__cta{margin-top:34px;display:flex;gap:14px;flex-wrap:wrap}
.dhero__viz{height:min(56vh,440px);align-self:stretch;box-shadow:0 40px 130px -48px rgba(2,162,182,.2)}
@media(max-width:920px){.dhero__viz{height:320px;order:-1}}

/* estado "live" de las vizzes de subpágina (espejo de .hpanel.is-active) */
.dviz.live .hviz__glow{opacity:1}

/* ---------- nosotros: manifiesto firma (lede, Text Reveal by Word) ---------- */
.lede{max-width:880px}
/* el lede es una pieza de marca, no texto corrido: va en la display (peso 500 = Medium) */
.lede p{font-family:var(--font-display);font-weight:500;font-size:clamp(20px,2.6vw,34px);line-height:1.4;letter-spacing:-.015em;color:#fff}
.lede p .grad-text,.lede-reveal .rwg{font-weight:800}

/* ---------- nosotros: timeline (21st.dev "Timeline") ---------- */
.tline{position:relative;max-width:760px;margin:0 auto;padding-left:44px}
.tline::before{content:"";position:absolute;left:11px;top:8px;bottom:18px;width:1px;
  background:linear-gradient(180deg,var(--teal),var(--lime) 60%,rgba(195,208,33,0))}
.tstep{position:relative;padding-bottom:42px}
.tstep:last-child{padding-bottom:0}
.tstep__dot{position:absolute;left:-44px;top:0;width:24px;height:24px;border-radius:50%;border:2px solid var(--teal);background:var(--bg);display:grid;place-items:center}
.tstep__dot::after{content:"";width:9px;height:9px;border-radius:50%;background:var(--grad)}
.tstep__no{font-weight:800;font-size:13px;letter-spacing:.2em;color:var(--teal)}
.tstep h3{font-weight:800;font-size:clamp(20px,2.2vw,28px);line-height:1.1;letter-spacing:-.01em;margin-top:8px;color:#fff}
.tstep p{margin-top:12px;color:var(--muted);font-size:16px;line-height:1.6;max-width:54ch}

/* ---------- nosotros: equipo ---------- */
.team{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
@media(max-width:760px){.team{grid-template-columns:1fr}}
.tmember{position:relative;overflow:hidden;border-radius:22px;border:1px solid var(--line);background:rgba(255,255,255,.025);padding:32px 28px;transition:border-color .35s,transform .35s}
.tmember:hover{border-color:rgba(2,162,182,.32);transform:translateY(-4px)}
.tavatar{width:72px;height:72px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:24px;color:var(--on-accent);background:var(--grad);box-shadow:0 10px 28px -14px rgba(2,162,182,.38)}
.tmember b{display:block;margin-top:20px;font-weight:800;font-size:19px;color:#fff;letter-spacing:-.01em}
.tmember .trole{display:block;margin-top:5px;font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--teal)}
.tmember p{margin-top:14px;color:var(--muted);font-size:14.5px;line-height:1.55}

/* ---------- nosotros: valores (reveal-list, lista sin cajas) ---------- */
.reveal-list{max-width:940px;margin:0 auto;list-style:none}
.rl__item{display:flex;gap:20px;align-items:center;padding:24px 4px;border-bottom:1px dashed rgba(255,255,255,.12)}
.reveal-list .rl__item:first-child{border-top:1px dashed rgba(255,255,255,.12)}
.rl__ic{flex:0 0 46px;width:46px;height:46px;border-radius:13px;display:grid;place-items:center;color:var(--teal);
  background:rgba(2,162,182,.08);border:1px solid rgba(2,162,182,.2)}
.rl__ic svg{width:22px;height:22px;stroke-linecap:round;stroke-linejoin:round}
.rl__tx{font-size:clamp(17px,1.7vw,22px);font-weight:500;color:var(--txt);line-height:1.35}
.rl__tx b{color:#fff;font-weight:700}
@media(max-width:560px){.rl__tx{font-size:17px}.rl__ic{width:40px;height:40px;flex-basis:40px}}

/* ---------- nosotros: con qué trabajamos (mapa de energía / techmap) ----------
   La IA es el núcleo (reactor #vorb) y las prácticas son ramas alimentadas por un
   bus. Anima al entrar en vista vía .dviz.live (observer en main.js). */
.techmap{display:grid;grid-template-columns:minmax(0,1.05fr) 84px minmax(0,1fr);align-items:center}
.tm__core{position:relative;display:grid;grid-template-columns:auto 1fr;gap:26px 28px;align-items:center}
/* conector núcleo→bus, a la altura del reactor */
.tm__core::after{content:"";position:absolute;top:88px;right:-43px;width:43px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,rgba(2,162,182,.6),rgba(2,162,182,.22));transform-origin:right}
/* reactor = orbe WebGL (#vorb). SIN marco ni grid: sólo el canvas sobre el fondo. */
.tm__reactor{position:relative;width:176px;height:176px}
.tm__corehead h3{font-weight:800;font-size:clamp(22px,2.2vw,30px);letter-spacing:-.015em;color:#fff}
.tm__corehead p{margin-top:10px;color:var(--muted);font-size:15px;line-height:1.55;max-width:44ch}
.tm__models{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:10px;list-style:none;padding:0;margin:0}
.tm__models li{display:inline-flex;align-items:center;gap:10px;font-size:14.5px;font-weight:600;color:var(--txt);
  border:1px solid rgba(2,162,182,.3);border-radius:12px;padding:10px 16px;background:rgba(2,162,182,.07)}
.tm__models .tm__logo{width:17px;height:17px;flex:0 0 17px;background:var(--dot,var(--teal));
  -webkit-mask:var(--logo) center/contain no-repeat;mask:var(--logo) center/contain no-repeat}
.tm__caps{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:10px 22px;list-style:none;padding:0;margin:0}
.tm__caps li{display:inline-flex;align-items:center;gap:9px;font-size:14px;color:rgba(255,255,255,.78)}
.tm__caps li::before{content:"";width:7px;height:7px;border-radius:50%;flex:0 0 7px;background:var(--dot,var(--teal));box-shadow:0 0 8px var(--dot,var(--teal))}
/* bus de energía */
.tm__bus{position:relative;width:2px;align-self:stretch;margin:0 auto;border-radius:2px;overflow:hidden;
  background:linear-gradient(180deg,transparent,rgba(2,162,182,.5) 10%,rgba(2,162,182,.5) 84%,rgba(195,208,33,.42) 96%,transparent);
  transform-origin:top}
.tm__bus i{position:absolute;left:0;top:0;width:2px;height:64px;border-radius:4px;opacity:0;
  background:linear-gradient(180deg,transparent,rgba(195,208,33,.95),transparent)}
/* ramas */
.tm__branches{display:flex;flex-direction:column;gap:38px;min-width:0}
.tm__branch{position:relative}
.tm__branch::before{content:"";position:absolute;left:-43px;top:11px;width:33px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,rgba(2,162,182,.55),rgba(2,162,182,.16));transform-origin:left}
.tm__branch::after{content:"";position:absolute;left:-13px;top:8px;width:8px;height:8px;border-radius:50%;
  background:var(--teal);box-shadow:0 0 10px rgba(2,162,182,.8)}
.tm__branch h4{font-weight:800;font-size:17.5px;letter-spacing:-.01em;color:#fff}
.tm__nodes{margin:14px 0 0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:11px 22px}
.tm__nodes li{display:inline-flex;align-items:center;gap:9px;font-size:14.5px;color:rgba(255,255,255,.82)}
.tm__nodes li::before{content:"";width:8px;height:8px;border-radius:50%;flex:0 0 8px;background:var(--dot,var(--teal));box-shadow:0 0 9px var(--dot,var(--teal))}
.tm__nodes li.tm__node--logo::before{width:16px;height:16px;flex-basis:16px;border-radius:0;box-shadow:none;
  background:var(--dot,var(--teal));-webkit-mask:var(--logo) center/contain no-repeat;mask:var(--logo) center/contain no-repeat}
/* --- Iconos de marca del techmap embebidos como data-URI (mask). El mask con SVG
   EXTERNO se cae al abrir por file:// (CORS de Chromium); inline es robusto en
   file:// y http, sin requests extra. Look monocromo teñido por --dot. --- */
.tm-i--claude{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z'/%3E%3C/svg%3E")}
.tm-i--django{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.146 0h3.924v18.166c-2.013.382-3.491.535-5.096.535-4.791 0-7.288-2.166-7.288-6.32 0-4.002 2.65-6.6 6.753-6.6.637 0 1.121.05 1.707.203zm0 9.143a3.894 3.894 0 00-1.325-.204c-1.988 0-3.134 1.223-3.134 3.365 0 2.09 1.096 3.236 3.109 3.236.433 0 .79-.025 1.35-.102V9.142zM21.314 6.06v9.098c0 3.134-.229 4.638-.917 5.937-.637 1.249-1.478 2.039-3.211 2.905l-3.644-1.733c1.733-.815 2.574-1.53 3.109-2.625.561-1.121.739-2.421.739-5.835V6.059h3.924zM17.39.021h3.924v4.026H17.39z'/%3E%3C/svg%3E")}
.tm-i--github{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}
.tm-i--googlegemini{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81'/%3E%3C/svg%3E")}
.tm-i--javascript{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z'/%3E%3C/svg%3E")}
.tm-i--microsoftexcel{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23 1.5q.41 0 .7.3.3.29.3.7v19q0 .41-.3.7-.29.3-.7.3H7q-.41 0-.7-.3-.3-.29-.3-.7V18H1q-.41 0-.7-.3-.3-.29-.3-.7V7q0-.41.3-.7Q.58 6 1 6h5V2.5q0-.41.3-.7.29-.3.7-.3zM6 13.28l1.42 2.66h2.14l-2.38-3.87 2.34-3.8H7.46l-1.3 2.4-.05.08-.04.09-.64-1.28-.66-1.29H2.59l2.27 3.82-2.48 3.85h2.16zM14.25 21v-3H7.5v3zm0-4.5v-3.75H12v3.75zm0-5.25V7.5H12v3.75zm0-5.25V3H7.5v3zm8.25 15v-3h-6.75v3zm0-4.5v-3.75h-6.75v3.75zm0-5.25V7.5h-6.75v3.75zm0-5.25V3h-6.75v3Z'/%3E%3C/svg%3E")}
.tm-i--microsoftoffice{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.53 4.306v15.363q0 .807-.472 1.433-.472.627-1.253.85l-6.888 1.974q-.136.037-.29.055-.156.019-.293.019-.396 0-.72-.105-.321-.106-.656-.292l-4.505-2.544q-.248-.137-.391-.366-.143-.23-.143-.515 0-.434.304-.738.304-.305.739-.305h5.831V4.964l-4.38 1.563q-.533.187-.856.658-.322.472-.322 1.03v8.078q0 .496-.248.912-.25.416-.683.651l-2.072 1.13q-.286.148-.571.148-.497 0-.844-.347-.348-.347-.348-.844V6.563q0-.62.33-1.19.328-.571.874-.881L11.07.285q.248-.136.534-.21.285-.075.57-.075.211 0 .38.031.166.031.364.093l6.888 1.899q.384.11.7.329.317.217.547.52.23.305.353.67.125.367.125.764zm-1.588 15.363V4.306q0-.273-.16-.478-.163-.204-.423-.28l-3.388-.93q-.397-.111-.794-.23-.397-.117-.794-.216v19.68l4.976-1.427q.26-.074.422-.28.161-.204.161-.477z'/%3E%3C/svg%3E")}
.tm-i--microsoftsharepoint{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M24 13.5q0 1.242-.475 2.332-.474 1.09-1.289 1.904-.814.815-1.904 1.29-1.09.474-2.332.474-.762 0-1.523-.2-.106.997-.557 1.858-.451.862-1.154 1.494-.704.633-1.606.99-.902.358-1.91.358-1.09 0-2.045-.416-.955-.416-1.664-1.125-.709-.709-1.125-1.664Q6 19.84 6 18.75q0-.188.018-.375.017-.188.04-.375H.997q-.41 0-.703-.293T0 17.004V6.996q0-.41.293-.703T.996 6h3.54q.14-1.277.726-2.373.586-1.096 1.488-1.904Q7.652.914 8.807.457 9.96 0 11.25 0q1.395 0 2.625.533T16.02 1.98q.914.915 1.447 2.145T18 6.75q0 .188-.012.375-.011.188-.035.375 1.242 0 2.344.469 1.101.468 1.928 1.277.826.809 1.3 1.904Q24 12.246 24 13.5zm-12.75-12q-.973 0-1.857.34-.885.34-1.577.943-.691.604-1.154 1.43Q6.2 5.039 6.06 6h4.945q.41 0 .703.293t.293.703v4.945l.21-.035q.212-.75.61-1.424.399-.673.944-1.218.545-.545 1.213-.944.668-.398 1.43-.61.093-.503.093-.96 0-1.09-.416-2.045-.416-.955-1.125-1.664-.709-.709-1.664-1.125Q12.34 1.5 11.25 1.5zM6.117 15.902q.54 0 1.06-.111.522-.111.932-.37.41-.257.662-.679.252-.422.252-1.055 0-.632-.263-1.054-.264-.422-.662-.703-.399-.282-.856-.463l-.855-.34q-.399-.158-.662-.334-.264-.176-.264-.445 0-.2.14-.323.141-.123.335-.193.193-.07.404-.094.21-.023.351-.023.598 0 1.055.152.457.153.95.457V8.543q-.282-.082-.522-.14-.24-.06-.475-.1-.234-.041-.486-.059-.252-.017-.557-.017-.515 0-1.054.117-.54.117-.979.375-.44.258-.715.68-.275.421-.275 1.03 0 .598.263.997.264.398.663.68.398.28.855.474l.856.363q.398.17.662.358.263.187.263.457 0 .222-.123.351-.123.13-.31.2-.188.07-.393.087-.205.018-.369.018-.703 0-1.248-.234-.545-.235-1.107-.621v1.875q1.195.468 2.472.468zM11.25 22.5q.773 0 1.453-.293t1.19-.803q.51-.51.808-1.195.299-.686.299-1.459 0-.668-.223-1.277-.222-.61-.62-1.096-.4-.486-.95-.826-.55-.34-1.207-.48v1.933q0 .41-.293.703t-.703.293H7.57q-.07.375-.07.75 0 .773.293 1.459t.803 1.195q.51.51 1.195.803.686.293 1.459.293zM18 18q.926 0 1.746-.352.82-.351 1.436-.966.615-.616.966-1.43.352-.815.352-1.752 0-.926-.352-1.746-.351-.82-.966-1.436-.616-.615-1.436-.966Q18.926 9 18 9t-1.74.357q-.815.358-1.43.973t-.973 1.43q-.357.814-.357 1.74 0 .129.006.258t.017.258q.551.27 1.02.65t.838.855q.369.475.627 1.026.258.55.387 1.148Q17.18 18 18 18Z'/%3E%3C/svg%3E")}
.tm-i--microsoftteams{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.625 8.127q-.55 0-1.025-.205-.475-.205-.832-.563-.358-.357-.563-.832Q18 6.053 18 5.502q0-.54.205-1.02t.563-.837q.357-.358.832-.563.474-.205 1.025-.205.54 0 1.02.205t.837.563q.358.357.563.837.205.48.205 1.02 0 .55-.205 1.025-.205.475-.563.832-.357.358-.837.563-.48.205-1.02.205zm0-3.75q-.469 0-.797.328-.328.328-.328.797 0 .469.328.797.328.328.797.328.469 0 .797-.328.328-.328.328-.797 0-.469-.328-.797-.328-.328-.797-.328zM24 10.002v5.578q0 .774-.293 1.46-.293.685-.803 1.194-.51.51-1.195.803-.686.293-1.459.293-.445 0-.908-.105-.463-.106-.85-.329-.293.95-.855 1.729-.563.78-1.319 1.336-.756.557-1.67.861-.914.305-1.898.305-1.148 0-2.162-.398-1.014-.399-1.805-1.102-.79-.703-1.312-1.664t-.674-2.086h-5.8q-.411 0-.704-.293T0 16.881V6.873q0-.41.293-.703t.703-.293h8.59q-.34-.715-.34-1.5 0-.727.275-1.365.276-.639.75-1.114.475-.474 1.114-.75.638-.275 1.365-.275t1.365.275q.639.276 1.114.75.474.475.75 1.114.275.638.275 1.365t-.275 1.365q-.276.639-.75 1.113-.475.475-1.114.75-.638.276-1.365.276-.188 0-.375-.024-.188-.023-.375-.058v1.078h10.875q.469 0 .797.328.328.328.328.797zM12.75 2.373q-.41 0-.78.158-.368.158-.638.434-.27.275-.428.639-.158.363-.158.773 0 .41.158.78.159.368.428.638.27.27.639.428.369.158.779.158.41 0 .773-.158.364-.159.64-.428.274-.27.433-.639.158-.369.158-.779 0-.41-.158-.773-.159-.364-.434-.64-.275-.275-.639-.433-.363-.158-.773-.158zM6.937 9.814h2.25V7.94H2.814v1.875h2.25v6h1.875zm10.313 7.313v-6.75H12v6.504q0 .41-.293.703t-.703.293H8.309q.152.809.556 1.5.405.691.985 1.19.58.497 1.318.779.738.281 1.582.281.926 0 1.746-.352.82-.351 1.436-.966.615-.616.966-1.43.352-.815.352-1.752zm5.25-1.547v-5.203h-3.75v6.855q.305.305.691.452.387.146.809.146.469 0 .879-.176.41-.175.715-.48.304-.305.48-.715t.176-.879Z'/%3E%3C/svg%3E")}
.tm-i--nextdotjs{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z'/%3E%3C/svg%3E")}
.tm-i--openai{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z'/%3E%3C/svg%3E")}
.tm-i--postgresql{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.5594 14.7228a.5269.5269 0 0 0-.0563-.1191c-.139-.2632-.4768-.3418-1.0074-.2321-1.6533.3411-2.2935.1312-2.5256-.0191 1.342-2.0482 2.445-4.522 3.0411-6.8297.2714-1.0507.7982-3.5237.1222-4.7316a1.5641 1.5641 0 0 0-.1509-.235C21.6931.9086 19.8007.0248 17.5099.0005c-1.4947-.0158-2.7705.3461-3.1161.4794a9.449 9.449 0 0 0-.5159-.0816 8.044 8.044 0 0 0-1.3114-.1278c-1.1822-.0184-2.2038.2642-3.0498.8406-.8573-.3211-4.7888-1.645-7.2219.0788C.9359 2.1526.3086 3.8733.4302 6.3043c.0409.818.5069 3.334 1.2423 5.7436.4598 1.5065.9387 2.7019 1.4334 3.582.553.9942 1.1259 1.5933 1.7143 1.7895.4474.1491 1.1327.1441 1.8581-.7279.8012-.9635 1.5903-1.8258 1.9446-2.2069.4351.2355.9064.3625 1.39.3772a.0569.0569 0 0 0 .0004.0041 11.0312 11.0312 0 0 0-.2472.3054c-.3389.4302-.4094.5197-1.5002.7443-.3102.064-1.1344.2339-1.1464.8115-.0025.1224.0329.2309.0919.3268.2269.4231.9216.6097 1.015.6331 1.3345.3335 2.5044.092 3.3714-.6787-.017 2.231.0775 4.4174.3454 5.0874.2212.5529.7618 1.9045 2.4692 1.9043.2505 0 .5263-.0291.8296-.0941 1.7819-.3821 2.5557-1.1696 2.855-2.9059.1503-.8707.4016-2.8753.5388-4.1012.0169-.0703.0357-.1207.057-.1362.0007-.0005.0697-.0471.4272.0307a.3673.3673 0 0 0 .0443.0068l.2539.0223.0149.001c.8468.0384 1.9114-.1426 2.5312-.4308.6438-.2988 1.8057-1.0323 1.5951-1.6698zM2.371 11.8765c-.7435-2.4358-1.1779-4.8851-1.2123-5.5719-.1086-2.1714.4171-3.6829 1.5623-4.4927 1.8367-1.2986 4.8398-.5408 6.108-.13-.0032.0032-.0066.0061-.0098.0094-2.0238 2.044-1.9758 5.536-1.9708 5.7495-.0002.0823.0066.1989.0162.3593.0348.5873.0996 1.6804-.0735 2.9184-.1609 1.1504.1937 2.2764.9728 3.0892.0806.0841.1648.1631.2518.2374-.3468.3714-1.1004 1.1926-1.9025 2.1576-.5677.6825-.9597.5517-1.0886.5087-.3919-.1307-.813-.5871-1.2381-1.3223-.4796-.839-.9635-2.0317-1.4155-3.5126zm6.0072 5.0871c-.1711-.0428-.3271-.1132-.4322-.1772.0889-.0394.2374-.0902.4833-.1409 1.2833-.2641 1.4815-.4506 1.9143-1.0002.0992-.126.2116-.2687.3673-.4426a.3549.3549 0 0 0 .0737-.1298c.1708-.1513.2724-.1099.4369-.0417.156.0646.3078.26.3695.4752.0291.1016.0619.2945-.0452.4444-.9043 1.2658-2.2216 1.2494-3.1676 1.0128zm2.094-3.988-.0525.141c-.133.3566-.2567.6881-.3334 1.003-.6674-.0021-1.3168-.2872-1.8105-.8024-.6279-.6551-.9131-1.5664-.7825-2.5004.1828-1.3079.1153-2.4468.079-3.0586-.005-.0857-.0095-.1607-.0122-.2199.2957-.2621 1.6659-.9962 2.6429-.7724.4459.1022.7176.4057.8305.928.5846 2.7038.0774 3.8307-.3302 4.7363-.084.1866-.1633.3629-.2311.5454zm7.3637 4.5725c-.0169.1768-.0358.376-.0618.5959l-.146.4383a.3547.3547 0 0 0-.0182.1077c-.0059.4747-.054.6489-.115.8693-.0634.2292-.1353.4891-.1794 1.0575-.11 1.4143-.8782 2.2267-2.4172 2.5565-1.5155.3251-1.7843-.4968-2.0212-1.2217a6.5824 6.5824 0 0 0-.0769-.2266c-.2154-.5858-.1911-1.4119-.1574-2.5551.0165-.5612-.0249-1.9013-.3302-2.6462.0044-.2932.0106-.5909.019-.8918a.3529.3529 0 0 0-.0153-.1126 1.4927 1.4927 0 0 0-.0439-.208c-.1226-.4283-.4213-.7866-.7797-.9351-.1424-.059-.4038-.1672-.7178-.0869.067-.276.1831-.5875.309-.9249l.0529-.142c.0595-.16.134-.3257.213-.5012.4265-.9476 1.0106-2.2453.3766-5.1772-.2374-1.0981-1.0304-1.6343-2.2324-1.5098-.7207.0746-1.3799.3654-1.7088.5321a5.6716 5.6716 0 0 0-.1958.1041c.0918-1.1064.4386-3.1741 1.7357-4.4823a4.0306 4.0306 0 0 1 .3033-.276.3532.3532 0 0 0 .1447-.0644c.7524-.5706 1.6945-.8506 2.802-.8325.4091.0067.8017.0339 1.1742.081 1.939.3544 3.2439 1.4468 4.0359 2.3827.8143.9623 1.2552 1.9315 1.4312 2.4543-1.3232-.1346-2.2234.1268-2.6797.779-.9926 1.4189.543 4.1729 1.2811 5.4964.1353.2426.2522.4522.2889.5413.2403.5825.5515.9713.7787 1.2552.0696.087.1372.1714.1885.245-.4008.1155-1.1208.3825-1.0552 1.717-.0123.1563-.0423.4469-.0834.8148-.0461.2077-.0702.4603-.0994.7662zm.8905-1.6211c-.0405-.8316.2691-.9185.5967-1.0105a2.8566 2.8566 0 0 0 .135-.0406 1.202 1.202 0 0 0 .1342.103c.5703.3765 1.5823.4213 3.0068.1344-.2016.1769-.5189.3994-.9533.6011-.4098.1903-1.0957.333-1.7473.3636-.7197.0336-1.0859-.0807-1.1721-.151zm.5695-9.2712c-.0059.3508-.0542.6692-.1054 1.0017-.055.3576-.112.7274-.1264 1.1762-.0142.4368.0404.8909.0932 1.3301.1066.887.216 1.8003-.2075 2.7014a3.5272 3.5272 0 0 1-.1876-.3856c-.0527-.1276-.1669-.3326-.3251-.6162-.6156-1.1041-2.0574-3.6896-1.3193-4.7446.3795-.5427 1.3408-.5661 2.1781-.463zm.2284 7.0137a12.3762 12.3762 0 0 0-.0853-.1074l-.0355-.0444c.7262-1.1995.5842-2.3862.4578-3.4385-.0519-.4318-.1009-.8396-.0885-1.2226.0129-.4061.0666-.7543.1185-1.0911.0639-.415.1288-.8443.1109-1.3505.0134-.0531.0188-.1158.0118-.1902-.0457-.4855-.5999-1.938-1.7294-3.253-.6076-.7073-1.4896-1.4972-2.6889-2.0395.5251-.1066 1.2328-.2035 2.0244-.1859 2.0515.0456 3.6746.8135 4.8242 2.2824a.908.908 0 0 1 .0667.1002c.7231 1.3556-.2762 6.2751-2.9867 10.5405zm-8.8166-6.1162c-.025.1794-.3089.4225-.6211.4225a.5821.5821 0 0 1-.0809-.0056c-.1873-.026-.3765-.144-.5059-.3156-.0458-.0605-.1203-.178-.1055-.2844.0055-.0401.0261-.0985.0925-.1488.1182-.0894.3518-.1226.6096-.0867.3163.0441.6426.1938.6113.4186zm7.9305-.4114c.0111.0792-.049.201-.1531.3102-.0683.0717-.212.1961-.4079.2232a.5456.5456 0 0 1-.075.0052c-.2935 0-.5414-.2344-.5607-.3717-.024-.1765.2641-.3106.5611-.352.297-.0414.6111.0088.6356.1851z'/%3E%3C/svg%3E")}
.tm-i--powerbi{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 12a1 1 0 0 1 1 1v11H4a1 1 0 0 1-1-1V13a1 1 0 0 1 1-1h6Zm-2-.5V7a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v17h-4.5V13a1.5 1.5 0 0 0-1.5-1.5H8Zm5-6V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v22a1 1 0 0 1-1 1h-3.5V7A1.5 1.5 0 0 0 15 5.5h-2Z'/%3E%3C/svg%3E")}
.tm-i--python{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z'/%3E%3C/svg%3E")}
.tm-i--react{--logo:url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z'/%3E%3C/svg%3E")}

/* móvil: el bus se vuelve espina izquierda y todo cuelga de ella */
@media(max-width:900px){
  .techmap{grid-template-columns:1fr;position:relative;padding-left:26px}
  .techmap::before{content:"";position:absolute;left:3px;top:104px;bottom:6px;width:2px;border-radius:2px;transform-origin:top;
    background:linear-gradient(180deg,rgba(2,162,182,.55),rgba(2,162,182,.45) 82%,rgba(195,208,33,.4) 96%,transparent)}
  .tm__bus{display:none}
  .tm__core{grid-template-columns:1fr;gap:18px}
  .tm__core::after{display:none}
  .tm__reactor{width:140px;height:140px;margin-left:0}
  .tm__branches{margin-top:34px;gap:30px}
  .tm__branch::before{left:-23px;width:15px;top:10px}
  .tm__branch::after{left:-12px;top:7px}
}
/* entrada orquestada (estado oculto SOLO bajo .anim: visible por defecto; al des-energizar se repliega) */
.anim .techmap .tm__bus{transform:scaleY(0);transition:transform .5s ease}
.anim .techmap.live .tm__bus{transition:transform 1.25s cubic-bezier(.22,1,.36,1) .15s;transform:scaleY(1)}
.anim .techmap::before{transform:scaleY(0);transition:transform .5s ease}
.anim .techmap.live::before{transition:transform 1.25s cubic-bezier(.22,1,.36,1) .15s;transform:scaleY(1)}
.anim .techmap .tm__core::after{transform:scaleX(0);transition:transform .45s ease}
.anim .techmap.live .tm__core::after{transition:transform .6s cubic-bezier(.22,1,.36,1) .4s;transform:scaleX(1)}
.anim .techmap .tm__branch::before{transform:scaleX(0);transition:transform .45s ease}
.anim .techmap.live .tm__branch::before{transition:transform .55s cubic-bezier(.22,1,.36,1) calc(.55s + var(--bi,0)*.16s);transform:scaleX(1)}
.anim .techmap .tm__branch::after{transform:scale(0);transition:transform .4s ease}
.anim .techmap.live .tm__branch::after{transition:transform .4s cubic-bezier(.22,1,.36,1) calc(.78s + var(--bi,0)*.16s);transform:scale(1)}
.anim .techmap .tm__branch>*{opacity:0;transform:translateY(10px);transition:opacity .45s ease,transform .45s ease}
.anim .techmap.live .tm__branch>*{transition:opacity .7s ease,transform .7s cubic-bezier(.22,1,.36,1);
  transition-delay:calc(.66s + var(--bi,0)*.16s);opacity:1;transform:none}
.anim .techmap .tm__models li{opacity:0;transform:translateY(8px);transition:opacity .45s ease,transform .45s ease}
.anim .techmap.live .tm__models li{transition:opacity .6s ease,transform .6s cubic-bezier(.22,1,.36,1);
  transition-delay:calc(.3s + var(--mi,0)*.1s);opacity:1;transform:none}
.anim .techmap .tm__caps{opacity:0;transform:translateY(8px);transition:opacity .45s ease,transform .45s ease}
.anim .techmap.live .tm__caps{transition:opacity .65s ease .55s,transform .65s cubic-bezier(.22,1,.36,1) .55s;opacity:1;transform:none}
/* vida continua del bus (pulso finito que baja al energizarse) */
.anim .techmap.live .tm__bus i{animation:tmFlow 5.5s linear 2.4s infinite}
@keyframes tmFlow{0%{transform:translateY(-70px);opacity:0}10%{opacity:.9}85%{opacity:.9}100%{transform:translateY(560px);opacity:0}}
@media(prefers-reduced-motion:reduce){
  .tm__bus i{animation:none!important}
  .anim .techmap .tm__bus,.anim .techmap::before,.anim .techmap .tm__core::after,
  .anim .techmap .tm__branch::before,.anim .techmap .tm__branch::after{transform:none;transition:none}
  .anim .techmap .tm__branch>*,.anim .techmap .tm__models li,.anim .techmap .tm__caps{opacity:1;transform:none;transition:none}
  .dviz.live .hviz__glow{opacity:1}
}

/* ---------- hero viz "team" (portado de HeroViz.astro) ----------
   Estado final visible sin .anim; animaciones disparadas por .dviz.live. */
.hv{position:absolute;inset:0}
.hv svg{position:absolute;left:20px;top:20px;width:calc(100% - 40px);height:calc(100% - 40px);overflow:visible}
.hv rect,.hv circle,.hv path,.hv line{stroke-width:1.8}
.hv-tick{stroke:var(--lime);stroke-width:2.4;fill:none}
.hv-check circle{stroke:var(--lime);fill:rgba(195,208,33,.1)}
.hv-check{transform-box:fill-box;transform-origin:center}
.hv-port{fill:rgba(2,162,182,.85);stroke:none}
.hv-spark rect{stroke:var(--teal);fill:#0a131f}
.hv-spark path{stroke:var(--teal);stroke-width:1.6;fill:rgba(2,162,182,.18)}
/* gate de entrada: oculto hasta que la viz entra en vista (.live) */
.anim .dviz:not(.live) .hv{opacity:0;translate:0 14px;transition:opacity .55s ease,translate .55s ease}
/* team */
.hv-ground{stroke:rgba(255,255,255,.14);stroke-width:2}
.hv-factory>path,.hv-factory>line{stroke:rgba(255,255,255,.28)}
.hv-factory>rect{stroke:rgba(255,255,255,.25);fill:rgba(255,255,255,.02)}
.hv-factory{transform-box:fill-box;transform-origin:center}
.anim .dviz.live .hv-factory{animation:hvGhost .7s ease .1s backwards}
.hv-smoke{stroke:none;fill:rgba(255,255,255,.35);transform-box:fill-box;transform-origin:center}
.anim .dviz.live .hv-smoke--1{animation:hvSmoke 3.8s ease-out 1.1s infinite backwards}
.anim .dviz.live .hv-smoke--2{animation:hvSmoke 3.8s ease-out 3s infinite backwards}
.hv-fwin{stroke:rgba(255,255,255,.2);fill:rgba(255,255,255,.02)}
.hv-fwin--lit,.hv-fwin--lit2{fill:rgba(2,162,182,.16)!important;stroke:rgba(2,162,182,.45)!important}
.anim .dviz.live .hv-fwin--lit{animation:hvWinGlow 3.2s ease-in-out 1.4s infinite}
.anim .dviz.live .hv-fwin--lit2{animation:hvWinGlow 3.2s ease-in-out 2.4s infinite}
.hv-person circle{stroke:rgba(255,255,255,.55);fill:rgba(8,12,20,.6)}
.hv-person>path:not(.hv-hat){stroke:rgba(255,255,255,.55);fill:rgba(255,255,255,.04)}
.hv-hat{stroke:var(--lime);fill:rgba(195,208,33,.12)}
.hv-person{transform-box:fill-box;transform-origin:center bottom}
.anim .dviz.live .hv-person--3{animation:wvDrop .5s cubic-bezier(.22,1,.36,1) .45s backwards}
.anim .dviz.live .hv-person--1{animation:wvDrop .5s cubic-bezier(.22,1,.36,1) .6s backwards}
.anim .dviz.live .hv-person--2{animation:wvDrop .5s cubic-bezier(.22,1,.36,1) .75s backwards}
.hv-build{stroke:rgba(2,162,182,.5);stroke-width:1.6}
.anim .dviz.live .hv-build{stroke-dasharray:1;stroke-dashoffset:1;animation:wvDash .5s ease-out 1.05s forwards}
.hv-panel>rect{stroke:rgba(2,162,182,.5);fill:rgba(8,12,20,.6)}
.hv-ptrack{stroke:rgba(255,255,255,.14);stroke-width:5}
.hv-pfill{stroke-width:5}
.hv-pfill--1{stroke:var(--teal)}
.hv-pfill--2{stroke:var(--lime)}
.hv-panel{transform-box:fill-box;transform-origin:center}
.anim .dviz.live .hv-panel{animation:wvPop .55s cubic-bezier(.22,1,.36,1) 1.35s backwards}
.anim .dviz.live .hv-pfill{stroke-dasharray:1;stroke-dashoffset:1;animation:wvDash .6s cubic-bezier(.22,1,.36,1) forwards}
.anim .dviz.live .hv-pfill--1{animation-delay:1.7s}
.anim .dviz.live .hv-pfill--2{animation-delay:1.9s}
.anim .dviz.live .hv-panel .hv-spark{animation:wvPop .45s cubic-bezier(.22,1,.36,1) 1.6s backwards}
.anim .dviz.live .hv-check--team{animation:wvPop .5s cubic-bezier(.22,1,.36,1) 2.25s backwards}
.anim .dviz.live .hv-check--team .hv-tick{stroke-dasharray:1;stroke-dashoffset:1;animation:wvDash .35s ease-out 2.5s forwards}
@keyframes wvDash{to{stroke-dashoffset:0}}
@keyframes wvDrop{from{opacity:0;translate:0 -16px}60%{opacity:1;translate:0 2px}to{opacity:1;translate:0 0}}
@keyframes wvPop{from{opacity:0;scale:.5}to{opacity:1;scale:1}}
@keyframes wvFade{from{opacity:0;translate:0 8px}to{opacity:1;translate:0 0}}
@keyframes hvGhost{from{opacity:0}to{opacity:1}}
@keyframes hvSmoke{0%{opacity:0;translate:0 8px;scale:.55}22%{opacity:.9}100%{opacity:0;translate:0 -32px;scale:1.3}}
@keyframes hvWinGlow{0%,100%{fill:rgba(2,162,182,.1)}50%{fill:rgba(2,162,182,.32)}}
@media(prefers-reduced-motion:reduce){
  .anim .dviz:not(.live) .hv{opacity:1;translate:none;transition:none}
  .hv *,.anim .hv *{animation:none!important;stroke-dashoffset:0!important}
}


/* ============================================================================
   SERVICIO · INFORMES TÉCNICOS (subpágina) — portado de teravolta-landing-oficial
   Reusa las primitivas ya definidas arriba (.section, .sec-head, .dhero, .dviz,
   .vrep, .reveal-list, .cta, .footer); acá solo lo propio de la página:
   before/after · barras "cuándo llega" · story pineado · FAQ · strip de servicios.

   REGLA DE VIDRIO (iOS 26): `position:sticky` es lo que rompe el Liquid Glass de
   Safari. Por eso el story NO usa sticky por defecto: el pin vive SOLO dentro del
   media query de escritorio con puntero fino. En táctil (iPhone/iPad/Android) la
   sección es un stack estático — mejor UX en touch y cero riesgo de franja negra.
   ============================================================================ */

/* ---------- problema → resultado (before / after) ---------- */
.bavs{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media(max-width:760px){.bavs{grid-template-columns:1fr}}
.bcol{position:relative;overflow:hidden;border-radius:22px;border:1px solid var(--line);background:rgba(255,255,255,.02);padding:clamp(28px,3vw,40px)}
.bcol--tv{border-color:rgba(2,162,182,.3);background:linear-gradient(180deg,rgba(2,162,182,.07),rgba(255,255,255,.012))}
.bcol--tv::after{content:"";position:absolute;left:0;top:0;height:3px;width:38%;background:linear-gradient(90deg,var(--teal),var(--lime))}
.bcol__lbl{font-size:12px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.bcol--tv .bcol__lbl{color:var(--teal)}
.bcol h3{font-weight:800;font-size:clamp(20px,2vw,26px);line-height:1.1;letter-spacing:-.01em;margin-top:12px;color:#fff}
.blist{list-style:none;margin-top:24px;display:flex;flex-direction:column;gap:15px}
.blist li{display:flex;gap:13px;align-items:flex-start;color:var(--muted);font-size:15.5px;line-height:1.5}
.blist li b{color:var(--txt);font-weight:600}
.bdot{flex:0 0 20px;width:20px;height:20px;border-radius:50%;margin-top:1px;display:grid;place-items:center}
.bcol--now .bdot{border:1.5px solid rgba(255,255,255,.2)}
.bcol--now .bdot::after{content:"";width:8px;height:8px;
  background:linear-gradient(45deg,transparent 43%,rgba(255,255,255,.45) 43% 57%,transparent 57%),linear-gradient(-45deg,transparent 43%,rgba(255,255,255,.45) 43% 57%,transparent 57%)}
.bcol--tv .bdot{background:rgba(2,162,182,.16);border:1.5px solid var(--teal)}
.bcol--tv .bdot::after{content:"";width:5px;height:9px;border:solid var(--lime);border-width:0 2px 2px 0;transform:translateY(-1px) rotate(45deg)}

/* ---------- "cuándo llega": barras relativas del momento de entrega (sin tiempos
   absolutos). Crecen cuando el bloque entra en vista ([data-reveal] → .is-in, el
   mismo observer genérico que usa el resto de la página). ---------- */
.dtl{max-width:820px;margin:0 auto;display:flex;flex-direction:column;gap:34px}
.dtl__row{display:grid;grid-template-columns:148px 1fr;align-items:center;gap:22px}
.dtl__lbl{font-size:14px;font-weight:600;color:var(--muted)}
.dtl__row--tv .dtl__lbl{color:var(--teal)}
.dtl__track{position:relative;display:flex;align-items:center;gap:12px;padding:5px}
.dtl__track::before{content:"";position:absolute;inset:0;border-radius:10px;background:rgba(255,255,255,.05);border:1px solid var(--line)}
.dtl__bar{position:relative;height:12px;border-radius:8px;transform-origin:left;transform:scaleX(0);transition:transform 1.1s cubic-bezier(.22,1,.36,1)}
.dtl__row--now .dtl__bar{width:86%;background:linear-gradient(90deg,rgba(var(--stale),.22),rgba(var(--stale),.44))}
.dtl__row--tv .dtl__bar{width:30%;background:var(--grad)}
.dtl__tag{position:relative;flex:none;font-size:11.5px;line-height:1;font-weight:600;white-space:nowrap;opacity:0;transition:opacity .45s ease .65s;color:var(--muted)}
.dtl__row--tv .dtl__tag{color:var(--teal)}
.dtl.is-in .dtl__bar{transform:scaleX(1)}
.dtl.is-in .dtl__tag{opacity:1}
.dtl__cap{max-width:680px;margin:36px auto 0;text-align:center;color:var(--muted);font-size:15.5px;line-height:1.6}
/* teléfonos: la etiqueta sube arriba de la pista (la columna de 148px la dejaba sin aire) */
@media(max-width:560px){
  .dtl{gap:26px}
  .dtl__row{grid-template-columns:1fr;gap:8px}
  .dtl__track{padding:5px}
}

/* ---------- story: el visual manda y los pasos cambian con el scroll ----------
   Base (móvil / tablet / cualquier táctil): stack estático, sin pin y sin sticky. */
.sticky-story{position:relative;z-index:10;background:var(--bg)}
.ss__pin{padding:90px 0 22px}
.ss__intro{padding-bottom:22px}
.ss__intro h2{font-weight:800;font-size:clamp(28px,4vw,56px);line-height:1.05;letter-spacing:-.03em;color:#fff;margin-top:14px;max-width:18ch}
.ss__in{display:grid;grid-template-columns:1fr;gap:28px;align-items:center;width:100%}
.ss__steps{display:flex;flex-direction:column;gap:16px}
.ss__step{position:relative;padding:14px 0 14px 24px}
.ss__step::before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:2px;border-radius:2px;background:linear-gradient(var(--teal),var(--lime))}
.ss__step .ss__no{font-weight:700;font-size:13px;letter-spacing:.2em;color:var(--teal)}
.ss__step h3{font-weight:800;font-size:clamp(20px,2.2vw,28px);line-height:1.08;letter-spacing:-.02em;color:#fff;margin-top:6px}
.ss__step p{margin-top:8px;color:var(--muted);font-size:15.5px;line-height:1.5;max-width:42ch}
.ss__viz{position:relative;height:280px}
.ss__frame{position:absolute;inset:0;border-radius:18px;overflow:hidden;background:rgba(8,12,20,.5);border:1px solid var(--line);box-shadow:0 40px 120px -48px rgba(2,162,182,.18)}
.ss__bars{position:absolute;left:18px;top:18px;z-index:4;display:flex;gap:7px}
.ss__bars i{width:22px;height:4px;border-radius:3px;background:rgba(255,255,255,.16);transition:background .3s,width .3s}
.ss__pin[data-step="0"] .ss__bars i:nth-child(1),.ss__pin[data-step="1"] .ss__bars i:nth-child(2),.ss__pin[data-step="2"] .ss__bars i:nth-child(3){background:var(--grad);width:30px}

/* PIN — solo escritorio con puntero fino y viewport alto: ahí sticky es seguro (el
   vidrio de Safari 26 es problema de iOS/iPadOS) y el scroll-jacking suma. El driver
   de main.js gatea con el MISMO query: CSS y JS nunca se desincronizan. */
@media(min-width:1025px) and (min-height:560px) and (pointer:fine){
  .sticky-story{height:300vh}
  /* el heading vive DENTRO del pin: heading + viz + pasos entran y salen como una unidad */
  .ss__pin{position:sticky;top:0;min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:74px 0 32px}
  .ss__intro{padding-bottom:clamp(20px,3vh,40px)}
  .ss__in{grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,72px)}
  .ss__steps{order:-1;gap:8px} /* DOM viz-first: los pasos van a la izquierda; la viz a la derecha */
  .ss__step{opacity:.4;transition:opacity .4s ease}
  .ss__step::before{background:rgba(255,255,255,.12);transition:background .4s}
  .ss__step.is-active{opacity:1}
  .ss__step.is-active::before{background:linear-gradient(var(--teal),var(--lime))}
  .ss__viz{order:0;height:min(56vh,440px)}
}
/* compresión por ALTURA: que las 3 etapas entren completas en viewports bajos (FHD@150%, zoom) */
@media(min-width:1025px) and (max-height:680px) and (pointer:fine){
  .ss__pin{padding:60px 0 16px}
  .ss__intro{padding-bottom:clamp(12px,2vh,22px)}
  .ss__intro h2{font-size:clamp(24px,3vw,40px);margin-top:8px}
  .ss__viz{height:min(42vh,300px)}
  .ss__steps{gap:4px}
  .ss__step{padding:9px 0 9px 22px}
  .ss__step h3{font-size:clamp(18px,2vw,24px)}
  .ss__step p{margin-top:6px;font-size:14.5px;line-height:1.45}
}
/* ---------- móvil / tablet (≤1024): la escena + el texto del paso se pinean juntos y SOLO se
   muestra el paso activo (crossfade en z), como .porque--vscroll. Así ninguno de los tres textos
   pasa por detrás ni por encima de la escena. Glass-safe: en fino la pinea position:sticky; en
   TÁCTIL (html.tpin) el motor de pins la clava por position:fixed —sticky rompe el vidrio de Safari 26—.
   Lo activa el JS con .ss--vscroll; los .pq-step invisibles dan el largo de scroll y son targets del IO.
   El pin mide igual que .porque__sticky (100svh − banda viva) → la misma matemática de scroll (58svh/paso). */
@media(max-width:1024px){
  /* BANDA VIVA — mismo arreglo que .porque__sticky, misma causa (ver la nota larga en
     .porque--vscroll): un pin que tapa el viewport entero deja la franja de la barra de
     Safari sin contenido que scrollee y iOS 26 abandona el vidrio. El pin corta
     --liveband antes del borde, el mismo token calibrado en #porque. Acá se aplica por
     identidad de estructura — conviene confirmarlo en una /servicio-*.html. */
  .ss--vscroll{padding:0}
  .ss--vscroll .ss__pin{position:sticky;top:0;height:calc(100svh - var(--liveband));display:flex;flex-direction:column;
    justify-content:flex-start;align-items:stretch;overflow:visible;
    padding:84px 0 34px}
  .ss--vscroll .ss__intro{flex:0 0 auto;padding-bottom:12px}
  .ss--vscroll .ss__intro h2{font-size:clamp(23px,5.6vw,30px);margin-top:10px}
  .ss--vscroll .ss__in{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;align-items:stretch;gap:14px}
  /* flex:0 1 auto + basis en vez de 0 0 auto: con el pin más corto la escena tiene que
     poder ceder, si no empuja los pasos fuera del pin y se recortan. */
  .ss--vscroll .ss__viz{flex:0 1 auto;height:clamp(132px,21svh,206px);min-height:0}
  /* área de texto: los 3 pasos apilados en z, SOLO el activo visible (crossfade) */
  .ss--vscroll .ss__steps{flex:1 1 auto;min-height:0;position:relative;display:block;gap:0}
  .ss--vscroll .ss__step{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
    padding:0 0 0 24px;opacity:0;visibility:hidden;transition:opacity .5s cubic-bezier(.22,1,.36,1);pointer-events:none}
  .ss--vscroll .ss__step.is-active{opacity:1;visibility:visible;pointer-events:auto}
  /* progreso: pill dots centrados abajo (mismo patrón que .porque--vscroll) */
  /* sin --safe-b: el pin corta --liveband antes del borde, la safe area queda muy abajo */
  .ss--vscroll .pq-dots{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);
    display:flex;gap:8px;z-index:6}
  .ss--vscroll .pq-dots button{width:7px;height:7px;border-radius:50%;border:0;padding:0;cursor:pointer;
    background:rgba(255,255,255,.22);transition:background .3s ease,width .3s ease}
  .ss--vscroll .pq-dots button.is-active{width:22px;border-radius:4px;background:var(--grad)}
  /* pasos de scroll invisibles: largo + targets del IO (58svh de dwell c/u) */
  .ss--vscroll .pq-track{position:relative;margin-top:-70svh;padding-bottom:50svh;pointer-events:none}
  .ss--vscroll .pq-step{height:58svh}
}
/* TÁCTIL: el sticky rompe el vidrio de Safari 26 → position:relative y que pinee el motor por fixed */
html.tpin .ss--vscroll .ss__pin{position:relative;top:auto}
/* TÁCTIL: las animaciones SVG (dash/filtros) re-rasterizan en el main thread → jitter al scrollear.
   En vscroll táctil la escena se muestra CONSTRUIDA y estática; el cambio de paso lo revela el
   crossfade de opacidad de la zona (GPU). Sin acentos infinitos. El puntero fino conserva el trazado. */
@media(pointer:coarse){
  .ss--vscroll .ssv *{animation:none!important;stroke-dashoffset:0!important}
  .ss--vscroll .ssv__wipe,.ss--vscroll .ssv__pop{opacity:1!important;transform:none!important}
  .ss--vscroll .ssv__fade{opacity:1!important}
  .ss--vscroll .ssv__spark,.ss--vscroll .ssv__pulse{opacity:0!important}
  .ss--vscroll .ssv__sealglow{opacity:.22!important}
}

/* ---------- escena del story (ssv): una escena enfocada por paso ----------
   Cada paso trae su propia escena a pantalla completa (crossfade) y, dentro, todo
   se construye con un mismo lenguaje —draw / wipe / pop / fade con stagger por --d—
   idéntico en mecánica a la escena .vrep de la home. Así los tres pasos comparten
   ritmo, easing y acabado (nada de keyframes sueltos con delays dispares).
   SVG absoluto contra el área (NO grid + height:100%: en tracks auto el porcentaje
   queda indefinido y Chrome usa el alto intrínseco del viewBox → desborda el panel). */
.ssv{position:absolute;inset:0}
.ssv svg{position:absolute;left:20px;top:30px;width:calc(100% - 40px);height:calc(100% - 48px);overflow:visible}

/* crossfade: solo la escena del paso activo se ve; las demás quedan armadas y ocultas */
.ssv-zone{opacity:0;transition:opacity .55s ease}
.ss__pin[data-step="0"] .ssv-a,
.ss__pin[data-step="1"] .ssv-b,
.ss__pin[data-step="2"] .ssv-c{opacity:1}

/* --- toolkit de construcción (misma mecánica que .vrep__*) --- */
.ssv__draw{stroke-dasharray:var(--len,300);stroke-dashoffset:var(--len,300);transition:stroke-dashoffset 1s cubic-bezier(.22,1,.36,1) var(--d,0s)}
.ssv__wipe{opacity:0;transform:scaleX(0);transform-box:fill-box;transform-origin:left center;transition:transform .7s cubic-bezier(.22,1,.36,1) var(--d,0s),opacity .5s ease var(--d,0s)}
.ssv__pop{opacity:0;transform:scale(0);transform-box:fill-box;transform-origin:center;transition:transform .55s cubic-bezier(.34,1.56,.64,1) var(--d,0s),opacity .4s ease var(--d,0s)}
.ssv__fade{opacity:0;transition:opacity .6s ease var(--d,0s)}
.ssv__spark,.ssv__pulse,.ssv__sealglow{opacity:0}

/* estado "construido" — se dispara en la escena del paso activo (.anim = motor de scroll vivo) */
.anim .ss__pin[data-step="0"] .ssv-a .ssv__draw,
.anim .ss__pin[data-step="1"] .ssv-b .ssv__draw,
.anim .ss__pin[data-step="2"] .ssv-c .ssv__draw{stroke-dashoffset:0}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__wipe,
.anim .ss__pin[data-step="1"] .ssv-b .ssv__wipe,
.anim .ss__pin[data-step="2"] .ssv-c .ssv__wipe{opacity:1;transform:scaleX(1)}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__pop,
.anim .ss__pin[data-step="1"] .ssv-b .ssv__pop,
.anim .ss__pin[data-step="2"] .ssv-c .ssv__pop{opacity:1;transform:scale(1)}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__fade,
.anim .ss__pin[data-step="1"] .ssv-b .ssv__fade,
.anim .ss__pin[data-step="2"] .ssv-c .ssv__fade{opacity:1}

/* --- acentos vivos: solo mientras su escena está activa --- */
.anim .ss__pin[data-step="0"] .ssv-a .ssv__flow{animation:ssvFlow 1s linear .9s infinite}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__spark{animation:ssvSpark 2.6s cubic-bezier(.5,0,.5,1) 1.2s infinite}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__pulse{animation:ssvPulse 2s ease-out 1.5s infinite}
.anim .ss__pin[data-step="0"] .ssv-a .ssv__sealglow{animation:ssvSeal 2.6s ease-in-out 1.8s infinite}
.anim .ss__pin[data-step="2"] .ssv-c .ssv__pulse{animation:ssvPulse 2.4s ease-out 1.6s infinite}
@keyframes ssvFlow{to{stroke-dashoffset:-16}}
@keyframes ssvSpark{0%{opacity:0;transform:translateX(0)}12%{opacity:1}80%{opacity:1}100%{opacity:0;transform:translateX(36px)}}
@keyframes ssvPulse{0%{opacity:.9;transform:scale(1);transform-box:fill-box;transform-origin:center}70%,100%{opacity:0;transform:scale(3.4);transform-box:fill-box;transform-origin:center}}
@keyframes ssvSeal{0%,100%{opacity:.18}50%{opacity:.4}}

/* sin pin (táctil / tablet) o antes de que arranque el motor: una sola escena, ya construida.
   Vale también para el paso pendiente en escritorio: hasta que no hay data-step, se ve la 1ª. */
.ss__pin:not([data-step]) .ssv-a{opacity:1}
.ss__pin:not([data-step]) .ssv-a .ssv__draw{stroke-dashoffset:0}
.ss__pin:not([data-step]) .ssv-a .ssv__wipe{opacity:1;transform:scaleX(1)}
.ss__pin:not([data-step]) .ssv-a .ssv__pop{opacity:1;transform:scale(1)}
.ss__pin:not([data-step]) .ssv-a .ssv__fade{opacity:1}

@media(prefers-reduced-motion:reduce){
  .ssv *{animation:none!important}
  .ssv__draw{stroke-dashoffset:0!important}
  .ssv__wipe,.ssv__pop{opacity:1!important;transform:none!important}
  .ssv__fade{opacity:1!important}
  .ssv__spark,.ssv__pulse{opacity:0!important}
  .ssv__sealglow{opacity:.22!important}
  .ssv-zone{opacity:0!important}
  .ssv-a{opacity:1!important}
  .ss__step{opacity:1!important}
}

/* ---------- FAQ (acordeón de apertura única; el alto lo escribe main.js) ---------- */
.faq{max-width:840px;margin:0 auto}
.faq__item{border-bottom:1px dashed rgba(255,255,255,.14)}
.faq__item:first-child{border-top:1px dashed rgba(255,255,255,.14)}
.faq__q{width:100%;background:none;border:0;color:#fff;font:inherit;font-weight:700;font-size:clamp(16px,1.5vw,20px);line-height:1.3;text-align:left;
  padding:26px 0;cursor:pointer;display:flex;justify-content:space-between;gap:20px;align-items:center}
.faq__ic{flex:0 0 auto;width:32px;height:32px;border-radius:50%;border:1px solid var(--line);position:relative;transition:transform .4s cubic-bezier(.22,1,.36,1),border-color .3s,background .3s}
.faq__ic::before,.faq__ic::after{content:"";position:absolute;left:50%;top:50%;background:var(--muted);border-radius:2px;transition:background .3s,opacity .3s}
.faq__ic::before{width:12px;height:2px;transform:translate(-50%,-50%)}
.faq__ic::after{width:2px;height:12px;transform:translate(-50%,-50%)}
.faq__item.open .faq__ic{transform:rotate(180deg);border-color:rgba(2,162,182,.5)}
.faq__item.open .faq__ic::after{opacity:0}
.faq__item.open .faq__ic::before{background:var(--teal)}
.faq__a{overflow:hidden;max-height:0;transition:max-height .45s cubic-bezier(.22,1,.36,1)}
.faq__a p{color:var(--muted);font-size:16px;line-height:1.65;padding:0 0 28px;max-width:68ch}
/* sin JS el acordeón queda abierto: el contenido (y su valor SEO) nunca se pierde */
html:not(.js) .faq__a{max-height:none}
html:not(.js) .faq__ic{display:none}

/* ---------- otros frentes: strip liviano de navegación entre servicios ---------- */
.relstrip{display:flex;gap:14px;flex-wrap:wrap}
.relstrip a{flex:1 1 230px;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:18px 22px;border-radius:16px;border:1px solid var(--line);background:rgba(255,255,255,.025);
  text-decoration:none;color:#fff;transition:border-color .3s,transform .3s,background .3s}
.relstrip a:hover{border-color:rgba(2,162,182,.35);transform:translateY(-3px);background:rgba(255,255,255,.045)}
.relstrip .rs__l{position:relative;display:flex;flex-direction:column;gap:4px;min-width:0}
.relstrip .rs__n{font-weight:700;font-size:11px;letter-spacing:.18em;color:var(--teal)}
.relstrip .rs__t{font-weight:600;font-size:14.5px;line-height:1.25}
.relstrip .rs__ar{position:relative;color:var(--lime);font-style:normal;transition:transform .3s}
.relstrip a:hover .rs__ar{transform:translateX(4px)}

/* ---------- steps: pasos horizontales conectados (21st.dev "Steps") ----------
   4 en fila en escritorio → 2×2 en tablet → columna en teléfono. El conector se
   esconde cuando deja de haber una fila que conectar. ---------- */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(14px,2vw,30px)}
@media(max-width:820px){.steps{grid-template-columns:1fr 1fr;gap:32px 24px}}
@media(max-width:480px){.steps{grid-template-columns:1fr}}
.stepc{position:relative}
.stepc__top{display:flex;align-items:center;gap:14px;margin-bottom:20px}
.stepc__num{flex:0 0 auto;width:46px;height:46px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:17px;color:var(--on-accent);background:var(--grad);box-shadow:0 10px 24px -14px rgba(2,162,182,.38)}
.stepc__bar{flex:1;height:2px;border-radius:2px;background:linear-gradient(90deg,rgba(2,162,182,.55),rgba(2,162,182,.05))}
.stepc:last-child .stepc__bar{display:none}
@media(max-width:820px){.stepc__bar{display:none}}
.stepc h3{font-weight:800;font-size:18.5px;letter-spacing:-.01em;color:#fff;line-height:1.16}
.stepc p{margin-top:11px;color:var(--muted);font-size:14.5px;line-height:1.55}

/* ============================================================================
   SERVICIO · INDICADORES (subpágina)
   La viz del hero es la misma .vdash de la card 03 del carrusel; sus disparadores
   vivían solo bajo .hpanel.is-active (home), así que acá se les suma el espejo
   .dviz.live que usan las subpáginas. Nada de position:sticky: la página es un
   stack normal y el vidrio de Safari 26 queda intacto.
   ============================================================================ */

/* la viz del tablero también se activa fuera del carrusel (hero de subpágina) */
.anim .dviz.live .vdash__stroke{stroke-dashoffset:0}
.anim .dviz.live .vbars span{height:var(--h)}
.anim .dviz.live .vbars span:nth-child(1){transition-delay:.05s}
.anim .dviz.live .vbars span:nth-child(2){transition-delay:.1s}
.anim .dviz.live .vbars span:nth-child(3){transition-delay:.15s}
.anim .dviz.live .vbars span:nth-child(4){transition-delay:.2s}
.anim .dviz.live .vbars span:nth-child(5){transition-delay:.25s}
.anim .dviz.live .vbars span:nth-child(6){transition-delay:.3s}
.anim .dviz.live .vbars span:nth-child(7){transition-delay:.35s}

/* el KPI del tablero entra junto con la línea (solo existe en el hero de subpágina) */
.dhero__viz .vdash__kpi{transition:opacity .6s ease .25s,transform .6s cubic-bezier(.22,1,.36,1) .25s}
.anim .dhero__viz.dviz:not(.live) .vdash__kpi{opacity:0;transform:translateY(8px)}
@media(prefers-reduced-motion:reduce){
  .anim .dhero__viz.dviz .vdash__kpi{opacity:1;transform:none;transition:none}
}

/* en pantallas chicas la viz mide 320px: el tablero necesita menos aire para no
   apretar las barras contra el KPI */
@media(max-width:560px){
  .vdash{padding:24px 22px}
  .vdash__kpi{top:20px;left:22px}
  .vdash__kpi b{font-size:26px}
}

/* ---------- statband: números grandes al día (21st.dev "Stats"), reusa .rnum ---------- */
.statband{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2.5vw,34px);
  padding:clamp(26px,3.4vw,44px) clamp(18px,2.6vw,36px);border:1px solid var(--line);border-radius:22px;
  background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.015))}
@media(max-width:680px){.statband{grid-template-columns:1fr;gap:0;padding:8px clamp(18px,5vw,26px)}}
.statc{position:relative;padding:0 clamp(8px,2vw,26px)}
.statc + .statc{border-left:1px solid var(--line)}
@media(max-width:680px){.statc{padding:26px 0}.statc + .statc{border-left:0;border-top:1px solid var(--line)}}
.statband .rnum{font-size:clamp(40px,5vw,64px)}
.statc p{margin-top:14px;color:var(--muted);font-size:15px;line-height:1.5;max-width:30ch}
@media(max-width:680px){.statc p{max-width:none}}


/* ============================================================================
   SERVICIO · INFORMACIÓN (subpágina)
   La viz del hero es la misma .vsearch de la card 04 del carrusel y sus disparadores
   ya tienen el espejo .dviz.live más arriba, así que acá solo falta el bloque
   .callout y compactar la viz cuando el hero pasa a una sola columna.
   ============================================================================ */

/* ---------- callout: bloque highlight, borde en degradado (21st.dev "Banner") ---------- */
.callout{position:relative;overflow:hidden;border-radius:24px;padding:clamp(34px,4.5vw,58px);
  background:linear-gradient(var(--surface),var(--surface)) padding-box,linear-gradient(120deg,var(--navy-l),var(--teal) 55%,var(--lime)) border-box;border:1.5px solid transparent}
.callout::after{content:"";position:absolute;right:-6%;top:-50%;width:420px;height:420px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(2,162,182,.16),rgba(0,74,144,.08) 50%,transparent 70%)}
.callout__eyebrow{position:relative;font-family:var(--font-display);font-weight:700;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--lime)}
.callout h3{position:relative;margin-top:16px;font-weight:800;font-size:clamp(24px,3.2vw,40px);line-height:1.1;letter-spacing:-.02em;color:#fff;max-width:24ch}
.callout__div{position:relative;height:2px;width:84px;margin-top:24px;border-radius:2px;background:var(--grad)}
.callout__sub{position:relative;margin-top:24px;color:var(--muted);font-size:16.5px;line-height:1.6;max-width:62ch}

/* ---------- la viz del buscador dentro del hero de subpágina ----------
   Bajo 920px el hero pasa a una columna y la viz queda con alto FIJO (320px), pero el
   .vsearch a tamaño completo mide ~380px y se desbordaba a cualquier ancho. Se compacta
   con valores fijos (la restricción es el alto, no el ancho), se acota el ancho para que
   no se estire en cajas anchas y, en pantallas chicas, se ocultan las etiquetas de etapa:
   la barra de avance ya comunica el estado. Solo afecta a este hero, no al carrusel. */
@media(max-width:920px){
  .dhero__viz .vsearch{gap:9px;padding:18px 20px;justify-content:center;align-items:center}
  .dhero__viz .vsearch__bar{padding:8px 13px}
  .dhero__viz .vsearch__bar,.dhero__viz .vresults{width:100%;max-width:520px}
  .dhero__viz .vresults{gap:9px}
  .dhero__viz .vproj{padding:8px 14px;gap:6px}
  .dhero__viz .vproj__head b{font-size:12.5px}
  .dhero__viz .vstages{font-size:9.5px}
  .dhero__viz .vstages span{white-space:nowrap}
}
@media(max-width:560px){
  .dhero__viz .vstages{display:none}
}


/* ============================================================================
   SERVICIO · A MEDIDA (subpágina)
   La viz del hero (.vfit) y la línea de tiempo (.tline) ya existen arriba; lo único
   propio de esta página es la tabla comparativa. Sigue sin haber sticky: stack normal.
   ============================================================================ */

/* ---------- cmp: tabla comparativa (21st.dev "Compare Table") ---------- */
.cmp{max-width:940px;margin:0 auto;border-radius:22px;border:1px solid var(--line);overflow:hidden;background:rgba(255,255,255,.022)}
.cmp__row{display:grid;grid-template-columns:1.5fr 1fr 1fr;align-items:stretch}
.cmp__row + .cmp__row{border-top:1px solid var(--line)}
.cmp__row--head>span{padding:18px 22px;font-weight:700;font-size:13.5px;letter-spacing:.01em;background:rgba(255,255,255,.03)}
.cmp__row--head .cmp__std{color:var(--muted)}
.cmp__row--head .cmp__tv{color:#fff;background:rgba(2,162,182,.07)}
.cmp__row--head .cmp__tv::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--grad);margin-right:9px;vertical-align:middle}
.cmp__attr{padding:18px 22px;font-size:15px;color:var(--txt);font-weight:500;display:flex;align-items:center}
.cmp__cell{padding:18px 22px;display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--muted)}
.cmp__cell.cmp__tv{background:rgba(2,162,182,.05)}
.cmp__cell svg{flex:0 0 auto;width:20px;height:20px;stroke-linecap:round;stroke-linejoin:round}
.cmp__cell--yes{color:var(--txt)}
.cmp__cell--yes svg{color:var(--teal)}
.cmp__cell--no svg{color:rgba(255,255,255,.28)}
@media(max-width:620px){
  .cmp__row{grid-template-columns:1.4fr 1fr 1fr}
  .cmp__row--head>span{padding:12px 10px;font-size:11px}
  .cmp__attr{padding:14px 12px;font-size:13px}
  .cmp__cell{padding:14px 10px;font-size:11.5px;gap:6px}
  .cmp__cell svg{width:17px;height:17px}
}


/* ============================================================================
   CONTACTO
   Hero con el mismo fondo de beams del index y el formulario partido en dos
   (21st.dev "Contact 2"). Sin sticky y sin backdrop-filter: el vidrio de Safari 26
   se dibuja sobre el fondo sin franjas y el scroll no arrastra composiciones caras.
   ============================================================================ */
.cwrap{display:grid;grid-template-columns:.92fr 1.08fr;gap:clamp(28px,4vw,56px);align-items:start;width:100%}
@media(max-width:860px){.cwrap{grid-template-columns:1fr;gap:32px}}

/* ---------- columna izquierda: el pitch y los datos de contacto ---------- */
.cinfo h1{font-weight:800;font-size:clamp(28px,3.6vw,50px);line-height:1.04;letter-spacing:-.03em;color:#fff}
.cinfo__sub{margin-top:20px;color:var(--muted);font-size:17px;line-height:1.6;max-width:38ch}
.cinfo__list{list-style:none;margin-top:34px;display:flex;flex-direction:column;gap:18px}
.cinfo__list li{display:flex;gap:14px;align-items:center}
.cinfo__ic{flex:0 0 44px;width:44px;height:44px;border-radius:13px;display:grid;place-items:center;color:var(--teal);background:rgba(2,162,182,.1);border:1px solid rgba(2,162,182,.22)}
.cinfo__ic svg{width:21px;height:21px;stroke-linecap:round;stroke-linejoin:round}
.cinfo__list li>span:not(.cinfo__ic){display:flex;flex-direction:column;gap:3px;min-width:0}
.cinfo__list .clbl,.cinfo__list .cval{display:block}
.cinfo__list .clbl{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.cinfo__list .cval{font-size:16px;font-weight:600;color:var(--txt);text-decoration:none;transition:color .2s}
a.cval:hover{color:var(--teal)}

/* ---------- columna derecha: el formulario ---------- */
.cform{position:relative;overflow:hidden;border-radius:24px;border:1px solid var(--line);background:rgba(255,255,255,.025);padding:clamp(28px,3.4vw,42px)}
.cform::after{content:"";position:absolute;left:0;top:0;height:3px;width:34%;border-radius:3px;background:linear-gradient(90deg,var(--teal),var(--lime))}
.field{display:flex;flex-direction:column;gap:8px;margin-bottom:20px}
.field label{font-size:13px;font-weight:600;letter-spacing:.02em;color:var(--muted)}
/* appearance:none mata el sombreado interior y el radio que iOS le impone a los campos */
.field input,.field textarea{-webkit-appearance:none;appearance:none;background:rgba(255,255,255,.04);border:1px solid var(--line);border-radius:12px;
  padding:14px 16px;color:#fff;font:inherit;font-size:15px;transition:border-color .25s,box-shadow .25s;width:100%}
.field input::placeholder,.field textarea::placeholder{color:rgba(255,255,255,.6)}
.field input:focus,.field textarea:focus{outline:none;border-color:rgba(2,162,182,.6);box-shadow:0 0 0 3px rgba(2,162,182,.14)}
.field textarea{min-height:130px;resize:vertical}
/* táctil: por debajo de 16px iOS hace zoom al enfocar el campo y deja la página descuadrada */
@media(pointer:coarse){.field input,.field textarea{font-size:16px}}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:520px){.frow{grid-template-columns:1fr}}
.cform .btn-primary{width:100%;justify-content:center;margin-top:8px}
.cform .btn-primary[aria-busy="true"]{opacity:.72;pointer-events:none}
.cform__note{margin-top:16px;font-size:12.5px;color:rgba(255,255,255,.58);line-height:1.5;text-align:center}

/* estado de éxito: reemplaza a los campos dentro de la misma tarjeta */
.cform__ok{display:none;flex-direction:column;align-items:center;text-align:center;padding:30px 10px}
.cform.sent .cform__fields{display:none}
.cform.sent .cform__ok{display:flex}
.cform__ok .okmark{width:64px;height:64px;border-radius:50%;display:grid;place-items:center;background:rgba(2,162,182,.12);border:1px solid rgba(2,162,182,.4);margin-bottom:20px}
.cform__ok .okmark svg{width:30px;height:30px;color:var(--teal);stroke-linecap:round;stroke-linejoin:round}
.cform__ok h3{font-weight:800;font-size:22px;color:#fff}
.cform__ok p{margin-top:10px;color:var(--muted);font-size:15px;line-height:1.55;max-width:34ch}
.cform__again{margin-top:26px}

/* validación inline + fallo de envío */
.field__err{margin-top:7px;font-size:13px;line-height:1.4;color:#ff9b9b;letter-spacing:.01em}
.field__err:empty{display:none}
.field--err input,.field--err textarea{border-color:rgba(255,120,120,.7)}
.field--err input:focus,.field--err textarea:focus{box-shadow:0 0 0 3px rgba(255,120,120,.18)}
.cform__fail{margin-top:14px;padding:12px 14px;border-radius:12px;border:1px solid rgba(255,120,120,.4);
  background:rgba(255,120,120,.08);color:#ffc2c2;font-size:13.5px;line-height:1.5;text-align:center}
.cform__fail:empty{display:none}
.cform__fail a{color:#fff;text-decoration:underline;text-underline-offset:2px}
