/* ═══════════════════════════════════════════════════════════
   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);
  --border-strong:   #cfd6e1;          /* control outlines */

  /* Elevation: hairlines carry structure; shadows only hint */
  --shadow-xs:       0 1px 2px rgba(15,23,42,.05);
  --shadow-sm:       0 1px 2px rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.05);
  --shadow-md:       0 2px 4px -1px rgba(15,23,42,.05), 0 8px 20px -4px rgba(15,23,42,.10);
  --shadow-lg:       0 4px 8px -2px rgba(15,23,42,.06), 0 18px 40px -8px rgba(15,23,42,.18);
  --glow-primary:    0 4px 12px rgba(var(--primary-rgb),.24);
  --focus-ring:      0 0 0 3px rgba(var(--primary-rgb),.26);
  /* Brand fills behind white text: gradient top / bottom */
  --primary-fill:    var(--primary);
  --primary-strong:  var(--primary-dark);

  --radius-xs:       6px;
  --radius-sm:       8px;
  --radius:          12px;
  --radius-lg:       16px;
  --font:            'Poppins', 'Inter', system-ui, -apple-system, sans-serif;

  /* Type scale (14px body), 4px spacing rhythm, short decelerating motion */
  --fs-xs: 11.5px; --fs-sm: 12.5px; --fs-base: 14px; --fs-md: 15px; --fs-lg: 17px;
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px;
  --ease: cubic-bezier(.2,0,0,1); --dur-fast: .12s; --dur: .18s;

  /* 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;
  --border-strong:  #3a3a46;

  --shadow-xs:      0 1px 2px rgba(0,0,0,.3);
  --shadow-sm:      0 1px 2px rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.2);
  --shadow-md:      0 2px 4px rgba(0,0,0,.3), 0 10px 24px -4px rgba(0,0,0,.45);
  --shadow-lg:      0 6px 14px rgba(0,0,0,.4), 0 24px 48px -8px rgba(0,0,0,.6);
  --glow-primary:   0 4px 14px rgba(var(--primary-rgb),.3);
  --focus-ring:     0 0 0 3px rgba(var(--primary-rgb),.38);
  /* White on the light dark-mode brand is ~3.3:1: deepen fills to clear AA */
  --primary-fill:   color-mix(in srgb, var(--primary) 84%, #000);
  --primary-strong: color-mix(in srgb, var(--primary) 68%, #000);

  --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%);
}

/* ── Bootstrap bridge: its tokens follow ours (brand, theme, radii) ── */
:root {
  --bs-primary: var(--primary); --bs-primary-rgb: var(--primary-rgb); --bs-link-color: var(--primary);
  --bs-link-color-rgb: var(--primary-rgb); --bs-link-hover-color: var(--primary-dark); --bs-link-hover-color-rgb: var(--primary-rgb);
  --bs-primary-text-emphasis: var(--primary-dark); --bs-primary-bg-subtle: rgba(var(--primary-rgb),.1); --bs-primary-border-subtle: rgba(var(--primary-rgb),.3);
  --bs-focus-ring-color: rgba(var(--primary-rgb),.26); --bs-body-color: var(--text-primary); --bs-body-bg: var(--card-bg);
  --bs-emphasis-color: var(--text-primary); --bs-secondary-color: var(--text-muted); --bs-secondary-bg: var(--surface-2);
  --bs-tertiary-bg: var(--surface-2); --bs-border-color: var(--border-color); --bs-border-color-translucent: var(--border-color);
  --bs-border-radius-sm: var(--radius-xs); --bs-border-radius: var(--radius-sm); --bs-border-radius-lg: var(--radius);
  --bs-border-radius-xl: var(--radius-lg);
}

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

body {
  font-family: var(--font);
  font-size: var(--fs-base);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { letter-spacing: -.01em; }

/* ── Heading scale (desktop) ──────────────────────────────────────────────
   One scale for the whole admin app, so an h2 on one page is not twice the
   size of the h5 the next page uses for the same job. Built on the --fs
   tokens above; the phone normaliser further down still wins below 768px. */
h1, .h1 { font-size: 28px; font-weight: 700; line-height: 1.25; }
h2, .h2 { font-size: 24px; font-weight: 700; line-height: 1.3; }
h3, .h3 { font-size: 20px; font-weight: 600; line-height: 1.35; }
h4, .h4 { font-size: 18px; font-weight: 600; line-height: 1.4; }
/* h5 keeps Bootstrap's 20px (the `h5.mb-0` card-header title), h6 its 16px;
   both get the same weight as the rest of the scale. */
h5, .h5, h6, .h6 { font-weight: 600; line-height: 1.4; }

/* ── Page header ──────────────────────────────────────────────────────────
   `h2.adm-page-title` (and the heading inside .adm-page-header) renders at the
   same 20px / 600 as the common `h5.mb-0` card-header title, instead of the
   32px Bootstrap h2 it fell back to when no rule existed. */
.adm-page-header { margin-bottom: 1.5rem; }
h2.adm-page-title, .adm-page-title,
.adm-page-header > h1, .adm-page-header > h2, .adm-page-header > h3,
.adm-page-header > div > h1, .adm-page-header > div > h2, .adm-page-header > div > h3 {
  font-size: 20px; font-weight: 600; line-height: 1.3; margin-bottom: .25rem;
}
.adm-page-header p, .adm-page-sub { color: var(--text-muted); font-size: var(--fs-base); margin-bottom: 0; }

/* Keyboard focus for anything in the admin app without its own style */
:where(.admin-body :is(a, button, [role="button"], summary, [tabindex])):focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* 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; }
}
/* While the theme toggle swaps data-theme (admin.js adds this class for one
   frame) no element transitions: the whole page repaints to the new palette in
   a single frame instead of thousands of elements each easing on their own
   timing — the flicker seen on long lists. */
html.theme-switching, html.theme-switching *,
html.theme-switching *::before, html.theme-switching *::after {
  transition: none !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-soft);
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--dur-fast), color var(--dur-fast);
  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-faint);
  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: 9px 12px;
  border-radius: var(--radius-sm);
  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-color var(--dur-fast), color var(--dur-fast);
  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-fill), var(--primary-strong));
  color: #fff !important;
  font-weight: 600;
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgba(255,255,255,.14);
}
.adm-nav-btn.active i { color: #fff; }
.adm-nav-btn.active:hover { background: linear-gradient(180deg, var(--primary-fill), var(--primary-strong)); }
.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;
}
/* One card: profile link (avatar · name › · role) + icon-only sign out */
.adm-user-card {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 6px 6px 9px;
  border-radius: 12px;
  border: 1px solid var(--sidebar-border);
  background: var(--sidebar-card);
  transition: background .15s, border-color .15s;
}
.adm-user-card:hover { border-color: rgba(var(--primary-rgb),.28); }
.adm-user-row {
  display: flex; align-items: center; gap: 10px;
  flex: 1; min-width: 0;
  padding: 3px 4px 3px 0;
  border-radius: 8px;
  text-decoration: none; color: inherit;
  transition: background .15s;
}
a.adm-user-row:hover { color: inherit; }
a.adm-user-row:hover .adm-user-name-text { color: var(--primary); }
a.adm-user-row:hover .adm-user-caret { color: var(--primary); transform: translateX(2px); }
.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-avatar { overflow: hidden; }
.adm-user-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.adm-user-info { flex: 1; min-width: 0; }
.adm-user-name {
  display: flex; align-items: center; gap: 5px; min-width: 0;
  font-size: 13px; font-weight: 600; color: var(--sidebar-ink);
}
.adm-user-name-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.adm-user-role { font-size: 11px; color: var(--sidebar-ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-user-caret { font-size: 11px; color: var(--sidebar-ink-faint); flex-shrink: 0; transition: color .15s, transform .15s; }
.adm-logout-form { display: contents; }
.adm-logout {
  width: 34px; height: 34px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 9px; background: none;
  color: var(--sidebar-ink-soft); font-size: 17px; cursor: pointer;
  transition: background .15s, color .15s;
}
.adm-logout:hover, .adm-logout:focus-visible { background: rgba(224,36,36,.1); color: var(--danger); }
/* Keyboard users need to see where they are before they sign out */
.adm-logout:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ── 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-card { flex-direction: column; gap: 6px; padding: 6px; border-color: transparent; background: none; }
  html.adm-rail .adm-sidebar .adm-user-row { justify-content: center; padding: 0; flex: 0 0 auto; }

  /* 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;
  /* A flex child is, by default, never narrower than its content. So a wide
     table, or the top bar's full row of buttons, used to WIDEN this column
     past the edge of the screen and the whole page scrolled sideways (121 of
     134 admin pages did at 1024px, 57 at 1280px). Letting it be as narrow as
     the space it is given makes .table-responsive scroll inside its card and
     lets the top-bar title shorten with "…", as both were meant to. */
  min-width: 0;
}
/* Same rule one level down: the page content is a flex child of the column. */
.admin-main > .admin-content { min-width: 0; }

/* ── 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);
  /* One line, always: a long page title (a course or user name) used to wrap
     and push the topbar's content out of its fixed height. It now shrinks
     with an ellipsis instead; the full text is still in the page heading. */
  flex: 0 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.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),.08);
  color: var(--primary);
}
.topbar-icon-btn:active { background: rgba(var(--primary-rgb),.14); }

/* Global search field */
.topbar-search-wrap { position: relative; margin-right: 8px; }
.topbar-search-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted); font-size: 13px; pointer-events: none;
}
.topbar-search {
  width: 252px; height: 36px;
  padding: 0 14px 0 34px;
  font: inherit; font-size: 13px;
  color: var(--text-primary);
  background: var(--surface-2);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  outline: none;
  transition: width var(--dur) var(--ease), border-color var(--dur-fast), box-shadow var(--dur-fast), background-color var(--dur-fast);
}
.topbar-search::placeholder { color: var(--text-muted); opacity: 1; }
.topbar-search:hover { border-color: var(--border-strong); }
.topbar-search:focus { width: 320px; background: var(--card-bg); border-color: var(--primary); box-shadow: var(--focus-ring); }
.topbar-search-drop {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  min-width: 320px; max-height: 360px; overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 9999;
}

/* Outlined pill links in the top bar (Learner panel, Shop) */
.topbar-pill {
  --pill-rgb: var(--primary-rgb);
  --pill-ink: var(--primary-dark);
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 13px;
  border-radius: 999px;
  border: 1px solid rgba(var(--pill-rgb),.4);
  background: rgba(var(--pill-rgb),.06);
  color: var(--pill-ink);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  text-decoration: none;
  transition: background-color var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.topbar-pill i { font-size: 12px; }
.topbar-pill:hover, .topbar-pill:focus-visible { background: rgba(var(--pill-rgb),.14); border-color: rgba(var(--pill-rgb),.7); color: var(--pill-ink); }
.topbar-pill--shop { --pill-rgb: 22,163,74; --pill-ink: #15803d; }
[data-theme="dark"] .topbar-pill--shop { --pill-ink: #4ade80; }

/* 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);
  overflow: hidden;
}
.topbar-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.topbar-avatar.has-photo { box-shadow: 0 0 0 1.5px rgba(var(--primary-rgb),.35); }

.topbar-username { font-size: 13px; font-weight: 600; line-height: 1.15; }
.topbar-user-meta { flex-direction: column; align-items: flex-start; min-width: 0; max-width: 160px; }
.topbar-userrole { font-size: 11px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.topbar-online { width: 7px; height: 7px; border-radius: 50%; background: #10b981; box-shadow: 0 0 0 2px rgba(16,185,129,.2); }
.topbar-user-caret { font-size: 11px; color: var(--text-muted); }
.topbar-user-btn .topbar-username { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; }

/* Tablets and small laptops (below 1200px): the top bar holds more than fits
   beside the sidebar. The signed-in name and role (still shown inside the
   menu that the avatar opens), and the page-speed / connection indicators,
   step aside, and the search box is a little shorter, so the user menu is not
   pushed off the right edge. */
@media (max-width: 1199.98px) {
  .admin-topbar .topbar-user-meta, .admin-topbar .topbar-user-caret { display: none !important; }
  .admin-topbar #admLoadTime, .admin-topbar #admNetWrap { display: none !important; }
  .admin-topbar #globalSearch { width: 170px !important; }
  .admin-topbar .topbar-divider { display: none; }
}

/* Phones: the topbar is a flex child of .admin-body, so without min-width:0 its
   intrinsic content (search box + user meta) widens the whole page and makes it
   scroll sideways. Collapse the search and the name/role text on small screens. */
@media (max-width: 767.98px) {
  .admin-main { min-width: 0; max-width: 100vw; }
  .admin-topbar { overflow: hidden; }
  .topbar-search-wrap { display: none; }
  .topbar-user-meta, .topbar-user-caret { display: none !important; }
  .topbar-divider { display: none; }
}

.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: var(--fs-sm); margin-bottom: 0; --bs-breadcrumb-divider-color: var(--border-strong); }
.breadcrumb-item a { color: var(--text-muted); text-decoration: none; transition: color var(--dur-fast); }
.breadcrumb-item a:hover { color: var(--primary); }
.breadcrumb-item.active { color: var(--text-primary); font-weight: 500; }

/* ── Content ────────────────────────────────────────────────── */
.admin-content {
  flex: 1;
  /* The 20px side gutter is a contract: full-bleed bars inside pages (course
     editor tabs) pull themselves out by exactly -20px. */
  padding: var(--space-6) var(--space-5);
  /* 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(4px); }
  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-xs);
  position: relative;
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.stat-card::before {                     /* brand hairline on top */
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--primary), transparent 85%);
  opacity: 0;
  transition: opacity var(--dur);
}
.stat-card:hover {
  box-shadow: var(--shadow-sm);
  border-color: rgba(var(--primary-rgb),.3);
}
.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: 20px; flex-shrink: 0;
  width: 46px; height: 46px;
  border-radius: var(--radius);
  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: 700; letter-spacing: -.02em; line-height: 1.2; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.stat-label { font-size: var(--fs-sm); 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-xs);
  background: var(--card-bg);
  overflow: hidden;
}

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

/* Bootstrap .card fallback — many admin pages use it directly */
.admin-content .card {
  --bs-card-inner-border-radius: calc(var(--radius) - 1px);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xs);
  background: var(--card-bg);
  color: var(--text-primary);
}
.admin-content .card-header {
  background: var(--card-bg);
  border-bottom: 1px solid var(--border-color);
  padding-top: 14px; padding-bottom: 14px;
  font-weight: 600;
}
.admin-content .card-footer {
  background: var(--surface-2);
  border-top: 1px solid var(--border-color);
}
.admin-content .card-title { font-weight: 600; letter-spacing: -.01em; }

/* ── Tables ─────────────────────────────────────────────────── */
.lms-table { font-size: 13.5px; margin-bottom: 0; font-variant-numeric: tabular-nums; }
.lms-table thead th {
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  border-bottom: 1px solid var(--border-color);
  padding: 10px 16px;
  position: sticky; top: 0;
  z-index: 1;
}
/* .lms-table implies Bootstrap's table-hover + align-middle: a list does not
   have to repeat those two classes to get the house behaviour. */
.lms-table { --bs-table-hover-bg: var(--row-hover); --bs-table-hover-color: var(--text-primary); }
.lms-table > :not(caption) > * > * { vertical-align: middle; }
.lms-table tbody tr { transition: background-color var(--dur-fast); }
.lms-table tbody tr:hover { background: var(--row-hover); }
.lms-table tbody tr:hover > * { --bs-table-bg-state: var(--row-hover); color: var(--text-primary); }
.lms-table tbody td {
  padding: 12px 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);
  font-variant-numeric: tabular-nums;
}
/* Plain Bootstrap tables get the same rhythm. Kept at Bootstrap's own
   specificity (the :where() parts count for nothing), so .lms-table and any
   page's own table rules still win. */
.table:where(.admin-content *) > :not(caption) > * > * { padding: .6rem .5rem; }
.table-sm:where(.admin-content *) > :not(caption) > * > * { padding: .35rem .25rem; }
.table:where(.admin-content *:not(.lms-table)) > :where(thead) > :where(tr) > th {
  color: var(--text-muted);
  font-size: min(var(--fs-sm), 1em); /* never larger than a compact table's own size */
  font-weight: 600;
  border-bottom-color: var(--border-color);
}

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

/* Buttons — every variant shares one height and type size. Borders stay
   (transparent on primary) so primary and outline buttons line up exactly. */
.btn {
  --bs-btn-font-size: .875rem; --bs-btn-padding-y: .469rem; --bs-btn-padding-x: .8rem;
  --bs-btn-focus-box-shadow: var(--focus-ring);
  font-weight: 600;
  transition: color var(--dur-fast), background-color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast);
}
.btn:active { transform: translateY(1px); }
.btn-sm, .btn-group-sm > .btn { --bs-btn-font-size: .8125rem; --bs-btn-padding-y: .3rem; --bs-btn-padding-x: .5rem; }
.btn-lg, .btn-group-lg > .btn { --bs-btn-font-size: 1rem; --bs-btn-padding-y: .6rem; --bs-btn-padding-x: 1.25rem; }

.btn-primary {
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
  --bs-btn-bg: var(--primary-fill); --bs-btn-disabled-bg: var(--primary-fill);
  --bs-btn-hover-bg: var(--primary-strong); --bs-btn-active-bg: var(--primary-strong);
  --bs-btn-border-color: transparent; --bs-btn-hover-border-color: transparent;
  --bs-btn-active-border-color: transparent; --bs-btn-disabled-border-color: transparent;
  background-image: linear-gradient(180deg, var(--primary-fill), var(--primary-strong));
  background-origin: border-box;
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgba(255,255,255,.14);
}
.btn-primary:is(:hover, :active, .active, .show) { background-image: none; }
.btn-primary:hover { box-shadow: var(--shadow-sm); }
.btn-outline-primary {
  --bs-btn-color: var(--primary); --bs-btn-hover-color: var(--primary); --bs-btn-disabled-color: var(--primary);
  --bs-btn-border-color: rgba(var(--primary-rgb),.45); --bs-btn-disabled-border-color: rgba(var(--primary-rgb),.45);
  --bs-btn-hover-bg: rgba(var(--primary-rgb),.07); --bs-btn-hover-border-color: var(--primary);
  --bs-btn-active-color: #fff; --bs-btn-active-bg: var(--primary-strong); --bs-btn-active-border-color: var(--primary-strong);
}
/* The neutral "default" button */
.btn-outline-secondary {
  --bs-btn-color: var(--text-primary); --bs-btn-hover-color: var(--text-primary); --bs-btn-active-color: var(--text-primary);
  --bs-btn-border-color: var(--border-strong); --bs-btn-hover-border-color: var(--border-strong); --bs-btn-active-border-color: var(--border-strong);
  --bs-btn-hover-bg: var(--surface-2); --bs-btn-active-bg: var(--border-color);
  --bs-btn-disabled-color: var(--text-muted); --bs-btn-disabled-border-color: var(--border-color);
}
.btn-light {
  --bs-btn-color: var(--text-primary); --bs-btn-hover-color: var(--text-primary); --bs-btn-active-color: var(--text-primary);
  --bs-btn-bg: var(--surface-2); --bs-btn-hover-bg: var(--border-color); --bs-btn-active-bg: var(--border-color);
  --bs-btn-border-color: var(--border-color); --bs-btn-hover-border-color: var(--border-strong); --bs-btn-active-border-color: var(--border-strong);
}

/* Forms — 14px fields at the button height, a field-strength outline and a
   brand focus ring. (Phones keep 16px fields: see the mobile type scale.) */
.form-control, .form-select {
  font-size: .875rem; padding-top: .469rem; padding-bottom: .469rem;
  border-radius: var(--radius-sm);
  border-color: var(--border-strong);
  background-color: var(--card-bg);
  color: var(--text-primary);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast), background-color var(--dur-fast);
}
.form-control { padding-left: .8rem; padding-right: .8rem; }
.form-select  { padding-left: .8rem; }
.form-control-sm, .form-select-sm { font-size: .8125rem; padding-top: .25rem; padding-bottom: .25rem; border-radius: var(--radius-xs); }
.form-control-sm { padding-left: .55rem; padding-right: .55rem; }
.form-select-sm  { padding-left: .55rem; }
.form-control-lg, .form-select-lg { font-size: 1rem; padding-top: .55rem; padding-bottom: .55rem; border-radius: var(--radius); }
.form-control-lg { padding-left: 1rem; padding-right: 1rem; }
.form-select-lg  { padding-left: 1rem; }
.form-control:hover:not(:focus):not(:disabled):not([readonly]),
.form-select:hover:not(:focus):not(:disabled) { border-color: color-mix(in srgb, var(--border-strong), var(--text-muted) 35%); }
.form-control:focus, .form-select:focus {
  border-color: var(--primary);
  box-shadow: var(--focus-ring);
  background-color: var(--card-bg);
  color: var(--text-primary);
}
.form-control::placeholder { color: var(--text-muted); opacity: .8; }
.form-control::file-selector-button { padding: .469rem .8rem; margin: -.469rem -.8rem; margin-inline-end: .8rem; background-color: var(--surface-2); color: var(--text-primary); font-weight: 500; }
.form-control-sm::file-selector-button { padding: .25rem .55rem; margin: -.25rem -.55rem; margin-inline-end: .55rem; }
.form-label { font-weight: 600; font-size: 13px; color: var(--text-primary); margin-bottom: .375rem; }
.form-text  { color: var(--text-muted); font-size: var(--fs-sm); }

.form-check-input { border-color: color-mix(in srgb, var(--text-muted) 60%, transparent); }
.form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.form-check-input:focus   { border-color: var(--primary); box-shadow: var(--focus-ring); }
.form-switch .form-check-input { cursor: pointer; }

.input-group-text {
  font-size: .875rem; padding: .469rem .8rem;
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
}
/* A focused field lights up its whole group, icon box included. */
.input-group { border-radius: var(--radius-sm); transition: box-shadow var(--dur-fast); }
.input-group:focus-within { box-shadow: var(--focus-ring); }
.input-group:focus-within > :is(.form-control, .form-select, .input-group-text) { border-color: var(--primary); box-shadow: none; }

/* Dropdown menus */
.dropdown-menu {
  --bs-dropdown-link-active-bg: rgba(var(--primary-rgb),.12);
  --bs-dropdown-link-active-color: var(--primary);
  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: var(--radius-xs);
  font-size: 13.5px;
  padding: .45rem .7rem;
  color: var(--text-primary);
  transition: background-color var(--dur-fast), color var(--dur-fast);
}
.dropdown-item:hover, .dropdown-item:focus { background-color: rgba(var(--primary-rgb),.07); color: var(--text-primary); }
.dropdown-item:active, .dropdown-item.active { background-color: rgba(var(--primary-rgb),.12); color: var(--primary); }
.dropdown-header { font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.dropdown-divider { border-color: var(--border-color); }

/* Modals */
.modal {
  --bs-modal-border-radius: var(--radius-lg); --bs-modal-inner-border-radius: calc(var(--radius-lg) - 1px);
  --bs-modal-header-padding: 1rem 1.25rem; --bs-modal-padding: 1.25rem; --bs-modal-footer-gap: .5rem;
}
.modal-content {
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-lg);
  background-color: var(--card-bg);
  color: var(--text-primary);
}
.modal-header { border-bottom-color: var(--border-color); }
.modal-title  { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.modal-footer { border-top-color: var(--border-color); background: var(--surface-2); }
.modal-backdrop { --bs-backdrop-bg: #0b1220; --bs-backdrop-opacity: .5; }

/* 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: var(--radius-xs) var(--radius-xs) 0 0;
  transition: color var(--dur-fast), border-color var(--dur-fast), background-color var(--dur-fast);
}
.nav-tabs .nav-link:hover { color: var(--text-primary); border-bottom-color: var(--border-strong); }
.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: var(--radius-sm); }
.nav-pills .nav-link:hover { color: var(--text-primary); background: var(--surface-2); }
.nav-pills .nav-link.active { color: #fff; background: var(--primary-strong); box-shadow: var(--shadow-xs); }

/* Pagination — separate, rounded page buttons */
.pagination {
  --bs-pagination-color: var(--text-primary); --bs-pagination-bg: var(--card-bg); --bs-pagination-border-color: var(--border-color);
  --bs-pagination-hover-color: var(--primary); --bs-pagination-hover-bg: rgba(var(--primary-rgb),.06); --bs-pagination-hover-border-color: rgba(var(--primary-rgb),.35);
  --bs-pagination-focus-color: var(--primary); --bs-pagination-focus-bg: var(--card-bg); --bs-pagination-focus-box-shadow: var(--focus-ring);
  --bs-pagination-active-bg: var(--primary-strong); --bs-pagination-active-border-color: var(--primary-strong);
  --bs-pagination-disabled-color: var(--text-muted); --bs-pagination-disabled-bg: var(--surface-2); --bs-pagination-disabled-border-color: var(--border-color);
  gap: 4px;
}
.page-link { border-radius: var(--bs-pagination-border-radius); min-width: 2.25em; text-align: center; font-weight: 500; font-variant-numeric: tabular-nums; }
.page-item:not(:first-child) .page-link { margin-left: 0; }

/* Badges & alerts */
/* One default badge size (.75rem = 12px at the 16px root). Views used to set
   font-size inline on most badges to get this; those inline sizes can now be
   dropped without a visual change. */
.badge { --bs-badge-font-size: .75rem; --bs-badge-font-weight: 600; --bs-badge-border-radius: var(--radius-xs); letter-spacing: .01em; }
.alert { --bs-alert-border-radius: var(--radius); }

/* Status badge (App\Helpers\StatusBadge::render): the same colour for the
   same status on every list. text-bg-* picks AA text for each colour. */
.lms-status { text-transform: capitalize; white-space: nowrap; }

/* Required-field marker: add class="form-label required" to the label, and
   `required` + aria-required="true" to the control. Nothing else is needed. */
.form-label.required::after { content: " *"; color: var(--danger); font-weight: 600; }

/* ── Text-colour contrast on the light background ────────────────────────
   Bootstrap's text-success (#198754 ok) / text-warning (#ffc107, 1.6:1) /
   text-info (#0dcaf0, 2:1) and our --text-muted #64748b (4.47:1) miss AA on
   #F5F8FD. These shades pass 4.5:1 on both the page and card backgrounds.
   Scoped to the light theme: dark mode keeps Bootstrap's dark-mode values,
   which already pass against the dark surfaces. */
html:not([data-theme="dark"]) .text-success { color: #067647 !important; }
html:not([data-theme="dark"]) .text-warning { color: #B54708 !important; }
html:not([data-theme="dark"]) .text-info    { color: #0B6E99 !important; }
html:not([data-theme="dark"]) .text-muted   { color: #5b6675 !important; }
html:not([data-theme="dark"]) .text-success-emphasis { color: #067647 !important; }
html:not([data-theme="dark"]) .text-warning-emphasis { color: #B54708 !important; }
html:not([data-theme="dark"]) .text-info-emphasis    { color: #0B6E99 !important; }

/* ── Skip link (first element in <body> of every layout) ─────────────────
   Hidden above the page, not off to the side, so an RTL page does not grow a
   scrollable 10,000px margin. Same markup/class as the learner layout. */
.lms-skip-link {
  position: absolute; top: 0; inset-inline-start: 0; z-index: 30000;
  transform: translateY(-110%);
  background: var(--primary-strong, var(--primary)); color: #fff; padding: 10px 18px;
  border-end-end-radius: 8px; font-weight: 600; font-size: 14px; text-decoration: none;
}
.lms-skip-link:focus { transform: none; color: #fff; outline: 3px solid var(--primary); outline-offset: 2px; }

/* ── List toolbar / pager (partials/list_toolbar.php, list_pager.php) ──── */
.list-toolbar .lt-date-label { font-size: var(--fs-sm); white-space: nowrap; }
.list-toolbar .lt-count { white-space: nowrap; }
.list-pager .lp-size-label { font-size: 12px; color: var(--bs-secondary-color); white-space: nowrap; }
.list-pager .lp-size {
  font-size: var(--fs-sm); padding: 2px 6px; border: 1px solid var(--bs-border-color);
  border-radius: 6px; background: var(--bs-body-bg); color: var(--bs-body-color);
}

/* ── Runtime toast of app.js (LMS.toast) on pages that load admin.css with
   app.js — the organisation portal. Same classes as app.css. */
.lms-toast-region { position: fixed; bottom: 24px; inset-inline-end: 20px; z-index: 99999; display: flex; flex-direction: column; gap: 8px; max-width: min(340px, calc(100vw - 32px)); pointer-events: none; }
.lms-toast { display: flex; align-items: center; gap: 10px; padding: 12px 18px; border-radius: var(--radius-sm); color: #fff; font-size: 13.5px; font-weight: 600; box-shadow: var(--shadow-md); pointer-events: auto; }
.lms-toast-success { background: #067647; }
.lms-toast-error   { background: var(--danger); }
.lms-toast-warning { background: #B54708; }
.lms-toast-info    { background: var(--primary-strong); }
.lms-toast.is-hiding { opacity: 0; transition: opacity .3s; }

/* ── Empty state (partials/empty_state.php) ──────────────────────────── */
.lms-empty { text-align: center; padding: 3rem 1rem; }
.lms-empty-icon { font-size: 3rem; line-height: 1; color: var(--border-color); }
.lms-empty-title { margin-top: 1rem; margin-bottom: .25rem; font-size: var(--fs-md); font-weight: 600; color: var(--text-muted); }
.lms-empty-hint { color: var(--text-muted); font-size: var(--fs-sm); margin-bottom: 0; }
.lms-empty-action { margin-top: .75rem; }

/* Progress — colour via the variable, so .bg-success etc. are not painted
   over by a brand gradient any more. */
.progress, .progress-stacked { --bs-progress-bg: var(--border-color); --bs-progress-bar-bg: var(--primary); --bs-progress-border-radius: 999px; }

/* 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"] .modal-backdrop { --bs-backdrop-opacity: .7; }
/* Bootstrap's "dark" variants are near-black: on a dark card they vanish
   (the license banner's Manage button did). Invert them instead. */
[data-theme="dark"] .btn-outline-dark {
  --bs-btn-color: var(--text-primary);
  --bs-btn-border-color: var(--border-strong);
  --bs-btn-hover-color: var(--content-bg);
  --bs-btn-hover-bg: var(--text-primary);
  --bs-btn-hover-border-color: var(--text-primary);
}
[data-theme="dark"] .btn-dark {
  --bs-btn-bg: #2a2a33;
  --bs-btn-border-color: var(--border-strong);
  --bs-btn-hover-bg: #34343f;
}
[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"] img { opacity: .94; }

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE — the sidebar collapses in ONE place: the
   "Admin sidebar mobile responsive" block further down, at
   991.98px (Bootstrap lg), the same breakpoint admin.js and the
   layout's pre-paint script use (window.innerWidth >= 992).
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  .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 {
  display: block; font-size: 13px; font-weight: 600; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.adm-qs-sub {
  display: block; 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); }
.adm-qs-msg em { font-style: normal; font-weight: 600; color: var(--text-primary); }
.adm-qs-group-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.adm-qs-group-row > span > i { font-size: 11px; margin-inline-end: 2px; }
.adm-qs-more, .adm-qs-clear {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--primary); text-decoration: none; background: none; border: 0; padding: 2px 6px; border-radius: 6px;
}
.adm-qs-more:hover, .adm-qs-clear:hover, .adm-qs-more.is-cursor { background: var(--row-hover); }
.adm-qs-more.is-cursor { outline: 2px solid var(--primary); outline-offset: -2px; }
.adm-qs-foot-n { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 10px; background: var(--primary); color: #fff; font-size: 11px; line-height: 18px; }
.adm-qs-hint {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
  padding: 7px 14px; border-top: 1px solid var(--border-color);
  font-size: 11px; color: var(--text-muted);
}
.adm-qs-hint kbd {
  font-family: inherit; font-size: 10px; padding: 1px 5px; margin-inline-end: 3px;
  border: 1px solid var(--border-color); border-bottom-width: 2px; border-radius: 4px;
  background: var(--surface-2); color: var(--text-primary);
}
@media (max-width: 600px) { .adm-qs-hint { display: none; } }

@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 ──────────────────────────────────────
   The single sidebar breakpoint: < 992px = off-canvas drawer (admin.js
   DESKTOP = 992, layouts/admin.php pre-paint script >= 992). */
@media (max-width: 991.98px) {
  .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}

/* ── User chip (App\Helpers\UserChip / LMS.userChip) ─────────────────────────
   A person wherever their name is printed: profile photo, or the default
   person icon when they have none, then the name. For an administrator who
   may manage the account the chip is a link to Users → Edit. The icon sits
   under the photo, so a photo that fails to load simply reveals it. */
.user-chip{display:inline-flex;align-items:center;gap:8px;min-width:0;max-width:100%;color:inherit;text-decoration:none;vertical-align:middle;text-align:left}
.user-chip-ava{--uc:26px;position:relative;width:var(--uc);height:var(--uc);flex:0 0 var(--uc);border-radius:50%;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;background:rgba(var(--primary-rgb),.10);color:var(--primary);font-size:calc(var(--uc) * .6);line-height:1}
.user-chip-ava > i{display:block;line-height:1}
.user-chip-ava > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:var(--card-bg,#fff)}
.user-chip-body{display:flex;flex-direction:column;min-width:0;line-height:1.3}
.user-chip-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.user-chip-sub{font-size:12px;font-weight:400;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.user-chip-only{gap:0}
a.user-chip{cursor:pointer;border-radius:6px}
.user-chip-link{color:inherit;text-decoration:none}
.user-chip-link:hover,.user-chip-link:focus-visible{color:var(--primary);text-decoration:underline}
a.user-chip:hover .user-chip-name,a.user-chip:focus-visible .user-chip-name{color:var(--primary);text-decoration:underline}
a.user-chip:hover .user-chip-ava,a.user-chip:focus-visible .user-chip-ava{box-shadow:0 0 0 2px rgba(var(--primary-rgb),.28)}
a.user-chip:focus-visible{outline:2px solid rgba(var(--primary-rgb),.55);outline-offset:2px}
[data-theme="dark"] .user-chip-ava{background:rgba(var(--primary-rgb),.18)}
@media print{.user-chip-ava{display:none}}

.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}

/* ── List toolbar: the search + filter bar above a paged list ──────────────
   (partials/list_toolbar.php). One control height for search, menus, dates
   and buttons; fields wrap onto new lines on a narrow screen. */
.list-toolbar{--lt-h:34px}
.list-toolbar .input-group>.form-control,.list-toolbar .input-group>.input-group-text,.list-toolbar .form-select,.list-toolbar .lt-date .form-control{height:var(--lt-h);font-size:13px}
.list-toolbar .form-select{padding-top:0;padding-bottom:0}
.list-toolbar .btn{height:var(--lt-h);display:inline-flex;align-items:center;white-space:nowrap}
.list-toolbar .lt-search{flex:2 1 240px;min-width:180px;max-width:460px}
.list-toolbar .lt-field{flex:1 1 170px;min-width:140px;max-width:260px}
.list-toolbar .lt-date .form-control{width:auto;padding-top:0;padding-bottom:0}
.list-toolbar input[type=search]::-webkit-search-cancel-button{cursor:pointer}
@media (max-width:575.98px){
  .list-toolbar .lt-search,.list-toolbar .lt-field{flex-basis:100%;max-width:none}
}
