/* ═══════════════════════════════════════════════════════════
   LMSAdvisor — Admin + Auth Stylesheet  (2026 refresh)
   Soft-depth "glass" design system — light & dark themes.

   NOTES FOR DEVS
   • Class hooks are unchanged (adm-*, topbar-*, stat-*, lms-*…)
     — only the visual layer was rebuilt.
   • ThemeService (Admin → Appearance) still overrides the same
     variables: --primary, --primary-rgb, --primary-dark,
     --primary-light, --content-bg, --card-bg, --text-primary,
     --text-muted, --font. Do NOT rename them.
   • Dark mode = [data-theme="dark"] AND [data-bs-theme="dark"]
     on <html> (both are toggled together — see admin.js).
   ═══════════════════════════════════════════════════════════ */

/* ── Design tokens — LIGHT ─────────────────────────────────── */
:root {
  --primary:        #2373EF;
  --primary-rgb:    35,115,239;
  --primary-dark:   #1b5fd6;
  --primary-light:  #EEF4FE;
  --success:        #0e9f6e;
  --warning:        #e3a008;
  --danger:         #e02424;

  /* ── Admin sidebar — light panel ────────────────────────────
     Was a deep ink gradient with white text. Now a white panel that
     reads as part of the page rather than a slab bolted to its edge.

     Only the ACCENT comes from --primary, so ThemeService (Admin →
     Appearance) still repaints the sidebar when the brand colour
     changes, while the structural greys stay legible whatever hue an
     administrator picks. Tints are rgba(var(--primary-rgb), a) rather
     than --primary-light for the same reason: they stay subtle for any
     hue, and they can't be overridden into something unreadable. */
  --sidebar-bg:        #FFFFFF;
  --sidebar-border:    #E6EAF2;
  --sidebar-ink:       #101A33;   /* brand + section headers */
  --sidebar-ink-soft:  #48566F;   /* item labels          — 7.4:1 on white */
  --sidebar-ink-faint: #64718A;   /* counts, carets, meta — 4.9:1 on white */
  --sidebar-hover:     rgba(var(--primary-rgb),.07);
  --sidebar-active:    rgba(var(--primary-rgb),.12);
  --sidebar-rail:      #E3E8F1;   /* guide line beside nested items */
  --sidebar-panel:     #F4F7FC;   /* open-section tray */
  --sidebar-chip:      #EDF1F7;   /* count pill */
  --sidebar-card:      #FFFFFF;   /* bottom user card */
  --adm-sidebar-w:     264px;
  --adm-rail-w:        76px;    /* collapsed: icons only */

  /* Student layout (app.css) still uses this — leave it alone. */
  --sidebar-width:    240px;

  --topbar-h:        60px;
  /* Frosted-glass topbar */
  --topbar-bg:       rgba(255,255,255,.78);
  --topbar-border:   rgba(15,23,42,.08);

  --content-bg:      #F5F8FD;
  --card-bg:         #ffffff;
  --surface-2:       #f8fafc;          /* subtle inset surfaces (table heads, wells) */
  --border-color:    #e2e8f0;
  --row-hover:       rgba(var(--primary-rgb),.05);

  --text-primary:    #333333;
  --text-muted:      #64748b;
  --text-sidebar:    var(--sidebar-ink-soft);

  /* Layered, soft shadows */
  --shadow-sm:       0 1px 2px rgba(15,23,42,.05), 0 1px 6px rgba(15,23,42,.04);
  --shadow-md:       0 2px 6px rgba(15,23,42,.05), 0 10px 26px rgba(15,23,42,.08);
  --shadow-lg:       0 6px 16px rgba(15,23,42,.07), 0 20px 48px rgba(15,23,42,.12);
  --glow-primary:    0 6px 18px rgba(var(--primary-rgb),.32);

  --radius:          14px;
  --radius-sm:       9px;
  --radius-lg:       18px;
  --font:            'Poppins', 'Inter', system-ui, -apple-system, sans-serif;

  /* Page background wash — very subtle brand tint top-left */
  --page-wash:
      radial-gradient(900px 480px at 8% -10%,  rgba(var(--primary-rgb),.06), transparent 60%),
      radial-gradient(720px 420px at 100% 0%,  rgba(99,102,241,.05),        transparent 55%);

  /* Build seed — read by admin.js at runtime (LMS.rev); keep in sync with releases */
  --seed: 5d8cd9b0;
}

/* ── Design tokens — DARK ──────────────────────────────────── */
/* ThemeService re-overrides the shared vars after this file loads,
   so keep these defaults in sync with ThemeService::defaults(). */
[data-theme="dark"] {
  --primary-light:  #1E2A44;

  /* Same panel, inverted. Flat rather than gradient so it matches the
     light treatment; every token above has a counterpart here, because a
     colour defined only in one theme is how a sidebar ends up with one
     theme's text on the other theme's ground. */
  --sidebar-bg:        #14141A;
  --sidebar-border:    #26262F;
  --sidebar-ink:       #F1F1F5;
  --sidebar-ink-soft:  #B4BCCC;
  --sidebar-ink-faint: #8791A3;
  --sidebar-hover:     rgba(255,255,255,.06);
  --sidebar-active:    rgba(var(--primary-rgb),.18);
  --sidebar-rail:      #2C2C36;
  --sidebar-panel:     #1B1B23;
  --sidebar-chip:      #26262F;
  --sidebar-card:      #1B1B23;

  --topbar-bg:      rgba(20,20,25,.72);
  --topbar-border:  rgba(255,255,255,.08);

  --content-bg:     #0F0F12;
  --card-bg:        #18181C;
  --surface-2:      #1d1d23;
  --border-color:   #26262e;
  --row-hover:      rgba(var(--primary-rgb),.09);

  --text-primary:   #F1F1F5;
  --text-muted:     #8B8B9E;

  --shadow-sm:      0 1px 2px rgba(0,0,0,.35), 0 1px 6px rgba(0,0,0,.25);
  --shadow-md:      0 2px 6px rgba(0,0,0,.35), 0 12px 28px rgba(0,0,0,.45);
  --shadow-lg:      0 8px 20px rgba(0,0,0,.45), 0 24px 56px rgba(0,0,0,.55);
  --glow-primary:   0 6px 20px rgba(var(--primary-rgb),.35);

  --page-wash:
      radial-gradient(900px 480px at 8% -10%,  rgba(var(--primary-rgb),.09), transparent 60%),
      radial-gradient(720px 420px at 100% 0%,  rgba(99,102,241,.07),        transparent 55%);
}

/* ── Reset / base ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

body {
  font-family: var(--font);
  font-size: 14px;
  color: var(--text-primary);
  margin: 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Smooth theme switching (colours only — never layout) */
body, .admin-topbar, .admin-content, .lms-card, .stat-card, .admin-footer,
.admin-breadcrumb, .modal-content, .dropdown-menu, .form-control, .form-select,
.lms-table thead th, .lms-table tbody td {
  transition: background-color .25s ease, border-color .25s ease, color .15s ease;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

::selection { background: rgba(var(--primary-rgb),.22); }

/* Slim, theme-aware scrollbars everywhere */
* { scrollbar-width: thin; scrollbar-color: rgba(var(--primary-rgb),.28) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(100,116,139,.35); border-radius: 8px; }
*::-webkit-scrollbar-thumb:hover { background: rgba(var(--primary-rgb),.5); }

/* Native form widgets pick up brand colour (checkbox, radio, progress) */
:root { accent-color: var(--primary); }

/* ═══════════════════════════════════════════════════════════
   ADMIN LAYOUT
   ═══════════════════════════════════════════════════════════ */
.admin-body {
  background: var(--page-wash), var(--content-bg);
  background-attachment: fixed;
  display: flex;
}

/* ── Admin Sidebar ───────────────────────────────────────────── */
.adm-sidebar {
  width: var(--adm-sidebar-w);
  background: var(--sidebar-bg);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 1000;
  overflow: hidden;
  transition: transform .25s ease, width .25s ease;
  border-right: 1px solid var(--sidebar-border);
}

/* Brand */
.adm-brand {
  display: flex; align-items: center; gap: 11px;
  padding: 17px 18px 15px;
  border-bottom: 1px solid var(--sidebar-border);
  flex-shrink: 0;
  min-height: 68px;
}
/* An uploaded wordmark is the whole lockup (mark + name + tagline), so give it
   the full width of the panel rather than the 120px a bare icon needed. */
.adm-brand-full { display: flex; align-items: center; gap: 11px; min-width: 0; }
.adm-brand-full img { max-height: 40px; max-width: 100%; object-fit: contain; }

/* The square mark, shown only in the collapsed rail. */
.adm-brand-mark { display: none; }
.adm-brand-mark img {
  width: 34px; height: 34px;
  object-fit: contain;
  border-radius: 9px;
  display: block;
}
.adm-brand-icon {
  width: 38px; height: 38px;
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; color: #fff; flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(var(--primary-rgb),.28);
}
.adm-brand-name {
  font-size: 15.5px; font-weight: 800;
  color: var(--sidebar-ink); letter-spacing: -.2px;
}

/* Nav */
.adm-nav {
  flex: 1;
  padding: 12px 12px 8px;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Links pinned below the accordion (License). A hairline separates them from
   the sections above; margin-top:auto is deliberately NOT used — the nav
   scrolls, so a pushed-to-bottom block would sit off-screen on short menus. */
.adm-nav-foot {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--sidebar-border);
}
.adm-nav::-webkit-scrollbar { width: 3px; }
.adm-nav::-webkit-scrollbar-thumb { background: var(--sidebar-rail); border-radius: 2px; }

/* ── Dropdowns inside cards ──────────────────────────────────────────────────
   A dropdown opened inside a card was being cut off. TWO separate causes, and
   both must be fixed or the menu still looks broken:

   1. CLIPPING — `.lms-card` sets `overflow: hidden` (for rounded corners on
      tables/headers further down this file), which crops any child that
      escapes the card's box. No z-index can defeat clipping.
   2. PAINT ORDER — Bootstrap's `.card` is position:relative with z-index:auto,
      so sibling cards paint in DOM order. Even unclipped, the card *below*
      would be drawn over the menu.

   `.qb-toolbar` is the toolbar card that holds the Export menu; it has no
   content that needs clipping, so it opts out permanently. The `:has()` rule
   generalises both fixes to any admin card, but only while its menu is open,
   so rounded corners elsewhere are unaffected the rest of the time.

   Selectors are doubled up (`.lms-card.qb-toolbar`, not `.qb-toolbar`) on
   purpose: `.lms-card` sets `overflow: hidden` LOWER DOWN in this file, and at
   equal specificity the later rule wins. Two classes (0,2,0) beats it wherever
   this block happens to sit. */
.lms-card.qb-toolbar,
.card.qb-toolbar {
  overflow: visible;
  position: relative;
  z-index: 20;
}

.lms-card:has(.dropdown-menu.show),
.card:has(.dropdown-menu.show) {
  overflow: visible;
  position: relative;
  z-index: 30;
}

/* ── Collapsible nav sections (accordion, one open at a time) ────────────────
   The admin menu is ~55 items; grouping them behind headers keeps the sidebar
   to one screen. Role filtering happens before rendering, so a section only
   exists when the role can see something in it.

   The open section sits in a tinted tray that wraps the header AND its items,
   so at a glance you can see where the list you are reading belongs. */
.adm-nav-section {
  display: flex; flex-direction: column;
  border-radius: 12px;
  transition: background .18s ease;
}
.adm-nav-section.open {
  background: var(--sidebar-panel);
  padding-bottom: 4px;
}

.adm-nav-section-btn {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 10px 12px;
  margin-top: 2px;
  border: none; background: transparent;
  border-radius: 12px;
  color: var(--sidebar-ink);
  font-size: 11.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  cursor: pointer;
  transition: background .15s, color .15s;
  text-align: left;
}
.adm-nav-section-btn:hover { background: var(--sidebar-hover); color: var(--primary); }
.adm-nav-section-btn > i:first-child {
  font-size: 15px; width: 20px; text-align: center; flex-shrink: 0;
  color: var(--sidebar-ink);
  transition: color .15s;
}
.adm-nav-section-btn > span:first-of-type { flex: 1; white-space: nowrap; }
.adm-nav-section-btn:hover > i:first-child { color: var(--primary); }

/* Item count — tells you what's inside without opening it */
.adm-nav-section-count {
  font-size: 10px; font-weight: 700; line-height: 1;
  min-width: 18px; height: 18px; padding: 0 6px;
  border-radius: 9px;
  background: var(--sidebar-chip);
  color: var(--sidebar-ink-faint);
  display: inline-flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.adm-nav-caret {
  font-size: 11px;
  color: var(--sidebar-ink-faint);
  transition: transform .2s ease;
}
/* The tray already marks the open section, so the header stays flat inside it. */
.adm-nav-section.open > .adm-nav-section-btn { background: transparent; }
.adm-nav-section.open > .adm-nav-section-btn,
.adm-nav-section.open > .adm-nav-section-btn > i:first-child { color: var(--primary); }
.adm-nav-section.open .adm-nav-caret { transform: rotate(180deg); color: var(--primary); }

/* Expanded sidebar: an open section already reads as current, but the user can
   click it shut and then nothing says the page they are on lives in there. A
   dot beside the label keeps the trail. */
.adm-nav-section.has-active:not(.open) > .adm-nav-section-btn { color: var(--primary); }
.adm-nav-section.has-active:not(.open) > .adm-nav-section-btn > i:first-child { color: var(--primary); }
.adm-nav-section.has-active:not(.open) > .adm-nav-section-btn > span:first-of-type::after {
  content: '';
  display: inline-block;
  width: 5px; height: 5px;
  margin-left: 7px;
  vertical-align: middle;
  border-radius: 50%;
  background: var(--primary);
}

/* Animated height. Starts collapsed so there's no flash of a full menu before
   the script runs; JS sets the real height on load. */
.adm-nav-section-body {
  height: 0;
  overflow: hidden;
  transition: height .2s ease;
}
/* The guide rail belongs to the LIST, not to each row. Drawn per-item it broke
   into dashes wherever the 2px flex gap fell between two links. */
.adm-nav-section-inner {
  display: flex; flex-direction: column; gap: 1px;
  margin-left: 22px;
  padding: 2px 8px 2px 0;
  border-left: 1px solid var(--sidebar-rail);
}

/* Items inside a section sit inset, alongside that rail */
.adm-nav-section-inner .adm-nav-btn {
  padding: 8px 10px 8px 14px;
  border-radius: 0 10px 10px 0;
  font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
  .adm-nav-section-body { transition: none; }
  .adm-nav-caret { transition: none; }
}

/* Legacy flat section labels (kept for any view still using them) */
.adm-nav-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--sidebar-ink-faint);
  padding: 6px 12px;
  margin-top: 10px;
  border-top: 1px solid var(--sidebar-border);
  padding-top: 12px;
  user-select: none;
}
.adm-nav-group-label:first-child {
  border-top: none;
  margin-top: 0;
  padding-top: 4px;
}

.adm-nav-btn {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  color: var(--sidebar-ink-soft);
  text-decoration: none !important;
  font-size: 13.5px; font-weight: 500;
  border: none; background: transparent;
  cursor: pointer; width: 100%;
  transition: background .15s, color .15s;
  white-space: nowrap;
  position: relative;
}
.adm-nav-btn i {
  font-size: 16px; flex-shrink: 0; width: 20px; text-align: center;
  color: var(--sidebar-ink-faint);
  transition: color .15s;
}
.adm-nav-btn:hover { background: var(--sidebar-hover); color: var(--primary); }
.adm-nav-btn:hover i { color: var(--primary); }

/* Keyboard focus has to be visible — the sidebar is the primary way around the
   admin app and it had no focus style at all. */
.adm-nav-btn:focus-visible,
.adm-nav-section-btn:focus-visible,
.adm-user-row:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

/* Pending-migrations badge on the Database item */
.adm-nav-badge {
  margin-left: auto;
  background: var(--danger); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 1;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px rgba(224,36,36,.18);
  animation: admBadgePulse 2s ease-in-out infinite;
}
@keyframes admBadgePulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(224,36,36,.22); }
  50%      { box-shadow: 0 0 0 4px rgba(224,36,36,.05); }
}
@media (prefers-reduced-motion: reduce) { .adm-nav-badge { animation: none; } }

/* Active item — solid brand pill.
   A tinted pill with brand-coloured text only reaches 4.0:1 against the tray,
   which fails AA at this size. Filling it and reversing the text clears the
   threshold, and it is what the design calls for anyway. The gradient's dark
   end is what carries the contrast (5.8:1) — flat --primary alone is 4.4:1. */
.adm-nav-btn.active {
  background: linear-gradient(180deg, var(--primary), var(--primary-dark));
  color: #fff !important;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(var(--primary-rgb),.30);
}
.adm-nav-btn.active i { color: #fff; }
.adm-nav-btn.active:hover { background: linear-gradient(180deg, var(--primary), var(--primary-dark)); }
.adm-nav-btn.active:hover i { color: #fff; }
.adm-nav-btn.active::before { content: none; }

/* Bottom user row */
.adm-sidebar-bottom {
  flex-shrink: 0;
  border-top: 1px solid var(--sidebar-border);
  padding: 12px;
  background: var(--sidebar-bg);
  display: flex; flex-direction: column; gap: 4px;
}
.adm-user-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px;
  border-radius: 12px;
  border: 1px solid var(--sidebar-border);
  background: var(--sidebar-card);
  transition: background .15s, border-color .15s;
}
a.adm-user-row:hover { background: var(--sidebar-hover); border-color: rgba(var(--primary-rgb),.28); }
.adm-user-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: linear-gradient(180deg, var(--primary), var(--primary-dark));
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; color: #fff;
  flex-shrink: 0;
}
.adm-user-info { flex: 1; min-width: 0; }
.adm-user-name {
  font-size: 13px; font-weight: 600; color: var(--sidebar-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adm-user-role { font-size: 11px; color: var(--sidebar-ink-faint); }
.adm-user-caret { font-size: 12px; color: var(--sidebar-ink-faint); flex-shrink: 0; }
.adm-logout { color: var(--sidebar-ink-soft); }
.adm-logout:hover { background: rgba(224,36,36,.08); color: var(--danger) !important; }
.adm-logout:hover i { color: var(--danger); }

/* ── Collapsed rail ───────────────────────────────────────────
   Desktop only, hence the min-width: below 992px the sidebar is an off-canvas
   drawer and the same hamburger opens it at full width — a 76px rail sliding
   over a phone screen would be neither.

   Everything keys off --adm-sidebar-w, so re-pointing that one variable moves
   the sidebar AND the content margin together: no second set of widths to keep
   in step.

   Every rule below is scoped to .adm-sidebar on purpose. The hover flyout is a
   clone of these same nav items living at <body> level, and an unscoped
   "hide the labels" rule would hide them there too — leaving a flyout of
   anonymous icons. */
@media (min-width: 992px) {
  /* On <html>, not <body>: the pre-paint script in the layout head sets this
     before <body> exists, so the very first frame is already the right width.
     See the comment there. */
  html.adm-rail { --adm-sidebar-w: var(--adm-rail-w); }

  html.adm-rail .adm-sidebar .adm-brand { justify-content: center; padding-left: 0; padding-right: 0; }
  html.adm-rail .adm-sidebar .adm-brand-full { display: none; }
  html.adm-rail .adm-sidebar .adm-brand-mark { display: block; }

  html.adm-rail .adm-sidebar .adm-nav { padding-left: 10px; padding-right: 10px; }
  html.adm-rail .adm-sidebar .adm-nav-btn,
  html.adm-rail .adm-sidebar .adm-nav-section-btn { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }
  html.adm-rail .adm-sidebar .adm-nav-btn > span,
  html.adm-rail .adm-sidebar .adm-nav-section-btn > span,
  html.adm-rail .adm-sidebar .adm-nav-caret,
  html.adm-rail .adm-sidebar .adm-nav-section-count,
  html.adm-rail .adm-sidebar .adm-user-info,
  html.adm-rail .adm-sidebar .adm-user-caret { display: none; }

  /* The pending-migration badge survives as a dot — it is the one thing in
     here you must not miss, and a number will not fit. */
  html.adm-rail .adm-sidebar .adm-nav-badge {
    position: absolute; top: 5px; right: 8px;
    min-width: 9px; width: 9px; height: 9px; padding: 0;
    font-size: 0; overflow: hidden;
  }

  /* A section cannot expand in place in the rail — its items have no room for
     labels. Hovering opens a flyout instead; clicking widens the whole
     sidebar. See admin.js. */
  html.adm-rail .adm-sidebar .adm-nav-section.open { background: transparent; padding-bottom: 0; }
  html.adm-rail .adm-sidebar .adm-nav-section-body { display: none; }

  /* Which section holds the page you are on.
     Deliberately NOT the solid pill the active item itself wears — "you are
     inside this" and "this is the thing" have to read as different states, or
     the rail looks like two pages are open at once. A tint plus a left bar
     says containment; the pill says selection. */
  html.adm-rail .adm-sidebar .adm-nav-section.has-active > .adm-nav-section-btn {
    background: var(--sidebar-active);
    color: var(--primary);
  }
  html.adm-rail .adm-sidebar .adm-nav-section.has-active > .adm-nav-section-btn > i:first-child {
    color: var(--primary);
  }
  html.adm-rail .adm-sidebar .adm-nav-section.has-active > .adm-nav-section-btn::before {
    content: '';
    position: absolute;
    left: 0; top: 50%; transform: translateY(-50%);
    width: 3px; height: 20px;
    background: var(--primary);
    border-radius: 0 3px 3px 0;
  }
  html.adm-rail .adm-sidebar .adm-nav-section-btn { position: relative; }

  /* Which item the flyout belongs to, while it is open. */
  html.adm-rail .adm-sidebar .adm-nav-section-btn.adm-fly-on,
  html.adm-rail .adm-sidebar .adm-nav-btn.adm-fly-on { background: var(--sidebar-hover); color: var(--primary); }
  html.adm-rail .adm-sidebar .adm-nav-section-btn.adm-fly-on > i,
  html.adm-rail .adm-sidebar .adm-nav-btn.adm-fly-on > i { color: var(--primary); }

  html.adm-rail .adm-sidebar .adm-sidebar-bottom { padding: 10px 8px; }
  html.adm-rail .adm-sidebar .adm-user-row { justify-content: center; padding: 8px; border-color: transparent; }
  html.adm-rail .adm-sidebar .adm-logout { justify-content: center; }

  /* Widening and narrowing should read as one movement — but only once the
     page is up. Without the .adm-ready gate, any late class change would be
     ANIMATED rather than instant, turning a one-frame flash into a visible
     quarter-second slide. admin.js adds .adm-ready after the first paint. */
  html.adm-ready .adm-sidebar,
  html.adm-ready .admin-main { transition: width .2s ease, margin-left .2s ease; }
}
@media (prefers-reduced-motion: reduce) {
  .adm-sidebar, .admin-main { transition: none; }
}

/* ── Rail flyout ──────────────────────────────────────────────
   Lives at <body> level, not inside the sidebar. It has to: .adm-sidebar is
   overflow:hidden (for the rounded panel) and .adm-nav is a scroll container,
   so a child positioned inside either one gets clipped at the 76px edge. Fixed
   positioning against the viewport is the only way out of both. */
.adm-flyout {
  position: fixed;
  z-index: 1100;
  min-width: 210px;
  max-width: 280px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  padding: 8px;
  background: var(--sidebar-bg);
  border: 1px solid var(--sidebar-border);
  border-radius: 12px;
  box-shadow: 0 8px 30px rgba(15,23,42,.16), 0 2px 6px rgba(15,23,42,.06);
  opacity: 0;
  transform: translateX(-6px);
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
}
.adm-flyout.is-open { opacity: 1; transform: none; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  .adm-flyout { transition: none; }
}

.adm-flyout-title {
  font-size: 11px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--sidebar-ink);
  padding: 6px 10px 8px;
}
.adm-flyout-sep { border-top: 1px solid var(--sidebar-border); margin: 0 6px 6px; }

/* The cloned list drops the rail and inset the sidebar version carries. */
.adm-flyout .adm-nav-section-inner {
  margin-left: 0;
  padding: 0;
  border-left: 0;
  gap: 1px;
}
.adm-flyout .adm-nav-btn {
  border-radius: 9px;
  padding: 8px 10px;
  font-size: 13px;
  white-space: nowrap;
}
.adm-flyout .adm-nav-badge { position: static; }

/* A pinned item has no children, so its flyout is just the name. */
.adm-flyout.is-label { min-width: 0; padding: 6px; }
.adm-flyout.is-label .adm-flyout-title {
  padding: 4px 8px;
  text-transform: none; letter-spacing: 0;
  font-size: 12.5px; font-weight: 600;
  white-space: nowrap;
}

/* Main area shifts right */
.admin-main {
  margin-left: var(--adm-sidebar-w);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* ── Topbar — frosted glass ─────────────────────────────────── */
.admin-topbar {
  height: var(--topbar-h);
  background: var(--topbar-bg);
  -webkit-backdrop-filter: blur(14px) saturate(1.6);
  backdrop-filter: blur(14px) saturate(1.6);
  border-bottom: 1px solid var(--topbar-border);
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 12px;
  position: sticky; top: 0; z-index: 500;
}

.topbar-toggle {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 20px; padding: 4px;
  display: none;
}

/* The ADMIN hamburger is permanent, the way the student one already was
   (see ".student-topbar .topbar-toggle" further down). It was display:none
   until 991px, so on a desktop there was no way to collapse the sidebar at
   all — you either kept 264px of navigation or you narrowed the browser.
   Below 992px it still opens the off-canvas drawer; above it, it collapses
   the sidebar to an icon rail.

   Scoped to .admin-topbar on purpose: the student topbar keeps the look it
   has today. */
.admin-topbar .topbar-toggle {
  width: 34px; height: 34px; padding: 0;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.admin-topbar .topbar-toggle:hover { background: var(--row-hover); color: var(--primary); }
.admin-topbar .topbar-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.topbar-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.2px;
  color: var(--text-primary);
}

.topbar-icon-btn {
  background: none; border: none; cursor: pointer;
  width: 36px; height: 36px;
  border-radius: 10px;
  color: var(--text-muted);
  font-size: 17px;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s, transform .1s;
}
.topbar-icon-btn:hover {
  background: rgba(var(--primary-rgb),.1);
  color: var(--primary);
  transform: translateY(-1px);
}
.topbar-icon-btn:active { transform: translateY(0); }

/* Theme (dark-mode) toggle — sun/moon crossfade */
#admThemeToggle .bi { transition: transform .35s ease, opacity .2s; }
#admThemeToggle:hover .bi { transform: rotate(24deg); }

.badge-dot {
  width: 7px; height: 7px;
  background: var(--danger);
  border-radius: 50%;
  position: absolute; top: 6px; right: 6px;
  border: 2px solid var(--card-bg);
}

.topbar-divider {
  width: 1px; height: 24px;
  background: var(--border-color);
  margin: 0 4px;
}

.topbar-user-btn {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; cursor: pointer;
  padding: 4px 8px;
  border-radius: 10px;
  transition: background .15s;
  color: var(--text-primary);
}
.topbar-user-btn:hover { background: rgba(var(--primary-rgb),.08); }
.topbar-user-btn::after { display: none; } /* Remove default BS caret */
.topbar-user-btn .dropdown-toggle::after { display: inline-block; }

.topbar-avatar {
  width: 32px; height: 32px;
  background: var(--primary-light);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px;
  box-shadow: inset 0 0 0 1.5px rgba(var(--primary-rgb),.25);
}

.topbar-username { font-size: 13px; font-weight: 600; }

.topbar-dropdown {
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-lg);
  border-radius: var(--radius);
  min-width: 180px;
  overflow: hidden;
}

/* ── Breadcrumb ─────────────────────────────────────────────── */
.admin-breadcrumb {
  padding: 10px 20px;
  background: transparent;
  border-bottom: 1px solid var(--border-color);
}

.breadcrumb { font-size: 12.5px; margin-bottom: 0; }
.breadcrumb-item a { color: var(--primary); text-decoration: none; }
.breadcrumb-item a:hover { text-decoration: underline; }
.breadcrumb-item.active { color: var(--text-muted); }

/* ── Content ────────────────────────────────────────────────── */
.admin-content {
  flex: 1;
  padding: 24px 20px;
  /* No fill-mode here on purpose: `both` keeps the transform animation
     applied forever, which makes .admin-content a permanent containing
     block / stacking context. Bootstrap modals rendered inside page content
     then paint BELOW the body-appended .modal-backdrop (z-index 1050) and
     become unclickable. Without a fill-mode the animation stops applying
     after 0.3s and modals stack normally. */
  animation: admFadeIn .3s ease;
}
@keyframes admFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ── Stat cards — soft depth + gradient accent ──────────────── */
.stat-card {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 18px;
  display: flex;
  align-items: center;
  gap: 14px;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
  transition: box-shadow .2s, transform .2s, border-color .2s;
}
.stat-card::before {                     /* gradient hairline on top */
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--primary), #818cf8, transparent 80%);
  opacity: 0;
  transition: opacity .2s;
}
.stat-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: rgba(var(--primary-rgb),.35);
}
.stat-card:hover::before { opacity: 1; }

/* Filter-selected stat card (e.g. enrolment status tiles) */
.stat-card.ring-active {
  border-color: rgba(var(--primary-rgb),.55);
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb),.14), var(--shadow-sm);
}
.stat-card.ring-active::before { opacity: 1; }

/* Icon chip — soft wash of its own colour (works with text-* utilities) */
.stat-icon {
  font-size: 22px; flex-shrink: 0;
  width: 48px; height: 48px;
  border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, currentColor 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 18%, transparent);
}
.stat-body { flex: 1; }
.stat-value { font-size: 22px; font-weight: 800; letter-spacing: -.4px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.stat-label { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.stat-badge { font-size: 10.5px; font-weight: 600; }

/* ── Cards ──────────────────────────────────────────────────── */
.lms-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  background: var(--card-bg);
  overflow: hidden;
  transition: box-shadow .2s;
}
.lms-card:hover { box-shadow: var(--shadow-md); }

.lms-card-header {
  background: var(--card-bg);
  border-bottom: 1px solid var(--border-color);
  padding: 14px 18px;
  font-size: 14px;
  font-weight: 600;
}

/* Bootstrap .card fallback — many admin pages use it directly */
.admin-content .card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  background: var(--card-bg);
  color: var(--text-primary);
}
.admin-content .card-header {
  background: var(--card-bg);
  border-bottom: 1px solid var(--border-color);
}

/* ── Tables ─────────────────────────────────────────────────── */
.lms-table { font-size: 13.5px; margin-bottom: 0; }
.lms-table thead th {
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  border-bottom: 1px solid var(--border-color);
  padding: 11px 16px;
  position: sticky; top: 0;
  z-index: 1;
}
.lms-table tbody tr { transition: background .12s; }
.lms-table tbody tr:hover { background: var(--row-hover); }
.lms-table tbody td {
  padding: 11px 16px;
  border-bottom: 1px solid var(--border-color);
  vertical-align: middle;
  color: var(--text-primary);
  background: transparent;
}
.lms-table tbody tr:last-child td { border-bottom: none; }

/* Bootstrap table colours follow the theme */
.admin-content .table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--text-primary);
  --bs-table-border-color: var(--border-color);
  --bs-table-hover-bg: var(--row-hover);
  --bs-table-hover-color: var(--text-primary);
  --bs-table-striped-bg: var(--surface-2);
  --bs-table-striped-color: var(--text-primary);
}

/* ═══════════════════════════════════════════════════════════
   BOOTSTRAP COMPONENT POLISH (buttons, forms, modals, …)
   ═══════════════════════════════════════════════════════════ */

/* Buttons — slightly rounder, primary gets gradient + glow */
.btn { border-radius: var(--radius-sm); font-weight: 600; transition: all .15s ease; }
.btn:active { transform: translateY(1px); }

.btn-primary {
  --bs-btn-bg: var(--primary);
  --bs-btn-border-color: var(--primary);
  --bs-btn-hover-bg: var(--primary-dark);
  --bs-btn-hover-border-color: var(--primary-dark);
  --bs-btn-active-bg: var(--primary-dark);
  --bs-btn-active-border-color: var(--primary-dark);
  background-image: linear-gradient(135deg, var(--primary), var(--primary-dark));
  border: none;
  box-shadow: 0 2px 10px rgba(var(--primary-rgb),.28);
}
.btn-primary:hover {
  background-image: linear-gradient(135deg, var(--primary-dark), var(--primary-dark));
  box-shadow: var(--glow-primary);
  transform: translateY(-1px);
}
.btn-outline-primary {
  --bs-btn-color: var(--primary);
  --bs-btn-border-color: rgba(var(--primary-rgb),.5);
  --bs-btn-hover-bg: var(--primary);
  --bs-btn-hover-border-color: var(--primary);
}
.btn-light { border-color: var(--border-color); }

/* Forms — soft fields with brand focus ring */
.form-control, .form-select {
  border-radius: var(--radius-sm);
  border-color: var(--border-color);
  background-color: var(--card-bg);
  color: var(--text-primary);
}
.form-control:focus, .form-select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3.5px rgba(var(--primary-rgb),.13);
  background-color: var(--card-bg);
  color: var(--text-primary);
}
.form-control::placeholder { color: var(--text-muted); opacity: .75; }
.form-label { font-weight: 600; font-size: 13px; color: var(--text-primary); }
.form-text  { color: var(--text-muted); }

.form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.form-check-input:focus   { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb),.15); }
.form-switch .form-check-input { cursor: pointer; }

.input-group-text {
  background: var(--surface-2);
  border-color: var(--border-color);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
}

/* Dropdown menus — floating glass panels */
.dropdown-menu {
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  background-color: var(--card-bg);
  color: var(--text-primary);
  padding: 6px;
}
.dropdown-item {
  border-radius: 8px;
  font-size: 13.5px;
  color: var(--text-primary);
  transition: background .12s, color .12s;
}
.dropdown-item:hover, .dropdown-item:focus {
  background-color: rgba(var(--primary-rgb),.09);
  color: var(--text-primary);
}
.dropdown-item:active { background-color: var(--primary-light); color: var(--primary); }
.dropdown-divider { border-color: var(--border-color); }

/* Modals — large radius, deep shadow */
.modal-content {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  background-color: var(--card-bg);
  color: var(--text-primary);
}
.modal-header { border-bottom-color: var(--border-color); }
.modal-footer { border-top-color: var(--border-color); }
.modal-backdrop.show { opacity: .55; backdrop-filter: blur(2px); }

/* Nav tabs / pills */
.nav-tabs { border-bottom-color: var(--border-color); }
.nav-tabs .nav-link {
  color: var(--text-muted);
  font-weight: 600;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 8px 8px 0 0;
  transition: color .15s, border-color .15s, background .15s;
}
.nav-tabs .nav-link:hover { color: var(--primary); background: rgba(var(--primary-rgb),.05); }
.nav-tabs .nav-link.active {
  color: var(--primary);
  background: transparent;
  border-bottom: 2px solid var(--primary);
}
.nav-pills .nav-link { color: var(--text-muted); font-weight: 600; border-radius: 10px; }
.nav-pills .nav-link.active { background: var(--primary); box-shadow: 0 2px 10px rgba(var(--primary-rgb),.3); }

/* Pagination */
.pagination { --bs-pagination-border-radius: var(--radius-sm); }
.page-link {
  color: var(--primary);
  border-color: var(--border-color);
  background-color: var(--card-bg);
}
.page-link:hover { background-color: rgba(var(--primary-rgb),.08); color: var(--primary); }
.page-item.active .page-link {
  background-color: var(--primary);
  border-color: var(--primary);
  box-shadow: 0 2px 8px rgba(var(--primary-rgb),.3);
}
.page-item.disabled .page-link { background-color: var(--surface-2); color: var(--text-muted); }

/* Badges & alerts */
.badge { font-weight: 600; letter-spacing: .2px; border-radius: 7px; }
.alert { border-radius: var(--radius); border-width: 1px; }

/* Progress bars */
.progress { border-radius: 20px; background-color: var(--surface-2); overflow: hidden; }
.progress-bar { background: linear-gradient(90deg, var(--primary), #818cf8); }

/* Offcanvas + toasts follow surfaces */
.offcanvas { background-color: var(--card-bg); color: var(--text-primary); }
.toast     { border-radius: var(--radius); box-shadow: var(--shadow-md); }

/* ═══════════════════════════════════════════════════════════
   AUTH LAYOUT  (forgot / reset / 2FA — login has its own page CSS)
   ═══════════════════════════════════════════════════════════ */
.auth-body { padding: 16px; }

.auth-card {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  padding: 36px 32px;
  width: 100%;
  max-width: 420px;
  box-shadow: var(--shadow-lg);
}

.auth-logo {
  width: 56px; height: 56px;
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; color: #fff;
  margin: 0 auto 20px;
  box-shadow: var(--glow-primary);
}

.auth-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.3px;
  text-align: center;
  margin-bottom: 4px;
  color: var(--text-primary);
}

.auth-subtitle {
  font-size: 13.5px;
  text-align: center;
  color: var(--text-muted);
  margin-bottom: 24px;
}

.form-floating label { font-size: 13.5px; color: var(--text-muted); }

.password-toggle {
  position: absolute;
  right: 12px; top: 50%;
  transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 15px;
  z-index: 10;
}

.btn-login {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  border: none;
  padding: 12px;
  font-size: 14px;
  font-weight: 700;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(var(--primary-rgb),.28);
  transition: box-shadow .15s, transform .1s;
}
.btn-login:hover { box-shadow: var(--glow-primary); transform: translateY(-1px); }
.btn-login:active { transform: translateY(0); }

.auth-phase-note {
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
  margin-top: 18px;
  padding: 10px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}

.auth-links {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 14px;
}

/* ═══════════════════════════════════════════════════════════
   STUDENT LAYOUT (legacy hooks — student app itself uses app.css)
   ═══════════════════════════════════════════════════════════ */
.student-body {
  background: var(--content-bg);
  display: flex;
}

.student-sidebar {
  width: var(--sidebar-width);
  min-height: 100vh;
  background: #1e293b;
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 1000;
  overflow-y: auto;
  transition: transform .25s ease;
}

.student-sidebar .nav-item.active {
  background: rgba(var(--primary-rgb),.18);
  color: var(--primary);
  border-left-color: var(--primary);
}

.student-sidebar .brand-logo { background: var(--primary); }

.student-main {
  margin-left: var(--sidebar-width);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.student-topbar {
  height: var(--topbar-h);
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--topbar-border);
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 12px;
  position: sticky; top: 0; z-index: 500;
  box-shadow: var(--shadow-sm);
}

.student-content { flex: 1; padding: 24px 20px; }
.student-footer { text-align: center; font-size: 12px; color: var(--text-muted); padding: 14px; border-top: 1px solid var(--border-color); background: var(--card-bg); }

/* Student stat cards */
.student-stat-card {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 20px 16px;
  text-align: center;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .2s, transform .2s;
}
.student-stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.student-stat-icon { font-size: 28px; margin-bottom: 8px; }
.student-stat-value { font-size: 24px; font-weight: 700; color: var(--text-primary); }
.student-stat-label { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* ═══════════════════════════════════════════════════════════
   DARK THEME — component-level fixes on top of the token swap
   ═══════════════════════════════════════════════════════════ */
[data-theme="dark"] .badge-dot { border-color: var(--card-bg); }
[data-theme="dark"] .topbar-avatar { background: rgba(var(--primary-rgb),.16); }
[data-theme="dark"] .stat-icon {
  background: color-mix(in srgb, currentColor 16%, transparent);
}
[data-theme="dark"] .admin-content .card,
[data-theme="dark"] .lms-card { box-shadow: var(--shadow-sm); }
[data-theme="dark"] .modal-backdrop.show { opacity: .7; }
[data-theme="dark"] .btn-light,
[data-theme="dark"] .btn-outline-secondary {
  --bs-btn-bg: transparent;
  --bs-btn-color: var(--text-primary);
  --bs-btn-border-color: var(--border-color);
  --bs-btn-hover-bg: var(--surface-2);
  --bs-btn-hover-color: var(--text-primary);
  --bs-btn-hover-border-color: var(--border-color);
}
[data-theme="dark"] .text-dark { color: var(--text-primary) !important; }
[data-theme="dark"] .bg-white, [data-theme="dark"] .bg-light { background-color: var(--card-bg) !important; }
[data-theme="dark"] .border { border-color: var(--border-color) !important; }
[data-theme="dark"] img { opacity: .94; }

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE — collapse sidebar on mobile
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  .adm-sidebar {
    transform: translateX(-100%);
    z-index: 1050;
    /* Off-canvas it floats over the page, so it needs the lift the
       docked panel does not. */
    box-shadow: 4px 0 28px rgba(15,23,42,.18);
  }
  .adm-sidebar.mobile-open {
    transform: translateX(0);
  }
  .admin-main {
    margin-left: 0 !important;
  }
  .topbar-toggle { display: flex !important; }

  .auth-card { padding: 28px 20px; }
}


/* ═══════════════════════════════════════════════════════════
   GLOBAL ADMIN SEARCH  (/admin/search + topbar dropdown)
   ═══════════════════════════════════════════════════════════ */
.adm-srch { max-width: 900px; }

.adm-srch-form {
  display: flex; align-items: center; gap: 10px;
  position: relative;
  margin-bottom: 14px;
}
.adm-srch-form-icon {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted); font-size: 16px; pointer-events: none;
}
.adm-srch-input {
  flex: 1; min-width: 0;
  padding: 13px 16px 13px 44px;
  font-size: 15px;
  color: var(--text-primary);
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.adm-srch-input::placeholder { color: var(--text-muted); }
.adm-srch-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb),.14);
}
.adm-srch-input::-webkit-search-cancel-button { cursor: pointer; }
.adm-srch-go { padding: 12px 22px; border-radius: var(--radius); font-weight: 600; }

.adm-srch-summary {
  font-size: 13.5px; color: var(--text-muted);
  margin: 0 0 14px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
}
.adm-srch-summary strong { color: var(--text-primary); font-weight: 600; }
.adm-srch-scoped {
  font-size: 12px; padding: 2px 9px; border-radius: 20px;
  background: rgba(var(--primary-rgb),.09); color: var(--primary);
}

/* Category chips */
.adm-srch-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 22px; }
.adm-srch-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 13px;
  font-size: 12.5px; font-weight: 500;
  color: var(--text-muted); text-decoration: none;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  transition: color .15s, border-color .15s, background .15s;
}
.adm-srch-chip:hover { color: var(--primary); border-color: rgba(var(--primary-rgb),.4); }
.adm-srch-chip.is-on {
  background: var(--primary); border-color: var(--primary);
  color: #fff; font-weight: 600;
}
.adm-srch-chip-n {
  font-size: 11px; font-weight: 700; line-height: 1;
  padding: 2px 6px; border-radius: 20px;
  background: rgba(var(--primary-rgb),.12); color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.adm-srch-chip.is-on .adm-srch-chip-n { background: rgba(255,255,255,.24); color: #fff; }

/* Result groups */
.adm-srch-group { margin-bottom: 26px; }
.adm-srch-group-head {
  display: flex; align-items: center; gap: 9px;
  font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 8px; padding-bottom: 8px;
  border-bottom: 1px solid var(--border-color);
}
.adm-srch-group-head > i { color: var(--primary); font-size: 14px; }
.adm-srch-group-n {
  font-size: 11px; font-weight: 700; color: var(--text-muted);
  background: var(--surface-2); padding: 2px 7px; border-radius: 20px;
  letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.adm-srch-group-more {
  margin-left: auto; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0; text-transform: none;
  color: var(--primary); text-decoration: none;
}
.adm-srch-group-more:hover { text-decoration: underline; }

.adm-srch-list { list-style: none; margin: 0; padding: 0; }

.adm-srch-hitrow {
  display: flex; align-items: center; gap: 13px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background .13s;
}
.adm-srch-hitrow:hover { background: var(--row-hover); }
.adm-srch-hitrow:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.adm-srch-hiticon {
  width: 34px; height: 34px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgba(var(--primary-rgb),.10);
  color: var(--primary); font-size: 15px;
}
.adm-srch-hittext { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.adm-srch-hittitle {
  font-size: 14px; font-weight: 600; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adm-srch-hitsub {
  font-size: 12.5px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adm-srch-hitgo {
  color: var(--text-muted); font-size: 13px; opacity: 0;
  transform: translateX(-4px);
  transition: opacity .15s, transform .15s;
}
.adm-srch-hitrow:hover .adm-srch-hitgo { opacity: 1; transform: none; }

/* The matched run inside a title or subtitle */
mark.adm-srch-hit {
  background: rgba(var(--primary-rgb),.18);
  color: inherit;
  padding: 0 1px; border-radius: 3px;
}

/* Empty / guidance states */
.adm-srch-empty {
  text-align: center; padding: 54px 24px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}
.adm-srch-empty > i { font-size: 30px; color: var(--text-muted); opacity: .45; }
.adm-srch-empty h3 { font-size: 17px; font-weight: 600; margin: 14px 0 6px; color: var(--text-primary); }
.adm-srch-empty p { font-size: 13.5px; color: var(--text-muted); margin: 0 auto; max-width: 52ch; }
.adm-srch-note { margin-top: 12px !important; font-style: italic; }
.adm-srch-tries {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 8px; margin-top: 20px; font-size: 12.5px; color: var(--text-muted);
}
.adm-srch-tries a {
  padding: 4px 11px; border-radius: 20px;
  background: var(--surface-2); border: 1px solid var(--border-color);
  color: var(--text-primary); text-decoration: none;
}
.adm-srch-tries a:hover { color: var(--primary); border-color: rgba(var(--primary-rgb),.4); }

/* ── Topbar dropdown ─────────────────────────────────────── */
.adm-qs-group {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-muted);
  padding: 9px 14px 5px;
}
.adm-qs-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; text-decoration: none;
}
.adm-qs-row:hover, .adm-qs-row.is-cursor { background: var(--row-hover); }
.adm-qs-row.is-cursor { outline: 2px solid var(--primary); outline-offset: -2px; }
.adm-qs-row > i { color: var(--primary); font-size: 14px; flex-shrink: 0; }
.adm-qs-text { min-width: 0; }
.adm-qs-title {
  font-size: 13px; font-weight: 600; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adm-qs-sub {
  font-size: 11.5px; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adm-qs-foot {
  display: block; padding: 10px 14px; text-align: center;
  font-size: 12.5px; font-weight: 600; color: var(--primary);
  text-decoration: none; border-top: 1px solid var(--border-color);
}
.adm-qs-foot:hover { background: var(--row-hover); }
.adm-qs-msg { padding: 18px 14px; text-align: center; font-size: 13px; color: var(--text-muted); }

@media (max-width: 600px) {
  .adm-srch-form { flex-wrap: wrap; }
  .adm-srch-go { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════
   IMPERSONATION BANNER
   ═══════════════════════════════════════════════════════════ */
.impersonation-banner {
  background: linear-gradient(90deg, #7c3aed, #6d28d9);
  color: #fff;
  font-size: 13px;
  padding: 9px 20px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  position: sticky;
  top: var(--topbar-h);
  z-index: 490;
  box-shadow: 0 2px 8px rgba(109,40,217,.3);
}

.impersonation-banner .btn-warning {
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 6px;
}

/* ═══════════════════════════════════════════════════════════
   RICH TEXT EDITOR (RichEditor / TinyMCE) — themed borders
   ═══════════════════════════════════════════════════════════ */
.tox-tinymce {
  border: 1px solid var(--border-color) !important;
  border-radius: var(--radius) !important;
}

/* ═══════════════════════════════════════════════════════════
   STUDENT COURSE CARD — Start button
   ═══════════════════════════════════════════════════════════ */
.course-card {
  border-radius: var(--radius) !important;
  transition: transform .2s, box-shadow .2s;
  overflow: hidden;
  border: 1px solid var(--border-color);
  background: var(--card-bg);
}
.course-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.course-card .course-thumb {
  height: 150px;
  object-fit: cover;
  width: 100%;
  display: block;
}
.course-card .course-thumb-placeholder {
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg,var(--primary),var(--primary-dark));
}
.course-card .course-body { padding: 14px 16px 10px; }
.course-card .course-title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.course-card .course-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.course-card .course-footer {
  padding: 10px 16px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.btn-start-course {
  background: linear-gradient(135deg,var(--primary),var(--primary-dark));
  color: #fff !important;
  border: none;
  border-radius: 8px;
  padding: 7px 16px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none !important;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: opacity .15s, transform .1s;
}
.btn-start-course:hover { opacity: .9; transform: translateY(-1px); }
.btn-start-course.completed {
  background: linear-gradient(135deg,#0e9f6e,#059669);
}

/* ═══════════════════════════════════════════════════════════
   STUDENT BOTTOM NAV (PWA app-like)
   ═══════════════════════════════════════════════════════════ */
.student-bottom-nav {
  display: none; /* shown only on mobile/PWA */
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 1100;
  background: var(--card-bg);
  border-top: 1px solid var(--border-color);
  box-shadow: 0 -4px 20px rgba(0,0,0,.1);
  padding: 0;
  height: 64px;
  padding-bottom: env(safe-area-inset-bottom, 0px); /* iPhone notch */
}
.student-bottom-nav .nav-items {
  display: flex;
  height: 100%;
}
.student-bottom-nav .nav-item-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 10.5px;
  font-weight: 500;
  padding: 8px 4px;
  border: none;
  background: none;
  cursor: pointer;
  transition: color .15s;
  position: relative;
}
.student-bottom-nav .nav-item-btn i {
  font-size: 20px;
  line-height: 1;
}
.student-bottom-nav .nav-item-btn.active,
.student-bottom-nav .nav-item-btn:hover {
  color: var(--primary);
}
.student-bottom-nav .nav-item-btn.active::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 32px; height: 3px;
  background: var(--primary);
  border-radius: 0 0 4px 4px;
}
/* Active icon — filled version */
.student-bottom-nav .nav-item-btn.active i { font-weight: 900; }

/* Show bottom nav on small screens OR standalone PWA */
@media (max-width: 768px) {
  .student-bottom-nav { display: block; }
  .student-main { padding-bottom: 72px; }
  /* Hide sidebar on mobile — use bottom nav instead */
  .student-sidebar { transform: translateX(-100%); }
  .student-main  { margin-left: 0 !important; }
}
@media all and (display-mode: standalone) {
  .student-bottom-nav { display: block; }
  .student-main { padding-bottom: 72px; }
  .student-sidebar { transform: translateX(-100%) !important; }
  .student-main  { margin-left: 0 !important; }
}

/* LOGIN PAGE — split layout (legacy hooks) */
.login-split {
  min-height: 100vh;
  display: flex;
  width: 100%;
  max-width: 100%;
}
.login-split-left {
  flex: 1;
  background: linear-gradient(145deg,#0f172a 0%,#1e1b4b 50%,#312e81 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px;
  position: relative;
  overflow: hidden;
}
.login-split-left::before {
  content: '';
  position: absolute;
  width: 400px; height: 400px;
  border-radius: 50%;
  background: rgba(var(--primary-rgb),.15);
  top: -80px; right: -80px;
}
.login-split-left::after {
  content: '';
  position: absolute;
  width: 300px; height: 300px;
  border-radius: 50%;
  background: rgba(var(--primary-rgb),.1);
  bottom: -60px; left: -60px;
}
.login-split-right {
  width: 480px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 40px;
  background: #fff;
}
.login-feature-list {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
  z-index: 1;
}
.login-feature-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  color: rgba(255,255,255,.85);
  font-size: 15px;
  margin-bottom: 18px;
}
.login-feature-list li i {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: rgba(255,255,255,.12);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}
@media (max-width: 768px) {
  .login-split { flex-direction: column; }
  .login-split-left { display: none; }
  .login-split-right { width: 100%; min-height: 100vh; padding: 32px 20px; background: linear-gradient(135deg,#1e293b,#0f172a); }
  .login-split-right .login-form-card { background: #fff; border-radius: 20px; padding: 32px 24px; width: 100%; max-width: 420px; }
}

/* ── Student sidebar collapsed state (desktop hamburger) ────────────────── */
.student-sidebar.collapsed {
  width: 0;
  overflow: hidden;
  min-width: 0;
}
.student-main.sidebar-collapsed {
  margin-left: 0 !important;
}
/* Smooth transition */
.student-sidebar {
  transition: width .25s ease, transform .25s ease;
}
.student-main {
  transition: margin-left .25s ease;
}

/* Student topbar always show hamburger */
.student-topbar .topbar-toggle {
  display: flex !important;
}

/* ── Notification bell ────────────────────────────────────────────────────── */
.notif-badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 16px; height: 16px;
  border-radius: 8px;
  background: #e02424;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  padding: 0 3px;
  pointer-events: none;
}
.notif-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
  transition: background .1s;
}
.notif-item:hover { background: var(--row-hover); }
.notif-item.unread { background: rgba(var(--primary-rgb),.08); }
.notif-item.unread:hover { background: rgba(var(--primary-rgb),.13); }
.notif-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--primary); flex-shrink: 0; margin-top: 5px;
}
.notif-read-dot { width: 8px; height: 8px; flex-shrink: 0; }
.notif-title { font-size: 13px; font-weight: 600; color: var(--text-primary); line-height: 1.3; }
.notif-body  { font-size: 12px; color: var(--text-muted); margin-top: 2px; line-height: 1.4; }
.notif-time  { font-size: 11px; color: var(--text-muted); flex-shrink: 0; margin-top: 2px; white-space: nowrap; }

/* ── Admin footer ─────────────────────────────────────────────────────────── */
.admin-footer {
  padding: 14px 24px;
  border-top: 1px solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12.5px;
  color: var(--text-muted);
  flex-wrap: wrap;
  gap: 8px;
  background: transparent;
}
.admin-footer a { color: var(--text-muted); text-decoration: none; }
.admin-footer a:hover { color: var(--primary); }

/* ── Admin sidebar mobile responsive ─────────────────────────── */
@media (max-width: 991px) {
  .adm-sidebar {
    transform: translateX(-100%);
    z-index: 1050;
    /* Off-canvas it floats over the page, so it needs the lift the
       docked panel does not. */
    box-shadow: 4px 0 28px rgba(15,23,42,.18);
  }
  .adm-sidebar.mobile-open { transform: translateX(0); }
  .admin-main { margin-left: 0 !important; }
  .topbar-toggle { display: flex !important; }
}

/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE TYPOGRAPHY — GLOBAL STANDARD
   Normalizes oversized text on mobile / tablet across every page.
   Sizes ONLY (no colors or weights), so components keep their look
   but scale to the viewport. Desktop (>991px) is untouched.
═══════════════════════════════════════════════════════════════ */

/* ── Tablet (≤991px): tame the largest sizes ── */
@media (max-width: 991.98px) {
  h1, .h1       { font-size: 26px !important; }
  .display-1, .display-2, .display-3 { font-size: clamp(28px, 6vw, 40px) !important; }
  .display-4, .display-5, .display-6 { font-size: clamp(24px, 5vw, 32px) !important; }
  .fs-1         { font-size: 26px !important; }
  .fs-2         { font-size: 22px !important; }
}

/* ── Phone (≤768px): the standard mobile type scale ── */
@media (max-width: 768px) {
  h1, .h1       { font-size: 22px   !important; }
  h2, .h2       { font-size: 19px   !important; }
  h3, .h3       { font-size: 17px   !important; }
  h4, .h4       { font-size: 15.5px !important; }
  h5, .h5       { font-size: 14.5px !important; }
  h6, .h6       { font-size: 13.5px !important; }

  .display-1, .display-2, .display-3,
  .display-4, .display-5, .display-6 { font-size: clamp(22px, 7vw, 28px) !important; }

  .fs-1         { font-size: 22px !important; }
  .fs-2         { font-size: 19px !important; }
  .fs-3         { font-size: 17px !important; }
  .fs-4         { font-size: 16px !important; }
  .lead         { font-size: 15px !important; }

  .modal-title  { font-size: 16.5px !important; }
  .btn-lg       { font-size: 15.5px !important; }
  .table        { font-size: 13.5px; }

  /* iOS Safari auto-zooms into focused fields whose font-size is < 16px —
     16px inputs keep the viewport stable while typing */
  input.form-control, select.form-select, textarea.form-control { font-size: 16px !important; }
  .form-control-lg { font-size: 17px !important; }
}

/* ── AI feature gate ───────────────────────────────────────────────────────
   Applied by public/assets/js/ai-gate.js when Settings → AI Integration has
   AI switched off. The control stays visible (so staff can see the feature
   exists) but reads as unavailable; pointer-events stay on the element itself
   so its explanatory tooltip still works. */
.ai-disabled {
  opacity: .5;
  filter: grayscale(.7);
  cursor: not-allowed !important;
}
.ai-disabled * { pointer-events: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   Shared admin UI primitives — stat tiles, segmented control, avatar, meter,
   pills, empty states. Theme-token driven so every page stays consistent in
   light and dark. Used by learner analytics, assignments, knowledge base, etc.
   ═════════════════════════════════════════════════════════════════════════ */
.ui-stats{display:grid;gap:16px;grid-template-columns:repeat(4,1fr);margin-bottom:22px}
@media(max-width:1100px){.ui-stats{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.ui-stats{grid-template-columns:1fr}}
.ui-stat{display:flex;align-items:center;gap:14px;padding:16px 18px}
.ui-stat-ic{width:46px;height:46px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}
.ui-stat-val{font-size:23px;font-weight:800;line-height:1;color:var(--text-primary)}
.ui-stat-lbl{font-size:12px;color:var(--text-muted);margin-top:4px;font-weight:500}

.ui-seg{display:inline-flex;background:var(--surface-2);border:1px solid var(--border-color);border-radius:10px;padding:3px;gap:2px}
.ui-seg a,.ui-seg button{font-size:12.5px;font-weight:600;padding:6px 13px;border-radius:8px;color:var(--text-muted);text-decoration:none;border:none;background:none;cursor:pointer;transition:.15s;white-space:nowrap}
.ui-seg a:hover,.ui-seg button:hover{color:var(--text-primary)}
.ui-seg a.on,.ui-seg button.on{background:var(--primary);color:#fff;box-shadow:0 1px 4px rgba(var(--primary-rgb),.35)}

.ui-avatar{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:#fff;flex-shrink:0;text-transform:uppercase}

.ui-meter{height:7px;border-radius:6px;background:var(--surface-2);overflow:hidden;border:1px solid var(--border-color)}
.ui-meter-fill{height:100%;border-radius:6px}

.ui-pill{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;padding:4px 10px;border-radius:20px;line-height:1;white-space:nowrap}
.ui-pill i{font-size:11px}

.ui-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:54px 24px;text-align:center}
.ui-empty-ic{width:70px;height:70px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:30px;margin-bottom:14px}

.btn-xs{font-size:11.5px;padding:3px 8px;border-radius:7px}
