/* =============================================================
   QuizX Institution Admin Panel — Premium Design System
   Teal/Emerald accents · Glassmorphism · Micro‑animations
   ============================================================= */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');

/* ── CSS Variables (dark mode = default) ── */
:root {
  color-scheme: dark;
  --ad-bg-primary:      #080d18;
  --ad-bg-secondary:    #0f1623;
  --ad-bg-card:         rgba(15, 22, 35, 0.82);
  --ad-bg-card-hover:   rgba(24, 34, 52, 0.92);
  --ad-bg-input:        rgba(24, 34, 52, 0.6);
  --ad-bg-sidebar:      #0a1020;
  --ad-border:          rgba(45, 65, 95, 0.55);
  --ad-border-light:    rgba(60, 85, 120, 0.3);

  --ad-text-primary:    #f0f4fd;
  --ad-text-secondary:  #8fa3c0;
  --ad-text-muted:      #5a7090;
  --ad-text-heading:    #d8e4f5;

  /* Teal/Emerald accent palette */
  --ad-accent-1:        #06b6d4;
  --ad-accent-2:        #10b981;
  --ad-accent-3:        #34d399;
  --ad-grad-primary:    linear-gradient(135deg, #06b6d4 0%, #10b981 60%, #34d399 100%);
  --ad-grad-success:    linear-gradient(135deg, #10b981, #34d399);
  --ad-grad-warning:    linear-gradient(135deg, #f59e0b, #fbbf24);
  --ad-grad-danger:     linear-gradient(135deg, #ef4444, #f87171);
  --ad-grad-info:       linear-gradient(135deg, #3b82f6, #60a5fa);
  --ad-grad-purple:     linear-gradient(135deg, #8b5cf6, #a78bfa);

  --ad-shadow-sm:  0 1px 4px rgba(0,0,0,0.35);
  --ad-shadow-md:  0 4px 16px rgba(0,0,0,0.45);
  --ad-shadow-lg:  0 12px 40px rgba(0,0,0,0.55);
  --ad-shadow-glow: 0 0 24px rgba(6,182,212,0.14);

  --ad-sidebar-width:     262px;
  --ad-header-height:     64px;
  --ad-radius:            12px;
  --ad-radius-sm:         8px;
  --ad-radius-lg:         18px;
  --ad-transition:        all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  --ad-transition-fast:   all 0.15s ease;
}

/* ── Light theme overrides ── */
[data-theme="light"] {
  color-scheme: light;
  --ad-bg-primary:      #f0f4fb;
  --ad-bg-secondary:    #ffffff;
  --ad-bg-card:         rgba(255,255,255,0.92);
  --ad-bg-card-hover:   rgba(246,249,255,1);
  --ad-bg-input:        rgba(240,244,251,0.9);
  --ad-bg-sidebar:      #ffffff;
  --ad-border:          rgba(190,210,235,0.65);
  --ad-border-light:    rgba(210,225,245,0.5);
  --ad-text-primary:    #0c1a2e;
  --ad-text-secondary:  #4a6080;
  --ad-text-muted:      #8fa3c0;
  --ad-text-heading:    #1a2d45;
  --ad-shadow-sm:  0 1px 3px rgba(0,0,0,0.08);
  --ad-shadow-md:  0 4px 14px rgba(0,0,0,0.10);
  --ad-shadow-lg:  0 10px 36px rgba(0,0,0,0.12);
  --ad-shadow-glow: 0 0 20px rgba(6,182,212,0.08);
}

/* ── Bootstrap Overrides for Dark Mode ── */
.bg-light { background-color: var(--ad-bg-secondary) !important; }
.bg-white { background-color: var(--ad-bg-card) !important; }
.card { 
  background-color: var(--ad-bg-card) !important; 
  border-color: var(--ad-border) !important; 
  color: var(--ad-text-primary) !important; 
}
.modal-content {
  background-color: var(--ad-bg-secondary) !important;
  border-color: var(--ad-border) !important;
}
.modal-header, .modal-footer {
  border-color: var(--ad-border) !important;
}
.form-control, .form-select {
  background-color: var(--ad-bg-input) !important;
  border-color: var(--ad-border-light) !important;
  color: var(--ad-text-primary) !important;
}
/* Cr1 consistency matrices (mission-PEO, PEO-PO): a 48px select cannot carry
   Bootstrap's caret AND a centred digit. The panel-wide `.form-control, .form-select`
   rule above replaces Bootstrap's ASYMMETRIC select padding (which reserves ~2.25rem
   on the right for the caret) with a symmetric 1rem, so the caret is painted over the
   value. In a wide, left-aligned select nobody notices; in a 48px matrix cell it lands
   directly on the digit and "3" reads as a squiggle. Compact asymmetric padding plus a
   smaller, inset caret gives the digit its own space. Geometry only, no colours, so it
   is unaffected by the panel's light/dark handling. */
.qx-level-select {
  padding: 0.3rem 1.1rem 0.3rem 0.4rem !important;
  background-position: right 0.3rem center !important;
  background-size: 9px 7px !important;
  text-align: center;
  text-align-last: center;
}

.form-control:focus, .form-select:focus {
  background-color: var(--ad-bg-secondary) !important;
  border-color: var(--ad-accent-1) !important;
  color: var(--ad-text-primary) !important;
}
/* ── Native date/time input icon theming ── */
input[type="date"],
input[type="datetime-local"],
input[type="time"] {
  color-scheme: dark;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  filter: invert(0.7) sepia(0.1) hue-rotate(180deg);
  cursor: pointer;
  opacity: 0.8;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}
[data-theme="light"] input[type="date"],
[data-theme="light"] input[type="datetime-local"],
[data-theme="light"] input[type="time"] {
  color-scheme: light;
}
[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="light"] input[type="datetime-local"]::-webkit-calendar-picker-indicator,
[data-theme="light"] input[type="time"]::-webkit-calendar-picker-indicator {
  filter: none;
  opacity: 0.7;
}
[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator:hover,
[data-theme="light"] input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover,
[data-theme="light"] input[type="time"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}
/* Suppress Bootstrap validation checkmark icon to prevent text overlap */
.was-validated .form-control.no-validation-icon:valid,
.was-validated .form-control.no-validation-icon:invalid {
  background-image: none !important;
  padding-right: 0.75rem !important;
}
.list-group-item {
  background-color: var(--ad-bg-card) !important;
  border-color: var(--ad-border) !important;
  color: var(--ad-text-primary) !important;
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--ad-bg-primary);
  color: var(--ad-text-primary);
  line-height: 1.6;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.4s ease, color 0.4s ease;
  overflow-x: hidden;
}
a { color: var(--ad-accent-1); text-decoration: none; transition: var(--ad-transition-fast); }
a:hover { color: var(--ad-accent-3); }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--ad-border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--ad-text-muted); }

/* ── Keyframes ── */
@keyframes ad-fade-in  { from { opacity: 0 } to { opacity: 1 } }
@keyframes ad-slide-up { from { opacity: 0; transform: translateY(22px) } to { opacity: 1; transform: translateY(0) } }
@keyframes ad-scale-in { from { opacity: 0; transform: scale(.93) } to { opacity: 1; transform: scale(1) } }
@keyframes ad-shimmer  { 0% { background-position: 200% 0 } 100% { background-position: -200% 0 } }
@keyframes ad-pulse-dot { 0%,100% { transform: scale(1); opacity: 1 } 50% { transform: scale(1.25); opacity: .7 } }

.ad-fade-in  { animation: ad-fade-in  0.5s ease-out forwards; }
.ad-slide-up { animation: ad-slide-up 0.6s cubic-bezier(0.16,1,0.3,1) forwards; opacity: 0; }
.ad-scale-in { animation: ad-scale-in 0.45s cubic-bezier(0.34,1.56,0.64,1) forwards; opacity: 0; }
.ad-stagger-1 { animation-delay: 80ms; }
.ad-stagger-2 { animation-delay: 160ms; }
.ad-stagger-3 { animation-delay: 240ms; }
.ad-stagger-4 { animation-delay: 320ms; }
.ad-stagger-5 { animation-delay: 400ms; }

/* ── Login Page ── */
.ad-login-wrapper {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background: var(--ad-bg-primary);
  position: relative; overflow: hidden;
}
.ad-login-wrapper::before {
  content: '';
  position: absolute; width: 640px; height: 640px;
  background: radial-gradient(circle, rgba(6,182,212,0.13) 0%, transparent 68%);
  top: -180px; right: -180px; pointer-events: none;
}
.ad-login-wrapper::after {
  content: '';
  position: absolute; width: 520px; height: 520px;
  background: radial-gradient(circle, rgba(16,185,129,0.09) 0%, transparent 68%);
  bottom: -200px; left: -120px; pointer-events: none;
}
.ad-login-card {
  background: var(--ad-bg-card);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--ad-border);
  border-radius: var(--ad-radius-lg);
  padding: 48px 42px;
  width: 100%; max-width: 448px;
  box-shadow: var(--ad-shadow-lg);
  position: relative; z-index: 1;
  animation: ad-scale-in 0.5s cubic-bezier(0.34,1.56,0.64,1);
}
.ad-login-logo {
  font-size: 26px; font-weight: 800;
  background: var(--ad-grad-primary);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text; text-align: center; margin-bottom: 6px;
}
.ad-login-subtitle {
  text-align: center; color: var(--ad-text-secondary);
  font-size: 13.5px; margin-bottom: 34px;
}
.ad-badge-inst {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(6,182,212,0.10);
  color: var(--ad-accent-1);
  font-size: 11px; font-weight: 600;
  padding: 4px 12px; border-radius: 20px;
  border: 1px solid rgba(6,182,212,0.22);
  margin-bottom: 28px; text-transform: uppercase; letter-spacing: 0.5px;
}

/* ── Form Controls ── */
.ad-form-group { margin-bottom: 20px; }
.ad-form-group label {
  display: block; font-size: 13px; font-weight: 500;
  color: var(--ad-text-secondary); margin-bottom: 6px;
}
.ad-form-control, .ad-form-select {
  width: 100%;
  padding: 13px 16px;
  background: var(--ad-bg-input);
  border: 1px solid var(--ad-border-light);
  border-radius: var(--ad-radius-sm);
  color: var(--ad-text-primary);
  font-family: inherit; font-size: 14px;
  outline: none;
  transition: all 0.25s cubic-bezier(0.2,0.8,0.2,1);
}
.ad-form-control:hover, .ad-form-select:hover {
  background: var(--ad-bg-card-hover);
  border-color: rgba(6,182,212,0.38);
}
.ad-form-control:focus, .ad-form-select:focus {
  border-color: var(--ad-accent-1);
  box-shadow: 0 0 0 3px rgba(6,182,212,0.18);
  background: var(--ad-bg-secondary);
}
.ad-form-control::placeholder { color: var(--ad-text-muted); }
.ad-input-group { display: flex; align-items: stretch; }
.ad-input-prefix {
  display: flex; align-items: center; padding: 0 14px;
  background: var(--ad-bg-card-hover);
  border: 1px solid var(--ad-border-light); border-right: none;
  border-radius: var(--ad-radius-sm) 0 0 var(--ad-radius-sm);
  color: var(--ad-text-muted); font-size: 14px; font-weight: 500;
}
.ad-input-group .ad-form-control { border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0; }
select.ad-form-control, select.ad-form-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238fa3c0' stroke-width='2'%3E%3Cpolyline points='6,9 12,15 18,9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
  padding-right: 40px;
}
[data-theme="light"] select.ad-form-control,
[data-theme="light"] select.ad-form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%234a6080' stroke-width='2'%3E%3Cpolyline points='6,9 12,15 18,9'%3E%3C/polyline%3E%3C/svg%3E");
}

/* ── Buttons ── */
.ad-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 22px;
  border: none; border-radius: var(--ad-radius-sm);
  font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; transition: var(--ad-transition); outline: none;
  text-decoration: none; line-height: 1; white-space: nowrap;
}
.ad-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.ad-btn-primary {
  background: var(--ad-grad-primary); color: #fff;
  box-shadow: 0 4px 14px rgba(6,182,212,0.28);
}
.ad-btn-primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 6px 22px rgba(6,182,212,0.40);
}
.ad-btn-outline {
  background: transparent; color: var(--ad-text-secondary);
  border: 1px solid var(--ad-border);
}
.ad-btn-outline:hover:not(:disabled) {
  background: var(--ad-bg-card-hover); color: var(--ad-text-primary);
  border-color: var(--ad-accent-1);
}
.ad-btn-ghost {
  background: transparent; color: var(--ad-text-secondary);
  padding: 7px 11px;
}
.ad-btn-ghost:hover { color: var(--ad-text-primary); background: var(--ad-bg-input); }
[data-theme="light"] .ad-btn-ghost { color: #4a6080; } /* explicitly darker for light mode */
[data-theme="light"] .ad-btn-ghost:hover { color: #0c1a2e; }
.ad-btn-danger { background: var(--ad-grad-danger); color: #fff; }
.ad-btn-success { background: var(--ad-grad-success); color: #fff; }
.ad-btn-sm { padding: 7px 13px; font-size: 12px; }
.ad-btn-lg { padding: 14px 28px; font-size: 15px; }
.ad-btn-full { width: 100%; }
.ad-btn-icon { width: 36px; height: 36px; padding: 0; border-radius: var(--ad-radius-sm); }

/* ── Sidebar ── */
.ad-layout { display: flex; min-height: 100vh; }

.ad-sidebar {
  width: var(--ad-sidebar-width);
  background: var(--ad-bg-sidebar);
  border-right: 1px solid var(--ad-border);
  display: flex; flex-direction: column;
  position: fixed; top: 0; left: 0; bottom: 0;
  z-index: 200;
  transition: var(--ad-transition);
  overflow-y: auto; overflow-x: hidden;
}
.ad-sidebar-header {
  padding: 22px 20px 16px;
  border-bottom: 1px solid var(--ad-border-light);
}
.ad-sidebar-brand {
  font-size: 20px; font-weight: 800;
  background: var(--ad-grad-primary);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text; white-space: nowrap;
}
.ad-sidebar-brand-sub {
  font-size: 10.5px; color: var(--ad-text-muted);
  text-transform: uppercase; letter-spacing: 1.1px; margin-top: 2px;
}
.ad-sidebar-nav { flex: 1; padding: 14px 12px; }
.ad-nav-section { margin-bottom: 22px; }
.ad-nav-section-title {
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.3px;
  color: var(--ad-text-muted); padding: 0 12px; margin-bottom: 6px;
}
.ad-nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  border-radius: var(--ad-radius-sm);
  color: var(--ad-text-secondary);
  font-size: 13px; font-weight: 500;
  cursor: pointer; transition: var(--ad-transition-fast);
  border: none; background: none; width: 100%; text-align: left;
  position: relative;
}
.ad-nav-item:hover {
  background: var(--ad-bg-card-hover);
  color: var(--ad-text-primary);
  transform: translateX(2px);
}
.ad-nav-item.active {
  background: rgba(6,182,212,0.1);
  color: var(--ad-accent-3);
  font-weight: 600;
}
.ad-nav-item.active::before {
  content: '';
  position: absolute; left: 0; top: 20%; bottom: 20%;
  width: 3px; border-radius: 0 3px 3px 0;
  background: var(--ad-grad-primary);
}
.ad-nav-icon {
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; flex-shrink: 0;
}
.ad-sidebar-footer {
  padding: 16px 20px;
  border-top: 1px solid var(--ad-border-light);
}
.ad-user-info { display: flex; align-items: center; gap: 10px; }
.ad-user-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--ad-grad-primary);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 14px; flex-shrink: 0;
}
.ad-user-name {
  font-size: 13px; font-weight: 600; color: var(--ad-text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ad-user-role { font-size: 11px; color: var(--ad-text-muted); }

/* ── Main layout ── */
.ad-main { flex: 1; margin-left: var(--ad-sidebar-width); transition: var(--ad-transition); }

.ad-header {
  height: var(--ad-header-height);
  background: var(--ad-bg-secondary);
  border-bottom: 1px solid var(--ad-border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 28px;
  position: sticky; top: 0; z-index: 100;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.ad-header-left { display: flex; align-items: center; gap: 14px; }
.ad-header-title { font-size: 17px; font-weight: 700; color: var(--ad-text-heading); }
.ad-header-right { display: flex; align-items: center; gap: 12px; }
.ad-menu-toggle {
  display: none; background: none; border: none;
  color: var(--ad-text-secondary); font-size: 22px; cursor: pointer; padding: 6px;
}

.ad-content { padding: 28px; max-width: 1440px; }

/* ── Cards ── */
.ad-card {
  background: var(--ad-bg-card);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--ad-border);
  border-radius: var(--ad-radius);
  padding: 24px;
  transition: var(--ad-transition);
}
.ad-card:hover { border-color: var(--ad-border-light); box-shadow: var(--ad-shadow-glow); }
.ad-card-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 20px;
}
.ad-card-title { font-size: 15px; font-weight: 700; color: var(--ad-text-heading); }

/* ── KPI cards ── */
.ad-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 16px; margin-bottom: 28px;
}
.ad-kpi-card {
  background: var(--ad-bg-card);
  border: 1px solid var(--ad-border);
  border-radius: var(--ad-radius);
  padding: 20px 22px;
  position: relative; overflow: hidden;
  transition: var(--ad-transition);
}
.ad-kpi-card:hover { transform: translateY(-2px); box-shadow: var(--ad-shadow-md); }
.ad-kpi-card::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  border-radius: var(--ad-radius) var(--ad-radius) 0 0;
}
.ad-kpi-card.kpi-teal::before  { background: var(--ad-grad-primary); }
.ad-kpi-card.kpi-green::before { background: var(--ad-grad-success); }
.ad-kpi-card.kpi-amber::before { background: var(--ad-grad-warning); }
.ad-kpi-card.kpi-red::before   { background: var(--ad-grad-danger); }
.ad-kpi-card.kpi-blue::before  { background: var(--ad-grad-info); }
.ad-kpi-card.kpi-purple::before { background: var(--ad-grad-purple); }
.ad-kpi-label {
  font-size: 11.5px; font-weight: 500;
  color: var(--ad-text-muted); text-transform: uppercase;
  letter-spacing: 0.5px; margin-bottom: 8px;
}
.ad-kpi-value {
  font-size: 28px; font-weight: 800;
  color: var(--ad-text-primary); line-height: 1.1;
}
.ad-kpi-sub { font-size: 12px; color: var(--ad-text-muted); margin-top: 6px; }
.ad-kpi-icon {
  position: absolute; top: 18px; right: 20px;
  font-size: 22px; opacity: 0.12; color: var(--ad-text-primary);
}

/* ── Tables ── */
.ad-table-wrapper {
  overflow-x: auto; border-radius: var(--ad-radius);
  border: 1px solid var(--ad-border);
}
.ad-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ad-table th {
  text-align: left; padding: 12px 16px;
  font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--ad-text-muted);
  background: var(--ad-bg-secondary);
  border-bottom: 1px solid var(--ad-border);
  white-space: nowrap; user-select: none;
}
.ad-table td {
  padding: 12px 16px; border-bottom: 1px solid var(--ad-border-light);
  color: var(--ad-text-secondary); vertical-align: middle;
}
/* An editable cell cannot afford 16px a side. A .form-control is width:100%, so it
   adds nothing to the column's intrinsic width — the column is exactly as wide as its
   <th> asks for, and the input gets whatever the padding leaves. At 16px a side a
   72px column left 6px of text area, so the value rendered but was never visible
   (OBE teaching plan: Ord and Lect.). The input draws its own inset; halve the
   cell's. Read-only cells keep the roomier padding. */
.ad-table td:has(.form-control),
.ad-table td:has(.form-select) { padding-left: 8px; padding-right: 8px; }
/* PANEL-11: a wide table in a .table-responsive scroller put its actions column off-screen even at
   1440px; the last column now stays pinned to the right edge while the rest scrolls under it. The
   cell needs an OPAQUE background (the card's is translucent) or the scrolled text shows through,
   and it must be background-color, never the `background` shorthand. Row hover is a tint layered
   over that opaque base so the pinned cell still follows its row. */
.table-responsive > .ad-table th:last-child,
.table-responsive > .ad-table td:last-child {
  position: sticky; right: 0; z-index: 1;
  background-color: var(--ad-bg-secondary);
  box-shadow: inset 1px 0 0 var(--ad-border-light);
}
.table-responsive > .ad-table tr:hover td:last-child {
  background-image: linear-gradient(var(--ad-bg-card-hover), var(--ad-bg-card-hover));
}
/* Each pinned cell is its own stacking context (sticky + z-index), so an open "More" menu in one
   row would slide UNDER the pinned cells of the rows below it; lift the cell that holds it. */
.table-responsive > .ad-table td:last-child:has(.dropdown-menu.show) { z-index: 3; }
/* PANEL-21: at ~900px a button label wrapped one word per line inside a squeezed cell. */
.ad-table .btn { white-space: nowrap; }

/* ── qx-picker (modules/qx-picker.js) ──
   Two panel-wide traps make this block necessary rather than optional:
   1. `data-bs-theme` is never set anywhere, so every Bootstrap 5.3 theme variable
      and *-subtle/-emphasis utility is frozen at its LIGHT value in BOTH themes.
      So we style from --ad-* only, dark as the unqualified default with a
      [data-theme="light"] override. (<body> used to hard-code data-theme="dark", which
      made [data-theme="dark"] selectors match in both themes; it no longer does.)
   2. .list-group-item colours are forced with !important further up this file,
      which also kills Bootstrap's :hover/:active feedback. The keyboard-active
      row therefore needs its own !important to be visible at all — without it
      ArrowDown moves a selection the user cannot see. */
.qx-picker-results .qx-picker-opt {
  background: var(--ad-bg-card) !important;
  color: var(--ad-text-primary) !important;
  border-color: var(--ad-border-light) !important;
}
.qx-picker-results .qx-picker-opt:hover,
.qx-picker-results .qx-picker-active {
  background: var(--ad-bg-card-hover) !important;
  color: var(--ad-text-primary) !important;
}
/* The active row must be identifiable without colour alone (WCAG 1.4.1). */
.qx-picker-results .qx-picker-active { box-shadow: inset 3px 0 0 0 var(--ad-accent, #0dcaf0); }
.qx-picker-results .qx-picker-opt:focus-visible { outline: 2px solid var(--ad-accent, #0dcaf0); outline-offset: -2px; }
.qx-picker-badge { background: var(--ad-bg-secondary); color: var(--ad-text-muted); font-size: 10px; }
[data-theme="light"] .qx-picker-results .qx-picker-opt { background: #fff !important; }
.ad-table tr:hover td { background: var(--ad-bg-card-hover); color: var(--ad-text-primary); }
.ad-table tr:last-child td { border-bottom: none; }

/* ── Badges ── */
.ad-badge {
  display: inline-flex; align-items: center;
  padding: 3px 10px; border-radius: 20px;
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.ad-badge-success { background: rgba(16,185,129,0.12); color: #34d399; }
.ad-badge-warning { background: rgba(245,158,11,0.12); color: #fbbf24; }
.ad-badge-danger  { background: rgba(239,68,68,0.12);  color: #f87171; }
.ad-badge-info    { background: rgba(59,130,246,0.12); color: #60a5fa; }
.ad-badge-teal    { background: rgba(6,182,212,0.12);  color: #22d3ee; }
.ad-badge-muted   { background: rgba(100,116,139,.1);  color: #94a3b8; }

/* ── Overview panels (live / completed) ── */
.ad-panels-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 991px) { .ad-panels-row { grid-template-columns: 1fr; } }

.ad-panel {
  background: var(--ad-bg-card);
  border: 1px solid var(--ad-border);
  border-radius: 18px; overflow: hidden; position: relative;
  transition: transform 0.32s cubic-bezier(0.2,0.8,0.2,1), box-shadow 0.32s ease;
}
.ad-panel::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0;
  height: 4px; border-radius: 18px 18px 0 0;
}
.ad-panel:hover { transform: translateY(-3px); box-shadow: var(--ad-shadow-glow); }
.ad-panel--live::before   { background: var(--ad-grad-primary); }
.ad-panel--live:hover     { border-color: rgba(6,182,212,0.32); }
.ad-panel--done::before   { background: var(--ad-grad-purple); }
.ad-panel--done:hover     { border-color: rgba(139,92,246,0.32); }

.ad-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.2rem 1.5rem;
  border-bottom: 1px solid var(--ad-border-light);
}
.ad-panel-title {
  display: flex; align-items: center; gap: 0.6rem;
  font-weight: 700; font-size: 0.94rem; margin: 0;
}
.ad-panel-icon {
  width: 34px; height: 34px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.ad-panel--live .ad-panel-icon  { background: rgba(6,182,212,0.14); color: var(--ad-accent-1); }
.ad-panel--done .ad-panel-icon  { background: rgba(139,92,246,0.14); color: #a78bfa; }
.ad-panel-count {
  font-size: 0.78rem; font-weight: 700;
  padding: 3px 10px; border-radius: 20px;
}
.ad-panel--live .ad-panel-count { background: rgba(6,182,212,0.12); color: var(--ad-accent-1); }
.ad-panel--done .ad-panel-count { background: rgba(139,92,246,0.12); color: #a78bfa; }
.ad-panel-body { padding: 1rem 1.5rem 1.5rem; max-height: 500px; overflow-y: auto; }

/* quiz item row */
.ad-quiz-item {
  padding: 0.82rem 1rem; border-radius: 10px;
  border: 1px solid var(--ad-border); background: var(--ad-bg-card);
  transition: all 0.18s ease; margin-bottom: 0.45rem;
}
.ad-quiz-item:last-child { margin-bottom: 0; }
.ad-quiz-item:hover {
  background: var(--ad-bg-card-hover);
  border-color: var(--ad-accent-1);
  transform: translateX(3px);
}

/* status badges */
.ad-status[data-status="ACTIVE"]    { background: rgba(16,185,129,0.12); color: #34d399; }
.ad-status[data-status="UPCOMING"]  { background: rgba(59,130,246,0.12); color: #60a5fa; }
.ad-status[data-status="COMPLETED"] { background: rgba(100,116,139,0.12); color: #94a3b8; }
.ad-status[data-status="DRAFT"]     { background: rgba(245,158,11,0.12); color: #fbbf24; }
.ad-status {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; padding: 3px 9px; border-radius: 6px;
  display: inline-flex; align-items: center;
}

/* empty state */
.ad-empty-state {
  text-align: center; padding: 2rem 1rem;
  color: var(--ad-text-muted); font-size: 0.88rem;
}
.ad-empty-state i { font-size: 2rem; display: block; margin-bottom: 0.5rem; opacity: 0.35; }

/* ── Pagination bar ── */
.ad-pagination-bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 0.75rem;
  margin-top: 1.2rem; padding: 0.8rem 1.2rem;
  background: var(--ad-bg-card);
  border: 1px solid var(--ad-border); border-radius: 12px;
}
.ad-pagination-controls { display: flex; align-items: center; gap: 0.35rem; }
.ad-pg-btn {
  width: 34px; height: 34px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; font-size: 0.84rem;
  background: transparent; border: 1px solid var(--ad-border);
  color: var(--ad-text-secondary); cursor: pointer;
  transition: all 0.18s ease;
}
.ad-pg-btn:hover:not(:disabled) { background: var(--ad-bg-card-hover); color: var(--ad-accent-1); border-color: var(--ad-accent-1); }
.ad-pg-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.ad-page-indicator {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 58px; padding: 3px 10px; border-radius: 9px;
  background: var(--ad-bg-input); color: var(--ad-text-primary);
  font-size: 0.79rem; font-weight: 700; text-align: center;
}

/* ── Skeleton loaders ── */
.ad-skeleton { border-radius: 8px; overflow: hidden; }
.ad-skeleton-line {
  height: 14px; border-radius: 6px; margin-bottom: 10px;
  background: linear-gradient(90deg, var(--ad-bg-card-hover) 25%, var(--ad-border) 50%, var(--ad-bg-card-hover) 75%);
  background-size: 200% 100%;
  animation: ad-shimmer 2s infinite linear;
}
.ad-skeleton-line.w-75 { width: 75%; }
.ad-skeleton-line.w-50 { width: 50%; }
.ad-skeleton-line.w-33 { width: 33%; }

/* ── Modal overrides ── */
.modal-content {
  background: var(--ad-bg-secondary) !important;
  border: 1px solid var(--ad-border) !important;
  border-radius: 18px !important;
  color: var(--ad-text-primary) !important;
}
.modal-header { border-bottom: 1px solid var(--ad-border-light) !important; }
.modal-footer { border-top: 1px solid var(--ad-border-light) !important; }

/* ── Bootstrap form control overrides ── */
.form-control, .form-select {
  background-color: var(--ad-bg-input) !important;
  color: var(--ad-text-primary) !important;
  border-color: var(--ad-border-light) !important;
  border-radius: 10px !important;
  padding: 0.7rem 1rem !important;
  min-height: 46px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-control:focus, .form-select:focus {
  border-color: var(--ad-accent-1) !important;
  box-shadow: 0 0 0 3.5px rgba(6,182,212,0.2) !important;
  background-color: var(--ad-bg-secondary) !important;
}
.form-control::placeholder { color: var(--ad-text-muted) !important; }
.form-label { font-weight: 600; font-size: 0.85rem; color: var(--ad-text-secondary); margin-bottom: 0.45rem; }
select.form-select option { background: var(--ad-bg-secondary); color: var(--ad-text-primary); }

/* ── The select caret needs its own gutter ──
   The rule above sets a SYMMETRIC `padding: 0.7rem 1rem !important` on `.form-control,
   .form-select` together. Bootstrap's own select padding is deliberately asymmetric —
   it reserves ~2.25rem on the right for the caret it paints as a background image at
   `right 0.75rem center` — and the symmetric override took that reserve away without
   removing the caret, so on every long option in the panel (class names, subject names,
   "SE — Computer Engineering · 2025-2026") the value ran straight underneath the arrow.
   Restoring only the right padding fixes it: same height, same left alignment, same
   colours, and the caret finally has somewhere to sit.

   `!important` is required to beat the shorthand above (equal specificity, later source
   order would otherwise win). The compact variants below re-assert their own tighter
   gutters for the same reason — they are declared EARLIER in this file than the shorthand
   and were silently losing to it.

   ORDER MATTERS in this block: every selector below is one class deep, so the LAST
   matching declaration wins. General gutter first, then the size modifier, then the
   named compact variants. */
.form-select {
  padding-right: 2.5rem !important;
}
/* Bootstrap's size modifier scales the gutter with the control. */
.form-select-sm {
  padding-right: 2rem !important;
}
/* Cr1 consistency matrices — a 48px cell cannot carry a 2rem gutter and a centred digit.
   Compact geometry plus a smaller, inset caret. This restates the block near the top of
   this file (search `.qx-level-select`), which is declared BEFORE the `.form-control,
   .form-select` shorthand and therefore lost to it at equal specificity: the matrix cells
   have been carrying the symmetric 1rem padding, and the caret over the digit, ever since.
   The copy up there still owns the text centring; this one owns the geometry. */
.qx-level-select {
  padding: 0.3rem 1.1rem 0.3rem 0.4rem !important;
  background-position: right 0.3rem center !important;
  background-size: 9px 7px !important;
}
/* Dense filter bars and page-size pickers keep their own narrower gutters (these two are
   two classes deep and would win anyway; kept together for readability). */
.qx-filter-field .form-select { padding-right: 2rem !important; }
.qx-filter-pagesize .form-select { padding-right: 2rem !important; }

/* ── Bootstrap btn-gradient override (used by existing JS) ── */
.btn-gradient {
  background: var(--ad-grad-primary) !important;
  border: none !important; color: #fff !important;
  box-shadow: 0 4px 14px rgba(6,182,212,0.28) !important;
  font-weight: 600;
}
.btn-gradient:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 22px rgba(6,182,212,0.40) !important;
  color: #fff !important;
}
.btn-outline-light {
  color: var(--ad-text-primary) !important;
  border-color: var(--ad-border) !important;
  background: transparent !important;
}
.btn-outline-light:hover {
  background: var(--ad-bg-card-hover) !important;
  border-color: var(--ad-accent-1) !important;
}
/* The SELECTED state of a button group, which had been invisible.
   Bootstrap styles `.btn-outline-light.active` by setting colour, border-colour and background —
   the same three properties the rule above pins with `!important`, and Bootstrap's are not. So
   `.active` was applied correctly by the JS and then suppressed entirely: the NBA module's six-way
   switcher (Scorecard / PEOs / Faculty / Research / Finance / Infrastructure) rendered all six tabs
   identically unselected, with nothing on screen saying which one you were looking at.
   The inset bar is deliberate — the selected tab must not be signalled by colour alone. */
.btn-outline-light.active,
.btn-outline-light[aria-pressed="true"] {
  background: var(--ad-bg-card-hover) !important;
  border-color: var(--ad-accent-1) !important;
  color: var(--ad-text-primary) !important;
  box-shadow: inset 0 -2px 0 0 var(--ad-accent-1) !important;
  font-weight: 600;
}
/* ── .btn-check toggle groups (a radio/checkbox + label.btn-outline-light) ──
   The rule at the top of this block pins colour, background and border with !important, and those
   are the only three things Bootstrap's `.btn-check:checked + .btn` changes — so a CHECKED option
   looked exactly like an unchecked one: Schedule Quiz's Practice/Exam and Live/Homework toggles,
   the notification audience, the longitudinal mode/period, the homework publish mode. Selected is
   an accent tint + accent text + the inset bar, so it is not signalled by colour alone and does not
   read as :hover (hover = card-hover background + accent border, no bar).
   Dark is the unqualified default and light is [data-theme="light"]. (<body> used to hard-code
   data-theme="dark", so a [data-theme="dark"] selector matched in BOTH themes; since PANEL-15 only
   <html> carries the theme and such selectors apply in dark alone.) */
:root {
  --ad-toggle-on-bg:     rgba(6, 182, 212, 0.16);
  --ad-toggle-on-text:   #a5f3fc;
  --ad-toggle-on-border: var(--ad-accent-1);
  --ad-focus-ring:       var(--ad-accent-1);
}
[data-theme="light"] {
  --ad-toggle-on-bg:     rgba(6, 182, 212, 0.12);
  --ad-toggle-on-text:   #0e7490;  /* #06b6d4 on white is ~2.4:1; this is ~4.8:1 */
  --ad-toggle-on-border: #0e7490;
  --ad-focus-ring:       #0e7490;
}
/* Keyboard focus: Bootstrap's own ring is rgba(248,249,250,.5) — invisible on the light theme. An
   outline, not a box-shadow, so it never fights the selected inset bar. Bootstrap sets outline:0 at
   (0,3,0), hence !important. */
.btn-check:focus-visible + .btn-outline-light {
  outline: 2px solid var(--ad-focus-ring) !important;
  outline-offset: 2px;
}
.btn-check:not(:checked):focus-visible + .btn-outline-light {
  box-shadow: none !important;
}
/* Selected. (0,3,0) beats `.btn-outline-light:hover` (0,2,0), so hovering the selected option keeps
   it looking selected. */
.btn-check:checked + .btn-outline-light {
  background: var(--ad-toggle-on-bg) !important;
  border-color: var(--ad-toggle-on-border) !important;
  color: var(--ad-toggle-on-text) !important;
  box-shadow: inset 0 -2px 0 0 var(--ad-toggle-on-border) !important;
}
/* Disabled: Bootstrap's opacity .65 still applies but its colours are overridden above, so a locked
   group must still show WHICH value is locked in. */
.btn-check:disabled + .btn-outline-light { opacity: .5; }
.btn-check:disabled:not(:checked) + .btn-outline-light { color: var(--ad-text-muted) !important; }
.btn-outline-info { color: var(--ad-accent-1) !important; border-color: var(--ad-accent-1) !important; }
.btn-outline-info:hover { background: rgba(6,182,212,0.1) !important; }
.btn { border-radius: 9px !important; font-weight: 600; transition: all 0.2s ease; }
.btn:active { transform: scale(0.97); }

/* ── Alert overrides ── */
.alert-danger  { background: rgba(239,68,68,0.10) !important; border-color: rgba(239,68,68,0.25) !important; color: #fca5a5 !important; }
.alert-warning { background: rgba(245,158,11,0.10) !important; border-color: rgba(245,158,11,0.25) !important; color: #fcd34d !important; }
.alert-info    { background: rgba(6,182,212,0.10) !important; border-color: rgba(6,182,212,0.25) !important; color: #67e8f9 !important; }
.alert-success { background: rgba(16,185,129,0.10) !important; border-color: rgba(16,185,129,0.25) !important; color: #6ee7b7 !important; }

/* ── Chips ── */
.chip { padding: 0.38rem 0.78rem; border-radius: 9999px; font-size: 0.74rem; font-weight: 600; display: inline-flex; align-items: center; gap: 0.35rem; border: 1px solid transparent; transition: transform 0.2s; }
.chip:hover { transform: scale(1.05); }
.chip-muted   { background: rgba(100,116,139,.12); color: var(--ad-text-secondary); border-color: var(--ad-border); }
.chip-success { background: rgba(16,185,129,.13); color: #34d399; border-color: rgba(16,185,129,.25); }
.chip-warning { background: rgba(245,158,11,.12); color: #fbbf24; border-color: rgba(245,158,11,.22); }
.chip-danger  { background: rgba(239,68,68,.12);  color: #f87171; border-color: rgba(239,68,68,.22); }

/* ── Text colors ── */
.ad-text-gradient {
  background: var(--ad-grad-primary);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.text-gradient { background: var(--ad-grad-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }

/* ── Icon shape ── */
.icon-shape {
  width: 40px; height: 40px; display: flex;
  align-items: center; justify-content: center;
  border-radius: 11px;
}
.bg-gradient-primary { background: var(--ad-grad-primary) !important; }

/* ── Table existing Bootstrap styles ── */
.table { border-color: var(--ad-border) !important; --bs-table-bg: transparent !important; }
.table thead th {
  background: var(--ad-bg-secondary) !important;
  color: var(--ad-text-muted) !important;
  border-bottom: 1px solid var(--ad-border) !important;
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
}
.table tbody td {
  border-bottom: 1px solid var(--ad-border-light) !important;
  color: var(--ad-text-secondary) !important; vertical-align: middle;
}
.table-hover tbody tr:hover { background-color: var(--ad-bg-card-hover) !important; }

/* ── qx-card compat (existing HTML uses this class) ── */
.qx-card {
  background: var(--ad-bg-card) !important;
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--ad-border) !important;
  border-radius: 14px !important;
  box-shadow: var(--ad-shadow-sm);
  transition: transform 0.28s cubic-bezier(0.2,0.8,0.2,1), box-shadow 0.28s ease, border-color 0.28s ease;
  overflow: hidden;
}
.qx-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--ad-shadow-glow) !important;
  border-color: rgba(6,182,212,0.28) !important;
}
/* Bootstrap dropdown menus are absolutely-positioned children of their toggle.
   Inside a .qx-card (overflow:hidden, to clip rounded corners) the open menu is
   clipped and looks like a no-op on click — e.g. the Analytics / Students /
   Results "Export" menus. While a menu is open, let the hosting card overflow so
   the menu shows; it still clips normally when closed. :has() scopes it to the
   open state and out-specifies the base .qx-card rule regardless of source order.

   THERE ARE TWO BUGS HERE AND THE OVERFLOW RULE ONLY FIXES THE FIRST. Un-clipping
   lets the menu escape the card, but it still paints UNDERNEATH any card that
   follows it in the DOM — the Dashboard "More" menu was sliced in half by the
   alerts strip, and two of its four items ("Publish notice", "Record fee payment")
   were completely unreachable.

   The cause is `backdrop-filter` on .qx-card above. Any backdrop-filter other than
   `none` CREATES A STACKING CONTEXT, so the menu's z-index:1000 is scoped INSIDE
   the card instead of competing at page level. The card itself is position:static
   / z-index:auto, so it paints in plain DOM order — and no z-index on the menu can
   ever lift it above a later sibling. That is why this looked fixed for the Export
   menus (they sit in the LAST card on their page, with nothing painting after) and
   stayed broken on the Dashboard.

   Raising the CARD is therefore the fix, not raising the menu. 1055 sits above
   Bootstrap's sticky/fixed bands and below .modal (1055/1060), so an open dropdown
   clears sibling cards without ever covering a dialog.

   The qx-picker typeahead list (modules/qx-picker.js — Fees "Find student", the
   concession picker, OBE/NBA/journey/onboarding student search) is the same
   absolutely-positioned child and hits both bugs: its 280px list was cut off at the
   card's bottom edge. It is "open" exactly when it lacks .d-none. */
.qx-card:has(.dropdown-menu.show),
.qx-card:has(.qx-picker-results:not(.d-none)) {
  overflow: visible !important;
  position: relative;
  z-index: 1055;
}

/* ── Overview panel compat (existing class names) ── */
.overview-panels-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 991px) { .overview-panels-row { grid-template-columns: 1fr; } }
.overview-panel {
  background: var(--ad-bg-card);
  border: 1px solid var(--ad-border);
  border-radius: 18px; overflow: hidden; position: relative;
  transition: transform 0.32s cubic-bezier(0.2,0.8,0.2,1), box-shadow 0.32s ease;
}
.overview-panel::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; border-radius: 18px 18px 0 0; }
.overview-panel:hover { transform: translateY(-3px); box-shadow: var(--ad-shadow-glow); }
.overview-panel--live::before { background: var(--ad-grad-primary); }
.overview-panel--live:hover { border-color: rgba(6,182,212,0.3); }
.overview-panel--completed::before { background: var(--ad-grad-purple); }
.overview-panel--completed:hover { border-color: rgba(139,92,246,0.3); }
.overview-panel-header { display: flex; align-items: center; justify-content: space-between; padding: 1.2rem 1.5rem; border-bottom: 1px solid var(--ad-border-light); }
.overview-panel-header .panel-title { display: flex; align-items: center; gap: 0.6rem; font-weight: 700; font-size: 0.94rem; margin: 0; }
.overview-panel-header .panel-icon { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-size: 1rem; }
.overview-panel--live .panel-icon { background: rgba(6,182,212,0.14); color: var(--ad-accent-1); }
.overview-panel--completed .panel-icon { background: rgba(139,92,246,0.14); color: #a78bfa; }
.overview-panel-count { font-size: 0.78rem; font-weight: 700; padding: 3px 10px; border-radius: 20px; }
.overview-panel--live .overview-panel-count { background: rgba(6,182,212,0.12); color: var(--ad-accent-1); }
.overview-panel--completed .overview-panel-count { background: rgba(139,92,246,0.12); color: #a78bfa; }
.overview-panel-body { padding: 1rem 1.5rem 1.5rem; max-height: 500px; overflow-y: auto; }
.overview-panel-body::-webkit-scrollbar { width: 5px; }
.overview-panel-body::-webkit-scrollbar-thumb { background: var(--ad-border); border-radius: 3px; }
.overview-quiz-item { padding: 0.82rem 1rem; border-radius: 10px; border: 1px solid var(--ad-border); background: var(--ad-bg-card); transition: all 0.18s ease; margin-bottom: 0.45rem; }
.overview-quiz-item:last-child { margin-bottom: 0; }
.overview-quiz-item:hover { background: var(--ad-bg-card-hover); border-color: var(--ad-accent-1); transform: translateX(3px); }

/* Pagination compat */
.overview-pagination-bar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.2rem; padding: 0.8rem 1.2rem; background: var(--ad-bg-card); border: 1px solid var(--ad-border); border-radius: 12px; }
.overview-pagination-controls { display: flex; align-items: center; gap: 0.35rem; }
.overview-pg-btn { width: 34px; height: 34px; padding: 0 !important; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px !important; font-size: 0.84rem; background: transparent; color: var(--ad-text-secondary) !important; border-color: var(--ad-border) !important; transition: all 0.18s ease; }
.overview-pg-btn:hover:not(:disabled) { background: var(--ad-bg-card-hover) !important; color: var(--ad-accent-1) !important; border-color: var(--ad-accent-1) !important; }
.overview-pg-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.overview-page-indicator { display: inline-flex; align-items: center; justify-content: center; min-width: 58px; padding: 3px 10px; border-radius: 9px; background: var(--ad-bg-input); color: var(--ad-text-primary); font-size: 0.79rem; font-weight: 700; text-align: center; }

/* ── Subscription section ── */
.sub-section-header { display: flex; align-items: flex-start; gap: 1rem; }
.sub-section-icon {
  width: 48px; height: 48px; border-radius: var(--ad-radius);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  background: var(--ad-grad-primary); color: #fff; font-size: 1.3rem;
}
.sub-section-title { font-size: 1.15rem; font-weight: 700; color: var(--ad-text-primary); margin: 0; }
.sub-section-subtitle { font-size: 0.85rem; color: var(--ad-text-secondary); margin-top: 2px; }

/* Status pill */
.sub-status-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 14px; border-radius: 999px; font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.sub-status-pill--active  { background: rgba(16,185,129,0.12); color: #10b981; }
.sub-status-pill--trial   { background: rgba(59,130,246,0.12); color: #3b82f6; }
.sub-status-pill--expired { background: rgba(239,68,68,0.12); color: #ef4444; }
.sub-status-pill--none    { background: rgba(143,163,192,0.12); color: var(--ad-text-secondary); }
.sub-status-dot {
  width: 7px; height: 7px; border-radius: 50%; background: currentColor;
  animation: sub-pulse 2s ease-in-out infinite;
}
@keyframes sub-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }

/* Info banner */
.sub-info-banner {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.85rem 1.1rem; border-radius: var(--ad-radius);
  background: rgba(6,182,212,0.06); border: 1px solid rgba(6,182,212,0.15);
  font-size: 0.82rem; color: var(--ad-text-secondary); line-height: 1.5;
}
.sub-info-banner i { color: var(--ad-accent-1); font-size: 1rem; margin-top: 2px; flex-shrink: 0; }

/* ── Plan cards ── */
.plan-card {
  border: 1px solid var(--ad-border); border-radius: 20px; padding: 1.75rem;
  background: var(--ad-bg-card); position: relative; cursor: pointer;
  transition: all 0.3s cubic-bezier(0.175,0.885,0.32,1.275);
  display: flex; flex-direction: column; gap: 1rem; min-height: 100%;
}
.plan-card:hover { border-color: var(--ad-accent-1); box-shadow: var(--ad-shadow-glow); transform: translateY(-4px); }
.plan-card.selected {
  border-color: var(--ad-accent-2); box-shadow: 0 0 0 2px var(--ad-accent-2);
  background: linear-gradient(135deg, rgba(16,185,129,0.04), rgba(6,182,212,0.04));
}
.plan-card.selected::after {
  content: '\F272'; font-family: 'bootstrap-icons';
  position: absolute; top: 14px; right: 14px;
  color: var(--ad-accent-2); font-size: 1.1rem;
}
.plan-card.current { border-color: rgba(6,182,212,0.35); }
.plan-price { font-size: 2rem; font-weight: 800; color: var(--ad-text-primary); letter-spacing: -0.04em; line-height: 1.1; }
.plan-price .plan-price-period { font-size: 0.8rem; font-weight: 500; color: var(--ad-text-secondary); letter-spacing: 0; }

/* Plan badge (free / popular / custom) */
.plan-badge {
  position: absolute; top: -1px; right: 20px;
  padding: 4px 12px; border-radius: 0 0 8px 8px; font-size: 0.68rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  background: var(--ad-grad-primary); color: #fff;
}

/* Plan feature list */
.plan-feature {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; font-size: 0.82rem; color: var(--ad-text-secondary);
  border-bottom: 1px solid rgba(45,65,95,0.18);
}
.plan-feature:last-child { border-bottom: none; }
.plan-feature i { color: var(--ad-accent-1); font-size: 0.9rem; width: 18px; text-align: center; flex-shrink: 0; }

/* Current plan indicator on card */
.plan-status-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: 0.7rem; font-weight: 600;
  background: rgba(6,182,212,0.12); color: var(--ad-accent-1);
}

/* ── Payment summary panel ── */
.plan-payment-summary {
  border-radius: var(--ad-radius-lg); padding: 1.5rem;
  background: var(--ad-bg-card); border: 1px solid var(--ad-border);
}
.plan-payment-amount {
  font-size: 2rem; font-weight: 800; letter-spacing: -0.03em;
  background: var(--ad-grad-primary); -webkit-background-clip: text;
  -webkit-text-fill-color: transparent; background-clip: text;
}
.plan-payment-meta {
  font-size: 0.82rem; color: var(--ad-text-secondary); line-height: 1.6;
}
.plan-payment-stat {
  padding: 1rem; border-radius: var(--ad-radius); background: var(--ad-bg-input);
  text-align: center;
}
.plan-payment-stat-label {
  font-size: 0.68rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ad-text-muted); margin-bottom: 4px;
}
.plan-payment-stat-value { font-size: 1.15rem; font-weight: 700; color: var(--ad-text-primary); }

/* Ad experience pills */
.ads-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: 999px; font-size: 0.74rem; font-weight: 500;
  background: var(--ad-bg-input); color: var(--ad-text-secondary);
  border: 1px solid var(--ad-border-light);
}
.ads-pill i { font-size: 0.85rem; color: var(--ad-accent-1); }

/* ── Plan summary (active subscription view) ── */
.sub-active-plan {
  display: grid; grid-template-columns: 1fr; gap: 1.5rem;
}
@media (min-width: 768px) { .sub-active-plan { grid-template-columns: 280px 1fr; } }
.sub-active-plan-price-block {
  padding: 1.5rem; border-radius: var(--ad-radius-lg);
  background: linear-gradient(145deg, var(--ad-bg-card), var(--ad-bg-card-hover));
  border: 1px solid var(--ad-border); text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.5rem;
}
.sub-active-plan-price {
  font-size: 2.2rem; font-weight: 800; letter-spacing: -0.04em;
  background: var(--ad-grad-primary); -webkit-background-clip: text;
  -webkit-text-fill-color: transparent; background-clip: text;
}
.sub-active-plan-name { font-size: 1.05rem; font-weight: 600; color: var(--ad-text-primary); }
.sub-plan-dates {
  display: flex; flex-direction: column; gap: 4px; margin-top: 0.5rem;
}
.sub-plan-date-row {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--ad-text-secondary);
}
.sub-plan-date-row i { font-size: 0.85rem; color: var(--ad-text-muted); width: 16px; text-align: center; }
.sub-plan-features-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem;
}
@media (max-width: 575.98px) { .sub-plan-features-grid { grid-template-columns: 1fr; } }
.sub-plan-feature-item {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: var(--ad-radius-sm);
  background: var(--ad-bg-input); font-size: 0.82rem; color: var(--ad-text-secondary);
}
.sub-plan-feature-item i {
  font-size: 1rem; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border-radius: 6px; background: rgba(6,182,212,0.1); color: var(--ad-accent-1); flex-shrink: 0;
}

/* ── Subscription responsive ── */
@media (max-width: 767.98px) {
  .plan-price { font-size: 1.6rem; }
  .sub-active-plan-price { font-size: 1.8rem; }
  .plan-payment-amount { font-size: 1.6rem; }
  .plan-card { padding: 1.25rem; }
}

/* ── Skeleton (existing class name) ── */
.results-skeleton .skeleton-line {
  height: 14px; border-radius: 6px; margin-bottom: 10px;
  background: linear-gradient(90deg, var(--ad-bg-card-hover) 25%, var(--ad-border) 50%, var(--ad-bg-card-hover) 75%);
  background-size: 200% 100%; animation: ad-shimmer 2s infinite linear;
}

/* ── Results Module ── */

/* Compact header card */
.results-header-card {
  padding: 0.875rem 1.25rem;
}
.results-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.results-header-title {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  flex-wrap: wrap;
  min-width: 0;
}
.results-header-title .h5 {
  white-space: nowrap;
}

/* Filter divider line */
.results-filter-divider {
  height: 1px;
  background: var(--ad-border-light);
  margin: 0.625rem 0;
}

/* Inline filter bar */
.results-filter-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.results-filter-fields {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex: 1 1 auto;
  flex-wrap: wrap;
  min-width: 0;
}
.results-filter-fields > select,
.results-filter-fields > div:not(.results-filter-date-group) select {
  min-width: 120px;
  max-width: 170px;
  flex: 1 1 120px;
}

/* Date range group */
.results-filter-date-group {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex: 0 1 auto;
}
.results-filter-date-group input {
  width: 130px;
  min-width: 110px;
}
.results-filter-date-sep {
  color: var(--ad-text-muted);
  font-size: 0.8rem;
  line-height: 1;
  flex-shrink: 0;
}

/* Filter action buttons */
.results-filter-actions {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-shrink: 0;
}

/* Active filter tags */
.results-active-tags {
  padding-top: 0.5rem;
}

/* Responsive: stack filters on mobile */
@media (max-width: 767.98px) {
  .results-header-card {
    padding: 0.75rem 1rem;
  }
  .results-filter-fields {
    gap: 0.375rem;
  }
  .results-filter-fields > select,
  .results-filter-fields > div:not(.results-filter-date-group) select {
    min-width: 0;
    max-width: none;
    flex: 1 1 calc(50% - 0.25rem);
  }
  .results-filter-date-group {
    flex: 1 1 100%;
  }
  .results-filter-date-group input {
    width: auto;
    flex: 1;
  }
  .results-filter-actions {
    flex: 1 1 100%;
    justify-content: flex-start;
  }
}

/* Quiz card */
.results-quiz-card {
  transition: border-color 0.15s, box-shadow 0.15s;
  border: 1px solid transparent;
}
.results-quiz-card:hover {
  border-color: var(--ad-accent-3);
  box-shadow: 0 0 0 1px rgba(6,182,212,0.15);
}
#resultsSubNav .nav-link {
  font-size: 0.82rem;
  font-weight: 500;
}
#resultsActiveFilters .badge {
  font-size: 0.72rem;
  font-weight: 500;
}
#resultsActiveFilters .btn-close {
  filter: none;
  opacity: 0.6;
}
#resultsActiveFilters .btn-close:hover { opacity: 1; }

/* Export modal */
#resultsExportModal .form-label.fw-semibold {
  font-size: 0.85rem;
  margin-bottom: 0.4rem;
}
#resultsExportModal .form-text {
  font-size: 0.75rem;
}

/* ── Nav link compat (sidebar uses Bootstrap nav-link) ── */
.sidebar .nav-link {
  color: var(--ad-text-secondary) !important;
  border-radius: 10px !important; padding: 0.72rem 1rem !important;
  font-weight: 500; display: flex; align-items: center; gap: 0.7rem;
  transition: all 0.18s cubic-bezier(0.4,0,0.2,1);
  position: relative;
}
.sidebar .nav-link:hover {
  background: var(--ad-bg-card-hover) !important;
  color: var(--ad-text-primary) !important;
  transform: translateX(3px);
}
.sidebar .nav-link.active {
  background: rgba(6,182,212,0.1) !important;
  color: var(--ad-accent-3) !important;
  font-weight: 600;
}
.sidebar .nav-link.active::before {
  content: ''; position: absolute; left: 0; top: 22%; bottom: 22%;
  width: 3px; border-radius: 0 3px 3px 0;
  background: var(--ad-grad-primary);
}
.sidebar .nav-link i { font-size: 1.15em; }

/* ── Create Quiz CTA ── */
.sidebar .open-create-quiz:hover {
  opacity: 0.9;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(6,182,212,0.3);
}
.sidebar .open-create-quiz:active {
  transform: translateY(0);
}
.sidebar .open-create-quiz.cta-active {
  box-shadow: 0 0 0 2px var(--ad-accent-3), 0 4px 12px rgba(6,182,212,0.25);
}

/* Legacy support */
.students-filter-group .form-label { color: var(--ad-text-secondary); }
/* background-COLOR, not the `background` shorthand: the shorthand with !important also resets
   background-image to none, and Bootstrap paints the .form-select caret as a background image — so
   every native select inside any .collapse (the Quizzes filter bar is one) rendered with no
   dropdown arrow at all, beside the tracker's bar which is not in a collapse and kept its arrows. */
.collapse .form-control, .collapse .form-select { background-color: var(--ad-bg-input) !important; }

/* ── Content toolbar breadcrumb ── */
.content-toolbar { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; }
.breadcrumb { --bs-breadcrumb-divider-color: var(--ad-text-muted); margin-bottom: 0; }
.breadcrumb-item a { color: var(--ad-text-muted); transition: color 0.2s; text-decoration: none; font-weight: 500;}
.breadcrumb-item a:hover { color: var(--ad-accent-1); }
.breadcrumb-item.active { color: var(--ad-text-primary); font-weight: 600; }

/* ── CQ (create quiz) section colors ── */
.cq-header { 
  background: linear-gradient(135deg, rgba(30,41,59,0.5) 0%, rgba(15,23,42,0.8) 100%) !important; 
  border: 1px solid var(--ad-border) !important; 
  border-radius: 18px; 
  padding: 1.5rem 2rem;
  margin-bottom: 1.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: var(--ad-shadow-sm);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
[data-theme="light"] .cq-header {
  background: linear-gradient(135deg, rgba(255,255,255,0.7) 0%, rgba(248,250,252,0.9) 100%) !important;
}
.cq-header-content { display: flex; align-items: center; gap: 1.25rem; }
.cq-header-icon { 
  background: var(--ad-grad-primary) !important; 
  width: 48px; height: 48px; 
  display: flex; align-items: center; justify-content: center; 
  border-radius: 14px; color: white; font-size: 1.4rem;
  box-shadow: 0 4px 12px rgba(6,182,212,0.3);
}
.cq-header-title { margin: 0; font-size: 1.4rem; font-weight: 700; color: var(--ad-text-primary); letter-spacing: -0.02em; }
.cq-header-subtitle { margin: 0; font-size: 0.88rem; color: var(--ad-text-secondary); margin-top: 0.2rem; }

.cq-tips-card { 
  background: var(--ad-bg-card) !important; 
  border: 1px solid var(--ad-border) !important;
  border-left: 4px solid var(--ad-accent-1) !important; 
  padding: 1.25rem;
  border-radius: 12px;
  margin-bottom: 1.5rem;
}

.cq-step-card { 
  background: var(--ad-bg-card) !important; 
  border: 1px solid var(--ad-border) !important; 
  border-radius: 18px !important; 
  padding: 0;
  margin-bottom: 2rem;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05), var(--ad-shadow-sm);
  transition: transform 0.28s cubic-bezier(0.2,0.8,0.2,1), box-shadow 0.28s ease, border-color 0.28s ease;
  overflow: hidden;
}
.cq-step-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--ad-shadow-glow) !important;
  border-color: rgba(6,182,212,0.25) !important;
}

.cq-step-indicator { 
  background: var(--ad-bg-secondary) !important; 
  border-bottom: 1px solid var(--ad-border) !important; 
  padding: 1rem 1.75rem;
  display: flex; align-items: center; gap: 1rem;
}
.cq-step-number { 
  background: var(--ad-grad-primary) !important; 
  color: white; font-weight: 700; width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px; font-size: 0.9rem;
}
.cq-step-label { font-size: 1.1rem; font-weight: 700; color: var(--ad-text-primary); }
.cq-step-body { padding: 1.75rem; }

.cq-save-bar { 
  background: var(--ad-bg-card) !important; 
  border: 1px solid var(--ad-border) !important; 
  border-radius: 14px;
  padding: 1rem 1.5rem;
  display: flex; justify-content: space-between; align-items: center;
  box-shadow: var(--ad-shadow-sm);
  margin-top: 1rem;
}
.cq-save-bar-hint {
  color: var(--ad-text-muted);
  font-size: 0.88rem;
  display: flex;
  align-items: center;
}

.cq-build-tabs { border-bottom: 2px solid var(--ad-border); margin-bottom: 1.5rem !important; }
.cq-build-tabs .nav-link { 
  border: none !important; 
  border-bottom: 2px solid transparent !important;
  color: var(--ad-text-secondary) !important; 
  background: transparent !important; 
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  margin-bottom: -2px;
  border-radius: 0 !important;
}
.cq-build-tabs .nav-link:hover { color: var(--ad-text-primary) !important; border-bottom-color: var(--ad-border-light) !important; }
.cq-build-tabs .nav-link.active { 
  color: var(--ad-accent-1) !important; 
  border-bottom-color: var(--ad-accent-1) !important; 
  background: transparent !important;
}

/* ── Smart Preview & Question Options ── */
.smart-preview, .smart-text-editor__preview {
  background-color: var(--ad-bg-secondary) !important;
  border-color: var(--ad-border) !important;
  color: var(--ad-text-primary) !important;
}

/* Standalone Question Options in Modal */
#qbModalOptionsContainer .card {
  background-color: var(--ad-bg-input) !important;
  border: 1px solid var(--ad-border-light) !important;
  transition: var(--ad-transition-fast);
}
#qbModalOptionsContainer .card:hover {
  border-color: var(--ad-accent-1) !important;
  background-color: var(--ad-bg-card-hover) !important;
}
#qbModalOptionsContainer .card-body {
  padding: 1rem !important;
}

.cq-add-question-btn { 
  border: 1px dashed rgba(6,182,212,0.4) !important; 
  color: var(--ad-text-muted) !important; 
  background: rgba(6,182,212,0.03) !important;
  padding: 1rem !important;
  border-radius: 14px !important;
  font-weight: 600;
}
.cq-add-question-btn:hover { 
  border-color: var(--ad-accent-1) !important; 
  color: var(--ad-accent-1) !important; 
  background: rgba(6,182,212,0.08) !important;
}

/* ── Form Groups in MQ ── */
.cq-field-group .form-label { font-size: 0.9rem; font-weight: 600; color: var(--ad-text-secondary); margin-bottom: 0.5rem; }
.cq-field-group .form-control { background: var(--ad-bg-card); }
.cq-field-group .form-control:focus { background: var(--ad-bg-secondary); }

/* ── Drag and drop compat ── */
.drag-handle { cursor: grab; color: var(--ad-text-muted); transition: color 0.2s; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 6px; }
.drag-handle:hover { color: var(--ad-accent-1); background: rgba(6,182,212,0.08); }
.drag-handle:active { cursor: grabbing; }
.qx-card.dragging { opacity: 0.5; border: 2px dashed var(--ad-accent-1) !important; transform: scale(0.98); }
.qx-card.drag-over { border-top: 4px solid var(--ad-accent-1) !important; }

/* ── Offcanvas (mobile nav) ── */
.offcanvas { background: var(--ad-bg-sidebar) !important; border-color: var(--ad-border) !important; color: var(--ad-text-primary) !important; }

/* ── Topbar (mobile) ── */
.app-topbar { background: var(--ad-bg-secondary) !important; border-bottom: 1px solid var(--ad-border) !important; }

/* ── Sidebar layout (existing .sidebar class) ── */
.sidebar {
  width: 280px; position: fixed; top: 0; bottom: 0; left: 0;
  padding: 1.5rem 1.25rem; overflow-y: auto;
  border-right: 1px solid var(--ad-border);
  background: var(--ad-bg-sidebar) !important;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  color: var(--ad-text-primary); z-index: 1000;
  transition: transform 0.3s ease;
}
.sidebar hr { border-color: var(--ad-border); opacity: 1; margin: 1.25rem 0; }

.content { margin-left: 280px; padding: 2rem; max-width: 1600px; }

/* ── Responsive ── */
@media (max-width: 991.98px) {
  .sidebar { transform: translateX(-100%); }
  .sidebar.show { transform: translateX(0); }
  .content { margin-left: 0; padding: 1rem; }
  .overview-panels-row { grid-template-columns: 1fr; }
}

/* ── Theme toggle button ── */
.theme-toggle {
  background: var(--ad-bg-input) !important;
  border: 1px solid var(--ad-border) !important;
  color: var(--ad-text-secondary) !important;
  border-radius: 9px !important;
  padding: 7px 12px !important;
  font-size: 13px;
  display: inline-flex; align-items: center; gap: 6px;
  transition: var(--ad-transition-fast);
}
.theme-toggle:hover { border-color: var(--ad-accent-1) !important; color: var(--ad-accent-1) !important; }

/* ── Modal/dialog backdrop ── */
.modal-backdrop { backdrop-filter: blur(4px); }

/* ── Utility ── */
.text-secondary { color: var(--ad-text-secondary) !important; }
.text-muted { color: var(--ad-text-muted) !important; }
.border { border-color: var(--ad-border) !important; }
.fw-bold { font-weight: 700 !important; }
.tracking-tight { letter-spacing: -0.02em; }
.tracking-wide  { letter-spacing: 0.06em; }
.display-5 { font-weight: 800 !important; color: var(--ad-text-primary) !important; }

/* Animate compat */
.animate-fade-in  { animation: ad-fade-in  0.5s ease-out forwards; }
.animate-slide-up { animation: ad-slide-up 0.6s cubic-bezier(0.16,1,0.3,1) forwards; opacity: 0; }
.animate-scale-in { animation: ad-scale-in 0.45s cubic-bezier(0.34,1.56,0.64,1) forwards; opacity: 0; }
.stagger-1 { animation-delay: 80ms; }
.stagger-2 { animation-delay: 160ms; }
.stagger-3 { animation-delay: 240ms; }
.stagger-4 { animation-delay: 320ms; }
.stagger-5 { animation-delay: 400ms; }

/* ── Input group compat ── */
.input-group-text {
  background: var(--ad-bg-card-hover) !important;
  border-color: var(--ad-border-light) !important;
  color: var(--ad-text-muted) !important;
}

/* ── Smart Text Editor & KaTeX Dark Mode Fix ── */
[data-theme="dark"] .bg-light.smart-text-editor__preview,
[data-theme="dark"] .bg-light.smart-preview {
  background-color: var(--ad-bg-input) !important;
  color: var(--ad-text-primary) !important;
  border-color: var(--ad-border) !important;
}

[data-theme="dark"] .katex {
  color: var(--ad-text-primary) !important;
}
[data-theme="dark"] .katex-display {
  color: var(--ad-text-primary) !important;
}

/* ── Create Quiz Form Enhancements ── */
.cq-step-card {
  padding: 1.5rem;
  margin-bottom: 2rem;
  transition: transform 0.2s, box-shadow 0.2s;
}
.cq-step-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--ad-shadow-glow) !important;
}
.cq-save-bar-hint {
  color: var(--ad-text-muted);
  font-size: 0.85rem;
  display: flex;
  align-items: center;
}
.smart-text-editor__controls .btn {
  border-radius: 8px !important;
}
.smart-text-editor__controls .btn-outline-secondary {
  color: var(--ad-text-secondary);
  border-color: var(--ad-border);
}
.smart-text-editor__controls .btn-outline-secondary:hover,
.smart-text-editor__controls .btn-outline-secondary.active {
  background: var(--ad-bg-card-hover);
  color: var(--ad-accent-1);
  border-color: var(--ad-accent-1);
}

/* ── OTP Settings cards ── */
.otp-channel-card {
  cursor: pointer;
  transition: all 0.2s ease;
  border-color: var(--ad-border) !important;
  background: var(--ad-bg-card);
}
.otp-channel-card:hover {
  border-color: var(--ad-accent-1) !important;
  background: var(--ad-bg-card-hover);
}
.otp-channel-card.selected {
  border-color: var(--ad-accent-1) !important;
  box-shadow: 0 0 0 2px rgba(var(--ad-accent-1-rgb, 99,102,241), 0.25);
  background: var(--ad-bg-card-hover);
}
.otp-channel-card.selected::after {
  content: '\F272';
  font-family: 'bootstrap-icons';
  position: absolute;
  top: 10px;
  right: 10px;
  color: var(--ad-accent-1);
  font-size: 1.1rem;
}
.otp-channel-card {
  position: relative;
}

/* ── Compact Filter Bar (Quizzes tab) ── */
.qx-filter-card {
  padding: 0.85rem 1.15rem !important;
}
.qx-filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.qx-filter-title-group {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  flex-wrap: wrap;
  min-width: 0;
}
.qx-filter-title-group .h5 {
  white-space: nowrap;
}
.qx-filter-pagesize {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.qx-filter-pagesize .form-select {
  width: auto;
  min-width: 62px;
  min-height: unset !important;
  padding: 0.3rem 2rem 0.3rem 0.55rem !important;
  font-size: 0.78rem !important;
}
.qx-filter-bar {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.7rem;
  margin-top: 0.7rem;
  border-top: 1px solid var(--ad-border-light);
}
.qx-filter-bar-inputs {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  flex: 1 1 0%;
  min-width: 0;
}
.qx-filter-field {
  flex: 1 1 130px;
  min-width: 120px;
  max-width: 200px;
}
.qx-filter-field--search {
  flex: 1.8 1 180px;
  max-width: 280px;
}
.qx-filter-field--narrow {
  flex: 0.8 1 110px;
  max-width: 160px;
}
/* A field whose values carry a qualifier at the END — global subjects labelled with their board
   ("Mathematics & Statistics — MSBSHSE"). At 200px the qualifier, the one part that tells four
   same-named subjects apart, is exactly what got clipped. The phone block below still stacks it
   full-width (its `.qx-filter-field` rule comes later at equal specificity). */
.qx-filter-field--wide {
  /* The BASIS is what buys the width: the bar shares its space in proportion to each field's
     basis. Measured on the Quizzes bar: 170px left this field ~185px at a 1366px laptop (board
     clipped); 215px gives ~218px there and ~271px at 1576px — every Class 12 label but the longest
     fits — and still keeps the bar on ONE row; 230px+ wraps it to two rows at 1366px. */
  flex: 1.5 1 215px;
  max-width: 300px;
}
/* PANEL-21: a control's intrinsic width (a long option label) must not push past its field. */
.qx-filter-card .form-control,
.qx-filter-card .form-select { min-width: 0; }
.qx-filter-field .form-control,
.qx-filter-field .form-select {
  min-height: unset !important;
  padding: 0.38rem 0.65rem !important;
  font-size: 0.8rem !important;
  border-radius: 8px !important;
}
.qx-filter-field .form-select {
  padding-right: 2rem !important;
}
.qx-filter-input-icon {
  position: relative;
}
.qx-filter-input-icon > i {
  position: absolute;
  left: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.75rem;
  color: var(--ad-text-muted);
  pointer-events: none;
  z-index: 2;
}
.qx-filter-input-icon > .form-control {
  padding-left: 1.85rem !important;
}
.qx-filter-bar-actions {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}
.qx-filter-bar-actions .btn {
  white-space: nowrap;
  padding: 0.38rem 0.85rem !important;
  font-size: 0.8rem !important;
}

/* Responsive: stack on small screens */
@media (max-width: 767.98px) {
  .qx-filter-header {
    gap: 0.5rem;
  }
  .qx-filter-title-group {
    flex-direction: column;
    gap: 0.1rem;
  }
  .qx-filter-bar {
    flex-direction: column;
    align-items: stretch;
  }
  .qx-filter-bar-inputs {
    flex-direction: column;
    /* The base rule's `align-items: center` is a CROSS-axis rule, and in a column that axis is the
       width: every stacked field shrank to its own content and sat centred, each a different width. */
    align-items: stretch;
  }
  .qx-filter-field,
  .qx-filter-field--search,
  .qx-filter-field--narrow {
    max-width: 100%;
    flex-basis: auto;
  }
  .qx-filter-bar-actions {
    justify-content: flex-start;
  }
}

/* ── Question Bank compact filter tweaks ── */
.qb-my-toggle {
  white-space: nowrap;
}
.qb-my-toggle .form-check-label {
  font-size: 0.8rem;
  color: var(--ad-text-secondary);
}
[data-theme="light"] .qb-my-toggle .form-check-label {
  color: #4a6080;
}

@keyframes qx-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.spin-animation {
  animation: qx-spin 0.8s linear infinite;
}

/* ══════════════════════════════════════════════════════════════
   Curriculum Tab — Redesigned UI
   ══════════════════════════════════════════════════════════════ */

/* Section header with icon and subtitle */
.curriculum-section-header {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 0.25rem;
}
.curriculum-section-header .section-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.95rem;
  flex-shrink: 0;
}
.curriculum-section-header .section-icon.icon-classes {
  background: rgba(6, 182, 212, 0.15);
  color: var(--ad-accent-1);
}
.curriculum-section-header .section-icon.icon-divisions {
  background: rgba(16, 185, 129, 0.15);
  color: var(--ad-accent-2);
}
.curriculum-section-header .section-icon.icon-subjects {
  background: rgba(139, 92, 246, 0.15);
  color: #8b5cf6;
}
.curriculum-section-header .section-icon.icon-faculties {
  background: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
}
.curriculum-section-subtitle {
  color: var(--ad-text-muted);
  font-size: 0.8rem;
  margin-top: 0.125rem;
}

/* Curriculum card container overrides — prevent hover lift on panel cards */
.curriculum-panel.qx-card {
  transition: none;
  overflow: visible;
}
.curriculum-panel.qx-card:hover {
  transform: none;
  box-shadow: var(--ad-shadow-sm);
  border-color: var(--ad-border) !important;
}

/* ── Curriculum item cards (class, division, subject) ── */
.curriculum-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: 10px;
  border: 1px solid var(--ad-border);
  background: var(--ad-bg-secondary);
  transition: all 0.2s ease;
  position: relative;
  overflow: hidden;
}

/* Class items are fully clickable */
.curriculum-item--class {
  cursor: pointer;
  user-select: none;
}
.curriculum-item--class:hover {
  background: var(--ad-bg-card-hover);
  border-color: rgba(6, 182, 212, 0.35);
  box-shadow: 0 2px 8px rgba(6, 182, 212, 0.08);
}
.curriculum-item--class:active {
  transform: scale(0.99);
}
.curriculum-item--class.is-selected {
  background: rgba(6, 182, 212, 0.1);
  border-color: var(--ad-accent-1);
  box-shadow: 0 0 0 1px rgba(6, 182, 212, 0.2), 0 2px 8px rgba(6, 182, 212, 0.1);
}
.curriculum-item--class.is-selected .curriculum-item-name {
  color: var(--ad-accent-1);
}

/* Item icon (leading indicator) */
.curriculum-item-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  flex-shrink: 0;
}
.curriculum-item--class .curriculum-item-icon {
  background: rgba(6, 182, 212, 0.12);
  color: var(--ad-accent-1);
}
.curriculum-item--division .curriculum-item-icon {
  background: rgba(16, 185, 129, 0.12);
  color: var(--ad-accent-2);
}
.curriculum-item--subject .curriculum-item-icon {
  background: rgba(139, 92, 246, 0.12);
  color: #8b5cf6;
}

/* Item content */
.curriculum-item-content {
  flex: 1;
  min-width: 0;
}
.curriculum-item-name {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--ad-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.curriculum-item-desc {
  font-size: 0.75rem;
  color: var(--ad-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}
.curriculum-item-meta {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.25rem;
}
.curriculum-item-meta .badge {
  font-size: 0.65rem;
  font-weight: 500;
  padding: 0.2em 0.5em;
  border-radius: 4px;
}

/* Item actions (edit/delete) */
.curriculum-item-actions {
  display: flex;
  gap: 0.25rem;
  flex-shrink: 0;
  position: relative;
  z-index: 2;
}
.curriculum-item-actions .btn {
  width: 28px;
  height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  font-size: 0.75rem;
  border: none;
  line-height: 1;
}
.curriculum-item-actions .btn-edit {
  background: rgba(6, 182, 212, 0.1);
  color: var(--ad-accent-1);
}
.curriculum-item-actions .btn-edit:hover {
  background: rgba(6, 182, 212, 0.25);
}
.curriculum-item-actions .btn-delete {
  background: rgba(239, 68, 68, 0.1);
  color: #ef4444;
}
.curriculum-item-actions .btn-delete:hover {
  background: rgba(239, 68, 68, 0.25);
}

/* Item list spacing */
.curriculum-item-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Empty state styling */
.curriculum-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  text-align: center;
  color: var(--ad-text-muted);
}
.curriculum-empty-state i {
  font-size: 1.75rem;
  margin-bottom: 0.5rem;
  opacity: 0.5;
}
.curriculum-empty-state p {
  font-size: 0.8rem;
  margin: 0;
}

/* Curriculum count badges in headers */
.curriculum-count {
  background: rgba(6, 182, 212, 0.1);
  color: var(--ad-accent-1);
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.15em 0.55em;
  border-radius: 6px;
  margin-left: 0.35rem;
}

/* Responsive tweaks — stack items tighter on small screens */
@media (max-width: 991px) {
  .curriculum-item {
    padding: 0.625rem 0.75rem;
    gap: 0.5rem;
  }
  .curriculum-item-icon {
    width: 30px;
    height: 30px;
    font-size: 0.8rem;
  }
  .curriculum-item-actions .btn {
    width: 26px;
    height: 26px;
    font-size: 0.7rem;
  }
}

/* Prevent header buttons from overlapping section titles */
.curriculum-panel .d-flex.justify-content-between {
  flex-wrap: nowrap;
  gap: 0.5rem;
}
.curriculum-panel .d-flex.justify-content-between > .btn,
.curriculum-panel .d-flex.justify-content-between > [data-master-action] {
  white-space: nowrap;
  flex-shrink: 0;
}

/* Light theme overrides */
[data-theme="light"] .curriculum-item {
  background: #f8fafc;
  border-color: #e2e8f0;
}
[data-theme="light"] .curriculum-item--class:hover {
  background: #f0f9ff;
  border-color: rgba(6, 182, 212, 0.4);
}
[data-theme="light"] .curriculum-item--class.is-selected {
  background: rgba(6, 182, 212, 0.08);
  border-color: var(--ad-accent-1);
}
[data-theme="light"] .curriculum-item-actions .btn-edit {
  background: rgba(6, 182, 212, 0.08);
}
[data-theme="light"] .curriculum-item-actions .btn-delete {
  background: rgba(239, 68, 68, 0.08);
}

/* --- Code question rendering ---------------------------------------------
 * Shared styling for code-type question/option bodies across the dashboard,
 * results, and question-bank views. Keeps long lines scrollable instead of
 * wrapping mid-token, preserves whitespace exactly (indentation, blank lines,
 * tabs), and stays bounded by max-height so a 200-line snippet doesn't blow
 * out the surrounding card. The dark background + light text matches Prism's
 * `prism-tomorrow` theme already loaded in dashboard.html, so syntax-
 * highlighted tokens land cleanly on the container colour.
 */
.qx-code-block,
pre.qx-code-block {
  /* `!important` is intentional on the layout-critical properties.
   * Bootstrap's reboot.scss styles `pre` (display:block, font-size, margin)
   * and various card/list-group selectors define their own white-space and
   * background. Without !important, a context-specific Bootstrap rule can
   * win the cascade and collapse multi-line code into a single line of
   * plain text — exactly the bug the dashboard was hitting before. */
  display: block !important;
  margin: 0 !important;
  padding: 0.85rem 1rem !important;
  background-color: #1e1e2f !important;
  color: #e6e6f0 !important;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace !important;
  font-size: 0.85rem;
  line-height: 1.5;
  max-height: 480px;
  overflow: auto !important;
  white-space: pre !important;
  word-break: normal !important;
  word-wrap: normal !important;
  tab-size: 4;
  -moz-tab-size: 4;
}

.qx-code-block code,
pre.qx-code-block code {
  display: block;
  background: transparent !important;
  color: inherit !important;
  font-family: inherit !important;
  font-size: inherit !important;
  padding: 0 !important;
  white-space: inherit !important;
  word-break: inherit !important;
}

/* Single-line code preview shown in collapsed list rows (e.g. the question-
 * bank header). Monospace + faint pill background so it's recognisable as
 * code at a glance, while `text-overflow: ellipsis` keeps row layout tidy.
 */
.qx-code-inline {
  display: inline-block;
  max-width: 100%;
  padding: 0.1rem 0.45rem;
  background-color: rgba(30, 30, 47, 0.08);
  color: #1e1e2f;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 0.85em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}

[data-theme="dark"] .qx-code-inline {
  background-color: rgba(255, 255, 255, 0.08);
  color: #e6e6f0;
}

/* ============================================================
   Responsive fixes for custom (non-Bootstrap-grid) markup.
   Surfaced by the 2026-06-19 responsive audit. CSS-only — each
   rule targets a stable id/class so module JS stays untouched.
   ============================================================ */

/* Long unbreakable identifiers (UUIDs / payout ids) rendered into
   card-embedded key/value tables: the parent .qx-card is overflow:hidden,
   so without wrapping the value is silently clipped on phones. */
.qx-card .table-sm td { overflow-wrap: anywhere; word-break: break-word; }

/* Tablet / phone: wrap custom flex toolbars & rows that lack flex-wrap. */
@media (max-width: 767.98px) {
  /* Submission-stats: 7 bare .col never stack -> 3-up here, 2-up below */
  #submission-stats-panel .row.text-center.small > .col { flex: 0 0 33.3333%; max-width: 33.3333%; }

  /* Pending-invitations rows (dashboard.js overview) */
  #pendingInvitationsList > [data-invitation-id] { flex-wrap: wrap; gap: .5rem; }
  #pendingInvitationsList > [data-invitation-id] > div:first-child { min-width: 0; flex: 1 1 12rem; }
  #pendingInvitationsList > [data-invitation-id] .fw-semibold { overflow-wrap: anywhere; }

  /* Students bulk-actions toolbar (students.js) */
  #studentsBulkToolbar { flex-wrap: wrap; }
  #studentsBulkToolbar .btn { white-space: nowrap; }

  /* Teachers header search/button group (dashboard.html) */
  #tab-teachers .qx-card > .d-flex > .d-flex.gap-2 { flex-wrap: wrap; }
  #teacherSearchInput { min-width: 0 !important; flex: 1 1 160px; }

  /* Analytics "All Students" header (dashboard.html) */
  #tab-analytics .qx-card > .d-flex.justify-content-between { flex-wrap: wrap; gap: .5rem; }
  #anStudentSearch, #anStudentSort { flex: 1 1 auto; }

  /* Onboarding checklist rows (dashboard.js) */
  #onboardingChecklistItems > div { flex-wrap: wrap; }
  #onboardingChecklistItems > div > div:first-child { min-width: 0; flex: 1 1 auto; }

  /* Overview quiz item header + action group (quiz-assignment-ui.js) */
  .overview-quiz-item > .d-flex { flex-wrap: wrap; }
  .overview-quiz-item .d-flex.gap-2 { flex-wrap: wrap; }

  /* Attempt-details option rows: let the result badge wrap under long text */
  #attemptDetailsBody .list-group-item > .d-flex.justify-content-between { flex-wrap: wrap; gap: .35rem; }
  #attemptDetailsBody .list-group-item .badge { white-space: normal; }
}

@media (max-width: 575.98px) {
  /* Submission-stats: 2-up on phones */
  #submission-stats-panel .row.text-center.small > .col { flex: 0 0 50%; max-width: 50%; }

  /* Invitation cards (invitations.js): stack actions under info, full-width */
  .invitation-card .card-body > .d-flex.justify-content-between { flex-direction: column; gap: .75rem; }
  .invitation-card .card-body > .d-flex.justify-content-between > .d-flex.gap-2 { width: 100%; }
  .invitation-card .accept-btn, .invitation-card .decline-btn { flex: 1 1 0; }
}


/* ── Role-grouped sidebar hierarchy (sidebar RBAC redesign) ─────────────────────────
   Three visual tiers so a group "tab title" reads differently from its sub-tabs:
   (1) pinned top-level items  (2) group headers = small-caps section labels + caret
   (3) sub-tab items = indented under a left rail, smaller than the pinned items.
   Text colour, hover and the active highlight are intentionally left to the panel's
   existing `.sidebar .nav-link` styles (which use !important) so every tier stays
   visually consistent with the rest of the dashboard; only structural properties
   (size / weight / case / indent / rail) are set here to create the hierarchy. */

/* Tier 1 — pinned top-level items (Overview / Campus Home / Profile) */
#mainNav > li:not(.nav-group) > .nav-link { font-weight: 600; }

/* Tier 2 — group header ("tab title"): a clickable small-caps section label + caret */
#mainNav .nav-group { margin-top: 8px; }
#mainNav .nav-group-toggle {
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 7px 12px;
  border-radius: 8px;
}
#mainNav .nav-group-toggle > span { display: inline-flex; align-items: center; gap: 8px; }
#mainNav .nav-group-toggle > span .bi { font-size: 0.95rem; }
.nav-group-caret { transition: transform .15s ease; font-size: .8em; opacity: .55; }
.nav-group-toggle[aria-expanded="true"] .nav-group-caret { transform: rotate(180deg); opacity: .85; }

/* Tier 3 — sub-tab items: indented under a left rail, smaller than pinned items */
#mainNav ul[id^="grp-"] {
  margin: 3px 0 6px 20px;
  padding-left: 10px;
  border-left: 2px solid var(--ad-border);
}
#mainNav ul[id^="grp-"] .nav-link { font-size: 0.85rem; font-weight: 500; }
#mainNav ul[id^="grp-"] .nav-link .bi { margin-right: 8px; }
/* Active sub-tab highlight. The panel drives visible text via -webkit-text-fill-color
   (not just `color`), so set BOTH, plus a background tint and a left accent bar (which
   depend on neither) — belt-and-suspenders so the active item is unmistakable and
   consistent with the pinned active look. Wins via specificity + !important. */
#mainNav ul[id^="grp-"] .nav-link.active {
  color: var(--ad-accent-3) !important;
  -webkit-text-fill-color: var(--ad-accent-3) !important;
  background: rgba(6, 182, 212, 0.12) !important;
  box-shadow: inset 3px 0 0 var(--ad-accent-3);
  font-weight: 600;
}
#mainNav ul[id^="grp-"] .nav-link:hover:not(.active) {
  color: var(--ad-text-primary) !important;
  -webkit-text-fill-color: var(--ad-text-primary) !important;
  background: var(--ad-bg-input) !important;
}

/* ── Sidebar smoothness / motion polish (sidebar RBAC redesign) ──────────────────
   The role-grouped sidebar is an accordion of Bootstrap collapses. Tune the motion
   so expand/collapse, hover and scroll all glide instead of stepping. */

/* Snappier, consistent group expand/collapse — overrides Bootstrap's default 0.35s
   height tween with a smooth ease-out, plus a GPU hint so the height animation is
   composited rather than repainted per frame. */
#mainNav .collapsing {
  transition: height 0.28s cubic-bezier(0.33, 0.0, 0.2, 1);
  will-change: height;
}
.nav-group-caret { will-change: transform; }

/* Sub-tabs fade + settle in as their group opens (opacity/filter only — never
   `transform`, so it can't clobber the base .nav-link hover translateX). A light
   per-item stagger makes the reveal feel considered rather than abrupt. Runs only
   while `.show` is present, i.e. after the height animation has finished. */
#mainNav ul[id^="grp-"].show > .nav-item {
  animation: qcNavItemIn 0.26s cubic-bezier(0.33, 0.0, 0.2, 1) both;
}
#mainNav ul[id^="grp-"].show > .nav-item:nth-child(1) { animation-delay: 0.00s; }
#mainNav ul[id^="grp-"].show > .nav-item:nth-child(2) { animation-delay: 0.03s; }
#mainNav ul[id^="grp-"].show > .nav-item:nth-child(3) { animation-delay: 0.06s; }
#mainNav ul[id^="grp-"].show > .nav-item:nth-child(4) { animation-delay: 0.09s; }
#mainNav ul[id^="grp-"].show > .nav-item:nth-child(n+5) { animation-delay: 0.12s; }
@keyframes qcNavItemIn {
  from { opacity: 0; filter: blur(0.4px); }
  to   { opacity: 1; filter: blur(0); }
}

/* Thin, subtle scrollbar + smooth programmatic scroll for the fixed sidebar, so a
   tall (many-groups-open) menu scrolls cleanly instead of showing a chunky bar. */
.sidebar { scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color: var(--ad-border) transparent; }
.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb {
  background: var(--ad-border);
  border-radius: 8px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--ad-text-muted); background-clip: padding-box; }

/* Accessibility: honour reduced-motion — no accordion/caret animation, no smooth scroll. */
@media (prefers-reduced-motion: reduce) {
  #mainNav .collapsing,
  .nav-group-caret,
  .sidebar .nav-link,
  #mainNav ul[id^="grp-"].show > .nav-item { transition: none !important; animation: none !important; }
  .sidebar { scroll-behavior: auto; }
}

/* ── Instant main-tab switching (kill the click→pane lag) ─────────────────────────
   Bootstrap's `.fade` tab-panes keep opacity:0 and only add `.show` after an EMULATED
   fade-duration (~150ms) — so a freshly-clicked pane is invisible for ~150ms while
   `shown.bs.tab` has already fired and data is loading underneath. That gap is the
   "lag". Top-level content panes are `#tab-*` (sub-tabs use other id prefixes:
   overSub-/resSub-/notifSub-/anSub-/accSub-/stuSub-), so for those ONLY make
   the pane fully visible the instant Bootstrap adds `.active` — no wait for `.show`,
   no fade. The screen opens immediately; the loading bar (tab-manager.js) then shows
   that data is loading. Sub-tab panes keep their normal fade. */
.tab-content > .tab-pane.fade[id^="tab-"] { transition: none; }
.tab-content > .tab-pane.fade[id^="tab-"].active { opacity: 1; }

/* ── Academic Calendar (campus-calendar.js) ───────────────────────────────────────
   Lives here, not in a JS-injected <style>, so it takes part in the [data-theme]
   cascade and applies to BOTH the month grid and the agenda list.

   The panel flips themes with `data-theme` only — it never sets Bootstrap's own
   `data-bs-theme`, so every `--bs-*` variable and every `bg-*-subtle`/`text-*-emphasis`
   utility is frozen at Bootstrap's LIGHT values. Anything on this screen that leaned on
   those was therefore unreadable in one theme or the other (grid text vanished in dark,
   cell borders vanished in light). All calendar colours below come from `--ad-*` or from
   an explicit per-theme pair. */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; --cal-cell-border: rgba(148, 172, 205, .30); }
[data-theme="light"] .cal-grid { --cal-cell-border: rgba(90, 115, 150, .42); }
.cal-head {
  font-size: .75rem; text-align: center; padding: 2px 0;
  color: var(--ad-text-secondary); font-weight: 600; letter-spacing: .02em;
}
.cal-cell {
  min-height: 92px; padding: 4px; overflow: hidden; cursor: default;
  /* Not --ad-border: at 1px x 35 cells it reads as ~1.3:1 against the card in both
     themes, which is what made the grid look borderless. A dedicated, stronger tone
     keeps the cells legible as cells without turning the month into a heavy table.
     The fallback matters — an undefined custom property invalidates the whole
     shorthand, dropping the cell back to a 3px currentColor border. */
  border: 1px solid var(--cal-cell-border, var(--ad-border));
  border-radius: 8px;
  background: var(--ad-bg-input);
  /* Only the colours animate — `all` would also animate padding/min-height and make a
     36-cell re-render visibly reflow. */
  transition: background-color .15s ease, border-color .15s ease;
}
.cal-empty { border: none; background: transparent; }
/* Admins can click an empty day to add an event — only then does the cell act clickable. */
.cal-grid--editable .cal-cell:not(.cal-empty) { cursor: pointer; }
.cal-grid--editable .cal-cell:not(.cal-empty):hover {
  background: var(--ad-bg-card-hover);
  border-color: var(--ad-accent-1);
}
.cal-today {
  outline: 2px solid var(--ad-accent-1);
  outline-offset: -1px;
  border-color: transparent;
}
/* --ad-text-muted is only ~2.3:1 on the light card — too weak for the date itself
   and for the "+N more" affordance, both of which are real information. */
.cal-daynum { font-size: .75rem; color: var(--ad-text-secondary); margin-bottom: 2px; font-weight: 600; }
.cal-today .cal-daynum { color: var(--ad-accent-1); }
.cal-more { font-size: .68rem; color: var(--ad-text-secondary); padding-left: 2px; }

/* Event chips (month grid), legend swatches and agenda kind badges all share one
   look, so a colour means the same thing wherever it appears. */
.cal-chip {
  display: block; font-size: .68rem; border-radius: 4px; padding: 1px 4px; margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
  border: 1px solid transparent; font-weight: 600;
}
.cal-tag {
  display: inline-block; font-size: .72rem; border-radius: 6px; padding: 2px 8px;
  border: 1px solid transparent; font-weight: 600; white-space: nowrap;
}
/* --cal-rgb drives the tint; the text colour is set per theme for contrast on it. */
.cal-chip, .cal-tag {
  background: rgba(var(--cal-rgb), .18);
  border-color: rgba(var(--cal-rgb), .34);
  color: var(--cal-fg);
}
.cal-kind-danger    { --cal-rgb: 239, 68, 68;   --cal-fg: #fca5a5; }
.cal-kind-warning   { --cal-rgb: 245, 158, 11;  --cal-fg: #fcd34d; }
.cal-kind-primary   { --cal-rgb: 6, 182, 212;   --cal-fg: #67e8f9; }
.cal-kind-success   { --cal-rgb: 16, 185, 129;  --cal-fg: #6ee7b7; }
.cal-kind-info      { --cal-rgb: 59, 130, 246;  --cal-fg: #93c5fd; }
.cal-kind-secondary { --cal-rgb: 139, 92, 246;  --cal-fg: #c4b5fd; }
.cal-kind-dark      { --cal-rgb: 100, 116, 139; --cal-fg: #cbd5e1; }
/* Light theme: same hues, but the pale tint needs dark ink on it. */
[data-theme="light"] .cal-chip, [data-theme="light"] .cal-tag { background: rgba(var(--cal-rgb), .14); }
[data-theme="light"] .cal-kind-danger    { --cal-fg: #b91c1c; }
[data-theme="light"] .cal-kind-warning   { --cal-fg: #854d0e; }
[data-theme="light"] .cal-kind-primary   { --cal-fg: #0b5c72; }
[data-theme="light"] .cal-kind-success   { --cal-fg: #03614a; }
[data-theme="light"] .cal-kind-info      { --cal-fg: #1d4ed8; }
[data-theme="light"] .cal-kind-secondary { --cal-fg: #6d28d9; }
[data-theme="light"] .cal-kind-dark      { --cal-fg: #475569; }

@media (max-width: 640px) {
  .cal-cell { min-height: 64px; }
  .cal-chip { font-size: .6rem; }
}
@media (prefers-reduced-motion: reduce) {
  .cal-cell { transition: none; }
}

/* ── Modal close button ───────────────────────────────────────────────────────────
   Bootstrap's .btn-close is a black SVG that only lightens under `data-bs-theme="dark"`,
   which this panel never sets — so every modal X (including the calendar's New/Edit
   event dialog) was a black glyph at 0.5 opacity on a #0f1623 header. Invert for the
   dark default; light mode keeps Bootstrap's own black. */
.btn-close { filter: invert(1) grayscale(100%) brightness(200%); }
[data-theme="light"] .btn-close { filter: none; }

/* ── Light-theme alert text ───────────────────────────────────────────────────────
   The .alert-* overrides above were written for the dark theme and hard-code pale
   ink (#fca5a5 / #fcd34d / #67e8f9 / #6ee7b7). Over the same 10%-opacity tint on a
   white card that lands around 1.6:1 — the calendar's save errors and its
   "No institution selected" warning were effectively invisible in light mode.
   Dark mode is untouched; this only supplies readable ink for light. */
[data-theme="light"] .alert-danger  { color: #b42318 !important; }
[data-theme="light"] .alert-warning { color: #93540a !important; }
[data-theme="light"] .alert-info    { color: #0e7490 !important; }
[data-theme="light"] .alert-success { color: #046c4e !important; }

/* ── V294 Teacher & Department performance (Overview widget, drawers, Users column) ──────
   Five bands + one muted tone for NEW / INSUFFICIENT_DATA. Colours are explicit (the panel
   never sets data-bs-theme, so Bootstrap's *-subtle utilities are frozen light); the light
   theme only darkens the chip ink so it stays readable over a white card. */
.perf-band-excellent { --perf-color: #16a34a; --perf-ink: #22c55e; --perf-bg: rgba(22,163,74,.14); }
.perf-band-good      { --perf-color: #0ea5e9; --perf-ink: #38bdf8; --perf-bg: rgba(14,165,233,.14); }
.perf-band-attention { --perf-color: #f59e0b; --perf-ink: #fbbf24; --perf-bg: rgba(245,158,11,.14); }
.perf-band-weak      { --perf-color: #f97316; --perf-ink: #fb923c; --perf-bg: rgba(249,115,22,.14); }
.perf-band-critical  { --perf-color: #ef4444; --perf-ink: #f87171; --perf-bg: rgba(239,68,68,.14); }
.perf-band-muted     { --perf-color: #94a3b8; --perf-ink: #94a3b8; --perf-bg: rgba(148,163,184,.14); }
[data-theme="light"] .perf-band-excellent { --perf-ink: #15803d; }
[data-theme="light"] .perf-band-good      { --perf-ink: #0369a1; }
[data-theme="light"] .perf-band-attention { --perf-ink: #b45309; }
[data-theme="light"] .perf-band-weak      { --perf-ink: #c2410c; }
[data-theme="light"] .perf-band-critical  { --perf-ink: #b91c1c; }
[data-theme="light"] .perf-band-muted     { --perf-ink: #64748b; }
.perf-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--perf-color, #94a3b8); vertical-align: middle; flex: none; box-shadow: 0 0 0 2px var(--perf-bg, rgba(148,163,184,.14)); }
.perf-cell { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.perf-cell .perf-status { font-weight: 500; }
.perf-chip { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 999px; font-size: .72rem; font-weight: 600; line-height: 1.5; white-space: nowrap; background: var(--perf-bg, rgba(148,163,184,.14)); color: var(--perf-ink, #94a3b8); border: 1px solid transparent; }
button.perf-chip { cursor: pointer; transition: transform .12s ease, box-shadow .12s ease; }
button.perf-chip:hover { transform: translateY(-1px); }
button.perf-chip.active { border-color: var(--perf-color); box-shadow: 0 0 0 2px var(--perf-bg); }
.perf-score-big { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.perf-na td { opacity: .6; }
.perf-history { display: flex; align-items: flex-end; gap: 4px; }
.perf-hist-col { flex: 1 1 0; min-width: 0; text-align: center; }
.perf-hist-area { height: 56px; display: flex; align-items: flex-end; border-bottom: 1px solid var(--ad-border-light); }
.perf-hist-bar { width: 100%; min-height: 3px; border-radius: 3px 3px 0 0; background: var(--perf-color, #94a3b8); }
.perf-hist-lbl { font-size: .62rem; color: var(--ad-text-secondary); margin-top: 2px; white-space: nowrap; }
.perf-drawer-body .table { --bs-table-color: inherit; }
.perf-drawer-body .table td, .perf-drawer-body .table th { border-color: var(--ad-border-light); }
.perf-section-title { text-transform: uppercase; font-size: .72rem; letter-spacing: .5px; margin-bottom: .25rem; }
.perf-config-row td { vertical-align: middle; }
.perf-config-row .form-control { min-width: 72px; }
.perf-total-bad { color: #f87171; font-weight: 700; }
[data-theme="light"] .perf-total-bad { color: #b91c1c; }

/* Performance drawer: evidence counters collapse under each component (V294) */
.perf-evidence { max-width: 22rem; }
.perf-evidence-toggle { cursor: pointer; color: var(--ad-text-muted); font-size: .78rem; letter-spacing: .04em; text-transform: uppercase; list-style: none; }
.perf-evidence-toggle::-webkit-details-marker { display: none; }
.perf-evidence-toggle::before { content: '▸ '; }
.perf-evidence[open] > .perf-evidence-toggle::before { content: '▾ '; }


/* ── qx-combo: one box that is both the search field and the dropdown ────────
   Replaces the orphan filter box enhanceLongSelect() injected ABOVE each long
   <select>. Dark is the unqualified default here, as everywhere in this file;
   light overrides live under [data-theme="light"]. Only --ad-* tokens: this
   stylesheet is the only one dashboard.html loads, so --qx-* would be undefined,
   and --ad-accent (no suffix) does not exist -- use --ad-accent-1. */
.qxc {
  --qxc-css: 1;                 /* stale-stylesheet sentinel, read by qx-combo.js */
  position: relative;
  display: inline-flex;
  flex-direction: column;
  min-width: 0;
}

/* The native select stays in the DOM (it IS the value) but is visually removed.
   Clipping -- not display:none -- so form.reset(), .value, .options and every
   cached node reference behave exactly as they always did. */
.qxc-native {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* .form-control gives the input the same bg/border/radius/height/focus-ring as
   the .form-select it replaced. The ONLY delta is the caret gutter, which
   .form-select-sm reserved at 2rem; we reserve 3.4rem for caret + clear. */
.qxc-input {
  width: 100%;
  padding-right: 3.4rem !important;
  text-overflow: ellipsis;
}
.qxc-input[aria-expanded="true"] {
  border-color: var(--ad-accent-1) !important;
  box-shadow: 0 0 0 3.5px rgba(6, 182, 212, 0.2) !important;
}
.qxc-caret {
  position: absolute; right: 0.6rem; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--ad-text-muted); font-size: 0.7rem;
}
.qxc-clear {
  position: absolute; right: 1.75rem; top: 50%; transform: translateY(-50%);
  border: 0; background: transparent; color: var(--ad-text-muted);
  line-height: 1; padding: 0 0.2rem; font-size: 0.8rem; cursor: pointer;
}
.qxc-clear:hover { color: var(--ad-text-primary); }
.qxc[data-qxc-empty="1"] .qxc-clear { display: none; }
/* ...so while the field is empty the 3.4rem above reserves room for a control that is not
   there, and clips the RESTING PLACEHOLDER -- the one string that is only ever visible when
   the field is empty -- by ~14px more than the .form-select this replaced ever did. 2.25rem is
   .form-select's own gutter, which is the width the placeholder copy was written against.
   Specificity (0,3,0) beats the .qxc-input rule above wherever it sits in the file. */
.qxc[data-qxc-empty="1"] .qxc-input { padding-right: 2.25rem !important; }
.qxc--disabled .qxc-caret, .qxc--disabled .qxc-clear { opacity: 0.5; }
/* Visually-hidden live region for the row-count announcements. */
.qxc-status {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* One popup node, appended to <body>, position:fixed. It is a descendant of
   neither .qx-card (overflow:hidden + backdrop-filter stacking context) nor
   .modal, so it needs neither the :has(.dropdown-menu.show) escape hatch nor a
   position:relative parent fixup. 1085 clears .modal (1055) and sits under
   .toast-container (1090). */
/* `type=search` (see qx-combo.js — it is what keeps Chrome's password manager off the field)
   brings a native clear button and a decoration box with it. Ours sits at 1.75rem from the right
   already, so the native one would double up inside the caret gutter. */
.qxc-input::-webkit-search-cancel-button,
.qxc-input::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

.qxc-pop {
  position: fixed; z-index: 1085; min-width: 180px;
  /* Roomier than the original 320px: these lists run to a couple of dozen classes and every row
     that fits is a row nobody has to scroll to. */
  max-height: min(420px, 60vh); overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--ad-border-light) transparent;
  background: var(--ad-bg-secondary);   /* opaque in BOTH themes: #0f1623 / #ffffff */
  border: 1px solid var(--ad-border);
  border-radius: var(--ad-radius-sm, 10px);
  box-shadow: var(--ad-shadow-lg);
  padding: 0.25rem;
}
.qxc-pop[hidden] { display: none !important; }
/* An always-visible track, rather than the overlay scrollbar that only appears once you are
   already scrolling: the list has to LOOK scrollable before anyone tries. */
.qxc-pop::-webkit-scrollbar { width: 10px; }
.qxc-pop::-webkit-scrollbar-track { background: transparent; }
.qxc-pop::-webkit-scrollbar-thumb {
  background: var(--ad-border-light);
  border-radius: 6px;
  border: 3px solid transparent;
  background-clip: content-box;
}
.qxc-pop::-webkit-scrollbar-thumb:hover { background: var(--ad-text-muted); background-clip: content-box; }

/* Deliberately NOT .list-group-item: the panel kills its hover/active feedback
   with three !important declarations. */
.qxc-opt {
  display: block; padding: 0.35rem 0.55rem; border-radius: 6px;
  color: var(--ad-text-primary); font-size: 0.82rem; line-height: 1.3;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.qxc-opt:hover, .qxc-opt:active, .qxc-opt.qxc-active { background: var(--ad-bg-card-hover); }
/* Not colour alone -- a sticky :hover after a tap must stay distinguishable. */
.qxc-opt.qxc-active { box-shadow: inset 3px 0 0 0 var(--ad-accent-1); }
.qxc-opt[aria-selected="true"] { font-weight: 600; color: var(--ad-accent-3); }
.qxc-opt[aria-disabled="true"] { opacity: 0.5; cursor: default; }
.qxc-opt mark { background: transparent; color: var(--ad-accent-1); font-weight: 600; padding: 0; }
.qxc-sub { display: block; color: var(--ad-text-secondary); font-size: 0.75rem; }
.qxc-group {
  padding: 0.3rem 0.55rem 0.15rem; color: var(--ad-text-muted);
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em;
}
.qxc-sep, .qxc-foot, .qxc-empty {
  color: var(--ad-text-muted); font-size: 0.72rem; padding: 0.35rem 0.55rem;
}
.qxc-sep { margin-top: 0.25rem; border-top: 1px solid var(--ad-border-light); }
.qxc-retry { color: var(--ad-accent-1); cursor: pointer; text-decoration: underline; }

/* .qx-card:hover applies transform: translateY(-2px) with no scroll/resize event
   to hook, which would drift a fixed popup by 2px. Suppress the lift only while
   one is open. */
body.qxc-open .qx-card:hover { transform: none !important; }

/* .results-filter-fields > select stops matching once the select is a grandchild.
   BOTH selectors are required: #resultsFilterTeacher lives inside
   #resultsFilterTeacherWrap. */
.results-filter-fields > .qxc,
.results-filter-fields > div:not(.results-filter-date-group) > .qxc {
  min-width: 120px; max-width: 170px; flex: 1 1 120px;
}

/* On a phone an anchored ~160px list, opened from a control near the top of the
   viewport with the soft keyboard eating the bottom 40%, has room for two rows.
   Become a bottom sheet instead. */
@media (max-width: 767.98px) and (pointer: coarse) {
  .qxc-pop.qxc-pop--sheet {
    left: 8px !important; right: 8px !important; bottom: 0 !important;
    top: auto !important; width: auto !important;
    max-height: 60vh; border-radius: 14px 14px 0 0; padding: 0.5rem 0.25rem;
  }
}

/* Mobile overrides live HERE, after the .qxc base rules above -- not in the earlier
   `@media (max-width: 767.98px)` block, which precedes them in source order and would lose
   every equal-specificity tie. */
@media (max-width: 767.98px) {
  .results-filter-fields > .qxc {
    min-width: 0;
    max-width: none;
    flex: 1 1 calc(50% - 0.25rem);
  }
  /* The teacher filter is wrapped in #resultsFilterTeacherWrap, so the WRAPPER is the flex item.
     Sizing the inner .qxc instead would resolve 50% against the wrapper rather than the filter
     bar, and the field would claim a whole row of its own. */
  .results-filter-fields > div:not(.results-filter-date-group):has(> .qxc) {
    flex: 1 1 calc(50% - 0.25rem);
    min-width: 0;
  }
  .results-filter-fields > div:not(.results-filter-date-group) > .qxc {
    min-width: 0;
    max-width: none;
    width: 100%;
    flex: 1 1 auto;
  }
  .qxc-input { font-size: 16px; }        /* iOS Safari zooms the page below 16px */
  .qxc-opt {
    padding: 0.6rem 0.55rem;             /* comfortable touch target */
    min-height: 44px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* A toolbar that is a single `d-flex gap-2` row of buttons overruns a phone. The Students roster
     bar measures 352px of space against 645px of content, and because both it and its parent are
     `overflow-x: visible` -- with no page-level horizontal scroll either -- Import CSV, Promote and
     Accommodations cannot be reached by any gesture at all. Wrapping beats `overflow-x: auto` here:
     a horizontally scrolling strip of buttons gives the operator no signal that anything is off to
     the right. Scoped to the toolbar so no other `d-flex` row is affected.
     Inside this @media block deliberately -- appended after it an equal-specificity rule would
     still win, but the next person editing this file would have no signal it is a mobile rule. */
  /* The toolbar itself AND the un-named `.d-flex gap-2` row that holds it beside Filters / Export /
     Refresh / Invite. Wrapping only the toolbar is not enough: measured at 375px the toolbar is a
     137px box sitting at left:295 because its PARENT is `flex-wrap: nowrap` and 390px wide inside a
     293px column, so the whole group is pushed off-screen before its own contents ever wrap.
     `:has()` reaches that parent without giving the markup an id — the same technique the
     `.results-filter-fields > div:has(> .qxc)` rule above already relies on. */
  #studentsOnboardingToolbar,
  #studentsOnboardingToolbar > .d-flex,
  .d-flex:has(> #studentsOnboardingToolbar) {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }
}

/* qx-combo inside a BOOTSTRAP GRID of `.col-*` columns -- Study Material's filter bar and its
   Add/Edit dialog row today, and any screen that adopts the class next. (The name says "filter"
   because the filter bar came first; the rule is about the GRID, not about filtering.)
   The Result Center's bar is a flex row, so its `.results-filter-fields > .qxc`
   rule above hands the wrapper a flex basis; a `.col-*` column hands it nothing, and `.qxc` is
   an `inline-flex` with no width of its own. Shrink-to-fit then resolves against the INPUT's
   intrinsic width -- which happens to land near the column width on a laptop, and stops growing
   at ~263px, so the field measurably under-fills its column from roughly 1750px of container
   width upward and the filter bar goes ragged next to the plain selects beside it. Sizing the
   WRAPPER, not the input inside it, is the fix: the input is already width:100%.

   Last in the file deliberately -- after the mobile @media blocks above, so no equal-specificity
   tie can be lost to a later rule. */
.qx-filter-grid .qxc {
  display: flex;
  width: 100%;
}

/* qx-combo inside the compact `.qx-filter-bar` (Quizzes, Scheduled Quiz Tracker, Question Bank,
   Predefined Quizzes). Same failure as the grid case above, in a flex bar: `.qx-filter-field` is a
   block box, so the inline-flex `.qxc` sized itself to its input instead of filling the field —
   Class 12's auto-converted Subject box sat narrower than the native selects beside it. Size the
   WRAPPER. */
.qx-filter-field > .qxc {
  display: flex;
  width: 100%;
}
/* `.qx-filter-field .form-control` (0,2,0) sets `padding: .38rem .65rem !important`, which beat
   `.qxc-input { padding-right: 3.4rem !important }` (0,1,0) — so once a value was chosen, its label
   ran under the clear X and the caret. Equal specificity and later in the file, so this wins; the
   empty-state `.qxc[data-qxc-empty="1"] .qxc-input` (0,3,0) still wins while the field is blank. */
.qx-filter-field .qxc-input {
  padding-right: 3.4rem !important;
}
/* A disabled filter has to LOOK disabled: the panel forces background and colour with !important on
   every control, which also flattened Bootstrap's :disabled grey, so Subject/Chapter before a class
   was picked read exactly like live fields. */
.qx-filter-field .form-select:disabled,
.qx-filter-field .qxc--disabled .qxc-input {
  opacity: 0.55;
  cursor: not-allowed;
}
/* iOS Safari zooms the page when a focused input is under 16px; `.qx-filter-field .form-control`'s
   .8rem !important out-ranks the base `.qxc-input { font-size: 16px }` phone rule above. */
@media (max-width: 767.98px) {
  .qx-filter-field .qxc-input { font-size: 16px !important; }
}
/* A fixed-width slot in a `d-flex flex-wrap` picker row (the Predefined Quiz question picker) for a
   select whose labels end in a qualifier ("Physics — MSBSHSE"). The width lives on the slot, not the
   select: once qx-combo claims a long list it moves the select into a .qxc wrapper and clips it to
   1px, so a max-width on the select sized nothing visible. Both states fill the slot. */
.qx-picker-slot--wide {
  flex: 0 1 290px;
  min-width: 0;
  max-width: 300px;
}
.qx-picker-slot--wide > .form-select { width: 100%; }
.qx-picker-slot--wide > .qxc { display: flex; width: 100%; }

/* ── qx-form-dialog: the "button opens the form in a dialog" overlay (modules/qx-form-dialog.js) ──
   The dialog is rendered IN PLACE inside the module that owns it (so its delegated listeners and
   scoped field reads keep working) and presented as a fixed full-viewport layer. It reuses
   Bootstrap's .modal-dialog/.modal-content/.modal-header/.modal-body/.modal-footer, which read
   their sizes from --bs-modal-* variables that Bootstrap only declares on `.modal` — so the root
   declares them itself (values copied from Bootstrap 5.3.3's .modal). The root deliberately does
   NOT carry the `.modal` class: Bootstrap's JS and a few panel sweeps act on `.modal` nodes.
   z-index 1045: above the topbar (900) and sidebar (1000), below Bootstrap's backdrop (1050) and
   modal (1055), so a confirmAction opened from the form paints over it; toasts (2000) and the
   qx-combo popup (1085) stay on top. */
.qx-fd {
  --bs-modal-zindex: 1045;
  --bs-modal-width: 500px;
  --bs-modal-padding: 1rem;
  --bs-modal-margin: 0.5rem;
  --bs-modal-color: var(--ad-text-primary);
  --bs-modal-bg: var(--ad-bg-secondary);
  --bs-modal-border-color: var(--ad-border);
  --bs-modal-border-width: var(--bs-border-width);
  --bs-modal-border-radius: var(--bs-border-radius-lg);
  --bs-modal-box-shadow: var(--bs-box-shadow-sm);
  --bs-modal-inner-border-radius: calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));
  --bs-modal-header-padding-x: 1rem;
  --bs-modal-header-padding-y: 1rem;
  --bs-modal-header-padding: 1rem 1.25rem;
  --bs-modal-header-border-color: var(--ad-border-light);
  --bs-modal-header-border-width: var(--bs-border-width);
  --bs-modal-title-line-height: 1.5;
  --bs-modal-footer-gap: 0.5rem;
  --bs-modal-footer-border-color: var(--ad-border-light);
  --bs-modal-footer-border-width: var(--bs-border-width);
  position: fixed;
  inset: 0;
  z-index: 1045;
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  outline: 0;
  pointer-events: auto;
  text-align: left;
  background: rgba(2, 6, 23, 0.58);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: qx-fd-fade .15s ease-out;
}
.qx-fd[hidden] { display: none !important; }
@media (min-width: 576px) {
  .qx-fd { --bs-modal-margin: 1.75rem; --bs-modal-box-shadow: var(--bs-box-shadow); }
}
@keyframes qx-fd-fade { from { opacity: 0; } to { opacity: 1; } }
.qx-fd .modal-content { box-shadow: var(--ad-shadow-lg); }
.qx-fd .modal-header { align-items: flex-start; }
.qx-fd .modal-title { font-size: 1.05rem; font-weight: 700; }
.qx-fd .modal-body { padding: 1.1rem 1.25rem; }
.qx-fd .modal-footer { padding: 0.65rem 1.25rem; }
/* The page no longer scrolls behind an open dialog. A class, not an inline style, so Bootstrap's
   own scrollbar helper (which saves/restores body's inline overflow around a confirm dialog)
   can never capture or restore it by mistake. */
body.qx-fd-open { overflow: hidden !important; }
/* Every ancestor of an OPEN dialog. Each of these properties makes an element the containing
   block of position:fixed descendants (or a stacking context that traps the dialog's z-index):
   `.qx-card` alone has backdrop-filter AND a hover transform, and the .ad-slide-up entrance
   animation leaves `transform: translateY(0)` behind. With any of them live, the "full-viewport"
   overlay would be positioned against — and clipped to — the card it was rendered in. !important
   also out-ranks CSS animations (without cancelling them — `animation: none` here would replay
   every entrance animation on the page the moment the dialog closed). The class exists only while
   a dialog is open. */
.qx-fd-anc {
  transform: none !important;
  filter: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  perspective: none !important;
  contain: none !important;
  will-change: auto !important;
  z-index: auto !important;
  opacity: 1 !important;
  isolation: auto !important;
  mix-blend-mode: normal !important;
  clip-path: none !important;
  mask: none !important;
}

/* ══════════════════════════════════════════════════════════════
   Board Results, layout 2 (2026-09-27) — `.qx-ra-*`
   The tab was seven peer pills over an event picker that came and went. Layout 2 is a
   context bar that is ALWAYS there (the exam picker, or "every exam" on the two registers),
   a strip grouped into "This exam" / "Whole college" with the two ingest steps hidden until
   they are the active step, an Overview with a four-step progress card, and a Results status
   bar with one "Load results" menu. Base rules first, this component's own @media LAST —
   never inside an earlier media block (later base rules would win over it).
   ══════════════════════════════════════════════════════════════ */
.qx-ra-nav { align-items: center; row-gap: .5rem !important; }
.qx-ra-nav .qx-ra-nav-group {
  display: inline-flex; align-items: center;
  font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ad-text-muted); padding: 0 .15rem 0 .1rem; user-select: none;
}
/* A group label after the first one gets a hairline to read as a second group. */
.qx-ra-nav .qx-ra-nav-group + .nav-item { margin-left: 0; }
.qx-ra-nav .qx-ra-nav-group:not(:first-child) {
  margin-left: .55rem; padding-left: .8rem; border-left: 1px solid var(--ad-border);
}
/* Step pills are hidden by the module until that step is on screen; the attribute is the
   contract so an older module that never sets it shows them like any other pill. */
.qx-ra-nav .qx-ra-step[hidden] { display: none !important; }
.qx-ra-nav .qx-ra-step .nav-link { border: 1px dashed var(--ad-border); }
.qx-ra-nav .qx-ra-step .nav-link.active { border-style: solid; }

/* Context bar: one line, never jumps. */
.qx-ra-ctx { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.qx-ra-ctx .qx-ra-ctx-label { font-size: .8rem; color: var(--ad-text-secondary); white-space: nowrap; }
.qx-ra-ctx .qx-ra-ctx-select { flex: 1 1 260px; max-width: 520px; min-width: 200px; }
.qx-ra-ctx .qx-ra-ctx-actions { display: flex; align-items: center; gap: .5rem; margin-left: auto; }
.qx-ra-ctx .qx-ra-ctx-scope { display: inline-flex; align-items: center; gap: .5rem; color: var(--ad-text-secondary); font-size: .9rem; }

/* Overview: the four-step progress card. */
.qx-ra-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .75rem; }
.qx-ra-step-card {
  display: flex; flex-direction: column; gap: .5rem; min-width: 0;
  padding: .85rem .9rem; border-radius: var(--ad-radius); border: 1px solid var(--ad-border);
  background-color: var(--ad-bg-input);
}
.qx-ra-step-card .qx-ra-step-head { display: flex; align-items: center; gap: .55rem; }
.qx-ra-step-card .qx-ra-step-n {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; border: 1px solid var(--ad-border); color: var(--ad-text-secondary);
}
.qx-ra-step-card .qx-ra-step-title { font-weight: 600; line-height: 1.2; }
.qx-ra-step-card .qx-ra-step-body { font-size: .82rem; color: var(--ad-text-secondary); min-height: 2.2em; }
.qx-ra-step-card .qx-ra-step-act { margin-top: auto; }
.qx-ra-step-card .qx-ra-step-act .btn { white-space: nowrap; }
.qx-ra-step-card.is-done { border-color: rgba(16,185,129,.45); }
.qx-ra-step-card.is-done .qx-ra-step-n { background-color: rgba(16,185,129,.16); border-color: rgba(16,185,129,.5); color: #34d399; }
.qx-ra-step-card.is-current { border-color: rgba(6,182,212,.55); box-shadow: 0 0 0 1px rgba(6,182,212,.25) inset; }
.qx-ra-step-card.is-current .qx-ra-step-n { background: var(--ad-grad-primary); border-color: transparent; color: #04121a; }
.qx-ra-step-card.is-attention { border-color: rgba(245,158,11,.5); }
.qx-ra-step-card.is-attention .qx-ra-step-n { background-color: rgba(245,158,11,.16); border-color: rgba(245,158,11,.5); color: #fbbf24; }
.qx-ra-step-card.is-todo { opacity: .78; }
[data-theme="light"] .qx-ra-step-card.is-done .qx-ra-step-n { color: #047857; }
[data-theme="light"] .qx-ra-step-card.is-attention .qx-ra-step-n { color: #b45309; }

/* Overview: the exams table. The selected exam is the one every other tab works on. */
.qx-ra-exams tr.is-selected td { background-color: rgba(6,182,212,.08); }
.qx-ra-exams .qx-ra-row-actions { white-space: nowrap; }
.qx-ra-exams .qx-ra-row-actions .btn + .btn { margin-left: .25rem; }

/* Results: status bar + compact table. */
.qx-ra-status { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.qx-ra-status .qx-ra-status-chips { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.qx-ra-status .qx-ra-status-chips .badge { font-weight: 600; }
.qx-ra-status .qx-ra-status-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-left: auto; }
.qx-ra-load-menu { min-width: 300px; }
.qx-ra-load-menu .dropdown-item { white-space: normal; padding: .55rem .9rem; }
.qx-ra-load-menu .dropdown-item strong { display: block; }
.qx-ra-results-table th, .qx-ra-results-table td { vertical-align: middle; }
.qx-ra-results-table .qx-ra-sub { display: block; font-size: .78rem; color: var(--ad-text-secondary); }
.qx-ra-results-table .qx-ra-row-actions { white-space: nowrap; text-align: right; }
.qx-ra-results-table .qx-ra-row-actions .btn + .btn { margin-left: .25rem; }
.qx-ra-empty { text-align: center; padding: 2.2rem 1rem; }
.qx-ra-empty .bi { font-size: 2.2rem; color: var(--ad-text-muted); }
.qx-ra-empty .qx-ra-empty-title { font-weight: 600; margin-top: .5rem; }
.qx-ra-empty .qx-ra-empty-actions { margin-top: .9rem; display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }

/* A result not yet linked to a student: `table-warning-subtle` was in the markup for months with
   no rule behind it, so the intended row tint never painted. */
.qx-ra-results-table tr.table-warning-subtle > td { background-color: rgba(245,158,11,.07); }

/* Plain-language help, folded away. */
.qx-ra-help > summary { cursor: pointer; font-size: .82rem; color: var(--ad-text-secondary); }
.qx-ra-help[open] > summary { margin-bottom: .4rem; }

@media (max-width: 991.98px) {
  .qx-ra-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767.98px) {
  .qx-ra-nav .qx-ra-nav-group:not(:first-child) { margin-left: 0; padding-left: 0; border-left: 0; flex-basis: 100%; }
  .qx-ra-nav .qx-ra-nav-group { flex-basis: 100%; }
  .qx-ra-ctx .qx-ra-ctx-select { max-width: none; }
  .qx-ra-ctx .qx-ra-ctx-actions { margin-left: 0; width: 100%; }
  .qx-ra-steps { grid-template-columns: 1fr; }
  .qx-ra-status .qx-ra-status-actions { margin-left: 0; width: 100%; }
  .qx-ra-load-menu { min-width: 260px; }
}

/* ══════════════════════════════════════════════════════════════
   Settings sub-tabs (2026-09-27) — #settingsSubNav
   Settings is one sidebar item whose screen is up to nine sub-tabs (Institution, Modules, Feature
   access, Academic year, Campus rules, Notifications, Early warning, Performance, Audit log). On a
   phone the ordinary wrapping pill row fits one or two per line — seven rows, measured at 375px —
   and pushes the section itself below the fold. A two-column grid holds them to five rows and
   still wraps (no sideways-scrolling strip that hides tabs off to the right). Gated pills are
   `hidden` / display:none, so they drop out of the grid and leave no gap. Mobile-only, and its own
   @media block at the end of the file, after nothing it needs to beat.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 575.98px) {
  #settingsSubNav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .375rem !important; }
  #settingsSubNav > .nav-item { min-width: 0; }
  #settingsSubNav .nav-link {
    width: 100%; text-align: left; font-size: .85rem;
    padding: .45rem .6rem !important;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}

/* PANEL-38: #csGeneralMount ships a "Loading settings…" skeleton. Its failure hint is for the case
   where campus-settings.js never ran at all (when it runs, its own 15 s watchdog takes over), so it
   stays invisible until the pane has been SHOWN for 15 s: an animation does not run under
   display:none. Only `visibility` is animated — no opacity/transform, so no stacking context. */
.cs-load-stalled { visibility: hidden; animation: cs-load-stalled-reveal 0s linear 15s forwards; }
@keyframes cs-load-stalled-reveal { to { visibility: visible; } }

/* ══════════════════════════════════════════════════════════════
   Settings › Initial setup (2026-09-27) — campus-initial-setup.js + setup/steps-*.js
   One step at a time: a header with the progress bar and the section chips, then one card with
   the current step, then Back / Skip for now / Save & Continue. Everything is namespaced
   .qx-setup-* and its phone rules sit in their own @media block at the end, after nothing they
   need to beat (an earlier @media block loses to rules appended after it).
   ══════════════════════════════════════════════════════════════ */
.qx-setup-progress { height: 8px; border-radius: 999px; background-color: var(--ad-bg-input); border: 1px solid var(--ad-border-light); overflow: hidden; }
.qx-setup-progress-bar { height: 100%; background: var(--ad-grad-primary); border-radius: 999px; transition: width .35s ease; }

.qx-setup-hero h2 { color: var(--ad-text-heading); }
.qx-setup-hero h2:focus { outline: none; } /* focused by script after Save & exit, like the step title */
.qx-setup-hero-icon, .qx-setup-done-icon { font-size: 2.4rem; color: var(--ad-accent-2); line-height: 1; }
.qx-setup-done-icon { font-size: 3.2rem; }

.qx-setup-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: .75rem 1.25rem; margin: 0; }
.qx-setup-summary > div { min-width: 0; }
.qx-setup-summary dt { font-size: .75rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--ad-text-muted); }
.qx-setup-summary dd { margin: .15rem 0 0; color: var(--ad-text-primary); overflow-wrap: anywhere; }

.qx-setup-chips, .qx-setup-sections-preview { display: flex; flex-wrap: wrap; gap: .4rem; }
.qx-setup-chip {
  display: inline-flex; align-items: center; gap: .35rem; padding: .28rem .65rem; border-radius: 999px;
  font-size: .8rem; line-height: 1.2; border: 1px solid var(--ad-border); background-color: var(--ad-bg-input);
  color: var(--ad-text-secondary); white-space: nowrap;
}
button.qx-setup-chip { cursor: pointer; }
button.qx-setup-chip:hover { border-color: var(--ad-accent-1); color: var(--ad-text-primary); }
button.qx-setup-chip:focus-visible { outline: 2px solid var(--ad-accent-1); outline-offset: 2px; }
.qx-setup-chip.is-done { color: var(--ad-accent-3); border-color: rgba(16,185,129,.45); }
.qx-setup-chip.is-partial { color: var(--ad-accent-1); border-color: rgba(6,182,212,.4); }
.qx-setup-chip.is-skipped { opacity: .75; }
.qx-setup-chip.is-current { background: var(--ad-grad-primary); color: #04121a; border-color: transparent; font-weight: 600; }
[data-theme="light"] .qx-setup-chip.is-done { color: #047857; }
[data-theme="light"] .qx-setup-chip.is-partial { color: #0e7490; }

.qx-setup-all > summary { cursor: pointer; font-size: .82rem; color: var(--ad-text-secondary); display: inline-block; }
.qx-setup-all[open] > summary { margin-bottom: .4rem; }
.qx-setup-steplist { list-style: none; margin: 0; padding: 0; columns: 2 260px; column-gap: 1.25rem; }
.qx-setup-steplist > li { break-inside: avoid; }
.qx-setup-steplink {
  display: flex; align-items: center; gap: .45rem; width: 100%; text-align: left; background: none; border: 0;
  padding: .3rem .35rem; border-radius: var(--ad-radius-sm); color: var(--ad-text-primary); font-size: .88rem;
}
.qx-setup-steplink:hover { background-color: var(--ad-bg-input); }
.qx-setup-steplink:focus-visible { outline: 2px solid var(--ad-accent-1); outline-offset: 1px; }
.qx-setup-steplink.is-current { background-color: rgba(6,182,212,.12); font-weight: 600; }

.qx-setup-step h3 { color: var(--ad-text-heading); }
.qx-setup-step h3:focus { outline: none; }
.qx-setup-badge { font-weight: 600; font-size: .72rem; border: 1px solid transparent; }
.qx-setup-badge-req { background-color: rgba(239,68,68,.14); color: #f87171; border-color: rgba(239,68,68,.35); }
.qx-setup-badge-opt { background-color: var(--ad-bg-input); color: var(--ad-text-secondary); border-color: var(--ad-border); }
.qx-setup-badge-done { background-color: rgba(16,185,129,.16); color: #34d399; border-color: rgba(16,185,129,.4); }
.qx-setup-badge-skipped { background-color: var(--ad-bg-input); color: var(--ad-text-secondary); border-color: var(--ad-border); }
.qx-setup-badge-blocked { background-color: rgba(245,158,11,.14); color: #fbbf24; border-color: rgba(245,158,11,.4); }
.qx-setup-badge-muted { background-color: var(--ad-bg-input); color: var(--ad-text-muted); border-color: var(--ad-border); }
[data-theme="light"] .qx-setup-badge-req { color: #b91c1c; }
[data-theme="light"] .qx-setup-badge-done { color: #047857; }
[data-theme="light"] .qx-setup-badge-blocked { color: #b45309; }

.qx-setup-why { font-weight: 600; color: var(--ad-text-secondary); }
.qx-setup-detail { color: var(--ad-text-secondary); }
.qx-setup-later {
  font-size: .85rem; padding: .5rem .75rem; border-radius: var(--ad-radius-sm);
  background-color: rgba(59,130,246,.10); border: 1px solid rgba(59,130,246,.28); color: var(--ad-text-primary);
}

.qx-setup-hint {
  display: inline-flex; align-items: center; justify-content: center; width: 1.35rem; height: 1.35rem;
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ad-accent-1);
  vertical-align: middle; cursor: pointer; font-size: .92rem; line-height: 1;
}
.qx-setup-hint:hover { background-color: rgba(6,182,212,.12); }
.qx-setup-hint:focus-visible { outline: 2px solid var(--ad-accent-1); outline-offset: 1px; }
.qx-setup-hint[aria-expanded="true"] { background-color: rgba(6,182,212,.18); }
/* The accent cyan is ~2.4:1 on white — below the 3:1 an icon-only control needs. */
[data-theme="light"] .qx-setup-hint { color: #0e7490; }
[data-theme="light"] .qx-setup-hint:focus-visible { outline-color: #0e7490; }
.qx-setup-hint-pop {
  display: block; margin: .35rem 0 .5rem; padding: .5rem .7rem; border-radius: var(--ad-radius-sm);
  font-size: .83rem; font-weight: 400; line-height: 1.45; text-transform: none; letter-spacing: normal;
  background-color: var(--ad-bg-secondary); border: 1px solid var(--ad-border); color: var(--ad-text-primary);
  box-shadow: var(--ad-shadow-sm);
}
.qx-setup-hint-pop[hidden] { display: none; }
.qx-setup-label { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem; }
.qx-setup-label .qx-setup-hint-pop { flex-basis: 100%; }
.qx-setup-opt {
  display: inline-block; font-size: .7rem; font-weight: 600; padding: .05rem .4rem; border-radius: 999px;
  color: var(--ad-text-muted); border: 1px solid var(--ad-border); line-height: 1.4; text-transform: none;
}

.qx-setup-body { min-height: 4rem; }
.qx-setup-body .form-control, .qx-setup-body .form-select { max-width: 100%; }
.qx-setup-empty { color: var(--ad-text-muted); font-size: .88rem; padding: .35rem 0; }
.qx-setup-list { list-style: none; margin: 0 0 .75rem; padding: 0; display: grid; gap: .35rem; }
.qx-setup-list > li {
  display: flex; align-items: center; gap: .55rem; padding: .45rem .65rem; border-radius: var(--ad-radius-sm);
  background-color: var(--ad-bg-input); border: 1px solid var(--ad-border-light); min-width: 0;
}
.qx-setup-list-ok { color: var(--ad-accent-2); flex: 0 0 auto; }
.qx-setup-list-main { display: flex; flex-direction: column; min-width: 0; }
.qx-setup-list-title { font-weight: 600; overflow-wrap: anywhere; }
.qx-setup-list-sub { font-size: .8rem; color: var(--ad-text-secondary); overflow-wrap: anywhere; }

/* A block inside a step: "What you already have", "Add", "Suggestions". */
.qx-setup-block { border: 1px solid var(--ad-border-light); border-radius: var(--ad-radius); padding: .9rem 1rem; margin-bottom: .9rem; background-color: rgba(0,0,0,.04); }
[data-theme="light"] .qx-setup-block { background-color: rgba(240,244,251,.5); }
.qx-setup-block > h4 { font-size: .9rem; font-weight: 600; margin: 0 0 .6rem; color: var(--ad-text-heading); }
.qx-setup-suggest { display: flex; flex-wrap: wrap; gap: .4rem; }
.qx-setup-suggest .btn { border-radius: 999px; }

/* Bulk entry grid: plain rows of inputs that stay usable on a phone (each row wraps). */
.qx-setup-grid { display: grid; gap: .45rem; }
.qx-setup-grid-row { display: grid; grid-template-columns: repeat(var(--qx-cols, 3), minmax(0, 1fr)) auto; gap: .4rem; align-items: start; }
.qx-setup-grid-head { font-size: .75rem; font-weight: 600; color: var(--ad-text-muted); text-transform: uppercase; letter-spacing: .03em; }
.qx-setup-grid-row .btn-row-remove { padding: .3rem .5rem; }
.qx-setup-rowmsg { grid-column: 1 / -1; font-size: .8rem; }

/* Institution type cards. */
.qx-setup-types { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .6rem; }
.qx-setup-type {
  position: relative; display: flex; gap: .6rem; align-items: flex-start; padding: .8rem .9rem; border-radius: var(--ad-radius);
  border: 1px solid var(--ad-border); background-color: var(--ad-bg-input); cursor: pointer; min-width: 0;
}
.qx-setup-type:hover { border-color: var(--ad-accent-1); }
.qx-setup-type input { margin-top: .2rem; flex: 0 0 auto; }
.qx-setup-type.is-selected { border-color: var(--ad-accent-1); box-shadow: 0 0 0 1px rgba(6,182,212,.35) inset; }
.qx-setup-type.is-disabled { opacity: .55; cursor: not-allowed; }
.qx-setup-type-title { font-weight: 600; }
.qx-setup-type-desc { font-size: .82rem; color: var(--ad-text-secondary); }

.qx-setup-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--ad-border-light); }

/* Review + post-setup checklist. */
.qx-setup-review { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: .9rem 1.25rem; }
.qx-setup-review-sec h4 { font-size: .85rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--ad-text-muted); margin-bottom: .35rem; }
.qx-setup-review-sec ul, .qx-setup-review-skipped ul { list-style: none; margin: 0; padding: 0; }
.qx-setup-review-row { display: flex; align-items: baseline; gap: .5rem; padding: .3rem 0; border-bottom: 1px dashed var(--ad-border-light); min-width: 0; }
.qx-setup-review-title { font-weight: 600; flex: 0 1 auto; min-width: 0; }
.qx-setup-review-val { color: var(--ad-text-secondary); font-size: .88rem; min-width: 0; overflow-wrap: anywhere; }
.qx-setup-check { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.qx-setup-check > li { display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap; }
.qx-setup-check > li.is-open .bi-circle { color: var(--ad-text-muted); }

@media (max-width: 767.98px) {
  .qx-setup-foot { flex-direction: column-reverse; align-items: stretch; }
  .qx-setup-foot > div { justify-content: stretch !important; }
  .qx-setup-foot .btn { width: 100%; }
  .qx-setup-foot > span:empty { display: none; }
  .qx-setup-chips { flex-wrap: nowrap; overflow-x: auto; padding-bottom: .25rem; scrollbar-width: thin; }
  .qx-setup-grid-row { grid-template-columns: 1fr auto; }
  .qx-setup-grid-row > :not(:last-child) { grid-column: 1 / 2; }
  .qx-setup-grid-row > :last-child { grid-column: 2 / 3; grid-row: 1 / span 1; }
  .qx-setup-grid-head { display: none; }
  .qx-setup-review { grid-template-columns: 1fr; }
  .qx-setup-review-row { flex-wrap: wrap; }
}
.qx-setup-body input[type="search"]::-webkit-search-cancel-button,
.qx-setup-body input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; display: none; }
