/* ============================================================
   THEME TOKENS — the one file that decides light or dark.
   Must load BEFORE every other stylesheet.

   The app was dark-only: 614 hardcoded neutral colours across the
   admin stylesheets, and no layer to flip. Rather than duplicate
   every rule, the neutrals now come from here.

   ── The overlay channel ─────────────────────────────────────
   Most of those neutrals were `rgba(255, 255, 255, α)` — a white
   film over a dark surface, used for fills, borders and muted
   text. On a light surface the same film has to be dark. Instead
   of one token per alpha (there were 28 distinct ones), --tint
   carries only the RGB channel:

       background: rgba(var(--tint), .05);

   so every alpha survives the conversion exactly, and the whole
   set flips by changing three numbers.

   ── Accents are NOT here ────────────────────────────────────
   Sky, emerald, amber, red and the per-page accents (--stud,
   --att, --am, ...) are deliberately left in their own files.
   They read correctly on both grounds, and a brand colour that
   changes with the theme stops being a brand colour.

   ── Three blocks, on purpose ────────────────────────────────
   1. :root                     — the complete LIGHT palette
   2. prefers-color-scheme:dark — dark, unless the user chose light
   3. [data-theme="dark"]       — dark, whatever the OS says
   Without block 3 the toggle could not override a light OS; without
   the :not() in block 2 it could not override a dark one.
   ============================================================ */

:root {
    color-scheme: light;

    /* Overlay channel — see above. */
    --tint: 15, 23, 42;

    /* Grounds */
    --bg: #eef2f7;
    --surface: #ffffff;
    --surface-2: #f8fafc;
    --surface-3: #e9eef4;
    --surface-slate: #ffffff;
    --surface-slate-2: #f1f5f9;

    /* Text, strongest to faintest */
    --ink: #0f172a;
    --ink-2: #1e293b;
    --ink-3: #475569;
    --ink-4: #64748b;
    --ink-5: #94a3b8;

    /* Hairlines */
    --line: rgba(15, 23, 42, .12);
    --line-strong: rgba(15, 23, 42, .2);

    /* Text that sits on a saturated accent. White in BOTH themes:
       the button underneath stays sky/emerald/red either way. */
    --on-accent: #ffffff;

    /* A genuinely white plate (the logo picker), which must not
       follow the theme — most school logos are dark ink on
       transparency and vanish on a dark ground. */
    --plate: #ffffff;

    --shadow: rgba(15, 23, 42, .1);
    --shadow-lg: rgba(15, 23, 42, .16);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --tint: 255, 255, 255;

        --bg: #0f0f13;
        --surface: #16161a;
        --surface-2: #1a1a2e;
        --surface-3: #2a2a33;

        --ink: #ffffff;
        --ink-2: #e2e8f0;
        --ink-3: #cbd5e1;
        --ink-4: rgba(255, 255, 255, .45);
        --ink-5: rgba(255, 255, 255, .3);

        --line: rgba(255, 255, 255, .12);
        --line-strong: rgba(255, 255, 255, .2);

        --on-accent: #ffffff;
        --plate: #ffffff;

        --shadow: rgba(0, 0, 0, .3);
        --shadow-lg: rgba(0, 0, 0, .5);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --tint: 255, 255, 255;

    --bg: #0f0f13;
    --surface: #16161a;
    --surface-2: #1a1a2e;
    --surface-3: #2a2a33;
    /* The app used two families of dark ground side by side: a
       neutral near-black and a blue-tinted slate. Merging them into
       one token would have quietly redesigned dark mode while adding
       light mode, so both survive. */
    --surface-slate: #0f172a;
    --surface-slate-2: #1e293b;

    --ink: #ffffff;
    --ink-2: #e2e8f0;
    --ink-3: #cbd5e1;
    --ink-4: rgba(255, 255, 255, .45);
    --ink-5: rgba(255, 255, 255, .3);

    --line: rgba(255, 255, 255, .12);
    --line-strong: rgba(255, 255, 255, .2);

    --on-accent: #ffffff;
    --plate: #ffffff;

    --shadow: rgba(0, 0, 0, .3);
    --shadow-lg: rgba(0, 0, 0, .5);
}

/* The page ground itself. Painted here rather than in main.css so
   a page that forgets to set a background still lands on the
   correct one instead of the browser's white. */
html,
body {
    background: var(--bg);
    color: var(--ink-2);
}

/* ─── The modal close button ─────────────────────────────────
   Ten templates carry Bootstrap's `.btn-close-white`, which
   hard-codes an invert filter so the ✕ is always white. On a white
   modal header that makes it invisible — the dialog looks like it
   has no way out. The filter is dropped and re-applied only in
   dark, which is the one theme that needs it.

   Scoped to nothing in particular on purpose: the class appears
   inside .app-modal, .lnk-qr-modal, .user-modal and plain Bootstrap
   modals alike, and every one of them has the same problem. */
.btn-close.btn-close-white {
    filter: none;
}

:root[data-theme="dark"] .btn-close.btn-close-white {
    filter: invert(1) grayscale(100%) brightness(200%);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .btn-close.btn-close-white {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}

/* ─── Accent "ink" on a light ground ─────────────────────────
   Each page picks a pale tint of its accent for small text —
   --stud-ink #7dd3fc, --att-ink #c4b5fd and so on. Those were
   chosen to glow on a near-black card; on white they are barely
   there, and they are used for the section labels and chips, which
   are text people actually have to read.

   Only the INK is darkened. The accents themselves (--stud, --att,
   the gradients, the status greens and reds) are untouched: they
   read on both grounds, and a brand colour that changes with the
   theme stops being a brand colour.

   These are declared on page classes (.stud-page, .qr-page, ...),
   so a bare :root would lose on specificity — hence the descendant
   selectors. */
:root:not([data-theme="dark"]) .stud-page,
:root:not([data-theme="dark"]) .qr-page,
:root:not([data-theme="dark"]) .trk-page,
:root:not([data-theme="dark"]) body,
:root:not([data-theme="dark"]) .app-modal,
:root:not([data-theme="dark"]) .app-swal {
    --stud-ink: #0369a1;
    --scan-ink: #0369a1;
    --qr-ink: #0369a1;
    --trk-ink: #0369a1;
    --sp-ink: #0369a1;
    --am-ink: #0369a1;
    --att-ink: #6d28d9;
    --lnk-ink: #6d28d9;
    --ok-ink: #047857;
    --warn-ink: #b45309;
    --bad-ink: #b91c1c;
}

/* ─── Decorative particle field ──────────────────────────────
   The QR generator, scanner and tracker sit on a particles.js
   canvas whose colour is set in JavaScript (#1b1e34 at .3 alpha,
   assets/js/shape.js). On a dark ground that is a faint texture; on
   a light one it is a grey smear across the page. It cannot be
   recoloured from CSS, so in light mode it is turned down instead. */
:root:not([data-theme="dark"]) #particles-js {
    opacity: .1;
}

/* ─── Floating theme switch ──────────────────────────────────
   For the pages with no topbar to put it in (see
   includes/theme_toggle.php). The topbar version is styled in
   topbar.css; these are the extra rules that make it float, so the
   two look the same wherever they appear. */
.tb-theme.theme-floating {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 9997;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink-3);
    font-size: 1.05rem;
    cursor: pointer;
    box-shadow: 0 6px 18px var(--shadow);
    transition: background .18s ease, color .18s ease, border-color .18s ease;
}

.tb-theme.theme-floating:hover {
    background: var(--surface-3);
    color: var(--ink);
    border-color: var(--line-strong);
}

.tb-theme.theme-floating:focus-visible {
    outline: 2px solid #667eea;
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .tb-theme.theme-floating {
        transition: none;
    }
}

/* SweetAlert2 dialogs are handed their colours by JavaScript —
   `background: '#16161a'`, `color: '#e0e0e0'` and friends, spread
   across 20 different files. SweetAlert writes those as INLINE
   styles, which beat any stylesheet, so in light mode every
   confirmation would still open as a near-black box.
   Overriding here fixes all 20 at once; their layout and accents
   still come from modal-form.css. */
.swal2-popup {
    background: var(--surface) !important;
    color: var(--ink-2) !important;
}

.swal2-popup .swal2-title,
.swal2-popup .swal2-html-container {
    color: var(--ink-2) !important;
}

