/* =============================================================================
   [2026-09-09 21:30] web.css — LA WEB DE LAVANDIO: tokens + todo el CSS, móvil primero
   =============================================================================
   Fase 1 del plan (docs/lavanda/web/conceptos/PLAN-WEB.md): los tokens del apartado 3 tal cual y
   los estilos de la escena clavada, de la sección del panel y del consumo en directo, portados de
   F-mezcla.html (la especificación en código) a los tokens. Lo que define el ASPECTO (colores,
   tamaños de texto, radios, sombras, tiempos, la posición de la pantalla en la foto, la geometría
   de la escena) es un token de :root y el JS lee los suyos con getComputedStyle; las medidas
   estructurales propias de cada componente (rellenos, huecos, anchos de columna) van en su regla.
   Único punto de corte: 820px (por debajo, móvil). Sin fuentes externas: Ubuntu si está.
   ========================================================================== */

:root {
    /* --- azules del reposo real (muestreados de 01-reposo.png) --- */
    --azul-1: #21bddb;   /* cian, arriba del degradado */
    --azul-2: #41abd6;   /* medio */
    --azul-3: #1f7ec9;   /* abajo-izquierda; también color de enlace/acento sobre blanco */
    --azul-4: #235bba;   /* abajo-derecha, el más profundo */
    --noche:  #061a3a;   /* DERIVADO (no muestreado): fondo del clímax, azul noche */
    --cielo:  linear-gradient(165deg, var(--azul-1) 0%, var(--azul-2) 38%, var(--azul-3) 72%, var(--azul-4) 100%);

    /* --- acentos del reposo real --- */
    --amarillo: #ffe07a; /* el «tres pasos» del título del reposo; títulos y regla sobre azul */
    --oro:      #d7a526; /* el sello «toca aquí para empezar»; botón principal */

    /* --- del producto (es lo que sale en las capturas) --- */
    --magenta:  #c40dd8; /* color real de la animación de envío de créditos (config develstack) */

    /* --- texto y superficies --- */
    --tinta:   #06233a;  /* texto principal sobre blanco */
    --tinta-2: #2b4a63;  /* texto secundario */
    --tinta-3: #5b7a92;  /* pies, notas, ejes */
    --nube:    #eaf6fb;  /* tarjetas claras, chips */
    --blanco:  #ffffff;
    --blanca:  rgba(255,255,255,.94); /* fondo de las secciones blancas: deja ver las burbujas */

    /* --- las 7 máquinas (LavandaPalette::machine_color, Palette.php:91-123) --- */
    --l1: #5B3FA8; --l2: #8C79C2; --l3: #432F7C; --l4: #B5A9D8;   /* lavadoras: morado y sus tonos */
    --s1: #00868F; --s2: #4DAAB1; --s3: #00636A;                  /* secadoras: teal y sus tonos   */

    /* --- tipografía --- */
    --fuente: 'Ubuntu', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
    /* Ubuntu es la del folleto. No se carga de Google Fonts (sin dependencias externas): si
       el visitante no la tiene, cae al stack del sistema. Pesos usados: 400, 700, 800. */

    /* --- escala (clamp: móvil → escritorio) --- */
    --t-hero:  clamp(32px, 4.8vw, 78px);   /* título de capítulo de la escena */
    --t-h2:    clamp(32px, 4vw, 62px);     /* título de sección */
    --t-h3:    clamp(26px, 2.8vw, 40px);   /* subtítulo de sección */
    --t-lead:  clamp(17px, 1.5vw, 21px);
    --t-cuerpo: clamp(15px, 1.2vw, 17px);
    --t-kicker: 13px;  /* letter-spacing .28em, mayúsculas */

    /* --- espacio --- */
    --seccion-y: 13vh; --seccion-x: 6vw;          /* móvil: 9vh / 6vw */
    --hueco: 2.4vw;                               /* separación de rejillas */

    /* --- formas --- */
    --r-tarjeta: 18px; --r-chip: 16px; --r-pill: 999px; --r-marco: 18px;
    --sombra-marco: 0 30px 80px rgba(3,20,50,.35);
    /* [2026-09-09 21:40] Mismos valores que el plan (0 60px 80px rgba(3,20,50,.5)) pero como box-shadow,
       no como filter: drop-shadow(). MEDIDO en Chrome sin GPU (1600×1000): con el filtro la portada iba
       a 11 fps y sin él a 57; congelar la máquina o quitar las burbujas no cambiaba nada. El filtro
       vuelve a difuminar 80 px la máquina entera en CADA fotograma (la escena repinta siempre por las
       burbujas); la box-shadow se rasteriza una vez y solo se compone. La foto es opaca salvo las
       esquinas redondeadas, así que la silueta de la sombra es la misma. */
    --sombra-maquina: 0 60px 80px rgba(3,20,50,.5);
    --sombra-tarjeta: 0 30px 80px rgba(3,20,50,.35);

    /* --- movimiento --- */
    /* [2026-09-09 22:20] --pulso-on / --pulso-off retirados (decisión 16 del plan: nada técnico del envío en la web) */
    --uso-cada: 2400ms;                      /* lo que dura cada pantalla en el patrón «uso real» */
    --suave: cubic-bezier(.2,.8,.2,1);

    /* --- la pantalla dentro de la foto de la máquina (bisel medido a píxel) --- */
    --pantalla-left: 16.82%; --pantalla-top: 7.58%; --pantalla-w: 65.57%; --pantalla-h: 51.79%;

    /* =====================================================================
       Tokens de componente: valores que en F-mezcla.html iban sueltos por los
       componentes. Aquí para que ningún archivo lleve cifras de aspecto propias.
       ===================================================================== */
    --kicker-espaciado: .28em;
    --t-portada: clamp(32px, 4.2vw, 66px);        /* el título del capítulo 0, algo más contenido */
    --t-hero-movil: clamp(26px, 7.5vw, 40px);
    --t-cap-p: clamp(16px, 1.35vw, 21px);         /* párrafo del capítulo */
    --t-h4: 17px; --t-tabla: 15px; --t-tabla-movil: 13px; --t-eje: 11px; --t-chip: 13px;
    --claro: #eef8fd;                             /* texto corrido sobre azul */
    --linea-clara: rgba(255,255,255,.28);         /* filetes sobre azul */
    --linea-oscura: rgba(6,35,58,.1);             /* filetes sobre blanco */
    --rejilla: rgba(6,35,58,.09);                 /* rejilla de la gráfica */
    --sombra-titulo: 0 4px 30px rgba(3,20,50,.25);
    --marco-borde: #0c2340; --marco-panel-borde: #cfe9f4;
    --latido: #ff3355; --latido-texto: #c02a4a;   /* el punto rojo «en directo» */
    --fondo-tarjeta-oscura: rgba(255,255,255,.12); --borde-tarjeta-oscura: rgba(255,255,255,.28);
    /* fondos de la pantalla de la máquina según la captura (apartado 4.2) */
    --pantalla-reposo: #0f6ccf; --pantalla-clara: #f5f4f7; --pantalla-tunel: #0a0410;
    --reflejo: linear-gradient(115deg, rgba(255,255,255,.25) 0%, rgba(255,255,255,0) 38%);
    /* el derrame magenta del clímax (apartado 4.4): del --magenta del producto, sin repetir su RGB */
    --derrame-centro: color-mix(in srgb, var(--magenta) 60%, transparent); --derrame-medio: color-mix(in srgb, var(--magenta) 16%, transparent);
    /* burbujas (apartado 4.1): sobre el azul, blancas; sobre las secciones blancas, azul tenue */
    --burbuja-centro: rgba(255,255,255,.55); --burbuja-medio: rgba(255,255,255,.08);
    --burbuja-borde: rgba(255,255,255,.22);  --burbuja-trazo: rgba(255,255,255,.35);
    /* [2026-09-11 07:20, usuario] Sobre el blanco, las burbujas en azul del mismo cuerpo que las blancas
       sobre el azul: el mismo dibujo, el color cambiado. */
    --burbuja-centro-blanca: rgba(33,189,219,.55); --burbuja-medio-blanca: rgba(33,189,219,.10);
    --burbuja-borde-blanca: rgba(33,189,219,.24); --burbuja-trazo-blanca: rgba(33,189,219,.38);
    /* geometría de la escena (apartados 4.2 y 5) */
    --maquina-alto: 90vh; --maquina-alto-movil: 56vh; --maquina-derecha: 8vw;
    --r-maquina: 5% / 2.3%;   /* esquinas de la foto (medidas en el PNG: ~45 px de radio sobre 880×1900) para recortar su sombra */
    --escena-arriba-movil: 3vh; --escena-abajo-movil: 8vh; --progreso-abajo-movil: 2.5vh;
    --columna-texto: 40vw;
    --grafica-alto: 360px; --grafica-alto-movil: 240px;
}

/* ======================= RESET ======================= */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
    font-family: var(--fuente); color: #fff; background: var(--azul-4);
    overflow-x: hidden;             /* en body se propaga al viewport: no rompe el sticky de la escena */
    -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }
button { font-family: inherit; }
em { font-style: normal; }
:focus-visible { outline: 3px solid var(--amarillo); outline-offset: 3px; }

/* ======================= EL FONDO: el reposo del kiosko, ampliado ======================= */
.cielo { position: fixed; inset: 0; z-index: 0; background: var(--cielo); }
#burbujas { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
main { position: relative; z-index: 1; }

/* ======================= TIPOGRAFÍA COMPARTIDA ======================= */
.kicker { font-size: var(--t-kicker); letter-spacing: var(--kicker-espaciado); text-transform: uppercase; font-weight: 700; }
.regla { height: 5px; width: 88px; background: var(--amarillo); border-radius: 3px; margin-top: 18px; }

/* ======================= LA ESCENA CLAVADA: PORTADA + LA COMPRA ======================= */
.escenario { height: 810vh; position: relative; }   /* [2026-09-12 06:36 → 12:15] 1000 → 900 → 810 vh: dos capítulos menos (ver escena.js), mismo recorrido de scroll para los que quedan */
.clavado { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.oscuro { position: absolute; inset: 0; background: var(--noche); opacity: 0; pointer-events: none; will-change: opacity; }
.derrame {
    position: absolute; left: 50%; top: 50%; width: 140vmax; height: 140vmax; margin: -70vmax 0 0 -70vmax;
    opacity: 0; pointer-events: none; will-change: transform, opacity;
    background: radial-gradient(circle, var(--derrame-centro) 0%, var(--derrame-medio) 26%, transparent 48%);
}
.escena3d {
    position: absolute; right: var(--maquina-derecha); top: 50%; height: var(--maquina-alto);
    aspect-ratio: 880 / 1900; transform: translateY(-50%); perspective: 1600px;
}
/* [2026-09-09 21:40] Sin filter (ver --sombra-maquina) y sin preserve-3d: en F-mezcla el filtro ya aplanaba el
   3D, así que los translateZ de la pantalla y el reflejo eran inertes; se quitan para que nada cambie de sitio
   respecto al bisel al girar. La sombra va en la foto, recortada a sus esquinas redondeadas (--r-maquina). */
.maquina { position: absolute; inset: 0; will-change: transform; }
.maquina > img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: var(--r-maquina); box-shadow: var(--sombra-maquina); }
.pantalla {
    position: absolute; left: var(--pantalla-left); top: var(--pantalla-top); width: var(--pantalla-w); height: var(--pantalla-h);
    overflow: hidden; background: var(--pantalla-clara); transition: background .4s;
}
/* capturas a 1080×1920: llenan el bisel entero (0,586 ≈ 9:16). Solo la actual se ve; sus vecinas
   quedan decodificadas a opacidad 0 para que el cambio sea instantáneo; el resto, ocultas. */
.pantalla img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; opacity: 0; }
.pantalla img.on { opacity: 1; }
.pantalla img[hidden] { display: none; }
.reflejo {
    position: absolute; left: var(--pantalla-left); top: var(--pantalla-top); width: var(--pantalla-w); height: var(--pantalla-h);
    pointer-events: none; background: var(--reflejo); mix-blend-mode: screen;
}

/* [2026-09-09 22:20] Los capítulos se apilan en UNA celda de rejilla (grid-area 1/1), no en absoluto: así
   .capitulos mide lo que el capítulo más alto y el translateY(-50%) centra de verdad (con los .cap
   absolutos medía 0 y el bloque colgaba del 50 %: a 1366×768 la portada se salía 75 px por abajo). */
.capitulos { position: absolute; left: var(--seccion-x); top: 50%; transform: translateY(-50%); width: var(--columna-texto); display: grid; align-items: center; }
.cap { grid-area: 1 / 1; position: relative; width: 100%; opacity: 0; transform: translateY(30px); pointer-events: none; will-change: transform, opacity; }
.cap.portada { opacity: 1; transform: none; }   /* sin JavaScript se lee la portada; con él, el scroll manda (estilo en línea) */
.cap .kicker { color: var(--amarillo); }
.cap h2 { font-size: var(--t-hero); line-height: 1; color: #fff; margin-top: 14px; letter-spacing: -.025em; text-shadow: var(--sombra-titulo); }
.cap h2 em { color: var(--amarillo); }
.cap p { color: var(--claro); font-size: var(--t-cap-p); line-height: 1.55; margin-top: 22px; max-width: 28em; }
.cap .dato {
    display: inline-block; margin-top: 24px; padding: 11px 16px; border: 1.5px solid rgba(255,255,255,.55);
    border-radius: 12px; font-size: var(--t-kicker); letter-spacing: .12em; text-transform: uppercase; color: #fff;
}
.cap ul { margin-top: 26px; max-width: 30em; list-style: none; }
.cap.portada h2 { font-size: var(--t-portada); }
.cap.portada p { margin-top: 16px; }
.cap.portada ul { margin-top: 18px; }
.cap li { display: flex; gap: 12px; padding: 8px 0; border-top: 1px solid var(--linea-clara); font-size: 16px; color: var(--claro); }
.cap li:last-child { border-bottom: 1px solid var(--linea-clara); }
.cap li i { width: 10px; height: 10px; border-radius: 50%; background: var(--amarillo); margin-top: 7px; flex: 0 0 auto; }
.cap li b { color: #fff; }

.progreso { position: absolute; left: var(--seccion-x); bottom: 4vh; width: var(--columna-texto); height: 3px; background: rgba(255,255,255,.3); }
.progreso i { display: block; height: 100%; background: var(--amarillo); transform: scaleX(0); transform-origin: left center; will-change: transform; }

/* ======================= LAS SECCIONES, AL PESO DEL PDF ======================= */
.bloque { position: relative; padding: var(--seccion-y) var(--seccion-x); }
/* el fondo blanco lo pinta el lienzo de las burbujas (burbujas.js) para que se vean a través; este de aquí
   es el respaldo por si el lienzo no llega a arrancar */
.blanca { background: var(--blanca); color: var(--tinta); }
/* solo las SECCIONES ceden su fondo al lienzo: la caja de la tabla comparativa también es `.blanca` y
   tiene esquinas redondeadas, que un rectángulo del lienzo dejaría cuadradas */
.burbujas-pintan section.blanca { background: none; }
/* [2026-09-10 04:30] El fondo azul se queda COMO ESTABA (petición del usuario: «no sé por qué ahora el azul
   del fondo es más oscuro cuando se baja; antes estaba bien»). El velo que había puesto para el contraste se
   retira. Para que el texto siga legible sobre el tramo cian del degradado, el contraste se refuerza en el
   TEXTO —no en el fondo— con una sombra suave, que no cambia el color de la web. */
.azul { color: #fff; }
.azul .kicker, .azul h2, .azul h3, .azul .lead, .azul .lista li, .azul .nota { text-shadow: 0 1px 12px rgba(3,20,50,.55), 0 1px 2px rgba(3,20,50,.45); }
.bloque .kicker { color: var(--azul-3); }
.azul .kicker { color: var(--amarillo); }
.bloque h2 { color: var(--tinta); font-size: var(--t-h2); letter-spacing: -.025em; line-height: 1.05; margin-top: 12px; }
.bloque h2 em { color: var(--azul-3); }
.azul h2 { color: #fff; }
.azul h2 em { color: var(--amarillo); }
.bloque h3 { color: var(--tinta); font-size: var(--t-h3); letter-spacing: -.02em; line-height: 1.1; margin-top: 9vh; }
.azul h3 { color: #fff; }
.bloque .lead { color: var(--tinta-2); margin-top: 18px; max-width: 46em; font-size: var(--t-lead); line-height: 1.55; }
.azul .lead { color: var(--claro); }
.azul .lead b { color: #fff; }
/* las tarjetas se reparten el ancho: dos si son dos, tres si son tres (al quitar «Ninguna se queda
   ocupada» quedaban dos en una rejilla de tres y sobraba un hueco a la derecha) */
.tarjetas { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.6vw; margin-top: 5vh; }
.tarjetas:has(> :nth-child(3)) { grid-template-columns: repeat(3, 1fr); }
.tarjeta { background: var(--nube); border: 1px solid var(--marco-panel-borde); border-radius: var(--r-chip); padding: 22px 24px; }
.tarjeta h4 { font-size: var(--t-h4); color: var(--tinta); }
/* [2026-09-10 06:50, usuario] Las siete banderas del kiosko, una detrás de otra, «para que luzca y se vean».
   Son las mismas que dibuja el producto en CSS (lavanda.css), sin ninguna descarga. */
.banderas { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 4px; }
.banderas .bandera { width: 42px; height: 30px; border-radius: 5px; box-shadow: 0 2px 6px rgba(3,20,50,.22), inset 0 0 0 1px rgba(0,0,0,.15); }
.tarjeta p { color: var(--tinta-2); margin-top: 6px; line-height: 1.5; font-size: var(--t-cuerpo); }
.tarjetas.oscuras .tarjeta { background: var(--fondo-tarjeta-oscura); border-color: var(--borde-tarjeta-oscura); }
.tarjetas.oscuras h4 { color: #fff; }
.tarjetas.oscuras p { color: var(--claro); }

/* ======================= EL CONSUMO EN DIRECTO (misma disposición que el panel real) ======================= */
.vivo { margin-top: 3.5vh; background: var(--blanca); color: var(--tinta); border-radius: var(--r-tarjeta); padding: 22px 26px; box-shadow: var(--sombra-tarjeta); }
.vivo-cab { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: var(--t-kicker); letter-spacing: .2em; text-transform: uppercase; color: var(--tinta-3); }
.vivo-cab .total { font-size: 22px; letter-spacing: 0; text-transform: none; font-weight: 800; color: var(--azul-3); font-variant-numeric: tabular-nums; }
.latido { display: inline-flex; align-items: center; gap: 8px; color: var(--latido-texto); }
.latido b { width: 9px; height: 9px; border-radius: 50%; background: var(--latido); animation: late 1.4s infinite; }
@keyframes late { 50% { opacity: .25; transform: scale(.7); } }
.vivo .ver {   /* solo con prefers-reduced-motion: arranca la gráfica a petición */
    font-size: 14px; font-weight: 800; letter-spacing: 0; text-transform: none; color: var(--tinta);
    background: var(--amarillo); border: 0; border-radius: var(--r-pill); padding: 8px 14px; cursor: pointer;
}
.vivo-tabla-caja { margin-top: 14px; }
.tabla-vivo { width: 100%; border-collapse: collapse; font-size: var(--t-tabla); font-variant-numeric: tabular-nums; }
.tabla-vivo th { text-align: right; font-weight: 600; color: var(--tinta-3); padding: 9px 12px; border-bottom: 2px solid var(--nube); font-size: var(--t-chip); }
.tabla-vivo th:first-child, .tabla-vivo td:first-child { text-align: left; }
.tabla-vivo td { padding: 9px 12px; border-bottom: 1px solid var(--nube); text-align: right; white-space: nowrap; transition: opacity .3s; }
.tabla-vivo td i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 9px; vertical-align: -1px; }
.tabla-vivo td .fase { color: var(--tinta-3); font-size: var(--t-chip); margin-left: 8px; font-weight: 400; }
.tabla-vivo td.ahora { font-weight: 700; }
.tabla-vivo tr.total td { font-weight: 800; border-top: 2px solid var(--azul-1); border-bottom: none; }
.tabla-vivo tr.apagada td { opacity: .4; }
.vivo-grafica { display: block; width: 100%; height: var(--grafica-alto); margin-top: 14px; }
.vivo-leyenda { display: flex; flex-wrap: wrap; gap: 6px 8px; justify-content: center; margin-top: 12px; }
.vivo-leyenda button {
    display: inline-flex; align-items: center; gap: 7px; min-height: 34px; font-size: var(--t-chip); color: var(--tinta-2);
    background: none; border: 1px solid transparent; border-radius: var(--r-pill); padding: 6px 12px; cursor: pointer;
    transition: opacity .3s, border-color .3s, background-color .3s;
}
.vivo-leyenda button i { width: 11px; height: 11px; border-radius: 3px; }
.vivo.aislando .vivo-leyenda button { opacity: .45; }
.vivo.aislando .vivo-leyenda button.on { opacity: 1; border-color: var(--azul-1); background: var(--nube); }
.vivo noscript { display: block; margin-top: 10px; font-size: var(--t-chip); color: var(--tinta-3); }
.vivo-pie { margin-top: 12px; font-size: var(--t-chip); color: var(--tinta-3); text-align: center; }

/* ======================= MÓVIL (la mayoría de los visitantes; apartado 5) ======================= */
@media (max-width: 820px) {
    :root { --seccion-y: 9vh; }
    .escena3d { right: auto; left: 50%; top: var(--escena-arriba-movil); height: var(--maquina-alto-movil); transform: translateX(-50%); }
    .capitulos { left: var(--seccion-x); right: var(--seccion-x); width: auto; top: auto; bottom: var(--escena-abajo-movil); transform: none; align-items: end; }   /* crece hacia ARRIBA: así nunca se sale por abajo */
    .cap h2 { font-size: var(--t-hero-movil); margin-top: 8px; }
    .cap p { font-size: 15px; margin-top: 10px; max-width: none; }
    .cap ul, .cap .dato { display: none; }
    .cap.portada ul { display: block; margin-top: 10px; }
    .cap.portada p { display: none; }
    .cap li { padding: 5px 0; font-size: 14px; }
    .progreso { left: var(--seccion-x); width: calc(100% - 2 * var(--seccion-x)); bottom: var(--progreso-abajo-movil); }
    .bloque h3 { margin-top: 7vh; }
    .tarjetas { grid-template-columns: 1fr; gap: 12px; }
    .vivo { padding: 14px; }
    .vivo-cab { flex-wrap: wrap; }
    .vivo-tabla-caja { overflow-x: auto; }
    .tabla-vivo { font-size: var(--t-tabla-movil); }
    /* [2026-09-09 21:38] a 390 px las cinco columnas caben sin scroll horizontal (medido: con 8 px de relleno
       se cortaba «Media»); el scroll de la caja queda solo como red de seguridad para anchos menores */
    .tabla-vivo td, .tabla-vivo th { padding: 7px 5px; }
    .tabla-vivo th { font-size: 12px; }
    .tabla-vivo td i { margin-right: 6px; }
    .tabla-vivo td .fase { display: block; margin-left: 0; font-size: 11px; }   /* la fase debajo del nombre: la primera columna se estrecha */
    .vivo-grafica { height: var(--grafica-alto-movil); }
}
/* [2026-09-09 22:20] Dentro de la escena, en móvil, TODO en la misma unidad que .clavado (100svh): con vh, la
   barra de direcciones del navegador (que resta al viewport pequeño) podía meter el texto sobre la máquina. */
@supports (height: 1svh) {
    :root { --maquina-alto-movil: 56svh; --escena-arriba-movil: 3svh; --escena-abajo-movil: 8svh; --progreso-abajo-movil: 2.5svh; }
}

/* =====================================================================================
   [2026-09-09 22:05] FASES 3, 4 y 5: el resto de secciones al peso del PDF, el patrón «feature +
   animación de uso real», el selector de idioma (mismo control que el kiosko) y el pulido.
   ===================================================================================== */
.pantalla picture { display: contents; }
.bloque { content-visibility: auto; contain-intrinsic-size: auto 1000px; }   /* lo que no está cerca no se pinta */

/* los tres pasos (PDF p.2) */
.pasos { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--hueco); margin-top: 6vh; }
.paso .n { width: 44px; height: 44px; border-radius: 50%; background: var(--azul-3); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 19px; }
.paso h3 { font-size: 24px; margin-top: 16px; color: var(--tinta); }
.paso p { color: var(--tinta-2); margin-top: 8px; line-height: 1.5; font-size: var(--t-cuerpo); }

/* ---- EL PATRÓN: feature + animación de uso real (apartado 7) ---- */
.feature { display: grid; grid-template-columns: 1fr 1fr; gap: 5vw; align-items: center; margin-top: 8vh; }
.feature.invertida .texto { order: 2; }
.feature .texto h3 { margin-top: 0; }
.uso { --uso-alto: 82vh; position: relative; opacity: 0; transform: translateY(40px); transition: opacity .8s var(--suave), transform .9s var(--suave); }
.uso.on { opacity: 1; transform: none; }
.uso.corta { --uso-alto: 66vh; }
.tira3 .uso { --uso-alto: 70vh; }
/* [2026-09-09 22:50] El marco toma la forma de su captura (--prop, que pone uso-real.js con las dimensiones
   reales) y la imagen va con `contain`: NINGUNA captura se recorta. Antes el marco era fijo y `cover`
   mutilaba lo que no encajaba (medido: 57-73 % perdido en las gráficas anchas y en la tira de fases). */
.uso .marco { position: relative; overflow: hidden; border-radius: var(--r-marco); background: #000; box-shadow: var(--sombra-marco); cursor: pointer; }
.uso[data-marco="kiosko"] .marco { aspect-ratio: var(--prop, 9 / 16); width: 100%; max-width: calc(var(--uso-alto) * var(--prop, .5625)); margin: 0 auto; border: 9px solid var(--marco-borde); }
.uso[data-marco="panel"] .marco { aspect-ratio: var(--prop, 1500 / 950); border: 1px solid var(--marco-panel-borde); background: var(--blanco); }
.uso .marco picture { display: contents; }
.uso .marco img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center; opacity: 0; transition: opacity .6s; }
/* [2026-09-10 05:30, regla del usuario] Lo que sobra alrededor de una captura se rellena con ELLA MISMA,
   ampliada y desenfocada; nunca con una franja de color plano. Vale para cualquier hueco que deje una
   pantalla más grande que su contenido. */
.uso .marco img.relleno, .mosaico figure.kiosk img.relleno { object-fit: cover; filter: blur(26px) saturate(1.12); transform: scale(1.14); }
.mosaico figure.kiosk { position: relative; overflow: hidden; }
.mosaico figure.kiosk img.relleno { position: absolute; left: 0; top: 0; width: 100%; height: clamp(300px, 42vw, 680px); opacity: 0; transition: opacity .6s; }
.mosaico figure.kiosk img.relleno.on { opacity: 1; }
.mosaico figure.kiosk img[data-captura]:not(.relleno) { position: relative; z-index: 1; background: none; }
.uso .marco img.on { opacity: 1; }
.uso .barra { position: absolute; left: 14px; right: 14px; top: 12px; display: flex; gap: 5px; z-index: 2; }
/* [2026-09-09 23:20] `box-sizing: content-box` a propósito: con el border-box del reset, el relleno de 6 px
   (que agranda el área táctil a 15 px) dejaba la pista en 0 px de alto y las pantallas pendientes no se
   veían. Ahora la pista mide sus 3 px y el relleno solo agranda la zona de toque. */
.uso .barra i { flex: 1; box-sizing: content-box; height: 3px; background: rgba(255,255,255,.35); border-radius: 2px; overflow: hidden; cursor: pointer; padding: 6px 0; background-clip: content-box; }
.uso .barra i b { display: block; height: 3px; background: #fff; transform: scaleX(0); transform-origin: left center; will-change: transform; }
.uso .barra i.hecha b { transform: scaleX(1); }
.uso .pie { margin-top: 14px; font-size: var(--t-cuerpo); color: var(--tinta-2); min-height: 1.5em; line-height: 1.45; }
.azul .uso .pie { color: var(--claro); }
.uso .pie b { color: var(--azul-3); margin-right: 8px; }
.azul .uso .pie b { color: var(--amarillo); }
.uso.ancha { margin-top: 5vh; }
.uso.ancha .marco { max-width: 1500px; margin: 0 auto; }
.tira3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--hueco); margin-top: 6vh; }

.lista { list-style: none; margin-top: 18px; }
.lista li { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid var(--linea-oscura); color: var(--tinta-2); line-height: 1.45; font-size: var(--t-cuerpo); }
.azul .lista li { border-color: var(--linea-clara); color: var(--claro); }
.lista li i { width: 9px; height: 9px; border-radius: 50%; background: var(--azul-1); margin-top: 8px; flex: 0 0 auto; }
.lista b { color: var(--tinta); }
.azul .lista b { color: #fff; }
.grupos { display: grid; grid-template-columns: 1fr 1fr; gap: 4vw; margin-top: 5vh; align-items: end; }
.grupos h3 { margin-top: 0; margin-bottom: 6px; font-size: 22px; }

/* mosaicos: entran escalonados (.on en el contenedor; --i es el orden de cada figura) */
/* [2026-09-09 23:20] `align-items: start`: sin él, la rejilla estira todas las figuras de la fila a la altura
   de la más alta y las bajas quedaban con media tarjeta en blanco (medido en el mosaico de energía y en el
   de PRO, donde una captura vertical mide 520 px y sus vecinas 226). */
.mosaico { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.4vw; margin-top: 5vh; align-items: start; }
.mosaico.g3 { grid-template-columns: repeat(3, 1fr); }
.mosaico.g2 { grid-template-columns: 1fr 1fr; margin-top: 1.4vw; }
.mosaico figure { border-radius: 12px; overflow: hidden; border: 1px solid var(--marco-panel-borde); background: var(--blanco); opacity: 0; transform: translateY(30px); transition: opacity .7s, transform .8s var(--suave); transition-delay: calc(var(--i, 0) * 110ms); }
.mosaico.on figure { opacity: 1; transform: none; }
.mosaico picture { display: contents; }
/* `height: auto` es obligatorio: las <img> llevan width/height reales (para reservar el hueco y que la página
   no salte al cargar) y sin esto el atributo manda y deforma la imagen (medido en móvil: 341×1900). */
.mosaico img { width: 100%; height: auto; display: block; }
.mosaico figcaption { padding: 10px 14px 12px; font-size: var(--t-chip); color: var(--tinta-2); line-height: 1.4; }
.mosaico.clara figure { border-color: rgba(255,255,255,.35); }
/* [2026-09-09 22:50] Las capturas VERTICALES (pantalla de la máquina, ficha del móvil) dentro de un mosaico de
   columnas anchas: se ven ENTERAS y centradas, con su fondo. Antes iban con max-height + cover y se perdía
   el 58 % y el 65 % (medido). */
.mosaico figure.kiosk img { height: clamp(300px, 42vw, 680px); object-fit: contain; object-position: center; background: var(--nube); }
.nota { font-size: var(--t-chip); color: var(--tinta-3); margin-top: 2.4vh; line-height: 1.45; }
.nota.clara { color: #cfe6f5; }
.pro-banner { margin-top: 5vh; background: var(--tinta); color: #fff; border-radius: var(--r-chip); padding: 22px 28px; font-size: var(--t-cuerpo); line-height: 1.55; }
.pro-banner b { color: var(--amarillo); }
.cta { margin-top: 6vh; background: var(--fondo-tarjeta-oscura); border: 1px solid rgba(255,255,255,.3); border-radius: var(--r-tarjeta); padding: 30px 34px; }
.cta h3 { margin-top: 0; font-size: 26px; color: #fff; }
.cta p { color: var(--claro); margin-top: 12px; line-height: 1.55; font-size: var(--t-cuerpo); max-width: 60em; }

/* la tabla comparativa (PDF p.7), dentro de una caja blanca que hace scroll si no cabe */
.caja-tabla { border-radius: var(--r-tarjeta); padding: 1.5vw 2.5vw; margin-top: 5vh; overflow-x: auto; }
.cmp { width: 100%; border-collapse: collapse; font-size: 16px; }
.cmp th, .cmp td { padding: 14px 16px; border-bottom: 1px solid var(--linea-oscura); text-align: left; color: var(--tinta-2); }
.cmp td b { color: var(--tinta); }
.cmp th.col, .cmp td.col { text-align: center; width: 160px; }
.cmp td.col { font-weight: 800; color: #12a37f; }
.cmp td.col.no { color: #b9c7d2; font-weight: 400; }
.tag { display: inline-block; font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; padding: 6px 12px; border-radius: var(--r-pill); }
.tag--base { background: var(--nube); color: var(--azul-3); }
.tag--pro { background: var(--tinta); color: var(--amarillo); }

/* el cierre */
.cierre { padding: 16vh var(--seccion-x); text-align: center; color: #fff; }
.cierre h2 { color: #fff; font-size: clamp(40px, 7vw, 120px); letter-spacing: -.04em; line-height: .92; }
.cierre h2 em { color: var(--amarillo); }
/* [2026-09-10 05:25, usuario] El correo BIEN GRANDE abajo, y el WhatsApp al lado. */
.cierre-lead { color: var(--claro); font-size: var(--t-lead); margin-top: 3vh; }
/* [2026-09-10 06:45, usuario] Los dos botones, del MISMO tamaño: misma rejilla de dos columnas iguales,
   misma altura y el texto centrado y ajustado dentro de cada uno. */
.contacto { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 20px; justify-content: center; align-items: stretch; margin-top: 5vh; max-width: 1000px; margin-inline: auto; }
.contacto a {
    display: flex; align-items: center; justify-content: center; gap: 12px; text-decoration: none;
    min-height: 92px; padding: 16px 26px; border-radius: var(--r-pill); box-shadow: var(--sombra-tarjeta);
    font-weight: 800; font-size: clamp(17px, 2.1vw, 30px); letter-spacing: -.01em; text-align: center;
    overflow-wrap: anywhere;
}
.contacto__mail { background: var(--amarillo); color: var(--tinta); }
.contacto__wa { background: #25D366; color: #fff; }
.contacto__wa svg { width: 1.1em; height: 1.1em; flex: 0 0 auto; }

/* [2026-09-11 08:40] Ir arriba: fijo a la izquierda, con el mismo aspecto que el selector de idioma de la
   derecha (píldora blanca con sombra) para que se lean como un par. */
.arriba {
    position: fixed; top: 12px; left: 16px; z-index: 5;
    display: flex; align-items: center; justify-content: center; width: 46px; height: 46px;
    background: var(--blanco); border: 1px solid var(--marco-panel-borde); border-radius: 50%;
    box-shadow: 0 2px 10px rgba(3,20,50,.22); color: var(--azul-3); cursor: pointer;
    transition: transform .2s var(--suave), background-color .2s;
}
.arriba svg { width: 22px; height: 22px; }
.arriba:hover { background: var(--nube); transform: translateY(-2px); }
.arriba:active { transform: translateY(0); }
/* [2026-09-11 13:10] En pantallas BAJAS (móvil apaisado) o muy estrechas, arriba a la izquierda es justo
   donde arranca el titular: medido, tapaba «La … de tu lavandería» en los cinco puntos de scroll de
   844×390 y varias líneas en 320×568. Ahí baja a la esquina de abajo, donde no hay texto. */
@media (max-height: 520px), (max-width: 360px) {
    .arriba { top: auto; bottom: 12px; left: 12px; }
}

/* el selector de idioma: el mismo control que el kiosko (bandera + código + caret; se despliegan las siete) */
.idioma { position: fixed; top: 12px; right: 16px; z-index: 5; }
.idioma .toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; background: var(--blanco); border: 1px solid var(--marco-panel-borde); border-radius: var(--r-pill); padding: 7px 12px 7px 9px; box-shadow: 0 2px 10px rgba(3,20,50,.22); }
.idioma .codigo { font-size: 14px; font-weight: 800; color: var(--tinta); }
.idioma .caret { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--azul-3); transition: transform .2s; }
.idioma.is-open .caret { transform: rotate(180deg); }
.idioma .panel { display: none; position: absolute; top: calc(100% + 8px); right: 0; min-width: 200px; background: var(--blanco); border: 1px solid var(--marco-panel-borde); border-radius: var(--r-chip); padding: 8px; box-shadow: var(--sombra-tarjeta); flex-direction: column; gap: 2px; }
.idioma.is-open .panel { display: flex; }
.idioma .panel button { display: flex; align-items: center; gap: 12px; width: 100%; cursor: pointer; background: none; border: 0; border-radius: 12px; padding: 10px 12px; font-size: 15px; font-weight: 600; color: var(--tinta); text-align: left; }
.idioma .panel button:hover { background: var(--nube); }
.idioma .panel button.is-active { background: var(--azul-3); color: #fff; }
/* banderas dibujadas en CSS, como en el producto (lavanda.css): ninguna descarga */
.bandera { display: inline-block; width: 28px; height: 20px; border-radius: 4px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); background-size: cover; flex: none; }
.bandera--es { background: linear-gradient(#C60B1E 0 25%, #FFC400 25% 75%, #C60B1E 75%); }
.bandera--fr { background: linear-gradient(90deg, #002395 0 33.33%, #fff 33.33% 66.66%, #ED2939 66.66%); }
.bandera--de { background: linear-gradient(#000 0 33.33%, #DD0000 33.33% 66.66%, #FFCE00 66.66%); }
.bandera--nl { background: linear-gradient(#AE1C28 0 33.33%, #fff 33.33% 66.66%, #21468B 66.66%); }
.bandera--it { background: linear-gradient(90deg, #009246 0 33.33%, #fff 33.33% 66.66%, #CE2B37 66.66%); }
.bandera--pt { background: linear-gradient(90deg, #006600 0 40%, #FF0000 40%); }
.bandera--en { background:
    linear-gradient(90deg, transparent 0 43%, #C8102E 43% 57%, transparent 57%),
    linear-gradient(transparent 0 36%, #C8102E 36% 64%, transparent 64%),
    linear-gradient(90deg, transparent 0 39%, #fff 39% 61%, transparent 61%),
    linear-gradient(transparent 0 31%, #fff 31% 69%, transparent 69%),
    linear-gradient(63deg, transparent 0 45.5%, #C8102E 45.5% 51.5%, transparent 51.5%),
    linear-gradient(-63deg, transparent 0 45.5%, #C8102E 45.5% 51.5%, transparent 51.5%),
    linear-gradient(63deg, transparent 0 42%, #fff 42% 55%, transparent 55%),
    linear-gradient(-63deg, transparent 0 42%, #fff 42% 55%, transparent 55%),
    #012169; }

/* ======================= MÓVIL, segunda parte (las secciones nuevas) ======================= */
@media (max-width: 820px) {
    .pasos, .tarjetas, .mosaico, .mosaico.g3, .mosaico.g2, .tira3, .grupos { grid-template-columns: 1fr; }
    /* [2026-09-11 22:00, cazado por el usuario en el móvil: «la parte de la derecha queda cortada»] Las
       tarjetas de TRES («Al instante», «Consumo por máquina») seguían en tres columnas: la regla de
       escritorio `.tarjetas:has(> :nth-child(3))` (:231) pesa más que `.tarjetas` y ganaba a las dos de
       móvil (:293 y la de arriba). El `overflow-x: hidden` del body (:120) escondía lo que se salía. */
    .tarjetas:has(> :nth-child(3)) { grid-template-columns: 1fr; }
    .mosaico, .mosaico.g2 { gap: 12px; margin-top: 4vh; }
    /* a una columna, las capturas verticales se ven a su tamaño natural: a 341 px de ancho el texto se lee
       (con la altura fija del escritorio quedaban a 0,14 de escala, ilegibles) */
    .mosaico figure.kiosk img { height: auto; }
    .feature { grid-template-columns: 1fr; gap: 4vh; margin-top: 6vh; }
    .feature.invertida .texto { order: 0; }
    .uso, .tira3 .uso, .uso.corta { --uso-alto: 70vh; }
    .tira3 { gap: 5vh; }
    .caja-tabla { padding: 4px 10px; }
    .cmp { font-size: 14px; }
    .cmp th, .cmp td { padding: 10px 8px; }
    .cmp th.col, .cmp td.col { width: 64px; }
    .cta { padding: 22px 20px; }
    .cierre h2 { font-size: 15vw; }
    /* en móvil, uno debajo del otro pero igual de grandes los dos */
    .contacto { grid-template-columns: 1fr; gap: 14px; }
    .contacto a { min-height: 74px; font-size: clamp(18px, 5.4vw, 26px); padding: 14px 18px; }
    .idioma { top: 10px; right: 10px; }
    .idioma .toggle { padding: 6px 10px 6px 8px; }
    .arriba { top: 10px; left: 10px; width: 44px; height: 44px; }   /* 44 px: el mínimo cómodo para el dedo */
}

/* ======================= MOVIMIENTO REDUCIDO ======================= */
@media (prefers-reduced-motion: reduce) {
    .pantalla { transition: none; }
    .latido b { animation: none; }
    .tabla-vivo td, .vivo-leyenda button, .idioma .caret, .arriba { transition: none; }
    .uso, .uso .marco img, .mosaico figure { transition: none; }
}

/* =====================================================================================
   [2026-09-11 23:42] LA PRESENTACIÓN QUE ABRE LA WEB (js/presentacion.js; PLAN-WEB.md, decisión 17)
   Integrada desde el prototipo G (bitácora depot/2026-09-11_2244_web-lavanda-splash-revolucion.md): un splash
   animado que se queda hasta pulsar «Cuéntame más» o «Repetir la introducción», con los cinco puntos fuertes
   (estadísticas, gestión en línea, gastos y rendimiento, consumo energético y fidelización); sin precios.
   · El guion lo marca js/presentacion.js añadiendo clases a .intro (a-antes, a-ruptura, a-marca, a-titulo,
     a-sub, a-p1…a-p5, a-final); aquí vive todo lo visual de cada momento.
   · Lo que se mueve, solo con transform y opacity: el Chrome de verificación va sin GPU y un filtro por
     fotograma cuesta ~80 ms (medido en la web: 11 fps → 61 fps al quitar un drop-shadow).
   · Sin JavaScript no hay presentación: html.intro-abierta la pone un script en el <head> de index.html.
   ===================================================================================== */
/* ---------- mientras está abierta: la web queda debajo, quieta y oculta ---------- */
html.intro-abierta { overflow: hidden; }
html.intro-abierta main > :not(.intro), html.intro-abierta .arriba { visibility: hidden; }

.intro {
    display: none; position: fixed; inset: 0; z-index: 3; overflow-x: hidden; overflow-y: auto; color: #fff;
    transition: opacity .9s var(--suave), transform 1.1s var(--suave);
}
html.intro-abierta .intro, .intro.intro--sale { display: block; }
.intro[hidden] { display: none !important; }
.intro:focus { outline: none; }
.intro.intro--sale { opacity: 0; transform: scale(1.06); pointer-events: none; }
/* al repetir: se vuelve al estado inicial en seco, sin ver las transiciones hacia atrás */
.intro.sin-transicion, .intro.sin-transicion *, .intro.sin-transicion *::before, .intro.sin-transicion *::after { transition: none !important; animation: none !important; }

/* ---------- 1 · lo de antes: gris, con las burbujas apagadas ---------- */
.intro__gris, .intro__destello { position: fixed; inset: 0; pointer-events: none; }
.intro__gris {
    background:
        radial-gradient(circle at 18% 72%, rgba(255,255,255,.06) 0 38px, transparent 39px),
        radial-gradient(circle at 80% 24%, rgba(255,255,255,.05) 0 58px, transparent 59px),
        radial-gradient(circle at 66% 82%, rgba(255,255,255,.04) 0 24px, transparent 25px),
        radial-gradient(circle at 30% 18%, rgba(255,255,255,.05) 0 18px, transparent 19px),
        radial-gradient(circle at 88% 64%, rgba(255,255,255,.035) 0 30px, transparent 31px),
        radial-gradient(120% 90% at 50% 42%, #4b5159 0%, #2b2f36 58%, #1a1d22 100%);
}
.intro__antes {
    position: fixed; left: 6vw; right: 6vw; top: 50%; transform: translateY(-50%); pointer-events: none;
    text-align: center; font-size: clamp(28px, 4vw, 64px); font-weight: 700; letter-spacing: -.02em; line-height: 1.12; color: #d3d8df;
}
.intro .pal { display: inline-block; }
/* [2026-09-11 23:36] Medido (diag-web-lavanda-presentacion-carga.js): a los 119 ms el titular y la frase gris se veían ENTEROS
   antes de que js/presentacion.js los partiera en palabras. Hasta que lo hace (clase .intro-lista), no se ven. */
.intro:not(.intro-lista) .intro__antes, .intro:not(.intro-lista) .intro__titulo { visibility: hidden; }
.intro__antes .pal { opacity: 0; transform: translateY(.45em); }
.a-antes .intro__antes .pal { opacity: 1; transform: none; transition: opacity .6s ease calc(var(--k) * 110ms), transform .8s var(--suave) calc(var(--k) * 110ms); }

/* ---------- 2 · la ruptura: destello, dos ondas, la frase vieja salta en pedazos y entra el azul ---------- */
.a-ruptura .intro__antes .pal {
    opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)) scale(1.25);
    transition: transform 1s cubic-bezier(.2,.7,.2,1), opacity .8s ease .1s;
}
.a-ruptura .intro__gris { opacity: 0; transition: opacity 1.1s ease .12s; }
.intro__destello { opacity: 0; background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.95) 0%, rgba(255,255,255,.35) 18%, rgba(255,255,255,0) 46%); }
.a-ruptura .intro__destello { animation: intro-destello 1s ease-out forwards; }
@keyframes intro-destello { 0% { opacity: 0; } 14% { opacity: .9; } 100% { opacity: 0; } }
.intro__onda {
    position: fixed; left: 50%; top: 50%; width: 170vmax; height: 170vmax; margin: -85vmax 0 0 -85vmax; pointer-events: none;
    border-radius: 50%; border: 3px solid rgba(255,255,255,.9); opacity: 0; transform: scale(.01);
}
.a-ruptura .intro__onda { animation: intro-onda 1.4s cubic-bezier(.12,.6,.25,1) forwards; }
.a-ruptura .intro__onda--2 { animation-delay: .2s; border-color: var(--amarillo); }
@keyframes intro-onda { 0% { opacity: 1; transform: scale(.01); } 100% { opacity: 0; transform: scale(1); } }
/* las burbujas que salen despedidas del centro: el mismo dibujo que las del fondo (tokens --burbuja-*) */
.intro__estallido { position: fixed; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; }
.intro__estallido span {
    position: absolute; left: 0; top: 0; width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2); border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, var(--burbuja-centro) 10%, var(--burbuja-medio) 70%, var(--burbuja-borde) 100%);
    box-shadow: inset 0 0 0 1.2px var(--burbuja-trazo); opacity: 0;
}
.a-ruptura .intro__estallido span { animation: intro-estalla 1.7s cubic-bezier(.15,.7,.2,1) var(--d) forwards; }
@keyframes intro-estalla { 0% { opacity: 0; transform: translate(0, 0) scale(.2); } 12% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--x), var(--y)) scale(1); } }

/* ---------- 3 · lo nuevo: marca, titular palabra a palabra, regla y subtítulo ---------- */
.intro__contenido {
    position: relative; min-height: 100%; max-width: 1560px; margin: 0 auto; padding: 84px var(--seccion-x) 44px;
    display: flex; flex-direction: column; justify-content: center;
}
.intro__marca { color: var(--amarillo); opacity: 0; transform: translateY(14px); letter-spacing: .7em; text-shadow: 0 1px 10px rgba(3,20,50,.4); }
.a-marca .intro__marca { opacity: 1; transform: none; letter-spacing: var(--kicker-espaciado); transition: opacity .8s ease, transform .9s var(--suave), letter-spacing 1.4s var(--suave); }
.intro__titulo { margin-top: 16px; max-width: 15em; font-size: clamp(38px, 5.3vw, 92px); font-weight: 800; line-height: 1; letter-spacing: -.03em; text-shadow: var(--sombra-titulo); }
.intro__titulo em { color: var(--amarillo); }
.intro__titulo .pal { opacity: 0; transform: translateY(.5em) scale(.96); }
.a-titulo .intro__titulo .pal { opacity: 1; transform: none; transition: opacity .7s ease calc(var(--k) * 85ms), transform .9s var(--suave) calc(var(--k) * 85ms); }
.intro .regla { transform: scaleX(0); transform-origin: left center; }
.a-sub .regla { transform: scaleX(1); transition: transform .9s var(--suave); }
.intro__sub { margin-top: 18px; max-width: 40em; font-size: var(--t-lead); line-height: 1.5; color: var(--claro); opacity: 0; transform: translateY(16px); text-shadow: 0 1px 12px rgba(3,20,50,.45); }
.a-sub .intro__sub { opacity: 1; transform: none; transition: opacity .8s ease .15s, transform .9s var(--suave) .15s; }

/* ---------- 4 · los cinco puntos fuertes, cada uno con su pantalla viva ---------- */
/* [2026-09-11 23:25] cinco columnas (antes cuatro): tarjetas algo más estrechas, con letra y rellenos a su medida */
.intro__pilares { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 16px; margin-top: 4.5vh; perspective: 1200px; }
.pilar {
    position: relative; overflow: hidden; padding: 10px 10px 16px; border-radius: var(--r-tarjeta);
    background: var(--fondo-tarjeta-oscura); border: 1px solid var(--borde-tarjeta-oscura); box-shadow: 0 24px 60px rgba(3,20,50,.28);
    opacity: 0; transform: translateY(46px) rotateX(18deg) scale(.96); transform-origin: 50% 100%;
}
.a-p1 .pilar:nth-child(1), .a-p2 .pilar:nth-child(2), .a-p3 .pilar:nth-child(3), .a-p4 .pilar:nth-child(4), .a-p5 .pilar:nth-child(5) { opacity: 1; transform: none; transition: opacity .7s ease, transform 1s var(--suave); }
/* un barrido de luz cruza la tarjeta al llegar */
.pilar::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.32) 50%, transparent 62%); transform: translateX(-130%); }
.a-p1 .pilar:nth-child(1)::after, .a-p2 .pilar:nth-child(2)::after, .a-p3 .pilar:nth-child(3)::after, .a-p4 .pilar:nth-child(4)::after, .a-p5 .pilar:nth-child(5)::after { animation: intro-barrido 1.2s var(--suave) .35s forwards; }
@keyframes intro-barrido { to { transform: translateX(130%); } }
.pilar h2 { margin-top: 14px; padding: 0 4px; font-size: clamp(17px, 1.25vw, 22px); line-height: 1.15; letter-spacing: -.01em; }
.pilar p { margin-top: 6px; padding: 0 4px; font-size: clamp(14px, 1vw, 16px); line-height: 1.42; color: var(--claro); }
.pilar__pantalla { position: relative; height: 132px; border-radius: 12px; background: var(--blanco); color: var(--tinta); overflow: hidden; }

/* 4.1 · estadísticas: la cifra que sube y unas barras apiladas que se reordenan solas */
.mini-estad { position: absolute; inset: 0; display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: end; padding: 14px 14px 12px; }
.mini-estad .cifra { align-self: center; font-size: clamp(32px, 2.6vw, 46px); font-weight: 800; line-height: 1; letter-spacing: -.03em; color: var(--azul-3); font-variant-numeric: tabular-nums; }
.mini-estad .cifra small { font-size: .55em; vertical-align: top; }
.mini-barras { display: flex; align-items: flex-end; gap: 5px; height: 100%; }
.mini-barras i { flex: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; transform: scaleY(0); transform-origin: 50% 100%; }
.mini-barras b { display: block; }
.mini-barras b:first-child { height: var(--a); background: var(--s2); border-radius: 3px 3px 0 0; }
.mini-barras b:last-child { height: var(--b); background: var(--l1); }
.a-p1 .mini-barras i { transform: scaleY(var(--e, 1)); transition: transform 1s var(--suave) calc(var(--k) * 60ms); }

/* 4.2 · gestión en línea: el panel en el navegador, con cada máquina y lo que le resta */
.mini-panel { position: absolute; inset: 0; display: flex; flex-direction: column; }
.mini-panel__barra {
    display: flex; align-items: center; gap: 5px; height: 22px; padding: 0 10px; background: var(--nube); border-bottom: 1px solid var(--marco-panel-borde);
    font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.mini-panel__barra > i { width: 7px; height: 7px; border-radius: 50%; background: #c9d6df; }
.mini-panel__barra .latido { margin-left: auto; gap: 5px; }
.mini-panel__barra .latido b { width: 6px; height: 6px; }
/* [2026-09-11 23:25] con cinco columnas la máquina va en vertical (anillo encima, nombre y minutos debajo): en fila no cabía */
.mini-maquinas { flex: 1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); align-content: center; gap: 5px 4px; padding: 6px 8px; }
.maq { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; opacity: 0; transform: scale(.6); }
.a-p2 .maq { opacity: 1; transform: none; transition: opacity .5s ease calc(var(--k) * 80ms + .3s), transform .7s var(--suave) calc(var(--k) * 80ms + .3s); }
.maq .anillo {
    flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
    background: conic-gradient(var(--c) calc(var(--p, 0) * 360deg), var(--nube) 0);
    -webkit-mask: radial-gradient(circle, transparent 5.5px, #000 6.5px); mask: radial-gradient(circle, transparent 5.5px, #000 6.5px);
}
.maq span { min-width: 0; font-size: 10px; line-height: 1.1; text-align: center; color: var(--tinta-3); white-space: nowrap; }
.maq b { display: block; font-size: 11px; color: var(--tinta); }
.maq small { display: block; font-size: 10px; font-variant-numeric: tabular-nums; }

/* 4.3 · gastos y rendimiento: lo cobrado, y de ahí luz, agua, producto y lo que queda */
.mini-margen { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; padding: 12px 14px; }
.mini-margen__cab { display: flex; justify-content: space-between; font-size: 12px; font-weight: 700; color: var(--tinta-3); }
.mini-margen__cab b { color: #12a37f; }
.pila { display: flex; height: 34px; margin-top: 8px; border-radius: 9px; overflow: hidden; background: var(--nube); }
.pila i { position: relative; overflow: hidden; width: 0; }
.a-p3 .pila i { width: var(--w); transition: width .9s var(--suave) calc(var(--k) * 180ms + .35s); }
.pila .luz { background: var(--oro); }
.pila .agua { background: var(--azul-1); }
.pila .producto { background: var(--azul-4); }
.pila .margen { background: #12a37f; }
.pila .margen::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.45) 50%, transparent 70%); transform: translateX(-100%); }
.a-final .pila .margen::after { animation: intro-brillo 2.8s ease-in-out infinite; }
@keyframes intro-brillo { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
.mini-margen__leyenda { display: flex; flex-wrap: wrap; gap: 3px 10px; margin-top: 9px; font-size: 11px; color: var(--tinta-2); }
.mini-margen__leyenda span::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; background: var(--c); }

/* 4.4 · consumo energético: la misma simulación que la caja «en directo» de la web, en pequeño */
.mini-consumo { position: absolute; inset: 0; }
.mini-consumo canvas { position: absolute; left: 0; right: 0; bottom: 4px; display: block; width: 100%; height: calc(100% - 38px); }
.mini-consumo__total { position: absolute; left: 14px; top: 9px; font-size: 22px; font-weight: 800; letter-spacing: -.01em; color: var(--azul-3); font-variant-numeric: tabular-nums; }
.mini-consumo__total small { margin-left: 6px; font-size: 12px; font-weight: 600; letter-spacing: 0; color: var(--tinta-3); }
.mini-consumo > .latido { position: absolute; right: 12px; top: 15px; }

/* 4.5 · [2026-09-11 23:25] fidelización: la tarjeta del club entra girando y los tramos del descuento se encienden uno
   tras otro, en bucle (el descuento crece por tramos con el gasto: sección PRO de index.html, clave pro.socio.v1). Sin cifras. */
.mini-club { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 14px; padding: 10px 14px; }
.mini-club__tarjeta {
    position: relative; flex: 0 0 auto; width: 96px; aspect-ratio: 85.6 / 54; padding: 7px 8px; border-radius: 8px; color: #fff;
    background: linear-gradient(135deg, var(--azul-1), var(--azul-3) 55%, var(--azul-4)); box-shadow: 0 6px 16px rgba(3,20,50,.28);
    opacity: 0; transform: translateY(12px) rotate(-14deg) scale(.8);
}
.a-p5 .mini-club__tarjeta { opacity: 1; transform: rotate(-6deg); transition: opacity .6s ease .3s, transform 1s var(--suave) .3s; }
.mini-club__tarjeta b { display: block; font-size: 9px; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
.mini-club__tarjeta i { position: absolute; left: 8px; bottom: 8px; width: 18px; height: 13px; border-radius: 3px; background: var(--amarillo); }
.mini-club__tramos { flex: 1; max-width: 90px; height: 70%; display: flex; align-items: flex-end; gap: 5px; }
.mini-club__tramos i { position: relative; flex: 1; height: var(--h); overflow: hidden; border-radius: 4px 4px 0 0; background: var(--nube); }
.mini-club__tramos i::after { content: ''; position: absolute; inset: 0; background: var(--oro); transform: scaleY(0); transform-origin: 50% 100%; }
.a-p5 .mini-club__tramos i::after { animation: intro-tramo 3.2s var(--suave) calc(var(--k) * 350ms + .6s) infinite; }
@keyframes intro-tramo { 0% { transform: scaleY(0); } 22%, 80% { transform: scaleY(1); } 100% { transform: scaleY(0); } }

/* ---------- 5 · el lema y los dos botones ---------- */
.intro__final { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px 32px; margin-top: 4.5vh; opacity: 0; transform: translateY(20px); visibility: hidden; }
.a-final .intro__final { opacity: 1; transform: none; visibility: visible; transition: opacity .8s ease, transform .9s var(--suave); }
/* [2026-09-11 23:57] Medido (verify-web-lavanda-presentacion.js, 1024×768): la presentación mide 889 px y los botones quedaban
   en 861-881 px, fuera de la pantalla. Cuando no cabe (clase .intro--desborda, que pone js/presentacion.js), el lema y los
   botones se quedan pegados abajo sobre un velo del azul del fondo; cuando cabe, no cambia nada. */
.intro--desborda .intro__final {
    position: sticky; bottom: 0; z-index: 2; margin-left: calc(-1 * var(--seccion-x)); margin-right: calc(-1 * var(--seccion-x));
    padding: 22px var(--seccion-x) 16px; background: linear-gradient(to top, var(--azul-4) 62%, transparent);
}
/* [2026-09-12 08:35, petición del usuario: «quiero que el scroll de las viñetas se haga solamente en el
   recuadro rojo, no hay que mover la parte superior ni la inferior»] Cuando la presentación no cabe, el
   que se desplaza es el BLOQUE DE LAS VIÑETAS, no la capa entera: la marca, el titular, el subtítulo y
   los botones se quedan donde están y las viñetas recorren su propia zona, que ocupa lo que sobra.
   `min-height: 0` es lo que permite a un hijo de flex encogerse por debajo de su contenido; sin él, la
   zona crecería hasta su alto natural y volvería a empujar los botones fuera de la pantalla.
   `overscroll-behavior: contain` evita que, al llegar al final, el gesto arrastre la página de debajo. */
/* [2026-09-12 09:50, hallazgo del gate que he confirmado midiendo] El scroll DENTRO de la zona solo se
   activa si la pantalla es lo bastante alta. Medido sin esta condición: en 640×360 (móvil girado) la zona
   quedaba en 2 px y en 1280×600 (portátil con barra de marcadores) en 144 px con viñetas de 253 → NI UNA
   entera, y encima el aviso la dejaba al fondo. Por debajo de 560 px de alto se vuelve al comportamiento de
   siempre: la capa entera se desplaza y las cinco se ven completas. El `min-height` remata lo mismo por
   arriba: la zona nunca es más baja que una viñeta (más lo que asoma de la siguiente); si no cabe, quien
   desborda es la capa, que para eso tiene su propio scroll. */
@media (min-height: 560px) {
.intro--desborda .intro__contenido { height: 100%; justify-content: flex-start; }
.intro--desborda .intro__pilares {
    /* [2026-09-12 10:00] `min-height` explícito y NO `0`: un valor propio ya permite al ítem de flex
       encogerse por debajo de su contenido (que es para lo que estaba el 0), y además pone el suelo. Con
       `min-height: 0` detrás, el mínimo no servía de nada: ganaba la última declaración y la zona volvía a
       quedarse en 144 px con viñetas de 253 (medido en 1280×600). */
    flex: 1 1 auto; min-height: 280px; overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: none; padding-bottom: 2px;
    /* [2026-09-12 08:50, el usuario: «las viñetas se tienen que mostrar ENTERAS y el scroll se tiene que
       seguir haciendo»] Las dos líneas de abajo son las que lo consiguen, y hacen falta las dos:
        · `align-content: start` para que las filas no se estiren ni se repartan la caja;
        · `grid-auto-rows: max-content` para que ninguna se ENCOJA. Medido en 360×640: sin esto las cinco
          viñetas se aplastaban a 37 px cada una (su pantallita, de 68 px, se salía por debajo) y
          scrollHeight == clientHeight, o sea ni viñetas enteras ni nada que desplazar. El motivo es que
          `.pilar` lleva `overflow: hidden` (web.css, «los cinco puntos fuertes»), y en una rejilla eso
          anula la altura mínima automática del ítem: puede encogerse hasta cero. */
    align-content: start; grid-auto-rows: max-content;
}
.intro--desborda .intro__pilares::-webkit-scrollbar { width: 0; height: 0; }
}
.intro__lema.latido { gap: 14px; font-size: clamp(22px, 2vw, 32px); font-weight: 800; letter-spacing: -.01em; color: #fff; text-shadow: var(--sombra-titulo); }
.intro__lema.latido b { width: 14px; height: 14px; }
.intro__botones { display: flex; flex-wrap: wrap; gap: 14px; }
.intro__boton {
    position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 58px; padding: 14px 28px;
    border-radius: var(--r-pill); font-size: 18px; font-weight: 800; letter-spacing: -.005em; cursor: pointer; transition: transform .2s var(--suave), background-color .2s;
}
.intro__boton svg { width: 20px; height: 20px; flex: 0 0 auto; }
.intro__boton:hover { transform: translateY(-2px); }
.intro__boton:active { transform: none; }
.intro__mas { background: var(--amarillo); color: var(--tinta); border: 0; box-shadow: var(--sombra-tarjeta); }
/* un aura que late alrededor de «Cuéntame más» y la flecha que empuja hacia delante */
.intro__mas::before { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 3px var(--amarillo); opacity: 0; pointer-events: none; }
.a-final .intro__mas::before { animation: intro-aura 2.2s ease-out 1s infinite; }
@keyframes intro-aura { 0% { opacity: .8; transform: scale(1); } 100% { opacity: 0; transform: scale(1.12, 1.45); } }
.a-final .intro__mas svg { animation: intro-empuja 1.6s ease-in-out 1s infinite; }
@keyframes intro-empuja { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(4px); } }
.intro__repetir { background: rgba(255,255,255,.08); color: #fff; border: 1.5px solid rgba(255,255,255,.6); }
.intro__repetir:hover { background: rgba(255,255,255,.18); }

/* ---------- anchos y altos ---------- */
/* [2026-09-11 23:25] con cinco tarjetas, tres columnas en anchos intermedios (antes dos, con cuatro) */
@media (min-width: 821px) and (max-width: 1100px) {
    .intro__pilares { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* [2026-09-11 23:46, gate] Entre 1101 y 1280 px las cinco tarjetas miden unos 180 px: a la tarjeta del club le quedaban
   ~2 px por tramo, las barras de estadísticas ~4 px y la leyenda de gastos no cabía en 108 px de alto (cálculo; se mide con
   el verificador a 1180×800). Tarjeta más pequeña, cinco barras y sin leyenda (la cabecera ya dice cobrado y margen). */
@media (min-width: 1101px) and (max-width: 1280px) {
    .mini-club { gap: 10px; padding: 10px; }
    .mini-club__tarjeta { width: 70px; padding: 5px 6px; }
    .mini-club__tarjeta b { font-size: 7px; }
    .mini-club__tarjeta i { left: 6px; bottom: 6px; width: 14px; height: 10px; }
    .mini-barras i:nth-child(n+6) { display: none; }
    .mini-margen__leyenda { display: none; }
}
@media (min-width: 821px) and (max-height: 820px) {
    .intro__contenido { padding-top: 70px; padding-bottom: 28px; }
    .intro__titulo { font-size: clamp(36px, 4.4vw, 68px); }
    .intro__sub { margin-top: 12px; font-size: 17px; }
    .intro__pilares { margin-top: 3vh; }
    .pilar__pantalla { height: 108px; }
    .pilar h2 { margin-top: 12px; font-size: 18px; }
    .pilar p { font-size: 13.5px; }
    .mini-panel__barra, .mini-margen__cab { display: none; }   /* [2026-09-11 23:25] a 108 px de alto no caben con cinco columnas */
    .intro__final { margin-top: 3vh; }
}
/* [2026-09-12 00:11, gate nº 3] Entre 1101 y 1280 px la leyenda de gastos está oculta; si además la pantalla es baja, el bloque
   de arriba quitaba también la cabecera y la pantallita se quedaba sin rótulos. Ahí vuelve la cabecera (cabe: 80 px de 108). */
@media (min-width: 1101px) and (max-width: 1280px) and (max-height: 820px) {
    .mini-margen__cab { display: flex; }
}
/* [2026-09-11 23:25] móvil más compacto: con el quinto punto fuerte la presentación sigue cabiendo en 390×860 */
@media (max-width: 820px) {
    .intro__contenido { justify-content: flex-start; padding: 62px var(--seccion-x) 16px; }
    .intro__antes { font-size: clamp(26px, 8vw, 38px); }
    .intro__titulo { margin-top: 8px; font-size: clamp(28px, 7.8vw, 44px); }
    .intro .regla { margin-top: 10px; }
    .intro__sub { margin-top: 10px; font-size: 14px; line-height: 1.45; }
    /* [2026-09-12 12:40, petición del usuario: «en los móviles hay que darle demasiado al dedo»] La escena
       de la compra pide la MITAD de scroll en móvil. Medido antes: 8,1 pantallas de alto eran 856 px por
       capítulo en 390×844 —unos QUINCE deslizamientos de dedo para los siete—; con 4,2 pantallas queda en
       torno a un deslizamiento por capítulo. En un ratón, con la rueda, ese recorrido largo no molestaba;
       en un dedo, sí. */
    .escenario { height: 420vh; }
    .intro__pilares { grid-template-columns: 1fr; gap: 8px; margin-top: 14px; }
    /* [2026-09-12 09:30, petición del usuario] Sin la sombra de las tarjetas. Demostrado con una prueba
       A/B en navegador (capturas «recuadro-1-con-sombra» / «recuadro-2-sin-sombra»): el azul oscuro que se
       veía recortado justo en el área de las viñetas NO era ningún fondo —los contenedores son
       transparentes—, eran las CINCO sombras (`0 24px 60px rgba(3,20,50,.28)`) sumándose: apiladas y
       pegadas en móvil, sus 60 px de difuminado tiñen todo el recuadro y tapan las burbujas. En columnas
       (escritorio) van separadas y no forman mancha, así que allí se conservan. Las tarjetas siguen
       distinguiéndose por su fondo claro y su borde. */
    .pilar { display: grid; grid-template-columns: 108px minmax(0, 1fr); column-gap: 10px; align-items: center; padding: 7px; box-shadow: none; }
    /* [2026-09-12 09:50] apiladas miden ~85 px: el mínimo de la zona son dos y lo que asoma de la tercera */
    .intro--desborda .intro__pilares { min-height: 190px; }
    .pilar__pantalla { grid-row: 1 / span 2; height: 68px; border-radius: 10px; }
    .pilar h2 { align-self: end; margin-top: 0; padding: 0; font-size: 16px; }
    .pilar p { align-self: start; margin-top: 2px; padding: 0; font-size: 12.5px; line-height: 1.3; }
    .mini-estad { gap: 6px; padding: 7px 8px 5px; }
    .mini-estad .cifra { font-size: 22px; }
    .mini-barras { gap: 3px; }
    .mini-barras i:nth-child(n+6) { display: none; }
    .mini-panel__barra { display: none; }
    .mini-maquinas { gap: 2px; padding: 4px 6px; }
    .maq { gap: 0; }
    .maq .anillo { width: 16px; height: 16px; -webkit-mask: radial-gradient(circle, transparent 4px, #000 5px); mask: radial-gradient(circle, transparent 4px, #000 5px); }
    .maq b { font-size: 10px; }
    .maq small { display: none; }
    .mini-margen { padding: 8px; }
    .mini-margen__cab, .mini-margen__leyenda { display: none; }
    .pila { height: 24px; margin-top: 0; }
    .mini-consumo__total { left: 8px; top: 5px; font-size: 14px; }
    .mini-consumo__total small, .mini-consumo > .latido { display: none; }
    .mini-consumo canvas { height: calc(100% - 24px); }
    .mini-club { gap: 8px; padding: 6px 8px; }
    .mini-club__tarjeta { width: 52px; padding: 4px; border-radius: 5px; }
    .mini-club__tarjeta b { display: none; }
    .mini-club__tarjeta i { left: 5px; bottom: 5px; width: 10px; height: 7px; border-radius: 2px; }
    .mini-club__tramos { max-width: 38px; gap: 3px; }
    .intro__final { gap: 10px; margin-top: 14px; }
    .intro__lema.latido { gap: 10px; font-size: 18px; }
    .intro__lema.latido b { width: 11px; height: 11px; }
    .intro__botones { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }
    .intro__boton { min-height: 48px; padding: 10px; font-size: 15px; }
}

/* ---------- movimiento reducido: el estado final, sin la ruptura ni transiciones ---------- */
@media (prefers-reduced-motion: reduce) {
    .intro__gris, .intro__destello, .intro__onda, .intro__estallido, .intro__antes { display: none; }
    .intro, .intro *, .intro *::before, .intro *::after { transition: none !important; animation: none !important; }
}
