/* ==========================================================================
   mejoras.css — TODO lo que agregamos nosotros.
   No toca el diseño original: velour.css se copia VERBATIM del sitio actual
   (y lo regenera tools/extraer.mjs). Así se puede comparar contra el original
   sin ruido: si algo se ve distinto, o está aquí, o es un bug.
   ========================================================================== */

/* --- enlace "saltar al contenido": aparece solo al navegar con teclado --- */
.salto{position:fixed;left:12px;top:-120px;z-index:300;background:var(--magenta);color:#fff;
  font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;
  padding:13px 18px;border-radius:2px;transition:top .2s}
.salto:focus{top:12px}

/* --- utilidad para texto que solo leen los lectores de pantalla --- */
.solo-lectores{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ==========================================================================
   DISPONIBILIDAD — existencias que llegan del inventario de Airtable.

   Solo aparece cuando el catálogo lleva control de stock: con los datos
   estáticos (existencias desconocidas) no hay sello ni aviso, y la tienda se
   ve exactamente como antes.
   ========================================================================== */

/* Sello sobre la foto, en la tarjeta y en la galería de la ficha. Se apoya en
   que .lienzo y .marco ya son position:relative (velour.css), y sube por
   encima del degradado de .lienzo::after. */
.sello{position:absolute;z-index:2;left:10px;top:10px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  padding:6px 9px;border-radius:2px}
.sello.agotado{background:rgba(20,18,26,.86);color:var(--hueso);
  border:1px solid rgba(242,237,228,.35)}
.sello.ultimas{background:var(--magenta);color:#fff}

/* Una pieza agotada se apaga un poco y no reacciona al pasar el mouse:
   sigue siendo clickeable para leer la ficha y pedir aviso. */
.pieza.agotada .lienzo img{opacity:.45;filter:saturate(.35)}
.pieza.agotada:hover .lienzo img{transform:none}

/* Aviso de disponibilidad en la ficha. */
.aviso-stock{margin:-6px 0 20px;font-size:14px;line-height:1.5;max-width:46ch}
.aviso-stock.agotado{color:var(--humo)}
.aviso-stock.ultimas{color:var(--magenta)}

/* ==========================================================================
   PROMOCIONES Y ENTREGA — sellos de la tarjeta y de la ficha.

   Los sellos viven apilados dentro de .sellos (columna, separados 6px): antes
   cada .sello se anclaba solo a la esquina y dos etiquetas caían una encima de
   la otra. El orden y el máximo los decide sellosDe() en src/scripts/tarjeta.ts
   —agotado > promo > últimas > express, máximo 2— y acá solo se pinta.

   Combina con los sellos de disponibilidad que ya existían: .ultimas sigue
   siendo el magenta sólido de la casa y .agotado el gris oscuro con borde
   hueso. Los nuevos van en fantasma para no confundirse entre sí:

     · .promo   — magenta translúcido: el mismo acento, sin robarle el turno
                  al magenta sólido de "Últimas unidades" cuando van juntos.
     · .express — cian de la chispa del logo, discreto a propósito: es una
                  promesa de velocidad, no una alarma.
   ========================================================================== */
.sellos{position:absolute;z-index:2;left:10px;top:10px;display:flex;flex-direction:column;
  align-items:flex-start;gap:6px;max-width:calc(100% - 20px)}
.sellos .sello{position:static;left:auto;top:auto}
.sello.promo{background:rgba(255,0,110,.16);color:#FFB3D2;border:1px solid rgba(255,0,110,.62)}
.sello.express{background:rgba(0,217,255,.12);color:#9BEAFF;border:1px solid rgba(0,217,255,.5)}

/* Línea de entrega de la ficha: va debajo de las cuotas y no repite el bloque
   de garantías (que sigue contando el empaque discreto). */
.det .entrega{font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;
  color:var(--humo);margin:-16px 0 22px}
.det .entrega.express{color:var(--cian)}

/* ==========================================================================
   CORRECCIONES DE LA BASE — cosas que venían mal en el diseño original.

   La línea de pulso del hero (svg.onda-portada) estaba anclada abajo pero con
   una altura de 260px: su pico (y=40 sobre un viewBox de 280) subía hasta la
   mitad del párrafo .entrada y el trazo partía las palabras. Aquí el pulso se
   confina a su propia banda, debajo del contenido, y el alto de la banda se
   calcula para que el punto más alto del dibujo (0.857 del alto, que es y=40
   del viewBox estirado por preserveAspectRatio="none") nunca pise el texto:

     alto del dibujo · 0.857  <  espacio reservado debajo del contenido

   205·0.857 = 176 < 232 ·  150·0.857 = 129 < 178 ·  142·0.857 = 122 < 170

   La holgura real (medida con Playwright a 390, 430, 768, 1024 y 1440) queda
   entre 38 y 44 px libres entre el trazo, el halo de la chispa y el botón más
   bajo del hero. Así el texto queda legible en cualquier ancho sin tocar
   colores, trazo ni glow: el pulso sigue siendo el mismo, solo vive donde debe.

   `.onda-capa` agrupa tubo, onda y chispa en una sola banda. Es a propósito:
   el parallax de más abajo mueve la capa entera, así la base del trazo nunca
   se separa de la barra neón (si el tubo se quedara fuera, se desalinearían
   entre sí hasta 13px al hacer scroll: la doble línea que reportó el cliente).
   ========================================================================== */
.portada{--onda-alto:205px; --onda-banda:232px; padding-bottom:var(--onda-banda)}
.portada .onda-capa{position:absolute;left:0;right:0;bottom:0;height:var(--onda-alto);z-index:1;opacity:.9}
.portada .onda-portada{position:absolute;inset:0;width:100%;height:100%}
@media(max-width:760px){
  .portada{--onda-alto:150px; --onda-banda:178px}
  .portada .onda-capa{opacity:.78}
}
@media(max-width:430px){
  .portada{--onda-alto:142px; --onda-banda:170px}
}

/* La barra neón de la base (.tubo, velour.css:375 la dejaba en bottom:78px)
   quedó 12px por encima de la base plana de la onda cuando el pulso bajó a su
   banda de 205px: se veían DOS líneas paralelas, no una. La base del trazo está
   en y=190 del viewBox, o sea 90/280 = 0.3214 del alto de la banda, así que el
   tubo se ancla a esa misma fracción y su borde inferior cae sobre el eje del
   trazo (que es 5px grueso y lo tapa): se lee como UNA línea, igual que en el
   diseño original. Como `--onda-alto` cambia por breakpoint, la alineación se
   mantiene en 205px (65.9), 150px (48.2) y 142px (45.6). */
.portada .tubo{bottom:calc(var(--onda-alto) * .3214)}

/* `overflow:hidden` convierte la portada en contenedor de scroll, y entonces la
   línea de tiempo `view()` del parallax se queda congelada en el propio
   contenedor (que nunca se desplaza). `clip` recorta igual —el pulso no se sale
   de la portada— pero no crea contenedor de scroll, así que el parallax vuelve
   a depender del scroll de la página. Donde `clip` no exista, la declaración se
   ignora y queda el `hidden` de siempre. */
.portada{overflow:clip}

/* El derrame de luz del corte (.barra-neon::after) se sale 6% por cada lado y
   es lo único que desborda el ancho del documento: 23px a 390 y 86px a 1440.
   El degradado ya termina transparente en los bordes, así que recortarlo al
   ancho de la barra no cambia lo que se ve. */
.corte .barra-neon::after{left:0; right:0}

/* ==========================================================================
   PULSO DEL HERO — dibujo, chispa viajera, respiración del glow y parallax.

   Todo lo dispara src/scripts/onda.ts. Aquí queda el estado final (que es el
   que se ve sin JavaScript y con prefers-reduced-motion) y los keyframes.
   ========================================================================== */
/* SIN `vector-effect:non-scaling-stroke` (estuvo aquí hasta el arreglo del
   corte). onda.ts mide el trazo con getTotalLength(), en unidades del viewBox,
   y el navegador solo las interpreta así cuando el trazo escala con el SVG: con
   `non-scaling-stroke` el dash pasa a espacio de pantalla y, como el SVG se
   estira a lo ancho (preserveAspectRatio="none"), el largo de pantalla supera
   al dash en viewports anchos y el trazo muere antes del borde (a 1900px el
   largo de pantalla es 2108 y el dash 1659 → moría al 78%; medido en píxeles:
   76.4%). En móvil pasaba lo contrario: el dash (1659) era mayor que el largo
   de pantalla (666) y el pulso aparecía dibujado de golpe. Si alguien vuelve a
   poner `non-scaling-stroke`, onda.ts tendría que medir el largo en pantalla
   (muestreo con getScreenCTM) y resincronizar en cada resize. */
.portada .onda-portada .traza{
  animation:none;               /* el dibujo lo maneja onda.ts, una sola vez */
  stroke-dasharray:none;
  stroke-dashoffset:0;
}
/* La chispa es un punto HTML, no un <circle>: dentro del SVG estirado el
   círculo salía ovalado (25×12px a 1900 y 34×12 a 2560, medido) y con el bloom
   parecía un cuadrado borroso. Aquí es redonda a cualquier ancho, con halo
   suave y sin borde. Su reposo —el pico del trazo, (430,40) del viewBox— queda
   escrito en CSS, así que también es el estado sin JavaScript; onda.ts solo la
   desplaza con WAAPI durante el dibujo y la devuelve a reposo al terminar. */
.portada .chispa{
  position:absolute;left:35.8333%;top:14.2857%;  /* 430/1200 y 40/280 */
  width:10px;height:10px;margin:-5px 0 0 -5px;border-radius:50%;
  background:#00D9FF;box-shadow:0 0 5px rgba(0,217,255,.95),0 0 14px rgba(0,217,255,.55);
  animation:none;opacity:1;z-index:2;pointer-events:none;
}

/* El glow respira cuando el pulso ya se dibujó y el hero está a la vista. */
@keyframes onda-respira{0%,100%{opacity:1}50%{opacity:.55}}
.portada.onda-lista .onda-glow{animation:onda-respira 4.2s ease-in-out .6s infinite}
.portada.onda-pausa .onda-glow{animation-play-state:paused}

/* Parallax muy leve (±13px) dibujado por el compositor con líneas de tiempo de
   scroll: cero JavaScript, cero listeners de scroll. Donde el navegador no las
   traiga, el pulso simplemente se queda quieto. */
@keyframes onda-paralaje{from{transform:translateY(-12px)}to{transform:translateY(14px)}}
@supports (animation-timeline:view()){
  @media(prefers-reduced-motion:no-preference){
    .portada .onda-capa{animation:onda-paralaje linear both; animation-timeline:view()}
  }
}

/* Latido del botón del asesor: dos pulsos y un silencio largo. */
@keyframes pulso-latido{
  0%,58%,100%{transform:scale(1)}
  64%{transform:scale(1.05)}
  70%{transform:scale(1)}
  76%{transform:scale(1.035)}
  82%{transform:scale(1)}
}
#pulso-btn{animation:pulso-latido 5.2s ease-in-out 2.5s infinite}

/* Sin animaciones a pedido del sistema: el pulso queda dibujado y quieto.
   velour.css ya apaga toda animación CSS con *{animation:none}; esto cubre
   además el estado de los elementos que anima onda.ts con WAAPI. */
@media(prefers-reduced-motion:reduce){
  .portada .onda-capa{animation:none; transform:none}
  .portada .onda-portada .traza{stroke-dasharray:none; stroke-dashoffset:0}
  .portada .chispa{opacity:1; transform:none}
}

/* ==========================================================================
   CORRECCIONES DE RESPONSIVE — hallazgos de la auditoría a 390/430/768/1024/1440.

   El botón flotante del asesor (z-index 95) quedaba por encima del cajón de la
   bolsa (z-index 90) y tapaba su pie —totales y botón de pago— en pantalla
   angosta. `body.cerrada` es el bloqueo que ya usa el sitio para la puerta, el
   menú móvil y la bolsa: mientras esté puesto, el asesor no tiene nada que
   hacer flotando encima.
   ========================================================================== */
body.cerrada #pulso-btn{display:none}

/* --- páginas de servicio (paginas/ayuda.html), mismo lenguaje visual --- */
.est{max-width:820px;margin:0 auto;padding:40px var(--pad) 96px}
.est h1{font-size:clamp(1.9rem,4vw,2.8rem);margin-bottom:14px}
.est h2{font-size:clamp(1.25rem,2.4vw,1.65rem);margin:46px 0 12px;scroll-margin-top:24px}
.est p,.est li{color:#D8D2E0}
.est p{margin-bottom:12px}
.est ul{margin:10px 0 0 20px;display:grid;gap:7px}
.est .volver{margin-bottom:28px}
.est .nota{font-family:var(--mono);font-size:11.5px;color:#8C86A0;margin-top:40px;line-height:1.75}
.est a{color:var(--cian);text-decoration:underline;text-underline-offset:3px}
.est-cab{border-bottom:1px solid var(--linea);padding:16px 0;position:sticky;top:0;
  background:rgba(11,10,15,.86);backdrop-filter:blur(10px);z-index:10}
.est-cab .env{display:flex;align-items:center;justify-content:space-between;gap:16px}
.est-cab button,.est-cab .volver-tienda{font-family:var(--mono);font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;border:1px solid var(--linea2);padding:12px 16px;border-radius:2px;display:inline-block}
.est-cab button:hover,.est-cab .volver-tienda:hover{border-color:var(--cian);color:var(--cian)}

/* ==========================================================================
   REMATES DE LA REVISIÓN GRÁFICA — chispa del logo, puerta corta y zoom.
   ========================================================================== */

/* 1) La chispa del logo vive fuera de su viewBox.
   --------------------------------------------------------------------------
   Todas las instancias de la marca (la puerta, el logo del encabezado, la del
   "pedido confirmado", el pie, el botón flotante de Pulso y la cabecera del
   asesor) dibujan el pulso en un `viewBox="0 0 120 44"` con la chispa en
   `cy="2"` y radio 3.4–4: su mitad de arriba queda por encima del viewBox. El
   elemento raíz de un SVG recorta por defecto (el `overflow:hidden` de la
   hoja del navegador), así que el punto salía con el lomo plano —medido en la
   puerta: el primer renglón de cian medía 7px de ancho, donde un círculo de
   8.5px debería empezar en punta. `overflow:visible` deja que la marca pinte
   su chispa y su glow fuera de la caja, sin deformar el dibujo: el viewBox no
   se toca. */
svg[viewBox="0 0 120 44"]{overflow:visible}

/* 2) La puerta de edad, en alturas cortas.
   --------------------------------------------------------------------------
   `#puerta` es una ventana fija centrada. Cuando el contenido no cabe —el
   paso del alias a 360×640, o cualquier estado con el texto ampliado al
   125%— el flex lo centraba y el sobrante se perdía arriba y abajo sin forma
   de alcanzarlo, porque `body.cerrada` bloquea el scroll de la página. Con
   `margin:auto` la escena se centra cuando sobra espacio y arranca desde
   arriba cuando falta, y la propia puerta desplaza el resto. */
#puerta{align-items:flex-start;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain}
#puerta .escena{margin:auto}

/* 3) Espaciados de la puerta por altura.
   --------------------------------------------------------------------------
   En ventanas de 700px de alto o menos el mismo contenido respira más junto,
   para que la puerta quede entera sin scroll en los tamaños del encargo (el
   paso del alias a 360×640 es el caso más apretado). Solo márgenes y alturas:
   los textos no cambian. */
@media(max-height:700px){
  #puerta{padding-top:18px;padding-bottom:max(18px,env(safe-area-inset-bottom))}
  #puerta .marca{margin-bottom:18px}
  #puerta .palabra{margin:14px 0 2px}
  #puerta .caja-txt p{margin-bottom:18px}
  .puerta-nota{margin-top:16px}
  .al-rejilla{max-height:min(36vh,240px);margin-bottom:14px}
  .al-nota{margin-top:12px}
}

/* 4) Zoom de texto al 125% en celular.
   --------------------------------------------------------------------------
   Con el texto ampliado, el ancho de composición del encabezado baja a ~276px
   y la fila logo + bolsa + menú no cabía: pedía ~340px y desbordaba el
   documento (medido: 434 > 390 a 125% en 390 de ancho). La consulta de
   contenedor mide la barra misma —no la ventana, que con el zoom puesto no
   cambia—, así que a partir de ahí sobra la palabra: la marca del logo se
   queda y el nombre lo sigue diciendo el resto del sitio (la puerta, el pie,
   el título de la pestaña). Donde `@container` no exista, la regla se ignora
   y queda el comportamiento de siempre. */
.nav{container-type:inline-size}
@container (max-width:315px){.logo span{display:none}}

/* ==========================================================================
   APRENDER — índice (/aprender/) y páginas de artículo (/aprender/<slug>/).

   La sección del inicio enlaza a estas páginas (antes las tarjetas eran
   botones sin destino). Mismo lenguaje visual que el resto del sitio: fondo
   noche, tarjetas ciruela como las puertas del catálogo, acento cian y
   Fraunces en los títulos. La cabecera reutiliza .est-cab, la de la ayuda.
   ========================================================================== */

/* Índice de artículos */
.lecturas{max-width:1080px;margin:0 auto;padding:54px var(--pad) 110px}
.lecturas .entrada{color:#BDB5C8;max-width:56ch;margin-top:16px}
.lecturas .rejilla-lecturas{margin-top:46px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.art-indice{display:flex;flex-direction:column;background:var(--ciruela);border:1px solid var(--linea);
  padding:30px 24px 26px;min-height:250px;transition:border-color .3s,background .3s,transform .3s;text-align:left}
.art-indice:hover{border-color:var(--magenta);background:var(--ciruela-alto);transform:translateY(-4px)}
.art-indice .etq{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--cian)}
.art-indice h2{margin:16px 0 10px}
.art-indice p{color:#A9A1B6;font-size:14.5px;line-height:1.6;flex:1}
.art-indice .min{margin-top:20px;font-family:var(--mono);font-size:11px;color:#8C86A0}
.lecturas .pie-indice{margin-top:44px;display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap}
.lecturas .pie-indice p{color:var(--humo);font-size:15px;max-width:48ch}
@media(max-width:900px){.lecturas .rejilla-lecturas{grid-template-columns:1fr}.lecturas{padding:42px var(--pad) 84px}}

/* Página de artículo: una columna de lectura de ~70 caracteres */
.articulo{max-width:660px;margin:0 auto;padding:54px var(--pad) 110px}
.articulo .etq{color:var(--cian)}
.articulo h1{margin:16px 0 20px;font-size:clamp(2rem,4.6vw,3.2rem)}
.articulo .meta{display:flex;gap:12px;flex-wrap:wrap;font-family:var(--mono);font-size:11.5px;
  letter-spacing:.06em;color:#8C86A0;padding-bottom:26px;border-bottom:1px solid var(--linea);margin-bottom:34px}
.articulo .cuerpo p{color:#D8D2E0;font-size:17px;line-height:1.78;margin-bottom:20px}
.articulo .cuerpo h2{font-family:var(--display);font-weight:400;font-size:clamp(1.3rem,2.6vw,1.7rem);
  line-height:1.25;margin:44px 0 14px;letter-spacing:-.01em}
.articulo .cierre{margin-top:54px;padding-top:30px;border-top:1px solid var(--linea);
  display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.articulo .siguiente{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--cian);transition:color .2s}
.articulo .siguiente:hover{color:var(--magenta)}
@media(max-width:620px){.articulo{padding:40px var(--pad) 84px}.articulo .cuerpo p{font-size:16.5px}}