        /* =====================================================================
           GU CONTROLLER PORTAL — DESIGN SYSTEM v3
           A registrar-grade interface: the working tool behind the official
           documents it produces. Palette and type are drawn from the University's
           own seal and its printed paperwork (see the .slip-* rules further down,
           which mirror the student-facing slip pixel for pixel) rather than a
           generic admin-panel default — a serif for institutional identity,
           a precise grotesque for the data-dense work itself.
           ===================================================================== */
        :root {
            /* Tells the browser this page manages its own colours (the sidebar
               is deliberately dark navy against an otherwise light page) so a
               browser- or extension-level "force dark mode on all sites"
               feature doesn't try to auto-repaint it — that kind of forced
               repaint is a known cause of exactly the overlapping/missing-text
               glitches a hand-built dark panel next to a light body can trigger. */
            color-scheme: light;
            /* ---- Ink & surface ----
               Palette below is taken directly from the user's own earlier
               version of this portal (admin.html) — same named roles, their
               actual hex values, carried over as-is. Where that file had no
               separate token (it reused one grey for both dark-surface panels
               and light-surface headings, and had no tint tier for the brand
               colours), the nearest matching value from that file was reused
               so nothing here is invented outside their palette; only the two
               brand tints and the gold tint are lightened versions of their
               own green/maroon/gold, computed to keep AA text contrast. */
            --gu-navy: #0f172a;          /* deepest surface: sidebar, login */
            --gu-slate: #1e293b;         /* sidebar panel / brand block */
            --gu-slate-light: #334155;   /* borders + hover on dark surfaces */
            --ink-900: #1e293b;          /* headings on light surfaces */
            --ink-700: #334155;          /* body text, dark */
            --ink-500: #94a3b8;          /* secondary / muted text */
            --ink-300: #94a3b8;          /* placeholders, faint labels */
            --line: #e2e8f0;             /* hairline borders */
            --line-soft: #eef2f7;        /* faint dividers */
            --surface: #ffffff;
            --gu-bg: #f4f7fa;            /* app canvas */
            --gu-text: #334155;

            /* ---- Brand accents (from the University seal) ---- */
            --gu-green: #1f7a4f;         /* seal green — primary action colour */
            --gu-green-light: #2f9d67;
            --gu-green-tint: #d6f5e6;
            --gu-maroon: #7a2632;        /* ribbon maroon — secondary accent */
            --gu-maroon-tint: #f3d8dc;
            --gu-gold: #d4a94a;          /* brass gold — ceremonial touches, used sparingly */
            --gu-gold-tint: #f5ebd6;

            /* ---- Semantic (their badge colours, carried over exactly) ---- */
            --ok: #15803d;      --ok-tint: #dcfce7;
            --warn: #b45309;    --warn-tint: #fef3c7;
            --bad: #b91c1c;     --bad-tint: #fee2e2;
            --info: #1d4ed8;    --info-tint: #dbeafe;

            /* ---- Shape & elevation ---- */
            --radius: 10px;
            --radius-lg: 14px;
            --radius-pill: 999px;
            --shadow-xs: 0 1px 3px rgba(14,21,38,0.10);
            --shadow-sm: 0 2px 12px rgba(14,21,38,0.12);
            --shadow-md: 0 10px 28px rgba(14,21,38,0.18);
            --shadow-lg: 0 22px 60px rgba(14,21,38,0.26);

            /* ---- Type ---- */
            --font-display: 'Source Serif 4', 'Georgia', serif;
            --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
        }
        * { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
        html { font-size: 14px; }
        body {
            font-family: var(--font-sans);
            background-color: var(--gu-bg);
            color: var(--gu-text);
            overflow-x: hidden;
            font-feature-settings: "cv11", "tnum";
        }
        h1, h2, h3, h4, h5, h6 { font-family: var(--font-sans); }
        b, strong { color: var(--ink-900); }
        ::selection { background: var(--gu-green-tint); color: var(--gu-green); }
        :focus-visible { outline: 2px solid var(--gu-green-light); outline-offset: 1px; }

        /* Layout Structure */
        #wrapper { display: none; width: 100vw; height: 100vh; overflow: hidden; }

        /* ---------------------------------------------------------------
           LOGIN GATE
           A calm, split-feel screen built around the seal rather than a
           generic centred card: a concentric-ring watermark (drawn in pure
           CSS — no extra asset) stands in for the University's own seal
           motif, printed the same way on every roll-no slip this portal
           issues. That watermark is the one deliberate flourish; the sign-in
           card itself stays quiet and precise.
           --------------------------------------------------------------- */
        #loginGate {
            display: flex; align-items: center; justify-content: center;
            width: 100vw; height: 100vh; position: relative; overflow: hidden;
            background:
                radial-gradient(circle at 50% 42%, rgba(212,169,74,0.16) 0%, rgba(212,169,74,0) 34%),
                repeating-radial-gradient(circle at 50% 42%, rgba(255,255,255,0.05) 0, rgba(255,255,255,0.05) 1px, transparent 1px, transparent 46px),
                linear-gradient(160deg, var(--gu-navy) 0%, #0d1c33 55%, var(--gu-slate) 100%);
        }
        #loginGate::before {
            content: ""; position: absolute; inset: 0; pointer-events: none;
            background-image:
                linear-gradient(rgba(255,255,255,0.035) 1px, transparent 1px),
                linear-gradient(90deg, rgba(255,255,255,0.035) 1px, transparent 1px);
            background-size: 42px 42px;
            mask-image: radial-gradient(circle at 50% 40%, #000 0%, transparent 68%);
        }
        .login-card {
            background: var(--surface); border-radius: var(--radius-lg);
            padding: 40px 38px 34px; width: 100%; max-width: 372px;
            text-align: center; box-shadow: var(--shadow-lg);
            position: relative; z-index: 1;
            border: 1px solid rgba(255,255,255,0.06);
        }
        .login-logo {
            width: 72px; height: 72px; border-radius: 50%; background: #fff; padding: 6px;
            box-shadow: 0 0 0 3px var(--gu-gold-tint), 0 0 0 4px rgba(212,169,74,0.5), 0 10px 22px rgba(14,21,38,0.18);
            object-fit: contain; margin-bottom: 16px;
        }
        .login-card h5 { font-family: var(--font-display); font-weight: 600; font-size: 21px; color: var(--ink-900); margin-bottom: 3px; }
        .login-sub { font-size: 12px; color: var(--ink-300); margin-bottom: 26px; letter-spacing: 0.4px; text-transform: uppercase; font-weight: 600; }
        .login-card .form-label { text-align: left; }
        .login-card .btn-signin { background: var(--gu-green); color: #fff; padding: 10px; letter-spacing: .2px; }
        .login-card .btn-signin:hover { background: var(--gu-green-light); color: #fff; }
        .login-card .btn-signin:disabled { opacity: 0.7; }

        /* ---------------------------------------------------------------
           SIDEBAR
           --------------------------------------------------------------- */
        #sidebar {
            width: 250px;
            min-width: 250px;
            background: var(--gu-slate);
            color: #fff;
            display: flex;
            flex-direction: column;
            transition: transform 0.3s ease;
            z-index: 1000;
            box-shadow: 4px 0 24px rgba(0,0,0,0.18);
        }
        .sidebar-brand {
            background: var(--gu-navy);
            text-align: center;
            border-bottom: 1px solid var(--gu-slate-light);
            position: relative; overflow: hidden;
            /* Never let the flex column above squeeze this shorter than its
               content (logo + name + the maroon ribbon) — without this, a
               short browser window forces every sidebar section to shrink
               equally, and because this block clips overflow, the ribbon
               and part of the office name get cut off / vanish instead of
               the page simply scrolling. */
            flex-shrink: 0;
        }
        .sidebar-brand::after {
            content: ""; position: absolute; inset: 0; pointer-events: none;
            background: radial-gradient(circle at 50% -10%, rgba(212,169,74,0.25), transparent 60%);
        }
        .brand-logo-wrap { padding: 20px 16px 12px; position: relative; z-index: 1; }
        .brand-logo {
            width: 46px; height: 46px; border-radius: 50%; background: #fff; padding: 5px;
            box-shadow: 0 0 0 3px rgba(212,169,74,0.45), 0 6px 16px rgba(0,0,0,0.35);
            object-fit: contain; display: block; margin: 0 auto 12px;
        }
        .sidebar-brand h4 { font-family: var(--font-display); font-weight: 600; font-size: 15px; margin: 0; letter-spacing: 0.4px; color: #fff; }
        .sidebar-brand .brand-sub { font-size: 9.5px; color: #8a94a6; margin: 4px 0 0 0; letter-spacing: 1.2px; text-transform: uppercase; font-weight: 600; }
        .brand-ribbon {
            background: linear-gradient(135deg, var(--gu-maroon), #591620);
            padding: 7px 16px;
            font-size: 9.5px;
            font-weight: 700;
            letter-spacing: 1.6px;
            color: #ecd9c6;
            border-top: 1px solid rgba(212,169,74,0.35);
            text-transform: uppercase;
            position: relative; z-index: 1;
        }

        .nav-menu {
            padding: 14px 10px; flex-grow: 1; overflow-y: auto;
            /* Flex items default to min-height:auto, which quietly overrides
               flex-grow/shrink and blocks this from ever shrinking below the
               height of all the nav links stacked up — so on a short window
               it can't scroll internally and instead pushes the brand block
               and footer out of shape. min-height:0 lets it actually shrink
               and scroll on its own, which is the whole point of the
               overflow-y:auto above. */
            min-height: 0;
        }
        .nav-menu::-webkit-scrollbar { width: 6px; }
        .nav-menu::-webkit-scrollbar-thumb { background: var(--gu-slate-light); border-radius: 6px; }
        .nav-group-label {
            font-size: 10px; font-weight: 700; letter-spacing: 1.3px; text-transform: uppercase;
            color: #5c687e; padding: 14px 12px 6px; user-select: none;
        }
        .nav-group-label:first-child { padding-top: 4px; }
        .nav-item {
            padding: 9px 12px;
            display: flex;
            align-items: center;
            gap: 11px;
            color: #b8c1d1;
            text-decoration: none;
            font-weight: 500;
            font-size: 12.75px;
            transition: background .15s ease, color .15s ease;
            cursor: pointer;
            border-radius: 8px;
            margin-bottom: 2px;
            position: relative;
        }
        .nav-item i { width: 16px; font-size: 13px; text-align: center; color: #6b7690; transition: color .15s ease; }
        .nav-item:hover { background: rgba(255,255,255,0.06); color: #fff; }
        .nav-item.active {
            background: rgba(212,169,74,0.16);
            color: #fff;
            font-weight: 600;
        }
        .nav-item.active::before {
            content: ""; position: absolute; left: -10px; top: 6px; bottom: 6px; width: 3px;
            border-radius: 0 3px 3px 0; background: var(--gu-gold);
        }
        .nav-item.active i { color: var(--gu-gold); }
        .sidebar-foot {
            padding: 13px 20px;
            border-top: 1px solid var(--gu-slate-light);
            font-size: 10px;
            color: #5c687e;
            text-align: center;
            letter-spacing: 0.4px;
            flex-shrink: 0; /* same reasoning as .sidebar-brand above */
        }

        /* ---------------------------------------------------------------
           UPDATE-AVAILABLE BANNER
           Hidden by default; guShowUpdateBanner() reveals it with a plain
           flex, no animation needed for something this quiet. Pinned above
           the login gate (z-index higher than everything else on the page)
           so it's visible however far a stale tab has been left open.
           --------------------------------------------------------------- */
        .gu-update-banner {
            display: none;
            align-items: center;
            justify-content: center;
            gap: 12px;
            position: fixed;
            top: 0; left: 0; right: 0;
            z-index: 5000;
            background: var(--gu-navy);
            color: #fff;
            padding: 9px 16px;
            font-size: 12.5px;
            font-weight: 500;
            box-shadow: var(--shadow-md);
        }
        .gu-update-banner i { color: var(--gu-gold); }
        .gu-update-btn {
            background: var(--gu-green);
            color: #fff;
            border: none;
            border-radius: 6px;
            padding: 5px 14px;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
        }
        .gu-update-btn:hover { background: var(--gu-green-light); }
        .gu-update-dismiss {
            background: none;
            border: none;
            color: #b8c1d1;
            font-size: 18px;
            line-height: 1;
            cursor: pointer;
            padding: 0 2px;
        }
        .gu-update-dismiss:hover { color: #fff; }

        /* Mobile sidebar toggle */
        #sidebarBackdrop { display: none; }
        #btnSidebarToggle { display: none; }
        @media (max-width: 991px) {
            #sidebar { position: fixed; top: 0; left: 0; height: 100vh; transform: translateX(-100%); }
            #sidebar.sidebar-open { transform: translateX(0); }
            #btnSidebarToggle {
                display: inline-flex; align-items: center; justify-content: center;
                width: 38px; height: 38px; border-radius: 8px; border: 1px solid var(--line);
                background: #fff; color: var(--ink-700); margin-right: 12px; cursor: pointer;
            }
            #sidebarBackdrop.show {
                display: block; position: fixed; inset: 0; background: rgba(10,20,40,0.55);
                backdrop-filter: blur(1px);
                z-index: 999; animation: fadeIn 0.2s ease;
            }
        }

        /* ---------------------------------------------------------------
           MAIN CONTENT + TOPBAR
           --------------------------------------------------------------- */
        #page-content {
            flex-grow: 1;
            display: flex;
            flex-direction: column;
            height: 100vh;
            overflow-y: auto;
            background: var(--gu-bg);
        }
        .topbar {
            background: rgba(255,255,255,0.92);
            backdrop-filter: saturate(180%) blur(8px);
            padding: 10px 20px;
            border-bottom: 1px solid var(--line);
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 10;
            position: sticky; top: 0;
        }
        .topbar h5 { font-size: 15.5px; font-weight: 700; color: var(--ink-900); letter-spacing: -.1px; }
        .topbar-eyebrow {
            font-size: 10px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase;
            color: var(--ink-300); margin: 0 0 1px; display: block;
        }
        #topbar-title i { color: var(--gu-green) !important; }
        .topbar .input-group-text { background: #fff; border-color: var(--line); color: var(--ink-300); }
        .topbar .form-control { border-color: var(--line); }
        .status-pill {
            display: inline-flex; align-items: center; gap: 6px;
            font-size: 11px; font-weight: 600; color: var(--ok);
            background: var(--ok-tint); border-radius: var(--radius-pill);
            padding: 6px 12px 6px 10px;
        }
        .status-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-tint); }
        @media (prefers-reduced-motion: no-preference) {
            .status-pill .dot { animation: pulseDot 2.2s ease-in-out infinite; }
            @keyframes pulseDot { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
        }
        .main-container { padding: 16px 20px 22px; }

        /* Tab Management */
        .module-tab { display: none; animation: fadeIn 0.35s ease; }
        .module-tab.active { display: block; }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

        /* ---------------------------------------------------------------
           TYPE SCALE
           Base moved from a soft 15px Poppins scale to 14px Inter: Inter's
           x-height is more moderate, so this reads calmer at a size that
           still fits more of a working table on one screen — the priority
           on a screen a registrar's team uses all day. Nothing drops below
           11px, the floor for text read continuously.
           --------------------------------------------------------------- */
        .form-control, .form-select, .btn, .input-group-text { font-size: 12.75px; }
        .form-control-sm, .form-select-sm, .btn-sm { font-size: 11.75px; }
        .form-label { font-size: 12px; font-weight: 600; margin-bottom: 4px; color: var(--ink-700); }
        .modal-title { font-size: 15px; font-weight: 700; font-family: var(--font-display); }
        .badge { font-size: 10.75px; font-weight: 600; }

        /* ---------------------------------------------------------------
           CARDS
           --------------------------------------------------------------- */
        .card { border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-xs); margin-bottom: 16px; }
        .card-header { background: #fff; border-bottom: 1px solid var(--line-soft); padding: 11px 16px; border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important; }
        .card-header.bg-dark { background: var(--gu-navy) !important; border-bottom: none; }
        .card-title { margin: 0; font-weight: 650; font-size: 13.5px; color: var(--ink-900); letter-spacing: -.1px; }
        .card-body { padding: 15px; }
        .card-header .card-title i { color: var(--ink-300); }
        .card-header.bg-dark .card-title, .card-header.bg-dark .card-title i { color: #fff; }
        .card-sub { font-size: 11.5px; color: var(--ink-300); margin: 3px 0 0; font-weight: 400; line-height: 1.5; }

        .page-head { margin: 2px 0 20px; }
        .page-head h4 { font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--ink-900); margin: 0 0 5px; letter-spacing: -.1px; }
        .page-head p { font-size: 12.75px; color: var(--ink-500); margin: 0; max-width: 78ch; line-height: 1.6; }
        .page-head h4 + p { font-size: 12.5px; line-height: 1.55; }
        body.dark-mode .page-head h4 { color: #f1f5f9; }
        body.dark-mode .page-head p, body.dark-mode .card-sub { color: #94a3b8; }
        body.dark-mode .card-header .card-title { color: #e2e8f0; }

        /* ---------------------------------------------------------------
           BUTTONS, FORMS, TABLES — global Bootstrap overrides so every
           module (uploads, datesheets, colleges, settings…) inherits the
           new system without its own markup changing.
           --------------------------------------------------------------- */
        .btn { border-radius: 8px; font-weight: 600; padding: 6px 13px; transition: all 0.15s ease; font-size: 12.75px; letter-spacing: .1px; }
        .btn-sm { border-radius: 7px; padding: 4px 10px; }
        .btn-primary { background: var(--gu-green); border-color: var(--gu-green); }
        .btn-primary:hover, .btn-primary:focus { background: var(--gu-green-light); border-color: var(--gu-green-light); }
        .btn-outline-primary { color: var(--gu-green); border-color: var(--gu-green); }
        .btn-outline-primary:hover { background: var(--gu-green); border-color: var(--gu-green); }
        .btn-success { background: var(--ok); border-color: var(--ok); }
        .btn-outline-success { color: var(--ok); border-color: #9fd4b8; }
        .btn-outline-success:hover { background: var(--ok); border-color: var(--ok); }
        .btn-danger { background: var(--bad); border-color: var(--bad); }
        .btn-outline-danger { color: var(--bad); border-color: #eab4af; }
        .btn-outline-danger:hover { background: var(--bad); border-color: var(--bad); }
        .btn-warning { background: #c17d00; border-color: #c17d00; color: #fff; }
        .btn-warning:hover { background: #a76900; border-color: #a76900; color: #fff; }
        .btn-outline-warning { color: #a76900; border-color: #e3c184; }
        .btn-outline-secondary { color: var(--ink-500); border-color: var(--line); }
        .btn-outline-secondary:hover { background: var(--ink-700); border-color: var(--ink-700); color: #fff; }
        .btn-check:checked + .btn-outline-primary, .btn-check:checked + .btn-outline-secondary { background: var(--gu-green); border-color: var(--gu-green); color: #fff; }

        .form-control, .form-select { border-radius: 8px; padding: 8px 13px; border: 1px solid #d3d9e1; background: #fff; color: var(--ink-700); }
        .form-control:focus, .form-select:focus { box-shadow: 0 0 0 3px var(--gu-green-tint); border-color: var(--gu-green-light); }
        .form-control::placeholder { color: var(--ink-300); }
        .form-check-input:checked { background-color: var(--gu-green); border-color: var(--gu-green); }
        .form-check-input:focus { box-shadow: 0 0 0 3px var(--gu-green-tint); }
        .form-switch .form-check-input:checked { background-color: var(--gu-green); border-color: var(--gu-green); }

        .table { font-size: 12.5px; color: var(--ink-700); }
        .table-dark { background-color: var(--gu-navy); }
        .table > thead { border-bottom: 2px solid var(--line); }
        .table th { font-size: 10.75px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-500); }
        .table-light, thead.table-light th { background-color: #f8f9fb !important; color: var(--ink-700); }
        .table-hover tbody tr:hover { background-color: var(--gu-green-tint); }
        .table td { vertical-align: middle; }

        .alert { border-radius: 10px; font-size: 12.5px; border-width: 1px; }
        .alert-success { background: var(--ok-tint); color: #0f5c38; border-color: #bfe4cf; }
        .alert-danger { background: var(--bad-tint); color: #8c1f19; border-color: #f0c3c0; }
        .alert-warning { background: var(--warn-tint); color: #7a4700; border-color: #edd3a0; }
        .alert-info { background: var(--info-tint); color: #164a7a; border-color: #bcd7f0; }

        .badge.bg-success { background-color: var(--ok) !important; }
        .badge.bg-danger { background-color: var(--bad) !important; }
        .badge.bg-warning { background-color: #c17d00 !important; color: #fff !important; }
        .badge.bg-primary { background-color: var(--gu-green) !important; }
        .badge.bg-info { background-color: var(--info) !important; }
        .badge.bg-secondary { background-color: var(--ink-500) !important; }

        .modal-content { border-radius: var(--radius-lg); border: none; box-shadow: var(--shadow-lg); }
        .modal-header { border-bottom: 1px solid var(--line-soft); padding: 16px 20px; }
        .modal-footer { border-top: 1px solid var(--line-soft); padding: 14px 20px; }
        .modal-body { padding: 20px; }

        .progress { border-radius: var(--radius-pill); background-color: #eceff3; }
        .progress-bar { background-color: var(--gu-green); }

        code { color: var(--gu-maroon); background: var(--gu-maroon-tint); padding: 1px 5px; border-radius: 5px; font-size: 90%; }

        /* ---------------------------------------------------------------
           SETTINGS — two-pane shell
           --------------------------------------------------------------- */
        .settings-shell { display: flex; gap: 22px; align-items: flex-start; }
        .settings-nav {
            width: 236px; min-width: 236px; background: #fff; border-radius: var(--radius-lg);
            box-shadow: var(--shadow-xs); border: 1px solid var(--line); padding: 8px; position: sticky; top: 12px;
        }
        .settings-nav-head {
            font-size: 10.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
            color: var(--ink-300); padding: 10px 12px 6px;
        }
        .settings-nav-item {
            display: flex; align-items: center; gap: 10px; width: 100%;
            padding: 10px 12px; border: none; background: transparent; border-radius: 8px;
            font-size: 12.5px; font-weight: 500; color: var(--gu-text); text-align: left;
            cursor: pointer; transition: background 0.15s, color 0.15s;
        }
        .settings-nav-item i { width: 18px; font-size: 13px; color: var(--ink-300); transition: color 0.15s; }
        .settings-nav-item:hover { background: #f1f5f9; }
        .settings-nav-item.active { background: var(--gu-green); color: #fff; font-weight: 600; }
        .settings-nav-item.active i { color: #fff; }
        .settings-nav-item.danger.active { background: var(--bad); }
        .settings-nav-item.danger i { color: var(--bad); }
        .settings-nav-item.danger.active i { color: #fff; }
        .settings-pane { flex: 1; min-width: 0; }
        .settings-section { display: none; animation: fadeIn 0.25s ease; }
        .settings-section.active { display: block; }
        .settings-head { margin-bottom: 18px; }
        .settings-head h4 { font-family: var(--font-display); font-size: 19px; font-weight: 600; color: var(--ink-900); margin: 0 0 4px; }
        .settings-head p { font-size: 12.5px; color: var(--ink-500); margin: 0; max-width: 76ch; line-height: 1.55; }
        .settings-card {
            background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
            box-shadow: var(--shadow-xs); margin-bottom: 16px; overflow: hidden;
        }
        .settings-card > header {
            padding: 14px 18px; border-bottom: 1px solid var(--line-soft);
            display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
        }
        .settings-card > header h5 { font-size: 13.5px; font-weight: 650; margin: 0; color: var(--ink-900); }
        .settings-card > header .sub { font-size: 11.5px; color: var(--ink-300); margin: 3px 0 0; font-weight: 400; }
        .settings-card > .body { padding: 18px; }
        .settings-card.is-danger { border-color: #ecc3c0; }
        .settings-card.is-danger > header { background: var(--bad-tint); border-bottom-color: #f0c3c0; }
        .settings-card.is-danger > header h5 { color: #8c1f19; }
        .settings-hint { font-size: 12px; color: var(--ink-500); line-height: 1.6; }
        .danger-banner {
            display: flex; gap: 12px; align-items: flex-start;
            background: var(--bad-tint); border: 1px solid #f0c3c0; border-radius: 10px;
            padding: 12px 14px; margin-bottom: 16px;
        }
        .danger-banner i { color: var(--bad); font-size: 16px; margin-top: 1px; }
        .danger-banner div { font-size: 12px; color: #7a1a15; line-height: 1.55; }
        @media (max-width: 991px) {
            .settings-shell { flex-direction: column; }
            .settings-nav { width: 100%; min-width: 0; position: static; display: flex; flex-wrap: wrap; gap: 4px; }
            .settings-nav-head { width: 100%; }
            .settings-nav-item { width: auto; }
        }

        /* ---------------------------------------------------------------
           KPI STAT CARDS
           Restored to the old file's own look: a full colour-tile gradient
           per card with white text, rather than a white card with a small
           icon chip — this is the "colour scheme" the old file actually
           carried on these cards, so it's brought back as-is (same gradient
           stops) instead of being reinterpreted through the icon-chip style.
           --------------------------------------------------------------- */
        .stat-box { border-radius: 12px; padding: 15px; color: #fff; text-align: center; box-shadow: 0 4px 10px rgba(0,0,0,0.1); position: relative; overflow: hidden; }
        .stat-box.primary { background: linear-gradient(135deg, #3b82f6, #2563eb); }
        .stat-box.success { background: linear-gradient(135deg, #10b981, #059669); }
        .stat-box.warning { background: linear-gradient(135deg, #f59e0b, #d97706); }
        .stat-box h5 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px; opacity: 0.9; margin-bottom: 6px; font-weight: 500; }
        .stat-box h2 { font-size: 23px; font-weight: 700; margin: 0; font-variant-numeric: tabular-nums; }
        .stat-box .stat-icon { position: absolute; right: 12px; top: 12px; font-size: 19px; opacity: 0.25; }
        .stat-box .stat-sub { font-size: 10.5px; opacity: 0.85; margin-top: 3px; font-weight: 500; }
        .stat-box .stat-sub-2 { font-size: 10px; opacity: 0.7; margin-top: 1px; font-weight: 500; }

        /* Small reset/history controls tucked into the bottom corners of a stat-box —
           kept out of the way of the headline number, only really needed occasionally
           (e.g. clearing test downloads before a public announcement). */
        .stat-box .stat-reset-btn {
            position: absolute; right: 8px; bottom: 8px; width: 24px; height: 24px; border-radius: 50%;
            border: none; background: rgba(255,255,255,.22); color: #fff; font-size: 10.5px;
            display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background .15s;
        }
        .stat-box .stat-reset-btn:hover { background: rgba(255,255,255,.42); }

        /* Needs Attention KPI card (4th slot) */
        .stat-box.attention { background: linear-gradient(135deg, #ef4444, #b91c1c); text-align: left; padding: 14px 16px; }
        .stat-box.attention.calm { background: linear-gradient(135deg, #64748b, #475569); }
        .stat-box.attention h5 { margin-bottom: 5px; }
        .stat-box.attention .attn-actions { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
        .stat-box.attention .attn-actions .btn { font-size: 10.5px; padding: 3px 9px; border-radius: 20px; }

        /* Quick Actions row */
        .quick-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
        .quick-action-btn {
            display: flex; align-items: center; gap: 8px;
            background: #fff; border: 1px solid var(--line); border-radius: 9px;
            padding: 8px 14px; font-size: 12.5px; font-weight: 600; color: var(--ink-700);
            box-shadow: var(--shadow-xs); transition: all 0.15s ease; cursor: pointer;
        }
        .quick-action-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); border-color: var(--gu-green-light); color: var(--gu-green); }
        .quick-action-btn i { font-size: 13px; color: var(--gu-green); }
        body.dark-mode .quick-action-btn { background: #16213a; border-color: #2a3a54; color: #e2e8f0; }

        /* Chart cards */
        .chart-card-header { display: flex; justify-content: space-between; align-items: center; }
        .chart-card-body { padding: 12px; position: relative; height: 280px; }
        .chart-card-body canvas { max-width: 100%; }
        .chart-empty-note { text-align: center; color: var(--ink-300); font-size: 12px; padding: 24px 0; }

        /* Engagement ratio mini progress bar */
        .ratio-wrap { display: flex; align-items: center; gap: 8px; justify-content: center; }
        .ratio-track { width: 70px; height: 7px; border-radius: 6px; background: #e7eaef; overflow: hidden; }
        .ratio-fill { height: 100%; border-radius: 6px; }
        .ratio-fill.good { background: var(--ok); }
        .ratio-fill.mid { background: #c17d00; }
        .ratio-fill.low { background: var(--bad); }
        .ratio-pct { font-size: 11.5px; font-weight: 700; color: var(--ink-500); min-width: 32px; text-align: left; }
        body.dark-mode .ratio-track { background: #334155; }

        /* ---------------------------------------------------------------
           GALLERY / UPLOAD PREVIEW
           --------------------------------------------------------------- */
        .gallery-img { width: 90px; height: 110px; object-fit: contain; background: #f1f3f5; cursor: pointer; border: 2px solid transparent; margin: 5px; border-radius: 8px; transition: 0.15s; }
        .gallery-img:hover { border: 2px solid var(--info); transform: scale(1.05); box-shadow: 0 4px 10px rgba(31,92,150,0.25); }
        .gallery-img.is-assigned { opacity: 0.45; filter: grayscale(50%); }
        .gallery-item-wrap { display: inline-block; text-align: center; vertical-align: top; margin-bottom: 10px; }
        .gallery-item-label { font-size: 11px; color: var(--ink-500); max-width: 90px; word-wrap: break-word; line-height: 1.2; margin-top: 4px; }
        .preview-thumb-btn { border: none; background: none; padding: 0; cursor: pointer; transition: transform 0.2s; }
        .preview-thumb-btn:hover { transform: scale(1.1); }
        .preview-thumb-btn img { border-radius: 6px; box-shadow: var(--shadow-xs); }

        .preview-toolbar { position: sticky; top: 0; z-index: 5; background: #fff; border-bottom: 1px solid var(--line); padding: 10px 12px; }
        .preview-toolbar .filter-chip { border-radius: var(--radius-pill); font-weight: 600; font-size: 12px; padding: 5px 14px; }
        .preview-toolbar .filter-chip.active { color: #fff; }
        .preview-toolbar .filter-chip[data-filter="all"].active { background: var(--ink-700); border-color: var(--ink-700); }
        .preview-toolbar .filter-chip[data-filter="issues"].active { background: var(--bad); border-color: var(--bad); }
        .preview-toolbar .filter-chip[data-filter="new"].active { background: var(--ok); border-color: var(--ok); }
        .preview-toolbar .filter-chip[data-filter="overwrite"].active { background: #c17d00; border-color: #c17d00; }
        .preview-row-name { font-weight: 600; color: var(--ink-900); line-height: 1.25; }
        .preview-row-name .reg-sub { display: block; font-size: 11px; font-weight: 500; color: var(--ink-300); margin-top: 2px; }
        #studentRowsBody td { transition: background-color 1.1s ease; }
        .student-preview-scroll { scroll-behavior: smooth; }

        /* ---------------------------------------------------------------
           MANAGE STUDENT (record editor)
           --------------------------------------------------------------- */
        .ms-hero { display: flex; gap: 20px; align-items: flex-start; padding: 22px 24px;
                   background: linear-gradient(135deg, #fbfbfc 0%, #f2f4f7 100%);
                   border: 1px solid var(--line); border-radius: var(--radius-lg) var(--radius-lg) 0 0; flex-wrap: wrap; }
        .ms-photo { position: relative; width: 96px; height: 122px; flex: 0 0 96px; border-radius: 10px;
                    overflow: hidden; background: #e9edf2; border: 1px solid #dfe3e8;
                    display: grid; place-items: center; }
        .ms-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
        .ms-photo .ms-photo-empty { font-size: 10.5px; color: var(--ink-300); text-align: center; padding: 6px; }
        .ms-photo-actions { position: absolute; inset: auto 0 0 0; background: rgba(10,20,40,.85);
                            display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 1px;
                            padding: 4px 2px; opacity: 0; transition: opacity .15s ease; }
        .ms-photo:hover .ms-photo-actions, .ms-photo:focus-within .ms-photo-actions { opacity: 1; }
        .ms-photo-actions button { background: none; border: 0; color: #fff; font-size: 12px; line-height: 1;
                                   cursor: pointer; padding: 3px 4px; border-radius: 5px; flex: 0 0 auto; }
        .ms-photo-actions button:hover { color: var(--gu-gold); background: rgba(255,255,255,.12); }

        .crop-stage { display: flex; flex-direction: column; align-items: center; gap: 12px; }
        .crop-canvas-wrap { position: relative; border-radius: 10px; overflow: hidden; background: var(--gu-navy);
                            touch-action: none; user-select: none; max-width: 100%;
                            box-shadow: 0 6px 18px rgba(10,20,40,.3); }
        .crop-canvas-wrap canvas { display: block; width: 100%; height: 100%; }
        .crop-canvas-wrap.is-empty::after { content: "No image loaded"; position: absolute; inset: 0;
                                            display: grid; place-items: center; color: #8a94a6; font-size: 12px; }
        .crop-box { position: absolute; cursor: move; border: 1px solid rgba(255,255,255,.95);
                    box-shadow: 0 0 0 9999px rgba(10,20,40,.6); }
        .crop-box-grid { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .15s ease; }
        .crop-canvas-wrap.is-active .crop-box-grid { opacity: 1; }
        .crop-box-grid span { position: absolute; background: rgba(255,255,255,.45); }
        .crop-box-grid span.v { top: 0; bottom: 0; width: 1px; }
        .crop-box-grid span.h { left: 0; right: 0; height: 1px; }
        .crop-h { position: absolute; background: #fff; border: 1px solid var(--gu-navy); border-radius: 2px; }
        .crop-h.corner { width: 13px; height: 13px; }
        .crop-h.edge-x { width: 22px; height: 8px; }
        .crop-h.edge-y { width: 8px; height: 22px; }
        .crop-h[data-dir="nw"] { left: -7px; top: -7px; cursor: nwse-resize; }
        .crop-h[data-dir="ne"] { right: -7px; top: -7px; cursor: nesw-resize; }
        .crop-h[data-dir="sw"] { left: -7px; bottom: -7px; cursor: nesw-resize; }
        .crop-h[data-dir="se"] { right: -7px; bottom: -7px; cursor: nwse-resize; }
        .crop-h[data-dir="n"] { top: -5px; left: 50%; transform: translateX(-50%); cursor: ns-resize; }
        .crop-h[data-dir="s"] { bottom: -5px; left: 50%; transform: translateX(-50%); cursor: ns-resize; }
        .crop-h[data-dir="w"] { left: -5px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
        .crop-h[data-dir="e"] { right: -5px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
        .crop-tools { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
        .crop-hint { font-size: 11.5px; color: var(--ink-300); text-align: center; }
        .crop-size { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-500); }

        .ms-ident { flex: 1 1 280px; min-width: 240px; }
        .ms-name { font-family: var(--font-display); font-size: 19px; font-weight: 600; color: var(--ink-900); line-height: 1.2; }
        .ms-sub { font-size: 12.5px; color: var(--ink-500); margin-top: 2px; }
        .ms-reg { font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--gu-maroon); letter-spacing: .4px; }
        .ms-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
        .ms-badge { font-size: 11px; font-weight: 600; padding: 4px 10px; border-radius: var(--radius-pill);
                    background: #eef1f5; color: var(--ink-500); border: 1px solid var(--line); }
        .ms-badge.good { background: var(--ok-tint); color: var(--ok); border-color: #bfe4cf; }
        .ms-badge.warn { background: var(--warn-tint); color: var(--warn); border-color: #edd3a0; }
        .ms-badge.bad  { background: var(--bad-tint); color: var(--bad); border-color: #f0c3c0; }
        .ms-stats { display: flex; gap: 22px; flex-wrap: wrap; }
        .ms-stat b { display: block; font-size: 17px; font-weight: 700; color: var(--ink-900); line-height: 1.1; font-variant-numeric: tabular-nums; }
        .ms-stat span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-300); font-weight: 700; }

        .ms-body { border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--radius-lg) var(--radius-lg); background: #fff; }
        .ms-section { border-bottom: 1px solid var(--line-soft); }
        .ms-section:last-child { border-bottom: 0; }
        .ms-sec-head { display: flex; align-items: center; gap: 9px; padding: 12px 22px; cursor: pointer; user-select: none; }
        .ms-sec-head:hover { background: #fafbfc; }
        .ms-sec-title { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--ink-700); }
        .ms-sec-count { font-size: 11px; color: var(--ink-300); font-weight: 600; }
        .ms-sec-chev { margin-left: auto; color: var(--ink-300); transition: transform .18s ease; }
        .ms-section.collapsed .ms-sec-chev { transform: rotate(-90deg); }
        .ms-section.collapsed .ms-sec-body { display: none; }
        .ms-sec-body { padding: 4px 22px 18px; }
        .ms-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px 20px; }
        .ms-field label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
                          color: var(--ink-300); margin-bottom: 3px; display: block; }
        .ms-field input.form-control, .ms-field select.form-select { font-size: 13.5px; }
        .ms-field.full { grid-column: 1 / -1; }
        .ms-locked { font-size: 12px; color: var(--ink-500); background: #f8fafc; border: 1px dashed #d3d9e1;
                     border-radius: 8px; padding: 7px 11px; }

        .ms-sched th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .3px; }
        .ms-sched td { font-size: 12.5px; }

        .ms-actionbar { position: sticky; bottom: 0; z-index: 6; display: flex; align-items: center; gap: 12px;
                        padding: 13px 22px; background: #fff; border: 1px solid var(--line); border-top: 2px solid var(--line-soft);
                        border-radius: 0 0 var(--radius-lg) var(--radius-lg); flex-wrap: wrap; box-shadow: 0 -6px 16px rgba(14,21,38,.05); }
        .ms-dirty { font-size: 12px; font-weight: 700; color: var(--warn); display: none; align-items: center; gap: 6px; }
        .ms-dirty.on { display: inline-flex; }
        .ms-dirty i { font-size: 8px; }

        body.dark-mode .ms-hero { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .ms-body, body.dark-mode .ms-actionbar { background: #0a1428; border-color: #2a3a54; }
        body.dark-mode .ms-name, body.dark-mode .ms-stat b { color: #e2e8f0; }
        body.dark-mode .ms-badge { background: #16213a; color: #cbd5e1; border-color: #2a3a54; }
        body.dark-mode .ms-locked { background: #16213a; border-color: #2a3a54; color: #cbd5e1; }

        /* ---------------------------------------------------------------
           EXAM READINESS
           --------------------------------------------------------------- */
        .rd-score { font-size: 36px; font-weight: 700; line-height: 1; letter-spacing: -1px; font-variant-numeric: tabular-nums; }
        .rd-score small { font-size: 15px; font-weight: 600; color: var(--ink-300); letter-spacing: 0; }
        .rd-ring { width: 108px; height: 108px; border-radius: 50%; display: grid; place-items: center;
                   background: conic-gradient(var(--rd-c, #157f4d) calc(var(--rd-p, 0) * 1%), #e7eaef 0); }
        .rd-ring-inner { width: 86px; height: 86px; border-radius: 50%; background: #fff; display: grid; place-items: center; }
        .rd-ring-inner b { font-size: 19px; font-weight: 700; color: var(--ink-900); }
        .rd-check { display: flex; align-items: flex-start; gap: 10px; padding: 9px 12px; border: 1px solid var(--line);
                    border-radius: 10px; background: #fff; margin-bottom: 7px; }
        .rd-check.ok { border-color: #bfe4cf; background: var(--ok-tint); }
        .rd-check.warn { border-color: #edd3a0; background: var(--warn-tint); }
        .rd-check.bad { border-color: #f0c3c0; background: var(--bad-tint); }
        .rd-check i.rd-ico { margin-top: 2px; }
        .rd-check-title { font-weight: 700; font-size: 13px; color: var(--ink-900); }
        .rd-check-sub { font-size: 11.5px; color: var(--ink-500); }
        .rd-fix { font-size: 11px; font-weight: 700; white-space: nowrap; }
        .rd-college-row td { vertical-align: middle; }
        .rd-pill { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: var(--radius-pill); }
        .rd-pill.ok { background: var(--ok-tint); color: var(--ok); }
        .rd-pill.warn { background: var(--warn-tint); color: var(--warn); }
        .rd-pill.bad { background: var(--bad-tint); color: var(--bad); }
        .rd-num { cursor: pointer; font-weight: 700; text-decoration: underline dotted; }
        .rd-num.zero { color: var(--ink-300); cursor: default; text-decoration: none; font-weight: 500; }
        body.dark-mode .rd-check, body.dark-mode .rd-ring-inner { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .rd-check-title, body.dark-mode .rd-ring-inner b { color: #e2e8f0; }

        /* ---- Undo bar ---- */
        #undoBar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 22px; z-index: 4000;
                   background: var(--gu-navy); color: #fff; border-radius: 12px; padding: 11px 16px;
                   box-shadow: var(--shadow-lg); display: none; align-items: center; gap: 14px; max-width: 92vw; }
        #undoBar .undo-text { font-size: 13px; }
        #undoBar .undo-count { font-weight: 800; color: var(--gu-gold); }

        /* ---------------------------------------------------------------
           COLLEGES & DEPARTMENTS
           --------------------------------------------------------------- */
        .cm-college-card { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 14px 16px; cursor: pointer;
                           background: #fff; transition: all .15s ease; height: 100%; }
        .cm-college-card:hover { border-color: var(--gu-maroon); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
        .cm-college-card.active { border-color: var(--gu-maroon); border-width: 2px; }
        .cm-code { font-weight: 700; font-size: 15px; color: var(--ink-900); letter-spacing: .3px; }
        .cm-name { font-size: 12px; color: var(--ink-500); margin-top: 2px; line-height: 1.35; }
        .cm-stat { font-size: 11px; font-weight: 700; color: var(--ink-700); }
        .cm-chip { cursor: pointer; background: #f1f3f6; color: var(--ink-700); border: 1px solid var(--line);
                   font-weight: 600; font-size: 11.5px; padding: 6px 11px; border-radius: var(--radius-pill); }
        .cm-chip:hover { background: #e7eaef; }
        .cm-chip.active { background: var(--gu-maroon); color: #fff; border-color: transparent; }
        .cm-chip.warn { background: var(--warn-tint); color: var(--warn); border-color: #edd3a0; }
        .cm-chip.warn.active { background: #a76900; color: #fff; }
        .cm-roster th { font-size: 11px; text-transform: uppercase; letter-spacing: .3px; white-space: nowrap; }
        .cm-roster td { font-size: 13px; }
        .cm-bulkbar { position: sticky; bottom: 0; z-index: 5; background: var(--gu-navy); color: #fff;
                      border-radius: 12px; padding: 10px 14px; box-shadow: 0 -4px 18px rgba(0,0,0,.2); }
        .cm-bulkbar select, .cm-bulkbar input { font-size: 13px; }
        body.dark-mode .cm-college-card { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .cm-code { color: #e2e8f0; }
        body.dark-mode .cm-chip { background: #16213a; color: #cbd5e1; border-color: #2a3a54; }

        /* ---------------------------------------------------------------
           MASTER DATESHEET
           --------------------------------------------------------------- */
        #datesheetSyncStatus .alert, #datesheetReportArea .alert { border-radius: 10px; font-size: 12.5px; }
        .datesheet-pdf-badge { font-size: 10px; letter-spacing: .3px; }
        /* Master Datesheet sub-tabs. The screen had grown to six stacked cards —
           deploy, repeater control, coverage, code lookup, code editor and the
           live list — so the thing you wanted was always several screens away.
           Grouping them into panes keeps one job on screen at a time. */
        .ds-subnav { gap: 6px; border-bottom: 1px solid var(--bs-border-color, #dee2e6); padding-bottom: 10px; }
        .ds-subnav .nav-link { border: 1px solid transparent; color: #495057; font-weight: 600; font-size: 14px; padding: 7px 14px; background: transparent; }
        .ds-subnav .nav-link:hover { background: rgba(13,110,253,.08); }
        .ds-subnav .nav-link.active { background: #0d6efd; color: #fff; }
        .ds-pane { display: none; }
        .ds-pane.active { display: block; }
        .ds-vbadge { font-size: 10px; vertical-align: middle; }
        .ds-step-track { display: flex; flex-wrap: wrap; gap: 6px; }
        .ds-step { font-size: 11px; font-weight: 600; color: var(--ink-300); background: #f1f3f6; border: 1px solid var(--line);
                   border-radius: var(--radius-pill); padding: 3px 10px; letter-spacing: .2px; }
        .ds-step b { display: inline-block; width: 15px; height: 15px; line-height: 15px; text-align: center;
                     border-radius: 50%; background: #c7cdd6; color: #fff; font-size: 9px; margin-right: 4px; }
        .ds-step.active { color: var(--info); background: var(--info-tint); border-color: #bcd7f0; }
        .ds-step.active b { background: var(--info); }
        .ds-step.done { color: var(--ok); background: var(--ok-tint); border-color: #bfe4cf; }
        .ds-step.done b { background: var(--ok); }
        .ds-meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
        .ds-meta-card { border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; background: #fff; }
        .ds-meta-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-300); }
        .ds-meta-value { font-size: 14px; font-weight: 700; color: var(--ink-900); margin-top: 2px; word-break: break-word; font-variant-numeric: tabular-nums; }
        .ds-chip { cursor: pointer; background: #f1f3f6; color: var(--ink-700); border: 1px solid var(--line);
                   font-weight: 600; font-size: 11px; padding: 5px 10px; border-radius: var(--radius-pill); }
        .ds-chip:hover { background: #e7eaef; }
        .ds-chip.active { background: var(--gu-maroon); color: #fff; border-color: transparent; }
        .ds-inline-input { font-size: 12px; min-width: 92px; }
        .ds-day-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .3px; }
        .ds-row-off { opacity: .45; }
        body.dark-mode .ds-meta-card { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .ds-meta-value { color: #e2e8f0; }
        body.dark-mode .ds-step { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .ds-chip { background: #16213a; color: #cbd5e1; border-color: #2a3a54; }

        /* ---------------------------------------------------------------
           DARK MODE
           --------------------------------------------------------------- */
        body.dark-mode { background-color: var(--gu-navy); color: #cbd5e1; color-scheme: dark; }
        body.dark-mode #page-content { background-color: var(--gu-navy); }
        body.dark-mode .topbar { background: rgba(16,27,48,0.92); border-color: #2a3a54; }
        body.dark-mode #topbar-title { color: #f1f5f9 !important; }
        body.dark-mode .topbar-eyebrow { color: #64748b; }
        body.dark-mode .card, body.dark-mode .modal-content { background-color: #16213a; color: #e2e8f0; border-color: #2a3a54; }
        body.dark-mode .card-header, body.dark-mode .card-footer { background-color: #101b30 !important; color: #e2e8f0; border-color: #2a3a54; }
        body.dark-mode .stat-box { background-color: #16213a; border-color: #2a3a54; color: #e2e8f0; }
        body.dark-mode .table { color: #cbd5e1; }
        body.dark-mode .table-light { --bs-table-bg: #1c2a44; --bs-table-color: #e2e8f0; background-color: #1c2a44 !important; color: #e2e8f0 !important; }
        body.dark-mode .table-light th, body.dark-mode .table-light td { color: #e2e8f0 !important; border-color: #2a3a54; background-color: #1c2a44 !important; }
        body.dark-mode .table-hover tbody tr:hover { background-color: rgba(255,255,255,0.04); color: #f1f5f9; }
        body.dark-mode .form-control, body.dark-mode .form-select { background-color: var(--gu-navy); color: #e2e8f0; border-color: #2a3a54; }
        body.dark-mode .form-control::placeholder { color: #64748b; }
        body.dark-mode .text-muted { color: #94a3b8 !important; }
        body.dark-mode .bg-light { background-color: #101b30 !important; }
        body.dark-mode .bg-white { background-color: #16213a !important; }
        body.dark-mode .text-dark { color: #e2e8f0 !important; }
        body.dark-mode .border { border-color: #2a3a54 !important; }
        body.dark-mode .settings-nav, body.dark-mode .settings-card { background: #16213a; border-color: #2a3a54; }
        body.dark-mode .settings-nav-item { color: #cbd5e1; }
        body.dark-mode .settings-nav-item:hover { background: #1c2a44; }
        body.dark-mode .settings-head h4 { color: #f1f5f9; }

        /* ---- CNIC Slip Search: printable Roll No. Slip ----
           Ported verbatim from the public/college portals' own slip CSS (same
           class names) so a slip generated here is pixel-identical to the one a
           student or college would produce themselves. Deliberately NOT touched
           by dark mode or the theme above — an official document stays
           white-on-black regardless of which theme the Controller is browsing
           in, same as the two portals. */
        .slip-container { display: none; background: white; font-family: 'Arial', sans-serif; width: 210mm; max-width: 100%; margin: 18px auto 0; padding: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); color: #000; position: relative; overflow: hidden; border-radius: 6px; }
        .slip-container.slip-visible { display: block; }
        /* AUDIT FIX: 0.05 opacity is faint enough that many printers' own halftone/dithering for a light tint rounds it down to pure white — the watermark was disappearing at the print driver, not the browser, which is also why print-color-adjust alone (already set globally below) didn't help: that property stops the BROWSER from skipping background graphics, it can't change what a printer's own colour reproduction does to a very light pixel. Raised to a level that survives dithering while staying a background watermark, not a foreground element — and print-color-adjust is set here too, redundantly with the global rule below, so this specific element is never depending on cascade order to keep it. */
        .slip-container::before { content: ""; position: absolute; top: 20%; left: 15%; width: 70%; height: 70%; background-image: var(--gu-slip-logo-bg); background-size: contain; background-repeat: no-repeat; background-position: center; opacity: 0.12; z-index: 0; pointer-events: none; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
        @media (prefers-reduced-motion: no-preference) {
            .slip-container.slip-visible { animation: slipFadeIn 0.4s ease both; }
            @keyframes slipFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
        }
        .slip-content { position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column; }
        .slip-border { border: 2px solid #000; padding: 8px 12px; flex-grow: 1; }

        .header-section { display: flex; align-items: center; justify-content: space-between; border-bottom: 2px solid #000; padding-bottom: 4px; margin-bottom: 8px; }
        .logo-box { width: 85px; text-align: left; }
        .logo-box img { width: 75px; height: auto; object-fit: contain; }
        .title-box { text-align: center; flex-grow: 1; padding: 0 5px; }
        .title-box h3 { margin: 0; font-weight: bold; font-size: 19px; font-family: 'Times New Roman', Times, serif; }
        .title-box p { margin: 0; font-weight: bold; font-size: 11px; margin-top: 2px; text-transform: uppercase; }
        /* AUDIT FIX: 70px printed at the ~96dpi a browser uses for CSS pixels is
           under 2cm on paper — too small for an ordinary phone camera to focus
           on and lock a scan onto at a normal reading distance, which is
           exactly what invigilator.html exists to do. Grown to roughly 2.6cm
           (≈100px) with a wider quiet-zone (the plain white margin QR readers
           need around the pattern to find its corner markers at all — 2px
           of it was barely there), sized to still fit the header row next to
           the university crest without crowding the title text between them. */
        .qr-box { width: 112px; text-align: right; }
        .qr-box img { width: 98px; height: 98px; border: 1px solid #000; padding: 5px; background: white; }

        .info-table { width: 100%; border-collapse: collapse; margin-bottom: 8px; background: transparent; font-size: 12px; }
        .info-table td { border: 1px solid #000; padding: 3px 6px; vertical-align: middle; }
        .info-table .label { font-weight: bold; font-size: 11px; background-color: rgba(240, 240, 240, 0.7); width: 20%; white-space: nowrap; }
        .info-data { font-weight: bold; font-size: 13px; text-transform: uppercase; }

        .photo-box { width: 90px; height: 115px; border: 2px solid #000; text-align: center; background: #eee; margin: 0 auto; display: flex; align-items: center; justify-content: center; font-size: 10px; color: #888; }
        .photo-box img { width: 100%; height: 100%; object-fit: cover; display: none; }

        /* A photo shot on a phone carries an EXIF Orientation tag: the pixels are
           stored as the sensor saw them and the tag says how far to turn them.
           Anything that ignores that tag shows the face sideways or upside down.
           from-image is the modern browser default, but it is stated explicitly
           here so the slip can never inherit image-orientation:none from anywhere
           and start printing rotated faces again. It only helps a photo that still
           HAS its EXIF tag — one already flattened the wrong way round has to be
           turned with the rotate control in Manage Student. */
        .photo-box img, .ms-photo img { image-orientation: from-image; }

        .schedule-title { text-align: center; font-weight: bold; margin-bottom: 4px; font-size: 13px; }
        /* AUDIT FIX (mobile "columns cramped, CR.HRS/DATE splitting mid-value"):
           with no column-width guidance the browser's default table layout let
           COURSE TITLE's long, naturally-wrapping text crowd out the narrow
           columns next to it, and once a mobile screen's zoom-to-fit scaled the
           whole slip down further those cramped columns had no room left for
           even a short unbroken value like "3(3-0)" or "14-09-2026" — so it
           wrapped mid-value instead of at a word boundary. table-layout: fixed
           plus an explicit percentage per column below (sized to each column's
           actual content, COURSE TITLE getting the most since it's the one
           column meant to wrap normally) makes every column's share of the
           table predictable and independent of what's actually in the cells,
           and white-space: nowrap on the short/token-like columns (day name,
           date, code, credit hours) stops them from ever breaking mid-value —
           excluded via :not([colspan]) so the full-width CENTRE line and other
           colspan="6" rows are unaffected and keep wrapping normally.
           SECOND AUDIT FIX: this whole block was previously written with "//"
           line comments, which are not valid CSS syntax (that's JavaScript's
           comment style). A CSS parser reads everything between "//" and the
           next "{" as one long invalid selector — which in this file meant the
           text of this comment plus every following /* */ comment (comments are
           stripped to whitespace before selector parsing, so they don't stop
           it) all got glued onto the SELECTOR of the very next real rule,
           .schedule-table { ... }. That made the whole rule's prelude invalid,
           so the browser discarded it outright: .schedule-table never actually
           got table-layout: fixed, its own font-size, or any of its base
           properties — the exact fix this comment describes had never been
           taking effect. Converted to a proper /* */ block for that reason,
           not just for tidiness. */
        /* Every schedule cell is meant to sit on a SINGLE line — a course title or
           an exam time broken across two lines makes the row twice as tall and the
           whole table read as cramped, which is what it used to do at 11px.
           The font is a size smaller and the column shares are re-balanced against
           what each column actually has to hold, measured at this size:
             DAY 10%   — "Wednesday", the longest weekday
             DATE 12%  — "16-09-2026"
             CODE 12%  — "COURSE CODE" (the header, wider than any code)
             TITLE 40% — the longest real title in use is about 60 characters
                         ("Interdisciplinary Course II Guidance & Counselling in
                         School"), which needs ~282px of the ~310px this share
                         gives it
             CR.HRS 8% — "CR. HRS"
             TIME 18%  — "12:00 AM to 02:00 PM"
           nowrap is on every column INCLUDING time now: at 9.5px the time string
           fits comfortably, and without it a browser would still be free to break
           it after "AM". Title is the one column left wrapping, purely as a safety
           valve — an unusually long title reflows instead of overflowing its cell —
           and at this size it does not reach that point in practice.
           :not([colspan]) keeps the full-width CENTRE line and the repeat-section
           header out of all of this; they are meant to wrap. */
        .schedule-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 9.5px; text-align: center; margin-bottom: 8px; background: transparent; }
        .schedule-table th, .schedule-table td { border: 1px solid #000; padding: 3px; overflow-wrap: break-word; }
        .schedule-table th:nth-child(1), .schedule-table td:not([colspan]):nth-child(1) { width: 10%; white-space: nowrap; }
        .schedule-table th:nth-child(2), .schedule-table td:not([colspan]):nth-child(2) { width: 12%; white-space: nowrap; }
        .schedule-table th:nth-child(3), .schedule-table td:not([colspan]):nth-child(3) { width: 12%; white-space: nowrap; }
        .schedule-table th:nth-child(4), .schedule-table td:not([colspan]):nth-child(4) { width: 40%; }
        .schedule-table th:nth-child(5), .schedule-table td:not([colspan]):nth-child(5) { width: 8%; white-space: nowrap; }
        .schedule-table th:nth-child(6), .schedule-table td:not([colspan]):nth-child(6) { width: 18%; white-space: nowrap; }
        .schedule-table th { background-color: rgba(233, 236, 239, 0.7); font-weight: bold; }
        /* No font-size of its own: this row sits at the table's size like every
           other row. It was briefly set smaller back when it printed the centre's
           full text from the Superintendent's Order — a college name repeated
           twice over, running to three bold lines and reading as the heaviest
           thing on the page. guCentreShortLabel now reduces that to the city and
           its AC code, so the line is short and there is nothing left to shrink;
           keeping the override would only make it look smaller than the rows it
           belongs with. */
        .centre-row { text-align: left; font-weight: bold; background-color: rgba(248, 249, 250, 0.7); padding: 3px 8px !important; }
        .repeat-section-header { background-color: rgba(212,169,74, 0.22) !important; color: var(--gu-maroon); }
        .repeat-subject-row td { background-color: rgba(212,169,74, 0.08); }

        .signatures { position: relative; text-align: right; font-weight: bold; font-size: 12px; margin-top: 40px; }
        .signature-img { position: absolute; right: 30px; top: -35px; width: 140px; height: auto; object-fit: contain; mix-blend-mode: multiply; }
        .signature-line { border-top: 1px solid #000; padding-top: 2px; display: inline-block; width: 200px; text-align: center; }

        .important-notice { border: 2px solid #dc3545; background-color: #fff5f5; color: #dc3545; border-radius: 6px; padding: 6px 10px; margin-top: 8px; }
        .important-notice h6 { font-size: 12px; margin-bottom: 3px; }
        .instructions { margin-top: 8px; }
        .instructions h5 { font-weight: bold; text-decoration: underline; font-size: 12px; margin-bottom: 3px; }
        .instructions ol { font-size: 10px; padding-left: 15px; line-height: 1.25; margin-bottom: 0; }

        @media print {
            /* AUDIT FIX (printed slip lands shrunk in one corner, rest of the
               sheet blank): the on-screen mobile fit scales the whole slip down
               with an inline `zoom` on #adminSlipArea so an A4-width document fits a
               phone, and the ONLY thing that took that zoom back off before
               printing was a 'beforeprint' JS listener. Mobile browsers commonly
               print via Share -> Print / Save as PDF, a path that does not fire
               'beforeprint' at all — so the phone's fit scale (often around 0.45)
               was still applied when the page rendered, and the slip printed at
               45% of the sheet in the top-left corner. Undoing it here in CSS
               instead means it holds whichever way printing was started, since a
               print stylesheet always applies and needs no event. The inverse
               zoom on the action buttons is undone for the same reason; those
               buttons are hidden in print anyway, but a stale inverse zoom on a
               visible ancestor chain can still affect layout. .slip-content is
               deliberately NOT reset here — that is the separate page-fit scale
               applied by fitSlipToPage/fitAdminSlipToPage, which shrinks an
               over-long slip to one sheet and must survive into the printout. */
            #adminSlipArea { zoom: 1 !important; }
            #adminSlipActions, #adminSlipZoomHint { zoom: 1 !important; display: none !important; }
            /* AUDIT FIX (printed/saved PDF used only part of the A4 sheet): the
               slip was scaled for print with an inline `zoom` on .slip-content,
               paired with a compensating percentage width. Browsers do not agree
               on how `zoom` interacts with a print box — the compensation
               resolved differently at print time than on screen, so the slip
               rendered at roughly 60% of the sheet with the right side and the
               bottom left blank, and mobile Save-as-PDF got it wrong in its own
               way again. Rather than trying to make that scaling behave
               identically everywhere, print now uses NO zoom at all: the slip is
               already authored as a real A4 document (.slip-container is 210mm),
               so at width:100% inside an 8mm-margin @page it fills the printable
               area exactly, with no scaling maths involved on any engine. The
               !important here also neutralises whatever inline zoom the on-screen
               fit or the page-fit pass happens to have left on the element,
               regardless of whether their JS ran at all.
               max-height/overflow are released with it: a slip longer than one
               sheet now continues onto a second page instead of being silently
               cut off at 279mm, which is what the old fixed height did once
               scaling was no longer shrinking it to fit. */
            #adminSlipArea, #adminSlipArea .slip-content { zoom: 1 !important; }
            #adminSlipArea .slip-content { width: 100% !important; height: auto !important; }
            #adminSlipArea { max-height: none !important; overflow: visible !important; }
            /* Printed size is set HERE, and this is the only dial for it.
               Two separate things are going on, and keeping them separate is what
               makes the output correct at any size:
               1. LAYOUT happens at the slip's authored width. The slip's internals
                  — column widths, font sizes, the point at which a course title
                  wraps — were all designed against a 210mm A4 document, so the
                  element is pinned to exactly that. Narrowing the element instead
                  (which is what a bigger @page margin or a bigger padding does)
                  does NOT shrink the slip: it squeezes the columns, wraps titles
                  onto extra lines, and pushes the instructions onto a second sheet,
                  leaving the layout looking larger and looser against the page.
               2. SIZE is then a pure scale of that finished layout. transform
                  scales what has already been laid out, so every element shrinks by
                  the same factor and nothing re-wraps or re-flows — the printed
                  slip is the designed one, just smaller.
               transform-origin: top center keeps it centred on the sheet as it
               shrinks, so the white space lands evenly on the left and right rather
               than all of it collecting on one side.
               padding is deliberately 0. The scale already leaves a white border on
               every side (at 0.96 a 210mm document prints ~202mm wide, so ~4mm of
               clear paper down each edge — enough to clear a printer's unprintable
               edge without leaving a visible band of empty paper beside the slip),
               and adding padding on top of that simply
               stacked a second, redundant margin inside the first — the slip ended
               up sitting in the middle of an unnecessarily wide frame while its own
               content had less room than it was designed for. One margin, produced
               by the scale, is the correct amount.
               The top margin is clear paper above the slip, and it is a MARGIN
               rather than padding on purpose: padding would sit inside the slip's
               own box and push its content down within it, while a margin moves the
               whole finished document down the sheet without touching anything
               inside it. It scales with the slip like everything else, so at 0.96
               the 8mm set here prints at roughly 7.7mm.
               To resize: change the scale below, and only that. Lower prints
               smaller, higher prints larger; 1 is full-page. Leave the width,
               padding and @page margin alone — they are layout, not size. */
            #adminSlipArea {
                width: 210mm !important;
                padding: 0 !important;
                box-sizing: border-box !important;
                margin: 8mm auto 0 !important;
                transform: scale(0.96) !important;
                transform-origin: top center !important;
            }
            /* AUDIT FIX (photo/QR blank in the PDF saved from a phone): the
               photo and QR are sized with object-fit inside a fixed-size box,
               and a mobile print rasterizer that does not implement object-fit
               on a scaled subtree drops the image rather than drawing it
               unscaled — the box prints empty. Giving them explicit width and
               height plus an object-fit fallback of `fill` means an engine that
               ignores object-fit still has real dimensions to draw into, so the
               image always renders even if the crop is slightly different.
               max-width:none matters because Bootstrap's own print reset sets
               img { max-width: 100% } against the PAGE, which on a scaled slip
               can compute to less than the box and clip the image to nothing. */
            .photo-box img.gu-photo-loaded { display: block !important; }
            .photo-box img { width: 100% !important; height: 100% !important; max-width: none !important; object-fit: cover; }
            .qr-box img { width: 98px !important; height: 98px !important; max-width: none !important; }
            img { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
            /* margin:0 is deliberate and is what suppresses the browser's own
               print header and footer — the date/time, page title and source URL
               it stamps at the top and bottom of every printed page. Those are
               drawn by the browser INTO the @page margin box, not by this
               document, so no CSS can style or hide them; the only thing that
               removes them without asking the user to untick "Headers and
               footers" in the print dialog is leaving no page margin for them to
               sit in.
               The white border the slip needs is therefore applied as padding on
               the slip itself just below, which the browser treats as ordinary
               page content and will not print anything over. Adjust the slip's
               size there, not here — this margin must stay 0. */
            @page { size: A4; margin: 0; }
            html, body { height: 99%; overflow: hidden; margin: 0 !important; padding: 0 !important; background: white; font-family: 'Arial', sans-serif !important; display: block; }
            #sidebar, #sidebarBackdrop, .topbar, .d-print-none, .page-head, #slipSearchCard, #undoBar { display: none !important; }
            .main-container { margin: 0 !important; padding: 0 !important; }
            .slip-container { display: block !important; box-shadow: none; margin: 0; padding: 0; width: 100%; height: auto; max-height: 279mm; overflow: hidden; border: none; border-radius: 0; page-break-inside: avoid; page-break-after: avoid; }
            * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
            .important-notice { border: 2px solid #dc3545 !important; background-color: #fff5f5 !important; color: #dc3545 !important; }
            /* AUDIT FIX: the exam date is printed in the site's brand colour
               (Bootstrap's .text-primary, themed teal/green here) — fine on a
               colour printer or screen, but a black-and-white/monochrome
               printer converts a colour to grayscale by LUMINANCE, and a
               light, saturated teal has high luminance — it comes out as a
               pale, washed-out gray next to genuinely black text, not the
               same darkness. print-color-adjust keeps the browser from
               skipping the colour, but it can't change what the printer
               itself does with that colour once it gets there — the fix is
               to print the date in actual black, not a colour that HAPPENS
               to render dark on a colour device. Scoped to the slip only, so
               .text-primary elsewhere in the admin app keeps printing in its
               normal colour. */
            .slip-container .text-primary { color: #000 !important; }
        }
