/*
 * Link3rs Backstage - Design System v3
 * Dark theme with glassmorphism inspired by Apple/Notion
 */

/* ============================================
   ROOT VARIABLES
   ============================================ */

:root {
    /* Background colors */
    --bg-primary: #050505;
    --bg-panel: rgba(12, 12, 12, 0.85);
    --bg-panel-solid: #0c0c0c;
    --bg-sidebar: #000000;

    /* Gray scale */
    --gray-950: #0a0a0a;
    --gray-900: #111111;
    --gray-800: #1a1a1a;
    --gray-700: #2a2a2a;
    --gray-600: #3a3a3a;
    --gray-500: #555555;
    --gray-400: #777777;
    --gray-300: #999999;
    --gray-200: #bbbbbb;
    --gray-100: #dddddd;
    --white: #ffffff;

    /* Borders */
    --border-subtle: rgba(255, 255, 255, 0.08);
    --border-hover: rgba(255, 255, 255, 0.15);
    --border-active: rgba(255, 255, 255, 0.2);

    /* Frosted glass (Hector's reference): absolutely NO border. A bright TOP + LEFT edge highlight,
       a soft inner frost glow, and a drop shadow do all the work — all baked into one box-shadow so it
       applies anywhere and follows the border-radius. Dark, slightly-transparent base keeps light text
       readable while the backdrop blur lets the background through like real glass. */
    /* ⚠ 2026-10-31: EL CRISTAL LÍQUIDO DE LINK3RS.COM («Link3rs — UI design code», §5), en
       oscuro, que es como va Backstage. Fondo translúcido, lo de detrás desenfocado y SATURADO,
       un canto de luz (las dos insets) y sombras en capas. Theme.applyGlass() lo reescribe con
       los ajustes de Behaviour → Design; si se cambia aquí, se cambia allí. */
    --glass-bg: rgb(22 22 23 / 0.72);
    --glass-bg-strong: rgb(22 22 23 / 0.82);
    --glass-blur: saturate(180%) blur(20px);
    --glass-highlight: rgba(255, 255, 255, 0.12);
    --glass-ring: transparent;   /* kept for back-compat; no ring/border anywhere */
    --glass-shadow:
        inset 0 1px 0 rgb(255 255 255 / 0.12),
        inset 0 0 0 0.5px rgb(255 255 255 / 0.1),
        0 0 0 0.5px rgb(0 0 0 / 0.08),
        0 12px 32px -8px rgb(0 0 0 / 0.18),
        0 2px 6px rgb(0 0 0 / 0.05);

    /* Lo demás del sistema de link3rs.com: color de acción, radios y los TRES muelles. Todo lo
       que se mueve usa uno de los tres (§6); colores y opacidad, 0,2 s. */
    --c-cta: #0096ff;
    --c-cta-hover: #007acc;
    --c-blue: #0081fe;
    --c-blue-ink: #2997ff;
    --radius-s: 12px;
    --radius-m: 20px;
    --radius-l: 28px;
    --spring-liquid: linear(0, 0.0575, 0.1779, 0.3246, 0.4734, 0.6081, 0.7225, 0.8148, 0.8853, 0.936, 0.9713, 0.9945,
        1.0082, 1.0151, 1.0177, 1.0176, 1.0158, 1.0132, 1.0105, 1.008, 1.0058, 1.004, 1.0025, 1.0015, 1.0007, 1.0002,
        0.9999, 1);
    --spring-liquid-dur: 780ms;
    --spring-liquid-fast: linear(0, 0.0859, 0.2578, 0.4547, 0.6386, 0.787, 0.8971, 0.9715, 1.0154, 1.0362, 1.0426,
        1.0401, 1.033, 1.0245, 1.0165, 1.0099, 1.0049, 1.0016, 0.9996, 0.9985, 0.9982, 0.9983, 0.9985, 0.9989, 0.9992,
        0.9995, 0.9998, 1);
    --spring-liquid-fast-dur: 780ms;
    --spring-close: linear(0, 0.0556, 0.167, 0.2952, 0.4201, 0.5321, 0.628, 0.7075, 0.772, 0.8234, 0.864, 0.8958,
        0.9204, 0.9394, 0.9539, 0.9651, 1);
    --spring-close-dur: 270ms;
    --content-in: 260ms cubic-bezier(0.22, 1, 0.36, 1);

    /* Functional colors */
    --success: #22c55e;
    --warning: #f59e0b;
    --error: #ef4444;
    --info: #3b82f6;
    --streaming: #3b82f6;
    
    /* Typography */
    /* La de link3rs.com: SF Pro en Apple; en lo demás, Helvetica Neue. NUNCA Segoe UI ni Roboto (§3). */
    --font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', 'Link3rs Helvetica', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    --font-mono: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', monospace;
    
    /* Sizing */
    --sidebar-width: 240px;
    --header-height: 64px;
    --border-radius: 12px;
    --border-radius-lg: 24px;
    --border-radius-sm: 8px;
    
    /* Transitions */
    --transition: all 0.4s cubic-bezier(0.25, 0.1, 0.25, 1);
    --transition-fast: all 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* ============================================
   RESET & BASE
   ============================================ */

*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 16px;
    /* ⚠ SIN ESTO, SAFARI DE iOS AGRANDA EL TEXTO AL GIRAR EL TELÉFONO. La maqueta es la
       misma y la letra, más grande: los textos se salen de sus cajas y se montan unos en
       otros. Con 100 % la letra mide lo que dice la hoja y el zoom con dos dedos sigue
       funcionando (no es `none`). Lo mide `test_el_movil_se_navega_sin_solapes.py`. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-family);
    background: var(--bg-primary);
    color: var(--gray-300);
    line-height: 1.5;
    /* ⚠ EN iOS `100vh` ES EL VIEWPORT GRANDE (con las barras de Safari escondidas), no el
       que se ve: una pantalla con poco contenido quedaba ~145 px más alta que la pantalla y
       se movía al tocarla sin nada que enseñar. `svh` es lo que se ve con las barras
       puestas; la línea de `vh` queda delante para quien no entienda `svh`. Los tres altos
       (body, .app-layout, .main-content) van juntos: basta uno en `vh` para que el
       antepasado estire a los demás. */
    min-height: 100vh;
    min-height: 100svh;
    overflow-x: hidden;
}

/* ============================================
   LIGHT RAYS BACKGROUND
   ============================================ */

.rays-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

.ray {
    position: absolute;
    top: -20%;
    transform-origin: top center;
    background: linear-gradient(
        to bottom,
        rgba(220, 220, 220, 0.4) 0%,
        rgba(200, 200, 200, 0.25) 20%,
        rgba(180, 180, 180, 0.15) 40%,
        rgba(150, 150, 150, 0.08) 60%,
        rgba(120, 120, 120, 0.02) 80%,
        transparent 100%
    );
    filter: blur(8px);
    pointer-events: none;
}

.ray-1 { left: 70%; width: 120px; height: 140%; transform: rotate(-25deg); animation: sway1 8s ease-in-out infinite, pulse1 6s ease-in-out infinite; opacity: 0.9; }
.ray-2 { left: 73%; width: 180px; height: 150%; transform: rotate(-15deg); animation: sway2 10s ease-in-out infinite, pulse2 7s ease-in-out infinite; opacity: 0.85; }
.ray-3 { left: 76%; width: 100px; height: 130%; transform: rotate(-5deg); animation: sway3 9s ease-in-out infinite, pulse3 8s ease-in-out infinite; opacity: 0.8; }
.ray-4 { left: 74%; width: 200px; height: 145%; transform: rotate(5deg); animation: sway4 11s ease-in-out infinite, pulse4 9s ease-in-out infinite; opacity: 0.9; }
.ray-5 { left: 72%; width: 90px; height: 125%; transform: rotate(15deg); animation: sway5 7s ease-in-out infinite, pulse5 6.5s ease-in-out infinite; opacity: 0.75; }
.ray-6 { left: 78%; width: 150px; height: 155%; transform: rotate(25deg); animation: sway6 12s ease-in-out infinite, pulse6 8.5s ease-in-out infinite; opacity: 0.85; }

.ray-bg-1 { left: 65%; width: 300px; height: 160%; transform: rotate(-20deg); animation: swayBg1 14s ease-in-out infinite; opacity: 0.4; filter: blur(25px); background: linear-gradient(to bottom, rgba(200, 200, 200, 0.2) 0%, rgba(180, 180, 180, 0.12) 30%, rgba(150, 150, 150, 0.05) 60%, transparent 100%); }
.ray-bg-2 { left: 72%; width: 350px; height: 165%; transform: rotate(10deg); animation: swayBg2 16s ease-in-out infinite; opacity: 0.35; filter: blur(30px); background: linear-gradient(to bottom, rgba(200, 200, 200, 0.18) 0%, rgba(180, 180, 180, 0.1) 30%, rgba(150, 150, 150, 0.04) 60%, transparent 100%); }

@keyframes sway1 { 0%, 100% { transform: rotate(-25deg) translateX(0); } 50% { transform: rotate(-23deg) translateX(10px); } }
@keyframes sway2 { 0%, 100% { transform: rotate(-15deg) translateX(0); } 50% { transform: rotate(-12deg) translateX(-15px); } }
@keyframes sway3 { 0%, 100% { transform: rotate(-5deg) translateX(0); } 50% { transform: rotate(-3deg) translateX(8px); } }
@keyframes sway4 { 0%, 100% { transform: rotate(5deg) translateX(0); } 50% { transform: rotate(8deg) translateX(-12px); } }
@keyframes sway5 { 0%, 100% { transform: rotate(15deg) translateX(0); } 50% { transform: rotate(18deg) translateX(10px); } }
@keyframes sway6 { 0%, 100% { transform: rotate(25deg) translateX(0); } 50% { transform: rotate(22deg) translateX(-8px); } }
@keyframes swayBg1 { 0%, 100% { transform: rotate(-20deg) translateX(0); } 50% { transform: rotate(-17deg) translateX(20px); } }
@keyframes swayBg2 { 0%, 100% { transform: rotate(10deg) translateX(0); } 50% { transform: rotate(13deg) translateX(-25px); } }
@keyframes pulse1 { 0%, 100% { opacity: 0.9; } 50% { opacity: 0.7; } }
@keyframes pulse2 { 0%, 100% { opacity: 0.85; } 50% { opacity: 0.65; } }
@keyframes pulse3 { 0%, 100% { opacity: 0.8; } 50% { opacity: 0.6; } }
@keyframes pulse4 { 0%, 100% { opacity: 0.9; } 50% { opacity: 0.75; } }
@keyframes pulse5 { 0%, 100% { opacity: 0.75; } 50% { opacity: 0.55; } }
@keyframes pulse6 { 0%, 100% { opacity: 0.85; } 50% { opacity: 0.7; } }

.light-source {
    position: fixed;
    top: -15%;
    left: 75%;
    transform: translateX(-50%);
    width: 600px;
    height: 400px;
    background: radial-gradient(ellipse at center, rgba(230, 230, 230, 0.25) 0%, rgba(200, 200, 200, 0.15) 30%, rgba(180, 180, 180, 0.08) 50%, rgba(150, 150, 150, 0.03) 70%, transparent 100%);
    filter: blur(40px);
    pointer-events: none;
    animation: glowPulse 10s ease-in-out infinite;
    z-index: 0;
}

@keyframes glowPulse { 0%, 100% { opacity: 1; transform: translateX(-50%) scale(1); } 50% { opacity: 0.85; transform: translateX(-50%) scale(1.05); } }

.atmosphere {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    background: radial-gradient(ellipse 100% 80% at 75% 0%, rgba(200, 200, 200, 0.06) 0%, transparent 60%);
    z-index: 0;
}

.vignette {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    background: radial-gradient(ellipse at center, transparent 50%, rgba(5, 5, 5, 0.5) 100%);
    z-index: 0;
}

/* ============================================
   LAYOUT
   ============================================ */

.app-layout {
    display: flex;
    min-height: 100vh;
    min-height: 100svh;     /* ver `body` */
    position: relative;
    z-index: 1;
}

/* ============================================
   SIDEBAR
   ============================================ */

/* ══════════════════════════════════════════════════════════════════════════
   NL-1 · EL CAMBIO DE PÁGINA NO PUEDE PASAR POR NEGRO
   ══════════════════════════════════════════════════════════════════════════
   Aquí no hay SPA: cada entrada del menú es una navegación de verdad. El
   navegador destruye la página, pinta el fondo oscuro del documento nuevo y
   deja ese hueco hasta que hay contenido. Eso es el «fundido a negro y luego
   se recarga»: no había NINGUNA transición de página en todo el producto.

   Con esto el navegador mantiene el fotograma de la página vieja hasta que la
   nueva puede pintar, y funde una con otra. Cuesta cero JavaScript.

   ⚠ ESTO SÓLO ES BUENA IDEA PORQUE EL MENÚ SE PINTA SÍNCRONO DESDE LA CACHÉ.
     `Sidebar.render` corre DESPUÉS de `await Auth.requireAuth()` —una ida y
     vuelta a la red—, así que sin el arranque instantáneo el primer fotograma
     del documento nuevo no tiene menú: la transición fotografiaría el hueco y
     se vería el menú DESVANECERSE, que es peor que lo que se viene a quitar.

   ⚠ Y por eso el menú va con nombre propio: sin él entra en la foto de la
     página entera y se funde con ella. Con nombre, el navegador lo trata como
     el MISMO elemento a los dos lados y se queda quieto mientras el contenido
     cambia — que es como se lee «he cambiado de sección», y no «he recargado».

   En un navegador que no lo soporte no pasa nada: se ignora y queda como
   estaba. */
@view-transition { navigation: auto; }

.sidebar { view-transition-name: menu-lateral; }
/* La cabecera tampoco parpadea: es la misma en todas las páginas. */
.sidebar-header { view-transition-name: menu-cabecera; }

/* Quien pide menos movimiento se queda sin el fundido, no sin la navegación.
   ⚠ Va con `animation-duration` y no con `@view-transition { navigation: none }`
     a propósito: la segunda forma es más nueva y donde no se entienda se
     ignora en silencio, dejando el movimiento puesto justo a quien pidió que
     no lo hubiera. */
@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) { animation-duration: .01ms !important; }
}

.sidebar {
    width: var(--sidebar-width);
    background: var(--bg-sidebar);
    border-right: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 100;
}

.sidebar-header {
    padding: 26px 16px 10px;
    flex-shrink: 0;
}

.sidebar-logo {
    display: block;
    height: 72px;
}

/* ⚠ EL LOGO NO PUEDE SER MÁS ANCHO QUE EL MENÚ. El del tema claro es otro dibujo, mucho
   más apaisado (1498×286): a 72 px de alto salía de 377 px dentro de un menú de 240 y se
   pintaba ENCIMA del título de todas las páginas. Con `max-width` la caja no pasa del ancho
   de la cabecera y `contain` encoge el dibujo entero dentro, pegado a la izquierda como
   el del tema oscuro (que a 190 px ya cabía y no cambia). */
.sidebar-logo img {
    height: 100%;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    object-position: left center;
}
.sidebar-logo .logo-light {
    display: none;
}
[data-theme="light"] .sidebar-logo .logo-dark {
    display: none;
}
[data-theme="light"] .sidebar-logo .logo-light {
    display: block;
    height: 100%;
    width: auto;
    max-width: 100%;        /* ver `.sidebar-logo img` */
    object-fit: contain;
    object-position: left center;
}

.sidebar-nav {
    flex: 1;
    min-height: 0;
    padding: 22px 8px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    /* ⚠ ESTO ARREGLA EL ENCOGIMIENTO DEL MENÚ, y la causa no estaba en el
       submenú. Los `.nav-item` son `width:100%` de ESTA caja; al abrirse el
       submenú la lista crece, aparece la barra de desplazamiento, y el 100%
       pasa a valer 4px menos: el menú entero se estrecha de golpe. Reservando
       el carril SIEMPRE, el ancho no depende de cuánto haya dentro.
       Se reserva 4px —lo que mide la barra de aquí abajo—, así que no se ve. */
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}

.sidebar-nav::-webkit-scrollbar {
    width: 4px;
}

.sidebar-nav::-webkit-scrollbar-track {
    background: transparent;
}

.sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.15);
    border-radius: 4px;
}

[data-theme="light"] .sidebar-nav {
    scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
}

[data-theme="light"] .sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.15);
}

/* ── SUBMENÚ del menú lateral ─────────────────────────────────────────────
   Sólo se pinta cuando su sección está abierta (lo decide sidebar.js). Va
   sangrado a la derecha para que se lea como lo que es: algo que cuelga del
   item de arriba y no una opción más del mismo nivel.

   ⚠ Sin sangrar, un submenú de dos elementos se confunde con dos secciones
     nuevas, y el menú pasa a tener doce cosas donde diez no vienen a cuento. */
/* El GRUPO: la sección abierta y sus hijos se leen como UNA cosa. Sin este
   fondo, Agenda y Archive parecían dos opciones sueltas y no «esto también es
   Events». */
.nav-group.abierto {
    background: var(--bg-hover, rgba(255,255,255,.04));
    /* ⚠ SIN MARGEN A LOS LADOS, Y ÉSTE ERA EL ENCOGIMIENTO DEL ANCHO.
       MEDIDO: con `margin: 2px 8px 4px` la fila de Events pasaba de 193px a
       177px al abrirse la sección, y se corría 8px a la derecha — porque los
       `.nav-item` son `width:100%` de ESTA caja, y la caja se metía 8px por
       cada lado. Al seleccionar Events el renglón se estrechaba delante de ti
       sin que nada explicara por qué.
       El fondo del grupo ocupa ahora lo mismo que ocupa un item cualquiera,
       que es lo que hace que el menú no se mueva. */
    border-radius: 12px; margin: 2px 0 4px; padding: 2px 0 4px;
}
.nav-group.abierto > .nav-cab > .nav-item { margin-left: 0; margin-right: 0; }
/* ⚠ El padre, estando en un hijo, es la CABECERA del grupo — no el elemento
   seleccionado. Con el mismo realce que el hijo no se distingue en cuál estás. */
.nav-group.abierto > .nav-cab > .nav-item.en-grupo { background: transparent; }
.nav-group.abierto > .nav-cab > .nav-item.en-grupo:hover { background: var(--bg-hover, rgba(255,255,255,.06)); }

/* ⚠ EL HUECO DE ARRIBA VA EN EL PRIMER HIJO, y no en esta caja. MEDIDO, y en
   dos pasos: con `margin-top: 2px` aquí el submenú cerrado medía 2px —el
   margen de la fila queda FUERA de lo que recorta la rejilla—, y pasarlo a
   `padding-top` NO lo arregló: con la fila a `0fr` el relleno del propio
   elemento también suma. La sección cerrada quedaba 2px más alta que
   cualquier otra del menú (43 contra 41). En el hijo sí se recorta: 0. */
.nav-sub { display: flex; flex-direction: column; gap: 1px; margin: 0;
    /* el raíl: dice de dónde cuelgan estos dos */
    border-left: 1.5px solid var(--border-subtle); margin-left: 26px; padding-left: 4px; }
/* ⚠ MISMO TAMAÑO QUE UNA SECCIÓN DE ARRIBA: letra, icono, hueco y alto.
   Lo pidió Hector el 2026-09-03 — «desplazados a la derecha sí, pero igual en
   tamaño». Un submenú más pequeño dice «esto es de segunda», y Agenda y
   Archive son sitios tan de primera como Streaming; lo único que los hace
   hijos es DÓNDE están, no cómo de grandes son. La jerarquía la lleva entera
   la sangría y el raíl de la izquierda. */
.nav-subitem {
    display: flex; align-items: center; gap: 12px;   /* = .nav-item */
    padding: 10px 12px;                              /* = .nav-item */
    margin: 0 6px; border-radius: 8px;
    font-size: 14px; font-weight: 500;               /* = .nav-item */
    color: var(--text-secondary); text-decoration: none;
    transition: background .15s ease, color .15s ease;
}
.nav-sub > .nav-subitem:first-child { margin-top: 2px; }
.nav-subitem svg { width: 20px; height: 20px; flex: none; opacity: .85; }
.nav-subitem:hover { background: var(--bg-hover, rgba(255,255,255,.06)); color: var(--text-primary); }
.nav-subitem.active { background: var(--bg-active, rgba(255,255,255,.10)); color: var(--text-primary); }
.nav-subitem.active svg { opacity: 1; }

/* ── LA CABECERA DEL GRUPO · el enlace y la flecha en la misma línea ───────
   ⚠ La flecha es HERMANA del enlace, no hija. Un `<button>` dentro de un `<a>`
     es HTML inválido —contenido interactivo anidado— y el navegador lo
     reordena: acabas con el botón FUERA del enlace y la flecha suelta debajo
     del menú. Por eso hay `.nav-cab` y no un span dentro del `<a>`. */
.nav-cab { display: flex; align-items: center; }
/* `.nav-item` es `width:100%`; dentro de la cabecera manda el flex. */
.nav-cab > .nav-item { flex: 1 1 auto; width: auto; min-width: 0; }

.nav-chevron {
    flex: none;
    display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; margin-right: 4px;
    padding: 0; border: none; background: none; cursor: pointer;
    color: var(--gray-400); opacity: .55;
    border-radius: 7px;
    transition: opacity .15s ease, background .15s ease, color .15s ease;
}
.nav-chevron:hover { opacity: 1; background: rgba(255,255,255,.08); color: var(--gray-200); }
[data-theme="light"] .nav-chevron:hover { background: rgba(0,0,0,.06); }
.nav-chevron:focus-visible { outline: 2px solid var(--brand, #6ea8fe); outline-offset: 1px; opacity: 1; }
.nav-chevron svg { width: 14px; height: 14px; }
/* Con el dedo, 26 px no se aciertan: la flecha es el ÚNICO sitio que abre Agenda y Archive
   sin salir de la página. En pantallas táctiles el botón mide 40×40 (el dibujo, igual). */
@media (pointer: coarse) {
    .nav-chevron { width: 40px; height: 40px; margin-right: 2px; }
}
/* NL-4 · abajo cerrado, arriba abierto. Es la única pista de que hay más. */
.nav-chevron svg { transition: transform .28s cubic-bezier(.4, 0, .2, 1); }
.nav-group.abierto > .nav-cab > .nav-chevron svg { transform: rotate(180deg); }
/* Con la sección abierta la flecha ya no tiene que llamar la atención. */
.nav-group.abierto > .nav-cab > .nav-chevron { opacity: .75; }

/* ── NL-2 · EL SUBMENÚ SE DESLIZA ─────────────────────────────────────────
   Se anima `grid-template-rows` de 0fr a 1fr y NO `max-height`: con altura
   máxima hay que inventarse un número mayor que el contenido, y ese número
   decide la velocidad real —si sobra, la primera mitad de la animación es
   tiempo muerto y el submenú «tarda en arrancar»—; además se rompe el día que
   alguien añade un tercer hijo. Con `0fr → 1fr` el navegador interpola la
   altura REAL del contenido, sea cual sea.

   ⚠ Las dos declaraciones de la fila de dentro son OBLIGATORIAS: sin
     `min-height: 0` la fila de la rejilla no baja del alto de su contenido
     —queda clavada en 1fr y no se cierra nunca— y sin `overflow: hidden` los
     hijos se salen y se ven flotando sobre el menú mientras se cierra. */
.nav-sub-wrap {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows .28s cubic-bezier(.4, 0, .2, 1),
                opacity .18s ease,
                visibility 0s linear .28s;
    visibility: hidden;
}
.nav-sub-wrap > .nav-sub { min-height: 0; overflow: hidden; }
.nav-group.abierto > .nav-sub-wrap {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
    transition: grid-template-rows .28s cubic-bezier(.4, 0, .2, 1),
                opacity .22s ease .06s,
                visibility 0s linear 0s;
}
/* ⚠ `visibility` NO es decoración: sin ella el submenú cerrado sigue en el
   orden de tabulación y el teclado entra en dos enlaces que no se ven. */

/* Quien no quiere movimiento no lo tiene. El submenú sigue abriendo y
   cerrando; lo que se va es el recorrido. */
@media (prefers-reduced-motion: reduce) {
    .nav-sub-wrap, .nav-group.abierto > .nav-sub-wrap { transition-duration: 0s; }
    .nav-chevron svg { transition-duration: 0s; }
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    color: var(--gray-400);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    border-radius: var(--border-radius-sm);
    transition: var(--transition-fast);
    cursor: pointer;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    flex-shrink: 0;
}

.nav-item:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--gray-200);
}

.nav-item.active {
    background: rgba(255, 255, 255, 0.1);
    color: var(--white);
}

.nav-item svg {
    width: 20px;
    height: 20px;
    opacity: 0.7;
}

.nav-divider {
    height: 1px;
    background: var(--border-subtle);
    margin: 8px 12px;
    flex-shrink: 0;
}

.sidebar-footer {
    padding: 16px;
    border-top: 1px solid var(--border-subtle);
    flex-shrink: 0;
}

.user-info {
    display: flex;
    align-items: center;
    gap: 12px;
}
/* Footer profile is now a link into /account. */
a.user-info-link { padding: 8px; margin: -8px; border-radius: 12px; transition: background .15s; }
a.user-info-link:hover { background: rgba(255,255,255,.05); }
a.user-info-link .user-avatar { overflow: hidden; }

.user-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--gray-700);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 600;
    color: var(--white);
}

.user-name {
    font-size: 14px;
    font-weight: 500;
    color: var(--white);
}

.user-email {
    font-size: 12px;
    color: var(--gray-500);
}

/* Organization info in sidebar footer */
.org-info {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}
.org-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--gray-700);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    color: var(--white);
    flex-shrink: 0;
    overflow: hidden;
}
.org-name {
    font-size: 10px;
    font-weight: 500;
    color: var(--gray-400);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 140px;
}
/* Sidebar org name: scoped by id so it isn't overridden by the duplicate bare
   `.org-name` (18px) further down that styles the org cards on the orgs page.
   Sized + weighted like the user's own name, vertically centred with its avatar. */
#sidebar-org-name {
    font-size: 14px;
    font-weight: 500;
    color: var(--white);
    line-height: 1.2;
}
/* Your role in the org, sized/coloured like the user's email line beneath it. */
.org-role {
    font-size: 12px;
    color: var(--gray-500);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 140px;
    line-height: 1.2;
}
/* Org block is now a link to /organization — mirror the user-info-link hover box. */
a.org-info-link { padding: 8px; margin: -8px -8px 6px; border-radius: 12px; transition: background .15s; }
a.org-info-link:hover { background: rgba(255,255,255,.05); }
a.org-info-link .org-avatar { overflow: hidden; }
.footer-divider {
    display: none;
}

/* ============================================
   MAIN CONTENT
   ============================================ */

.main-content {
    flex: 1;
    margin-left: var(--sidebar-width);
    min-height: 100vh;
    min-height: 100svh;     /* ver `body` */
    position: relative;
}

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 24px 32px 16px 32px;
    border: none;
    background: transparent;
    backdrop-filter: none;
}

.page-title {
    font-size: 24px;
    font-weight: 600;
    color: var(--white);
    letter-spacing: -0.02em;
}

.page-subtitle {
    font-size: 13px;
    color: var(--gray-500);
    margin-top: 4px;
    margin-bottom: 8px;
}

.page-content {
    padding: 8px 32px 32px 32px;
}

/* ============================================
   CARDS / PANELS
   ============================================ */

.card {
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: none;
    border-radius: var(--border-radius-lg);
    padding: 24px;
    position: relative;
    box-shadow: var(--glass-shadow);
}

/* Bright glass top edge only — a highlight line faded at the ends, inset from the corners so it never
   pokes the rounded corner. No border, and NO left edge line (it read as a weird vertical bar on tall cards). */
.card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 12px;
    right: 12px;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
}

.card-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--white);
    letter-spacing: -0.01em;
}

/* ============================================
   BUTTONS
   ============================================ */

/* ⚠ 2026-10-31: LOS BOTONES DE LINK3RS.COM (§7 y global.css .btn): pastilla de 40 px, 15/500.
   Son de cristal líquido (liquid.js): se aprietan, se estiran y vuelven con rebote. Por eso aquí
   NO hay `transform` en ningún estado ni `transition: all`: el script escribe el transform en cada
   fotograma, y una transición encima lo haría ir detrás del dedo. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 18px;
    font-size: 14px;   /* Hector, 31-10: «el texto un pelín más pequeño» (la guía, 15) */
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.005em;
    white-space: nowrap;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s, opacity 0.2s;
    border: none;
    text-decoration: none;
    font-family: inherit;
    /* CRISTAL LÍQUIDO (Hector, 31-10: «+ Stage, + Event… que sean de cristal líquido»): el
       relleno es translúcido y lo de detrás se ve desenfocado y saturado; el canto de luz lo
       pone `.lq-shine` (liquid.js). */
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
    box-shadow: 0 4px 14px -6px rgb(0 0 0 / 0.35);
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* El principal: BLANCO, como fue siempre en Backstage (Hector, 31-10: «déjalos tal y como están
   pero blancos como antes»), y de cristal: casi opaco, con lo de detrás desenfocado. */
.btn-primary {
    background: rgb(255 255 255 / 0.88);
    color: var(--gray-950);
    box-shadow: 0 6px 18px -6px rgb(255 255 255 / 0.28);
}

.btn-primary:hover:not(:disabled) {
    background: rgb(255 255 255 / 0.96);
}

/* El «quiet» de la web, en cristal: un velo claro que deja ver lo de detrás. */
.btn-secondary {
    background: rgb(255 255 255 / 0.1);
    color: var(--gray-200);
    border: none;
}

.btn-secondary:hover:not(:disabled) {
    background: rgb(255 255 255 / 0.16);
}

.btn-ghost {
    background: transparent;
    color: var(--gray-400);
    padding: 0 14px;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
}

.btn-ghost:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.06);
    color: var(--gray-200);
}

/* ⚠ QUITAR (Hector, 2026-11-01): «todos los botones de Remove algo tienen que ser de glass y,
   cuando pases el cursor por encima, tintarse de rojo». En reposo es el cristal de los demás (no
   grita en rojo a todas horas); al pasar el cursor, o al llegar con el teclado, se tiñe. Es LA
   clase de quitar: también la llevan los de icono de cada pantalla (papelera, ✕), que en su
   propia clase sólo guardan el tamaño y la forma. */
.btn-danger {
    background: rgb(255 255 255 / 0.1);
    color: var(--gray-200);
    border: none;
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
    transition: background-color 0.2s, color 0.2s, box-shadow 0.2s, opacity 0.2s;
}

.btn-danger:hover:not(:disabled),
.btn-danger:focus-visible {
    background: rgb(239 68 68 / 0.22);
    color: #fca5a5;
    box-shadow: inset 0 0 0 1px rgb(239 68 68 / 0.45), 0 6px 18px -6px rgb(239 68 68 / 0.55);
}

/* Los compactos de las filas densas: 32 px (el objetivo de 40 lo da el hueco de la fila). */
.btn-sm {
    min-height: 32px;
    padding: 0 14px;
    font-size: 13px;
}

.btn-lg {
    min-height: 48px;
    padding: 0 28px;
    font-size: 15px;
}

.btn-icon {
    padding: 10px;
    width: 40px;
    height: 40px;
}

/* ============================================
   FORM ELEMENTS
   ============================================ */

.form-group {
    margin-bottom: 20px;
}

.form-label {
    display: block;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-500);
    margin-bottom: 8px;
}

.form-input,
.form-select,
.form-textarea {
    width: 100%;
    padding: 14px 16px;
    font-size: 14px;
    font-family: inherit;
    color: var(--white);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-sm);
    transition: var(--transition-fast);
}

.form-input::placeholder,
.form-textarea::placeholder {
    color: var(--gray-600);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
    outline: none;
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--border-active);
}

.form-select {
    cursor: pointer;
    appearance: none;
    background-image: 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='%23777777' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 40px;
}

.form-select option {
    background: var(--gray-900);
    color: var(--white);
}

.form-checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-size: 14px;
    color: var(--gray-300);
}

.form-checkbox input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--white);
    cursor: pointer;
}

/* ============================================
   TABS
   ============================================ */

/* ⚠ 2026-11-01 · EL CARRIL Y LA PASTILLA DE LINK3RS.COM, como el menú de Events (dashboard).
   Hector: «cuando vamos a Share, en Channels continúa el glass» — la pestaña que arrancaba
   activa se quedaba con el canto de cristal de los botones (liquid.js la ataba por tener
   fondo) y la elegida no lo tenía. Ahora el carril es una pastilla con un velo, las pestañas
   no son botones líquidos, y la elegida la marca la pastilla de vidrio que SE DESLIZA
   (`.lq-ind`, la pone liquid.js en `.tabs`). */
.tabs {
    position: relative;
    display: flex;
    gap: 4px;
    padding: 4px;
    background: rgb(255 255 255 / 0.08);
    border: none;
    border-radius: 999px;
    margin-bottom: 24px;
}

/* La letra de la guía (.t-label: 500, −0,005em) un pelín más pequeña, como los botones.
   ⚠ El PESO no cambia con el estado: un 500→600 re-fluye la fila y la pastilla medía la
   pestaña antes de que cambiara de ancho. */
.tab {
    position: relative;
    z-index: 1;
    flex: 1;
    padding: 8px 16px;
    /* ⚠ Un <button> NO hereda la letra: sin esto el navegador le pone la suya (Arial en
       Chrome, medido el 2026-10-17) y no la del sistema que lleva el resto de la casa. */
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: -0.005em;
    color: var(--gray-400);
    background: transparent;
    border: none;
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.2s ease, background 0.2s ease;
}

.tab:hover {
    color: var(--gray-200);
    background: rgba(255, 255, 255, 0.04);
}

/* Sin la pastilla (antes de que liquid.js llegue, o sin él) la elegida se pinta sola. */
.tab.active {
    background: rgba(255, 255, 255, 0.14);
    color: var(--white);
}
/* Con la pastilla puesta, el fondo lo pinta ELLA. */
.tabs[data-lq-ind] > .tab.active,
.tabs[data-lq-ind] > .tab.active:hover {
    background: transparent;
    box-shadow: none;
}

[data-theme="light"] .tabs {
    background: rgb(0 0 0 / 0.05);
    border: none;
}
[data-theme="light"] .tab { color: #555; }
[data-theme="light"] .tab:hover { color: #111; background: rgba(0, 0, 0, 0.04); }
[data-theme="light"] .tab.active { background: #ffffff; color: #111; box-shadow: 0 1px 2px rgba(0,0,0,0.06); }
[data-theme="light"] .tabs[data-lq-ind] > .tab.active,
[data-theme="light"] .tabs[data-lq-ind] > .tab.active:hover { background: transparent; box-shadow: none; }

.tab-content {
    display: none;
}

.tab-content.active {
    display: block;
    animation: fadeUp 0.3s ease;
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ============================================
   EVENT GRID
   ============================================ */

.events-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
}

.event-card {
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: none;
    border-radius: var(--border-radius);
    padding: 20px;
    cursor: pointer;
    transition: var(--transition);
    position: relative;
    box-shadow: var(--glass-shadow);
}

.event-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.1) 50%, transparent 100%);
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

.event-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--glass-shadow), 0 16px 48px rgba(0, 0, 0, 0.4);
}

.event-code {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--gray-500);
    background: rgba(255, 255, 255, 0.06);
    padding: 4px 8px;
    border-radius: 4px;
    font-family: var(--font-mono);
}

.event-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--white);
    margin: 12px 0 8px;
    letter-spacing: -0.02em;
}

.event-meta {
    display: flex;
    align-items: center;
    gap: 16px;
    font-size: 13px;
    color: var(--gray-500);
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 6px;
}

.status-dot.active {
    background: var(--success);
    box-shadow: 0 0 8px var(--success);
}

.status-dot.inactive {
    background: var(--gray-600);
}

/* ============================================
   CHANNELS
   ============================================ */

.channels-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.channel-card {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-sm);
    padding: 16px;
    transition: var(--transition-fast);
}

.channel-card:hover {
    border-color: var(--border-hover);
    background: rgba(255, 255, 255, 0.06);
}

.channel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

/* S3: the channel trash button turns red on hover */
.channel-delete { transition: color .12s, background .12s, transform .12s; }
.channel-delete:hover {
    color: #ef4444;
    background: rgba(239, 68, 68, 0.12);
    transform: scale(1.06);
}

/* ── G2: Knowledge tab — grouped Context / Terms with higher contrast ── */
.knowledge-group {
    border: 1px solid transparent;
    border-radius: 12px;
    padding: 16px 16px 18px;
    background: rgba(255, 255, 255, 0.045);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}
.knowledge-group-title {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--gray-400);
    margin-bottom: 14px;
}
.trans-terms-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 280px;
    overflow-y: auto;
    margin-bottom: 8px;
    padding-right: 2px;
}
.trans-term-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-subtle);
    transition: background .12s, border-color .12s;
}
.trans-term-row:hover { background: rgba(255, 255, 255, 0.08); border-color: var(--border-hover); }
.trans-term-row .tt-src { color: var(--white); font-size: 0.85rem; flex: 1; font-weight: 600; word-break: break-word; }
.trans-term-row .tt-arrow { color: var(--gray-400); font-size: 0.8rem; flex: 0 0 auto; }
.trans-term-row .tt-tgt { color: #60a5fa; font-size: 0.85rem; flex: 1; font-weight: 500; word-break: break-word; }
.trans-term-row .tt-del {
    cursor: pointer; font-size: 15px; line-height: 1; width: 24px; height: 24px; padding: 0;
    border-radius: 999px; flex: 0 0 auto; display: inline-grid; place-items: center;
}
.trans-term-add {
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
    padding-top: 10px; margin-top: 4px; border-top: 1px solid var(--border-subtle);
}
[data-theme="light"] .knowledge-group { background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .trans-term-row { background: rgba(0, 0, 0, 0.03); }
[data-theme="light"] .trans-term-row .tt-tgt { color: #2563eb; }

.channel-name {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 15px;
    font-weight: 500;
    color: var(--white);
}

.channel-flag {
    font-size: 20px;
    line-height: 1;
}

.channel-badge {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-950);
    background: var(--white);
    padding: 3px 8px;
    border-radius: 4px;
}

.channel-info {
    display: flex;
    gap: 16px;
    font-size: 13px;
    color: var(--gray-500);
    margin-bottom: 12px;
}

.channel-actions {
    display: flex;
    gap: 8px;
}

/* ============================================
   TERMINAL
   ============================================ */

.terminal {
    background: var(--gray-950);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
    overflow: hidden;
}

.terminal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid var(--border-subtle);
}

.terminal-title {
    font-size: 12px;
    font-weight: 500;
    color: var(--gray-400);
}

.terminal-body {
    padding: 16px;
    max-height: 400px;
    overflow-y: auto;
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 1.6;
}

.log-line {
    display: flex;
    gap: 12px;
    margin-bottom: 4px;
}

.log-time {
    color: var(--gray-600);
    min-width: 70px;
}

.log-level {
    font-weight: 500;
    min-width: 50px;
}

.log-level.info { color: var(--info); }
.log-level.success { color: var(--success); }
.log-level.warning { color: var(--warning); }
.log-level.error { color: var(--error); }

.log-message {
    color: var(--gray-300);
    flex: 1;
}

/* ============================================
   MODAL
   ============================================ */

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
}

.modal-overlay.hidden {
    display: none;
}

/* Un panel flotante: cristal líquido (el más opaco, que lleva texto) y radio de panel grande. */
.modal {
    background: var(--glass-bg-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: none;
    border-radius: var(--radius-l);
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    overflow-y: auto;
    position: relative;
    box-shadow: var(--glass-shadow), 0 24px 80px rgba(0, 0, 0, 0.5);
}

.modal::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.12) 20%, rgba(255, 255, 255, 0.12) 80%, transparent 100%);
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-subtle);
}

.modal-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--white);
}

.modal-close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--gray-500);
    font-size: 18px;
    cursor: pointer;
    border-radius: 6px;
    transition: var(--transition-fast);
}

.modal-close:hover {
    background: rgba(255, 255, 255, 0.08);
    color: var(--white);
}

.modal-body {
    padding: 24px;
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    padding: 16px 24px;
    border-top: 1px solid var(--border-subtle);
}

/* ============================================
   SHARE
   ============================================ */

.share-link {
    display: flex;
    gap: 8px;
}

.share-link input {
    flex: 1;
    font-family: var(--font-mono);
    font-size: 13px;
}

.qr-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 24px;
    background: var(--white);
    border-radius: var(--border-radius);
    width: fit-content;
}

.qr-container canvas {
    border-radius: 8px;
}

/* ============================================
   STATS
   ============================================ */

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 16px;
}

.stat-card {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
    padding: 20px;
    text-align: center;
}

.stat-label {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-500);
    margin-bottom: 8px;
}

.stat-value {
    font-size: 28px;
    font-weight: 600;
    color: var(--white);
    letter-spacing: -0.02em;
}

/* ============================================
   DANGER ZONE
   ============================================ */

.danger-zone {
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid rgba(239, 68, 68, 0.2);
    /* El mismo radio que las tarjetas de al lado (`.card`, 24px): con 12px se veía de otra familia. */
    border-radius: var(--border-radius-lg);
    /* Y el mismo margen interior: 24px de la tarjeta menos el píxel del borde, para que el texto caiga
       a plomo con el de las tarjetas de arriba. */
    padding: 23px;
    margin-top: 24px;
}

.danger-zone-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--error);
    margin-bottom: 8px;
}

.danger-zone-text {
    font-size: 13px;
    color: var(--gray-400);
    margin-bottom: 16px;
}

/* ============================================
   SPEAKER PAGE
   ============================================ */

.speaker-layout {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--gray-950);
}

.speaker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 32px;
    border-bottom: 1px solid var(--border-subtle);
}

.speaker-title {
    font-size: 20px;
    font-weight: 600;
    color: var(--white);
}

.speaker-content {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 400px;
    gap: 24px;
    padding: 32px;
}

.speaker-main {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.speaker-sidebar {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Waveform */
.waveform-container {
    background: var(--gray-900);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
    padding: 32px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 300px;
}

.waveform-canvas {
    width: 100%;
    height: 200px;
    background: transparent;
}

.waveform-status {
    margin-top: 16px;
    font-size: 14px;
    color: var(--gray-500);
}

.waveform-status.active {
    color: var(--success);
}

/* Device selector */
.device-selector {
    background: var(--gray-900);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
    padding: 20px;
}

.device-selector h3 {
    font-size: 14px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 16px;
}

/* ============================================
   AUTH PAGES
   ============================================ */

.auth-layout {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    position: relative;
    z-index: 1;
}

.auth-card {
    width: 100%;
    max-width: 400px;
}

.auth-header {
    text-align: center;
    margin-bottom: 32px;
}

.auth-header img {
    height: 32px;
    margin-bottom: 24px;
}

.auth-header h1 {
    font-size: 24px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.auth-header p {
    font-size: 14px;
    color: var(--gray-500);
}

.auth-footer {
    text-align: center;
    margin-top: 24px;
    font-size: 14px;
    color: var(--gray-500);
}

.auth-footer a {
    color: var(--white);
    text-decoration: none;
}

.auth-footer a:hover {
    text-decoration: underline;
}

/* ============================================================================
   LANYARD CREDENTIAL AUTH — login / signup / join live inside the REAL badge
   PNG (static/img/badge-rope.png). The BADGE is centred and the rope runs off
   the top of the screen (hangs from above). One adaptive Backstage badge (login
   ⇄ signup in place, animated tech-gradient that CYCLES one colour) + an org
   invite badge (waves in the org's colour). Forward swap = rise (no fade); back
   = fade. Dark-only (light theme is platform-side).
   ============================================================================ */
.auth-stage{ position:fixed; inset:0; display:flex; align-items:center; justify-content:center; padding:12px; perspective:1800px; z-index:1; overflow:hidden; }
.lanyard{ position:relative; transform:translateY(-14%); }   /* badge centred, rope pushed off the top */
/* ⚠ EL TAMAÑO ES UNO SOLO PARA TODAS LAS PANTALLAS (login, signup, join). Que
   la acreditación cambie de tamaño al pasar de una a otra se nota como un
   salto y parece un fallo, así que este valor NO se ajusta por pantalla.

   Subido de 760 a 880 el 2026-09-03: a 1180x820 la pila medía 760 y sobraban
   136px por debajo sin usar. La ventana interior (.badge-content) va en
   PORCENTAJES de la pila, así que crece con ella y sigue cuadrando con el
   marco dibujado del PNG — no hay dos números que mantener a la vez.

   Y el `96vh` pasa a `112vh` por la misma medición: la pila se centra y luego
   `.lanyard` la sube un 14%, así que el borde de abajo cae en
   `50vh + 0.36·H` — con 96vh sobraban 127px muertos por debajo. Con 112vh el
   tope de 880 es el que ata en un escritorio normal, y en pantallas bajas
   sigue mandando el viewport y la acreditación se encoge sola. */
.badge-stack{ position:relative; width:min(880px, 112vh); height:min(880px, 112vh); transform-style:preserve-3d; }

.auth-badge{ position:absolute; inset:0; transform-origin:top center; backface-visibility:hidden;
  transition: transform .66s cubic-bezier(.5,.02,.23,1), opacity .5s ease; }
.auth-badge.is-active{ transform:none; opacity:1; z-index:3; }
/* forward exit: rise up & off, NO fade (the physical rise is the effect) */
.auth-badge.is-up{ transform:translateY(-124%) rotateX(30deg) scale(.94); opacity:1; z-index:1; }
/* back exit / waiting: fade */
.auth-badge.is-down{ transform:translateY(12%) rotateX(-10deg) scale(.95); opacity:0; z-index:0; }
@media (prefers-reduced-motion: reduce){ .auth-badge{ transition:opacity .35s ease; } .auth-badge.is-up,.auth-badge.is-down{ transform:none; } }

.badge-frame{ position:absolute; inset:0; width:100%; height:100%; z-index:2; pointer-events:none; filter: drop-shadow(0 30px 46px rgba(0,0,0,.55)); }
.badge-content{ position:absolute; left:30.4%; top:34.5%; width:39.1%; height:57.2%; z-index:1;
  border-radius:22px; overflow:hidden; display:flex; flex-direction:column; justify-content:center; padding:22px 20px 20px; }

.aw-bg{ position:absolute; inset:0; z-index:0; }
/* BOTH the org-invite badge AND the Backstage badge use bottom-half DIAGONAL diffuse
   waves — colour fills ~to the middle (peak far-right, rising left→right), heavily
   blurred so it fades to black up top with NO hard line; two moving layers.
   Org = the org's colour (fixed); Backstage = a colour that CYCLES the spectrum. */
.aw-bg-waves, .aw-bg-tech{ background:#0a0c11; overflow:hidden; }
.aw-bg-waves::before, .aw-bg-waves::after, .aw-bg-tech::before, .aw-bg-tech::after{ content:''; position:absolute; inset:-15%; will-change:transform; }
.aw-bg-waves::before, .aw-bg-tech::before{ background: radial-gradient(105% 96% at 100% 108%, var(--org-color,#4f8cff) 0%, transparent 68%);
  filter: blur(26px); opacity:1; animation: awWaveA 11s ease-in-out infinite; }
.aw-bg-waves::after, .aw-bg-tech::after{ background: radial-gradient(98% 88% at 50% 118%, var(--org-color,#4f8cff) 0%, transparent 74%);
  filter: blur(36px); opacity:.62; animation: awWaveB 15s ease-in-out infinite; }
.aw-bg-tech{ --org-color:#2b7cff; animation: awHue 16s linear infinite; }   /* Backstage: cycle the wave colour */
@keyframes awHue{ to{ filter: hue-rotate(360deg); } }
@keyframes awWaveA{ 0%,100%{ transform:translate(0,0) scale(1);} 50%{ transform:translate(-3%,-4%) scale(1.08);} }
@keyframes awWaveB{ 0%,100%{ transform:translate(0,0) scale(1.05);} 50%{ transform:translate(4%,-3%) scale(1.13);} }
@media (prefers-reduced-motion: reduce){ .aw-bg-tech,.aw-bg-waves::before,.aw-bg-waves::after,.aw-bg-tech::before,.aw-bg-tech::after{ animation:none; } }
.aw-scrim{ position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(9,10,14,.7) 0%, rgba(9,10,14,.16) 26%, rgba(9,10,14,.12) 60%, rgba(9,10,14,.6) 100%); }
.aw-body{ position:relative; z-index:2; display:flex; flex-direction:column; justify-content:center; height:100%; transform-origin:center center; }
.aw-body.top{ justify-content:flex-start; }

/* ⚠ ESTOS TAMAÑOS SUBIERON CON LA ACREDITACIÓN (2026-09-03). La pila pasó de
   760 a 880 y la ventana interior de 435 a 503px de alto; con la tipografía
   vieja el contenido quedaba flotando en el centro de una tarjeta grande y
   medio vacía. Suben JUNTOS a propósito: son el mismo ajuste, y tocar uno sin
   el otro devuelve el problema por el otro lado. */
.aw-head{ text-align:center; }
/* 84 → 96 (Hector, 2026-10-29: «el logo de Backstage un poco más grande»). Si un paso no
   cabe, el auto-encaje de `acreditacion.js` lo mete dentro; el móvil tiene su tamaño abajo. */
.aw-logo{ height:96px; width:auto; margin:0 auto 30px; display:block; }
.aw-crow{ display:flex; align-items:center; justify-content:center; gap:10px; margin-bottom:2px; }
.aw-c2{ font-size:25px; font-weight:650; letter-spacing:-.02em; color:#fff; }
.aw-org{ display:inline-flex; align-items:center; gap:7px; padding:5px 11px 5px 6px; border-radius:999px;
  background:rgba(255,255,255,.13); box-shadow:inset 0 0 0 1px rgba(255,255,255,.16); font-size:11.5px; color:#fff; font-weight:500; }
.aw-org .aw-org-logo{ width:20px; height:20px; border-radius:50%; object-fit:cover; background:rgba(0,0,0,.35); display:grid; place-items:center; font-size:10px; font-weight:700; color:#fff; overflow:hidden; flex:none; }
.aw-org .aw-org-logo img{ width:100%; height:100%; object-fit:cover; }
.aw-org b{ color:#fff; font-weight:650; }
.aw-form{ margin-top:18px; display:flex; flex-direction:column; gap:12px; }
.aw-field{ text-align:left; }
.aw-label{ display:block; font-size:10.5px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:rgba(255,255,255,.6); margin:0 0 5px; }
.aw-input{ width:100%; padding:13px 15px; font-size:15px; font-family:inherit; color:#fff;
  background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.17); border-radius:10px; transition:.16s; }
.aw-input::placeholder{ color:rgba(255,255,255,.42); }
.aw-input:focus{ outline:none; background:rgba(255,255,255,.15); border-color:rgba(255,255,255,.42); }
.aw-btn{ width:100%; padding:14px; font-size:15px; font-weight:650; font-family:inherit; cursor:pointer;
  color:#111; background:#fff; border:none; border-radius:10px; transition:.16s; margin-top:3px; }
.aw-btn:hover:not(:disabled){ transform:translateY(-1px); box-shadow:0 8px 20px rgba(0,0,0,.4); }
.aw-btn:disabled{ opacity:.65; cursor:default; }
.aw-btn.secondary{ color:#fff; background:rgba(255,255,255,.15); box-shadow:inset 0 0 0 1px rgba(255,255,255,.22); }
.aw-btn.secondary:hover:not(:disabled){ background:rgba(255,255,255,.22); }
.aw-actions{ display:flex; flex-direction:column; gap:9px; }
.aw-foot{ text-align:center; font-size:12px; color:rgba(255,255,255,.62); margin-top:15px; }
.aw-foot a{ color:#fff; text-decoration:none; font-weight:600; cursor:pointer; }
.aw-foot a:hover{ text-decoration:underline; }
.aw-body.top .aw-head{ margin-top:6%; }   /* drop "invited to" down a touch */
.aw-invited{ font-size:11px; letter-spacing:.11em; text-transform:uppercase; color:rgba(255,255,255,.62); margin:0 0 20px; }
.aw-orglogo-big{ width:66px; height:66px; border-radius:18px; margin:0 auto 12px; display:grid; place-items:center;
  font-size:27px; font-weight:700; color:#fff; overflow:hidden; background:rgba(255,255,255,.1); box-shadow:inset 0 0 0 1px rgba(255,255,255,.18); }
.aw-orglogo-big img{ width:100%; height:100%; object-fit:cover; }
.aw-title{ font-size:22px; font-weight:650; letter-spacing:-.02em; color:#fff; margin:0 0 4px; }
.aw-sub{ font-size:12.5px; color:rgba(255,255,255,.66); margin:0; }
.aw-desc{ font-size:12px; line-height:1.5; color:rgba(255,255,255,.74); margin:10px auto 0; max-width:210px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; text-wrap:balance; }
.aw-msg{ font-size:12px; line-height:1.4; margin:11px 2px 0; text-align:center; }
.aw-msg.err{ color:#ff9a9a; } .aw-msg.ok{ color:#8ff0c2; }
.aw-statebadge{ display:inline-flex; align-items:center; gap:7px; padding:6px 13px; border-radius:999px; font-size:12px; font-weight:600; margin:0 auto; }
.aw-statebadge.pending{ background:rgba(234,179,8,.2); color:#facc15; }
.aw-statebadge.member{ background:rgba(52,211,153,.2); color:#6ee7b7; }
.aw-statebadge.denied{ background:rgba(239,68,68,.2); color:#fca5a5; }
.aw-statebadge .dot{ width:8px; height:8px; border-radius:50%; background:currentColor; }

/* ============================================
   LOADING & SPINNER
   ============================================ */

/* Hector, 2026-09-28: «los loading spinners de todas las páginas tienen que estar centrados en
   el centro». Dos casos:
   · el de una SECCIÓN (una lista, una tarjeta, un modal, una tabla) se centra en su caja, en
     los dos ejes; dentro de una rejilla ocupa la fila ENTERA (antes caía en la primera celda y
     se veía arriba a la izquierda, p. ej. en Events);
   · el de la carga de una PÁGINA (`.loading-pagina`) va en el centro de lo que se ve: fijo,
     descontando el menú lateral cuando la página lo tiene (`.main-content`). No se toca: pasa
     el puntero a lo de debajo. Desaparece solo en cuanto la lista pinta su contenido. */
.loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px;
    width: 100%;
    min-height: 120px;
    box-sizing: border-box;
    grid-column: 1 / -1;
}
.loading.loading-pagina {
    position: fixed; top: 0; right: 0; bottom: 0; left: 0;
    width: auto; min-height: 0; padding: 0;
    z-index: 5; pointer-events: none;
}
.main-content .loading.loading-pagina { left: var(--sidebar-width); }

.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border-subtle);
    border-top-color: var(--white);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ============================================
   EMPTY STATE
   ============================================ */

.empty-state {
    text-align: center;
    padding: 48px 24px;
}

.empty-state-icon {
    font-size: 48px;
    margin-bottom: 16px;
    opacity: 0.5;
}

.empty-state-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.empty-state-text {
    font-size: 14px;
    color: var(--gray-500);
    margin-bottom: 24px;
}

/* ============================================
   UTILITIES
   ============================================ */

.text-muted { color: var(--gray-500); }
.text-success { color: var(--success); }
.text-warning { color: var(--warning); }
.text-danger { color: var(--error); }
.text-white { color: var(--white); }
.text-center { text-align: center; }
.text-right { text-align: right; }

.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 16px; }
.mt-4 { margin-top: 24px; }
.mb-1 { margin-bottom: 4px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 16px; }
.mb-4 { margin-bottom: 24px; }

.hidden { display: none !important; }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 16px; }
.gap-4 { gap: 24px; }

/* ============================================
   ERROR PAGE
   ============================================ */

.error-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px;
    text-align: center;
}

.error-icon {
    font-size: 64px;
    margin-bottom: 24px;
}

.error-title {
    font-size: 32px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.error-text {
    font-size: 16px;
    color: var(--gray-500);
    max-width: 400px;
    margin-bottom: 32px;
}

/* ============================================
   RESPONSIVE
   ============================================ */

@media (max-width: 1024px) {
    .speaker-content {
        grid-template-columns: 1fr;
    }
}

/* ============================================
   MOBILE HAMBURGER + DRAWER (always rendered, only visible on mobile)
   ============================================ */
.mobile-hamburger {
    display: none;
    position: fixed;
    top: calc(14px + env(safe-area-inset-top, 0px));
    right: calc(14px + env(safe-area-inset-right, 0px));
    width: 44px;
    height: 44px;
    align-items: center;
    justify-content: center;
    background: rgba(20, 20, 22, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    color: var(--white);
    cursor: pointer;
    z-index: 310;
    backdrop-filter: saturate(180%) blur(16px);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    -webkit-tap-highlight-color: transparent;
    transition: background 0.18s ease, transform 0.18s ease;
}
.mobile-hamburger svg { width: 22px; height: 22px; stroke-width: 1.75; }
/* El mismo botón abre y CIERRA el menú, en el mismo sitio: con el cajón abierto enseña la ✕
   (sidebar.js pone `body.nav-open` y `aria-expanded`). Antes seguía siendo ☰ encima del
   cajón —tapándole el logo— o, en Events, desaparecía y no quedaba con qué cerrar. */
.mobile-hamburger .ico-cerrar { display: none; }
body.nav-open .mobile-hamburger .ico-abrir { display: none; }
body.nav-open .mobile-hamburger .ico-cerrar { display: block; }
.mobile-hamburger:hover { background: rgba(40, 40, 44, 0.8); }
.mobile-hamburger:active { transform: scale(0.96); }
[data-theme="light"] .mobile-hamburger {
    background: rgba(255, 255, 255, 0.78);
    border-color: rgba(0, 0, 0, 0.08);
    color: #111;
}

.mobile-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: 280;
    opacity: 0;
    transition: opacity 0.22s ease;
}
.mobile-backdrop.open {
    display: block;
    opacity: 1;
}

/* ============================================
   MOBILE RESPONSIVE (<= 768px)
   ============================================ */
@media (max-width: 768px) {
    :root {
        --sidebar-width: 0px;
    }

    /* Show hamburger on mobile */
    .mobile-hamburger { display: inline-flex; }

    /* IMPORTANT: break .app-layout's stacking context so the drawer
       (z-index 300) can sit above body-level backdrop (z-index 280). */
    .app-layout { z-index: auto; }

    /* Sidebar → right-side drawer */
    .sidebar {
        position: fixed;
        top: 0;
        right: 0;
        left: auto;
        width: min(272px, 76vw);   /* narrower: 85vw swallowed the whole phone */
        height: 100dvh;
        border-right: none;
        border-left: 1px solid var(--border-subtle);
        /* La sombra, sólo abierto: cerrado, el cajón está en x=100% y su sombra (-16px) asomaba
           como una franja gris en el borde derecho, en tema claro (rediseño de Users, 05-11).
           Al cerrar se quita DESPUÉS del deslizamiento, para que no desaparezca de golpe. */
        box-shadow: none;
        transform: translateX(100%);
        transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0s linear 0.28s;
        z-index: 300;
        /* make sure nothing behind bleeds through */
        background: var(--bg-sidebar);
        isolation: isolate;
        /* iPhone notch / home indicator safe area */
        padding-top: env(safe-area-inset-top, 0px);
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    .sidebar.open {
        transform: translateX(0);
        box-shadow: -16px 0 40px rgba(0, 0, 0, 0.5);
        transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
    }
    /* El botón de cerrar vive en la esquina de arriba a la derecha, que es también la del
       cajón: la cabecera le deja su hueco (14 px de margen + 44 de botón + 10 de aire) y
       el logo ya no queda debajo. */
    .sidebar-header { padding-right: calc(68px + env(safe-area-inset-right, 0px)); }

    .main-content {
        margin-left: 0;
        width: 100%;
    }

    /* Page header — Swiss/Apple proportions: generous top breathing room, fluid title */
    .page-header {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        /* Generous top padding (with iPhone notch support) */
        padding: calc(72px + env(safe-area-inset-top, 0px)) 22px 16px 22px;
    }
    /* Make the inner title block a flex-column so all siblings
       (back-link, title, subtitle, event-code) share the same rhythm */
    .page-header > div:first-child {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
        width: 100%;
    }
    .page-title,
    .page-subtitle {
        max-width: 100%;
        margin: 0;  /* reset — gap handles spacing */
    }
    .page-title {
        font-size: clamp(22px, 5.8vw, 28px);
        font-weight: 600;
        line-height: 1.15;
        letter-spacing: -0.022em;
        word-break: break-word;
        overflow-wrap: break-word;
        hyphens: auto;
    }
    .page-subtitle {
        font-size: 14px;
        line-height: 1.4;
        letter-spacing: -0.003em;
    }
    /* Back-links inside page-header: bigger tap target, consistent rhythm */
    .page-header .text-muted,
    .page-header .back-btn {
        font-size: 15px !important;
        display: inline-flex !important;
        align-items: center;
        gap: 8px;
        padding: 6px 0;
        min-height: 36px;
        margin: 0;
    }
    /* «VOLVER» ES NAVEGACIÓN DE PRIMERA EN UN MÓVIL (el menú no sabe de dónde venías): se
       pulsa con el dedo, 44 px como los botones. Cada pantalla le puso su clase —el de un
       espacio medía 18 px de alto y el de un curso 21—, así que se reúnen AQUÍ, en una
       sola regla, en vez de arreglarlos página a página. Sólo los enlaces: un
       `.text-muted` suelto en una cabecera no es un botón y no crece. */
    .page-header a.text-muted,
    .page-header .back-btn,
    .page-header .breadcrumb a,
    .sv-back,                    /* organization.html · «Back to spaces» */
    .course-detail-back,         /* learn.html · «Back to courses» */
    .ed-back, .kn-back {         /* jobs.html · el estudio y sus stages */
        /* Sólo la altura: el `display` es de cada pantalla (`.ed-back` nace escondido y
           lo enseña su JS; forzarlo aquí lo sacaría siempre). */
        min-height: 44px;
    }
    /* Extra breathing room between back-link and title */
    .page-header .text-muted + .page-title,
    .page-header .back-btn + .page-title {
        margin-top: 4px;
    }
    .page-header > div:last-child,
    .page-header > .header-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        width: 100%;
        padding-right: 0;
    }

    .page-content {
        padding: 12px 22px 24px 22px;
    }

    /* If the page has NO .page-header (e.g. direct page-content), still reserve top space for the hamburger */
    main.main-content > .page-content:first-child {
        padding-top: calc(72px + env(safe-area-inset-top, 0px));
    }

    /* One-column grids for common layouts */
    .events-grid,
    .stats-strip,
    .ms-events-grid,
    .device-grid,
    .courses-grid-new,
    .channel-grid,
    .orgs-grid,
    .stats-grid,
    .video-urls-grid {
        grid-template-columns: 1fr !important;
    }

    /* Touch-friendly buttons */
    .btn {
        min-height: 44px;
        padding: 12px 18px;
        font-size: 15px;
    }
    .btn-sm { min-height: 38px; padding: 8px 14px; }

    /* Inputs: 16px to prevent iOS zoom-on-focus */
    .form-input,
    .form-select,
    .form-textarea {
        font-size: 16px;
        padding: 13px 14px;
        min-height: 44px;
    }

    /* Modals */
    .modal {
        width: 92vw !important;
        max-width: 92vw !important;
        margin: 12px;
        max-height: 90dvh;
        overflow-y: auto;
    }
    .modal-body { padding: 16px; }
    .modal-footer { padding: 14px 16px; flex-wrap: wrap; }

    /* Tables → horizontal scroll */
    .users-table,
    table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Compact spacing in cards */
    .card { padding: 16px; }

    /* Tabs: scroll horizontally if they overflow */
    .tabs,
    .nav-tabs {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        flex-wrap: nowrap !important;
        /* El carril es una pastilla: la barra de desplazamiento le pintaba una raya debajo. */
        scrollbar-width: none;
    }
    .tabs::-webkit-scrollbar,
    .nav-tabs::-webkit-scrollbar { display: none; }
    .tabs .tab,
    .nav-tabs .tab {
        flex: 0 0 auto;
        min-height: 40px;
        white-space: nowrap;
    }

    /* Channel cards: actions wrap, info stacks */
    .channel-header { flex-wrap: wrap; gap: 8px; }
    .channel-info { flex-wrap: wrap; gap: 8px 12px; }
    .channel-actions { flex-wrap: wrap; }

    /* Danger zone modal confirmations */
    .danger-zone { padding: 15px; }
    .danger-zone-title { font-size: 1rem; }

    /* Auth layout (login/signup/pending-approval) */
    .auth-layout { padding: 16px; }
    .auth-card { max-width: 100%; padding: 24px 20px; }
    .auth-header { margin-bottom: 24px; }
    .auth-header img { height: 28px; margin-bottom: 20px; }
    .auth-header h1 { font-size: 20px; }

    /* Lanyard credential auth (login / signup / join — shared .auth-stage/.badge-stack/.aw-* )
       Keep the whole badge form reachable above the on-screen keyboard on phones. */
    /* Was a fixed, overflow:hidden window with no scroll fallback → submit button trapped
       under the keyboard. Make the stage scroll vertically and anchor to the top so the
       focused field/button can be scrolled into view. */
    .auth-stage {
        align-items: flex-start;
        padding-top: 24px;
        overflow-x: hidden;
        overflow-y: auto;
    }
    /* Size the (square) badge against the actually-visible area (dvh, not vh, so iOS
       Safari toolbar state can't push the button off-screen) and cap it so it fits the
       phone width instead of the ~760px desktop badge. */
    .badge-stack {
        /* Mismo tope que en escritorio (880), para que la acreditación no
           cambie de tamaño al girar el teléfono ni entre pantallas. En un móvil
           manda el `150vw` de todas formas: a 393px de ancho da 590, muy por
           debajo del tope. */
        width: min(880px, 150vw, 112dvh);
        height: min(880px, 150vw, 112dvh);
    }
    /* 16px kills iOS focus-zoom (these inputs don't use the global .form-input rule). */
    .aw-input { font-size: 16px; }

    /* ⚠ LA TIPOGRAFÍA SUBIDA PARA ESCRITORIO NO CABE EN UN MÓVIL PEQUEÑO, y
       aquí vuelve a la de antes. Medido en un 375x553 (un iPhone SE con la
       barra del navegador puesta): la ventana de la acreditación mide 322px y
       el contenido pedía 453 — el auto-encaje lo metía dentro, pero al 69%, y
       una pantalla de entrar al 69% se lee mal.

       En escritorio la ventana es de 503px y sobra sitio; aquí no. El tamaño
       de la acreditación ya se adapta solo (el `min()` de arriba), pero el
       texto no, porque va en píxeles. Con esto el contenido baja a ~350 y
       entra sin encoger.

       El `font-size` de los campos NO se toca: los 16px de arriba son los que
       impiden que iOS haga zoom al enfocarlos, y bajarlos devolvería ese salto
       que descoloca la página entera. Se recorta el RELLENO, que no tiene ese
       efecto. */
    .aw-logo { height: 70px; margin-bottom: 18px; }
    .aw-c2 { font-size: 21px; }
    .aw-form { margin-top: 14px; gap: 9px; }
    .aw-input { padding: 11px 13px; }
    .aw-btn { padding: 12px; font-size: 14px; }
    .aw-label { font-size: 9.5px; }
    /* Footer links (Sign up/Sign in toggle, '‹ Back', 'Not you? Sign out') → real tap area. */
    .aw-foot a { display: inline-block; padding: 8px 6px; min-height: 40px; }
}

/* Even smaller: phones */
@media (max-width: 420px) {
    .page-header { padding: calc(68px + env(safe-area-inset-top, 0px)) 20px 14px 20px; }
    .page-title { letter-spacing: -0.025em; }
    .page-subtitle { font-size: 13px; }
    .page-content { padding: 10px 20px 20px 20px; }
    .card { padding: 14px; }
    .btn { font-size: 14px; }
}

/* ============================================
   ADMIN PAGE
   ============================================ */

.users-table {
    width: 100%;
    border-collapse: collapse;
}

.users-table th,
.users-table td {
    padding: 12px 16px;
    text-align: left;
    border-bottom: 1px solid var(--border-subtle);
}

.users-table th {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-500);
}

.users-table td {
    font-size: 14px;
    color: var(--gray-300);
}

.users-table tr:hover {
    background: rgba(255, 255, 255, 0.02);
}

.badge {
    display: inline-block;
    padding: 4px 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    border-radius: 4px;
}

.badge-success {
    background: rgba(34, 197, 94, 0.15);
    color: var(--success);
}

.badge-warning {
    background: rgba(245, 158, 11, 0.15);
    color: var(--warning);
}

.badge-info {
    background: rgba(59, 130, 246, 0.15);
    color: var(--info);
}

/* ============================================
   FLAG EMOJIS FOR LANGUAGES
   ============================================ */

.flag-en::before { content: "🇬🇧"; }
.flag-es::before { content: "🇪🇸"; }
.flag-fr::before { content: "🇫🇷"; }
.flag-de::before { content: "🇩🇪"; }
.flag-it::before { content: "🇮🇹"; }
.flag-pt::before { content: "🇧🇷"; }
.flag-zh::before { content: "🇨🇳"; }
.flag-ja::before { content: "🇯🇵"; }
.flag-ko::before { content: "🇰🇷"; }
.flag-ru::before { content: "🇷🇺"; }
.flag-ar::before { content: "🇸🇦"; }
.flag-hi::before { content: "🇮🇳"; }
.flag-nl::before { content: "🇳🇱"; }
.flag-pl::before { content: "🇵🇱"; }
.flag-ca::before { content: "🏳️"; }
.flag-any::before { content: "🌐"; }

/* ============================================
   STREAMING STATUS DOT
   ============================================ */

.status-dot.streaming {
    background: var(--info);
    box-shadow: 0 0 8px var(--info);
    animation: streamPulse 1.5s ease-in-out infinite;
}

/* En emisión pero sin voz desde hace minutos (dashboard: estadoVisibleDelStage). */
.status-dot.silent {
    background: var(--warning);
}

@keyframes streamPulse {
    0%, 100% { box-shadow: 0 0 8px var(--info); }
    50% { box-shadow: 0 0 16px var(--info), 0 0 24px rgba(59, 130, 246, 0.3); }
}

/* ============================================
   EVENT TYPE BADGES
   ============================================ */

.event-type-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    padding: 3px 9px;
    border-radius: 5px;
}
.event-space-tag {
    font-size: 13px;
    font-weight: 400;
    letter-spacing: normal;
    padding: 3px 9px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--gray-400);
}
.event-card .event-meta { margin-top: 12px; }
.event-card-type {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 14px;
}

.event-type-badge.speech {
    background: rgba(236, 72, 153, 0.16);
    color: #ec4899;
}

.event-type-badge.subtitles {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
}

.event-type-badge.mixer {
    background: rgba(45, 212, 191, 0.16);
    color: #2dd4bf;
}

/* Slides — el cuarto tipo. NARANJA (#f97316): el telón, no el micrófono.
   Sin esta clase el badge sale sin fondo ni color y la tarjeta se lee como
   una Speech mal pintada.

   ⚠ NARANJA, NO ROJO. Empezó siendo un rosa-rojo (#f43f5e) y se leía como una
     Speech (#ec4899) apagada: 25° de tono los separaban, y en un badge de 11px
     eso no lo distingue nadie. El naranja está a 25° de tono absoluto —a 55°
     del magenta de Speech, a 149° del turquesa de Mixer y a 192° del azul de
     Subtitles— y sube el contraste sobre el panel oscuro de 4,93:1 a 6,45:1.
     El tono vive AQUÍ y en `.event-card.cat-slides:hover`, en `CAT_GLOW`
     (dashboard.html), en `.stage-code-chip.type-slides` (event.html) y en las
     paletas de las dos pantallas propias (slides_script.css, slides_stage.css).
     Cambiar uno solo deja el producto a dos colores. */
.event-type-badge.slides {
    background: rgba(249, 115, 22, 0.16);
    color: #f97316;
}

/* ── El tinte del tipo en la tarjeta del stage: entra desde el borde derecho y se apaga hacia el centro
   (Hector, 2026-11-02: «los stages son un poco grises»). Mismos tonos que el badge y el brillo de hover. ── */
.event-card.cat-speech    { --cat-tinte: rgba(236, 72, 153, 0.17); }
.event-card.cat-subtitles { --cat-tinte: rgba(59, 130, 246, 0.17); }
.event-card.cat-mixer     { --cat-tinte: rgba(45, 212, 191, 0.15); }
.event-card.cat-slides    { --cat-tinte: rgba(249, 115, 22, 0.16); }
.event-card.cat-master    { --cat-tinte: rgba(168, 85, 247, 0.17); }
.event-card[class*="cat-"] { background-image: linear-gradient(270deg, var(--cat-tinte) 0%, transparent 62%); }

/* ── Diffused category-colour glow when hovering an event card ── */
.event-card.cat-speech:hover {
    border-color: rgba(236, 72, 153, 0.45);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 8px 90px 6px rgba(236, 72, 153, 0.32);
}
.event-card.cat-subtitles:hover {
    border-color: rgba(59, 130, 246, 0.45);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 8px 90px 6px rgba(59, 130, 246, 0.32);
}
.event-card.cat-mixer:hover {
    border-color: rgba(45, 212, 191, 0.45);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 8px 90px 6px rgba(45, 212, 191, 0.32);
}
.event-card.cat-slides:hover {
    border-color: rgba(249, 115, 22, 0.45);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 8px 90px 6px rgba(249, 115, 22, 0.32);
}
/* Master (el quinto tipo): VIOLETA, el mismo tono que CAT_GLOW y el chip de event.html. */
.event-type-badge.master {
    background: rgba(168, 85, 247, 0.16);
    color: #c084fc;
}
.event-card.cat-master:hover {
    border-color: rgba(168, 85, 247, 0.45);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 8px 90px 6px rgba(168, 85, 247, 0.32);
}

/* ── Create-event pill: gradient in the selected type's colour, fading to the dark panel.
   --cat-glow is set per selected type by dashboard.js; as a background-image it layers over
   --bg-panel (above the background colour, below the modal content — no z-index juggling). ── */
#eventModal .modal {
    background-image: linear-gradient(180deg, var(--cat-glow, rgba(236, 72, 153, 0.22)) 0%, transparent 42%);
}

/* ============================================
   DIVINITY NAV SECTION
   ============================================ */

.nav-section-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--gray-600);
    padding: 8px 12px 4px;
    margin-top: 4px;
}

/* ============================================
   TOGGLE SWITCH
   ============================================ */

.toggle-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
}

.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0; left: 0; right: 0; bottom: 0;
    background: var(--gray-700);
    border-radius: 24px;
    transition: var(--transition-fast);
}

.toggle-slider::before {
    content: '';
    position: absolute;
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background: var(--white);
    border-radius: 50%;
    transition: var(--transition-fast);
}

.toggle-switch input:checked + .toggle-slider {
    background: var(--success);
}

.toggle-switch input:checked + .toggle-slider::before {
    transform: translateX(20px);
}

/* ============================================
   LIGHT THEME
   ============================================ */

/* ============================================
   LIGHT MODE — comprehensive overrides
   ============================================ */
[data-theme="light"] {
    --bg-primary: #f5f5f7;
    --bg-panel: rgba(255, 255, 255, 0.92);
    --bg-panel-solid: #ffffff;
    --bg-sidebar: #f8f8fa;
    --gray-950: #f5f5f5;
    --gray-900: #eeeeee;
    --gray-800: #e0e0e0;
    --gray-700: #cccccc;
    --gray-600: #999999;
    --gray-500: #777777;
    --gray-400: #555555;
    --gray-300: #333333;
    --gray-200: #222222;
    --gray-100: #111111;
    --white: #111111;
    --border-subtle: rgba(0, 0, 0, 0.1);
    --border-hover: rgba(0, 0, 0, 0.18);
    --border-active: rgba(0, 0, 0, 0.25);
    --glass-bg: rgb(255 255 255 / 0.72);
    --glass-bg-strong: rgb(255 255 255 / 0.8);
    --glass-blur: saturate(180%) blur(20px);
    --glass-highlight: rgba(255, 255, 255, 0.75);
    --glass-ring: rgba(0, 0, 0, 0.08);
    --glass-shadow:
        inset 0 1px 0 rgb(255 255 255 / 0.75),
        inset 0 0 0 0.5px rgb(255 255 255 / 0.5),
        0 0 0 0.5px rgb(0 0 0 / 0.08),
        0 12px 32px -8px rgb(0 0 0 / 0.18),
        0 2px 6px rgb(0 0 0 / 0.05);
    --c-blue-ink: #006edb;
}

[data-theme="light"] body {
    color: #333333;
}

/* Hide dark-mode decorative backgrounds */
[data-theme="light"] .rays-container,
[data-theme="light"] .light-source,
[data-theme="light"] .atmosphere,
[data-theme="light"] .vignette {
    display: none;
}

/* ── Page Header ─────────────────────────────── */
[data-theme="light"] .page-header {
    background: transparent;
    backdrop-filter: none;
    border: none;
}

[data-theme="light"] .page-title {
    color: #111111;
}

[data-theme="light"] .page-subtitle {
    color: #777777;
}

/* ── Sidebar ─────────────────────────────────── */
[data-theme="light"] .sidebar {
    background: var(--bg-sidebar);
    border-right: 1px solid rgba(0, 0, 0, 0.08);
}


[data-theme="light"] .sidebar-footer {
    border-top: 1px solid rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .nav-item {
    color: #555555;
}

[data-theme="light"] .nav-item:hover {
    background: rgba(0, 0, 0, 0.05);
    color: #333333;
}

[data-theme="light"] .nav-item.active {
    background: rgba(0, 0, 0, 0.08);
    color: #111111;
}

[data-theme="light"] .nav-item svg {
    opacity: 0.6;
}

[data-theme="light"] .nav-divider {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .org-avatar {
    background: #e8e8ec;
    color: #333333;
}
[data-theme="light"] .org-name {
    color: #222222;
}
[data-theme="light"] .footer-divider {
    background: rgba(0, 0, 0, 0.08);
}
[data-theme="light"] .user-avatar {
    background: #e8e8ec;
    color: #333333;
}

[data-theme="light"] .user-info .user-name {
    color: #222222;
}

[data-theme="light"] .user-info .user-email {
    color: #888888;
}

[data-theme="light"] .org-role {
    color: #888888;
}
[data-theme="light"] a.org-info-link:hover {
    background: rgba(0, 0, 0, .05);
}

/* ── Cards / Panels ──────────────────────────── */
[data-theme="light"] .card {
    background: rgba(255, 255, 255, 0.7);
    border: none;
    box-shadow:
        0 8px 30px rgba(0, 0, 0, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.9),
        inset 0 0 30px 2px rgba(255, 255, 255, 0.4);
}

[data-theme="light"] .card::before,
[data-theme="light"] .card::after,
[data-theme="light"] .event-card::before,
[data-theme="light"] .modal::before {
    background: none;
}

[data-theme="light"] .event-card {
    border: none;
    box-shadow:
        0 1px 3px rgba(0, 0, 0, 0.04),
        0 4px 16px rgba(0, 0, 0, 0.03);
}

[data-theme="light"] .event-card:hover {
    box-shadow:
        0 4px 12px rgba(0, 0, 0, 0.06),
        0 8px 32px rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .event-code {
    background: rgba(0, 0, 0, 0.05);
    color: #555555;
}

[data-theme="light"] .channel-card {
    background: rgba(0, 0, 0, 0.02);
    border-color: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .channel-card:hover {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .channel-badge {
    color: #ffffff;
    background: #333333;
}

[data-theme="light"] .stat-card {
    background: rgba(0, 0, 0, 0.02);
    border-color: rgba(0, 0, 0, 0.06);
}

/* ── Buttons ─────────────────────────────────── */
/* En claro el principal era NEGRO (#111): cristal oscuro, como antes. */
[data-theme="light"] .btn-primary {
    background: rgb(17 17 17 / 0.88);
    color: #ffffff;
    box-shadow: 0 6px 18px -6px rgb(0 0 0 / 0.3);
}

[data-theme="light"] .btn-primary:hover:not(:disabled) {
    background: rgb(17 17 17 / 0.96);
}

[data-theme="light"] .btn-secondary {
    background: rgb(255 255 255 / 0.55);
    color: #1d1d1f;
    border: none;
    box-shadow: 0 0 0 0.5px rgb(0 0 0 / 0.08), 0 4px 14px -6px rgb(0 0 0 / 0.18);
}

[data-theme="light"] .btn-secondary:hover:not(:disabled) {
    background: rgb(255 255 255 / 0.75);
}

[data-theme="light"] .btn-ghost {
    color: #555555;
}

[data-theme="light"] .btn-danger {
    background: rgb(255 255 255 / 0.55);
    color: #1d1d1f;
    box-shadow: 0 0 0 0.5px rgb(0 0 0 / 0.08), 0 4px 14px -6px rgb(0 0 0 / 0.18);
}

[data-theme="light"] .btn-danger:hover:not(:disabled),
[data-theme="light"] .btn-danger:focus-visible {
    background: rgb(239 68 68 / 0.14);
    color: #b91c1c;
    box-shadow: inset 0 0 0 1px rgb(239 68 68 / 0.4), 0 6px 18px -6px rgb(239 68 68 / 0.4);
}

[data-theme="light"] .btn-ghost:hover:not(:disabled) {
    background: rgba(0, 0, 0, 0.05);
    color: #333333;
}

/* ── Tabs ────────────────────────────────────── */

[data-theme="light"] .tab {
    color: #777777;
}

[data-theme="light"] .tab:hover {
    color: #444444;
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .tab.active {
    color: #111111;
    background: rgba(0, 0, 0, 0.06);
    border-bottom-color: #111111;
}

/* ── Forms ────────────────────────────────────── */
[data-theme="light"] .form-input,
[data-theme="light"] .form-select,
[data-theme="light"] .form-textarea {
    /* background-COLOR, no el atajo: el atajo borraba la flecha de .form-select (background-image)
       y en claro todos los desplegables salían sin flecha (lo vio el rediseño de Users, 05-11). */
    background-color: rgba(0, 0, 0, 0.03);
    color: #222222;
    border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .form-input::placeholder,
[data-theme="light"] .form-textarea::placeholder {
    color: #aaaaaa;
}

[data-theme="light"] .form-input:focus,
[data-theme="light"] .form-select:focus,
[data-theme="light"] .form-textarea:focus {
    border-color: rgba(0, 0, 0, 0.25);
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05);
    background-color: #ffffff;
}

[data-theme="light"] .form-select option {
    background: #ffffff;
    color: #222222;
}

[data-theme="light"] .form-label {
    color: #444444;
}

[data-theme="light"] .form-group .text-muted,
[data-theme="light"] .text-muted {
    color: #888888;
}

/* ── Modals ───────────────────────────────────── */
[data-theme="light"] .modal-overlay {
    background: rgba(0, 0, 0, 0.2);
}

[data-theme="light"] .modal {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.08);
    box-shadow: 0 16px 64px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .modal-header {
    border-bottom-color: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .modal-title {
    color: #111111;
}

[data-theme="light"] .modal-close {
    color: #777777;
}

[data-theme="light"] .modal-close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: #333333;
}

/* ── Badges / Status ─────────────────────────── */
[data-theme="light"] .badge {
    background: rgba(0, 0, 0, 0.06);
    color: #555555;
}

[data-theme="light"] .badge-success { background: rgba(34, 197, 94, 0.1); color: #16a34a; }
[data-theme="light"] .badge-warning { background: rgba(245, 158, 11, 0.1); color: #d97706; }
[data-theme="light"] .badge-error   { background: rgba(239, 68, 68, 0.1); color: #dc2626; }
[data-theme="light"] .badge-info    { background: rgba(59, 130, 246, 0.1); color: #2563eb; }

/* ── Terminal ─────────────────────────────────── */
[data-theme="light"] .terminal {
    background: #fafafa;
    border: 1px solid rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .terminal-header {
    background: rgba(0, 0, 0, 0.03);
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

/* ── Tables ───────────────────────────────────── */
[data-theme="light"] .table th {
    background: rgba(0, 0, 0, 0.03);
    color: #555555;
}

[data-theme="light"] .table td {
    border-color: rgba(0, 0, 0, 0.05);
}

[data-theme="light"] .table tr:hover {
    background: rgba(0, 0, 0, 0.02);
}

[data-theme="light"] .users-table tr:hover {
    background: rgba(0, 0, 0, 0.02);
}

/* ── Toggle switch ────────────────────────────── */
[data-theme="light"] .toggle-slider {
    background: #cccccc;
}

/* ── Tooltips ─────────────────────────────────── */
[data-theme="light"] .tooltip {
    background: #333333;
    color: #ffffff;
}

/* ── QR Container ─────────────────────────────── */
[data-theme="light"] .qr-container {
    background: #f5f5f5;
    border: 1px solid rgba(0, 0, 0, 0.08);
}

/* ── Scrollbar ────────────────────────────────── */
[data-theme="light"] ::-webkit-scrollbar-track {
    background: transparent;
}

[data-theme="light"] ::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.12);
    border-radius: 4px;
}

[data-theme="light"] ::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 0, 0, 0.2);
}

/* ── Empty State ──────────────────────────────── */
[data-theme="light"] .empty-state {
    color: #888888;
}

[data-theme="light"] .empty-state-icon {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .empty-state-title {
    color: #444444;
}

/* ── Loading spinner ──────────────────────────── */
[data-theme="light"] .spinner {
    border-color: rgba(0, 0, 0, 0.1);
    border-top-color: #333333;
}

/* ── Tags / Vocab ─────────────────────────────── */
[data-theme="light"] .tag {
    background: rgba(0, 0, 0, 0.05);
    color: #555555;
}

[data-theme="light"] .tag:hover {
    background: rgba(0, 0, 0, 0.08);
}

/* ── Agenda / Schedule ────────────────────────── */
[data-theme="light"] .schedule-item,
[data-theme="light"] .agenda-item {
    background: rgba(0, 0, 0, 0.02);
    border: 1px solid rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .calendar-nav-btn {
    color: #555555;
    border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .calendar-nav-btn:hover {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .calendar-today-btn {
    color: #555555;
}

[data-theme="light"] .day-header {
    color: #777777;
}

[data-theme="light"] .day-cell {
    border-color: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .day-cell:hover {
    background: rgba(0, 0, 0, 0.02);
}

/* ── Conditionals ─────────────────────────────── */
[data-theme="light"] .conditional-rule {
    background: rgba(0, 0, 0, 0.02);
}

/* ── Account page ─────────────────────────────── */
[data-theme="light"] .account-section {
    border-color: rgba(0, 0, 0, 0.06);
}

/* ── Admin page ───────────────────────────────── */
[data-theme="light"] .admin-card {
    background: var(--bg-panel);
    border: 1px solid rgba(0, 0, 0, 0.06);
}

/* ── Links ────────────────────────────────────── */
[data-theme="light"] a.text-muted {
    color: #666666;
}

[data-theme="light"] a.text-muted:hover {
    color: #333333;
}

/* ============================================
   VOCABULARY SECTION
   ============================================ */

.vocab-section {
    margin-bottom: 24px;
}

.vocab-section-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.vocab-section-desc {
    font-size: 13px;
    color: var(--gray-500);
    margin-bottom: 12px;
}

.vocab-textarea {
    width: 100%;
    min-height: 120px;
    padding: 12px 16px;
    font-size: 13px;
    font-family: var(--font-mono);
    color: var(--white);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-sm);
    resize: vertical;
    transition: var(--transition-fast);
}

.vocab-textarea:focus {
    outline: none;
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--border-active);
}

.vocab-char-count {
    font-size: 12px;
    color: var(--gray-600);
    text-align: right;
    margin-top: 4px;
}

.translation-term-row {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 8px;
    margin-bottom: 8px;
    align-items: center;
}

.translation-term-row .form-input {
    padding: 10px 12px;
    font-size: 13px;
}

/* ============================================
   CONDITIONAL RULES
   ============================================ */

.conditional-rule {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius-sm);
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.conditional-rule .form-select {
    width: auto;
    min-width: 120px;
    padding: 8px 36px 8px 12px;
    font-size: 13px;
}

.conditional-label {
    font-size: 13px;
    color: var(--gray-400);
    font-weight: 500;
}

/* ============================================
   AGENDA TIMELINE
   ============================================ */

.agenda-timeline {
    position: relative;
    padding-left: 24px;
}

.agenda-timeline::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--border-subtle);
}

.agenda-item {
    position: relative;
    padding: 16px 0 16px 24px;
    border-bottom: 1px solid var(--border-subtle);
}

.agenda-item::before {
    content: '';
    position: absolute;
    left: -29px;
    top: 22px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--gray-600);
    border: 2px solid var(--bg-primary);
}

.agenda-item.active::before {
    background: var(--success);
    box-shadow: 0 0 8px var(--success);
}

.agenda-item.streaming::before {
    background: var(--info);
    box-shadow: 0 0 8px var(--info);
}

.agenda-time {
    font-size: 12px;
    font-weight: 600;
    color: var(--gray-500);
    margin-bottom: 4px;
}

.agenda-event-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--white);
}

.agenda-event-meta {
    font-size: 13px;
    color: var(--gray-500);
    margin-top: 4px;
}

/* ============================================
   LEARN / COURSES
   ============================================ */

.courses-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
}

.course-card {
    background: var(--bg-panel);
    backdrop-filter: blur(40px);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
    overflow: hidden;
    cursor: pointer;
    transition: var(--transition);
}

.course-card:hover {
    border-color: var(--border-hover);
    transform: translateY(-4px);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
}

.course-thumbnail {
    width: 100%;
    height: 160px;
    background: linear-gradient(135deg, var(--gray-800), var(--gray-900));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 48px;
}

.course-body {
    padding: 16px 20px;
}

.course-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.course-desc {
    font-size: 13px;
    color: var(--gray-500);
    margin-bottom: 12px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.course-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 12px;
    color: var(--gray-500);
}

.progress-bar {
    width: 100%;
    height: 4px;
    background: var(--gray-800);
    border-radius: 2px;
    margin-top: 12px;
    overflow: hidden;
}

.progress-bar-fill {
    height: 100%;
    background: var(--success);
    border-radius: 2px;
    transition: width 0.3s ease;
}

/* ============================================
   ORGANIZATION CARDS
   ============================================ */

/* Divinity /orgs grid: 4 opaque frosted-glass cards per row, each with its own colour wave. */
.orgs-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 22px;
    align-items: start;
}
@media (max-width: 1200px) { .orgs-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 900px)  { .orgs-grid { grid-template-columns: repeat(2, 1fr); } }

.org-card {
    position: relative;
    overflow: hidden;
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: 1px solid transparent;
    border-radius: 16px;
    padding: 20px;
    min-height: 150px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-shadow: var(--glass-shadow);
    transition: transform .22s cubic-bezier(.2,.85,.3,1), box-shadow .22s;
}
/* Per-org colour wave rising from the bottom, tinted by --wave-hue (set inline per card). */
.org-card::before {
    content: '';
    position: absolute;
    left: -15%; right: -15%; top: 0; bottom: 0;
    pointer-events: none;
    background:
      radial-gradient(78% 62% at 30% 122%, hsla(var(--wave-hue, 220), 72%, 54%, .5), transparent 62%),
      radial-gradient(66% 54% at 76% 128%, hsla(calc(var(--wave-hue, 220) + 22), 74%, 50%, .38), transparent 60%);
    filter: blur(14px);
    animation: orgWave 9s ease-in-out infinite alternate;
}
.org-card > * { position: relative; z-index: 1; }
@keyframes orgWave { 0% { transform: translate3d(-6%, 3%, 0) scale(1.06); } 100% { transform: translate3d(7%, -4%, 0) scale(1.2); } }
@media (prefers-reduced-motion: reduce) { .org-card::before { animation: none; } }

.org-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--glass-shadow), 0 22px 50px -18px hsla(var(--wave-hue, 220), 60%, 45%, .55);
}

.org-handle {
    font-size: 13px;
    font-family: var(--font-mono);
    color: var(--info);
    margin-bottom: 4px;
}

.org-name {
    font-size: 18px;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 8px;
}

.org-meta {
    display: flex;
    gap: 16px;
    font-size: 13px;
    color: var(--gray-500);
}

/* ============================================
   TOAST NOTIFICATIONS
   ============================================ */
#toast-container {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 10000;
    display: flex;
    flex-direction: column-reverse;
    gap: 8px;
    pointer-events: none;
}
.toast {
    padding: 10px 18px;
    border-radius: 10px;
    font-size: 0.825rem;
    font-weight: 500;
    color: var(--white);
    pointer-events: auto;
    animation: toast-in 0.25s ease-out;
    max-width: 380px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.3);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
}
.toast.toast-success {
    background: rgba(34, 197, 94, 0.9);
}
.toast.toast-error {
    background: rgba(239, 68, 68, 0.9);
}
.toast.toast-info {
    background: rgba(59, 130, 246, 0.9);
}
.toast.toast-out {
    animation: toast-out 0.2s ease-in forwards;
}
@keyframes toast-in {
    from { opacity: 0; transform: translateY(12px) scale(0.95); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toast-out {
    from { opacity: 1; transform: translateY(0) scale(1); }
    to { opacity: 0; transform: translateY(8px) scale(0.95); }
}
[data-theme="light"] .toast { color: #fff; }

/* ============================================
   BILLBOARD — global Divinity banner + must-accept notification
   ============================================ */
.billboard-banner {
    position: fixed; top: 0; left: 0; right: 0; height: 40px; z-index: 300;
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 0 48px; font-size: 13.5px; font-weight: 600; text-align: center;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}
/* When the banner is up, push the sidebar + content down so nothing hides behind it. */
body.billboard-on .sidebar { top: var(--billboard-h, 0px); height: calc(100vh - var(--billboard-h, 0px)); }
body.billboard-on .main-content { padding-top: var(--billboard-h, 0px); }

.billboard-notif-back {
    position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center;
    background: rgba(4, 4, 8, 0.72); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.billboard-notif-card {
    max-width: 420px; width: calc(100% - 40px); text-align: center; padding: 34px 32px 28px;
    border-radius: 20px; background: var(--bg-panel-solid, #0e0e10);
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.billboard-notif-card .bn-emoji { font-size: 46px; line-height: 1; margin-bottom: 14px; }
.billboard-notif-card .bn-title { color: var(--white); font-size: 1.3rem; font-weight: 700; letter-spacing: -0.01em; }
.billboard-notif-card .bn-sub { color: var(--gray-400); font-size: 0.95rem; line-height: 1.5; margin-top: 10px; }
.billboard-notif-card .bn-ok {
    margin-top: 24px; min-width: 140px; padding: 11px 24px; border: none; border-radius: 12px; cursor: pointer;
    background: #fff; color: #111; font-size: 0.95rem; font-weight: 700; transition: transform 0.12s, box-shadow 0.2s;
}
.billboard-notif-card .bn-ok:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgba(255, 255, 255, 0.15); }
/* En claro la tarjeta es --bg-panel-solid = #fff: el OK blanco desaparecía (blanco sobre blanco).
   Lo vio el rediseño de Behaviour (05-11), cuya vista previa usa estas mismas clases. */
[data-theme="light"] .billboard-notif-card .bn-ok { background: #111; color: #fff; }
[data-theme="light"] .billboard-notif-card .bn-ok:hover { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); }

/* ═══════════════════════════════════════════════════════════════════════════
   WIDGET · FONDO NEGRO
   ───────────────────────────────────────────────────────────────────────────
   El resto de Backstage lleva el decorado de luz: seis rayos animados, un foco,
   una atmósfera y una viñeta. En Widget estorba, y hay una razón concreta y no
   estética: estas pantallas enseñan el widget de accesibilidad del cliente —su
   color de marca, sus filtros de color, sus modos de contraste— y juzgar un
   color sobre un fondo que late y cambia de luminosidad es juzgarlo mal.

   Se apaga con una clase en el <body> en vez de quitando los divs de las
   plantillas, para que un decorado nuevo que alguien añada mañana también se
   apague aquí sin acordarse de este fichero.

   ⚠ Es cosmética, NO layout. La memoria del proyecto avisa de meter layout en
     una clase del <body>: convierte en bug toda ruta que olvide limpiarla.
     Aquí no aplica —cada pantalla es una carga completa, no hay SPA que
     arrastre la clase— y aun así no se toca ni una propiedad de caja.
   ═══════════════════════════════════════════════════════════════════════════ */
body.widget-negro {
    background: #000;
}
body.widget-negro .rays-container,
body.widget-negro .light-source,
body.widget-negro .atmosphere,
body.widget-negro .vignette {
    display: none !important;
}
/* Los mismos resplandores viven también en pseudoelementos del body en algunas
   pantallas. Si no se apagan, el fondo queda «casi» negro con una mancha, que
   es peor que dejarlo como estaba. */
body.widget-negro::before,
body.widget-negro::after {
    display: none !important;
}

/* ═══ EL BOTÓN «i» DE INFORMACIÓN ═══════════════════════════════════════════
   Hector, 2026-09-24: todo bloque o función (menos los controllers) lleva una
   «i» redonda que dice qué es y cómo funciona. El comportamiento vive en
   static/js/info.js; aquí sólo la forma. Todo sale de tokens: vale igual en
   el tema claro y en el oscuro sin una regla por tema. */
.info-i {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 auto;
    width: 18px; height: 18px; padding: 0; margin: 0 0 0 6px;
    border-radius: 50%;
    border: 1px solid var(--border-hover);
    background: transparent;
    color: var(--gray-300);
    font: italic 600 11px/1 Georgia, 'Times New Roman', serif;
    cursor: pointer; vertical-align: middle;
    transition: color .15s ease, border-color .15s ease, background .15s ease;
    -webkit-tap-highlight-color: transparent;
}
.info-i:hover, .info-i[aria-expanded="true"] {
    color: var(--white); border-color: var(--gray-400);
    background: var(--border-subtle);
}
.info-i:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
/* Un dedo necesita más que 18 px: el área táctil crece sin que crezca el dibujo. */
@media (pointer: coarse) {
    .info-i { position: relative; }
    .info-i::after { content: ''; position: absolute; inset: -12px; }
}
.info-pop {
    position: fixed; z-index: 10000;
    max-width: min(300px, calc(100vw - 24px));
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid var(--border-hover);
    background: var(--bg-panel-solid);
    color: var(--gray-300);
    font: 400 13px/1.45 var(--font-family);
    letter-spacing: -0.005em;
    box-shadow: 0 12px 32px rgba(0, 0, 0, .35);
    animation: info-pop-entra .14s ease-out;
    pointer-events: auto;
}
@keyframes info-pop-entra { from { opacity: 0; transform: translateY(-3px); } }
.info-pop.arriba { animation-name: info-pop-entra-arriba; }
@keyframes info-pop-entra-arriba { from { opacity: 0; transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .info-pop { animation: none; } }


/* ═══════════════════════════════════════════════════════════════════════════
   CRISTAL LÍQUIDO: LA LUZ DE LOS BOTONES Y LO QUE EXIGE LA ACCESIBILIDAD (2026-10-31)
   ═══════════════════════════════════════════════════════════════════════════
   De link3rs.com (global.css: [data-liquid], .lq-shine). El script es static/js/liquid.js;
   `data-liquid-ready` lo pone él en cada botón que ata. NO van: los badges ni los controllers
   con estilo skeuomórfico (Hector, 2026-10-31).
   ═══════════════════════════════════════════════════════════════════════════ */
/* Las reglas de los botones líquidos (`[data-liquid-ready]`, `.lq-shine`, `.lq-copia`) las pone
   el propio liquid.js (`ESTILOS`): el mismo fichero sirve a Backstage y a Live. */

/* ── Accesibilidad: lo que la guía exige siempre ────────────────────────── */
/* «Reducir transparencia»: el cristal se vuelve opaco (§5, «always the opaque fallback»).
   Theme.applyGlass() hace lo mismo con los valores de Behaviour → Design. */
@media (prefers-reduced-transparency: reduce) {
    :root { --glass-bg: #161617; --glass-bg-strong: #161617; --glass-blur: none; }
    [data-theme="light"] { --glass-bg: #ffffff; --glass-bg-strong: #ffffff; --glass-blur: none; }
}

/* ── Los desplegables y los pop-ups: radio de menú 18 px, sin borde, con el canto de luz y la
   sombra del cristal. Salen del botón que los abre con el morph de liquid.js (§8).
   ⚠ OPACOS, NO DE CRISTAL: casi siempre se abren ENCIMA de una tarjeta, y la guía (§5) y la casa
   dicen lo mismo: nunca cristal sobre cristal (se transparentaban el QR y el código de School;
   test_school_cada_papel_en_el_navegador). `:root` delante para ganar a cabecera-lista.css. */
:root .sort-menu,
:root .space-menu,
:root .info-pop {
    background: var(--bg-panel-solid);
    border: none;
    border-radius: 18px;
    box-shadow: var(--glass-shadow), 0 14px 34px rgba(0, 0, 0, 0.45);
}

/* ── La lista de un <select> (liquid.js): sale del propio select con el morph que rebota.
   Opaca como los menús (casi siempre se abre encima de una tarjeta), con el canto y la sombra
   del cristal. El <select> de debajo sigue mandando: esto sólo pinta sus opciones. */
.lq-lista {
    position: fixed;
    z-index: 10050;
    box-sizing: border-box;
    min-width: 160px;
    max-width: min(420px, calc(100vw - 16px));
    overflow-y: auto;
    padding: 6px;
    background: var(--bg-panel-solid);
    border-radius: 18px;
    box-shadow: var(--glass-shadow), 0 14px 34px rgba(0, 0, 0, 0.45);
    color: var(--gray-200);
    font-family: var(--font-family);
    font-size: 14px;
    line-height: 1.3;
}
.lq-lista-op {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 34px;
    padding: 7px 12px;
    border-radius: 10px;
    cursor: pointer;
    white-space: nowrap;
    outline: none;
}
/* ⚠ Resaltado SÓLO con el ratón encima o con el teclado (`data-activa`, lo pone liquid.js),
   no con el foco a secas: al abrir, el foco va a la opción elegida y se quedaba «con cristal» mientras el ratón
   estaba en otra (Hector, 31-10). La elegida se marca con el ✓, no con el fondo. */
.lq-lista-op:hover,
.lq-lista-op[data-activa] {
    background: rgba(255, 255, 255, 0.08);
    color: var(--white);
}
.lq-lista-op[aria-selected="true"] {
    color: var(--white);
    font-weight: 500;
}
.lq-lista-op[aria-selected="true"]::after {
    content: '✓';
    color: var(--c-blue-ink);
}
.lq-lista-op[aria-disabled="true"] {
    opacity: 0.4;
    cursor: default;
}
.lq-lista-grupo {
    padding: 8px 12px 4px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gray-500);
}
[data-theme="light"] .lq-lista-op:hover,
[data-theme="light"] .lq-lista-op[data-activa] {
    background: rgba(0, 0, 0, 0.05);
}

/* ── La pastilla que se desliza bajo la pestaña elegida (guía §10, «Segmented tabs»; en oscuro,
   la de «Backstage modes»): la pone liquid.js en los carriles de pestañas y se mueve y cambia
   de ancho con el muelle líquido. */
.lq-ind {
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 0;
    width: var(--w, 0px);
    translate: var(--x, 0px) 0;
    border-radius: 999px;
    background: rgb(255 255 255 / 0.16);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.14), 0 4px 14px rgb(0 0 0 / 0.18);
    pointer-events: none;
    transition: translate var(--spring-liquid-dur) var(--spring-liquid),
        width var(--spring-liquid-dur) var(--spring-liquid), opacity 0.2s;
}
[data-theme="light"] .lq-ind {
    background: #ffffff;
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.08), 0 4px 14px rgb(0 0 0 / 0.1);
}
@media (prefers-reduced-motion: reduce) {
    .lq-ind { transition: opacity 0.2s; }
}
