/* ════════════════════════════════════════════════════════════
 * LA BÓVEDA · tokens.css · DDL-001
 * Single source of truth visual de toda la plataforma.
 * Curadores: LINK (auditoría) + MAMA (autoría) + ICON (icon scale).
 *
 * REGLA MAESTRA: ningún CSS de La Bóveda usa hex/rgb/named colors
 * directamente. Todo pasa por var(--token). LINK bloquea PRs que
 * lo violen.
 *
 * Mantenemos intactos: brand-primary #FFCC00, dark-first,
 * Inter/Satoshi/JetBrains Mono. Todo lo demás puede evolucionar.
 * ════════════════════════════════════════════════════════════ */

:root {

    /* ── COLOR · MARCA (intocables) ─────────────────────────── */
    --brand-primary:           #FFCC00;
    --brand-primary-hover:     #E6B800;
    --brand-primary-active:    #CCA300;
    --brand-primary-soft:      rgba(255, 204, 0, 0.10);  /* fondo sutil de elementos brand */
    --brand-primary-text:      #0A0A0F;                   /* texto sobre brand (negro, alto contraste) */

    /* ── COLOR · SUPERFICIES (dark-first) ───────────────────── */
    --surface-page:            #0A0A0F;   /* fondo principal del documento */
    --surface-card:            #14141B;   /* cards, modales, paneles */
    --surface-elevated:        #1C1C25;   /* hover de cards, dropdowns */
    --surface-overlay:         rgba(10, 10, 15, 0.72); /* overlay de modales */

    /* ── COLOR · TEXTO ──────────────────────────────────────── */
    --text-primary:            #FAFAFA;   /* texto principal */
    --text-secondary:          #A3A3B0;   /* labels, captions, metadata */
    --text-muted:              #6E6E78;   /* placeholder, disabled */
    --text-inverse:            #0A0A0F;   /* texto sobre fondos claros (brand-primary) */

    /* ── COLOR · BORDES ─────────────────────────────────────── */
    --border-subtle:           #2A2A35;
    --border-default:          #3A3A48;
    --border-strong:           #525266;
    --border-focus:            var(--brand-primary);

    /* ── COLOR · ESTADO ─────────────────────────────────────── */
    --success:                 #22C55E;
    --success-bg:              rgba(34, 197, 94, 0.10);
    --success-border:          rgba(34, 197, 94, 0.30);

    --warning:                 #F59E0B;
    --warning-bg:              rgba(245, 158, 11, 0.10);
    --warning-border:          rgba(245, 158, 11, 0.30);

    --error:                   #EF4444;
    --error-bg:                rgba(239, 68, 68, 0.10);
    --error-border:            rgba(239, 68, 68, 0.30);

    --info:                    #3B82F6;
    --info-bg:                 rgba(59, 130, 246, 0.10);
    --info-border:             rgba(59, 130, 246, 0.30);

    /* ── TIPOGRAFÍA · FAMILIAS (intocables) ─────────────────── */
    --font-display:            'Satoshi', 'Inter', system-ui, sans-serif;       /* headlines hero */
    --font-body:               'Inter', system-ui, -apple-system, sans-serif;   /* TODO el body */
    --font-mono:               'JetBrains Mono', 'SF Mono', Menlo, monospace;   /* código, números técnicos */

    /* ── TIPOGRAFÍA · ESCALA (modular 1.25) ─────────────────── */
    --font-size-xs:            0.75rem;    /* 12px */
    --font-size-sm:            0.875rem;   /* 14px */
    --font-size-base:          1rem;       /* 16px */
    --font-size-md:            1.125rem;   /* 18px */
    --font-size-lg:            1.25rem;    /* 20px */
    --font-size-xl:            1.5rem;     /* 24px */
    --font-size-2xl:           1.875rem;   /* 30px */
    --font-size-3xl:           2.25rem;    /* 36px */
    --font-size-4xl:           3rem;       /* 48px */
    --font-size-5xl:           3.75rem;    /* 60px - hero headlines */

    /* ── TIPOGRAFÍA · PESOS ─────────────────────────────────── */
    --font-weight-regular:     400;
    --font-weight-medium:      500;
    --font-weight-semibold:    600;
    --font-weight-bold:        700;

    /* ── TIPOGRAFÍA · LINE HEIGHT ───────────────────────────── */
    --line-height-tight:       1.15;   /* headlines */
    --line-height-snug:        1.35;
    --line-height-normal:      1.5;    /* body por defecto */
    --line-height-relaxed:     1.75;   /* lecturas largas */

    /* ── SPACING · ESCALA ÚNICA (8/16/24/32/48/64/96) ──────── */
    --space-1:                 0.25rem;   /* 4px  - micro ajustes */
    --space-2:                 0.5rem;    /* 8px  - BASE */
    --space-3:                 0.75rem;   /* 12px */
    --space-4:                 1rem;      /* 16px */
    --space-5:                 1.25rem;   /* 20px */
    --space-6:                 1.5rem;    /* 24px */
    --space-8:                 2rem;      /* 32px */
    --space-10:                2.5rem;    /* 40px */
    --space-12:                3rem;      /* 48px */
    --space-16:                4rem;      /* 64px */
    --space-20:                5rem;      /* 80px */
    --space-24:                6rem;      /* 96px */

    /* ── RADIUS ─────────────────────────────────────────────── */
    --radius-sm:               6px;       /* inputs, badges */
    --radius-md:               12px;      /* cards, buttons */
    --radius-lg:               16px;      /* modales */
    --radius-xl:               20px;      /* hero cards, paneles grandes */
    --radius-2xl:              28px;
    --radius-full:             9999px;    /* pills, avatares */

    /* ── ICONOS · TAMAÑOS CANÓNICOS (ICON manda) ────────────── */
    --icon-xs:                 12px;
    --icon-sm:                 16px;
    --icon-md:                 20px;      /* default */
    --icon-lg:                 24px;
    --icon-xl:                 32px;
    --icon-2xl:                48px;

    /* ── SOMBRAS (dark-first: sombras sutiles, glow para focus) */
    --shadow-sm:               0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md:               0 4px 12px rgba(0, 0, 0, 0.4);
    --shadow-lg:               0 12px 32px rgba(0, 0, 0, 0.5);
    --shadow-glow-brand:       0 0 0 3px rgba(255, 204, 0, 0.25);  /* focus ring */

    /* ── MOTION (curvas fuertes · filosofía Emil Kowalski) ──── */
    --motion-fast:             120ms;   /* press feedback, tooltips, hovers */
    --motion-base:             200ms;   /* dropdowns, selects, entradas */
    --motion-slow:             280ms;   /* modales, drawers (UI siempre < 300ms) */
    --ease-out:                cubic-bezier(0.16, 1, 0.3, 1);     /* entra/sale · responde al instante */
    --ease-in-out:             cubic-bezier(0.77, 0, 0.175, 1);   /* mueve/transforma en pantalla */
    --ease-drawer:             cubic-bezier(0.32, 0.72, 0, 1);    /* drawers/paneles estilo iOS */
    --ease-spring:             cubic-bezier(0.34, 1.56, 0.64, 1); /* rebote sutil · solo deleites raros */
    --stagger-step:            40ms;     /* retraso entre items de una lista que entra en cascada */

    /* ── BREAKPOINTS (referencia · usar en media queries) ──── */
    /* mobile:    < 768px  */
    /* tablet:    768px - 1023px */
    /* desktop:   >= 1024px */
    /* No son tokens CSS porque media queries no usan vars */

    /* ── Z-INDEX (escala ordenada) ──────────────────────────── */
    --z-base:                  0;
    --z-dropdown:              100;
    --z-sticky:                200;
    --z-overlay:               300;
    --z-modal:                 400;
    --z-popover:               500;
    --z-toast:                 600;
    --z-tooltip:               700;

    /* ── LAYOUT ─────────────────────────────────────────────── */
    --container-sm:            640px;
    --container-md:            768px;
    --container-lg:            1024px;
    --container-xl:            1280px;
    --container-2xl:           1440px;
}

/* ════════════════════════════════════════════════════════════
 * RESET BASE (mínimo, no opinado)
 * ════════════════════════════════════════════════════════════ */

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

html {
    font-family: var(--font-body);
    font-size: 16px;
    line-height: var(--line-height-normal);
    color-scheme: dark;
    -webkit-text-size-adjust: 100%;
    /* Render más nítido de la fuente (Emil: la calidad del texto se siente). */
    text-rendering: optimizeLegibility;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--surface-page);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Focus accesible siempre visible y consistente */
:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ════════════════════════════════════════════════════════════
 * SCROLLBARS — sutiles, consistentes con dark-first
 * Aplica globalmente. Personaliza para que NO aparezcan tracks
 * blancos/gigantes en macOS Chrome.
 * ════════════════════════════════════════════════════════════ */

/* Firefox: thumb sutil que aparece al hover del contenedor */
* {
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}
*:hover {
    scrollbar-color: var(--border-default) transparent;
}

/* WebKit (Chrome, Safari, Edge): thumb invisible por default, aparece al hover */
*::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}
*::-webkit-scrollbar-track {
    background: transparent;
}
*::-webkit-scrollbar-thumb {
    background: transparent;
    border-radius: var(--radius-full);
    transition: background var(--motion-fast) var(--ease-out);
}
*:hover::-webkit-scrollbar-thumb {
    background: var(--border-default);
}
*::-webkit-scrollbar-thumb:hover {
    background: var(--border-strong);
}
*::-webkit-scrollbar-corner {
    background: transparent;
}

/* ════════════════════════════════════════════════════════════
 * COMPONENTES GLOBALES DEL ADMIN
 * (extraídos para que apliquen en TODAS las páginas, no scoped)
 * ════════════════════════════════════════════════════════════ */

/* Select custom · oculta chevron nativo del browser y pinta uno propio */
.bvd-int2-select { position: relative; }
.bvd-int2-select::after {
    content: '▾';
    position: absolute;
    right: var(--space-3);
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-secondary);
    pointer-events: none;
    font-size: var(--font-size-sm);
}
.bvd-int2-select select {
    width: 100%;
    padding: var(--space-2) var(--space-6) var(--space-2) var(--space-3);
    background: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: var(--font-size-sm);
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    cursor: pointer;
    background-image: none;
}
.bvd-int2-select select:focus {
    outline: none;
    border-color: var(--brand-primary);
    box-shadow: var(--shadow-glow-brand);
}
.bvd-int2-select select option {
    background: var(--surface-card);
    color: var(--text-primary);
}

/* File input custom — dropzone con brand */
.bvd-file-drop {
    position: relative;
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-4);
    background: var(--surface-card);
    border: 1px dashed var(--border-default);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color var(--motion-fast) var(--ease-out),
                background var(--motion-fast) var(--ease-out);
}
.bvd-file-drop:hover { border-color: var(--brand-primary); background: var(--surface-elevated); }
.bvd-file-drop.is-drag-over { border-color: var(--brand-primary); background: var(--brand-primary-soft); }
.bvd-file-drop__icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px;
    background: var(--surface-page);
    color: var(--brand-primary);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}
.bvd-file-drop__body { flex: 1; min-width: 0; }
.bvd-file-drop__title {
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    display: block;
    margin-bottom: 2px;
}
.bvd-file-drop__hint {
    color: var(--text-muted);
    font-size: 11px;
    line-height: var(--line-height-snug);
}
.bvd-file-drop input[type="file"] {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
.bvd-file-drop__preview {
    color: var(--brand-primary);
    font-size: var(--font-size-xs);
    font-weight: 600;
    margin-top: var(--space-1);
}

/* ════════════════════════════════════════════════════════════
 * SECTION LAYOUT MAESTRO — patrón obligatorio en TODAS las
 * secciones del admin (Alumnos, Tickets, Comunidad, etc.)
 *
 * Estructura:
 *   1. Header con título + descripción opcional + toolbar derecha
 *      (buscador + botón acción contextual)
 *   2. Row de 1-4 KPI cards (mini-tarjetas)
 *   3. Bulk-action bar (oculta · aparece al marcar checkboxes)
 *   4. Lista/tabla con checkbox column
 * ════════════════════════════════════════════════════════════ */
.bvd-section { display: flex; flex-direction: column; gap: var(--space-4); }

.bvd-section__header {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
}
.bvd-section__title-block { flex: 1; min-width: 0; }

/* Info chip · banner compacto inline (reemplaza title/desc cuando hay banner explicativo) */
.bvd-section__info-chip {
    flex: 1; min-width: 0;
    display: inline-flex; align-items: center; gap: 8px;
    padding: 10px 14px;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-snug);
}
.bvd-section__info-chip-icon {
    display: inline-flex;
    color: var(--brand-primary);
    flex-shrink: 0;
}
.bvd-section__info-chip-label strong { color: var(--text-primary); font-weight: var(--font-weight-semibold); }
.bvd-section__info-chip-body {
    color: var(--text-muted);
    border-left: 1px solid var(--border-default);
    padding-left: 8px;
    margin-left: 2px;
}
.bvd-section__title {
    margin: 0 0 var(--space-1);
    font-family: var(--font-display);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}
.bvd-section__desc {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-relaxed);
    max-width: 720px;
}
.bvd-section__toolbar {
    display: flex; align-items: center; gap: var(--space-2);
    flex-shrink: 0;
}
.bvd-section__search {
    position: relative;
    width: 280px;
}
.bvd-section__search input {
    width: 100%;
    padding: 8px 12px 8px 36px;
    background: var(--surface-card);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
}
.bvd-section__search input:focus { outline: none; border-color: var(--brand-primary); }
.bvd-section__search svg {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

/* KPI cards row · compactas */
.bvd-section__kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-2);
}
/* Cascada al cargar la sección (Emil): las KPI entran escalonadas, no de
 * golpe. Aplica a TODAS las secciones del admin que usan section-layout.
 * Como cada página es una carga completa (PHP), corre una vez por visita. */
.bvd-section__kpis > .bvd-section-kpi,
.bvd-section__kpis > .bvd-section-kpi--chip { animation: bvd-enter var(--motion-base) var(--ease-out) backwards; }
.bvd-section__kpis > *:nth-child(1) { animation-delay: 0ms; }
.bvd-section__kpis > *:nth-child(2) { animation-delay: calc(var(--stagger-step) * 1); }
.bvd-section__kpis > *:nth-child(3) { animation-delay: calc(var(--stagger-step) * 2); }
.bvd-section__kpis > *:nth-child(4) { animation-delay: calc(var(--stagger-step) * 3); }
.bvd-section__kpis > *:nth-child(5) { animation-delay: calc(var(--stagger-step) * 4); }
@media (prefers-reduced-motion: reduce) {
    .bvd-section__kpis > .bvd-section-kpi,
    .bvd-section__kpis > .bvd-section-kpi--chip { animation: bvd-fade var(--motion-fast) var(--ease-out) backwards; }
}
/* Cuando hay info chip a la izquierda · primera col más angosta */
.bvd-section__kpis.has-chip {
    grid-template-columns: minmax(220px, 1.1fr) repeat(auto-fit, minmax(160px, 1fr));
}

/* Card · chip explicativo · estilo más sobrio que las KPIs */
.bvd-section-kpi--chip {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    display: flex; flex-direction: column; gap: 4px;
    justify-content: center;
}
.bvd-section-kpi__chip-head {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--text-primary);
    font-size: var(--font-size-xs);
}
.bvd-section-kpi__chip-icon { color: var(--brand-primary); display: inline-flex; }
.bvd-section-kpi__chip-head strong { font-weight: var(--font-weight-semibold); }
.bvd-section-kpi__chip-body {
    color: var(--text-muted);
    font-size: 11px;
    line-height: var(--line-height-snug);
}
.bvd-section-kpi__chip-cta {
    color: var(--brand-primary);
    font-size: 11px;
    font-weight: 600;
    text-decoration: none;
    margin-top: 2px;
}
.bvd-section-kpi__chip-cta:hover { text-decoration: underline; }
.bvd-section-kpi {
    padding: var(--space-3) var(--space-4);
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto auto;
    gap: 2px 8px;
    align-items: center;
    text-decoration: none;
    color: inherit;
    transition: border-color var(--motion-fast) var(--ease-out),
                transform var(--motion-fast) var(--ease-out),
                box-shadow var(--motion-fast) var(--ease-out);
}
.bvd-section-kpi:hover { border-color: var(--border-default); }
.bvd-section-kpi.is-link:active { transform: scale(0.985); }
/* KPI clicable · hover marca con brand y cursor pointer */
.bvd-section-kpi.is-link {
    cursor: pointer;
}
.bvd-section-kpi.is-link:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-md, 0 4px 12px rgba(0,0,0,0.15));
}
.bvd-section-kpi.is-active {
    border-color: var(--text-primary);
    box-shadow: 0 0 0 1px var(--text-primary) inset;
}
.bvd-section-kpi.is-link.is-danger.is-active  { border-color: var(--error);   box-shadow: 0 0 0 1px var(--error) inset; }
.bvd-section-kpi.is-link.is-warning.is-active { border-color: var(--warning); box-shadow: 0 0 0 1px var(--warning) inset; }
.bvd-section-kpi.is-link.is-success.is-active { border-color: var(--success); box-shadow: 0 0 0 1px var(--success) inset; }
.bvd-section-kpi.is-link.is-primary.is-active { border-color: var(--brand-primary); box-shadow: 0 0 0 1px var(--brand-primary) inset; }

/* Label con punto de color */
.bvd-section-kpi__label {
    grid-column: 1 / 2;
    grid-row: 1;
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--text-muted);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.bvd-section-kpi__label::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    flex-shrink: 0;
}
.bvd-section-kpi__value {
    grid-column: 1 / 2;
    grid-row: 2;
    font-family: var(--font-display);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    line-height: 1;
    color: var(--text-primary);
}
.bvd-section-kpi__sub {
    grid-column: 1 / 2;
    grid-row: 3;
    color: var(--text-muted);
    font-size: 11px;
    font-family: var(--font-mono);
}

/* Sparkline a la derecha (opcional) */
.bvd-section-kpi__spark {
    grid-column: 2 / 3;
    grid-row: 2 / 4;
    width: 72px;
    height: 32px;
    align-self: end;
    display: block;
    opacity: 0.85;
}
.bvd-section-kpi__spark path.area  { stroke: none; fill-opacity: 0.15; }
.bvd-section-kpi__spark path.line  { fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* Variantes de color */
.bvd-section-kpi.is-danger  .bvd-section-kpi__label::before { background: var(--error); }
.bvd-section-kpi.is-danger  .bvd-section-kpi__value         { color: var(--error); }
.bvd-section-kpi.is-danger  .bvd-section-kpi__spark path.line { stroke: var(--error); }
.bvd-section-kpi.is-danger  .bvd-section-kpi__spark path.area { fill: var(--error); }
.bvd-section-kpi.is-warning .bvd-section-kpi__label::before { background: var(--warning); }
.bvd-section-kpi.is-warning .bvd-section-kpi__value         { color: var(--warning); }
.bvd-section-kpi.is-warning .bvd-section-kpi__spark path.line { stroke: var(--warning); }
.bvd-section-kpi.is-warning .bvd-section-kpi__spark path.area { fill: var(--warning); }
.bvd-section-kpi.is-success .bvd-section-kpi__label::before { background: var(--success); }
.bvd-section-kpi.is-success .bvd-section-kpi__value         { color: var(--success); }
.bvd-section-kpi.is-success .bvd-section-kpi__spark path.line { stroke: var(--success); }
.bvd-section-kpi.is-success .bvd-section-kpi__spark path.area { fill: var(--success); }
.bvd-section-kpi.is-primary .bvd-section-kpi__label::before { background: var(--brand-primary); }
.bvd-section-kpi.is-primary .bvd-section-kpi__value         { color: var(--brand-primary); }
.bvd-section-kpi.is-primary .bvd-section-kpi__spark path.line { stroke: var(--brand-primary); }
.bvd-section-kpi.is-primary .bvd-section-kpi__spark path.area { fill: var(--brand-primary); }

/* Bulk-action bar · oculta por default, aparece al marcar 1+ checkbox */
.bvd-bulk-bar {
    display: none;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-4);
    background: var(--surface-elevated);
    border: 1px solid var(--brand-primary);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-glow-brand, 0 0 0 3px rgba(255,204,0,0.1));
    animation: bvd-bulk-slide-in 0.2s var(--ease-out, ease);
}
.bvd-bulk-bar.is-active { display: flex; }
@keyframes bvd-bulk-slide-in {
    from { transform: translateY(-6px); opacity: 0; }
    to   { transform: translateY(0);     opacity: 1; }
}
.bvd-bulk-bar__count {
    color: var(--brand-primary);
    font-weight: 700;
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
}
.bvd-bulk-bar__actions {
    display: flex; gap: var(--space-2);
    margin-left: auto;
}
.bvd-bulk-bar__clear {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    cursor: pointer;
    padding: 4px 8px;
}
.bvd-bulk-bar__clear:hover { color: var(--text-primary); }

/* Checkbox column en tablas/filas */
.bvd-row-check {
    width: 16px; height: 16px;
    appearance: none;
    -webkit-appearance: none;
    background: var(--surface-card);
    border: 1.5px solid color-mix(in srgb, var(--text-muted) 55%, transparent);
    border-radius: 4px;
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    vertical-align: middle;
    transition: border-color var(--motion-fast) var(--ease-out),
                background var(--motion-fast) var(--ease-out);
}
.bvd-row-check:hover { border-color: var(--brand-primary); }
.bvd-row-check:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 1px; }
.bvd-row-check:checked {
    background: var(--brand-primary);
    border-color: var(--brand-primary);
}
.bvd-row-check:checked::after {
    content: '';
    position: absolute;
    left: 4px; top: 1px;
    width: 4px; height: 8px;
    border: solid var(--brand-primary-text, #0a0a0a);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
/* Select-all con selección parcial: guion en vez de check */
.bvd-row-check:indeterminate {
    background: var(--brand-primary);
    border-color: var(--brand-primary);
}
.bvd-row-check:indeterminate::after {
    content: '';
    position: absolute;
    left: 3px; top: 5.5px;
    width: 7px; height: 2px;
    background: var(--brand-primary-text, #0a0a0a);
    border-radius: 1px;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * TABLAS ADMIN COMPARTIDAS · DDL-tablas-admin
 * Source of truth: /admin/alumnos?tab=usuarios (la referencia visual).
 * Aplica a Usuarios · Inscripciones · Marketing (Leads/Landings/Campañas/Cupones)
 * · Contenido (Recursos) · Tickets · Comunidad · Invitaciones · Certificados.
 * ═══════════════════════════════════════════════════════════════════════════ */

.bvd-users-table,
.bvd-insc-table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
}
.bvd-users-table thead tr,
.bvd-insc-table thead tr { background: var(--surface-card); }
.bvd-users-table thead th,
.bvd-insc-table thead th {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    color: var(--text-primary);
    padding: 8px 10px;
    background: var(--surface-card);
    border-top: 1px solid var(--border-default);
    border-bottom: 2px solid var(--border-default);
    position: sticky; top: 0; z-index: 1;
    text-align: left;
}
.bvd-users-table thead th:first-child,
.bvd-insc-table thead th:first-child { border-top-left-radius: var(--radius-md); }
.bvd-users-table thead th:last-child,
.bvd-insc-table thead th:last-child  { border-top-right-radius: var(--radius-md); }
.bvd-users-table tbody td,
.bvd-insc-table tbody td {
    padding: 6px 10px;
    font-size: 13px;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
}
.bvd-users-table tbody tr:hover td,
.bvd-insc-table tbody tr:hover td { background: var(--surface-elevated); }
.bvd-users-table tbody tr:last-child td,
.bvd-insc-table tbody tr:last-child td { border-bottom: none; }

/* CELLS REUTILIZABLES — clases que viven en TODA tabla admin */
.bvd-user-cell__name {
    color: var(--text-primary);
    font-weight: 500;
    font-size: var(--font-size-sm);
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
}
.bvd-user-cell__email {
    color: var(--text-muted);
    font-size: 11px;
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
}
.bvd-user-cell__sec {
    color: var(--text-secondary);
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
    font-size: 11px;
}
.bvd-user-cell__state {
    display: inline-flex; align-items: center; gap: 6px;
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
}
.bvd-user-cell__dot {
    width: 6px; height: 6px; border-radius: 50%;
    flex-shrink: 0;
}

/* PROG PILLS · badges pequeños tipo SG, EG */
.bvd-prog-pill {
    display: inline-block;
    padding: 2px 6px;
    margin-right: 2px;
    background: var(--surface-page);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    font-size: 10px;
    font-weight: 600;
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
}
.bvd-prog-pill--empty { background: transparent; color: var(--text-muted); }
.bvd-prog-pill--full {
    padding: 4px 10px;
    background: var(--brand-primary-soft, rgba(255,204,0,0.1));
    color: var(--brand-primary);
    font-family: var(--font-body);
    font-size: var(--font-size-xs);
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    white-space: nowrap;
}

/* SRC TAG · tag pequeño tipo "landing" / "link" para origen de datos */
.bvd-src-tag {
    display: inline-block;
    padding: 1px 6px;
    margin-left: 6px;
    background: var(--surface-elevated);
    color: var(--text-muted);
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-family: var(--font-mono, monospace);
}
.bvd-src-tag--landing { color: #60A5FA; }
.bvd-src-tag--link    { color: #A78BFA; }

/* ════════════════════════════════════════════════════════════
 * PIXELS HUB (Marketing → Pixels) · SIGNAL + ATLAS
 * Cards hero, sub-tabs internos, drawer drilldown, stream live
 * ════════════════════════════════════════════════════════════ */
.bvd-px-tabs {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-1);
    margin: 0 0 var(--space-5);
    background: var(--surface-page);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    width: fit-content;
}
.bvd-px-tabs__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px 12px;
    background: transparent;
    border: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background 0.15s, color 0.15s;
}
.bvd-px-tabs__item:hover { color: var(--text-primary); background: var(--surface-elevated); }
.bvd-px-tabs__item.is-active {
    background: var(--brand-primary);
    color: var(--brand-primary-text);
}
.bvd-px-tabs__counter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    background: rgba(0,0,0,.15);
    border-radius: var(--radius-full);
    font-size: 10px;
    font-weight: var(--font-weight-bold);
    font-family: var(--font-mono);
}
.bvd-px-tabs__item:not(.is-active) .bvd-px-tabs__counter {
    background: var(--surface-elevated);
    color: var(--text-muted);
}

.bvd-px-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: var(--space-4);
}
.bvd-px-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    transition: border-color 0.15s, transform 0.15s;
}
.bvd-px-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }

.bvd-px-card__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}
.bvd-px-card__icon {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--brand-primary-soft);
    color: var(--brand-primary);
    border-radius: var(--radius-md);
}
.bvd-px-card__icon--meta       { background: rgba(24,119,242,.12); color: #1877F2; }
.bvd-px-card__icon--tiktok     { background: rgba(254,44,85,.12);  color: #FE2C55; }
.bvd-px-card__icon--ga4        { background: rgba(255,160,0,.12);  color: #FFA000; }
.bvd-px-card__icon--google_ads { background: rgba(66,133,244,.12); color: #4285F4; }
.bvd-px-card__icon--snapchat   { background: rgba(255,252,0,.12);  color: #FFFC00; }
.bvd-px-card__icon--linkedin   { background: rgba(10,102,194,.12); color: #0A66C2; }
.bvd-px-card__icon--pinterest  { background: rgba(230,0,35,.12);   color: #E60023; }

.bvd-px-card__title {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.bvd-px-card__title h3 {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bvd-px-card__title .bvd-badge { align-self: flex-start; }

.bvd-px-card__metrics {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-2);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
}
.bvd-px-metric {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: center;
}
.bvd-px-metric__value {
    font-family: var(--font-mono);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1.1;
}
.bvd-px-metric__label {
    font-size: 10px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.bvd-px-metric.is-danger .bvd-px-metric__value { color: var(--error); }

.bvd-px-card__spark {
    position: relative;
    height: 32px;
    color: var(--brand-primary);
}
.bvd-px-card__spark svg {
    width: 100%;
    height: 32px;
    display: block;
}
.bvd-px-card__spark-label {
    position: absolute;
    bottom: -16px;
    left: 0;
    font-size: 10px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.bvd-px-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding-top: var(--space-4);
    margin-top: auto;
}
.bvd-px-card__hint {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
}
.bvd-px-card__hint--muted { color: var(--text-muted); }

.bvd-px-otros { margin-top: var(--space-6); }
.bvd-px-otros h4 {
    margin: 0 0 var(--space-3);
    font-family: var(--font-display);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.bvd-px-otros__grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.bvd-px-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 8px 12px;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    cursor: pointer;
    transition: border-color 0.15s;
}
.bvd-px-chip:hover { border-color: var(--brand-primary); }
.bvd-px-chip__name { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }
.bvd-px-chip__count {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    padding: 2px 6px;
    background: var(--surface-elevated);
    border-radius: var(--radius-sm);
}

/* Stream eventos en vivo */
.bvd-px-stream__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
}
.bvd-px-stream__title {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
}
.bvd-px-stream__title strong { color: var(--text-primary); font-family: var(--font-display); }
.bvd-px-stream__sub { color: var(--text-muted); font-size: var(--font-size-xs); }
.bvd-px-stream__dot {
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    background: var(--success);
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4);
    transition: box-shadow 0.4s;
}
.bvd-px-stream__dot.is-pulse {
    box-shadow: 0 0 0 8px rgba(34, 197, 94, 0);
}
.bvd-px-stream__ctrls { display: inline-flex; align-items: center; gap: var(--space-3); }
.bvd-px-stream__toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
    cursor: pointer;
}
.bvd-px-stream__empty td {
    padding: var(--space-6) var(--space-4) !important;
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
}
.bvd-px-stream__row { animation: bvd-px-fade-in 0.4s ease; }
@keyframes bvd-px-fade-in {
    from { background: var(--brand-primary-soft); }
    to   { background: transparent; }
}

.bvd-px-canal {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: var(--font-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.bvd-px-canal--client { background: rgba(96, 165, 250, .15); color: #60A5FA; }
.bvd-px-canal--server { background: rgba(167, 139, 250, .15); color: #A78BFA; }
.bvd-px-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
}
.bvd-px-dot.is-ok    { background: var(--success); }
.bvd-px-dot.is-error { background: var(--error); }

.bvd-px-detalle__loading,
.bvd-px-detalle__empty,
.bvd-px-detalle__error {
    padding: var(--space-6);
    text-align: center;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}
.bvd-px-detalle__error { color: var(--error); }
.bvd-px-detalle__head { margin-bottom: var(--space-5); }
.bvd-px-detalle__head h3 {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}
.bvd-px-detalle__sub {
    margin: var(--space-1) 0 0;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}
.bvd-px-pixel {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    margin-bottom: var(--space-3);
    background: var(--surface-page);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}
.bvd-px-pixel__row1 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}
.bvd-px-pixel__row1 strong {
    font-family: var(--font-display);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
}
.bvd-px-pixel__row2 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}
.bvd-px-pixel__row2 code {
    flex: 1;
    padding: 4px 8px;
    background: var(--surface-elevated);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bvd-px-pixel__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
    gap: var(--space-2);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--border-subtle);
}
.bvd-px-pixel__stats span {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}
.bvd-px-pixel__stats strong {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
}
.bvd-px-pixel__stats em { font-style: normal; font-size: 10px; }
.bvd-px-pixel__stats .is-danger strong { color: var(--error); }
.bvd-px-pixel__stats .is-success strong { color: var(--success); }
.bvd-px-pixel__cfg {
    display: flex;
    gap: var(--space-2);
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
}
.bvd-px-pixel__cfg-label { color: var(--text-muted); }
.bvd-px-pixel__actions { display: flex; gap: var(--space-2); }
.bvd-px-mini th, .bvd-px-mini td { padding: 8px 10px !important; font-size: var(--font-size-xs); }

.bvd-px-docs { display: flex; flex-direction: column; gap: var(--space-4); max-width: 760px; }
.bvd-px-docs__step {
    display: flex;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
}
.bvd-px-docs__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    background: var(--brand-primary-soft);
    color: var(--brand-primary);
    border-radius: var(--radius-full);
    font-family: var(--font-mono);
    font-weight: var(--font-weight-bold);
}
.bvd-px-docs__step h4 {
    margin: 0 0 var(--space-2);
    font-family: var(--font-display);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}
.bvd-px-docs__step p {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-relaxed);
}
.bvd-px-docs__step code {
    padding: 2px 6px;
    background: var(--surface-elevated);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--brand-primary);
}
.bvd-px-docs__foot {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-subtle);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}
.bvd-px-docs__foot strong { color: var(--text-secondary); margin-right: var(--space-2); }
.bvd-link { color: var(--brand-primary); text-decoration: none; }
.bvd-link:hover { text-decoration: underline; }

.bvd-badge--error {
    background: rgba(248, 113, 113, 0.12);
    color: var(--error);
    border: 1px solid rgba(248, 113, 113, 0.25);
}
.bvd-badge--sm { font-size: 10px; padding: 1px 6px; }

@media (max-width: 720px) {
    .bvd-px-card__metrics { grid-template-columns: repeat(2, 1fr); }
    .bvd-px-stream__head { flex-direction: column; align-items: flex-start; }
}

/* ════════════════════════════════════════════════════════════
 * FLUJOS · UI lista refactor + template picker
 * ════════════════════════════════════════════════════════════ */
.bvd-fl-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-4);
}
.bvd-fl-toolbar__hint {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}
.bvd-fl-toolbar__actions { display: inline-flex; gap: var(--space-2); }

.bvd-fl-tpl-card {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    cursor: pointer;
    margin-bottom: var(--space-3);
    transition: border-color 0.15s, transform 0.15s;
}
.bvd-fl-tpl-card:hover { border-color: var(--brand-primary); transform: translateY(-1px); }
.bvd-fl-tpl-card__icon {
    width: 40px; height: 40px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-md);
}
.bvd-icon-btn--danger { color: var(--error); }
.bvd-icon-btn--danger:hover { background: rgba(239,68,68,.1); }


/* ════════════════════════════════════════════════════════════
 * AUTH · layout card centrado · idéntico para /login /registro
 * /recuperar-password /reset-codigo /verificar-codigo /login-2fa
 * /completar-datos. Todas estas páginas comparten estructura
 * .bvd-auth > .bvd-auth__card. Los estilos viven aquí GLOBAL.
 * ════════════════════════════════════════════════════════════ */
.bvd-auth {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6);
    width: 100%;
    min-height: 70vh;
}
.bvd-auth__card {
    width: 100%;
    max-width: 440px;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    padding: var(--space-10) var(--space-8);
}
.bvd-auth__title {
    margin: 0 0 var(--space-2);
    font-family: var(--font-display);
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
}
.bvd-auth__sub {
    margin: 0 0 var(--space-6);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}
.bvd-auth__form { margin-bottom: var(--space-6); }
.bvd-auth__msg {
    min-height: 24px;
    margin-bottom: var(--space-3);
    font-size: var(--font-size-sm);
}
.bvd-auth__msg--error   { color: var(--error); }
.bvd-auth__msg--success { color: var(--success); }
.bvd-auth__alt {
    text-align: center;
    margin: 0 0 var(--space-4);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}
.bvd-auth__alt a { color: var(--brand-primary); text-decoration: none; font-weight: var(--font-weight-medium); }
.bvd-auth__legal {
    margin: 0;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-align: center;
    line-height: var(--line-height-relaxed);
}
.bvd-auth__legal a { color: var(--text-secondary); }

@media (max-width: 480px) {
    .bvd-auth__card { padding: var(--space-7) var(--space-5); }
    .bvd-auth__title { font-size: var(--font-size-xl); }
}

/* ════════════════════════════════════════════════════════════
 * MOTION & INTERACCIÓN GLOBAL · filosofía Emil Kowalski
 * "Los detalles invisibles se acumulan." Aplica a admin Y alumno
 * (ambos cargan tokens.css). Press feedback, entrada, stagger,
 * origin-aware y accesibilidad — todo desde la fundación.
 * ════════════════════════════════════════════════════════════ */

/* 1 · PRESS FEEDBACK — todo lo presionable se encoge al tocar.
 *     Da la sensación de que la interfaz "escucha" al usuario.
 *     scale sutil (0.97) + curva responsiva. Helper: .bvd-press */
.bvd-press {
    transition: transform var(--motion-fast) var(--ease-out),
                background  var(--motion-fast) var(--ease-out),
                border-color var(--motion-fast) var(--ease-out),
                color       var(--motion-fast) var(--ease-out);
}
.bvd-press:active:not(:disabled):not([aria-disabled="true"]),
[role="button"]:active:not([aria-disabled="true"]) {
    transform: scale(0.97);
}

/* 2 · ENTRADA — nada aparece de la nada (regla de Emil).
 *     Pequeño scale + opacity en vez de pop seco. Helper: .bvd-enter */
.bvd-enter { animation: bvd-enter var(--motion-base) var(--ease-out) backwards; }
@keyframes bvd-enter {
    from { opacity: 0; transform: scale(0.97) translateY(4px); }
    to   { opacity: 1; transform: scale(1)    translateY(0);   }
}
@keyframes bvd-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* 3 · STAGGER — listas y grids entran en cascada, no de golpe.
 *     Poner .bvd-stagger en el contenedor; los hijos heredan el
 *     retraso incremental. Cap a 12 para que la cola no se eternice. */
.bvd-stagger > * { animation: bvd-enter var(--motion-base) var(--ease-out) backwards; }
.bvd-stagger > *:nth-child(1)  { animation-delay: 0ms; }
.bvd-stagger > *:nth-child(2)  { animation-delay: calc(var(--stagger-step) * 1);  }
.bvd-stagger > *:nth-child(3)  { animation-delay: calc(var(--stagger-step) * 2);  }
.bvd-stagger > *:nth-child(4)  { animation-delay: calc(var(--stagger-step) * 3);  }
.bvd-stagger > *:nth-child(5)  { animation-delay: calc(var(--stagger-step) * 4);  }
.bvd-stagger > *:nth-child(6)  { animation-delay: calc(var(--stagger-step) * 5);  }
.bvd-stagger > *:nth-child(7)  { animation-delay: calc(var(--stagger-step) * 6);  }
.bvd-stagger > *:nth-child(8)  { animation-delay: calc(var(--stagger-step) * 7);  }
.bvd-stagger > *:nth-child(9)  { animation-delay: calc(var(--stagger-step) * 8);  }
.bvd-stagger > *:nth-child(10) { animation-delay: calc(var(--stagger-step) * 9);  }
.bvd-stagger > *:nth-child(11) { animation-delay: calc(var(--stagger-step) * 10); }
.bvd-stagger > *:nth-child(12) { animation-delay: calc(var(--stagger-step) * 11); }
.bvd-stagger > *:nth-child(n+13) { animation-delay: calc(var(--stagger-step) * 12); }

/* 4 · ORIGIN-AWARE — popovers/menús escalan desde su disparador,
 *     no desde el centro (los modales SÍ quedan centrados).
 *     Se combina con --pop-origin inline calculado en JS. */
.bvd-origin { transform-origin: var(--pop-origin, top center); }

/* 4b · REVEAL al entrar al viewport (Emil) — secciones e imágenes se
 *      descubren al hacer scroll en vez de estar ahí de golpe. reveal.js
 *      añade .is-revealed. .bvd-reveal = fundido+sube; .bvd-reveal--wipe =
 *      corte clip-path de abajo hacia arriba (para imágenes/hero).
 *      BLINDAJE: solo se oculta cuando hay JS (html.js-on). Sin JavaScript
 *      —o si el script falla— el contenido se ve completo (clave para SEO
 *      y para que una landing nunca quede en blanco). */
.js-on .bvd-reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
    will-change: opacity, transform;
}
.js-on .bvd-reveal--wipe {
    transform: none;
    clip-path: inset(0 0 100% 0);
    transition: clip-path 700ms var(--ease-out), opacity 700ms var(--ease-out);
}
.bvd-reveal.is-revealed { opacity: 1; transform: translateY(0); }
.bvd-reveal--wipe.is-revealed { clip-path: inset(0 0 0 0); }
@media (prefers-reduced-motion: reduce) {
    .bvd-reveal, .bvd-reveal--wipe {
        opacity: 1 !important; transform: none !important;
        clip-path: none !important; transition: none !important;
    }
}

/* 5 · ELEVACIÓN SOLO EN PUNTERO FINO — el táctil no dispara hover
 *     falso al tocar. Helper: .bvd-lift (mouse sube, touch hunde). */
@media (hover: hover) and (pointer: fine) {
    .bvd-lift { transition: transform var(--motion-base) var(--ease-out),
                            box-shadow var(--motion-base) var(--ease-out),
                            border-color var(--motion-base) var(--ease-out); }
    .bvd-lift:hover { transform: translateY(-2px); }
}
@media (hover: none) {
    .bvd-lift:active { transform: translateY(-1px); }
}

/* 6 · ACCESIBILIDAD — quien marca "menos movimiento" recibe menos.
 *     Conservamos fundidos (ayudan a entender), anulamos desplazamiento
 *     y rebote que pueden marear. Sin esto las animaciones marean. */
@media (prefers-reduced-motion: reduce) {
    .bvd-enter,
    .bvd-stagger > * { animation: bvd-fade var(--motion-fast) var(--ease-out) backwards; }
    .bvd-lift:hover,
    .bvd-press:active,
    [role="button"]:active { transform: none !important; }
    *, *::before, *::after {
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}

/* ════════════════════════════════════════════════════════════
 * TIPOGRAFÍA & PULIDO GLOBAL · craft de Emil aplicado a TODO
 * Detalles invisibles que se acumulan. Aplica a admin, alumno y
 * público (las tres zonas cargan tokens.css).
 * ════════════════════════════════════════════════════════════ */

/* 1 · Sin destello gris/azul al tocar en móvil (se siente barato). */
* { -webkit-tap-highlight-color: transparent; }

/* 2 · Selección de texto con color de marca (cohesión). */
::selection { background: var(--brand-primary-soft); color: var(--text-primary); }

/* 3 · Títulos con tracking ligeramente negativo: se ven más sólidos
 *     y caros. Solo en encabezados reales, no en el cuerpo. */
h1, h2, h3,
.bvd-section__title,
.bvd-card__heading,
.bvd-modal__title { letter-spacing: -0.012em; }

/* 4 · Números técnicos alineados en columna (KPIs, precios, métricas
 *     no "bailan" al cambiar de valor). */
.bvd-section-kpi__value,
.bvd-px-metric__value,
.bvd-user-cell__sec,
[class*="mono"] { font-variant-numeric: tabular-nums; }

/* 5 · Links: transición de color suave en toda la plataforma. */
a { transition: color var(--motion-fast) var(--ease-out); }

/* 6 · Inputs a 16px en móvil: iOS deja de hacer zoom al enfocar
 *     (el salto de zoom es de las cosas que más se sienten "no app"). */
@media (max-width: 767px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select, textarea { font-size: 16px; }
}

/* ════════════════════════════════════════════════════════════
 * DENSIDAD COMPACTA · estándar admin para pantallas de 14"
 * Capas: nav → header → KPIs → filtros → tabla, con UN solo aire.
 * Aplica a todo el admin sin reescribir cada página.
 * ════════════════════════════════════════════════════════════ */
:root { --bvd-layer-gap: var(--space-4); }

/* Tabla compacta: 13px + números tabulares; entran ~13 filas en 14" */
.bvd-table { font-variant-numeric: tabular-nums; }
.bvd-table thead th { padding: 8px 10px; }
.bvd-table tbody td { padding: 6px 10px; font-size: 13px; }

/* Tabs principales más bajos */
.bvd-tabs__item { padding: 10px 12px; }
.bvd-tabs-row { margin-bottom: var(--bvd-layer-gap); }

/* KPIs bajos: tarjeta ~72px, número y sparkline comparten línea */
.bvd-section-kpi { padding: var(--space-2) var(--space-3); }
.bvd-section-kpi__value { font-size: var(--font-size-lg); }
.bvd-section-kpi__spark { width: 56px; height: 24px; }

/* Con un filtro KPI activo, los inactivos se apagan (se nota qué filtra) */
.bvd-section__kpis:has(.bvd-section-kpi.is-active) .bvd-section-kpi.is-link:not(.is-active) { opacity: .65; }
.bvd-section__kpis:has(.bvd-section-kpi.is-active) .bvd-section-kpi.is-link:not(.is-active):hover { opacity: 1; }

/* Truncado controlado por celda: 1 línea + … (tooltip via title) */
.bvd-trunc { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bvd-trunc--sm { max-width: 150px; }

/* Buscador colapsable: solo el icono hasta foco o con texto escrito */
.bvd-section__search.is-collapse { width: 36px; transition: width var(--motion-base) var(--ease-out); }
.bvd-section__search.is-collapse:focus-within,
.bvd-section__search.is-collapse.has-value { width: 240px; }
.bvd-section__search.is-collapse input { opacity: 0; transition: opacity var(--motion-fast) var(--ease-out); cursor: pointer; }
.bvd-section__search.is-collapse:focus-within input,
.bvd-section__search.is-collapse.has-value input { opacity: 1; cursor: text; }

/* Acciones de fila emergen al pasar el mouse (teclado y touch: siempre visibles) */
.bvd-table tbody tr .bvd-icon-actions { opacity: 0; transition: opacity var(--motion-fast) var(--ease-out); }
.bvd-table tbody tr:hover .bvd-icon-actions,
.bvd-table tbody tr:focus-within .bvd-icon-actions { opacity: 1; }
@media (hover: none) { .bvd-table tbody tr .bvd-icon-actions { opacity: 1; } }

/* Fila seleccionada (checkbox marcado): tinte dorado suave en toda la fila */
.bvd-table tbody tr:has(.bvd-row-check:checked) td {
    background: color-mix(in srgb, var(--brand-primary) 7%, transparent);
}

/* ── Herramientas de tabla (bvd-table-tools.js) · estilos compartidos ── */
/* Cinturón: la tabla JAMÁS crece más que su contenedor, aunque las columnas
 * sumen de más (table-layout fixed las comprime). Responsive garantizado. */
.bvd-table { max-width: 100%; }
/* Handle de resize en el borde derecho de cada th central.
 * right:0 (no negativo): el th tiene overflow hidden y recortaria el sobrante. */
.bvd-col-resize {
    position: absolute; right: 0; top: 0; bottom: 0;
    width: 8px; cursor: col-resize; z-index: 3;
    user-select: none; touch-action: none;
}
.bvd-col-resize:hover,
.bvd-col-resize.is-active { background: var(--brand-primary); opacity: .35; border-radius: 3px; }
body.bvd-resizing { cursor: col-resize !important; user-select: none !important; }
body.bvd-resizing * { cursor: col-resize !important; }
/* Columna iluminada mientras se arrastra (se ve cuál estás moviendo) */
body.bvd-resizing .bvd-table .is-col-resizing {
    background: color-mix(in srgb, var(--brand-primary) 9%, transparent);
}
/* Botón autoajustar columnas · mínimo, junto al checkbox del header */
.bvd-autofit-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; padding: 0;
    background: none; border: none; border-radius: var(--radius-sm);
    color: var(--text-muted); cursor: pointer;
    transition: color var(--motion-fast) var(--ease-out);
}
.bvd-autofit-btn:hover { color: var(--brand-primary); }
.bvd-autofit-btn:active { transform: scale(0.92); }
/* Orden por columna: header clicable con flecha de dirección */
.bvd-table thead th.is-sortable { cursor: pointer; user-select: none; }
.bvd-table thead th.is-sortable:hover { color: var(--brand-primary); }
.bvd-table thead th.sort-asc::after  { content: ' ▲'; font-size: 8px; color: var(--brand-primary); }
.bvd-table thead th.sort-desc::after { content: ' ▼'; font-size: 8px; color: var(--brand-primary); }

/* Celda estado+fecha fusionada (punto de color + último acceso).
 * El punto va como ::before (no span) para que el truncado del td nunca lo corte.
 * Color via custom property: style="--dot: var(--success)" en el span. */
.bvd-cell-pulse { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; max-width: 100%; }
.bvd-cell-pulse::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--dot, var(--text-muted)); flex-shrink: 0; }
.bvd-cell-pulse__dot { display: none; }


@media (prefers-reduced-motion: reduce) {
    .bvd-section__search.is-collapse,
    .bvd-section__search.is-collapse input,
    .bvd-table tbody tr .bvd-icon-actions { transition: none; }
}

/* ════════════════════════════════════════════════════════════
 * DÍA / NOCHE — alumno · MISMOS PATRONES QUE ADMIN V2
 *   Día  = Bruma   → acento AZUL  #3B6EF0  (superficies azul-gris claro)
 *   Noche= Obsidiana→ acento CHAMPÁN #C7A86B (superficies cálidas oscuras)
 *
 *   Se aplica SÓLO a páginas migradas, marcadas con data-paleta="v2" en
 *   <html> (lo pone el layout cuando temaDia). Así `:root` (legacy oro
 *   vivo) queda intacto para las páginas aún no migradas → cero choque
 *   oro-vs-champán fuera de inicio. Valores espejo de admin-v2.css.
 * ════════════════════════════════════════════════════════════ */

/* track/surco neutro (barras de progreso, celdas, chips mudos) */
:root { --track: rgba(255,255,255,0.07); }

/* ─── NOCHE V2 · Obsidiana (champán) · default de las páginas v2 ─── */
html[data-paleta="v2"] {
    color-scheme: dark;

    --surface-page:      #0E1318;
    --surface-card:      #161D25;
    --surface-elevated:  #1C242E;
    --surface-sunken:    #0A0E12;
    --surface-overlay:   rgba(0,0,0,0.55);

    --text-primary:      #E8E5DD;
    --text-secondary:    #A7A399;
    --text-muted:        #6E7682;
    --text-inverse:      #14110A;

    --border-subtle:     #222A33;
    --border-default:    #2A333D;
    --border-strong:     #3A4654;

    --brand-primary:       #C7A86B;   /* champán */
    --brand-primary-hover: #D9BC80;   /* champán vivo (hover) */
    --brand-primary-soft:  rgba(199,168,107,0.12);
    --brand-primary-text:  #14110A;
    --acc-ring:            rgba(199,168,107,0.40);
    --acc-vivo:            #D9BC80;

    --success:           #4BC68A;
    --warning:           #E0B458;
    --error:             #E06055;
    --info:              #5C87F5;

    --track:             rgba(255,255,255,0.06);

    --shadow-xs:  0 1px 2px rgba(0,0,0,0.4);
    --shadow-sm:  0 1px 3px rgba(0,0,0,0.4);
    --shadow-md:  0 4px 16px rgba(0,0,0,0.35);
    --shadow-lg:  0 12px 32px rgba(0,0,0,0.45);
    --shadow-xl:  0 28px 64px rgba(0,0,0,0.5);
}

/* ─── DÍA V2 · Bruma (azul) ─── */
html[data-paleta="v2"][data-theme="dia"] {
    color-scheme: light;

    --surface-page:      #EEF1F5;
    --surface-card:      #FFFFFF;
    --surface-elevated:  #F7F9FB;
    --surface-sunken:    #E2E7EE;
    --surface-overlay:   rgba(26,36,51,0.42);

    --text-primary:      #1A2433;
    --text-secondary:    #637087;
    --text-muted:        #93A0B3;
    --text-inverse:      #FFFFFF;

    --border-subtle:     #E8ECF2;
    --border-default:    #DCE2EA;
    --border-strong:     #93A0B3;

    --brand-primary:       #3B6EF0;   /* azul */
    --brand-primary-hover: #2F5BD6;
    --brand-primary-soft:  rgba(59,110,240,0.09);
    --brand-primary-text:  #FFFFFF;
    --acc-ring:            rgba(59,110,240,0.35);
    --acc-vivo:            #5C87F5;

    --success:           #15803D;
    --warning:           #99620A;
    --error:             #C2362B;
    --info:              #2563EB;

    --track:             rgba(26,36,51,0.06);

    --shadow-xs:  0 1px 2px rgba(26,36,51,0.05);
    --shadow-sm:  0 1px 3px rgba(26,36,51,0.07);
    --shadow-md:  0 6px 18px rgba(26,36,51,0.08);
    --shadow-lg:  0 16px 40px rgba(26,36,51,0.11);
    --shadow-xl:  0 28px 64px rgba(26,36,51,0.14);
}

/* Marca · escudo LB · cambia solo con el tema (azul día / dorado noche).
   PNG transparentes. Compacto e integrado (no grande). */
.bvd-brand-logo {
    display: inline-block;
    width: 17px; height: 26px;
    background: url('/assets/img/logo-noche.png') center / contain no-repeat;  /* noche = dorado */
    flex: none;
    vertical-align: middle;
}
html[data-theme="dia"]   .bvd-brand-logo,
html[data-theme="claro"] .bvd-brand-logo { background-image: url('/assets/img/logo-dia.png'); }  /* día = azul */

/* ════════════════════════════════════════════════════════════
 * FIN tokens.css
 * Cualquier componente nuevo PARTE de aquí.
 * Hardcodear hex/rgb/named colors es violación que LINK bloquea.
 * ════════════════════════════════════════════════════════════ */
