/* =====================================================================
   venta.css — NÚCLEO COMPARTIDO de las páginas de venta de Axioma
   /shopify · /landing · /sitio-web        (y candidato a /cro cuando se descongele)

   Base viva del 6-ago-2026 16:07:
     · HOME  → axioma-build-20260806/base/index.html      (estándar de piel)
     · /cro/ → axioma-build-20260806/base/cro-index.html  (estándar de VENTA)

   Reglas que gobiernan este archivo:
     PLAN-COHERENCIA.md  → «Lo que gana, en un bloque copiable» + 38 divergencias
     DOSSIER-MOVIMIENTO.md → catálogo de efectos y candados C1–C5
     SPEC-PAGINAS.md §0.4 (tipografía de venta) y §0.5 (candados)
     CHECKLIST-CONFIANZA.md §4 (lo que NO va)

   NO está aquí a propósito (prohibido por el dossier en páginas de venta):
     preloader #intro · Lenis · #glow que sigue al cursor · ticker ·
     stack sticky de servicios de la home · split por carácter en precio/alcance ·
     entrada 3D sin comprimir · píldoras flotantes · velo atado al scroll ·
     tokens muertos --rl / --rxl · contadores regresivos.
   Cada línea de este archivo dice de dónde salió: [HOME] o [CRO].
   ===================================================================== */


/* =====================================================================
   1 · TOKENS  [HOME index.html:16-25]
   Copiados literales de la home según PLAN-COHERENCIA «Lo que gana».
   Se ELIMINAN --rl y --rxl: declarados en la home, usados en 0 reglas.
   Se FORMALIZAN como token las curvas y las dos sombras que la home
   tenía escritas a mano (index:189 y index:244).
   ===================================================================== */
:root{
  /* --- paleta: idéntica a la home. No editar. --- */
  --bg:#dcdcd9; --card:#fff; --ink:#171717; --ink2:#5f5f5c; --ink3:#8b8b87;
  --dark:#0e0f12; --dark2:#17181c;
  --blue:#2F6BFF; --blue-d:#1a4bd8; --cyan:#3fd3ff; --violet:#7d5cff;
  --line:rgba(23,23,23,.16); --line-d:rgba(255,255,255,.14);

  /* --- forma --- */
  --rs:5px;            /* tarjetas, thumbs, chips                       [HOME] */
  --rm:10px;           /* <details> del FAQ                             [HOME] */
  --rp:100px;          /* píldoras: nav, botones. El gesto de marca.    [HOME] */
  --pad:40px;          /* → 20px en ≤860                                [HOME] */
  --max:1400px;        /* contenedor                                    [HOME] */
  --sec:96px;          /* ritmo de sección: padding-top                 [HOME] */
  --sec-dark:120px;    /* margen antes de bloque oscuro y footer        [HOME] */

  /* --- tipografía --- */
  --sans:'Geist','Geist Fallback',Inter,system-ui,-apple-system,sans-serif;
  --mono:'Geist Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* --- sombras (normalización de los dos valores sueltos de la home) --- */
  --sh:0 22px 50px -30px rgba(23,23,23,.35);   /* = .svc  [HOME index:189] */
  --sh-sm:0 20px 40px -34px rgba(23,23,23,.5); /* = .step [HOME index:244] */

  /* --- LAS 4 CURVAS DE LA CASA  [HOME · DOSSIER §3.3, todas LEÍDAS] --- */
  --ease:cubic-bezier(.16,1,.3,1);          /* marca / expo-out. 9 reglas en la home */
  --ease-ui:cubic-bezier(.4,0,.2,1);        /* UI: header, rotador, salidas          */
  --ease-bounce:cubic-bezier(.34,1.56,.64,1);/* rebote, pico 1.0758. Solo micro-acentos */
  --ease-sweep:cubic-bezier(.76,0,.24,1);   /* barrido in-out fuerte. Uso muy puntual */
  --ease-draw:cubic-bezier(.44,0,.56,1);    /* extra: trazos SVG (Hanzo, comprimido)  */

  /* --- duraciones de VENTA (comprimidas respecto a la home) --- */
  --dur-rv:700ms;      /* DOSSIER §3.1: 1050ms de la home → 700ms en venta */
  --dur-blur:550ms;    /* chips / filas / listas: .55s + blur(10px)→0      */
  --dur-ui:300ms;      /* micro-interacciones: rango medido 250–340ms      */
  --dur-cae:450ms;     /* tarjeta de cierre que cae (90% ya está a 253ms)  */
  --dur-draw:1100ms;   /* trazo SVG comprimido (Hanzo usa 1770ms)          */
}


/* =====================================================================
   2 · FUENTES  [HOME, corregido]
   La home carga Geist por Google Fonts con display=swap y declara
   'Geist Fallback' que NO EXISTE (grep @font-face = 0) → CLS 0.29.
   PLAN-COHERENCIA lo marca OBLIGATORIO: autoalojar + fallback con
   métricas ajustadas. Si los .woff2 aún no están subidos, la página
   se pinta con 'Geist Fallback' (Arial ajustado) y no hay salto.

   FIX 7-ago-2026 · `optional` → `swap`. MEDIDO, no supuesto:
   con la woff2 retrasada 2.5 s (3G real), CDP CSS.getPlatformFontsForNode
   sobre el H1 devolvía
       /            a 1.2 s ".SF NS"  → a 6.2 s "Geist"   (cambia: swap)
       /shopify/    a 1.2 s "Arial"   → a 6.2 s "Arial"   (NO cambia)
       /landing/    a 1.2 s "Arial"   → a 6.2 s "Arial"
       /sitio-web/  a 1.2 s "Arial"   → a 6.2 s "Arial"
       /legal/      a 1.2 s "Arial"   → a 6.2 s "Arial"
   `font-display:optional` le da a la fuente ~100 ms; si no llega a tiempo,
   Chrome PINTA TODA LA PÁGINA en el fallback y ya NUNCA la cambia. O sea:
   en la primera visita desde una red lenta, estas cuatro páginas salían en
   Arial mientras la home salía en Geist. Es exactamente «no se ve como la
   home», no lo arregla ningún ?v=, y no se ve en pruebas con caché caliente
   ni en Wi-Fi. /cro/ no estaba afectada: carga Geist por Google Fonts con
   display=swap, igual que la home.
   `swap` es seguro aquí PRECISAMENTE porque 'Geist Fallback' de abajo lleva
   size-adjust/ascent/descent ajustados: el intercambio no mueve la caja.
   ⚠️ Este archivo se sirve con max-age=604800: subirlo SIN subir el ?v=
   nuevo de los HTML no le llega a nadie que ya haya visitado.
   ===================================================================== */
@font-face{
  font-family:'Geist';
  src:url(/assets/fonts/geist.woff2?v=f4634c3bc1) format('woff2');
  font-weight:400 900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Geist Mono';
  src:url(/assets/fonts/geist-mono.woff2?v=cd5b257811) format('woff2');
  font-weight:400 600; font-style:normal; font-display:swap;
}
/* El fallback métrico. Los números de antes (97/95/24) no salían de ninguna
   medición y por eso el swap movía la caja: con ellos, pasar de Arial a Geist
   daba CLS 0.16-0.28 (medido con la woff2 retrasada 2.5 s, 1440 y 390 px).
   Éstos SÍ están medidos, con canvas TextMetrics a 100px sobre el H1 real:
       ancho    Geist 5866.100  ·  Arial 5852.734  → size-adjust    100.23 %
       ascent   Geist 101       ·  Arial 91        → ascent-override 100.77 %
       descent  Geist  29       ·  Arial 21        → descent-override 28.93 %
   (los override van divididos entre el size-adjust, que es como los
   interpreta el navegador).                                                */
@font-face{
  font-family:'Geist Fallback';
  src:local('Arial');
  size-adjust:100.23%; ascent-override:100.77%; descent-override:28.93%; line-gap-override:0%;
}


/* =====================================================================
   3 · RESET  [HOME index.html:26-33]
   ===================================================================== */
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}  /* [CRO] scroll nativo, sin Lenis */
body{
  background:var(--bg); color:var(--ink); font-family:var(--sans);
  font-weight:500;                 /* [HOME] las otras 3 páginas iban en 400 */
  letter-spacing:-.02em;           /* [HOME] */
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
img,video,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
table{border-collapse:collapse}
::selection{background:var(--blue);color:#fff}

/* C2 · foco visible OBLIGATORIO. Prohibido outline:none sin sustituto. */
:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:3px}

/* Salto al contenido: barato y necesario con nav fija */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--ink);color:#fff;
  padding:10px 16px;border-radius:var(--rp);font-size:14px}
.skip:focus{left:12px;top:12px}


/* =====================================================================
   4 · GRANO  [HOME index.html:36-38]  — capa estática, coste cero.
   Calibrado por fondo (regla de hanzo-07): .055 sobre #dcdcd9.
   ===================================================================== */
body::after{
  content:'';position:fixed;inset:0;z-index:60;pointer-events:none;
  opacity:.055;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}


/* =====================================================================
   5 · CONTENEDOR Y RITMO  [HOME]
   1400 / 40px → 20px en ≤860. Cuatro anchos vivos hoy (1400/1140/1220/1320):
   este es el único que sobrevive.
   ===================================================================== */
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}
.wrap--angosto{max-width:860px}     /* FAQ, garantía, bloques de lectura larga */
.sec{position:relative;padding:var(--sec) 0 0}
.sec--ultima{padding-bottom:var(--sec)}


/* =====================================================================
   6 · TIPOGRAFÍA DE VENTA
   Aquí gana /cro, NO la home: el uppercase de 128px de la home se come
   4+ líneas a 390px. SPEC-PAGINAS §0.4, medido en la única página que cobra.
   ===================================================================== */

/* H1 de venta [CRO cro-index.html:53-54] */
.h1{
  font-size:clamp(2.1rem,6vw,3.6rem);   /* 57.6px @1440 */
  line-height:1.04; letter-spacing:-.03em; font-weight:800;
  text-transform:none;                   /* nunca uppercase en venta */
  max-width:15ch; text-wrap:balance; margin:0 0 14px;
}
.h1--ancho{max-width:22ch}

/* H2 [CRO cro-index.html:85 + SPEC §0.4].
   line-height 1.55 es el valor MEDIDO en /cro (hereda el del body).
   Para titulares de 2+ líneas usa .h2--compacta. */
.h2{font-size:clamp(1.5rem,4vw,2.2rem);line-height:1.55;font-weight:800;
  letter-spacing:-.02em;margin:18px 0 8px;text-wrap:balance}
.h2--compacta{line-height:1.15}
.h3{font-size:clamp(1.1rem,2.4vw,1.35rem);font-weight:700;letter-spacing:-.03em;line-height:1.25}

/* Precio [CRO cro-index.html:64-66] — C5: nunca lleva .rv */
.precio{font-size:clamp(2.6rem,7vw,3.4rem);font-weight:800;letter-spacing:-.03em;line-height:1}
.precio em{font-style:normal;font-family:var(--mono);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink2);display:block;margin-top:6px}
.precio .desde{font-family:var(--mono);font-size:12px;letter-spacing:.08em;color:var(--ink2);
  margin-right:8px;vertical-align:.32em;text-transform:uppercase}
.precio-linea{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink2);margin-top:8px}   /* «pago único · MXN» en la MISMA zona del número */

/* Etiquetas mono: gana la home (12px / +.06em). /cro las tiene a +.12em, el doble. */
.mono{font-family:var(--mono);font-weight:500;font-size:12px;letter-spacing:.06em;text-transform:uppercase}
.mono--sm{font-size:11px}
.lead{color:var(--ink2);max-width:52ch;line-height:1.5;font-size:1.02rem}
.nota{font-size:.8rem;color:var(--ink3);line-height:1.5}
.blue{color:var(--blue)}
.ink2{color:var(--ink2)}


/* =====================================================================
   7 · CABECERA DE SECCIÓN  [HOME index.html:136-142 + CRO:50-52]
   Gramática única de todo el sitio: [NN] // Nombre · Descriptor + regla.
   ===================================================================== */
.sec-head{display:flex;justify-content:space-between;gap:16px;padding-bottom:7px;
  font-family:var(--mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink2)}
.sec-head .c{color:var(--ink)}
.rule{height:1px;background:var(--line);transform-origin:left;transform:scaleX(0);
  transition:transform 1.1s var(--ease)}
.on .rule,.rule.on{transform:scaleX(1)}
.rule--dark{background:var(--line-d)}


/* =====================================================================
   8 · NAV DE PÍLDORAS  [HOME index.html:69-88, con auto-hide]
   fixed + transparente + translateY(-104%) al bajar. Enlace real a "/"
   OBLIGATORIO (hoy /shopify/ es un callejón sin salida: 0 href="/").
   ===================================================================== */
header{position:fixed;top:0;left:0;right:0;z-index:50;
  transition:transform .45s var(--ease-ui),background .3s ease}
header.hide{transform:translateY(-104%)}
/* fondo solo cuando ya hay contenido debajo: legibilidad sin tapar el hero */
header.scrolled{background:rgba(220,220,217,.82);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line)}

.nav{display:flex;align-items:center;justify-content:space-between;gap:16px;
  max-width:var(--max);margin:0 auto;padding:18px var(--pad)}
.brand{display:flex;align-items:center;gap:9px;font-size:19px;font-weight:800;
  letter-spacing:-.05em;text-transform:uppercase}
.brand .iso{width:19px;height:19px;flex:0 0 auto}

/* píldoras */
.nav-links{display:flex;gap:6px;align-items:center}
.nav-links a{position:relative;display:inline-flex;align-items:center;gap:6px;
  border-radius:var(--rp);padding:8px 14px;font-size:15px;font-weight:500;letter-spacing:-.03em;
  border:1px solid transparent;transition:background var(--dur-ui) ease,border-color var(--dur-ui) ease}
.nav-links a sup{font-family:var(--mono);font-size:9px;letter-spacing:.04em;opacity:.5;vertical-align:super}
.nav-links a:hover{background:rgba(23,23,23,.06);border-color:var(--line)}
.nav-links a[aria-current="page"]{background:rgba(23,23,23,.06);border-color:var(--line)}

/* CTA de la nav = el mismo gesto que el botón primario */
.cta-pill{display:inline-flex;align-items:center;gap:10px;background:var(--dark);color:#fff;
  border-radius:var(--rp);padding:8px 8px 8px 18px;font-size:14px;letter-spacing:-.03em;
  transition:transform var(--dur-ui) ease,background var(--dur-ui) ease}
.cta-pill:hover{transform:translateY(-2px);background:var(--blue)}
.cta-pill .dot{width:26px;height:26px;border-radius:50%;background:var(--blue);display:grid;
  place-items:center;font-size:12px;color:#fff;transition:background var(--dur-ui) ease}
.cta-pill:hover .dot{background:#fff;color:var(--blue)}

.burger{display:none;width:44px;height:44px;border-radius:50%;background:var(--dark);color:#fff;
  place-items:center}

/* Menú móvil: transform + clip-path, NUNCA height (bug #4 del dossier).
   Vive en el HTML como <nav id="menu">, no se inyecta por innerHTML. */
#menu{position:fixed;inset:0;z-index:55;background:var(--dark);color:#fff;
  display:grid;align-content:center;gap:6px;padding:32px;
  font-size:34px;font-weight:700;letter-spacing:-.045em;text-transform:uppercase;
  transform:translateY(-12px);opacity:0;visibility:hidden;
  transition:transform .35s var(--ease),opacity .3s ease,visibility 0s .35s}
#menu.abierto{transform:none;opacity:1;visibility:visible;transition-delay:0s}
#menu a{padding:4px 0}
#menu .wa{color:var(--blue);margin-top:14px}
#menu .cerrar{position:absolute;top:22px;right:22px;font-size:26px;width:44px;height:44px}

/* la nav es fixed: todo destino de ancla se aparta de ella (C1 depende de esto) */
[id]{scroll-margin-top:104px}
@media (max-width:860px){[id]{scroll-margin-top:88px}}


/* =====================================================================
   9 · BARRA DE PROGRESO  [HOME #prog, corregida]
   La home anima style.width → layout cada frame (1.7 layouts/frame medidos).
   Aquí: scaleX + transform-origin:left. Solo compositing.
   ===================================================================== */
#prog{position:fixed;top:0;left:0;height:2px;width:100%;z-index:70;background:var(--blue);
  transform:scaleX(0);transform-origin:left center;pointer-events:none}


/* =====================================================================
   10 · BOTONES  [HOME .cta-pill + CRO .btn]
   Un solo gesto: píldora de 100px. El botón no cambia de forma entre páginas.
   Primario = fondo --dark + punto azul (el acento #2F6BFF va en la CIFRA,
   nunca en el fondo del botón — patrón agero-06, SPEC §4 B4).
   Hover: gap 8→18px en 340ms (versión barata aprobada, DOSSIER §3.4).
   ===================================================================== */
.btn{display:inline-flex;justify-content:center;align-items:center;gap:8px;
  border-radius:var(--rp);padding:14px 24px;font-weight:700;font-size:15px;letter-spacing:-.03em;
  border:1px solid transparent;position:relative;
  transition:background var(--dur-ui) ease,color var(--dur-ui) ease,
             border-color var(--dur-ui) ease,transform var(--dur-ui) ease,gap 340ms var(--ease)}
.btn:hover{gap:18px}
.btn:active{transform:translateY(1px)}
.btn .ico{flex:none;transition:transform 340ms var(--ease)}

/* primario — el que cobra */
.btn--pago{background:var(--dark);color:#fff;padding:13px 13px 13px 24px}
.btn--pago .dot{width:28px;height:28px;border-radius:50%;background:var(--blue);display:grid;
  place-items:center;font-size:13px;color:#fff;flex:none;transition:background var(--dur-ui) ease}
.btn--pago:hover{background:var(--blue);transform:translateY(-2px)}
.btn--pago:hover .dot{background:#fff;color:var(--blue)}

/* secundario — WhatsApp «Dudas», peso MEDIO (SPEC §0.2), no discreto */
.btn--wa{border-color:var(--line);color:var(--ink);font-weight:600;font-size:14px}
.btn--wa:hover{border-color:var(--ink);background:rgba(23,23,23,.04)}

/* terciario — enlace con subrayado, para «ver qué incluye» */
.btn--linea{padding:0 0 2px;border-radius:0;border-bottom:1px solid var(--line);font-size:14px;
  font-weight:600;gap:7px}
.btn--linea:hover{border-color:var(--ink);gap:12px}

/* sobre superficie oscura */
.btn--claro{border-color:var(--line-d);color:#fff}
.btn--claro:hover{border-color:#fff;background:rgba(255,255,255,.06)}

.btn--full{width:100%}
.btn[aria-disabled="true"],.btn:disabled{opacity:.5;pointer-events:none}

/* CINTURÓN DE DATOS bajo el botón (CHECKLIST señal 2 + §2.8):
   fecha de entrega · precio · esquema de pago · reversa de riesgo.
   Nunca lleva .rv: viaja pegado al precio (C5). */
.cinturon{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:12px;
  font-family:var(--mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink2)}
.cinturon span{display:inline-flex;align-items:center;gap:6px}
.cinturon span::before{content:'';width:4px;height:4px;border-radius:50%;background:var(--blue)}


/* =====================================================================
   11 · TARJETAS  [HOME .step/.bx (radio 5px) + CRO .buy (contenido de venta)]
   Radio 5px SIEMPRE. /cro usa 16-20px: 4x más redondo, no entra.
   ===================================================================== */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--rs);
  padding:22px;box-shadow:var(--sh-sm)}
.card--plana{box-shadow:none}
.card--borde{background:transparent;box-shadow:none}
.card h3,.card .t{font-size:1.05rem;font-weight:700;letter-spacing:-.03em;margin-bottom:6px}
.card p{color:var(--ink2);font-size:.95rem;line-height:1.5}
.card .n{font-family:var(--mono);color:var(--blue);font-size:12px;letter-spacing:.06em}

/* superficie oscura: bloque de precios, cierre, prueba */
.card--dark{background:var(--dark);color:#fff;border-color:transparent;box-shadow:var(--sh)}
.card--dark p,.card--dark .lead{color:rgba(255,255,255,.72)}
.card--dark .mono{color:rgba(255,255,255,.5)}
.card--dark .precio em{color:rgba(255,255,255,.5)}

/* TARJETA DE PRECIO (las dos de /shopify, las dos de /landing) */
.tier{background:var(--card);border:1px solid var(--line);border-radius:var(--rs);padding:26px 24px;
  box-shadow:var(--sh-sm);display:flex;flex-direction:column}
.tier--destacada{background:var(--dark);color:#fff;border-color:transparent;box-shadow:var(--sh)}
.tier--destacada .tier-d,.tier--destacada .lista li{color:rgba(255,255,255,.8)}
.tier--destacada .precio em,.tier--destacada .precio .desde{color:rgba(255,255,255,.5)}
.tier--destacada hr{background:var(--line-d)}
.tier--destacada .tier-excl{border-color:var(--line-d);color:rgba(255,255,255,.6)}
.tier-t{font-size:1.35rem;font-weight:700;letter-spacing:-.04em;display:flex;align-items:center;
  gap:10px;flex-wrap:wrap}
.tier-d{font-family:var(--mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink2);line-height:1.6;margin-top:12px}
.tier hr{border:0;height:1px;background:var(--line);margin:20px 0}
/* exclusión ARRIBA, pegada al precio (SPEC §4 B4), no en el pie */
.tier-excl{font-size:.82rem;line-height:1.5;color:var(--ink3);border-left:2px solid var(--line);
  padding-left:10px;margin:14px 0 0}
.tier .btn{margin-top:auto}
.tier-pie{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink3);margin-top:10px;text-align:center}

/* insignia «el más elegido» — se marca el Pro, no el Esencial */
.badge{display:inline-block;background:var(--blue);color:#fff;font-family:var(--mono);font-size:10px;
  letter-spacing:.08em;text-transform:uppercase;border-radius:var(--rs);padding:4px 8px}
.badge--linea{background:transparent;color:var(--blue);border:1px solid var(--blue)}

/* LISTAS DE ALCANCE [CRO .buy ul] — entran como bloque, nunca por carácter */
.lista{list-style:none;display:flex;flex-direction:column;gap:9px;font-size:.95rem;margin:16px 0 20px}
.lista li{display:flex;gap:9px;align-items:flex-start;line-height:1.45}
.lista li svg{flex:none;margin-top:5px}
.lista--no li{color:var(--ink2)}
.lista--no li::before{content:'—';color:var(--ink3);flex:none;font-family:var(--mono)}

/* chips [HOME .chips] — entran con blur corto, no con 72px de recorrido */
.chips{display:flex;flex-wrap:wrap;gap:7px}
.chips span{font-family:var(--mono);font-size:11px;letter-spacing:.02em;background:rgba(23,23,23,.07);
  border-radius:var(--rs);padding:5px 9px;white-space:nowrap}
.card--dark .chips span,.tier--destacada .chips span{background:rgba(255,255,255,.1)}

/* clave→valor [CRO .kv] — la muestra del entregable */
.kv{display:flex;gap:10px;font-size:.9rem;line-height:1.5}
.kv .k{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--blue);flex:none;padding-top:3px;min-width:74px}

/* rejillas de uso general */
.grid{display:grid;gap:16px}
.grid--2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid--4{grid-template-columns:repeat(4,minmax(0,1fr))}

/* HERO de venta [CRO .hero-grid]: copy a la izquierda, caja de precio a la derecha.
   El precio queda en el primer viewport, <0.5 pantallas. */
.hero{padding:120px 0 40px;position:relative}
.hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:28px;align-items:start;margin-top:34px}
.hero-sub{color:var(--ink2);max-width:44ch;margin:0 0 26px;font-size:1.05rem;line-height:1.5}

/* barra de especificaciones: 4 celdas → 2x2 en móvil (SPEC §2 B2) */
.specs{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--rs);overflow:hidden}
.specs div{background:var(--bg);padding:16px 18px}
.specs .k{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink2);display:block;margin-bottom:5px}
.specs .v{font-size:1rem;font-weight:700;letter-spacing:-.03em}

/* cifras de prueba [HOME .stat] — el número puede llevar data-count */
.cifra b{display:block;font-size:clamp(26px,3.6vw,42px);font-weight:700;letter-spacing:-.045em}
.cifra span{font-family:var(--mono);font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink2);display:block;margin-top:6px;line-height:1.45}
.card--dark .cifra span{color:rgba(255,255,255,.55)}

/* caja de garantía / promesa (sin porcentajes inventados) */
.aviso{border:1px solid var(--line);border-radius:var(--rs);padding:20px 22px;background:var(--card)}
.aviso--acento{border-left:2px solid var(--blue);border-radius:0 var(--rs) var(--rs) 0}
.aviso b{display:block;margin-bottom:6px;letter-spacing:-.03em}
.aviso p{color:var(--ink2);font-size:.95rem;line-height:1.55}

/* post-pago publicado ANTES de pagar (CHECKLIST señal 10) */
.pasos{list-style:none;counter-reset:p;display:grid;gap:10px}
.pasos li{counter-increment:p;display:flex;gap:12px;align-items:flex-start;font-size:.95rem;
  line-height:1.5;color:var(--ink2)}
.pasos li::before{content:counter(p);font-family:var(--mono);font-size:11px;color:var(--blue);
  border:1px solid var(--line);border-radius:var(--rs);width:24px;height:24px;display:grid;
  place-items:center;flex:none}


/* =====================================================================
   12 · TABLAS  [nuevo — la home no tiene ninguna]
   Regla dura: el body NUNCA scrollea en horizontal. La tabla scrollea
   dentro de su propio contenedor (SPEC §2 B6, §3 B3, §4 B6).
   Toda tabla comparativa lleva .tabla-fuente con la FECHA de consulta.
   ===================================================================== */
.tabla-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--line);
  border-radius:var(--rs);background:var(--card)}
.tabla{width:100%;min-width:620px;font-size:.92rem}
.tabla th,.tabla td{padding:14px 16px;text-align:left;vertical-align:top;
  border-bottom:1px solid var(--line);line-height:1.45}
.tabla thead th{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink2);font-weight:500;white-space:nowrap;background:var(--bg)}
.tabla tbody tr:last-child td{border-bottom:0}
.tabla th[scope="row"]{font-weight:600;color:var(--ink);white-space:nowrap}
.tabla .col-nuestra{background:rgba(47,107,255,.05)}
.tabla thead .col-nuestra{color:var(--ink)}
.tabla .si{color:var(--blue);font-weight:700}
.tabla .no{color:var(--ink3)}
.tabla-fuente{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink3);margin-top:10px;line-height:1.6}
.tabla-fuente a{border-bottom:1px solid var(--line)}


/* =====================================================================
   13 · FAQ con <details>  [HOME index.html:289-295, con el bug arreglado]
   Bug #5 del dossier: hoy el <details> salta (148px constantes, sin frames
   intermedios). Aquí se anima con grid-template-rows 0fr→1fr, nunca height.
   Markup: <details><summary>…<i>+</i></summary><div class="faq-in">
             <div class="faq-c"><p>…</p></div></div></details>
   ===================================================================== */
details{background:var(--card);border-radius:var(--rm);padding:0 22px;overflow:hidden;
  border:1px solid var(--line)}
.qs{display:grid;gap:10px}
summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;
  gap:16px;padding:20px 0;font-size:16px;font-weight:600;letter-spacing:-.035em}
summary::-webkit-details-marker{display:none}
summary i{font-style:normal;font-size:20px;line-height:1;flex:0 0 auto;color:var(--ink2);
  transition:transform .35s var(--ease-ui),color .35s ease}
details[open] summary i{transform:rotate(45deg);color:var(--blue)}
.faq-in{display:grid;grid-template-rows:0fr;transition:grid-template-rows .35s var(--ease)}
details[open] .faq-in{grid-template-rows:1fr}
details.cerrando .faq-in{grid-template-rows:0fr}   /* la pone venta.js al cerrar */
.faq-c{overflow:hidden}
.faq-c > *{padding-bottom:22px}
.faq-c p{font-size:14.5px;line-height:1.6;letter-spacing:-.02em;color:var(--ink2);max-width:66ch}


/* =====================================================================
   14 · BLOQUE DE PAGO  [CRO cro-index.html:140-153]
   C5: entra PINTADO desde el HTML. Sin .rv, sin opacity:0 inicial.
   Stripe embebido en el bloque; el modal queda como respaldo.
   ===================================================================== */
.pago{background:var(--card);border:1px solid var(--line);border-radius:var(--rs);padding:24px;
  box-shadow:var(--sh-sm)}
.pago-metodos{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:14px;
  font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink2)}
.pago-metodos img{height:18px;width:auto;opacity:.8}
#checkout{position:relative;z-index:1;min-height:420px}

/* modal de respaldo */
#pago-modal{position:fixed;inset:0;z-index:120;display:none;align-items:flex-start;
  justify-content:center;background:rgba(14,15,18,.62);overflow-y:auto;padding:24px 12px}
#pago-modal.abierto{display:flex}
.pago-caja{background:#fff;border-radius:var(--rs);width:100%;max-width:460px;margin:auto;
  padding:14px;position:relative;min-height:520px}
.pago-cerrar{position:absolute;top:10px;right:10px;z-index:2;border:1px solid var(--line);
  background:#fff;border-radius:var(--rp);width:32px;height:32px;cursor:pointer;font-size:15px;
  line-height:1;color:var(--ink2)}
.pago-cerrar:hover{color:var(--ink)}
.pago-cargando{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink2)}
#pago-modal #checkout{padding-top:28px}


/* =====================================================================
   15 · BARRA STICKY DE COMPRA EN MÓVIL  (SPEC §0.7 — HIPÓTESIS etiquetada)
   Regla que ya nos mordió en Shopify y vive en CLAUDE.md:
   se oculta cuando hay menú, overlay o checkout abierto.
   C5: entra pintada, sin .rv. Solo ≤860px.
   ===================================================================== */
.lp-sticky-bar{position:fixed;left:0;right:0;bottom:0;z-index:45;display:none;
  align-items:center;justify-content:space-between;gap:12px;
  padding:10px 16px calc(10px + env(safe-area-inset-bottom,0px));
  background:rgba(220,220,217,.94);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-top:1px solid var(--line);
  transform:translateY(105%);transition:transform .3s var(--ease-ui)}
.lp-sticky-bar.visible{transform:none}
.lp-sticky-bar .p{font-weight:800;letter-spacing:-.03em;font-size:1.05rem;line-height:1.1}
.lp-sticky-bar .p em{display:block;font-style:normal;font-family:var(--mono);font-size:10px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink2);margin-top:2px}
.lp-sticky-bar .btn{padding:11px 18px;font-size:14px}
body.overflow-hidden .lp-sticky-bar{display:none!important}


/* =====================================================================
   16 · FOOTER  [HOME index.html:298-315]
   Oscuro, corte diagonal de 58px, wordmark con gradiente, .f-bot mono.
   OBLIGATORIO: enlaces legales reales. Y sin «V9 · prueba interna».
   El wordmark va SIN simbolo de marca registrada: no hay registro IMPI otorgado.
   ===================================================================== */
footer{position:relative;background:var(--dark);color:#fff;margin-top:var(--sec-dark);
  padding:120px 0 34px;clip-path:polygon(0 0,100% 58px,100% 100%,0 100%);overflow:hidden}
.f-top{display:grid;grid-template-columns:1.2fr 1fr 1fr 1fr;gap:36px}
.f-top .mono{color:rgba(255,255,255,.5)}
.f-mail{font-size:clamp(22px,3vw,34px);font-weight:700;letter-spacing:-.045em;text-transform:uppercase;
  display:inline-block;margin-top:12px;border-bottom:1px solid rgba(255,255,255,.25);padding-bottom:3px;
  transition:color var(--dur-ui) ease,border-color var(--dur-ui) ease}
.f-mail:hover{border-color:var(--blue);color:var(--blue)}
.f-tel{font-family:var(--mono);font-size:13px;color:rgba(255,255,255,.65);letter-spacing:.05em;margin-top:16px}
.f-col a{display:block;font-size:15px;letter-spacing:-.03em;padding:5px 0;color:rgba(255,255,255,.8);
  transition:color var(--dur-ui) ease}   /* bug #3: la home los tiene sin transición */
.f-col a:hover{color:#fff}
.wordmark{font-size:clamp(38px,12.6vw,182px);font-weight:700;letter-spacing:-.055em;text-transform:uppercase;
  line-height:.86;margin:70px 0 40px;
  background:linear-gradient(96deg,#fff 40%,#b9cdff 68%,var(--blue) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.f-bot{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  border-top:1px solid var(--line-d);padding-top:18px;font-family:var(--mono);font-size:11px;
  letter-spacing:.06em;text-transform:uppercase;color:rgba(255,255,255,.45)}
.f-bot a{transition:color var(--dur-ui) ease}
.f-bot a:hover{color:#fff}
/* línea fiscal: se escribe SIN RFC, SIN domicilio y SIN afirmar nada sobre IVA */
.f-fiscal{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:rgba(255,255,255,.45);margin-top:10px}


/* =====================================================================
   17 · MOVIMIENTO
   Solo lo aprobado en DOSSIER-MOVIMIENTO.md, en su versión de VENTA.
   ===================================================================== */

/* --- reveal genérico [HOME index:322-330], comprimido 1050ms → 700ms --- */
.rv{opacity:0;transform:translateY(72px);
  transition:opacity var(--dur-rv) ease,transform var(--dur-rv) var(--ease)}
.rv.on{opacity:1;transform:none}
.rv-far{transform:translateY(120px)}
/* al recargar a media página: lo que quedó arriba aparece SIN animar */
.settled,.settled *{transition:none!important;animation-delay:0s!important}
/* stagger opcional dentro de un bloque (máx 4 pasos; más es espera, no gesto) */
.rv-d1{transition-delay:.06s}.rv-d2{transition-delay:.12s}
.rv-d3{transition-delay:.18s}.rv-d4{transition-delay:.24s}

/* --- variante barata para chips, filas y listas: .55s + blur(10px)→0 ---
   Lo único que se adopta de /diseno-de-paginas-web/: 72px de recorrido en
   8 chips produce 8 recorridos largos que compiten con la lectura. */
.rv-blur{opacity:0;filter:blur(10px);transform:translateY(10px);
  transition:opacity var(--dur-blur) ease,filter var(--dur-blur) ease,transform var(--dur-blur) var(--ease)}
.rv-blur.on{opacity:1;filter:blur(0);transform:none}

/* --- tarjeta oscura del cierre que cae desde arriba (DOSSIER §3.9) ---
   Cortada a 450ms. A ≤860px el recorrido baja de 600px a 180px.
   El BOTÓN de dentro va pintado (C5): lo que cae es la tarjeta. */
.cae{opacity:0;transform:translateY(-600px);
  transition:opacity var(--dur-cae) ease,transform var(--dur-cae) var(--ease)}
.cae.on{opacity:1;transform:none}

/* --- entrada 3D comprimida: UN SOLO bloque por página (DOSSIER §3.17) --- */
.cap3d{perspective:3900px}
.cap3d img,.cap3d .m{transform:translateY(-10px) scale(.9) rotateX(30deg);opacity:0;
  transition:transform 900ms var(--ease),opacity 700ms ease}
.cap3d.on img,.cap3d.on .m{transform:none;opacity:1}
/* bug #1 del dossier: .on ganaba al :hover. Se escribe con .on delante. */
.cap3d.on:hover img,.cap3d.on:hover .m{transform:scale(1.035)}

/* --- trazos SVG que se dibujan entre los pasos del proceso (DOSSIER §3.12) ---
   Comprimido a 1100ms (Hanzo usa 1770ms: lento para vender). --- */
.traza path{stroke-dasharray:1;stroke-dashoffset:1;stroke-width:2;stroke-linecap:round;
  stroke-linejoin:round;fill:none;stroke:var(--blue);
  transition:stroke-dashoffset var(--dur-draw) var(--ease-draw)}
.traza.on path{stroke-dashoffset:0}
.traza.on path:nth-child(2){transition-delay:.3s}
.traza.on path:nth-child(3){transition-delay:.6s}


/* =====================================================================
   18 · RESPONSIVE  — móvil primero de verdad: 94-95% del tráfico es móvil
   ===================================================================== */
@media (max-width:1080px){
  .grid--4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid--3{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:880px){
  .hero-grid{grid-template-columns:1fr}
  .f-top{grid-template-columns:1fr 1fr}
}
@media (max-width:860px){
  :root{--pad:20px;--sec:64px;--sec-dark:84px}
  .nav-links,.cta-pill{display:none}
  .burger{display:grid}
  .hero{padding-top:96px}
  .grid--2,.grid--3,.grid--4{grid-template-columns:1fr}
  .specs{grid-template-columns:1fr 1fr}
  .lp-sticky-bar{display:flex}
  /* la barra sticky no puede tapar el final de la página ni el checkout */
  body{padding-bottom:76px}
  /* recorrido de la tarjeta que cae: 600px es una pantalla entera a 390 */
  .cae{transform:translateY(-180px)}
  /* sin rotateX en móvil: solo fade + 40px */
  .cap3d{perspective:none}
  .cap3d img,.cap3d .m{transform:translateY(40px)}
  .cap3d.on:hover img,.cap3d.on:hover .m{transform:none}
  .wordmark{margin:44px 0 28px}
  footer{padding-top:84px}
}
@media (max-width:520px){
  .f-top{grid-template-columns:1fr;gap:24px}
  .btn{width:100%}
  .cinturon{gap:4px 12px}
}


/* =====================================================================
   19 · prefers-reduced-motion  [HOME index:397-402]
   C3: estado final visible y getAnimations().length === 0.
   Nuestro bloque es más completo que el de las dos referencias juntas.
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation:none!important;transition:none!important}
  .rv,.rv-blur,.cae,.cap3d img,.cap3d .m{opacity:1!important;transform:none!important;filter:none!important}
  .rule{transform:scaleX(1)!important}
  .traza path{stroke-dashoffset:0!important}
  #menu{transition:none!important}
}


/* =====================================================================
   20 · SIN JS  [HOME index:403-408]
   La clase .js la pone un script inline en el <head>. Si el JS falla o
   está desactivado, la página se lee entera (Q2 del checklist).
   ===================================================================== */
html:not(.js) .rv,
html:not(.js) .rv-blur,
html:not(.js) .cae,
html:not(.js) .cap3d img,
html:not(.js) .cap3d .m{opacity:1!important;transform:none!important;filter:none!important}
html:not(.js) .rule{transform:scaleX(1)!important}
html:not(.js) .traza path{stroke-dashoffset:0!important}
html:not(.js) #prog{display:none}
html:not(.js) .lp-sticky-bar{transform:none}


/* =====================================================================
   21 · CORRECCIONES DE CONTRASTE Y DE BARRA STICKY  · 7-ago-2026
   Las tres páginas de venta parcheaban esto en su propio <style>. Aquí
   deja de ser un parche por página y pasa a ser la regla del núcleo.
   No se toca ningún token (PLAN-COHERENCIA §tokens dice «No editar»):
   se sobreescribe el COLOR DE USO donde el token no llega a AA.
   ===================================================================== */

/* 21.1 · --ink3 (#8b8b87) mide 2.49:1 sobre --bg y 3.42:1 sobre --card.
   AA pide 4.5:1. Y el texto afectado es justo el que nos protege: la
   coletilla del plazo, la fecha de corte de las tablas, lo que NO
   incluye cada paquete y la línea de facturación. La letra chica legal
   era la menos legible de la página. Medido después: 4.66:1 sobre --bg
   y 6.41:1 sobre --card. */
.nota,
.tabla-fuente,
.tabla .no,
.tier-excl,
.tier-pie,
.quiz .ph{color:#6a6a66}
.card .nota,.card .tier-pie,.card .tier-excl,
.tier .tier-pie,.tier .tier-excl,
.pago .nota{color:#5f5f5c}

/* 21.2 · Sobre fondo oscuro, .lista/.lista--no y .cinturon heredaban
   --ink2 (#5f5f5c) sobre --dark (#0e0f12) = 2.99:1. Afecta al bloque
   de honestidad «qué NO se migra» y al cinturón de la tarjeta Pro, que
   es donde vive la letra chica obligatoria del anticipo del 50 %.
   Medido después: 11.7:1. */
.card--dark .lista li,.card--dark .lista--no li,
.tier--destacada .lista li,.tier--destacada .lista--no li,
.card--dark .cinturon,.tier--destacada .cinturon,
.card--dark .cinturon span,.tier--destacada .cinturon span{color:rgba(255,255,255,.78)}
.card--dark .lista--no li::before,
.tier--destacada .lista--no li::before{color:rgba(255,255,255,.55)}
.card--dark .tier-excl,.tier--destacada .tier-excl,
.card--dark .tier-pie,.tier--destacada .tier-pie,
.card--dark .nota,.tier--destacada .nota{color:rgba(255,255,255,.62)}

/* 21.3 · La barra sticky tapaba el checkout embebido.
   El núcleo solo la escondía con body.overflow-hidden, que venta.js pone
   ÚNICAMENTE en la rama del modal. Las páginas que montan Stripe inline
   ([data-checkout-inline]) nunca pasan por ahí: medidos 73-76 px del
   formulario de tarjeta tapados a 390×844, con un botón «Apartar» encima.
   SPEC §0.7 exige que se oculte con el checkout abierto.
   Se cura sola: al destruir el checkout el div queda vacío. */
body:has(#pago-inline > *) .lp-sticky-bar{display:none!important}
body:has([data-checkout-inline] > *) .lp-sticky-bar{display:none!important}

/* 21.4 · Tablas comparativas: alcanzables por teclado (WCAG 2.1.1).
   A 390 px scrollean ~680 px dentro de una caja de ~350: sin tabindex un
   usuario de teclado nunca llega a la última columna. */
.tabla-wrap[tabindex]:focus-visible{outline:2px solid var(--blue);outline-offset:3px}

/* 21.5 · Aviso visible de fallo de cobro (lo dispara venta.js en el catch). */
#pago-fallo[hidden]{display:none}
#pago-fallo:focus{outline:2px solid var(--blue);outline-offset:2px}

/* =====================================================================
   §22 · LUZ, APARICIÓN Y EFECTOS DE TEXTO  (portado de la home, 7-ago-2026)
   Owen: «faltan los colores que tienen la home, elementos como luz; al entrar
   debe tener ese efecto de aparición; no hay efectos de escritura».
   Los valores son los MEDIDOS del index.html vivo, no aproximaciones.
   ===================================================================== */

/* ---- 22.1 · Blobs de luz --------------------------------------------
   Radiales exactos de la home. blur(74px) y opacity .6 por defecto; cada
   instancia ajusta tamaño/posición/opacidad por style="" como en la home.
   Van SIEMPRE dentro de un contenedor con position:relative y por debajo
   del contenido (el .blobs es z-index 0; el contenido debe ir en z-index 1). */
.blobs{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.blob{position:absolute;border-radius:50%;filter:blur(74px);opacity:.6;will-change:transform}
.b-blue{background:radial-gradient(circle,rgba(47,107,255,.95),rgba(47,107,255,0) 70%)}
.b-cyan{background:radial-gradient(circle,rgba(63,211,255,.9),rgba(63,211,255,0) 70%)}
.b-vio {background:radial-gradient(circle,rgba(125,92,255,.75),rgba(125,92,255,0) 70%)}
/* el contenido de una sección con blobs se levanta por encima de la luz.
   `footer > .wrap` se añadió el 7-ago-2026 al llevar luz al footer: el footer
   ya era position:relative + overflow:hidden, solo le faltaba levantar su
   contenido por encima del .blobs (z-index 0). */
.sec > .wrap, .hero > .wrap, .conluz > .wrap, footer > .wrap{position:relative;z-index:1}
.conluz{position:relative;overflow:hidden}

/* ---- 22.2 · Glow que sigue al cursor --------------------------------
   Solo puntero fino y ≥861px: en táctil no hay cursor que seguir.

   FIX 7-ago-2026 · Owen: «mouse sin el seguimiento de la luz».
   El bucle SÍ funcionaba —lerp medido 0.1200, idéntico al de la home— pero
   el glow estaba en z-index 1, IGUAL que en la home, y estas páginas son
   mucho más ricas en tarjetas blancas opacas que el escaparate. Medido con
   diff de píxeles a 1440 sobre /shopify/, con el cursor encima del contenido:
       z-index 1 (como la home) → Δ [0, 0, 0]     ← literalmente invisible
       z-index alto + multiply  → Δ [-34, -24, -1]
   Sobre el fondo desnudo las dos dan lo mismo (Δ ≈ [-9,-8,-1]), o sea que la
   luz que la home ya enseñaba NO cambia; lo que se gana es la superficie que
   antes tapaban las tarjetas.

   z-index 49 y no 59: por encima de TODO el contenido (el contenido vive en
   z-index 1 vía `.sec > .wrap`) y por debajo de la escalera de chrome, que no
   se tiñe nunca — header 50 · #menu 55 · grano 60 · #prog 70 · #intro 80 ·
   #pago-modal 120. Con 59 la píldora de pago del header quedaba teñida y la
   barra sticky de compra también; a 49 el checkout y la navegación se quedan
   con su color exacto y la luz solo toca el contenido.

   multiply y no normal, por el texto: multiply nunca aclara, así que el trazo
   del H1 se queda donde estaba (medido 23,23,23 → 20,21,23; contraste 12.19 →
   10.63, muy por encima de 4.5). Con blend normal el mismo trazo se levanta a
   26,33,55 y el contraste cae a 9.45 — la luz se comería el texto. */
#glow{position:fixed;width:520px;height:520px;left:0;top:0;border-radius:50%;pointer-events:none;z-index:49;
  mix-blend-mode:multiply;
  background:radial-gradient(circle,rgba(47,107,255,.16),rgba(47,107,255,0) 65%);
  transform:translate(-50%,-50%);opacity:0;transition:opacity .6s}
@media (max-width:860px){#glow{display:none}}
@media (hover:none){#glow{display:none}}
@media (prefers-reduced-motion:reduce){#glow{display:none}}

/* ---- 22.3 · Intro de entrada ----------------------------------------
   Mismo mecanismo que la home (capa que barre hacia arriba) pero a 1.2s en
   vez de 2.3s: esto es una página de VENTA y el precio no puede esperar.
   Se salta con cualquier interacción. Con reduced-motion no existe. */
#intro{position:fixed;inset:0;z-index:80;background:var(--bg);overflow:hidden;
  display:grid;place-items:center;transition:transform .8s cubic-bezier(.76,0,.24,1)}
#intro.go{transform:translateY(-100%)}

/* ---- RED DE SEGURIDAD DEL INTRO · 7-ago-2026 --------------------------
   Hasta hoy el intro SOLO lo movia el JS. Medido con Playwright: con
   /assets/venta.js bloqueado (cache envenenada, red caida, adblock, o un
   deploy que lanza al arrancar) #intro se quedaba tapando /shopify/,
   /landing/, /sitio-web/ y /legal/ PARA SIEMPRE: pantalla de marca, sin
   precio, sin contenido, y sin un solo error en consola. El precio pasaba
   de verse en 2.0 s a no verse NUNCA.
   Ahora el barrido lo arranca el CSS (1.42 s = los 1200 ms del temporizador
   + los 220 ms del blur, iguales que en el JS). Si venta.js SI llega, se
   apaga esta animacion en arrancaIntro() y manda el JS como siempre —
   incluido el salto por clic. Verificado: sano 1901 ms, clic temprano
   998 ms, js bloqueado 1885 ms, modulo roto 1999 ms. Antes: NUNCA. */
#intro{animation:introRed .8s cubic-bezier(.76,0,.24,1) 1.42s both}
@keyframes introRed{to{transform:translateY(-100%);visibility:hidden}}
html.intro-on,html.intro-on body{overflow:hidden}
.intro-wm{position:relative;z-index:2;text-align:center;
  transition:opacity .45s ease,filter .45s ease,transform .45s cubic-bezier(.4,0,.2,1)}
.intro-wm b{display:block;font-size:clamp(34px,5.4vw,72px);font-weight:800;letter-spacing:-.05em;
  text-transform:uppercase;line-height:1;color:var(--ink)}
.intro-wm i{display:block;font-family:var(--mono);font-style:normal;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink2);margin-top:14px;
  transition:opacity .3s ease,transform .3s ease}
.intro-wm i.sw{opacity:0;transform:translateY(-8px)}
.intro-wm.in{animation:wmIn .75s cubic-bezier(.16,1,.3,1) both}
.intro-wm.out{opacity:0;filter:blur(14px);transform:scale(1.05)}
@keyframes wmIn{from{opacity:0;filter:blur(16px);transform:scale(1.06)}to{opacity:1;filter:none;transform:none}}
/* sin JS o con reduced-motion, el intro nunca tapa nada */
html:not(.js) #intro{display:none}
@media (prefers-reduced-motion:reduce){#intro{display:none}html.intro-on,html.intro-on body{overflow:auto}}

/* ---- 22.4 · Rotador de frases (el 2º renglón que cambia solo) -------- */
.rot{display:block;min-height:1.15em}
.rot .rw{display:inline-block;color:var(--blue);
  transition:opacity .5s cubic-bezier(.4,0,.2,1),transform .5s cubic-bezier(.4,0,.2,1)}
.rot.swap .rw{opacity:0;transform:translateY(-16px)}
@media (prefers-reduced-motion:reduce){.rot .rw{transition:none}}

/* ---- 22.5 · RETIRADO: typewriter con cursor de bloque ---------------
   Aquí vivía `.tw::after{content:'█'; animation:twCaret 1.2s infinite}`.
   La home NO tiene ese efecto: es una invención de este núcleo que además
   dejaba una animación viva PARA SIEMPRE. Medido: la home deja 1 animación
   en reposo (el ticker); estas páginas dejaban 2 (tickMove + twCaret).
   Owen lo describió como «sigue sin verse como la home con las letras como
   aparecen» — el █ era justo lo que estaba viendo de más.
   Sustituido por §22.8, que es el mecanismo REAL de la home.
   No queda regla `.tw`: los `data-tw` se quitaron de las 3 páginas. */

/* ---- 22.6 · Ticker a 40 px/s ---------------------------------------- */
.tick{overflow:hidden;border-block:1px solid var(--line);padding:12px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.tick-in{display:flex;gap:44px;width:max-content;animation:tickMove var(--tk,60s) linear infinite}
.tick:hover .tick-in{animation-play-state:paused}
.tick span{font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink2);white-space:nowrap;display:inline-flex;align-items:center;gap:12px}
.tick span::after{content:'';width:5px;height:5px;border-radius:50%;background:var(--blue);opacity:.7}
@keyframes tickMove{to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.tick-in{animation:none}}

/* ---- 22.7 · Navegación: página actual y luz en el hover -------------- */
.nav-links a{position:relative}
.nav-links a[aria-current="page"]{color:var(--ink);font-weight:600}
.nav-links a[aria-current="page"]::before{content:'';position:absolute;left:0;right:0;bottom:-6px;height:2px;
  background:var(--blue);border-radius:2px}
.nav-links a::after{content:'';position:absolute;left:50%;right:50%;bottom:-6px;height:2px;background:var(--blue);
  border-radius:2px;opacity:0;transition:left .32s cubic-bezier(.16,1,.3,1),right .32s cubic-bezier(.16,1,.3,1),opacity .2s}
.nav-links a:hover::after{left:0;right:0;opacity:.55}
.nav-links a[aria-current="page"]::after{display:none}
#menu a[aria-current="page"]{color:var(--blue)}

/* el precio del nav es un precio: SIEMPRE con $ y con coma de millares.
   El `gap:6px` del inline-flex ya separa, pero si alguien cambia el display
   este margen impide el «Landing4999» que medimos en /landing/. */
.nav-links a sup{margin-left:.15em}


/* =====================================================================
   §22.8 · APARICIÓN DEL TEXTO — el mecanismo real de la home
   -----------------------------------------------------------------
   Owen: «sigue sin verse como la home con las letras como aparecen».
   Medido antes de esto: la home tiene 96 `.w` + 349 `.ch` + 10 reglas CSS;
   estas 4 páginas tenían 0 · 0 · 0. Revelaban BLOQUES enteros (.rv, 72px,
   700ms); la home revela PALABRAS y CARACTERES. Por eso «aparecen» las dos
   y aun así no se parecen.

   GANCHO NEUTRO, y esto no es opcional: `[data-palabras]` y `[data-split]`,
   NUNCA `.h1 .w` / `.h2 .w` como la home. En la home `.h1` es uppercase de
   128px; aquí `.h1` es tipografía de VENTA (57.6px, text-transform:none,
   SPEC §0.4, medida en la única página que cobra). Colgarse de `.h1`
   arrastraría la tipografía de la home a las páginas de venta.

   `.w` envuelve PALABRAS con white-space:nowrap y los espacios quedan FUERA,
   como nodos de texto normales. Ese envoltorio es lo único que impide el bug
   «evide/ncia» que ya nos mordió: una animación por carácter sin envoltura
   por palabra deja que el navegador rompa la línea a media palabra.
   Verificado a 360/390/768/1440: getClientRects().length === 1 en todos.

   Valores: los MEDIDOS del index.html vivo, no aproximaciones.
   ===================================================================== */

/* ---- el envoltorio, común a los dos sistemas ---- */
.w{display:inline-block;white-space:nowrap}
.ch{display:inline-block;white-space:pre}

/* ---- por PALABRA, con escala — el H1 del hero [HOME index:102-104,332-333]
   Sube 40px y des-escala desde 1.16. NO es un fade: hay translate Y escala.
   900ms, cubic-bezier(.16,1,.3,1), stagger 55ms por palabra.
   Curva medida en la home desde .on:
     0ms=40px/1.16/op0 · 278ms=12.56/1.0503/.221 · 377ms=4.43/1.0177/.542
     · 652ms=0.61/1.0024/.867 · 937ms=0/1/.997                              */
[data-palabras] .w{
  transform:translateY(40px) scale(1.16);opacity:0;
  transition:transform .9s var(--ease),opacity .9s ease}
.on [data-palabras] .w,[data-palabras].on .w{transform:none;opacity:1}

/* ---- por PALABRA, sin escala — los H2 de sección [HOME index:145-147]
   Sube .3em y aparece. 800ms, mismo stagger de 55ms. Sin escala: a 35px de
   H2 de venta, un scale(1.16) se lee como un rebote y la home no lo hace. */
[data-palabras="suave"] .w{
  transform:translateY(.3em) scale(1);
  transition:transform .8s var(--ease),opacity .8s ease}

/* ---- por CARÁCTER — los párrafos [HOME index:861-896]
   SOLO opacity: los caracteres no se mueven, no escalan y no llevan blur.
   500ms cada uno, stagger 17ms (medido 16.7-20.1ms, la diferencia es
   cuantización de rAF). El JS acota el stagger para que ningún párrafo
   tarde más que el de la home — ver venta.js parteChars(). */
[data-split] .ch{opacity:0;transition:opacity .5s ease}
.on [data-split] .ch,[data-split].on .ch{opacity:1}

/* ---- ACCESIBILIDAD — tres candados -------------------------------------
   1) sin JS no hay .w ni .ch, pero si alguna vez los hubiera (HTML servido
      con spans) el texto se pinta igual;
   2) con reduced-motion el JS ni siquiera parte el texto, y esto lo remata;
   3) el texto NUNCA depende de una animación para ser legible.            */
/* FIX 7-ago-2026 · `marca()` en venta.js dice "visible YA, sin animar" y le pone
   .settled, pero no habia ninguna regla que saltara la transicion: al recargar a media
   pagina, un parrafo de 113 caracteres seguia encendiendose letra por letra 2.4 s
   despues, con caracteres todavia en opacity:0. Medido y corregido en /cro/ primero. */
[data-palabras].settled .w,
.settled [data-palabras] .w,
[data-split].settled .ch,
.settled [data-split] .ch{transition:none}

html:not(.js) [data-palabras] .w,
html:not(.js) [data-split] .ch{opacity:1!important;transform:none!important}
@media (prefers-reduced-motion:reduce){
  [data-palabras] .w,[data-split] .ch{
    opacity:1!important;transform:none!important;transition:none!important}
}

/* =====================================================================
   §23 · VSL — el video de Owen  (7-ago-2026)
   Owen: «agrega este vsl corto a cada servicio · aquí se vería bien en la
   derecha y en mobile debajo · crea botones y animaciones de video que
   combinen con todo lo que tenemos».
   Va en una banda DEBAJO del hero, no dentro: la columna derecha del hero
   la ocupa el precio, y el precio no se mueve del primer viewport.
   ===================================================================== */
.vsl-sec{padding-block:clamp(48px,7vw,86px)}
.vsl-grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(28px,4vw,64px);align-items:center}
@media (max-width:900px){
  .vsl-grid{grid-template-columns:minmax(0,1fr);gap:26px}
  /* «en mobile debajo»: el texto primero, el video después */
  .vsl-copy{order:1}.vsl{order:2}
}
.vsl-copy p{max-width:46ch}
.vsl-lista{list-style:none;padding:0;margin:18px 0 0;display:grid;gap:9px}
.vsl-lista li{display:flex;gap:10px;align-items:flex-start;color:var(--ink2);line-height:1.5}
.vsl-lista li::before{content:'';flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  background:var(--blue);margin-top:.55em}

/* ---- la tarjeta del video ---- */
.vsl{position:relative;margin:0;border-radius:20px;overflow:hidden;background:var(--dark);
  aspect-ratio:16/9;
  box-shadow:0 1px 1px rgba(23,23,23,.04),0 2px 4px rgba(23,23,23,.04),0 6px 12px rgba(23,23,23,.05),
             0 12px 24px rgba(23,23,23,.05),0 24px 48px rgba(23,23,23,.06),0 48px 96px rgba(23,23,23,.07);
  transition:transform .6s cubic-bezier(.16,1,.3,1),box-shadow .6s cubic-bezier(.16,1,.3,1)}
.vsl video{display:block;width:100%;height:100%;object-fit:cover;background:var(--dark)}
/* velo que se va al reproducir: da contraste al botón sin apagar la imagen */
.vsl::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(14,15,18,.10) 0%,rgba(14,15,18,.42) 100%);
  transition:opacity .5s ease}
.vsl.reproduciendo::after{opacity:0}
.vsl:not(.reproduciendo):hover{transform:translateY(-3px)}
.vsl:not(.reproduciendo):hover video{transform:scale(1.03)}
.vsl video{transition:transform 1.1s cubic-bezier(.16,1,.3,1)}

/* ---- botón de reproducir ---- */
.vsl-play{position:absolute;inset:0;width:100%;height:100%;display:flex;align-items:center;
  justify-content:center;gap:14px;background:none;border:0;cursor:pointer;color:#fff;
  font-family:inherit;font-size:15px;font-weight:600;letter-spacing:-.01em;
  transition:opacity .35s ease}
.vsl.reproduciendo .vsl-play{opacity:0;pointer-events:none}
.vsl-ico{position:relative;flex:0 0 auto;width:62px;height:62px;border-radius:50%;
  background:var(--blue);display:grid;place-items:center;
  box-shadow:0 10px 30px rgba(47,107,255,.45);
  transition:transform .45s cubic-bezier(.16,1,.3,1),box-shadow .45s ease}
.vsl-ico svg{width:20px;height:22px;margin-left:3px;fill:#fff}
/* anillo que late: el mismo azul de la casa, no un rojo de YouTube */
.vsl-ico::before{content:'';position:absolute;inset:-8px;border-radius:50%;
  border:1px solid rgba(47,107,255,.55);animation:vslPulso 2.6s cubic-bezier(.16,1,.3,1) infinite}
@keyframes vslPulso{0%{transform:scale(.92);opacity:.9}70%{transform:scale(1.28);opacity:0}100%{opacity:0}}
.vsl-play:hover .vsl-ico,.vsl-play:focus-visible .vsl-ico{transform:scale(1.08);
  box-shadow:0 14px 40px rgba(47,107,255,.6)}
.vsl-play:focus-visible{outline:2px solid var(--blue);outline-offset:4px;border-radius:20px}
.vsl-txt{text-shadow:0 1px 12px rgba(14,15,18,.6)}
@media (max-width:640px){.vsl-ico{width:54px;height:54px}.vsl-txt{font-size:14px}}

/* ---- pie de la tarjeta ---- */
.vsl-cap{position:absolute;left:14px;bottom:12px;right:14px;display:flex;justify-content:space-between;
  gap:12px;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:rgba(255,255,255,.82);pointer-events:none;transition:opacity .35s ease}
.vsl.reproduciendo .vsl-cap{opacity:0}


/* ---- 23.1 · en movil el VSL se muda DEBAJO DEL PRECIO (7-ago-2026) -------
   Owen: «en mobile ponlo debajo del precio». El bloque vive despues del hero
   —ahi la columna derecha es del precio y el precio no se mueve del primer
   viewport—, pero en movil no hay columnas: el video sube a pegarse al precio,
   que es donde el comprador ya esta decidiendo. Lo mueve venta.js (colocaVsl)
   y vuelve solo a su sitio al pasar a escritorio. */
.vsl-sec.en-hero{padding:0;margin:20px 0 0}
.vsl-sec.en-hero > .wrap{padding:0;max-width:none}
.vsl-sec.en-hero .blobs{display:none}      /* el hero ya tiene su propia luz */
.vsl-sec.en-hero .vsl{order:1}             /* el video, pegado al precio */
.vsl-sec.en-hero .vsl-copy{order:2}
.vsl-sec.en-hero .vsl-copy .sec-head{margin-top:4px}

/* nada se mueve solo si el sistema lo pide */
@media (prefers-reduced-motion:reduce){
  .vsl-ico::before{animation:none}
  .vsl,.vsl video,.vsl-ico{transition:none}
  .vsl:not(.reproduciendo):hover{transform:none}
  .vsl:not(.reproduciendo):hover video{transform:none}
}

/* ---- 23.2 · cinta de marcas, encima del video (7-ago-2026) --------------
   Owen: «un banner que se mueve de lado a lado arriba del video de todas las
   marcas que trabajamos». Misma mecánica y misma velocidad que el ticker de
   texto (40 px/s, medidos en la home), y los logos en la tinta de la casa al
   58 % — NO en sus colores: cuatro paletas distintas en 60 px de alto no son
   un sistema, son un collage. Al pasar el mouse suben a tinta plena.
   Los logos son los archivos REALES de cada marca, tratados; no recreaciones. */
/* FIX 7-ago-2026 · la mascara iba en .marcas y se comia la primera letra de la
   etiqueta y los extremos de las dos lineas. Ahora vive en .marcas-pista, que
   solo envuelve a los logos en movimiento: el borde cruza entero y el texto se
   lee completo. El degradado tambien se acorto de 7% a 3.5%. */
.marcas{position:relative;margin:0 0 clamp(22px,3vw,34px);padding:14px 0;
  border-block:1px solid var(--line)}
.marcas-pista{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 3.5%,#000 96.5%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 3.5%,#000 96.5%,transparent)}
.marcas-et{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink3);margin-bottom:12px}
.marcas-in{display:flex;align-items:center;gap:clamp(38px,5vw,72px);width:max-content;
  animation:marcasMove var(--mk,42s) linear infinite}
.marcas:hover .marcas-in{animation-play-state:paused}
@keyframes marcasMove{to{transform:translateX(-50%)}}
.marcas img{display:block;width:auto;opacity:.58;
  transition:opacity .35s ease,transform .35s cubic-bezier(.16,1,.3,1)}
.marcas img:hover{opacity:1;transform:translateY(-2px)}
/* altura por marca: un escudo vertical y una tipografía ancha NO pueden medir
   igual, se ven desequilibrados. Calibrado a ojo sobre la tira de contacto. */
.marcas .m-zully  {height:44px}
.marcas .m-succeso{height:26px}
.marcas .m-zaiva  {height:29px}
.marcas .m-cade   {height:30px}
@media (max-width:640px){
  .marcas .m-zully{height:38px}.marcas .m-succeso{height:22px}
  .marcas .m-zaiva{height:25px}.marcas .m-cade{height:26px}
  .marcas-in{gap:34px}
}
@media (prefers-reduced-motion:reduce){
  .marcas-in{animation:none;width:100%;justify-content:space-around;flex-wrap:wrap;gap:24px}
  .marcas-in > :nth-child(n+5){display:none}   /* sin movimiento, no se duplica */
}

/* FIX 7-ago-2026 · `.marcas-in` mide max-content (870px con los 8 logos). Al
   mudar la seccion DENTRO de .hero-grid en movil, esa medida intrinseca inflaba
   la columna y sacaba /cro/ a 870px de ancho a 390. Es el mismo patron de
   siempre: una caja de rejilla no encoge por debajo de su contenido salvo que
   se le diga. Medido: 870 -> 390, 0 desborde. */
.vsl-sec,.vsl-sec > .wrap,.vsl-grid,.marcas,.vsl-copy{min-width:0}
.marcas{max-width:100%}

/* FIX 7-ago-2026 · la flecha pasa a ser pseudo-elemento.
   Motivo: la herramienta de Meta lee el TEXTO del boton, y «Lo quiero ↓» y
   «Lo quiero ↗» son textos distintos — obligarian a tres reglas en vez de una.
   Como pseudo-elemento la flecha se ve igual pero NO forma parte del texto:
   los 21 botones dicen exactamente «Lo quiero» para Meta, y cada uno conserva
   su direccion (↗ abre el pago · ↓ baja al bloque · ↑ sube). */
[data-flecha]::after{content:attr(data-flecha);margin-left:.5em;display:inline-block;
  transition:transform .3s cubic-bezier(.16,1,.3,1)}
[data-flecha]:hover::after{transform:translate(2px,-2px)}
[data-flecha="↓"]:hover::after{transform:translateY(3px)}
[data-flecha="↑"]:hover::after{transform:translateY(-3px)}

/* la pista no debe crecer con su contenido: en /shopify/ a 390 media 2618px */
.marcas-pista{min-width:0;max-width:100%;width:100%}

/* FIX 7-ago-2026 · en /shopify/ el .hero-grid es FLEX, y un elemento flex se
   dimensiona por su contenido: la cinta de marcas (7,039px con los juegos
   repetidos) estiraba la seccion entera. No se veia porque .conluz recorta,
   pero la mitad de la pista dejaba de cubrir la caja y la cinta parecia
   acabarse. Se fuerza a ocupar exactamente el ancho disponible. */
.vsl-sec.en-hero{flex:1 1 100%;width:100%;max-width:100%;min-width:0}
