/* Revva — landing de validación. Mobile-first.
   Sistema cromático 2026-07-31 (dirección de Jorge, referencia qoves ~90%):
   tres familias — MINERAL (azules #52646A/#60757D/#8299A5 + halo clínico #B6CEDB),
   NEUTROS (hueso #F3EFE7 · tinta #172024) y LATÓN (#CDB06A) SOLO como señal
   instrumental (retícula, puntos, indicadores) — nunca superficie ni decoración.
   Proporción de marca ~55% mineral · 25% hueso · 17% tinta · 3% latón.
   Tipografía con funciones estrictas: Cormorant Garamond (hero y titulares
   principales, peso 500) · Instrument Sans (todo el producto: nav, párrafos,
   botones, formularios) · IBM Plex Mono (SOLO datos y etiquetas de medición).
   Las tres OFL y AUTOALOJADAS (assets/fonts/): ni una petición a Google. */

/* Fuentes propias — subconjunto latin (basta para español) servido desde nuestro dominio */
@font-face{font-family:'Cormorant Garamond';src:url('assets/fonts/cormorant-garamond-var-latin.woff2') format('woff2');
  font-weight:400 700;font-style:normal;font-display:swap}
@font-face{font-family:'Instrument Sans';src:url('assets/fonts/instrument-sans-var-latin.woff2') format('woff2');
  font-weight:400 700;font-style:normal;font-stretch:100%;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('assets/fonts/plexmono-400-latin.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('assets/fonts/plexmono-500-latin.woff2') format('woff2');
  font-weight:500;font-style:normal;font-display:swap}

:root{
  --ink:#172024;
  --min-d:#52646A; --min-m:#60757D; --min-l:#8299A5; --halo:#B6CEDB;
  --bone:#F3EFE7; --paper:#FAF8F3;
  --brass:#CDB06A; --brass-text:#77622E; /* latón oscurecido: AA sobre hueso */
  --line:#DFD9CC; --cap:#52646A; --body-2:#28343A;
  --bone-dim:#D6E0E7; /* texto secundario sobre mineral */
  /* ESCALA TIPOGRÁFICA (2026-08-10) — SIETE peldaños, y ninguno suelto.
     Por qué existe: el censo (`_qa_censo_tipografia.py`) midió la pantalla de resultado a
     390 px y encontró **16 tamaños distintos, ocho de ellos entre 13,3 y 17,9 px** — o sea,
     el documento entero repartido en peldaños que se diferencian entre un 1 % y un 9 %.
     Nadie ve esa diferencia: lo que se ve es «todo del mismo tamaño», que es exactamente lo
     que dijo Jorge («se ve todo uniforme, no destaca nada»). Y el salto del titular al
     cuerpo era **×1,9** contra el ×4-5 de la referencia declarada
     (`referencias/qoves-landing-analisis.md` §2: titular 64-88 px sobre cuerpo 16-18).
     Cada tamaño nuevo que no sea uno de estos siete vuelve a aplanar la página. Si hace
     falta un peldaño más, se añade AQUÍ y se justifica; no se escribe un `.87rem` local. */
  --t-mono:.6rem;      /*  9,6  etiquetas y pies de medición (mono, versalitas) */
  --t-fine:.82rem;     /* 13,1  letra pequeña: legal, teaser, notas, pies de tarjeta */
  --t-body:.95rem;     /* 15,2  cuerpo */
  --t-lead:1.18rem;    /* 18,9  entradilla y estados */
  --t-card:clamp(1.08rem,4.2vw,1.32rem);  /* 17,3-21,1  titular de tarjeta y hallazgo */
  --t-h3:clamp(1.6rem,5.6vw,2.2rem);      /* 21,8-35,2  titular de sección secundaria */
  --t-h2:clamp(2rem,8.4vw,3.4rem);        /* 32,8-54,4  el ÚNICO display de la pantalla */
  --serif:'Cormorant Garamond',Georgia,serif;
  --sans:'Instrument Sans',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --pad:22px; --maxw:1120px;
  /* Alto reservado para la barra flotante (píldora ≈62px + su separación superior). Existe
     desde el plan 007: el hero móvil necesita saber cuánto ocupa la nav para reservarle
     banda sobre el rostro — sin eso la barra caía sobre la frente. Los tres sitios que ya
     usaban 96px lo derivan de aquí; el valor computado es idéntico al de antes. */
  --nav-h:72px;
  /* pulsación (señal en el pointer-down): compresión de control discreto, compresión
     de superficie grande, atenuación de texto/filas y duración única del gesto */
  --press:.97; --press-lg:.985; --press-dim:.6; --press-dur:.1s;
  /* anillo de foco: cambia de color con la superficie (ver bloque de foco más abajo) */
  --focus:var(--ink);
  /* error: el mismo tono terracota que ya usaba el gate de la foto, con su contrapartida
     clara para superficies oscuras — #9A4525 sobre tinta se queda en 2,6:1 */
  --err:#9A4525;

  /* CAMPO MINERAL — UNA sola receta (2026-08-05). Hasta hoy había dos superficies minerales
     que se parecían pero no eran el mismo material: el hero con este degradado y la puerta
     de email con `--min-m` liso más dos halos de 70px de desenfoque animados en bucle. Se
     unifica en el degradado del hero, que es el que ya está medido, y de paso caen los dos
     halos: hacían que el fondo NO fuera determinista bajo un panel translúcido y eran la
     capa más cara de pintar en un móvil.
     Los valores son EXACTAMENTE los que tenía `#hero-v5` — extraerlos aquí es un refactor
     sin cambio visual, no un rediseño del hero. `--campo` es el de ≥1240px (diagonal, aclara
     hacia el retrato) y `--campo-v` el de apilado. */
  --campo-v:linear-gradient(180deg,rgba(23,32,36,.28) 0%,rgba(23,32,36,0) 20%),
    linear-gradient(180deg,#4D5E66 0%,#61747D 55%,#8299A5 100%);
  --campo:linear-gradient(180deg,rgba(23,32,36,.28) 0%,rgba(23,32,36,0) 20%),
    linear-gradient(100deg,#4F6069 0%,#576870 36%,#62757E 52%,#7E939D 64%,#53646C 82%,#4B5B63 100%);
  /* grano de dithering del campo (ver hero-v5.css para el porqué de cada parámetro) */
  --campo-grano:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='170' height='170'><filter id='n' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncA type='discrete' tableValues='1'/></feComponentTransfer></filter><rect width='170' height='170' filter='url(%23n)'/></svg>");
}

/* Superficie de campo reutilizable: la usan el hero, la pantalla de entrada del flujo y la
   puerta de email. El grano va en ::before con `overlay` e `isolation:isolate`, igual que
   en el hero, para que la mezcla sea determinista y no toque a lo que va encima. */
.campo{background:var(--campo-v);isolation:isolate}
.campo>*{position:relative;z-index:1}
.campo::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  opacity:.1;mix-blend-mode:overlay;background-size:170px 170px;background-image:var(--campo-grano)}
@media(min-width:1240px){.campo{background:var(--campo)}}
*{box-sizing:border-box;margin:0;padding:0}
/* OJO al ocultar con el atributo `hidden`: lo pinta la hoja del NAVEGADOR con
   `display:none`, y eso pierde contra cualquier clase que fije un `display`. Un panel con
   `display:flex` se queda a la vista aunque el JS lo oculte (pasó el 2026-08-04 con el
   esqueleto y el panel de error del checkout: los tres estados se veían a la vez, y las
   sondas daban verde porque miraban la propiedad `.hidden`, no lo que se pinta).
   La regla es dar el display SOLO cuando el elemento no está oculto —
   `.lo-que-sea:not([hidden]){display:flex}` — y NO poner aquí un `[hidden]{...!important}`
   global: reventaría el crossfade de `.ipanel`, que transiciona `display` con
   `allow-discrete` y necesita seguir pintándose 150 ms mientras se funde. */
html{scroll-behavior:smooth}
body{background:var(--bone);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}

/* tipografía */
/* Cormorant: altura de x pequeña — al mismo cuerpo pesa menos en pantalla, así que
   los tamaños display suben respecto al sans y el peso se fija en 500 (elegancia
   sin perder autoridad; ni cursivas ni pesos finos). */
.serif{font-family:var(--serif);font-weight:500;line-height:.95;letter-spacing:-.02em}
.mono{font-family:var(--mono);font-weight:400;font-size:.66rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--cap)}
h1{font-family:var(--serif);font-weight:500;font-size:clamp(3rem,13.5vw,6.4rem);line-height:.92;
  letter-spacing:-.025em}
h2{font-family:var(--serif);font-weight:500;font-size:clamp(2.2rem,8.6vw,3.7rem);line-height:.98;
  letter-spacing:-.02em}
p.lead{font-size:clamp(1rem,4.4vw,1.18rem);color:var(--body-2);max-width:40ch}
h1+p,h2+p{margin-top:18px}
.muted{color:var(--cap)}

/* wordmark — logotipo principal: la palabra REVVA en Instrument Sans Medium,
   mayúsculas con tracking, y un punto de latón bajo el vértice de cada V (el rasgo
   propio de la marca: el landmark de medición). Color por contexto: hueso sobre el
   hero, tinta sobre fondos claros; el punto va latón sobre oscuro y latón-texto
   sobre claro (#CDB06A sobre hueso se queda en 1,9:1 y desaparece).

   `font-kerning:none` no es un detalle: los másteres vectoriales de
   identidad/masters/ se construyen SIN kerning GPOS, así que desactivarlo aquí hace
   que el texto vivo y el vector sean idénticos por construcción, no por suerte.
   Con tracking de .3em el kerning es ruido de todas formas.

   Las cotas .3053em / 1.3363em salen de las métricas reales de Instrument Sans 500
   (vértice de la V medido sobre el contorno: 365,3/1000 em; avance de la V: 731) y
   están verificadas contra Chrome: el ancho medido de .vv es 2,062em, exactamente el
   que predice la fuente, y el punto cae en el vértice con desviación de 0,003em
   (identidad/generator/_qa_dot_sitio.py, render diferencial con/sin punto).
   El .80em vertical + el radio .06em pone el centro en .86em, que es la línea base
   (medida: 0,8583em de la caja de .vv; Chrome la redondea a píxel entero, así que a
   16px cae en .875em y a 14,4px en .8333em — el desvío resultante es de décimas de
   píxel). Depende de que .wordmark mantenga line-height:1. */
.wordmark{font-family:var(--sans);font-weight:500;font-size:1rem;letter-spacing:.3em;
  line-height:1;display:inline-flex;align-items:baseline;text-transform:uppercase;
  font-kerning:none;--dot:var(--brass)}
footer .wordmark,.scbrand .wordmark,nav .pill .wordmark{color:var(--ink);--dot:var(--brass-text)}
.wordmark .vv{position:relative}
.wordmark .vv::before,.wordmark .vv::after{content:"";position:absolute;top:.80em;
  width:.12em;height:.12em;border-radius:50%;background:var(--dot);pointer-events:none}
.wordmark .vv::before{left:.3053em}
.wordmark .vv::after{left:1.3363em}

/* botones — sin sombras, sin degradados: primario hueso/tinta (tinta/hueso en claro) */
/* transición con propiedades EXPLÍCITAS: `transition:.25s ease` computa `all` y anima
   cualquier propiedad que cambie, incluidas las de layout. */
.btn{display:inline-flex;align-items:center;gap:.6em;font-family:var(--sans);font-weight:500;
  font-size:.92rem;padding:.95em 1.5em;border-radius:999px;border:1px solid var(--ink);
  transition:background-color .18s ease,border-color .18s ease,color .18s ease,
    transform var(--press-dur) ease-out;cursor:pointer}
.btn-solid{background:var(--ink);color:var(--bone)}
.btn-solid:hover{background:#000}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{border-color:var(--ink)}
.btn-lg{width:100%;justify-content:center;font-size:1rem;padding:1.1em 1.5em}

/* ---- feedback de pulsación (transversal a todas las páginas: styles.css es la única hoja común) ----
   La señal llega al pointer-down, no al soltar: hasta 2026-08-04 no había NI UNA regla
   :active en el sitio y ningún control respondía hasta procesarse el click. Dos gestos:
   · lo discreto (pastilla, chip, tab) se COMPRIME — scale(.97): en una pastilla de
     ~180 px son ~3 px por borde, señal de instrumento, no rebote;
   · lo grande y lo textual no puede comprimirse igual: un .btn-lg de ~660 px a .97
     movería ~10 px por borde, así que las superficies anchas van a .985 (~5 px) y el
     texto y las filas ATENÚAN opacidad, que es el highlight clásico de un enlace.
   100 ms ease-out (a esa duración una curva más elaborada no se lee) y solo
   transform/opacity — nada de layout. La vuelta usa la misma transición: soltar
   responde igual de rápido que pulsar. Las clases de las otras hojas (chipbtn, itab,
   pay-action…) se listan con :where() —especificidad 0— para que el sistema viva en un
   único sitio; donde una clase no existe, el selector no hace nada. El tap-highlight
   nativo se retira SOLO donde damos señal propia (si no, en Android se veían las dos). */
:where(.btn,.chipbtn,.itab,.pay-action,.linkbtn,.acc-h,.checkout-back,.brand,.ntext,
  .fnav a,nav .links a,footer .fl a){-webkit-tap-highlight-color:transparent}
:where(.btn,.chipbtn,.itab):active{transform:scale(var(--press))}
:where(.btn-lg,.pay-action):active{transform:scale(var(--press-lg))}
:where(.btn[aria-disabled="true"]):active{transform:none}
:where(.linkbtn,.acc-h,.checkout-back,.brand,.ntext,.fnav a,nav .links a,footer .fl a){
  transition:opacity var(--press-dur) ease-out}
:where(.linkbtn,.acc-h,.checkout-back,.brand,.ntext,.fnav a,nav .links a,footer .fl a):active{
  opacity:var(--press-dim)}

/* ---- foco visible (transversal a todas las páginas: styles.css es la única hoja común) ----
   Hasta 2026-08-04 no había NI UNA regla `:focus-visible` propia: los 9 controles del
   camino del dinero caían al anillo por defecto de Chrome —rgb(16,16,16)—, que sobre el
   panel de tinta del paywall mide 1,11:1 contra el panel y solo se lee porque bordea la
   pastilla hueso; en la tarjeta de email convivía además con el anillo de latón que sí
   definen los dos inputs (dos lenguajes de foco en la misma tarjeta).
   Es un TOKEN y no un color fijo porque el anillo tiene que cambiar con la superficie:
   tinta sobre claro (14,4:1) y latón sobre oscuro (7,9:1 sobre tinta). El latón sobre
   hueso se quedaría en 1,9:1 — la misma regla que ya aplica `--dot`.
   `:where()` (especificidad 0) para que cualquier hoja pueda afinarlo sin pelearse. */
.paywall,.product-card,#precio,body.an.email-active,body.an.intro-active{--focus:var(--brass);--err:#EDA085}
:where(a,button,input,select,textarea,summary,
  .btn,.chipbtn,.linkbtn,.pay-action,.acc-h,.itab):focus-visible{
  outline:2px solid var(--focus);outline-offset:2px}
/* los titulares de paso reciben el foco al cambiar de paso (solo para anunciar): sin anillo */
:where(h1,h2,h3)[tabindex="-1"]:focus{outline:none}

/* progreso móvil (regla en desktop). Se escala en X en vez de animar `width`: la barra se
   actualiza en cada evento de scroll y `width` es layout+paint por frame; `transform` va al
   compositor. js/nav.js escribe scaleX(0..1). */
#bar{position:fixed;top:0;left:0;height:2px;background:var(--brass);width:100%;z-index:60;
  transform:scaleX(0);transform-origin:left center;transition:transform .1s linear}
#ruler{display:none}

/* nav de las páginas de flujo (analisis.html): vidrio hueso sencillo */
nav{position:fixed;top:0;left:0;right:0;z-index:50;display:flex;justify-content:center;
  padding:12px;pointer-events:none}
nav .pill{pointer-events:auto;display:flex;align-items:center;gap:16px;
  /* OPACA, y por un defecto medido, no por gusto (feedback de Jorge, 2026-08-10 §5): la
     pastilla ocupa casi todo el ancho en móvil, así que la barra de pasos pasa POR DEBAJO al
     hacer scroll — y con relleno al .72/.93 más blur no quedaba tapada, quedaba **fantasma**:
     «se mete debajo de la pastilla del logo y se lee a medias». Con hueso pleno, lo que pasa
     por debajo desaparece limpiamente en vez de leerse a medias.
     De paso cae el `backdrop-filter`, que sobre relleno opaco no pinta nada y era la capa más
     cara del scroll en un móvil. El vidrio sigue vivo donde SÍ tiene función: la isla oscura
     de la home (`nav.ndark .nvw`), que flota sobre el hero.
     El canto y la sombra se quedan: son la separación que se decidió el 10-08 por la mañana
     —la pastilla es hueso y las pantallas de DOCUMENTO también, y el canto de .08 no separaba
     nada—, y ahora son lo único que separa. */
  background:var(--bone);
  border:1px solid rgba(23,32,36,.22);border-radius:999px;
  box-shadow:0 6px 22px rgba(23,32,36,.10);
  padding:10px 18px;transition:background-color .3s ease,border-color .3s ease}
nav .links{display:none;gap:20px;font-size:.83rem}
nav .links a{color:var(--cap)}
nav .links a:hover{color:var(--ink)}
nav .btn{padding:.6em 1.15em;font-size:.8rem}

/* --- barra de la home (dynamic island, referencia qoves): al cargar flota a todo
   el ancho SIN fondo sobre el hero mineral; con un toque de scroll el contenedor
   se estrecha unos px y gana un vidrio de tinta redondeado — logo y acciones se
   deslizan hacia el centro casi imperceptiblemente. Lento y discreto. --- */
nav.ndark{padding:10px 12px;transition:none}
nav.ndark .nvw{pointer-events:auto;width:100%;max-width:1440px;margin:0 auto;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:12px calc(var(--pad) + 4px);border-radius:999px;background:rgba(23,32,36,0);
  /* el borde existe ya sin scroll, transparente: si naciera con el estado `.scrolled` la
     isla crecería 2 px al aparecer y eso se ve como un salto */
  border:1px solid transparent;
  transition:max-width .6s cubic-bezier(.3,.7,.2,1),background .45s ease,padding .45s ease,
    border-color .45s ease,box-shadow .45s ease}
/* La isla es tinta translúcida, así que sobre las secciones OSCURAS de la home (el panel
   «la nueva forma», el footer) el relleno coincidía con lo de detrás y la pastilla
   desaparecía — medido en el iPhone de Jorge, 2026-08-10. La separación no puede venir del
   relleno, porque el fondo que pasa por debajo no lo controlamos: viene del CANTO.
   Filete hueso al 38 % = 3,30:1 contra tinta (el mismo valor que ya usa el bloque de
   contraste alto) y sombra para despegarla del hueso. Así la isla se lee sobre los dos
   fondos sin depender de por dónde vaya el scroll. */
nav.ndark.scrolled .nvw{max-width:1180px;background:rgba(23,32,36,.78);
  backdrop-filter:blur(16px) saturate(1.1);-webkit-backdrop-filter:blur(16px) saturate(1.1);
  border-color:rgba(243,239,231,.38);box-shadow:0 10px 30px rgba(23,32,36,.20);
  padding:11px 12px 11px 26px}
nav.ndark .brand{grid-column:1;justify-self:start;color:var(--bone)}
nav.ndark .links{grid-column:2;font-size:.85rem}
nav.ndark .nacts{grid-column:3}
nav.ndark .links a{color:var(--bone);text-shadow:0 1px 2px rgba(23,32,36,.35)}
nav.ndark .links a:hover{color:#fff}
nav.ndark .nacts{display:flex;justify-content:flex-end;align-items:center;gap:20px}
nav.ndark .ntext{display:none;font-size:.85rem;color:var(--bone)}
nav.ndark .ntext:hover{color:var(--halo)}
nav.ndark .btn.nsolid{background:var(--bone);color:var(--ink);border-color:var(--bone);
  padding:.62em 1.25em;font-size:.8rem}
nav.ndark .btn.nsolid:hover{background:#fff;border-color:#fff}

/* ventana de escaneo (paso de medición del flujo) */
.scanwin{position:relative;width:min(82vw,320px);margin:0 auto;border-radius:16px;overflow:hidden;
  border:1px solid var(--line)}
.scanwin img{width:100%;height:auto;display:block}
.scanwin canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}

/* secciones */
section{padding:clamp(70px,16vw,150px) 0;position:relative;content-visibility:auto;contain-intrinsic-size:auto 720px}
.eyebrow{margin-bottom:22px}
.divline{height:1px;background:var(--line);border:0;margin:0}

/* MÉTODO — argumento */
#metodo h2 span{display:block}
#metodo .vs{color:var(--min-m)} /* mineral medio: 4,2:1 sobre hueso (el claro se quedaba en 2,6) */
#metodo p.lead{margin-top:26px}

/* PROGRAMA — timeline medido */
.tl{margin-top:30px;border-left:1px solid var(--line);padding-left:24px}
.tl .step{position:relative;padding:0 0 30px}
.tl .step:last-child{padding-bottom:0}
.tl .step::before{content:"";position:absolute;left:-28px;top:6px;width:7px;height:7px;
  border-radius:50%;background:var(--brass)}
.tl .day{font-family:var(--mono);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;color:var(--cap)}
.tl .st{font-family:var(--sans);font-weight:500;font-size:1.2rem;margin-top:2px}

/* QUÉ RECIBES — artefacto informe */
.report{margin-top:34px;background:var(--paper);border:1px solid var(--line);border-radius:14px;
  padding:26px 22px;max-width:420px}
.report .rhead{display:flex;justify-content:space-between;align-items:center;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;color:var(--cap);
  margin-bottom:16px}
.report .stat{display:flex;justify-content:space-between;font-family:var(--mono);font-size:.72rem;
  color:var(--ink);padding:7px 0;border-bottom:1px dotted var(--line)}
.report .stat span:last-child{color:var(--brass-text)}
.report ul{list-style:none;margin-top:16px;font-size:.9rem;color:var(--body-2)}
.report li{padding:4px 0 4px 16px;position:relative}
.report li::before{content:"—";position:absolute;left:0;color:var(--brass)}

/* OFERTA + FORM — sección de tinta (renombrada #reservar → #precio en la landing v2) */
#precio{background:var(--ink);color:var(--bone)}
#precio .eyebrow,#precio .mono{color:#9FB3BD}
#precio h2{color:var(--bone)}
#precio .ladder{display:flex;flex-wrap:wrap;gap:10px 26px;margin:26px 0 6px;
  font-family:var(--mono);font-size:.74rem;letter-spacing:.05em;color:var(--bone-dim)}
#precio .ladder b{color:var(--brass);font-weight:500}
form{margin-top:26px;max-width:440px}
form .field{margin-bottom:14px}
input[type=email]{width:100%;background:transparent;border:1px solid #46545C;color:var(--bone);
  font-family:var(--sans);font-size:1rem;padding:1em 1.1em;border-radius:12px}
input[type=email]::placeholder{color:#8DA0AA}
input[type=email]:focus{outline:none;border-color:var(--brass)}
.check{display:flex;gap:10px;align-items:flex-start;font-size:.8rem;color:var(--bone-dim);line-height:1.5;margin:10px 0}
.check input{margin-top:3px;accent-color:var(--brass)}
.check a{color:var(--halo);text-decoration:underline}
#precio .btn-solid,form .btn-solid{background:var(--bone);color:var(--ink);border-color:var(--bone)}
#precio .btn-solid:hover,form .btn-solid:hover{background:#fff}
.trust{margin-top:18px;font-family:var(--mono);font-size:.6rem;letter-spacing:.14em;
  text-transform:uppercase;color:#8DA0AA}
.ok{display:none;padding:22px;border:1px solid var(--brass);border-radius:12px;margin-top:26px}
.ok.show{display:block}
.ok .serif{font-size:1.7rem;color:var(--bone)}

/* FOOTER */
footer{padding:46px 0;border-top:1px solid var(--line)}
footer .wrap{display:flex;flex-direction:column;gap:14px}
footer .fl{font-family:var(--mono);font-size:.58rem;letter-spacing:.12em;text-transform:uppercase;color:var(--cap);line-height:1.9}
footer .fl a{text-decoration:underline}
footer .fl a:hover{color:var(--ink)}

/* ---------- footer de tinta con wordmark gigante ----------
   El wordmark gigante es el MISMO texto vivo (.wordmark): los puntos de latón van en em
   y escalan solos. Obligatorio conservar line-height:1 y letter-spacing:.3em — las cotas
   .3053/.13363em de los puntos asumen ese tracking (SISTEMA-DISENO §4). Color plano:
   los degradados en el logo están prohibidos (GUIA-MARCA §6). */
footer.fink{background:var(--ink);border-top:0;padding:64px 0 40px}
footer.fink .fl{color:#8DA0AA}
footer.fink .fl a:hover{color:var(--bone)}
footer.fink .wordmark{color:var(--bone);--dot:var(--brass)}
.wordmark.giant{font-size:clamp(2.1rem,10.5vw,7.5rem);white-space:nowrap;margin-top:38px}


/* reveal on scroll — lento y discreto. La curva es un ease-out fuerte: `ease` arranca
   despacio y a 700 ms se leía como pesadez, no como calma. */
.rv{opacity:0;transform:translateY(18px);
  transition:opacity .52s cubic-bezier(.23,1,.32,1),transform .52s cubic-bezier(.23,1,.32,1)}
.rv.in{opacity:1;transform:none}

/* ============ DESKTOP ============ */
@media(min-width:761px){
  :root{--pad:48px}
  /* regla lateral que mide el scroll: SIN banda propia — flota sobre el fondo
     que toque (arranca bajo la barra). Trazo mineral, indicador de latón. */
  #bar{display:none}
  #ruler{position:fixed;left:0;top:calc(var(--nav-h) + 24px);bottom:16px;width:54px;z-index:40;
    display:flex;flex-direction:column;align-items:center;pointer-events:none}
  #ruler .track{position:relative;flex:1;width:1px;background:rgba(130,153,165,.45);margin-bottom:12px}
  #ruler .track::before{content:"";position:absolute;inset:0;
    background:repeating-linear-gradient(to bottom,rgba(130,153,165,.45) 0 1px,transparent 1px 22px)}
  #ruler .dot{position:absolute;left:50%;transform:translate(-50%,-50%);top:0;
    width:7px;height:7px;border-radius:50%;background:var(--brass)}
  #ruler .val{font-family:var(--mono);font-size:.6rem;color:var(--brass);letter-spacing:.05em}
  nav .links{display:flex}

  h1{font-size:clamp(4rem,7vw,6.6rem)}
  p.lead{font-size:1.22rem}
  .two{display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:start}
  .report{margin-top:0}
  form .btn-solid{width:auto}
}
@media(min-width:761px){.center-narrow{max-width:760px}}

/* ============ MOVIMIENTO REDUCIDO ============
   Menos movimiento y más suave, NO cero animación: se conservan opacidad y color (ayudan a
   comprender el cambio) y se retira el desplazamiento. landing.css y hero-v5.css ya tenían su
   bloque; este archivo no tenía ninguno, así que el reveal de las 10 secciones —el motion más
   visible de la página— seguía desplazándose 18 px con la preferencia activa (medido con
   Emulation.setEmulatedMedia: matrix(1,0,0,1,0,18)). */
@media (prefers-reduced-motion: reduce){
  /* el ancla de la nav movía la página entera: Chrome no desactiva scroll-behavior solo */
  html{scroll-behavior:auto}
  .rv{transform:none;transition:opacity .2s ease}
  .rv.in{transform:none}
  /* la barra de progreso salta a su valor en vez de deslizarse */
  #bar{transition:none}
  /* la isla dinámica: se queda el vidrio, se va la reducción de ancho animada */
  nav.ndark .nvw{transition:background-color .45s ease}
  /* pulsación: la señal se conserva (atenuación de opacidad), la compresión se retira */
  :where(.btn,.btn-lg,.chipbtn,.itab,.pay-action):active{transform:none;opacity:var(--press-dim)}
}

/* ============ TRANSPARENCIA REDUCIDA ============
   §14 de apple-design: las superficies translúcidas se vuelven sólidas y el desenfoque
   desaparece. Solo se tocan las que dejan ver CONTENIDO detrás (aquí, la página pasando
   por debajo de la barra); los rellenos translúcidos sobre un panel de color plano no
   entran, porque no hay nada que ver a través. El grano del campo (mix-blend-mode sobre
   un degradado plano) tampoco: no es un material sobre contenido, es el propio fondo.
   Un `backdrop-filter` además no es gratis: es de lo más caro que se puede pintar en un
   móvil, así que quitarlo también devuelve frames a quien pide menos transparencia. */
@media (prefers-reduced-transparency: reduce){
  /* pastilla de las páginas de flujo: hueso pleno desde el primer píxel de scroll */
  nav .pill{background:var(--bone);backdrop-filter:none;-webkit-backdrop-filter:none;
    border-color:rgba(23,32,36,.22)}
  nav.scrolled .pill{background:var(--bone)}
  /* isla dinámica de la home: tinta plena. El estado SIN scroll se queda transparente a
     propósito — ahí no hay material translúcido, hay ausencia de material; el que quiera
     una placa la recibe en el bloque de contraste alto, que es donde la pide la norma. */
  nav.ndark.scrolled .nvw{background:var(--ink);
    backdrop-filter:none;-webkit-backdrop-filter:none}
}

/* ============ CONTRASTE ALTO ============
   §14: fondos casi sólidos con borde definido. Los tokens suben a AAA (≥7:1 en texto,
   ≥3:1 en separadores y bordes). Contrastes MEDIDOS con la fórmula WCAG sobre los valores
   reales, no estimados:
     --cap      #52646A  5,40:1 -> #3B4A50   8,03:1  sobre hueso
     --min-m    #60757D  4,22:1 -> #43535A   6,98:1  sobre hueso (es texto grande: AAA=4,5)
     --brass-text #77622E 5,13:1 -> #5E4C20  7,24:1  sobre hueso
     --line     #DFD9CC  1,23:1 -> #8C8271   3,30:1  sobre hueso (3,57:1 sobre papel)
     --bone-dim #D6E0E7 12,36:1 -> #F3EFE7  14,44:1  sobre tinta
   --body-2 (#28343A, 11,15:1) y --halo (#B6CEDB, 10,12:1) ya cumplen y no se tocan. */
@media (prefers-contrast: more){
  :root{
    --cap:#3B4A50;
    --min-m:#43535A;
    --brass-text:#5E4C20;
    --line:#8C8271;
    --bone-dim:#F3EFE7;
  }
  /* el anillo de foco engorda: a 2px sobre un borde ya contrastado se confundía con él */
  :where(a,button,input,select,textarea,summary,
    .btn,.chipbtn,.linkbtn,.pay-action,.acc-h,.itab):focus-visible{outline-width:3px}
  /* barra de la home: placa sólida DESDE EL PRINCIPIO, no solo al hacer scroll.
     Es la prescripción literal de §14 —fondo casi sólido con borde contrastado— y aquí
     el texto de la nav flota sobre el hero, que es lo más variable de la página. */
  nav.ndark .nvw{background:var(--ink);border:1px solid rgba(243,239,231,.38)}
  nav.ndark.scrolled .nvw{background:var(--ink)}
  nav.ndark .links a{text-shadow:none}      /* con placa sólida, la sombra sobra: 14,4:1 */
  nav .pill{background:var(--bone);border-color:rgba(23,32,36,.45)}
  /* separadores atenuados sobre tinta: de punteados casi invisibles a línea definida */
  footer.fink .fl{color:#CFDCE3}            /* #8DA0AA 6,10:1 -> 11,82:1 sobre tinta */
  .trust{color:#CFDCE3}
  #precio .eyebrow,#precio .mono{color:#CFDCE3}
  input[type=email]{border-color:var(--bone)}
  input[type=email]::placeholder{color:#CFDCE3}
  .report .stat{border-bottom-style:solid}
}

/* ============ CONSENTIMIENTO (banner + panel) ============
   ADR 2026-08-06-medicion-embudo-dos-capas. Bloque ADITIVO al final: no toca ninguna regla
   anterior, igual que hicieron los bloques de preferencias del plan 002.

   Material: **panel de tinta opaco**, el mismo que el paywall y la puerta de email. Nada de
   vidrio — un `backdrop-filter` sobre el hero mineral o sobre una foto haría que el contraste
   del texto NO fuera determinista, que es exactamente el defecto que se corrigió el 04-08 en
   la tarjeta de email (3,59:1 medidos en móvil).

   El filete de latón de arriba no es decoración y por eso está: en `index.html` y en el blog
   el pie es `footer.fink`, también de tinta, así que al final de la página el panel se fundiría
   con él y no se vería dónde empieza. Sobre tinta el latón mide 7,9:1; sobre hueso 1,9:1, o
   sea que se ve justo donde hace falta y desaparece donde no.

   Contrastes (fórmula WCAG sobre los valores reales, sin estimar):
     --bone     #F3EFE7 sobre tinta #172024 ....... 14,44:1   (título y botones)
     --bone-dim #D6E0E7 sobre tinta ............... 12,36:1   (descripciones)
     --halo     #B6CEDB sobre tinta ............... 10,12:1   (enlaces)
     --ink      sobre relleno hueso de los botones  14,44:1
   Los DOS botones comparten la clase `.cns-b` entera: misma caja, mismo relleno, mismo peso
   y mismo contraste. La prominencia igual de aceptar y rechazar (guía AEPD 2023) queda
   garantizada por construcción, no por haber elegido bien dos colores — y `_qa_consentimiento.py`
   lo mide de todos modos. */
.cns{position:fixed;left:0;right:0;bottom:0;z-index:70;pointer-events:none}
/* El diálogo recibe el foco al abrirse (para que el teclado entre dentro) y por eso lleva
   `tabindex="-1"`. Sin esto, Chrome le pinta SU anillo por defecto alrededor del panel entero:
   en el móvil de Jorge se veía un cerco azul rodeando el banner. El foco sigue estando —los
   tres controles conservan su anillo propio—, lo que se retira es el cerco del contenedor,
   que no es un control. Misma regla que ya existe para los titulares de paso. */
.cns[tabindex="-1"]:focus{outline:none}

/* VELO. El banner es BLOQUEANTE hasta que hay respuesta, y no por gusto: medido el
   2026-08-07, una barra flotante de 268 px de alto TAPA el CTA de 9,90 EUR en 390x844
   (CTA en 680-737, barra desde 576) y tambien la mitad inferior de la pantalla de entrada.
   Las dos pantallas estan compuestas para caber en UN viewport (planes 004 y 006) y no
   sobra sitio: en movil quedan ~107 px de holgura bajo el CTA y ningun banner que cumpla
   —titulo, explicacion, dos botones iguales y opcion granular— cabe en eso. Como el trafico
   de pago aterriza en /scan, donde entrada y resultado son la MISMA pagina, quien ignorase
   la barra llegaria al CTA con el CTA tapado. Bloqueando, ese estado no puede existir.

   El velo atenua, no oculta: la pagina se sigue viendo detras. Por eso NO entra en el bloque
   de `prefers-reduced-transparency` —volverlo opaco no seria "menos transparencia", seria
   otro componente— y por eso un clic en el velo no cierra nada: cerrar por descarte
   equivaldria a consentir en silencio, que es justo lo que prohibe el art. 4.11 RGPD. */
.cns-velo{position:fixed;inset:0;z-index:-1;pointer-events:auto;background:rgba(23,32,36,.5)}

.cns-in{pointer-events:auto;width:100%;max-width:var(--maxw);margin:0 auto;
  background:var(--ink);color:var(--bone);border-top:1px solid var(--brass);
  border-radius:16px 16px 0 0;
  padding:20px var(--pad) calc(20px + env(safe-area-inset-bottom,0px));
  display:grid;gap:14px;
  animation:cns-entra .28s cubic-bezier(.23,1,.32,1) both}
@keyframes cns-entra{from{transform:translateY(100%)}to{transform:none}}

.cns-h{font-family:var(--sans);font-weight:500;font-size:1rem;line-height:1.35;color:var(--bone)}
.cns-p{font-size:.86rem;line-height:1.55;color:var(--bone-dim);margin-top:6px;max-width:62ch}
.cns-p a{color:var(--halo);text-decoration:underline}
.cns-p a:hover{color:var(--bone)}

/* acciones: `flex:1 1 0` con `min-width:0` les da el MISMO ancho en móvil pase lo que pase
   con la longitud de las etiquetas — que es la otra mitad de «misma prominencia». */
.cns-acts{display:flex;gap:10px}
.cns-b{flex:1 1 0;min-width:0;display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--sans);font-weight:500;font-size:.92rem;line-height:1.2;
  padding:.85em 1.4em;border-radius:999px;border:1px solid var(--bone);
  background:var(--bone);color:var(--ink);cursor:pointer;
  transition:background-color .18s ease,transform var(--press-dur) ease-out}
.cns-b:hover{background:#fff}
.cns-b:active{transform:scale(var(--press))}

.cns-cfg{justify-self:start;background:none;border:0;padding:2px 0;
  font-family:var(--sans);font-size:.85rem;color:var(--halo);text-decoration:underline;
  cursor:pointer;transition:opacity var(--press-dur) ease-out}
.cns-cfg:hover{color:var(--bone)}
.cns-cfg:active{opacity:var(--press-dim)}

/* `:not([hidden])` NO es cosmetico: sin el, este `display:grid` gana a la hoja del
   navegador y el panel se pinta ABIERTO aunque el JS lo oculte. Es literalmente el gotcha
   que styles.css ya documenta desde el 04-08 (los tres estados del checkout visibles a la
   vez) y en el que se volvio a caer el 07-08 al escribir esto — lo delato la sonda midiendo
   616 px de banner donde tocaban 268. */
.cns-panel:not([hidden]){border-top:1px solid rgba(243,239,231,.18);padding-top:16px;
  display:grid;gap:14px}
.cns-fila{display:grid;grid-template-columns:20px 1fr;gap:2px 12px;align-items:start}
.cns-fila input{grid-column:1;grid-row:1;width:18px;height:18px;margin:1px 0 0;
  accent-color:var(--brass);cursor:pointer}
.cns-punto{grid-column:1;grid-row:1;width:8px;height:8px;margin:6px 0 0 5px;border-radius:50%;
  background:var(--brass)}
.cns-nom{grid-column:2;grid-row:1;font-size:.9rem;font-weight:500;color:var(--bone)}
.cns-nom em{font-style:normal;font-family:var(--mono);font-size:.58rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brass);margin-left:10px}
.cns-des{grid-column:2;grid-row:2;font-size:.8rem;line-height:1.5;color:var(--bone-dim)}
.cns-fila:has(input){cursor:pointer}
.cns-guardar{justify-self:start;flex:0 0 auto;margin-top:2px}

/* enlace de retirada en el pie: hereda la mono del pie para no ser un cuerpo extraño */
.cns-link{background:none;border:0;padding:0;font:inherit;letter-spacing:inherit;
  text-transform:inherit;color:inherit;text-decoration:underline;cursor:pointer}
.cns-link:hover{color:var(--ink)}
footer.fink .cns-link:hover{color:var(--bone)}

@media(min-width:761px){
  .cns-in{grid-template-columns:1fr auto;align-items:center;gap:16px 34px;
    padding:22px var(--pad) 24px}
  .cns-txt{grid-column:1;grid-row:1}
  .cns-acts{grid-column:2;grid-row:1;flex:0 0 auto}
  .cns-b{flex:0 0 auto;min-width:150px}
  .cns-cfg{grid-column:1;grid-row:2}
  .cns-panel{grid-column:1/-1;grid-row:3}
}

@media (prefers-reduced-motion: reduce){
  /* aparece sin desplazarse: la señal de que ha llegado algo se conserva en la opacidad */
  .cns-in{animation:cns-aparece .2s ease both}
  @keyframes cns-aparece{from{opacity:0}to{opacity:1}}
  .cns-b:active{transform:none;opacity:var(--press-dim)}
}

@media (prefers-contrast: more){
  /* el separador del panel deja de ser un velo y pasa a línea definida */
  .cns-panel{border-top-color:#CFDCE3}
  .cns-p{color:#F3EFE7}
  .cns-des{color:#F3EFE7}
}
