/* ════════════════════════════════════════════════════════════════════════
   FUSION APP — CAPA DE TEMA (theme.css)
   Sistema de tokens en 3 capas con modo claro/oscuro y temas por vertical.

   Capa 1 · PRIMITIVAS   → la marca, en coordenadas OKLCH (L, C, H).
                           Las inyecta el administrador (storage/branding.json)
                           o el inquilino (config/tenants/*.json).
   Capa 2 · SEMANTICOS   → superficies, texto, bordes y acentos DERIVADOS de
                           la marca. Cambian con [data-theme].
   Capa 3 · COMPATIBLES  → alias con los nombres que ya usa app.css, para que
                           el CSS heredado herede el tema sin reescribirlo.

   Regla de oro: ningun componente escribe un color literal. Todo sale de aqui.
   ════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────
   CAPA 1 · PRIMITIVAS DE MARCA
   Solo estas tres cifras definen la identidad de un vertical. El resto del
   sistema se deriva de ellas, asi que un inquilino nuevo son 3 numeros.
   --------------------------------------------------------------------- */
:root {
    color-scheme: light;

    /* Cadena de mando del color, de menor a mayor autoridad:
         1. estos valores por defecto (verde Guardia Civil #1B4D3E)
         2. [data-vertical] mas abajo, que pone --v-*
         3. el inquilino, que pisa --v-* desde el <style> del header
         4. el administrador, que pone --brand-* directamente y gana siempre
       Por eso aqui se lee --v-* y no se escribe un valor fijo. */
    --brand-l: var(--v-brand-l, 0.38);
    --brand-c: var(--v-brand-c, 0.06);
    --brand-h: var(--v-brand-h, 170);

    /* Acento de honor (insignias, rangos, logros): dorado militar #C59B27 */
    --honor-l: var(--v-honor-l, 0.70);
    --honor-c: var(--v-honor-c, 0.12);
    --honor-h: var(--v-honor-h, 88);

    /* Cuanto tine la marca a los grises. 0 = neutro puro, 0.012 = ambiente. */
    --tint-c: var(--v-tint-c, 0.010);

    /* ── Tipografia ── */
    --font-display: 'Sora', system-ui, -apple-system, sans-serif;
    --font-body: 'Instrument Sans', system-ui, -apple-system, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

    /* Escala fluida 1.2 (minor third), legible de 360px a 1920px */
    --text-xs: clamp(0.69rem, 0.68rem + 0.05vw, 0.72rem);
    --text-sm: clamp(0.80rem, 0.78rem + 0.08vw, 0.85rem);
    --text-md: clamp(0.92rem, 0.90rem + 0.10vw, 0.98rem);
    --text-lg: clamp(1.08rem, 1.04rem + 0.18vw, 1.20rem);
    --text-xl: clamp(1.32rem, 1.24rem + 0.35vw, 1.55rem);
    --text-2xl: clamp(1.65rem, 1.50rem + 0.65vw, 2.10rem);
    --text-3xl: clamp(2.05rem, 1.80rem + 1.10vw, 2.95rem);

    --leading-tight: 1.15;
    --leading-snug: 1.35;
    --leading-normal: 1.6;
    --tracking-caps: 0.08em;

    /* ── Espaciado: base 4px, una sola escala para todo ── */
    --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
    --sp-5: 20px;  --sp-6: 24px;  --sp-7: 32px;  --sp-8: 40px;
    --sp-9: 48px;  --sp-10: 64px; --sp-11: 80px;

    /* ── Radios ── */
    --radius-xs: 6px;  --radius-sm: 8px;  --radius-md: 10px;
    --radius-lg: 14px; --radius-xl: 20px; --radius-pill: 9999px;
    --radius: var(--radius-lg);

    /* ── Movimiento ── */
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-out: cubic-bezier(0.33, 1, 0.68, 1);
    --duration-fast: 120ms;
    --duration: 180ms;
    --duration-slow: 280ms;

    /* ── Capas ── */
    --z-base: 1; --z-sticky: 100; --z-drawer: 200; --z-modal: 300; --z-toast: 400;
}

/* ───────────────────────────────────────────────────────────────────────
   CAPA 2 · TOKENS SEMANTICOS
   Las superficies no son colores: son posiciones en una escalera de
   luminancia. Cambiar de tema = mover la escalera, no repintar la casa.
   --------------------------------------------------------------------- */

/* ── Escalera en MODO CLARO ── */
:root,
:root[data-theme="light"] {
    color-scheme: light;

    --l-canvas: 0.958;  --c-canvas: var(--tint-c);
    --l-surface: 1.000; --c-surface: 0;
    --l-raised: 1.000;  --c-raised: 0;
    --l-sunken: 0.925;  --c-sunken: var(--tint-c);
    --l-overlay: 1.000;

    --l-text-strong: 0.22; --l-text: 0.30; --l-text-soft: 0.47;
    --l-text-mute: 0.55;   --l-text-faint: 0.62;
    --c-text: 0.018;

    --l-line: 0.22;
    --a-line: 0.15;
    --a-line-soft: 0.09;
    --a-line-strong: 0.24;

    /* El relleno de marca se normaliza a una banda segura: garantiza
       contraste AA con texto blanco aunque el admin elija un color claro. */
    --l-accent-fill: clamp(0.34, var(--brand-l), 0.52);
    --l-accent-text: clamp(0.30, var(--brand-l), 0.46);
    --c-accent: var(--brand-c);
    --l-on-accent: 0.99;

    --a-accent-subtle: 0.08;
    --a-accent-soft: 0.14;
    --a-accent-glow: 0.18;

    --l-honor-fill: clamp(0.60, var(--honor-l), 0.74);
    --l-honor-text: clamp(0.38, calc(var(--honor-l) - 0.22), 0.52);
    --l-on-honor: 0.16;

    --a-shadow-1: 0.05;
    --a-shadow-2: 0.07;
    --a-shadow-3: 0.10;

    /* Semanticos: mantienen su tono propio, nunca se tinen de marca */
    --l-success: 0.46; --l-warning: 0.54; --l-danger: 0.52; --l-info: 0.54;
    --a-semantic-soft: 0.12;
}

/* ── Escalera en MODO OSCURO ──
   No es una inversion: es un ambiente propio, tenido con el tono de la marca.
   Guardia Civil cae en verde profundo, Policia en azul noche, Ejercito en
   oliva oscuro. Un solo bloque de cifras produce los tres. */
:root[data-theme="dark"] {
    color-scheme: dark;

    --l-canvas: 0.128;  --c-canvas: calc(var(--tint-c) * 3.5);
    --l-surface: 0.198; --c-surface: calc(var(--tint-c) * 3);
    --l-raised: 0.255;  --c-raised: calc(var(--tint-c) * 2.5);
    --l-sunken: 0.105;  --c-sunken: calc(var(--tint-c) * 4);
    --l-overlay: 0.225;

    --l-text-strong: 0.975; --l-text: 0.935; --l-text-soft: 0.775;
    /* El tenue sube de 0.545 a 0.620: a 0.545 no llegaba a AA sobre ninguna
       superficie oscura (2.9:1 sobre la tarjeta elevada) y es el color de los
       marcadores de posicion y de la letra pequena del acceso. Sigue por
       debajo de --l-text-mute, asi que la escalera no se invierte. */
    --l-text-mute: 0.655;   --l-text-faint: 0.620;
    --c-text: 0.012;

    --l-line: 0.98;
    --a-line: 0.18;
    --a-line-soft: 0.11;
    --a-line-strong: 0.28;

    /* Sobre fondo oscuro la marca se eleva para seguir leyendose */
    --l-accent-fill: clamp(0.52, calc(var(--brand-l) + 0.24), 0.74);
    --l-accent-text: clamp(0.68, calc(var(--brand-l) + 0.36), 0.86);
    --c-accent: min(0.2, calc(var(--brand-c) * 2));
    --l-on-accent: 0.14;

    --a-accent-subtle: 0.14;
    --a-accent-soft: 0.22;
    --a-accent-glow: 0.30;

    --l-honor-fill: clamp(0.66, var(--honor-l), 0.80);
    --l-honor-text: clamp(0.72, calc(var(--honor-l) + 0.08), 0.88);
    --l-on-honor: 0.14;

    --a-shadow-1: 0.30;
    --a-shadow-2: 0.40;
    --a-shadow-3: 0.55;

    --l-success: 0.72; --l-warning: 0.78; --l-danger: 0.68; --l-info: 0.72;
    --a-semantic-soft: 0.20;
}

/* Preferencia del sistema cuando el usuario no ha elegido todavia */
@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] {
        color-scheme: dark;

        --l-canvas: 0.128;  --c-canvas: calc(var(--tint-c) * 3.5);
        --l-surface: 0.198; --c-surface: calc(var(--tint-c) * 3);
        --l-raised: 0.255;  --c-raised: calc(var(--tint-c) * 2.5);
        --l-sunken: 0.105;  --c-sunken: calc(var(--tint-c) * 4);
        --l-overlay: 0.225;

        --l-text-strong: 0.975; --l-text: 0.935; --l-text-soft: 0.775;
        --l-text-mute: 0.655;   --l-text-faint: 0.620;
        --c-text: 0.012;

        --l-line: 0.98;
        --a-line: 0.18;
        --a-line-soft: 0.11;
        --a-line-strong: 0.28;

        --l-accent-fill: clamp(0.52, calc(var(--brand-l) + 0.24), 0.74);
        --l-accent-text: clamp(0.68, calc(var(--brand-l) + 0.36), 0.86);
        --c-accent: min(0.2, calc(var(--brand-c) * 2));
        --l-on-accent: 0.14;

        --a-accent-subtle: 0.14;
        --a-accent-soft: 0.22;
        --a-accent-glow: 0.30;

        --l-honor-fill: clamp(0.66, var(--honor-l), 0.80);
        --l-honor-text: clamp(0.72, calc(var(--honor-l) + 0.08), 0.88);
        --l-on-honor: 0.14;

        --a-shadow-1: 0.30;
        --a-shadow-2: 0.40;
        --a-shadow-3: 0.55;

        --l-success: 0.72; --l-warning: 0.78; --l-danger: 0.68; --l-info: 0.72;
        --a-semantic-soft: 0.20;
    }
}

/* ── Los tokens que de verdad usan los componentes ── */
:root {
    /* Superficies */
    --canvas: oklch(var(--l-canvas) var(--c-canvas) var(--brand-h));
    --surface: oklch(var(--l-surface) var(--c-surface) var(--brand-h));
    --surface-raised: oklch(var(--l-raised) var(--c-raised) var(--brand-h));
    --surface-sunken: oklch(var(--l-sunken) var(--c-sunken) var(--brand-h));
    --surface-overlay: oklch(var(--l-overlay) var(--c-surface) var(--brand-h));

    /* Texto */
    --text-strong: oklch(var(--l-text-strong) var(--c-text) var(--brand-h));
    --text: oklch(var(--l-text) var(--c-text) var(--brand-h));
    --text-soft: oklch(var(--l-text-soft) var(--c-text) var(--brand-h));
    --text-mute: oklch(var(--l-text-mute) var(--c-text) var(--brand-h));
    --text-faint: oklch(var(--l-text-faint) var(--c-text) var(--brand-h));

    /* Lineas */
    --line: oklch(var(--l-line) var(--c-text) var(--brand-h) / var(--a-line));
    --line-soft: oklch(var(--l-line) var(--c-text) var(--brand-h) / var(--a-line-soft));
    --line-strong: oklch(var(--l-line) var(--c-text) var(--brand-h) / var(--a-line-strong));

    /* Marca */
    --accent: oklch(var(--l-accent-fill) var(--c-accent) var(--brand-h));
    --accent-hover: oklch(calc(var(--l-accent-fill) + 0.05) var(--c-accent) var(--brand-h));
    --accent-active: oklch(calc(var(--l-accent-fill) - 0.04) var(--c-accent) var(--brand-h));
    --accent-text: oklch(var(--l-accent-text) var(--c-accent) var(--brand-h));
    --accent-subtle: oklch(var(--l-accent-fill) var(--c-accent) var(--brand-h) / var(--a-accent-subtle));
    --accent-soft: oklch(var(--l-accent-fill) var(--c-accent) var(--brand-h) / var(--a-accent-soft));
    --accent-glow: oklch(var(--l-accent-fill) var(--c-accent) var(--brand-h) / var(--a-accent-glow));
    --on-accent: oklch(var(--l-on-accent) 0 0);

    /* Honor / insignias */
    --honor: oklch(var(--l-honor-fill) var(--honor-c) var(--honor-h));
    --honor-text: oklch(var(--l-honor-text) var(--honor-c) var(--honor-h));
    --honor-soft: oklch(var(--l-honor-fill) var(--honor-c) var(--honor-h) / 0.14);
    --honor-line: oklch(var(--l-honor-fill) var(--honor-c) var(--honor-h) / 0.32);
    --on-honor: oklch(var(--l-on-honor) 0 0);

    /* Semanticos */
    --success: oklch(var(--l-success) 0.13 152);
    --success-soft: oklch(var(--l-success) 0.13 152 / var(--a-semantic-soft));
    --warning: oklch(var(--l-warning) 0.15 72);
    --warning-soft: oklch(var(--l-warning) 0.15 72 / var(--a-semantic-soft));
    --danger: oklch(var(--l-danger) 0.19 27);
    --danger-soft: oklch(var(--l-danger) 0.19 27 / var(--a-semantic-soft));
    --info: oklch(var(--l-info) 0.14 240);
    --info-soft: oklch(var(--l-info) 0.14 240 / var(--a-semantic-soft));

    /* Elevacion: sombra proyectada, no neumorfismo */
    --shadow-xs: 0 1px 2px oklch(0 0 0 / var(--a-shadow-1));
    --shadow-sm: 0 1px 2px oklch(0 0 0 / var(--a-shadow-1)),
                 0 2px 6px oklch(0 0 0 / var(--a-shadow-1));
    --shadow-md: 0 2px 4px oklch(0 0 0 / var(--a-shadow-1)),
                 0 8px 20px oklch(0 0 0 / var(--a-shadow-2));
    --shadow-lg: 0 4px 10px oklch(0 0 0 / var(--a-shadow-2)),
                 0 18px 44px oklch(0 0 0 / var(--a-shadow-3));
    --shadow-accent: 0 6px 20px var(--accent-glow);
    --ring: 0 0 0 3px var(--accent-soft);

    /* Velo de los dialogos. Va oscuro en los dos temas y tenido con la
       marca: en claro un velo claro no separa nada del fondo, y en oscuro
       lo que hace falta es hundir la pagina, no aclararla. Lo pedia
       design-fidelity.css, que lo traia como un azul pizarra fijo. */
    --scrim: oklch(0.14 calc(var(--tint-c) * 4) var(--brand-h) / 0.68);
}

/* ───────────────────────────────────────────────────────────────────────
   CAPA 3 · ALIAS DE COMPATIBILIDAD
   app.css y design-fidelity.css ya consumen estos nombres. Mapearlos aqui
   hace que todo el CSS heredado que use var() siga el tema automaticamente,
   incluido el modo oscuro, sin tocar una linea de los componentes antiguos.
   --------------------------------------------------------------------- */
:root {
    --bg: var(--canvas);
    --bg-page: var(--canvas);
    --surface-card: var(--surface);
    --surface-2: var(--surface-raised);
    --surface-muted: var(--surface-sunken);
    --surface-strong: var(--surface-raised);

    --text-main: var(--text-strong);
    --text-primary: var(--text-strong);
    --text-secondary: var(--text-soft);
    --muted: var(--text-mute);

    --border-color: var(--line);
    --border: 1px solid var(--line);
    --border-subtle: 1px solid var(--line-soft);
    --border-tactical: 1px solid var(--line);

    --primary: var(--accent);
    --primary-hover: var(--accent-hover);
    --primary-active: var(--accent-active);
    --primary-subtle: var(--accent-subtle);
    --primary-light: var(--accent-soft);
    --primary-glow: var(--accent-glow);

    --brand: var(--accent);
    --brand-hover: var(--accent-hover);
    --brand-strong: var(--accent-active);
    --accent-ink: var(--accent-text);
    --accent-honor: var(--honor);
    --accent-insignia: var(--honor);
    --gold: var(--honor);
    --gold-light: var(--honor-soft);
    --gold-border: var(--honor-line);
    --warm: var(--warning);

    --elev-xs: var(--shadow-xs);
    --elev-1: var(--shadow-sm);
    --elev-2: var(--shadow-md);
    --elev-3: var(--shadow-lg);
    --shadow-tactical: var(--shadow-sm);
    --shadow-hover: var(--shadow-md);
    --shadow-focus: var(--ring);

    /* Neumorfismo heredado: se neutraliza en vez de borrarse, para que las
       reglas antiguas dejen de dibujar relieve sin romper la cascada. */
    --shadow-light: transparent;
    --shadow-dark: oklch(0 0 0 / var(--a-shadow-1));

    /* Huerfanos: nombres que app.css consume pero que nadie definia nunca.
       Una variable inexistente invalida la declaracion entera, asi que estos
       estilos no se estaban aplicando. Definirlos aqui los resucita. */
    /* 79 declaraciones pintan texto con --ink, que app.css define como
       #0F172A fijo: negro sobre fondo oscuro, es decir, invisible. */
    --ink: var(--text-strong);

    --c-warm: var(--warning);
    --c-warm-bg: var(--warning-soft);
    --c-warm-dark: var(--warning);
    --sv2-color-success: var(--success);
    --sv2-color-danger: var(--danger);
    --sv2-radius: var(--radius-md);
}

/* ───────────────────────────────────────────────────────────────────────
   VERTICALES · un tema = tres cifras de marca + el acento de honor
   Se aplican con [data-vertical] y los sobreescribe siempre el branding
   del administrador, que es la ultima palabra.
   --------------------------------------------------------------------- */

/* Guardia Civil — verde corporacion + dorado de tricornio */
[data-vertical="guardia-civil"] {
    --v-brand-l: 0.38; --v-brand-c: 0.065; --v-brand-h: 168;
    --v-honor-l: 0.70; --v-honor-c: 0.125; --v-honor-h: 88;
    --v-tint-c: 0.012;
}

/* Policia Nacional — azul marino + acero luminoso */
[data-vertical="policia-nacional"] {
    --v-brand-l: 0.40; --v-brand-c: 0.115; --v-brand-h: 262;
    --v-honor-l: 0.74; --v-honor-c: 0.095; --v-honor-h: 235;
    --v-tint-c: 0.013;
}

/* Ejercito / FAS — caqui de campana + arena.
   Tono desplazado al amarillo-verde para no confundirse con el verde
   corporacion de la Guardia Civil, que vive en 168. */
[data-vertical="ejercito"] {
    --v-brand-l: 0.42; --v-brand-c: 0.048; --v-brand-h: 108;
    --v-honor-l: 0.75; --v-honor-c: 0.090; --v-honor-h: 72;
    --v-tint-c: 0.016;
}

/* Policia Local — azul cobalto + lima de alta visibilidad */
[data-vertical="policia-local"] {
    --v-brand-l: 0.44; --v-brand-c: 0.135; --v-brand-h: 248;
    --v-honor-l: 0.80; --v-honor-c: 0.150; --v-honor-h: 120;
    --v-tint-c: 0.013;
}

/* Bomberos — rojo intervencion + ambar de senalizacion */
[data-vertical="bomberos"] {
    --v-brand-l: 0.46; --v-brand-c: 0.165; --v-brand-h: 28;
    --v-honor-l: 0.76; --v-honor-c: 0.145; --v-honor-h: 68;
    --v-tint-c: 0.014;
}

/* ───────────────────────────────────────────────────────────────────────
   RESPALDO SIN OKLCH
   Navegadores sin soporte (Safari < 15.4, Chrome < 111) reciben la paleta
   fija de Guardia Civil en claro. Nadie ve una pagina rota.
   --------------------------------------------------------------------- */
@supports not (color: oklch(0.5 0.1 180)) {
    :root {
        --canvas: #F4F6F8; --surface: #FFFFFF; --surface-raised: #FFFFFF;
        --surface-sunken: #F1F4F6; --surface-overlay: #FFFFFF;
        --text-strong: #0F172A; --text: #1E293B; --text-soft: #475569;
        --text-mute: #64748B; --text-faint: #94A3B8;
        --line: rgba(15, 23, 42, 0.10); --line-soft: rgba(15, 23, 42, 0.06);
        --line-strong: rgba(15, 23, 42, 0.18);
        --accent: #1B4D3E; --accent-hover: #2D6A4F; --accent-active: #14382D;
        --accent-text: #14382D; --accent-subtle: rgba(27, 77, 62, 0.08);
        --accent-soft: rgba(27, 77, 62, 0.14); --accent-glow: rgba(27, 77, 62, 0.18);
        --on-accent: #FFFFFF;
        --honor: #C59B27; --honor-text: #8A6A12; --honor-soft: rgba(197, 155, 39, 0.14);
        --honor-line: rgba(197, 155, 39, 0.32); --on-honor: #1A1A1A;
        --success: #17794F; --warning: #B45309; --danger: #DC2626; --info: #0369A1;
        --success-soft: rgba(23, 121, 79, 0.12); --warning-soft: rgba(180, 83, 9, 0.12);
        --danger-soft: rgba(220, 38, 38, 0.12); --info-soft: rgba(3, 105, 161, 0.12);
        --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
        --scrim: rgba(15, 23, 42, 0.68);
    }
}

/* ───────────────────────────────────────────────────────────────────────
   ACCESIBILIDAD TRANSVERSAL
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    :root { --duration-fast: 1ms; --duration: 1ms; --duration-slow: 1ms; }
    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
}

@media (prefers-contrast: more) {
    :root {
        --a-line: 0.28; --a-line-soft: 0.18; --a-line-strong: 0.42;
        --l-text-soft: 0.38; --l-text-mute: 0.44; --l-text-faint: 0.52;
    }
    :root[data-theme="dark"] {
        --l-text-soft: 0.86; --l-text-mute: 0.78; --l-text-faint: 0.70;
    }
}

/* ───────────────────────────────────────────────────────────────────────
   CORRECCIONES DE BASE
   Primer trozo de la migracion de los 467 colores literales de app.css.
   Aqui solo entra lo que, sin corregir, deja el modo oscuro inservible.
   --------------------------------------------------------------------- */

/* app.css (linea ~2395) pinta el body con un degradado crema fijo que gana
   por orden de carga. En oscuro dejaba texto claro sobre fondo crema, es
   decir, ilegible. Se conserva el mismo gesto —halo de marca arriba a la
   izquierda, halo calido a la derecha— pero en tokens, asi que ahora sigue
   al tema y al color del administrador. */
body {
    background:
        radial-gradient(95% 75% at 6% 0%, var(--accent-glow), transparent 58%),
        radial-gradient(75% 65% at 100% 6%, var(--honor-soft), transparent 52%),
        var(--canvas);
    background-attachment: fixed;
}

/* Las opciones del asistente de test habian perdido su caja. app.css:3722
   les pone borde, pero app.css:8530 vuelve a declarar la misma clase con
   border:0 y gana por orden de aparicion. Sin borde, lo unico que las
   delimitaba era un fondo al 72 % de --surface, que en claro apenas se
   distinguia y sobre oscuro es practicamente el fondo. Resultado: solo se
   veia la opcion elegida y las demas flotaban como texto suelto.
   El estado activo, ademas, estaba escrito en un teal fijo
   rgba(14, 116, 144, ...) que no tenia nada que ver con la marca.

   Aqui las opciones son eleccion, no logro, asi que van en verde: el
   dorado se reserva a donde estas y a lo que has conseguido. */
.sv2-test-build-chip {
    border: 1px solid var(--line);
    background: var(--surface-raised);
    color: var(--text-soft);
    transition: border-color var(--duration-fast) var(--ease),
                box-shadow var(--duration-fast) var(--ease),
                color var(--duration-fast) var(--ease);
}

.sv2-test-build-chip:hover {
    border-color: var(--accent-soft);
    background: var(--surface-raised);
    color: var(--text-strong);
}

.sv2-test-build-chip.is-active {
    border-color: var(--accent);
    background: var(--accent-subtle);
    color: var(--accent-text);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.sv2-test-build-chip--card strong { color: var(--text-strong); }
.sv2-test-build-chip--card span { color: var(--text-mute); }
.sv2-test-build-chip--card.is-active strong { color: var(--accent-text); }

/* ───────────────────────────────────────────────────────────────────────
   SALTAR AL CONTENIDO
   Invisible hasta que recibe el foco. Es lo primero que encuentra quien
   navega con teclado, y le ahorra recorrer la barra lateral entera en
   cada pagina.
   --------------------------------------------------------------------- */
.skip-link {
    position: absolute;
    left: var(--sp-4);
    top: -100px;
    z-index: 999;
    padding: var(--sp-3) var(--sp-5);
    border-radius: var(--radius-md);
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--shadow-lg);
    transition: top var(--duration) var(--ease);
}
.skip-link:focus {
    top: var(--sp-4);
}

/* El contenido principal recibe foco al saltar, pero sin dibujar anillo:
   el usuario no lo ha enfocado, lo ha alcanzado. */
.app-content:focus { outline: none; /* a11y-ok: foco programatico, no del usuario */ }

/* ───────────────────────────────────────────────────────────────────────
   ACENTOS DE LOGRO
   Reparto de papeles, y es lo que da vida sin perder jerarquia:
     verde  → estructura y accion. Lo que se pulsa.
     dorado → logro, progreso y posicion. Donde estas y que has conseguido.
   El dorado no decora nunca: si aparece, significa algo. Por eso lo lleva
   el elemento activo —que es uno solo por zona— y no todas las tarjetas.
   --------------------------------------------------------------------- */

/* Donde estas: el elemento activo se rellena.
   Corrige ademas el rgba(27, 77, 62, 0.10) literal que traia
   design-fidelity.css, un verde fijo que ignoraba la marca del inquilino:
   en un tema de Policia la navegacion activa salia verde igualmente. */
.sidebar-nav-item.is-active {
    background-color: var(--honor);
    color: var(--on-honor);
    font-weight: 700;
    box-shadow: 0 4px 14px var(--honor-soft);
}
.sidebar-nav-item.is-active .sidebar-nav-icon { opacity: 1; }
.sidebar-nav-item.is-active .sidebar-badge {
    background: var(--on-honor);
    color: var(--honor);
}

/* Lo que has conseguido: las cifras del escritorio.
   Se usa --honor-text, no --honor, porque en claro el dorado plano sobre
   blanco se queda corto de contraste. */
.home-chip-value { color: var(--honor-text); }

/* Lo que llevas avanzado */
.progress-bar-fill {
    background: linear-gradient(90deg, var(--accent), var(--honor) 85%);
    box-shadow: 0 0 14px var(--honor-soft);
}

/* Relieve: en oscuro la tarjeta se separa del fondo; en claro no cambia
   nada, porque alli --surface y --surface-raised son el mismo blanco. */
.card,
.neu-raised,
.neu-raised-lg,
.test-hub-panel {
    background: linear-gradient(180deg, var(--surface-raised), var(--surface));
}

/* Filo dorado solo en las piezas de cabecera. Si lo llevaran todas las
   tarjetas volveria a no significar nada, que es justo lo que le pasa a
   la referencia que sirvio de punto de partida. */
.neu-raised-lg {
    border-top: 2px solid var(--honor-line);
}

/* Las cifras del escritorio son dato conseguido, asi que su tarjeta va
   enmarcada entera en el tono de honor y no solo por arriba. */
.home-chip {
    border: 1px solid color-mix(in oklab, var(--honor) 45%, transparent);
}

/* ── Accesos del escritorio ──
   Las clases tone-* de app.css daban a cada azulejo un color distinto y la
   fila quedaba desigual: cuatro atajos equivalentes con tres aspectos. Van
   todos en el tono de honor, que es el que marca ya la navegacion activa:
   dorado para moverse y para lo conseguido, marca para lo que se acciona.

   Se respetan tone-warning y tone-danger: ahi el color no decora, avisa de
   que hay mensajes sin leer o algo que falla. */
.home-action-icon svg,
.home-mgmt-icon svg { width: 20px; height: 20px; }

.home-action:not(.tone-warning):not(.tone-danger) .home-action-icon,
.home-action.tone-primary .home-action-icon,
.home-action.tone-accent .home-action-icon,
.home-action.tone-neutral .home-action-icon,
.home-mgmt-card .home-mgmt-icon {
    background: var(--honor-soft);
    color: var(--honor-text);
    border: 1px solid var(--honor-line);
}

/* ── Las cifras son logro, en todas las pantallas y no solo en el
   escritorio. Se dejan fuera las que llevan modificador semantico, donde
   el color dice que algo va mal o esta pendiente. ── */
.home-chip-value,
.sv2-mgmt-hero-stat-value:not(.is-danger):not(.is-warm),
.sv2-perfil-hero-stat-value,
.sv2-progress-hero-stat-value,
.sv2-study-admin-stat-value,
.sv2-test-selector-stat-value {
    color: var(--honor-text);
}

/* El badge no se encaramaba al titulo por estar mal colocado: el bloque de
   texto, con flex-basis 0 y min-width 0, se encogia hasta 22 px en una
   tarjeta de 226 y el texto se desbordaba por encima. Con un minimo que
   respetar, el badge baja a su linea cuando no cabe. */
.home-action {
    flex-wrap: wrap;
    row-gap: var(--sp-2);
}
.home-action-text {
    min-width: 7rem;
}
.home-action-badge {
    align-self: flex-start;
    white-space: nowrap;
}

/* ───────────────────────────────────────────────────────────────────────
   GESTION · pestanas
   El panel es largo y el menu de anclas obligaba a subir y bajar. Con las
   pestanas solo se pinta la seccion abierta. La clase la pone el script, de
   modo que sin JavaScript no se oculta nada.
   --------------------------------------------------------------------- */
.sv2-mgmt-tabbed .sv2-mgmt-section[hidden] { display: none; }

.sv2-mgmt-nav-item[aria-selected="true"],
.sv2-mgmt-nav-item.is-active {
    background: var(--accent-subtle);
    border-color: var(--accent);
    color: var(--accent-text);
    font-weight: 700;
}
.sv2-mgmt-nav-item[role="tab"] { cursor: pointer; }
.sv2-mgmt-nav-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Los iconos de las pestanas y de la bandeja eran emoji, y app.css los
   dimensionaba con font-size porque eran texto. Ahora son SVG de trazo, que
   heredan el color con currentColor: en la pestana activa el icono se tine
   del color de la marca junto al texto, que es lo que un emoji no podia
   hacer. Se les da medida aqui, no en app.css, para no rehacer el minificado. */
.sv2-mgmt-nav-icon {
    display: inline-flex;
    width: 16px;
    height: 16px;
    flex: none;
}
.sv2-mgmt-nav-icon svg,
.sv2-mgmt-inbox-tab > svg,
.sv2-mgmt-head-actions .btn > svg {
    width: 16px;
    height: 16px;
    flex: none;
}

/* ───────────────────────────────────────────────────────────────────────
   TUTOR IA Y ASESOR DE IMPUGNACIONES · iconos de linea
   Los emoji del modal convivian con los SVG que ya usaba el resto de la
   pantalla de test, cada uno con su dibujo y su paleta. Los contenedores
   ya eran flex con su hueco, asi que aqui solo se da medida. Los iconos
   que caen dentro de una linea de texto se alinean con vertical-align y
   no con flex, para que el parrafo siga fluyendo y parta linea.
   --------------------------------------------------------------------- */
.sv2-preview-bar-label { display: inline-flex; align-items: center; gap: 6px; }
.sv2-preview-bar-label svg { width: 16px; height: 16px; flex: none; }

.sv2-ai-badge-icon svg { width: 24px; height: 24px; }
/* Las pildoras de la cabecera miden 22 px de alto: un SVG sin medida se
   estira hasta desbordarlas, que es lo que hacia el icono del motor. */
.sv2-ai-meta-pills .badge svg { width: 13px; height: 13px; flex: none; }
.sv2-ai-block-icon,
.sv2-ai-error-icon { display: inline-flex; align-items: center; }
.sv2-ai-block-icon svg { width: 18px; height: 18px; }
.sv2-ai-error-icon svg { width: 20px; height: 20px; }
.sv2-ai-close svg { width: 16px; height: 16px; }
.sv2-ai-explain-btn svg,
.sv2-ai-footer-actions .btn svg { width: 15px; height: 15px; flex: none; }

.sv2-debate-block h5 { display: flex; align-items: center; gap: 6px; }
.sv2-debate-block h5 svg,
.sv2-debate-badge svg { width: 15px; height: 15px; flex: none; }
.sv2-debate-trigger-btn svg,
.sv2-debate-submit-btn svg { width: 16px; height: 16px; flex: none; }

.sv2-ai-summary-bar svg,
.sv2-debate-resolved p svg {
    width: 15px;
    height: 15px;
    vertical-align: -3px;
    margin-right: 5px;
}

/* ───────────────────────────────────────────────────────────────────────
   LOGIN · ayuda, legales y mostrar contrasena
   --------------------------------------------------------------------- */
/* Aqui el dorado no marca logro, porque todavia no hay nada conseguido:
   da calor a una pantalla que si no es verde sobre verde. Va en el filo de
   la tarjeta, en la marca y en los iconos de ayuda, nunca en el boton de
   entrar, que es la accion y se queda en verde. */
.login-card { border-top: 2px solid var(--honor-line); }

.login-brand-icon {
    background: var(--honor-soft);
    border: 1px solid var(--honor-line);
    color: var(--honor-text);
}

/* La rejilla del login dimensionaba su columna al contenido, asi que un
   correo de soporte largo la empujaba hasta 344 px dentro de una ventana de
   320 y la pagina acababa con scroll horizontal (WCAG 1.4.10). Con una
   columna que puede encoger, la tarjeta se adapta. */
.login-screen {
    grid-template-columns: minmax(0, 420px);
    justify-content: center;
}

/* El acceso no comparte cabecera con la app, asi que el conmutador de tema
   va aqui. Flotando en la esquina pisaba la esquina superior derecha de la
   tarjeta -- a 320 px entero, pero tambien un poco en escritorio -- asi que
   va en el flujo, como primera fila de la rejilla y alineado con el borde
   derecho de la tarjeta. */
.login-theme-switch {
    display: flex;
    justify-content: flex-end;
    /* La rejilla centra sus hijos: sin esto el contenedor se encoge al
       tamano del grupo y queda centrado en vez de a la derecha. */
    justify-self: stretch;
    width: 100%;
    margin-bottom: var(--sp-3);
}

/* Puede caer sobre la imagen de fondo que sube el cliente: el grupo ya es
   opaco, la sombra es para que no se pegue a una foto clara. */
.login-theme-switch .theme-switch {
    box-shadow: var(--shadow-md);
}

/* Y que un correo largo parta linea en vez de estirar la tarjeta.
   break-word y no anywhere: anywhere corta por cualquier letra y dejaba
   'WhatsApp' como 'What sApp' en pantallas estrechas. Con break-word solo
   parte la palabra que de verdad no cabe. */
.login-support-item {
    min-width: 0;
    overflow-wrap: break-word;
    flex-wrap: wrap;
}

.login-input-wrap { position: relative; display: block; }
.login-input-wrap .login-input { width: 100%; padding-right: 48px; }

.login-reveal {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border: none;
    background: transparent;
    border-radius: var(--radius-sm);
    color: var(--text-mute);
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease),
                background var(--duration-fast) var(--ease);
}
.login-reveal svg { width: 19px; height: 19px; }
.login-reveal:hover { color: var(--text-strong); background: var(--surface-sunken); }
.login-reveal[aria-pressed="true"] { color: var(--accent-text); }
.login-reveal:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.login-forgot {
    display: block;
    margin-top: var(--sp-2);
    text-align: right;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent-text);
    text-decoration: none;
}
.login-forgot:hover { text-decoration: underline; text-underline-offset: 3px; }

.login-support {
    margin-top: var(--sp-6);
    padding-top: var(--sp-5);
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}
.login-support-title { color: var(--text-mute); margin-bottom: var(--sp-1); }

.login-support-item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    min-height: 46px;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface-raised);
    color: var(--text-soft);
    font-size: var(--text-sm);
    text-decoration: none;
    transition: border-color var(--duration-fast) var(--ease),
                color var(--duration-fast) var(--ease);
}
.login-support-item svg { width: 19px; height: 19px; flex: none; color: var(--honor-text); }
.login-support-item strong { color: var(--text-strong); font-weight: 700; }
.login-support-item:hover { border-color: var(--honor-line); color: var(--text-strong); }
.login-support-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.login-legal {
    margin: var(--sp-5) 0 0;
    text-align: center;
    font-size: var(--text-xs);
    color: var(--text-faint);
}
.login-legal a { color: var(--text-mute); text-decoration: none; }
.login-legal a:hover { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }

/* ───────────────────────────────────────────────────────────────────────
   CONMUTADOR DE TEMA
   Unico componente que vive en este archivo, porque es la interfaz de lo
   que este archivo hace. Tres estados explicitos (claro / automatico /
   oscuro) en vez de un interruptor de dos, para que "seguir al sistema"
   sea una opcion visible y no un estado oculto.
   --------------------------------------------------------------------- */
.theme-switch {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: var(--radius-md);
    background: var(--surface-sunken);
    border: 1px solid var(--line-soft);
}

.theme-switch-btn {
    display: grid;
    place-items: center;
    width: 32px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-mute);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease),
                color var(--duration-fast) var(--ease);
}

.theme-switch-btn svg { width: 16px; height: 16px; }
.theme-switch-btn:hover { color: var(--text-strong); }

.theme-switch-btn[aria-pressed="true"] {
    background: var(--surface);
    color: var(--accent-text);
    box-shadow: var(--shadow-xs);
}

.theme-switch-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* En movil el conmutador se va a Perfil: en la cabecera compite con el
   titulo de la pagina y pierde el titulo, que importa mas. */
@media (max-width: 680px) {
    .app-topbar .theme-switch { display: none; }
}
