/* Estilos globales de Univai — extraídos de base.html (2026-07-13).
 * Vivían INLINE: viajaban en CADA página (10.6 KB) y el navegador NO los podía cachear
 * (los re-bajaba y re-parseaba en cada navegación). Como archivo, WhiteNoise los versiona
 * por contenido → el navegador los guarda para SIEMPRE y solo los pide cuando cambian. */
:root {
            /* B&W neutral scale — 0 tono crema. Texturas/formas hacen el carácter. */
            --bg: #fafafa;          /* off-white global */
            --surface: #ffffff;     /* pure white cards/inputs */
            --surface-soft: #f5f5f5;/* gray-100 — hover / nested */
            --border: #e5e5e5;      /* gray-200 — borders neutrales */
            --text: #0a0a0a;        /* near-black — contraste máximo */
            --muted: #737373;       /* gray-500 — copy secundario */
            --muted-strong: #525252;/* gray-600 — copy con peso */
            --accent: #0a0a0a;      /* same as text — el "color" es la ausencia */
            --accent-hover: #2c2c2c;/* hover de botones/links accent (negro un punto más claro) */
            --danger: #b00020;      /* ÚNICA excepción de color: errores/riesgo (regla: color = riesgo) */
            /* Paleta de DATA-VIZ (founder 2026-06-28): 1 tono por serie, usado en la BARRA *y* en su
               CANTIDAD → el ojo liga el número con su barra. Grayscale llamativo: negro pleno vs gris
               sólido (no lavado). 'in' = ingresos/emitido/cobrado · 'out' = egresos/recibido/pagado. */
            /* EXPERIMENTO founder 2026-06-28: POSITIVO/ingreso = VERDE (contrasta sobre blanco, donde
               un negro o gris no resaltan), NEGATIVO/egreso = NEGRO (alto contraste). Aplica a números
               Y barras (numbers match chart). Si el founder prefiere el grayscale, revertir a #0a0a0a / #8a8a8a. */
            --data-in: #0a7d3c;          /* positivo/ingreso = verde */
            --data-in-soft: #0e9a48;     /* degradado de la barra verde */
            --data-out: #0a0a0a;         /* egreso/negativo en BARRAS = negro */
            --data-out-soft: #3a3a3a;    /* degradado de la barra negra */
            --data-out-strong: #0a0a0a;  /* número negativo = negro (lo que al founder le gustó: máximo contraste) */

            /* ══ LOS CUATRO EJES QUE FALTABAN (2026-08-09, orden del founder: «efecto Apple») ══
               El color ya estaba resuelto arriba. Lo que hacía que la app se sintiera "web" y no
               "nativa" eran los otros cuatro, y ninguno necesita un framework: React y Django
               entregan el MISMO HTML+CSS al navegador. Lo que se ve es esto. */

            /* 1 · ESPACIO — rejilla de 4, y el censo la respalda (medido 2026-08-09).
               El barrido afirmó que esta escala estaba «desfasada +2px de la que la app ya usa».
               Se comprobó contando las 1,937 declaraciones de padding/margin/gap, y NO se sostiene:
                   10px×192 · 8px×192 · 12px×184 · 16px×170 · 14px×163 · 6px×126 · 4px×116 · 18px×115
               No hay una escala desplazada: hay DOS ENTRELAZADAS —la de 4 y la de 2— y por eso el
               ojo lee desorden. Cobertura de esta escala 36%, de la otra 33%: ninguna manda.
               Se conserva la de 4 porque es la mayor agrupación y porque un solo paso (4) es más
               fácil de sostener que dos. La migración de los 6/10/14/18 es progresiva: se
               convierte lo que se toca, no se hace un `sed` de 1,200 sitios a ciegas.
               🔑 Y la lección para mí: el agente lo dijo con seguridad y estaba a medias. Medir
               antes de obedecer vale igual para un humano que para un subagente. */
            --e1: 4px;   --e2: 8px;   --e3: 12px;  --e4: 16px;
            --e5: 24px;  --e6: 32px;  --e7: 48px;  --e8: 64px;

            /* 2 · TIPOGRAFÍA — MEDIDA, no inventada (corregido 2026-08-09 el mismo día).
               🪤 La primera versión decía 12 / 13.5 / 15 y la escribí de memoria. El barrido de UI
               lo puso en duda y el censo lo confirmó: **el 13.5 no existe en el código**. Lo que
               la app usa de verdad, contando las 837 declaraciones de `font-size`:
                   13px×162 · 12px×144 · 11px×112 · 14px×103 · 28px×25 · 24px×11
               Imponer 13.5 habría obligado a tocar 400 sitios para llegar a un número que me
               inventé. La escala describe lo que hay y lo ORDENA; no lo sustituye por gusto.
               Cuerpo: 11 (mínimo legible, rótulos) · 12 · 13 (el dominante) · 14.
               Despliegue: 20 · 28 · 40. */
            --t-2xs: 11px; --t-xs: 12px; --t-sm: 13px; --t-md: 14px;
            --t-lg: 20px; --t-xl: 28px;   --t-2xl: 40px;
            /* Piso DISPLAY (F1 del rework, 2026-08-23): la dirección editorial del founder
               (tipografía como arquitectura) necesita cuerpos que 40px no alcanza. Dos y solo
               dos, para titulares-cartel y el dato-héroe. Añadidos también a TIPO_OK del gate
               `check_escala_visual` — a la escala se entra por la puerta, no de contrabando. */
            --t-3xl: 56px; --t-4xl: 88px;
            --tracking-tight: -0.02em;   /* los números y titulares grandes respiran mejor apretados */

            /* 3 · RADIOS — tres, y el de píldora. Mezclar radios distintos en la misma pantalla es
               de lo que más delata a una interfaz sin sistema. */
            --r-sm: 8px; --r-md: 12px; --r-lg: 18px; --r-full: 999px;

            /* 4 · MOVIMIENTO — el eje que estaba en CERO, y el que más "sofisticación" da por peso.
               Un panel que aparece de golpe se siente web; uno que entra en 180ms desacelerando se
               siente nativo. La curva es la de las hojas de iOS: sale rápido y FRENA largo, que es
               lo que el ojo lee como "físico" en vez de "programado". */
            --ease: cubic-bezier(0.32, 0.72, 0, 1);
            --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
            --dur-1: 120ms;   /* microestados: hover, focus */
            --dur-2: 180ms;   /* aparecer/desaparecer */
            --dur-3: 260ms;   /* mover algo grande */

            /* 5 · ELEVACIÓN — sombras en capas, no bordes. Separar con SOMBRA y ESPACIO en vez de
               con línea es la diferencia más grande entre "formulario" y "producto caro". */
            --sombra-1: 0 1px 2px rgba(10,10,10,.05), 0 1px 1px rgba(10,10,10,.03);
            --sombra-2: 0 2px 4px rgba(10,10,10,.05), 0 4px 12px rgba(10,10,10,.05);
            --sombra-3: 0 8px 24px rgba(10,10,10,.09), 0 2px 6px rgba(10,10,10,.05);

            /* ── EL VIDRIO (ley nº1 del founder: «glass SOLO en lo interactuable») ──────────
               Sale de `.pricing-cta`, que es la receta aprobada y en producción desde el
               27-ago. Aquí se tokeniza por una razón concreta: allí son rgba() cableados y un
               rgba() no se entera del tema — el mismo vidrio sobre tinta se vuelve una mancha
               lechosa. Con token, el oscuro trae el suyo y las cinco familias lo heredan. */
            --vidrio: linear-gradient(165deg, rgba(255,255,255,.95), rgba(255,255,255,.45) 40%, rgba(10,10,10,.05));
            --vidrio-borde: rgba(10,10,10,.20);
            --vidrio-luz: rgba(255,255,255,.95);
            --vidrio-sombra: inset 0 1px 0 rgba(255,255,255,.95), inset 0 -1px 0 rgba(10,10,10,.06),
                             0 1px 2px rgba(10,10,10,.10), 0 8px 16px rgba(10,10,10,.12);
            /* el invertido: mismo material, contraste opuesto — tinta donde el otro es luz */
            --vidrio-inv: linear-gradient(165deg, rgba(10,10,10,.92), rgba(10,10,10,.72) 40%, rgba(10,10,10,.88));
            --vidrio-inv-borde: rgba(10,10,10,.55);
            --vidrio-inv-texto: #fafafa;
            /* 16-sep (founder): «el desplegable transparenta y choca con el monto de atrás; que no transparente tanto sin
               perder el liquid glass». Los PANELES que flotan sobre contenido (listas desplegables, el selector de
               periodo) llevan un vidrio más denso que los botones: casi opaco, con más desenfoque detrás. */
            --vidrio-panel: linear-gradient(165deg, rgba(255,255,255,.97), rgba(255,255,255,.90) 45%, rgba(246,246,246,.94));
            --vidrio-panel-blur: blur(24px) saturate(1.3);

            /* Los controles nativos (inputs, scrollbars) siguen al tema. */
            color-scheme: light;
        }

        /* ══ EL TEMA OSCURO (F0 del rework, 2026-08-23) — decisión del founder: claro Y oscuro
           de primera clase («es algo que sí me pidieron»). Pares elegidos A MANO en la tarjeta
           «Temas» del sistema de diseño, no invertidos: el verde SUBE de luz para contrastar
           sobre tinta, el rojo también, y el «negro de la casa» se convierte en el claro.

           ⚠️ SE ACTIVA SOLO CON `data-theme="dark"` EXPLÍCITO — a propósito NO hay
           `@media (prefers-color-scheme: dark)` todavía. El censo del rework
           (docs/REWORK_UI_MAPA.md) contó 67 hex literales vivos en las plantillas: activar el
           oscuro en automático HOY le serviría a todo usuario con sistema oscuro una app a
           medio teñir (lo tokenizado se voltea, lo hex no). El automático llega al FINAL del
           rework, cuando ese censo dé cero — y `tests_tokens_bilingues` vigila que nadie lo
           adelante sin decidirlo.

           El selector es `[data-theme="dark"]` a CUALQUIER profundidad, no solo :root: una
           sección puede optar al oscuro localmente (la banda negra editorial de la landing es
           exactamente eso) porque las custom properties cascadean desde donde se declaran. */
        [data-theme="dark"] {
            --bg: #101012;
            --surface: #1a1b1d;
            --surface-soft: #232427;
            --border: #2a2b2e;
            --text: #f2f2f0;
            --muted: #8b8d90;
            --muted-strong: #b5b7ba;
            --accent: #f2f2f0;          /* el «color» sigue siendo la ausencia — ahora clara */
            --accent-hover: #d8d8d6;
            --danger: #e5484d;          /* sube de luz: #b00020 desaparece sobre tinta */
            --data-in: #34c86b;
            --data-in-soft: #23c55e;
            --data-out: #f2f2f0;        /* egreso = tinta, y de noche la tinta es clara */
            --data-out-soft: #b5b7ba;
            --data-out-strong: #f2f2f0;
            /* Sobre tinta una sombra clara no existe: se oscurece el ambiente, no el objeto. */
            --sombra-1: 0 1px 2px rgba(0,0,0,.35), 0 1px 1px rgba(0,0,0,.25);
            --sombra-2: 0 2px 4px rgba(0,0,0,.35), 0 4px 12px rgba(0,0,0,.30);
            --sombra-3: 0 8px 24px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.30);

            /* De noche el vidrio no puede ser blanco translúcido: sobre tinta eso es niebla.
               Es tinta clara MUY tenue, con la luz en el borde superior — el mismo material
               leído al revés, que es lo que hace que se reconozca como el mismo botón. */
            --vidrio: linear-gradient(165deg, rgba(255,255,255,.14), rgba(255,255,255,.06) 40%, rgba(0,0,0,.20));
            --vidrio-borde: rgba(255,255,255,.18);
            --vidrio-luz: rgba(255,255,255,.22);
            --vidrio-sombra: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 0 rgba(0,0,0,.30),
                             0 1px 2px rgba(0,0,0,.35), 0 8px 16px rgba(0,0,0,.40);
            --vidrio-inv: linear-gradient(165deg, rgba(242,242,240,.96), rgba(242,242,240,.86) 40%, rgba(242,242,240,.94));
            --vidrio-inv-borde: rgba(242,242,240,.70);
            --vidrio-inv-texto: #101012;
            --vidrio-panel: linear-gradient(165deg, rgba(44,45,48,.97), rgba(30,31,34,.94) 45%, rgba(24,25,28,.96));
            --vidrio-panel-blur: blur(24px) saturate(1.3);
            color-scheme: dark;
        }

        /* ── EL MOVIMIENTO, APLICADO ─────────────────────────────────────────────────────────
           Todo lo que un dedo puede tocar transiciona. No es decoración: un cambio instantáneo no
           da tiempo al ojo a ligar causa y efecto, y esa desconexión es lo que se siente "barato".
           Se enumeran las propiedades a propósito — `transition: all` obliga al navegador a vigilar
           TODAS y provoca saltos cuando algo cambia de layout. */
        a, button, .btn, [role="button"], summary, input, select, textarea,
        .card, .chip, .tab, tr[data-href], label {
            transition: background-color var(--dur-1) var(--ease),
                        border-color var(--dur-1) var(--ease),
                        color var(--dur-1) var(--ease),
                        box-shadow var(--dur-2) var(--ease),
                        transform var(--dur-1) var(--ease),
                        opacity var(--dur-2) var(--ease);
        }

        /* QUIEN PIDE QUIETUD, QUIETUD. No es un detalle de accesibilidad opcional: hay gente a la
           que el movimiento le provoca mareo, y el sistema operativo ya lo dice por ella. */
        @media (prefers-reduced-motion: reduce) {
            *, *::before, *::after {
                animation-duration: 0.01ms !important;
                transition-duration: 0.01ms !important;
                /* 🩸 FALTABA ESTA LÍNEA Y LA PROMESA ERA FALSA (31-ago). Con solo la duración a
                   0.01ms, una animación `infinite` no se detiene: da MILES DE VUELTAS POR SEGUNDO.
                   Lo destapó la regresión visual al intentar retratar la landing por primera vez:
                   no se quedaba quieta, y el culpable era `lp-deriva 60s infinite alternate`
                   —el «$0.00» gigante del pie— cumpliendo la regla al pie de la letra.
                   🔑 Poner una duración a cero no PARA un bucle: lo acelera. Quien pide quietud
                      pide que TERMINE, y eso lo dice `animation-iteration-count`. */
                animation-iteration-count: 1 !important;
            }
        }

        /* Sane default: inputs/textareas/buttons no se desbordan de su contenedor.
           Aplica a TODOS los templates que extienden base.html (login, signup, panel, etc). */
        *, *::before, *::after { box-sizing: border-box; }

        body {
            font-family: "Inter", sans-serif;
            background: var(--bg);
            color: var(--text);
            display: flex;
            flex-direction: column;
            min-height: 100vh;
            margin: 0;
        }

        /* ── BUTTONS unificados — una sola "voz" para todos los class names legacy.
           v2 brutalista (2026-08-23): filo vivo, sin sombra, sin flotar. El hover del primario
           usa --accent-hover; el del fantasma es un cambio de superficie plano. Token-puro:
           el tema oscuro de F0 los voltea sin tocar nada. */
        a.btn, button.btn, a.btn-primary, button.btn-primary, a.btn-outline, button.btn-outline,
        a.primary-button, button.primary-button, a.ghost-button, button.ghost-button,
        a.cta-primary, button.cta-primary, a.cta-secondary, button.cta-secondary,
        .btn, .btn-primary, .btn-outline, .btn-ghost,
        .primary-button, .ghost-button, .cta-primary, .cta-secondary {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 13px 22px;
            border-radius: 0;
            font-size: 14px;
            font-weight: 700;
            text-decoration: none;
            white-space: nowrap;
            border: 1px solid;
            cursor: pointer;
            font-family: inherit;
            line-height: 1.2;
            transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
        }
        /* PRIMARY — tinta plena */
        a.btn-primary, button.btn-primary, a.primary-button, button.primary-button, a.cta-primary, button.cta-primary,
        .btn-primary, .primary-button, .cta-primary {
            background-color: var(--accent);
            color: var(--bg);
            border-color: var(--accent);
        }
        a.btn-primary:hover, button.btn-primary:hover, a.primary-button:hover, button.primary-button:hover,
        a.cta-primary:hover, button.cta-primary:hover,
        .btn-primary:hover, .primary-button:hover, .cta-primary:hover {
            background-color: var(--accent-hover);
            color: var(--bg);
            border-color: var(--accent-hover);
            text-decoration: none;
        }
        /* GHOST/OUTLINE — papel con borde */
        a.btn, button.btn, a.btn-outline, button.btn-outline, a.btn-ghost, button.btn-ghost,
        a.ghost-button, button.ghost-button, a.cta-secondary, button.cta-secondary,
        .btn:not(.btn-primary), .btn-outline, .btn-ghost, .ghost-button, .cta-secondary {
            background-color: var(--surface);
            color: var(--text);
            border-color: var(--border);
        }
        a.btn:hover, button.btn:hover, a.btn-outline:hover, button.btn-outline:hover, a.btn-ghost:hover, button.btn-ghost:hover,
        a.ghost-button:hover, button.ghost-button:hover, a.cta-secondary:hover, button.cta-secondary:hover,
        .btn:not(.btn-primary):hover, .btn-outline:hover, .btn-ghost:hover, .ghost-button:hover, .cta-secondary:hover {
            background-color: var(--surface-soft);
            color: var(--text);
            border-color: var(--text);
            text-decoration: none;
        }

        .container {
            flex: 1;
            width: min(1120px, calc(100% - 32px));
            margin: 0 auto;
            padding: 40px 0;
        }

        /* ── EL MASTHEAD DE IMPRENTA (v2 brutalista del rework, 2026-08-23) ──
           Orden del founder: fuera el rectángulo flotante (negro translúcido, radio 18,
           sombra, blur). Queda una cabecera de periódico: papel, UNA línea de tinta abajo,
           wordmark tipográfico y acciones en mono mayúsculas. Va EN FLUJO (no fija): el
           masthead se va con el scroll, y así su alto variable en móvil no obliga a ningún
           padding-top mágico en .container. Token-puro: se voltea solo con el tema de F0. */
        @font-face {
            font-family: "Archivo";
            font-style: normal;
            font-weight: 100 900;
            font-stretch: 62% 125%;
            font-display: swap;
            src: url("../fonts/archivo-latin.de2f1fe81758.woff2") format("woff2");
        }
        @font-face {
            font-family: "Plex Mono";
            font-style: normal;
            font-weight: 500;
            font-display: swap;
            src: url("../fonts/plexmono-latin.b1c8a895f5fd.woff2") format("woff2");
        }

        .site-header {
            background: var(--bg);
            border-bottom: 1px solid var(--text);
            padding: 0 16px;
        }

        .site-nav {
            width: min(1120px, calc(100% - 32px));
            margin: 0 auto;
            padding: 16px 0;
            display: grid;
            grid-template-columns: 1fr auto 1fr;
            align-items: center;
            gap: 16px;
        }

        .site-brand {
            justify-self: start;
            font-family: "Archivo", "Inter", sans-serif;
            font-variation-settings: 'wdth' 116;
            font-size: 20px;
            font-weight: 800;
            letter-spacing: -0.02em;
            text-transform: uppercase;
            color: var(--text);
            text-decoration: none;
        }

        .site-brand:hover,
        .site-brand:focus,
        .site-brand:active,
        .site-brand:visited {
            color: var(--text);
            text-decoration: none;
        }

        .site-links,
        .site-actions {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .site-links { justify-self: center; justify-content: center; }
        .site-actions { justify-self: end; justify-content: flex-end; }

        .site-link,
        .site-button,
        .site-button-muted,
        .site-user {
            font-family: "Plex Mono", ui-monospace, monospace;
            font-size: 12px;
            font-weight: 500;
            letter-spacing: 0.08em;
            text-transform: uppercase;
            white-space: nowrap;
        }

        .site-link {
            color: var(--text);
            text-decoration: none;
            border-bottom: 2px solid transparent;
            padding-bottom: 2px;
        }

        .site-link:hover {
            border-bottom-color: var(--text);
            text-decoration: none;
        }

        .site-button,
        .site-button-muted {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 8px 14px;
            border-radius: 0;
            text-decoration: none;
        }

        .site-button {
            border: 1px solid var(--accent);
            background: var(--accent);
            color: var(--bg);
        }

        /* 🩸 EL HOVER ESTABA MUERTO, y era el ÚNICO botón público así. MEDIDO en píxeles el
           31-ago pasando el ratón en Chromium: «CREAR CUENTA» cambiaba **0.00%** de sus píxeles
           mientras sus hermanos cambiaban 91-92%. Y es el botón que convierte visitante en
           cuenta, presente en las TRES pantallas públicas.
           La causa se ve sola: `:hover` estaba agrupado con `:visited`, y `:visited` necesita
           los colores de REPOSO (si no, el enlace se pinta morado). Al compartir bloque, el
           reposo ganó y el hover dejó de existir. `.site-button-muted`, cinco líneas más abajo,
           los separa bien — y por eso el suyo sí funciona.
           🔑 Agrupar `:hover` con `:visited` no es un atajo: es apagar el hover, porque los dos
              quieren cosas opuestas. */
        .site-button:hover,
        .site-button:active {
            background: transparent;
            color: var(--accent);
            text-decoration: none;
        }

        .site-button:focus,
        .site-button:visited {
            background: var(--accent);
            color: var(--bg);
            text-decoration: none;
        }

        .site-button-muted {
            border: 1px solid var(--text);
            background: transparent;
            color: var(--text);
        }

        /* Hover brutalista: intercambio duro tinta↔papel — nada flota, nada se difumina. */
        .site-button-muted:hover {
            background: var(--text);
            color: var(--bg);
            text-decoration: none;
        }

        .site-button-muted:focus,
        .site-button-muted:active,
        .site-button-muted:visited {
            color: var(--text);
            text-decoration: none;
        }

        .site-nav a:focus-visible,
        .site-nav button:focus-visible {
            outline: 2px solid var(--text);
            outline-offset: 2px;
        }

        .site-user {
            color: var(--muted);
        }

        button.site-button-muted {
            cursor: pointer;
        }

        form input,
        form button,
        form select,
        form textarea {
            border-radius: 12px;
            border: 1px solid var(--border);
            background-color: var(--surface);
            color: var(--text);
        }

        form input:focus,
        form button:focus,
        form select:focus,
        form textarea:focus {
            border-color: var(--accent);
            box-shadow: none;
            outline: none;
        }

        .site-footer {
            width: min(1120px, calc(100% - 32px));
            margin: 0 auto;
            padding: 0 0 28px;
            display: flex;
            justify-content: center;
            gap: 14px;
            flex-wrap: wrap;
            color: var(--muted-strong);
            font-size: 12px;
        }

        .site-footer a {
            color: var(--muted);
            font-weight: 700;
            text-decoration: none;
        }

        .site-footer a:hover {
            color: var(--text);
            text-decoration: none;
        }

        @media (max-width: 860px) {
            .site-nav {
                grid-template-columns: 1fr;
                justify-items: center;
            }

            .site-links,
            .site-actions {
                justify-content: center;
                flex-wrap: wrap;
            }

            .container {
                width: calc(100% - 24px);
            }
        }

/* ═════════════════════════════════════════════════════════════════════════════════════════
   LAS CINCO FAMILIAS · el contrato de interactuables (F1 · founder, 2026-08-29)
   ═════════════════════════════════════════════════════════════════════════════════════════

   POR QUÉ EXISTEN. Medido el 29-ago con un escáner kill-testeable: **474 elementos que se
   pulsan** bajo **132 nombres de clase**, y **110 de esos 132 (83%) viven en UNA sola
   plantilla**. Casi cinco de cada seis familias de botón no son de la casa: son de una
   habitación. Y **16 clases están definidas en dos o más archivos** — `.primary` en 7,
   `.pill` en 5 —, así que el mismo nombre hace cosas distintas según dónde caiga.

   Homologar pantalla por pantalla (F4) sin vocabulario es repintar 474 elementos a mano y
   esperar suerte. Esto es el vocabulario. **Cinco, no 132.**

   NINGUNA SE APLICA TODAVÍA, y es a propósito (F1: «se despliega el CSS nuevo, sin usar»).
   Aplicarlas es F4, pantalla por pantalla, con el instrumento de F0 midiendo el antes y el
   después. Definir y aplicar en el mismo commit haría imposible saber cuál de los dos movió
   el píxel.

   LAS RECETAS NO SE INVENTARON: se extrajeron de lo que ya está aprobado y en producción —
   `.pricing-cta` (el vidrio, 27-ago), `.sf-enlace` (el enlace-acción) y `.app-back` (la
   salida). Lo nuevo es que ahora viven UNA vez, con tokens, y con gemelo oscuro.

   CÓMO SE ELIGE, en una frase por familia:
     ¿es LA acción de la pantalla?            → accion-primaria    (una por pantalla, nunca dos)
     ¿es una acción de peso, pero no la principal? → accion-secundaria
     ¿es una acción que cabe en una línea de texto? → accion-terciaria
     ¿es una caja entera que se pulsa?        → cajon
     ¿saca al usuario de donde está?          → salida
   ═════════════════════════════════════════════════════════════════════════════════════════ */

/* El suelo que comparten las cinco. 44px de alto real: el censo del 29-ago encontró que
   «nadie midió contraste, foco ni área táctil» en las 80 familias de una sola plantilla. */
.accion-primaria,
.accion-secundaria,
.accion-terciaria,
.cajon,
.salida,
.app-back,
.par {
    display: inline-flex;
    align-items: center;
    gap: var(--e2);
    min-height: 44px;
    box-sizing: border-box;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    font-family: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease),
                color var(--dur-1) var(--ease);
}
/* Un foco visible en las cinco, de una vez. El censo contó 26 declaraciones de foco en 13
   archivos: la mayoría de las familias no tenía ninguna, y quien navega con teclado no veía
   dónde estaba. */
.accion-primaria:focus-visible,
.accion-secundaria:focus-visible,
.accion-terciaria:focus-visible,
.cajon:focus-visible,
.salida:focus-visible,
.app-back:focus-visible,
.par:focus-visible {
    outline: 2px solid var(--text);
    outline-offset: 2px;
}
/* Desactivado, que el censo encontró estilado en 7 sitios y CERO en hojas compartidas — y
   `.btnv` no lo tenía en ninguna parte: se veía igual vivo que muerto. */
.accion-primaria[disabled], .accion-primaria[aria-disabled="true"],
.accion-secundaria[disabled], .accion-secundaria[aria-disabled="true"],
.accion-terciaria[disabled], .accion-terciaria[aria-disabled="true"],
.cajon[disabled], .cajon[aria-disabled="true"],
.salida[disabled], .salida[aria-disabled="true"],
.par[disabled], .par[aria-disabled="true"] {
    opacity: .45;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* 1 · LA ACCIÓN DE LA PANTALLA. Vidrio, y solo aquí: la ley nº1 del founder es «glass SOLO en
      lo interactuable», así que el material ES la señal de que esto se toca. UNA por pantalla:
      dos primarias es no tener ninguna. */
.accion-primaria {
    padding: var(--e3) var(--e5);
    color: var(--text);
    background: var(--vidrio);
    border-color: var(--vidrio-borde);
    border-top-color: var(--vidrio-luz);
    box-shadow: var(--vidrio-sombra);
    backdrop-filter: blur(12px) saturate(1.2);
    -webkit-backdrop-filter: blur(12px) saturate(1.2);
    font-family: "Plex Mono", ui-monospace, monospace;
    font-size: var(--t-2xs);
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
}
.accion-primaria:hover { transform: translateY(-1px); }

/* 2 · PESO, PERO NO LA PRINCIPAL. El mismo material leído al revés: tinta donde el otro es luz.
      Se reconoce como pariente del primario —misma geometría, misma tipografía— y aun así
      nadie los confunde, que es justo lo que se le pide a una secundaria. */
.accion-secundaria {
    padding: var(--e3) var(--e5);
    color: var(--vidrio-inv-texto);
    background: var(--vidrio-inv);
    border-color: var(--vidrio-inv-borde);
    box-shadow: var(--sombra-1);
    font-family: "Plex Mono", ui-monospace, monospace;
    font-size: var(--t-2xs);
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
}
.accion-secundaria:hover { transform: translateY(-1px); }

/* 3 · UNA ACCIÓN QUE CABE EN UNA LÍNEA DE TEXTO. Receta de `.sf-enlace`. El subrayado NO es
      decorativo: sin él, un enlace-acción apagado es indistinguible de prosa — el bug 2 del
      29-ago era exactamente eso, con 1.21 de contraste. */
.accion-terciaria {
    padding: var(--e2) 0;
    min-height: 0;
    color: var(--muted);
    background: none;
    font-family: "Plex Mono", ui-monospace, monospace;
    font-size: var(--t-2xs);
    letter-spacing: .12em;
    text-transform: uppercase;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.accion-terciaria:hover { color: var(--text); }
/* la flechita viaja con la familia, no con la página */
.accion-terciaria .fl { display: inline-block; transition: transform var(--dur-2) var(--ease); }
.accion-terciaria:hover .fl { transform: translateX(4px); }

/* 4 · UNA CAJA ENTERA QUE SE PULSA. Un destino, no una acción: se anuncia con el borde y
      responde con el fondo.
      🩸 ESTA REGLA DECÍA «NO LLEVA VIDRIO: el vidrio es de las acciones», Y SE CORRIGIÓ EL 30-ago
      CON SU PRIMER CASO REAL. La frase se escribió cuando `cajon` tenía CERO usos —o sea que
      nunca se había probado contra nada—, y el primero en llegar fue el muro de meses de
      Sincronización: 68 destinos en pantalla, aprobados en el lab CON vidrio. La ley nº1 del
      founder dice «vidrio SOLO en lo interactuable», no «solo en las acciones»; una casilla que
      se pulsa 68 veces por pantalla necesita ese aviso más que nadie.
      🔑 Lo que la familia fija es la GEOMETRÍA y el CONTRATO (columna, 44 px, foco, desactivado,
      estado activo). El MATERIAL lo elige la pantalla, y con tokens `--vidrio*` para que gire con
      el tema. Una regla que nunca se probó contra un caso real no es una regla: es una intuición
      con formato de regla. */
.cajon {
    display: flex;
    align-items: stretch;
    flex-direction: column;
    gap: var(--e1);
    width: 100%;
    padding: var(--e4);
    text-align: left;
    color: var(--text);
    background: var(--surface);
    border-color: var(--border);
    font-size: var(--t-sm);
}
.cajon:hover { background: var(--surface-soft); }
.cajon[aria-current="true"], .cajon.is-active { border-color: var(--text); }

/* 5 · SACA AL USUARIO DE DONDE ESTÁ. Receta de `.app-back`. Una sola por pantalla y siempre en
      el mismo sitio: el censo contó **6 patrones de salida en 4 posiciones**, y 13 de 41 vistas
      del panel sin ninguna.
      🪤 EL GLIFO VA AQUÍ, no en la plantilla: se escribía con CUATRO grafías distintas
      (`←` ×7 · `&larr;` ×6 · `&#8592;` ×2 · `&lsaquo;` ×2 — que además es OTRO carácter, el del
      paginador). Con la flecha en el CSS, escribirla mal deja de ser posible. */
.salida,
.app-back {
    /* 🩸 EL AIRE DE ABAJO NO ES ADORNO, Y COSTÓ UN DEPLOY. La salida siempre es lo primero de su superficie y siempre
       necesita separarse de lo que abre (sin él, cada migración movía su pantalla 16 px; lo cazó la regresión visual). */
    margin-bottom: var(--e4);
    /* 26-sep (founder, viendo el muro «Sin permiso»: arriba el «Volver» sin borde, abajo el de vidrio): «hay que
       homologar para que se vea como el volver de abajo, que ya tiene el liquid glass con diseño moderno». La
       decisión que este comentario esperaba desde F4 («el día que se decida cambiar el aspecto será una decisión»):
       la salida se viste con el MATERIAL de la casa —vidrio, luz arriba, desenfoque— y la letra de los pares.
       Sin la sombra ni el salto de `accion-primaria`, y con la letra un tono más suave (la del par): una sola primaria
       por pantalla, y la salida no compite con ella — `tests_navegador_familias` cazó que quedaban IDÉNTICAS. Al pasar
       el cursor la letra se entinta. `.app-back` (el nombre viejo, aún en 10 plantillas) comparte ESTA regla: dos
       nombres, un solo aspecto. */
    padding: 0 var(--e4);
    color: var(--muted-strong);
    background: var(--vidrio);
    border-color: var(--vidrio-borde);
    border-top-color: var(--vidrio-luz);
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    font-family: "Plex Mono", ui-monospace, monospace;
    font-size: var(--t-2xs);
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
}
.salida::before { content: "\2190"; }
/* el tinte del par encima del vidrio (una sombra interior no reemplaza el degradado: lo tiñe) */
.salida:hover, .app-back:hover { color: var(--text); box-shadow: inset 0 0 0 100vmax color-mix(in srgb, var(--text) 9%, transparent); }

/* 6 · UN GRUPO DE IGUALES (founder, 30-ago) — la familia que faltaba.
      📏 NO SE AÑADIÓ POR GUSTO, SE MIDIÓ: **17 plantillas** tienen una fila de 3 o más acciones
      PARES —descargar Excel/CSV/XML/PDF, elegir el mes, cambiar de vista—, o sea un tercio del
      producto. Y el producto ya tenía respuesta para eso, dicha de 17 maneras: `.mes-mini`,
      `.con-btn`, `.lb-chip`, `.export-link`, `.enlace-m`, `.uz-btn-ghost`, `.is-on`… **ninguna
      un bloque relleno.** Meterlas en `accion-secundaria` hacía gritar a 17 pantallas: se probó
      en `invoice_detail` y las tres descargas pesaban más que la propia factura, que es lo que
      la pantalla existe para enseñar.

      UNA FAMILIA, DOS USOS, y por eso no son dos:
        · ELEGIR uno   — Mes/Año, Facturado/Cobrado: uno va marcado `aria-current="true"`.
        · HACER uno    — Excel/CSV/XML/PDF: ninguno marcado, todos hacen algo distinto.
      Se ven igual porque SON lo mismo: hermanos del mismo peso. La marca de activo es un estado
      opcional, no otra familia.

      El grupo lleva el borde y el recorte; cada hermano solo su tinta. Así los bordes no se
      duplican entre vecinos, que es el defecto clásico de las filas de botones. */
/* 16-sep (founder): «los botones de Facturado/Cobrado que tengan el mismo diseño que el botón de Filtrar, lo
   mismo con Anterior/Siguiente y con Apariencia · Blanco/Negro»: la familia entera pasa al VIDRIO de la casa
   (el mismo de Filtrar, la búsqueda y las listas desplegables): degradado de vidrio, borde translúcido con
   luz arriba, desenfoque del fondo. El ELEGIDO sigue siendo tinta sobre papel: es el único estado que
   necesita gritar. */
.grupo-de-pares {
    display: inline-flex;
    flex-wrap: wrap;
    border: 1px solid var(--vidrio-borde);
    border-top-color: var(--vidrio-luz);
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--vidrio);
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
}
.par {
    padding: 0 var(--e4);
    min-height: 44px;   /* área táctil de la casa (tests_navegador_familias): 40 fue rojo en el gate */
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--muted-strong);
    font-family: "Plex Mono", ui-monospace, monospace;
    font-size: var(--t-2xs);
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    justify-content: center;
    transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
/* 16-sep (founder): «me agrada más que no haya divisiones y que el hover sí se note la división, es más limpio».
   Sin rayas entre hermanos: la división la enseña el cursor (el hermano bajo el cursor se tiñe entero) y el elegido
   la enseña con su tinta. */
.par:hover { background: color-mix(in srgb, var(--text) 9%, transparent); color: var(--text); }
/* ELEGIDO. `aria-current` no es decoración: es lo que hace que un lector de pantalla diga cuál
   está puesto. La clase acompaña para los casos donde el marcado no puede llevar el atributo. */
.par[aria-current="true"], .par.es-el-elegido {
    background: var(--text);
    color: var(--bg);
}
.par:focus-visible { outline-offset: -2px; }
/* UN PAR SOLO (fuera de un grupo) lleva el vidrio del grupo: «Quitar», «+ Agregar», el summary de un cajón, «Ver la
   factura». Vivía en la piel del formulario de Emisión (`.emi-form.fx`); el 26-sep el libro de pólizas lo necesitó
   FUERA de un formulario y fuera de Emisión — una familia se define una vez, o el segundo sitio la copia y se separa. */
.par[data-solo] { display: inline-flex; width: max-content; max-width: 100%; padding: 0 var(--e4);
    background: var(--vidrio); border: 1px solid var(--vidrio-borde); border-top-color: var(--vidrio-luz); border-radius: var(--r-md);
    backdrop-filter: blur(14px) saturate(1.2); -webkit-backdrop-filter: blur(14px) saturate(1.2); color: var(--text); }
.par[data-solo]:hover { transform: translateY(-1px); }
.par[data-solo][hidden] { display: none; }



/* 6b · EL SELECTOR DE PERIODO — ‹ · [2026 / ago ▾] · › (27-sep-2026). Nació en Facturas el 16-sep (founder: «que el
      selector de año con flechas a los extremos se pueda seleccionar el contenido interno … un drop down de año y mes …
      y con el desplegable abierto el 2026 se vuelva un icono de palomita para aceptar los cambios») y vivía en su
      plantilla. El 27-sep pidió LO MISMO para el «‹ Ago 2026 ›» de Contabilidad, DIOT, Gastos, Nómina… («el box externo
      se ve cuadrado y viejo … del mismo height, bordes redondeados, las flechas seleccionables en todo su recuadro, y que
      se puedan elegir años completos»): era una caja cuadrada con un desplegable de vidrio ADENTRO (caja dentro de caja,
      52 px). Una familia se define UNA vez: si el segundo sitio la copia, se separa.
        · `.periodo` (con `.grupo-de-pares`) — el grupo de vidrio: ‹ · centro · ›, 44 px, esquinas de la casa. Las
          flechas son pares enteros: se pulsa todo su segmento, no el glifo.
        · `.periodo-sel` — el centro, un <details>: cerrado enseña las migas (2026 / ago); abierto, el panel debajo y la
          palomita en su lugar. Elegir NO navega: la palomita aplica (`_selector_periodo_js.html`).
        · `.periodo-panel` — una fila de años (línea de tiempo) y una fila de meses del año elegido; vidrio DENSO. */
/* el grupo recorta (overflow: hidden) y eso se tragaba el panel absoluto: aquí el grupo no recorta y las puntas ‹ ›
   llevan su propio radio para que el relleno de tinta no asome por las esquinas. Medido en Facturas: el LIENZO del héroe
   —posicionado y posterior en el DOM— se pintaba encima del panel y el clic en un año caía en el canvas: el grupo va por
   encima. */
/* `width: max-content`: en una columna flexible (Gastos y Visor en el teléfono) el grupo se estiraba a todo el ancho y
   dejaba vidrio vacío a la derecha de la flecha › (medido 27-sep a 390 px). El grupo mide lo que su contenido. */
/* z-index 25: por encima del contenido posicionado de la página (el lienzo del héroe de Facturas, los paneles de 8 y 20) y
   POR DEBAJO de las barras fijas (cabecera del teléfono y pestañas, 30). Con 40, al hacer scroll el selector pasaba por
   encima de la cabecera y se comía el toque de la «R» (revisión 27-sep). */
nav.periodo.grupo-de-pares { position: relative; overflow: visible; z-index: 25; isolation: isolate;
    flex-wrap: nowrap; width: max-content; max-width: 100%;
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
/* El vidrio del grupo vive en un pseudo-elemento y no en el nav: un backdrop-filter en el propio nav lo vuelve «raíz de
   fondo» y el panel —hijo suyo— ya no podía desenfocar lo de atrás (founder: «el desplegable transparenta y choca con el
   monto»: la cifra se veía NÍTIDA a través del panel). */
nav.periodo.grupo-de-pares::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    border-radius: inherit; background: var(--vidrio);
    backdrop-filter: blur(14px) saturate(1.2); -webkit-backdrop-filter: blur(14px) saturate(1.2); }
/* REVERTIR (Facturas): junto a la palomita, quitar el periodo; solo se ve con el panel abierto */
.periodo-revertir { display: none; }
.periodo-sel[open] + .periodo-revertir { display: inline-flex; }
.periodo-revertir svg { width: 18px; height: 18px; }
/* sin rayas entre hermanos (founder 16-sep: «más limpio»): la división la enseña el hover y el elegido */
.periodo > .par:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
.periodo > .par:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }
.periodo .par { text-decoration: none; }
.periodo > .par[aria-label], .periodo > .par.periodo-flecha { padding: 0 var(--e3); font-size: var(--t-sm); }   /* ‹ › */
/* apagado = la opacidad de `.par[aria-disabled]` y nada más: con el color de borde encima quedaba a ~1.2:1 y la rejilla
   parecía tener huecos (revisión 27-sep) */
.periodo > .par[aria-disabled="true"] { pointer-events: none; }
.periodo-sel { position: static; }
.periodo-sel > summary { position: relative; display: inline-flex; align-items: center; gap: var(--e2); list-style: none; cursor: pointer; }
.periodo-sel > summary::-webkit-details-marker { display: none; }
.periodo-texto { display: inline-flex; align-items: center; gap: var(--e2); }
.periodo-texto .sep { color: var(--vidrio-borde); }
.periodo-texto [aria-current="page"] { color: var(--text); font-weight: 700; }
.periodo-texto::after { content: "▾"; color: var(--muted); font-size: var(--t-2xs); }
/* ABIERTO, EL CENTRO NO CAMBIA DE ANCHO: el texto se tapa (no se quita) y la palomita va encima. Al quitarlo, el centro
   pasaba de 131 a 50 px, la flecha quedaba bajo el cursor y un doble clic en «2026 / ago» cambiaba de mes (revisión
   27-sep, severidad alta; también en Facturas). */
.periodo-ok { display: none; width: 18px; height: 18px; }
.periodo-sel[open] > summary .periodo-texto { visibility: hidden; }
.periodo-sel[open] > summary .periodo-ok { display: block; position: absolute; inset: 0; margin: auto; }
.periodo-sel[open] > summary { background: var(--text); color: var(--bg); }
/* HORIZONTAL (founder): una fila de años (en orden, como una línea de tiempo) y una fila de meses; vidrio denso de panel
   (casi opaco, más desenfoque) para no chocar con la cifra de atrás. */
.periodo-panel { position: absolute; right: 0; top: calc(100% + var(--e2)); z-index: 30; display: flex; flex-direction: column;
    gap: var(--e2); padding: var(--e3); width: max-content; max-width: min(760px, calc(100vw - 48px));
    border: 1px solid var(--vidrio-borde); border-top-color: var(--vidrio-luz); border-radius: var(--r-md);
    background: var(--vidrio-panel); box-shadow: var(--vidrio-sombra);
    backdrop-filter: var(--vidrio-panel-blur); -webkit-backdrop-filter: var(--vidrio-panel-blur); }
.periodo-anios { display: flex; flex-wrap: wrap; gap: var(--e1); padding-bottom: var(--e2); border-bottom: 1px solid var(--vidrio-borde); }
.periodo-meses { display: flex; flex-wrap: wrap; gap: var(--e1); }
.periodo-meses[hidden] { display: none; }   /* `display: flex/grid` le ganaba al atributo: los seis años se apilaban */
.periodo-panel .par { min-height: 36px; min-width: 54px; border-radius: var(--r-sm); background: none; }
.periodo-panel .par[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.periodo-panel .par[aria-disabled="true"] { pointer-events: none; }   /* un mes que aún no llega: apagado por opacidad */
/* EL FOCO SE VE sobre lo relleno de tinta: el anillo de `.par` es del color de la tinta y va por dentro, así que en la
   palomita abierta y en el año o mes elegido desaparecía (revisión 27-sep). Anillo claro dentro de la tinta. */
.periodo-sel[open] > summary:focus-visible, .periodo-panel .par[aria-pressed="true"]:focus-visible {
    outline-color: var(--bg); outline-offset: -4px; }
.periodo-panel .k { font-family: "Plex Mono", ui-monospace, monospace; font-size: var(--t-2xs);
    letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }

/* 7 · UN DESPLEGABLE (founder, 16-sep: «¿no hay familia para dropdowns o listas desplegables? es muy notoria la
      diferencia de diseño»). No la había: la fachada `dd-facade` (jul-2026) vestía su disparador con el borde gris
      cuadrado del formulario viejo y cada pantalla lo re-vestía a su modo (Facturas en mono, Emisión en vidrio,
      Contabilidad a pelo). Ahora es UNA familia con tres piezas, y la fachada las pone sola:
        · `.desplegable`        — el DISPARADOR (el <summary>): la geometría del par (44 px, esquina de la casa) con
                                  el material de un campo (vidrio, luz arriba) y un galón que gira con el tema.
        · `.desplegable-panel`  — la LISTA que flota: el vidrio denso de la casa (`--vidrio-panel`), como el selector
                                  de periodo de Facturas.
        · `.desplegable-opcion` — cada OPCIÓN: una fila de 44 px que se tiñe al pasar y va en tinta si es la elegida.
      Los <details class="multi-select"> escritos a mano llevan la primera clase en su <summary>. */
:root { --chevron-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
[data-theme="dark"] { --chevron-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23fafafa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
.desplegable {
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
    line-height: 42px;
    padding: 0 40px 0 var(--e4);
    border: 1px solid var(--vidrio-borde);
    border-top-color: var(--vidrio-luz);
    border-radius: var(--r-md);
    background-image: var(--chevron-select), var(--vidrio);
    background-repeat: no-repeat;
    background-position: right 14px center, 0 0;
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    color: var(--text);
    font-family: inherit;
    font-size: var(--t-md);
    text-align: left;
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.desplegable::-webkit-details-marker { display: none; }
.desplegable[data-vacio] { color: var(--muted); }   /* sin valor: la pista, apagada como un placeholder */
.desplegable:hover { border-color: var(--text); transform: translateY(-1px); }
details[open] > .desplegable { border-color: var(--text); transform: none; }
.desplegable:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.desplegable[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; }
.desplegable-panel {
    position: absolute;
    z-index: 8;
    top: calc(100% + 6px);
    left: 0;
    min-width: 100%;
    max-height: 320px;
    overflow-y: auto;
    padding: var(--e2);
    display: grid;
    gap: 2px;
    /* color sólido debajo del degradado: el panel tiene caja aunque un juez lea solo backgroundColor, y no transparenta */
    background-color: color-mix(in srgb, var(--surface) 88%, transparent);
    background-image: var(--vidrio-panel);
    border: 1px solid var(--vidrio-borde);
    border-top-color: var(--vidrio-luz);
    border-radius: var(--r-md);
    box-shadow: 0 18px 50px rgba(10, 10, 10, .12);
    backdrop-filter: var(--vidrio-panel-blur);
    -webkit-backdrop-filter: var(--vidrio-panel-blur);
}
.desplegable-panel[hidden] { display: none; }
.desplegable-panel .desplegable-opcion {
    display: flex;
    align-items: center;
    gap: var(--e2);
    width: 100%;
    min-height: 44px;
    padding: 0 var(--e3);
    border: 0;
    border-radius: var(--r-sm);
    background: none;
    color: var(--text);
    font: inherit;
    font-size: var(--t-md);
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.desplegable-panel .desplegable-opcion:hover,
.desplegable-panel .desplegable-opcion.activa { background: color-mix(in srgb, var(--text) 9%, transparent); }
.desplegable-panel .desplegable-opcion.dd-selected,
.desplegable-panel .desplegable-opcion[aria-selected="true"] { background: var(--text); color: var(--bg); font-weight: 500; }
/* 26-sep: en móvil el panel NO puede ser más ancho que su campo — con opciones de una línea («NOMBRE LARGO — RFC») se
   salía por la derecha de la pantalla (medido a 390 px). Mide lo que el campo y la opción larga parte línea.
   🪤 VA DESPUÉS de la regla base de la opción: misma especificidad, gana la última (la revisión cazó que estaba antes y no aplicaba). */
@media (max-width: 600px) {
    .desplegable-panel { max-width: 100%; }
    .desplegable-panel .desplegable-opcion { white-space: normal; overflow-wrap: anywhere; padding-block: var(--e2); }
}

/* ── 16-sep-2026 · LOS BOTONES PÚBLICOS, homologados con la landing (founder: «me gusta más el diseño del botón de
   Precios pero … quiero algo más negro sin brillo pero igual de moderno»): tinta mate, esquinas de la casa, mono. ── */
.site-button, .site-button-muted {
    border-radius: var(--r-md); box-shadow: none; background-image: none;
    font-family: "Plex Mono", ui-monospace, monospace; font-size: var(--t-2xs); font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; padding: var(--e2) var(--e4);
    border: 1px solid var(--text); transition: transform var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease);
}
.site-button { background: var(--text); color: var(--bg); }
.site-button-muted { background: transparent; color: var(--text); }
.site-button:hover, .site-button-muted:hover { transform: translateY(-1px); opacity: .92; }
/* 16-sep (founder, 2ª ronda): «al hacer hover se dejan de ver las letras, todo adquiere el mismo color en vez de
   INVERTIR los colores». El hover SÍ invierte (tinta↔papel), y las letras no pueden desaparecer.
   🪤 LA CAUSA de las letras invisibles: las reglas viejas de arriba ponen `:visited` DESPUÉS de `:hover` con la
   misma especificidad. «Iniciar sesión» y «Crear cuenta» son enlaces que él YA visitó: al pasar el cursor, `:hover`
   pintaba el fondo de tinta y `:visited`, más abajo, dejaba la letra de tinta → tinta sobre tinta. Aquí el hover es
   la ÚLTIMA palabra sobre fondo y color, también para un enlace visitado (`:visited:hover` gana por especificidad). */
.site-button:focus, .site-button:visited { background: var(--text); color: var(--bg); }
.site-button-muted:focus, .site-button-muted:visited { background: transparent; color: var(--text); }
.site-button:hover, .site-button:active, .site-button:visited:hover { background: var(--bg); color: var(--text); }
.site-button-muted:hover, .site-button-muted:active, .site-button-muted:visited:hover { background: var(--text); color: var(--bg); }
.site-button:focus-visible, .site-button-muted:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

/* la luna/el sol: UN solo icono a la vista, sin contorno ni fondo en ningún estado (founder: «que no tenga contorno el
   botón, solo sean ambos iconos … es un simple switch»). Luna en claro (pulsar = oscuro) y el icono gira a sol; pulsar el
   sol lo revierte. Los dos SVG viven apilados: `display:none` no se puede animar, la opacidad y el giro sí. */
.site-brand-wrap { display: flex; align-items: center; gap: var(--e5); }
:root .site-button-muted[data-tema-sw], :root[data-theme="dark"] .site-button-muted[data-tema-sw],
:root .site-button-muted[data-tema-sw]:hover, :root[data-theme="dark"] .site-button-muted[data-tema-sw]:hover,
:root .site-button-muted[data-tema-sw]:focus, :root[data-theme="dark"] .site-button-muted[data-tema-sw]:focus,
:root .site-button-muted[data-tema-sw]:active, :root[data-theme="dark"] .site-button-muted[data-tema-sw]:active {
    position: relative; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px;
    padding: 0; border: 0; background: transparent; color: var(--text); box-shadow: none; transform: none; opacity: 1; }
:root .site-button-muted[data-tema-sw]:hover svg, :root[data-theme="dark"] .site-button-muted[data-tema-sw]:hover svg { opacity: .6; }
.site-button-muted[data-tema-sw]:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.site-button-muted[data-tema-sw] svg { position: absolute; inset: 0; margin: auto;
    transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }
.site-button-muted[data-tema-sw] [data-luna] { opacity: 1; transform: none; }
.site-button-muted[data-tema-sw] [data-sol] { opacity: 0; transform: rotate(-90deg) scale(.6); }
:root[data-theme="dark"] .site-button-muted[data-tema-sw] [data-luna] { opacity: 0; transform: rotate(90deg) scale(.6); }
:root[data-theme="dark"] .site-button-muted[data-tema-sw] [data-sol] { opacity: 1; transform: none; }
:root .site-button-muted[data-tema-sw]:hover [data-luna], :root[data-theme="dark"] .site-button-muted[data-tema-sw]:hover [data-sol] { opacity: .6; }
:root .site-button-muted[data-tema-sw]:hover [data-sol], :root[data-theme="dark"] .site-button-muted[data-tema-sw]:hover [data-luna] { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .site-button-muted[data-tema-sw] svg { transition: none; } }
