/* Novolease 2026 - Design tokens */
/* Tipografias autoalojadas (subset latin, variables). Antes venian de Google Fonts:
   dos conexiones a terceros -DNS+TLS de googleapis y de gstatic- antes de que bajara
   un solo byte de letra, y en la ruta critica. Ahora salen del mismo origen ya abierto.
   La italica es la cara DIBUJADA: sin ella el navegador oblicuaba la redonda, y en una
   grotesca de astas finas se nota. No se precarga a proposito - son cuatro notas de
   letra chica, ninguna above-the-fold. */
@font-face{font-family:'Sora';font-style:normal;font-weight:100 800;font-display:swap;src:url('assets/fonts/sora-latin.woff2') format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:100 900;font-display:swap;src:url('assets/fonts/hanken-grotesk-latin.woff2') format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-style:italic;font-weight:100 900;font-display:swap;src:url('assets/fonts/hanken-grotesk-italic-latin.woff2') format('woff2')}
/* Texto: Hanken Grotesk (variable, autoalojada) - mejor pairing con Sora.
   Los pesos base van medio escalon arriba que con General Sans: Hanken tiene astas
   mas finas y a 11-15px se veia anemica. Ver body/.eyebrow/.btn/.lede abajo. */
:root {
  --navy-950: #060F29;
  --navy-900: #0A1B3D;
  --navy-800: #0F2550;
  --navy-700: #173168;
  --navy-600: #24427F;
  --ink-900: #0A0F1C;
  --ink-700: #1A2540;
  --ink-500: #3B4765;
  --ink-400: #5A6785;
  --ink-300: #8A97B3;
  --cream-50: #F7F5EF;
  --cream-100: #F1EEE6;
  --paper: #FAF8F3;
  --pale-blue: #EEF3FC;
  --pale-section: #F0F5FF;
  --line-dark: rgba(255,255,255,0.08);
  --line-darker: rgba(255,255,255,0.12);
  --line-light: rgba(10,27,61,0.10);
  --accent: #7FA6E8;         /* translucent blue */
  --accent-bright: #9FBEF2;
  --accent-deep: #3E6BC7;
  --good: #6BD3B0;
  --bad: #E89A9A;
  --font-display: 'Sora', system-ui, sans-serif;
  --font-sans: 'Hanken Grotesk', system-ui, sans-serif;
  --font-mono: 'Hanken Grotesk', system-ui, sans-serif;
  --font-serif: 'Sora', system-ui, sans-serif;
  --maxw: 1280px;
}

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

/* ── Franja de estado en iOS: un TOPE PLANO, no una meta ─────────────────────
   Se intento dos veces con theme-color y no puede funcionar: es un valor unico y
   nuestro fondo cambia con el scroll (hero navy -> "Tres pasos" claro -> oscuro), asi
   que sobre la seccion clara Safari descarta el color declarado y pinta gris por su
   cuenta para mantener legibles los iconos de estado.
   La solucion es de CONTENIDO: una banda fija del alto exacto del area segura,
   siempre del mismo navy. Con eso lo que hay debajo del reloj es navy plano en
   TODAS las secciones -que es lo que theverge.com tiene de fabrica y nosotros no-,
   asi que ni la muestra automatica ni el heuristico de contraste tienen de donde
   sacar otro tono. En pantallas sin area segura mide 0 y no existe.
   No usa padding: es position:fixed, asi que no empuja el contenido ni un pixel. */
body::before {
  content: '';
  position: fixed;
  top: 0; left: 0; right: 0;
  height: env(safe-area-inset-top, 0px);
  background: var(--nv-top-tint, #060F29);
  z-index: 199;
  pointer-events: none;
  /* La meta theme-color cambia de golpe -por eso el articulo de referencia acabo
     descartandola-. La banda si puede fundir, y es la superficie que se ve. */
  transition: background-color .25s linear;
}
@media (prefers-reduced-motion: reduce) { body::before { transition: none; } }

/* Snap entre secciones: manejado por JS (fx.jsx) para que embone limpio.
   Solo dejamos el desplazamiento del nav bien posicionado. */
html { scroll-padding-top: 88px; }
body {
  font-family: var(--font-sans);
  font-weight: 550;
  background: var(--navy-950);
  color: #E8ECF4;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'ss01' on, 'cv11' on;
  /* clip y no hidden: 'hidden' en un eje obliga al otro a computar 'auto', el body
     se convierte en contenedor de scroll y ahi muere todo position:sticky del sitio.
     'clip' recorta igual en horizontal sin crear scrollport. */
  overflow-x: clip;
}

/* type */
.display {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.0;
}
.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}
.mono { font-family: var(--font-mono); }
.serif { font-family: var(--font-serif); font-style: italic; font-weight: 400; }

/* layout */
.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 32px;
}
@media (max-width: 760px) {
  .container { padding: 0 20px; }
}

/* glass */
.glass {
  background: linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.025));
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.09);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    0 10px 40px -10px rgba(0,0,0,0.4);
}
.glass-strong {
  background: linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.05));
  backdrop-filter: blur(28px) saturate(160%);
  -webkit-backdrop-filter: blur(28px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.14);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.12),
    0 20px 60px -15px rgba(0,0,0,0.5);
}
.glass-light {
  background: rgba(10,27,61,0.04);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid rgba(10,27,61,0.10);
}

/* buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform .24s cubic-bezier(.34,1.56,.64,1), background .2s ease, box-shadow .2s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px) scale(1.02); }
.btn:active { transform: translateY(0) scale(0.98); transition-duration: .08s; }
.btn-primary {
  background: #ffffff;
  color: var(--navy-900);
}
.btn-primary:hover { box-shadow: 0 14px 34px -8px rgba(255,255,255,0.5), 0 0 0 4px rgba(255,255,255,0.12); }

/* CTA con glow pulsante - para incitar el click en el paso de conversión */
.btn-glow { position: relative; }
.btn-glow::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: -1;
  box-shadow: 0 0 26px 4px rgba(127,166,232,0.65), 0 8px 30px -4px rgba(127,166,232,0.5);
  opacity: 0.35; will-change: opacity;
  animation: btn-glow-pulse 2.6s ease-in-out infinite;
}
.btn-glow:hover::after { opacity: 1; animation-play-state: paused; }
@keyframes btn-glow-pulse { 0%,100% { opacity: 0.28; } 50% { opacity: 0.7; } }
@media (prefers-reduced-motion: reduce) { .btn-glow::after { animation: none; opacity: 0.4; } }
.btn-ghost {
  background: transparent;
  color: #E8ECF4;
  border-color: rgba(255,255,255,0.18);
}
.btn-ghost:hover { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.4); }
.btn-dark {
  background: var(--navy-900);
  color: #fff;
}
.btn-dark:hover { background: var(--navy-800); box-shadow: 0 14px 34px -10px rgba(10,27,61,0.55); }

/* section scaffolding */
section {
  position: relative;
  padding: 120px 0;
}
@media (max-width: 760px) { section { padding: 72px 0; } }

.section-dark { background: var(--navy-950); color: #E8ECF4; }
.section-navy { background: var(--navy-900); color: #E8ECF4; }
.section-light { background: var(--paper); color: var(--ink-900); }
.section-pale { background: var(--pale-blue); color: var(--ink-900); }
/* diagonal clip for section transitions */
.clip-bottom { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 48px), 0 100%); margin-bottom: -48px; padding-bottom: calc(120px + 48px); }
.clip-top { clip-path: polygon(0 48px, 100% 0, 100% 100%, 0 100%); margin-top: -48px; padding-top: calc(120px + 48px); }

/* shared bits */
.section-head {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 64px;
  align-items: end;
  margin-bottom: 72px;
}
@media (max-width: 900px) {
  .section-head { grid-template-columns: 1fr; gap: 24px; margin-bottom: 48px; }
}
.section-head h2 {
  font-family: var(--font-display);
  font-size: clamp(36px, 5vw, 64px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.0;
  margin: 0;
}
.section-head p.lede {
  font-size: 18px;
  font-weight: 570;
  line-height: 1.5;
  color: var(--ink-400);
  max-width: 520px;
  margin: 0;
}
.section-dark .section-head p.lede,
.section-navy .section-head p.lede { color: var(--ink-300); }

/* ambient navy background flourishes */
.ambient {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.ambient .orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(100px);
  opacity: 0.55;
}
.ambient .orb-a {
  width: 520px; height: 520px;
  background: radial-gradient(circle, rgba(127,166,232,0.35), transparent 60%);
  top: -120px; right: -120px;
}
.ambient .orb-b {
  width: 440px; height: 440px;
  background: radial-gradient(circle, rgba(62,107,199,0.28), transparent 60%);
  bottom: -180px; left: -120px;
}

/* keyframe: subtle glass sheen */
@keyframes sheen {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(220%); }
}

/* Glow-up: animated gradient shimmer on hero headline accent */
@keyframes nv-grad-flow {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
.hero-grad {
  background-size: 200% auto !important;
  animation: nv-grad-flow 6s linear infinite;
}

/* Glow-up: ambient orbs drift slowly for living depth */
@keyframes nv-orb-a {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(-46px, 38px, 0); }
}
@keyframes nv-orb-b {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(54px, -30px, 0); }
}
.ambient .orb-a { animation: nv-orb-a 16s ease-in-out infinite; will-change: transform; }
.ambient .orb-b { animation: nv-orb-b 20s ease-in-out infinite; will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .hero-grad { animation: none; }
  .ambient .orb-a, .ambient .orb-b { animation: none; }
}

/* Móvil / touch: orbes más ligeros (blur menor, sin drift) y sin shimmer de texto -
   los blurs gigantes animados consumen GPU y batería en teléfonos */
@media (max-width: 900px), (pointer: coarse) {
  .ambient .orb { filter: blur(56px); opacity: 0.38; }
  .ambient .orb-a, .ambient .orb-b { animation: none; will-change: auto; }
  .hero-grad { animation: none; background-position: 50% 50% !important; }
}

/* Chat trigger - attention-grabbing halo (composited) */
@keyframes novo-chat-ring {
  0%        { opacity: 0.6; transform: scale(1); }
  70%, 100% { opacity: 0;   transform: scale(1.7); }
}
/* Auditoría móvil 390px: tap targets ≥44px */
@media (max-width: 640px) {
  .ex-chip { min-height: 44px !important; padding: 12px 18px !important; }
  .footer-grid a { padding: 12px 0 !important; }
}
.novo-chat-trigger {
  position: relative;
  box-shadow:
    0 14px 40px -10px rgba(0,0,0,0.5),
    0 0 26px 3px rgba(107,211,176,0.32),
    inset 0 1px 0 rgba(255,255,255,0.15);
}
/* Expanding halo - animates only transform+opacity (composited, cheap),
   the ring itself (box-shadow) is painted once and never re-rendered. */
.novo-chat-trigger::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: 0 0 0 1.5px rgba(107,211,176,0.5);
  animation: novo-chat-ring 2.6s ease-out infinite;
  pointer-events: none;
}
.novo-chat-trigger:hover {
  box-shadow:
    0 22px 52px -10px rgba(0,0,0,0.6),
    0 0 44px 8px rgba(107,211,176,0.50),
    inset 0 1px 0 rgba(255,255,255,0.15) !important;
}
.novo-chat-trigger:hover::after { animation-play-state: paused; opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .novo-chat-trigger::after { animation: none; opacity: 0; }
}

/* ── Detalles nativos premium ── */
::selection { background: rgba(75,125,224,0.85); color: #fff; }
::-webkit-scrollbar { width: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(110,140,195,0.45);
  border-radius: 8px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(130,160,215,0.6); border: 3px solid transparent; background-clip: content-box; }

.tabular { font-variant-numeric: tabular-nums; }

/* utility */
.flex { display: flex; }
.gap-2 { gap: 8px; } .gap-3 { gap: 12px; } .gap-4 { gap: 16px; } .gap-6 { gap: 24px; }
.text-dim { color: var(--ink-300); }
.text-dim-dark { color: var(--ink-400); }

/* focus-visible */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* ── Microinteracciones consistentes: hundimiento al presionar (misma física) ── */
.ex-chip { transition: background .2s ease, border-color .2s ease, transform .18s cubic-bezier(.34,1.56,.64,1); }
.ex-chip:active { transform: scale(0.95); }
.ex-arrow:active:not(:disabled) { transform: scale(0.9); transition-duration: .08s; }
.ex-dot { transition: transform .18s ease, background .2s ease; }
.ex-dot:active { transform: scale(0.8); }

/* ── Film grain cinematográfico sobre zonas oscuras (hero, ejemplos, nosotros) ── */
.section-dark::after, .section-navy::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNjAnIGhlaWdodD0nMTYwJz48ZmlsdGVyIGlkPSduJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC44NScgbnVtT2N0YXZlcz0nMicgc3RpdGNoVGlsZXM9J3N0aXRjaCcvPjwvZmlsdGVyPjxyZWN0IHdpZHRoPScxMDAlJyBoZWlnaHQ9JzEwMCUnIGZpbHRlcj0ndXJsKCNuKScvPjwvc3ZnPg==");
  background-size: 170px 170px;
  opacity: 0.05; mix-blend-mode: soft-light;
}


/* ── Compatibilidad movil (iOS/Android) ─────────────────────────────────────
   1. Alturas de modal: 100vh en iOS Safari INCLUYE la barra de direcciones, asi que
      un panel de "calc(100vh - 40px)" queda mas alto que el area visible y su parte
      baja (donde vive el boton de accion) se esconde tras el chrome del navegador.
      dvh mide el viewport real. Se declara dos veces: los motores viejos se quedan
      con vh, los nuevos pisan con dvh.
   2. overscroll-behavior: sin esto, al llegar al final del scroll de un modal el
      gesto sigue de largo y arrastra la pagina de atras (encadenamiento). */
.nv-h-chat { height: 560px; max-height: calc(100vh - 140px); max-height: calc(100dvh - 140px); overscroll-behavior: contain; }
.nv-h-modal { max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overscroll-behavior: contain; }
.nv-h-priv { max-height: min(84vh, 900px); max-height: min(84dvh, 900px); overscroll-behavior: contain; }
/* El destello gris del toque en Chrome Android delata el rectangulo real del boton y
   choca con los estados :active propios. */
a, button, [role="button"] { -webkit-tap-highlight-color: transparent; }


/* -- Saltar el pintado de lo que no se ve ---------------------------------
   content-visibility: auto le permite al navegador no calcular ni pintar una
   seccion mientras esta fuera de pantalla. Es la palanca mas grande que queda para
   el scroll en Android de gama media, porque el sitio usa mucho backdrop-filter
   (caro de re-rasterizar en cada cuadro).

   OJO: solo va en secciones que YA recortan (overflow:hidden). La propiedad impone
   contencion de pintado, o sea que recorta lo que se salga de la caja; aplicarla a
   #ventajas o #marcas (overflow visible) cortaria elementos decorativos que
   sobresalen a proposito. #top queda fuera aparte: es la primera pantalla y nunca
   hay que aplazarla.

   contain-intrinsic-size reserva el alto mientras la seccion esta saltada, para que
   la barra de scroll no brinque; la palabra clave auto hace que el navegador
   recuerde el alto real una vez medido. Los valores son de la CAJA DE CONTENIDO: no
   incluyen el padding de la seccion (medirlos con getBoundingClientRect y pegarlos
   tal cual duplica el padding y alarga la pagina). */
#ejemplos { content-visibility: auto; contain-intrinsic-size: auto 1010px; }
#como     { content-visibility: auto; contain-intrinsic-size: auto 1449px; }
/* #nosotros NO lleva content-visibility: trae un panel sticky (la cortina de la
   foto) y la contencion de pintado se lleva mal con el; ademas la seccion mide
   ~2300px, asi que la estimacion de 1120px hacia brincar la barra de scroll. */
#faq      { content-visibility: auto; contain-intrinsic-size: auto 660px; }
#empezar  { content-visibility: auto; contain-intrinsic-size: auto 495px; }
/* Al imprimir tiene que existir TODO el documento. */
@media print {
  #ejemplos, #como, #faq, #empezar { content-visibility: visible; }
}

/* -- Botones flotantes en movil ---------------------------------------------
   Convivian dos llamadas a la accion del mismo peso peleandose el pulgar, y con
   alturas distintas porque vienen de componentes que no se conocen. La conversion
   ("Empezar solicitud") se queda como pastilla solida; Novo se reduce a un circulo
   con el icono: el chat es asistencia, no destino. Misma altura para que la linea
   inferior lea pareja. */
@media (max-width: 680px) {
  .novo-chat-trigger { width: 54px; height: 54px; padding: 0 !important; gap: 0 !important; justify-content: center; }
  .novo-chat-label { display: none; }
  .nv-mobile-cta .btn { min-height: 54px; }
}

/* Enlaces SIN clase. El `:not([class])` no es cosmetico: sin el, estas reglas se
   comian el color de los botones -.btn-primary es un <a>, y dentro de una seccion
   oscura le tocaba texto azul claro sobre la pildora blanca-. Todo componente trae su
   propio color; esto es solo la red para el enlace suelto que se agregue despues, que
   sin regla saldria azul de navegador.
   El sistema no subraya: el color hace el trabajo y el hover confirma que es tocable. */
a:not([class]) { color: var(--accent-deep); text-decoration: none; }
a:not([class]):hover { color: var(--navy-700); }
.section-dark a:not([class]), .section-navy a:not([class]) { color: #BFD4F5; }
.section-dark a:not([class]):hover, .section-navy a:not([class]):hover { color: #fff; }
.ex-inline-link { transition: color .2s ease; }
.ex-inline-link:hover { color: #fff; }

/* Titular del hero: palabras enmascaradas + destello que barre la frase clave */
.hero-headline .nv-line{display:block}
.hero-headline .nv-w{display:inline-block;clip-path:inset(-0.4em -0.22em 0 -0.22em)}
.hero-headline .nv-w+.nv-w{margin-left:.26em}
.hero-headline .nv-wi{display:inline-block}
.hero-headline .hero-setup{font-size:.6em;font-weight:550;letter-spacing:-.022em;opacity:.86;margin-bottom:.14em}
.hero-punch .nv-wi{background:linear-gradient(100deg,#7FA6E8 0%,#7FA6E8 26%,#EAF1FC 42%,#FFF 50%,#EAF1FC 58%,#7FA6E8 74%,#7FA6E8 100%);background-size:300% auto;background-position:100% 50%;-webkit-background-clip:text;background-clip:text;color:transparent}
.hero-headline.nv-go .hero-punch .nv-wi{animation:nv-shine 4.6s cubic-bezier(.45,0,.25,1) infinite both}
.hero-punch .nv-period{transform:scale(.35);opacity:0}
.hero-headline.nv-go .hero-punch .nv-period{animation:nv-period-pop .5s cubic-bezier(.2,1.5,.4,1) both}
@keyframes nv-period-pop{from{transform:scale(.35);opacity:0}to{transform:scale(1);opacity:1}}
.hero-headline .nv-w.nv-w-tight{margin-left:0}
/* Latón sobre navy: el #B5832F del manual se apaga en oscuro, por eso #C79A4A. */
.hero-punch .nv-period{background:none;color:#C79A4A;-webkit-text-fill-color:#C79A4A}
@keyframes nv-shine{0%{background-position:100% 50%}42%{background-position:0% 50%}100%{background-position:0% 50%}}
@media (prefers-reduced-motion: reduce){.hero-headline.nv-go .hero-punch .nv-wi,.hero-headline.nv-go .hero-punch .nv-period{animation:none}.hero-punch .nv-wi{background-position:0% 50%}.hero-punch .nv-period{transform:none;opacity:1}}

/* ── Sliders del estimador ───────────────────────────────────────────────────
   Tercera version. La primera eran range nativos con accent-color: en movil el
   pulgar es chico y queda bajo el dedo, sin señal de que lo estabas controlando.
   La segunda hacia crecer el pulgar y sacaba un halo -mejor, pero el gesto seguia
   siendo "una bolita con onda de color"-.
   Esta imita el slider de iOS: al presionar SE ENSANCHA LA PISTA (5px -> 15px) y
   el pulgar se convierte en una capsula dentro de ella. El interruptor visual es
   la pista entera, no un adorno alrededor del dedo, asi que se lee aunque la mano
   tape el punto de contacto.
   POR QUE NO ES UN range NATIVO: la altura de la pista de un input[type=range]
   no se puede animar de forma fiable -webkit la toma de ::-webkit-slider-runnable-track
   y firefox de ::-moz-range-track, y ninguno de los dos hereda bien un degradado ni
   respeta un border-radius al crecer-. Aqui la pista y el pulgar son elementos
   REALES y el input va encima, transparente: se conserva el teclado, el foco, el
   arrastre nativo y los lectores de pantalla, y el dibujo es nuestro.
   Geometria: --nv-p es el avance 0-1. El relleno y el pulgar usan la MISMA cuenta
   -calc(8px + (100% - 16px) * var(--nv-p))-, asi que el borde del relleno cae
   siempre en el centro del pulgar; con porcentajes a secas se desalineaban en los
   extremos, que es donde mas se nota. */
.nv-range-wrap { position: relative; display: block; height: 26px; margin: 4px 0;
  --nv-h: 5px; --nv-thumb: 1; }
/* Pista. La expansion va en height y en border-radius a la vez para que las
   tapas sigan redondas en los dos tamaños. */
.nv-range-track { position: absolute; left: 0; right: 0; top: 50%; height: var(--nv-h);
  transform: translateY(-50%); border-radius: 99px; overflow: hidden;
  background: rgba(255,255,255,0.16);
  transition: height .3s cubic-bezier(.2,.9,.25,1.06), background-color .3s ease; }
.nv-range-fill { position: absolute; left: 0; top: 0; bottom: 0;
  width: calc(8px + (100% - 16px) * var(--nv-p, 0)); border-radius: 99px;
  background: var(--nv-acc); transition: background-color .3s ease; }
/* Filete especular: aparece solo cuando la pista esta ensanchada, donde hay sitio
   para que se lea. Mismo vocabulario que los pods del nav. */
.nv-range-track::after { content: ''; position: absolute; top: 0; left: 6px; right: 6px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5) 50%, transparent);
  opacity: 0; transition: opacity .3s ease; pointer-events: none; }
.nv-range-thumb { position: absolute; top: 50%; left: calc(8px + (100% - 16px) * var(--nv-p, 0));
  width: 16px; height: 16px; border-radius: 99px; background: #fff;
  transform: translate(-50%, -50%) scale(var(--nv-thumb));
  box-shadow: 0 1px 4px rgba(0,0,0,0.42), inset 0 1px 0 rgba(255,255,255,0.9);
  transition: transform .3s cubic-bezier(.2,.9,.25,1.06), box-shadow .3s ease, height .3s cubic-bezier(.2,.9,.25,1.06);
  pointer-events: none; }
/* El input va encima y transparente: se ve nuestro dibujo, manda el nativo. */
.nv-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none; background: transparent; border: 0;
  opacity: 0; cursor: pointer; z-index: 2; }
.nv-range:focus { outline: none; }
/* El pulgar nativo se queda invisible pero DEBE existir: sin el, webkit no arrastra. */
.nv-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%; background: transparent; border: 0; }
.nv-range::-moz-range-thumb { width: 26px; height: 26px; border-radius: 50%;
  background: transparent; border: 0; }
/* Estado activo: ensanche. :has() evita tener que sincronizar una clase por JS,
   y cubre dedo y raton igual. */
.nv-range-wrap:has(.nv-range:active) { --nv-h: 15px; --nv-thumb: 1.12; }
.nv-range-wrap:has(.nv-range:active) .nv-range-track { background: rgba(255,255,255,0.22); }
.nv-range-wrap:has(.nv-range:active) .nv-range-track::after { opacity: 1; }
.nv-range-wrap:has(.nv-range:active) .nv-range-thumb {
  height: 21px; box-shadow: 0 3px 10px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.95); }
/* Teclado: sin ensanche -no hay dedo que tapar- pero con aro de foco visible. */
.nv-range-wrap:has(.nv-range:focus-visible) .nv-range-thumb {
  box-shadow: 0 0 0 5px rgba(127,166,232,0.28), 0 1px 4px rgba(0,0,0,0.42), inset 0 1px 0 rgba(255,255,255,0.9); }
@media (prefers-reduced-motion: reduce) {
  .nv-range-track, .nv-range-fill, .nv-range-thumb, .nv-range-track::after { transition: none; }
}
