/* ═══════════════════════════════════════════════════════════════
   Makers and Leaders Lab Studio — v4.0 CSS
   Brand: Debiso Best | Google Material palette on a pure-white foundation
   Typography: rem-based scale on Inter (respects user zoom/font-size prefs)
   Icons: Google Material Symbols (Outlined), 3-tier sizing (16/24/32px)
   Depth: Material Design elevation shadows (1dp/3dp/6dp) — since surfaces
   are now pure white on white, shadows (not background-color steps) are
   what separates a container from the page behind it.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* Brand blue — Google's standard Material blue */
  --primary:       #1967D2;
  --primary-dark:  #185ABC;
  --primary-light: #4285F4;
  --primary-rgb:   25, 103, 210;
  --primary-tint:  #E8F0FE;

  /* Neutral surfaces — pure white foundation; --surface-2/-3 are reserved
     for functional fills (inputs, hover states) that would otherwise be
     invisible on white, never for a "page" or "card" background. */
  --bg:            #FFFFFF;
  --surface:       #FFFFFF;
  --surface-2:     #F1F3F4;
  --surface-3:     #E8EAED;
  --bg-elevated:   #F1F3F4;
  --border:        #DADCE0;
  --border-light:  #BDC1C6;
  --border-strong: #80868B;

  /* Text — pure black primary; one secondary gray for helper/meta text */
  --text-primary:  #000000;
  --text-muted:    #5F6368;
  --text-dim:      #5F6368;

  /* Semantic (unchanged from the prior palette pass — already verified
     AA-passing on a white surface, see the contrast audit below) */
  --success:       #1E7A46;
  --success-rgb:   30, 122, 70;
  --warning:       #8A5A00;
  --warning-rgb:   138, 90, 0;
  --info:          #1D5AA0;
  --info-rgb:      29, 90, 160;
  --danger:        #B3261E;
  --danger-rgb:    179, 38, 30;

  /* Leaderboard medal colors — darkened from the classic gold/silver/bronze
     so rank text still clears 4.5:1 on a white card. */
  --gold:   #946E00;
  --silver: #5B6670;
  --bronze: #A0522D;

  --sidebar-w:    240px;
  --topbar-h:     60px;
  --radius:       5px;   /* was 7px — reduced 30% for a sharper edge style */
  --radius-sm:    3px;   /* was 4px */

  /* Thin uniform outline for container/wrapper surfaces (cards, panels,
     modals, media wrappers) — a tinted primary border used instead of the
     neutral --border on anything that reads as a distinct "box" on the
     page, so elevated content stays visually distinguishable from page
     chrome (sidebar/topbar/table rules), which keep the neutral --border. */
  --border-accent: rgba(var(--primary-rgb), 0.35);

  /* Spacing scale — the values already in near-universal use across the
     app, named so new/updated rules snap to a consistent step instead of
     picking an arbitrary px value. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;

  /* Material Design elevation — shadow recipes match Google's own product
     UI (Workspace/Drive), umbra + ambient pair per level. --shadow/--shadow-lg
     keep their old names (every existing consumer already references them)
     but now point at the 3dp/6dp tiers; --shadow-sm is the new 1dp tier. */
  --shadow-sm:  0 1px 2px rgba(60,64,67,0.3), 0 1px 3px 1px rgba(60,64,67,0.15);
  --shadow:     0 1px 3px rgba(60,64,67,0.3), 0 4px 8px 3px rgba(60,64,67,0.15);
  --shadow-lg:  0 3px 4px rgba(60,64,67,0.3), 0 8px 14px 6px rgba(60,64,67,0.15);

  /* Icon System Replacement — 3-tier sizing so the whole app uses exactly
     three icon sizes: 16px inline, 24px nav/action, 32px large feature. */
  --icon-sm: 1rem;
  --icon-md: 1.5rem;
  --icon-lg: 2rem;

  --transition:   0.2s ease;
}

/* ── Dark theme ──────────────────────────────────
   Overrides every color token above; everything else in this file consumes
   colors exclusively through var(--...), so a single attribute flip on
   <html> (data-theme="dark", set by applyStoredTheme() in index.html and
   toggled by toggleTheme() in js/app.js, persisted to localStorage) re-themes
   the whole app with no per-component CSS needed. Deliberately NOT touched:
   .certificate-frame (a printable document, meant to look the same on
   screen and paper — see its own comment) and .login-visual-panel (a fixed
   brand gradient, already dark, not meant to react to the toggle). */
:root[data-theme="dark"] {
  --primary:       #8AB4F8;
  --primary-dark:  #669DF6;
  --primary-light: #AECBFA;
  --primary-rgb:   138, 180, 248;
  --primary-tint:  #22314A;

  --bg:            #16171B;
  --surface:       #1E1F23;
  --surface-2:     #26272C;
  --surface-3:     #313236;
  --bg-elevated:   #26272C;
  --border:        #3C3D42;
  --border-light:  #4A4B50;
  --border-strong: #6B6C70;

  --text-primary:  #E8EAED;
  --text-muted:    #9AA0A6;
  --text-dim:      #9AA0A6;

  --success:       #81C995;
  --success-rgb:   129, 201, 149;
  --warning:       #FDD663;
  --warning-rgb:   253, 214, 99;
  --info:          #8AB4F8;
  --info-rgb:      138, 180, 248;
  --danger:        #F28B82;
  --danger-rgb:    242, 139, 130;

  --gold:   #FDD663;
  --silver: #C4C7C5;
  --bronze: #E2A66E;

  /* Umbra on a dark surface needs to be pure black, not the light theme's
     dark-gray (60,64,67) — that would barely read as a shadow at all. */
  --shadow-sm:  0 1px 2px rgba(0,0,0,0.6), 0 1px 3px 1px rgba(0,0,0,0.4);
  --shadow:     0 1px 3px rgba(0,0,0,0.6), 0 4px 8px 3px rgba(0,0,0,0.4);
  --shadow-lg:  0 3px 4px rgba(0,0,0,0.6), 0 8px 14px 6px rgba(0,0,0,0.4);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; font-size: 100%; }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text-primary);
  font-size: 1rem;
  line-height: 1.5;
  overflow: hidden;
  height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ── SCROLLBAR ─────────────────────────────────── */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-light); border-radius: 1px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }

/* ── GOOGLE MATERIAL SYMBOLS (Outlined) — ligature-based icon rendering ──
   3-tier sizing system: 16px inline (.icon-inline), 24px nav/action
   (.nav-icon and icon-only buttons), 32px large feature (every other bare
   .material-symbols-outlined sitting alone in a sizing container — stat
   tiles, empty states, badges, etc.). */
.material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  vertical-align: -0.2em;
  font-feature-settings: 'liga';
  -webkit-font-feature-settings: 'liga';
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 40;
  font-size: var(--icon-lg); /* large-feature default; overridden by the two tiers below */
}
/* Inline tier (16px) — an icon sitting next to a text label (nav items,
   buttons, card titles, toasts). Slightly lighter weight reads better at
   small sizes next to body text. */
.icon-inline {
  font-size: var(--icon-sm);
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;
  margin-right: 2px;
}
/* Nav/action tier (24px) — sidebar nav icons and icon-only action buttons
   (edit/delete/close/etc). A touch bolder than inline text icons so wayfinding
   icons stay legible at a glance. */
.nav-icon,
.btn > .material-symbols-outlined:not(.icon-inline),
.modal-close .material-symbols-outlined,
.toast-close .material-symbols-outlined,
.logout-btn .material-symbols-outlined,
.theme-toggle-btn .material-symbols-outlined,
.sidebar-toggle .material-symbols-outlined,
.password-toggle .material-symbols-outlined {
  font-size: var(--icon-md);
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}
/* Active/selected nav state gets a filled icon — a standard Material way to
   distinguish the current page from the rest without relying on color alone. */
.nav-item.active .nav-icon,
.course-lesson-btn.active .material-symbols-outlined {
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* ════════════════════════════════════════════════
   LOGIN — split screen: a static branded story panel on the left,
   the active auth box (login/signup/forgot, toggled by showAuthBox() in
   app.js — unchanged) centered in a plain panel on the right. The visual
   panel is decorative only, so it's dropped below 900px — this screen is
   also reached over LAN from phones/tablets (see the dashboard's "Class
   Access" card), where every pixel needs to go to the actual form.
   ════════════════════════════════════════════════ */
#login-screen {
  position: fixed; inset: 0;
  display: flex;
  background: var(--bg);
  z-index: 1000;
}

/* ── Visual panel ──────────────────────────────── */
.login-visual-panel {
  flex: 1 1 46%; max-width: 560px;
  background: linear-gradient(160deg, #0B2545 0%, #0F3A6B 55%, #12468A 100%);
  color: #fff;
  padding: 48px 44px;
  display: flex; align-items: center;
  position: relative; overflow: hidden;
}
.login-visual-panel::before {
  content: ''; position: absolute; inset: 0;
  background-image: radial-gradient(circle at 15% 12%, rgba(99,179,255,0.28) 0%, transparent 45%),
                    radial-gradient(circle at 88% 92%, rgba(99,179,255,0.18) 0%, transparent 50%);
  pointer-events: none;
}
.login-visual-content { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-6); }
.login-visual-brand { display: flex; align-items: center; gap: 10px; }
.login-visual-brand img { width: 32px; height: 32px; }
.login-visual-brand span { font-weight: 800; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: #BFD7FF; }
.login-visual-headline { font-size: 2.25rem; font-weight: 800; line-height: 1.2; }
.login-visual-headline .accent { color: #63B3FF; }
.login-visual-tagline { font-size: 1rem; color: #D7E6FF; font-weight: 500; line-height: 1.5; margin-top: var(--space-3); }
.login-visual-tagline strong { color: #fff; }

.login-visual-features { display: flex; flex-direction: column; gap: var(--space-4); }
.login-visual-feature { display: flex; align-items: flex-start; gap: var(--space-3); }
.login-visual-feature-icon {
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.25);
  display: flex; align-items: center; justify-content: center;
}
.login-visual-feature-icon .material-symbols-outlined { font-size: 22px; color: #fff; }
.login-visual-feature-title { font-size: 0.875rem; font-weight: 700; color: #fff; }
.login-visual-feature-desc { font-size: 0.8125rem; color: #C3D7F5; margin-top: 2px; line-height: 1.4; }

.login-visual-capsule {
  display: flex; align-items: center; gap: var(--space-3);
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.2);
  border-radius: 49px; padding: 12px 20px;
}
.login-visual-capsule .material-symbols-outlined { font-size: 26px; color: #fff; flex-shrink: 0; }
.login-visual-capsule span { font-size: 0.8125rem; color: #D7E6FF; line-height: 1.4; }
.login-visual-capsule strong { color: #fff; }

.login-visual-strip {
  display: flex; flex-wrap: wrap; gap: var(--space-5);
  border-top: 1px solid rgba(255,255,255,0.15); padding-top: var(--space-5);
}
.login-visual-strip-item { display: flex; align-items: center; gap: var(--space-2); font-size: 0.75rem; font-weight: 700; color: #BFD7FF; }
.login-visual-strip-item .material-symbols-outlined { font-size: 18px; }

@media (max-width: 900px) {
  .login-visual-panel { display: none; }
}

/* ── Form panel ────────────────────────────────── */
.login-form-panel {
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 24px;
  position: relative; overflow-y: auto;
}

.login-bg-pattern {
  position: absolute; inset: 0;
  background-image: radial-gradient(circle at 20% 20%, rgba(var(--primary-rgb),0.08) 0%, transparent 50%),
                    radial-gradient(circle at 80% 80%, rgba(var(--primary-rgb),0.05) 0%, transparent 50%);
  pointer-events: none;
}

.login-box {
  background: var(--surface);
  border: 1px solid var(--border-accent);
  border-radius: 8px;
  padding: 40px;
  width: 100%;
  max-width: 420px;
  box-shadow: var(--shadow-lg);
  position: relative;
  z-index: 1;
}

.login-logo { text-align: center; margin-bottom: 28px; }
.login-logo-img { width: 80px; height: 80px; margin-bottom: 12px; }
.login-logo h1 { font-size: 1.25rem; font-weight: 800; color: var(--text-primary); line-height: 1.3; }
.login-brand { color: var(--text-muted); font-size: 0.8125rem; margin-top: 4px; }
.login-brand a { color: var(--primary); text-decoration: none; }
.login-brand strong { color: var(--primary); }
.login-tagline { color: var(--text-dim); font-size: 0.6875rem; letter-spacing: 3px; margin-top: 6px; text-transform: uppercase; }
.login-error { background: rgba(var(--danger-rgb),0.1); border: 1px solid var(--danger); color: var(--danger); padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.8125rem; margin-bottom: 12px; }
.login-success { background: rgba(var(--success-rgb),0.1); border: 1px solid var(--success); color: var(--success); padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.8125rem; margin-bottom: 12px; }
.login-signup-link { color: var(--text-muted); font-size: 0.8125rem; }
.login-signup-link a { color: var(--primary); text-decoration: none; font-weight: 600; }
.login-signup-link a:hover { text-decoration: underline; }

.login-demo { margin-top: 20px; border-top: 1px solid var(--border); padding-top: 16px; }
.demo-label { text-align: center; color: var(--text-muted); font-size: 0.75rem; margin-bottom: 10px; }
.demo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.demo-btn { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); padding: 8px 12px; border-radius: var(--radius-sm); cursor: pointer; font-size: 0.75rem; transition: var(--transition); }
.demo-btn:hover { border-color: var(--primary); color: var(--primary); background: rgba(var(--primary-rgb),0.05); }

/* ════════════════════════════════════════════════
   APP LAYOUT
   ════════════════════════════════════════════════ */
#app { display: flex; height: 100vh; overflow: hidden; }

/* ── SIDEBAR ───────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  flex-shrink: 0;
  height: 100vh;
  overflow-y: auto;
  transition: transform var(--transition);
  z-index: 10;
}

.sidebar-logo {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.sidebar-logo-img { width: 36px; height: 36px; }
.sidebar-logo-title { font-size: 0.75rem; font-weight: 800; color: var(--text-primary); line-height: 1.2; }
.sidebar-logo-sub { font-size: 0.6875rem; color: var(--primary); font-weight: 600; }

.sidebar-nav { flex: 1; padding: 12px 8px; overflow-y: auto; }
.nav-section-label { font-size: 0.6875rem; color: var(--text-dim); letter-spacing: 1.5px; text-transform: uppercase; font-weight: 700; padding: 16px 8px 4px; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 9px 12px;
  border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-muted);
  cursor: pointer; font-size: 0.8125rem; font-weight: 500;
  text-align: left; transition: var(--transition);
  margin-bottom: 2px;
}
.nav-item:hover { background: var(--surface-2); color: var(--text-primary); }
.nav-item.active { background: rgba(var(--primary-rgb),0.12); color: var(--primary); border-left: 3px solid var(--primary); }
.nav-icon { font-size: 1.125rem; flex-shrink: 0; }

.sidebar-footer {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.sidebar-user-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--primary); color: white;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.875rem; flex-shrink: 0;
}
.sidebar-user-name { font-size: 0.75rem; font-weight: 600; color: var(--text-primary); }
.sidebar-user-role { font-size: 0.6875rem; color: var(--text-muted); text-transform: capitalize; }
.sidebar-user-info { flex: 1; min-width: 0; overflow: hidden; }
.sidebar-user-name, .sidebar-user-role { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.logout-btn { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; align-items: center; justify-content: center; border-radius: var(--radius-sm); flex-shrink: 0; transition: var(--transition); display: inline-flex; }
.logout-btn:hover { color: var(--danger); }
.theme-toggle-btn { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; align-items: center; justify-content: center; border-radius: var(--radius-sm); flex-shrink: 0; transition: var(--transition); display: inline-flex; }
.theme-toggle-btn:hover { color: var(--primary); background: var(--surface-2); }
/* Login screen has no sidebar to host the toggle — pin it to the corner of
   the form panel instead (the visual brand panel goes fixed-width/absent
   below 900px, so anchoring to the viewport keeps this reachable either way). */
.login-theme-toggle { position: absolute; top: var(--space-4); right: var(--space-4); z-index: 2; }

/* ── MAIN AREA ─────────────────────────────────── */
#main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }

/* ── TOPBAR ────────────────────────────────────── */
#topbar {
  height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px;
  flex-shrink: 0;
  position: relative; z-index: 5;
}
.sidebar-toggle { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; align-items: center; justify-content: center; border-radius: var(--radius-sm); display: none; }
.topbar-title { font-size: 1.0625rem; font-weight: 700; color: var(--text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-breadcrumb { font-size: 0.75rem; color: var(--text-muted); }
.topbar-actions { display: flex; align-items: center; gap: 8px; }

/* ── Notification bell (Community Collaboration Module) ────────────── */
.notification-bell-btn {
  position: relative; background: none; border: none; color: var(--text-muted);
  cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); flex-shrink: 0; transition: var(--transition);
}
.notification-bell-btn:hover { color: var(--primary); background: var(--surface-2); }
.notification-unread { border-left: 3px solid var(--primary); }
.notification-bell-badge {
  position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 8px; background: var(--danger); color: #fff;
  font-size: 0.625rem; font-weight: 700; line-height: 16px; text-align: center;
}

/* ── Community detail tabs ───────────────────────────────────────────── */
.community-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin: var(--space-4) 0; }
.tab-btn {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 10px 14px; font-size: 0.8125rem; font-weight: 600; color: var(--text-muted);
  cursor: pointer; transition: var(--transition);
}
.tab-btn:hover { color: var(--text-primary); }
.tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); }

/* ── Topic threads (nested replies indented by depth) ───────────────── */
.topic-reply-node { margin-top: 12px; }
.topic-reply-node .reply-card { margin-bottom: 0; }
.topic-reply-children { margin-left: 28px; border-left: 2px solid var(--border); padding-left: 14px; }
.reaction-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px;
  border-radius: 49px; border: 1px solid var(--border-strong); background: var(--surface-2);
  font-size: 0.75rem; cursor: pointer; transition: var(--transition); margin-right: 6px;
}
.reaction-chip:hover { border-color: var(--primary); }
.reaction-chip.mine { border-color: var(--primary); background: rgba(var(--primary-rgb),0.12); color: var(--primary); }
.tag-chip {
  display: inline-flex; align-items: center; padding: 2px 10px; border-radius: 49px;
  background: var(--surface-2); color: var(--text-muted); font-size: 0.6875rem; font-weight: 600; margin-right: 6px;
}

.mention-chip {
  display: inline; padding: 1px 5px; border-radius: 4px;
  background: var(--primary-light, rgba(99,102,241,0.15)); color: var(--primary); font-weight: 600;
}
.mention-dropdown {
  position: fixed; z-index: 2000; min-width: 180px; max-height: 190px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
}
.mention-dropdown-item {
  padding: 8px 12px; font-size: 0.8125rem; cursor: pointer;
}
.mention-dropdown-item:hover { background: var(--surface-2); }

/* Rich content editor (Quill) — Community Collaboration Module Phase 2.
   Mirrors #lesson-edit-quill's inline styling (courses.js/index.html) as a
   reusable class instead of repeating it across four containers (new
   topic, reply composer, edit-topic, edit-reply — see ensureCommunityQuill()
   in topics.js). */
.community-quill {
  background: var(--surface); border: 1px solid var(--border-accent); border-radius: 4px;
  min-height: 140px; max-width: 100%; overflow-wrap: anywhere; overflow-x: auto;
}

/* ── PAGES ─────────────────────────────────────── */
/* overflow-x: auto is a containment safety net — #main/#app/body all clip
   overflow-x above this, so without it anything wider than the pane (a
   stray fixed-width child, a wide table) is silently cut off with no way
   to reach it instead of staying reachable via a contained scrollbar. */
#pages { flex: 1; overflow-y: auto; overflow-x: auto; padding: 24px; }
.page { display: none; }
.page.active { display: block; animation: fadeIn 0.2s ease; }

@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

.page-header {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-6); flex-wrap: wrap;
}
.page-header h2 { font-size: 1.375rem; font-weight: 800; flex: 1 1 200px; min-width: 160px; overflow-wrap: anywhere; }
.page-sub { color: var(--text-muted); font-size: 0.8125rem; margin-top: 2px; }

/* ════════════════════════════════════════════════
   COMPONENTS
   ════════════════════════════════════════════════ */

/* ── CARD ──────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border-accent);
  border-radius: var(--radius);
  padding: var(--space-5);
  box-shadow: var(--shadow);
  transition: var(--transition);
  /* .card sits as a direct child of nearly every grid/flex layout in the
     app (two-col-grid, charts-grid, builder-layout, profile-layout, …).
     Grid/flex items default to min-width:auto, i.e. "never shrink below
     my content's intrinsic width" — without this, one long unbroken run
     of text/rows inside a card silently widens its whole track and pushes
     the layout into horizontal overflow instead of wrapping/truncating
     the way its own CSS intends. Only affects sizing when .card is a
     grid/flex item; a no-op everywhere else. */
  min-width: 0;
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.card-title { font-size: 0.875rem; font-weight: 700; color: var(--text-primary); }

/* ── BUTTONS ───────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: var(--radius-sm);
  font-size: 0.8125rem; font-weight: 600; cursor: pointer;
  border: none; transition: var(--transition); text-decoration: none;
  white-space: nowrap;
}
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-dark); transform: translateY(-1px); }
.btn-ghost { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); }
.btn-ghost:hover { color: var(--text-primary); border-color: var(--border-strong); }
.btn-outline { border: 1px solid var(--border-strong); color: var(--text-primary); background: var(--surface); }
.btn-outline:hover { border-color: var(--primary); color: var(--primary); }
.btn-danger { background: var(--danger); color: white; }
.btn-danger:hover { opacity: 0.85; }
.btn-success { background: var(--success); color: white; }
.btn-sm { padding: 5px 10px; font-size: 0.75rem; }
.btn-full { width: 100%; justify-content: center; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none !important; }

/* ── BADGES ────────────────────────────────────── */
.badge {
  display: inline-block; padding: 3px 9px;
  border-radius: 10px; font-size: 0.6875rem; font-weight: 600;
}
.badge-primary   { background: rgba(var(--primary-rgb),0.15); color: var(--primary); }
.badge-success   { background: rgba(var(--success-rgb),0.15); color: var(--success); }
.badge-warning   { background: rgba(var(--warning-rgb),0.15); color: var(--warning); }
.badge-info      { background: rgba(var(--info-rgb),0.15); color: var(--info); }
.badge-muted     { background: var(--surface-2); color: var(--text-muted); }
.badge-danger    { background: rgba(var(--danger-rgb),0.15); color: var(--danger); }

/* ── FORMS ─────────────────────────────────────── */
/* min-width: 0 — .form-group is a grid item wherever it sits inside
   .form-grid (or a flex item in a few ad-hoc layouts); without it, a
   grid/flex item defaults to never shrinking below its content's intrinsic
   min-width, and an <input>/<select>'s native minimum width (not overridden
   by the `width:100%` below — that only governs the *available*-space case)
   was winning, pushing whole rows wider than their card and clipping/
   overflowing it instead of the input actually fitting the column. */
.form-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-4); min-width: 0; }
.form-group label { font-size: 0.75rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.form-group input,
.form-group textarea,
.form-group select {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  padding: 9px 12px; font-size: 1rem;
  box-shadow: var(--shadow-sm);
  transition: var(--transition); width: 100%;
  font-family: inherit;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb),0.2), var(--shadow-sm); }
.form-group textarea { resize: vertical; min-height: 80px; }

/* Plain (non-hidden) <input type="file"> — the AI Assistant resource
   upload, lesson video upload, and project submission file picker all
   render the browser's native control directly (unlike every other file
   input in the app, which stays display:none behind a styled label/button).
   That native "Choose File" button ignores CSS custom properties by
   default and stays stark white regardless of theme — file-selector-button
   is the standard hook (supported in the Chromium version Electron ships)
   to theme it instead. */
input[type="file"] { color: var(--text-primary); font-size: 0.875rem; }
input[type="file"]::file-selector-button {
  background: var(--surface-2);
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  margin-right: 10px;
  cursor: pointer;
  font-family: inherit;
  font-size: inherit;
  transition: var(--transition);
}
input[type="file"]::file-selector-button:hover { background: var(--surface-3); border-color: var(--primary); }
.form-group select { cursor: pointer; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Show/hide toggle for password fields — input is wrapped in
   .password-field by renderer/js/password-toggle.js at load time. */
.password-field { position: relative; }
.password-field input { padding-right: 38px; }
.password-toggle {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); border-radius: var(--radius-sm);
}
.password-toggle:hover { color: var(--text-primary); }

.select-input {
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); color: var(--text-primary);
  padding: 7px 10px; font-size: 0.8125rem; cursor: pointer;
  box-shadow: var(--shadow-sm);
  font-family: inherit;
}
.select-input:focus { outline: none; border-color: var(--primary); }

.search-input {
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); color: var(--text-primary);
  padding: 7px 12px; font-size: 0.8125rem; min-width: 200px;
  box-shadow: var(--shadow-sm);
}
.search-input:focus { outline: none; border-color: var(--primary); }

/* ── STATS GRID ────────────────────────────────────
   Icon-chip layout: a colored icon badge to the left, value/label stacked
   to the right — placed via CSS grid so the existing icon/value/label DOM
   order (unchanged by every page that renders a .stat-card) just slots
   into a 2-column, 2-row template instead of needing new wrapper markup. */
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
.stat-card {
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 16px;
  display: grid; grid-template-columns: 40px 1fr; grid-template-rows: auto auto;
  column-gap: 12px; align-items: center;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}
.stat-card:hover { border-color: var(--primary); box-shadow: var(--shadow); transform: translateY(-2px); }
.stat-icon {
  grid-row: 1 / 3; grid-column: 1;
  width: 40px; height: 40px; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--primary-rgb), 0.12); color: var(--primary);
}
.stat-icon .material-symbols-outlined { font-size: 21px; }
.stat-card.success .stat-icon { background: rgba(var(--success-rgb), 0.12); color: var(--success); }
.stat-card.info    .stat-icon { background: rgba(var(--info-rgb), 0.12); color: var(--info); }
.stat-card.warning .stat-icon { background: rgba(var(--warning-rgb), 0.12); color: var(--warning); }
.stat-value { grid-row: 1; grid-column: 2; align-self: end; font-size: 1.375rem; font-weight: 800; color: var(--text-primary); line-height: 1.15; }
.stat-label { grid-row: 2; grid-column: 2; align-self: start; font-size: 0.75rem; color: var(--text-muted); font-weight: 500; }

/* ── CHARTS GRID ───────────────────────────────── */
.charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.chart-wrap { height: 240px; }
.two-col-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* ── DASHBOARD LISTS (Top Courses / Announcements) ─────────────────
   Shared "ranked/icon row" pattern for compact dashboard list cards —
   rank badge or icon chip, a title that truncates instead of wrapping the
   row taller, and a trailing metric/timestamp pinned to the right. */
.dash-list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.dash-list-row:last-child { border-bottom: none; }
.dash-list-rank {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: var(--surface-2); color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 700;
}
.dash-list-row:nth-child(1) .dash-list-rank { background: rgba(var(--warning-rgb),0.15); color: var(--warning); }
.dash-list-icon {
  width: 30px; height: 30px; border-radius: var(--radius-sm); flex-shrink: 0;
  background: rgba(var(--primary-rgb), 0.12); color: var(--primary);
  display: flex; align-items: center; justify-content: center;
}
.dash-list-icon .material-symbols-outlined { font-size: 17px; }
.dash-list-title { flex: 1; min-width: 0; font-size: 0.8125rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-list-meta { flex-shrink: 0; font-size: 0.75rem; color: var(--text-muted); }

/* ── CARDS GRID ────────────────────────────────── */
.cards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }

/* ── COHORT CARD ───────────────────────────────── */
.cohort-card {
  position: relative;
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 20px;
  cursor: pointer; transition: var(--transition);
  border-top: 4px solid var(--primary);
  box-shadow: var(--shadow);
}
.cohort-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--primary); }
.cohort-card-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.cohort-icon { font-size: var(--icon-lg); }
/* ADD-ON (June 2026 customization update): this class was referenced in
   renderer/js/cohorts.js's card template from day one but had no rule here
   at all — the emoji rendered as bare unstyled inline text. Now doubling as
   the cover-image box when a cohort has one uploaded. */
.cohort-icon-wrap {
  width: 48px; height: 48px; border-radius: 5px; font-size: var(--icon-lg);
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); margin-bottom: 10px; overflow: hidden; flex-shrink: 0;
}
.cohort-name { font-size: 0.9375rem; font-weight: 700; }
.cohort-desc { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.5; }
.cohort-meta { display: flex; gap: 12px; font-size: 0.75rem; color: var(--text-muted); }

/* ── COURSE CARD ───────────────────────────────── */
.courses-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.course-card {
  position: relative;
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); overflow: hidden;
  cursor: pointer; transition: var(--transition);
  box-shadow: var(--shadow);
}
.course-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--primary); }
.course-card-thumb {
  height: 130px; display: flex; align-items: center; justify-content: center;
  font-size: var(--icon-lg); position: relative; color: #fff;
}
.course-card-level {
  position: absolute; top: 10px; right: 10px;
  background: rgba(0,0,0,0.55); padding: 3px 8px;
  border-radius: 10px; font-size: 0.6875rem; color: white; font-weight: 600;
}
.course-card-body { padding: 16px; }
.course-card-title { font-size: 0.875rem; font-weight: 700; margin-bottom: 6px; }
.course-card-desc { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 12px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.course-card-meta { display: flex; gap: 8px; font-size: 0.6875rem; color: var(--text-muted); flex-wrap: wrap; }
.course-card-meta span { display: flex; align-items: center; gap: 4px; }
.course-progress-bar { height: 4px; background: var(--border); border-radius: 1px; margin-top: 10px; overflow: hidden; }
.course-progress-fill { height: 100%; background: var(--primary); border-radius: 1px; transition: width 0.4s ease; }

/* ── COURSE VIEW LAYOUT ────────────────────────── */
.course-view-layout { display: grid; grid-template-columns: 260px 1fr; gap: 20px; }
.course-sidebar-nav { display: flex; flex-direction: column; gap: 10px; }
.course-sidebar-nav .card { padding: 12px; }
.course-module-item { padding: 8px; }
.course-module-title { font-size: 0.75rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.course-lesson-btn {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 10px; border: none;
  background: transparent; color: var(--text-muted);
  border-radius: var(--radius-sm); cursor: pointer;
  font-size: 0.75rem; text-align: left; transition: var(--transition);
  margin-bottom: 2px;
}
.course-lesson-btn:hover { background: var(--surface-2); color: var(--text-primary); }
.course-lesson-btn.active { background: rgba(var(--primary-rgb),0.1); color: var(--primary); }
.course-lesson-btn.completed { color: var(--success); }
.lesson-check { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--border-strong); flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 0.5625rem; }
.lesson-check.done { background: var(--success); border-color: var(--success); color: white; }
.course-content-area { min-width: 0; }

/* ── LESSON VIEW ───────────────────────────────── */
.lesson-content { line-height: 1.8; overflow-wrap: anywhere; }
.lesson-content h1, .lesson-content h2, .lesson-content h3 { color: var(--text-primary); margin: 20px 0 10px; }
.lesson-content h2 { font-size: 1.25rem; font-weight: 700; border-bottom: 2px solid var(--primary); padding-bottom: 8px; }
.lesson-content h3 { font-size: 1rem; font-weight: 600; color: var(--primary); }
.lesson-content p { margin-bottom: 14px; color: var(--text-primary); }
.lesson-content ul, .lesson-content ol { padding-left: 24px; margin-bottom: 14px; }
.lesson-content li { margin-bottom: 8px; color: var(--text-primary); }
.lesson-content strong { color: var(--primary); }
.lesson-content blockquote { border-left: 4px solid var(--primary); padding: 12px 16px; background: var(--surface-2); border-radius: 0 4px 4px 0; margin: 16px 0; color: var(--text-muted); }
.lesson-content table { border-collapse: collapse; max-width: 100%; }
.lesson-content img, .lesson-content video, .lesson-content iframe { max-width: 100%; height: auto; }
.lesson-content, .ai-output { overflow-x: auto; overflow-wrap: anywhere; }

/* ── COURSE BUILDER ────────────────────────────── */
.builder-layout { display: grid; grid-template-columns: 320px 1fr; gap: var(--space-5); min-width: 0; }
.builder-meta { position: sticky; top: 0; min-width: 0; }
.builder-modules { min-width: 0; }
.builder-module-item { border: 1px solid var(--border-accent); border-radius: var(--radius-sm); margin-bottom: var(--space-3); overflow: hidden; box-shadow: var(--shadow-sm); transition: opacity 0.15s, box-shadow 0.15s; }
.builder-module-item.dragging { opacity: 0.4; }
.builder-module-item.drag-over { box-shadow: 0 0 0 2px var(--primary) inset; }
.builder-module-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); background: var(--surface-2); cursor: pointer; flex-wrap: wrap; }
.builder-drag-handle { cursor: grab; color: var(--text-muted); font-size: 20px; }
.builder-drag-handle:active { cursor: grabbing; }
.builder-module-title { flex: 1; min-width: 120px; font-weight: 600; font-size: 0.8125rem; overflow-wrap: anywhere; }
.builder-lessons-list { padding: var(--space-2) var(--space-3); }
.builder-lesson-item { display: flex; align-items: center; gap: var(--space-2); padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 0.75rem; color: var(--text-muted); flex-wrap: wrap; }
.builder-lesson-item .builder-lesson-title { flex: 1; min-width: 100px; overflow-wrap: anywhere; }
.builder-lesson-item:last-child { border-bottom: none; }

/* ── QUIZ ──────────────────────────────────────── */
.quiz-container { max-width: 700px; margin: 0 auto; }
.quiz-progress { margin-bottom: 20px; }
.quiz-q-counter { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 6px; }
.quiz-progress-bar { height: 6px; background: var(--border); border-radius: 2px; overflow: hidden; }
.quiz-progress-fill { height: 100%; background: var(--primary); transition: width 0.3s ease; }
.quiz-question-card { padding: 24px; }
.quiz-q-text { font-size: 1.0625rem; font-weight: 600; margin-bottom: 20px; line-height: 1.5; }
.quiz-option {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border: 2px solid var(--border-strong);
  border-radius: var(--radius-sm); cursor: pointer;
  margin-bottom: 10px; transition: var(--transition);
  font-size: 0.875rem; background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.quiz-option:hover { border-color: var(--primary); background: rgba(var(--primary-rgb),0.05); }
.quiz-option.selected { border-color: var(--primary); background: rgba(var(--primary-rgb),0.1); }
.quiz-option.correct { border-color: var(--success); background: rgba(var(--success-rgb),0.1); }
.quiz-option.wrong { border-color: var(--danger); background: rgba(var(--danger-rgb),0.1); }
.quiz-option-letter {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--border); color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 700; flex-shrink: 0;
}
.quiz-option.selected .quiz-option-letter { background: var(--primary); color: white; }
.quiz-nav { display: flex; justify-content: space-between; margin-top: 20px; }
.quiz-result { text-align: center; padding: 40px; }
.quiz-result-score { font-size: 4.5rem; font-weight: 900; color: var(--primary); }
.quiz-result-label { font-size: 1rem; color: var(--text-muted); margin-top: 8px; }
.quiz-result-pass { color: var(--success); font-size: 1.125rem; font-weight: 700; margin-top: 16px; }
.quiz-result-fail { color: var(--danger); font-size: 1.125rem; font-weight: 700; margin-top: 16px; }
.quiz-timer { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 14px; font-size: 0.8125rem; font-weight: 700; color: var(--warning); }

/* ── DISCUSSIONS ───────────────────────────────── */
.discussions-layout { display: grid; grid-template-columns: 200px 1fr; gap: 20px; }
.discussions-course-filter-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  cursor: pointer; font-size: 0.8125rem; color: var(--text-muted);
  transition: var(--transition); margin-bottom: 4px;
}
.discussions-course-filter-item:hover { background: var(--surface-2); color: var(--text-primary); }
.discussions-course-filter-item.active { background: rgba(var(--primary-rgb),0.1); color: var(--primary); }
.discussion-post-card {
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 18px; margin-bottom: 12px;
  cursor: pointer; transition: var(--transition);
  box-shadow: var(--shadow);
}
.discussion-post-card:hover { border-color: var(--primary); box-shadow: var(--shadow-lg); transform: translateX(3px); }
.post-title { font-size: 0.9375rem; font-weight: 600; margin-bottom: 6px; color: var(--text-primary); }
.post-meta { font-size: 0.75rem; color: var(--text-muted); display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.post-pinned { background: rgba(var(--warning-rgb),0.15); color: var(--warning); padding: 2px 8px; border-radius: 10px; font-size: 0.6875rem; }
.post-announcement { background: rgba(var(--primary-rgb),0.15); color: var(--primary); padding: 2px 8px; border-radius: 10px; font-size: 0.6875rem; }
.reply-card { background: var(--surface-2); border-radius: var(--radius-sm); padding: 14px; margin-bottom: 10px; border-left: 3px solid var(--border); box-shadow: var(--shadow-sm); }
.reply-card.solution { border-left-color: var(--success); }
.reply-author { font-size: 0.75rem; font-weight: 600; color: var(--primary); margin-bottom: 8px; }
.reply-body { font-size: 0.8125rem; line-height: 1.6; color: var(--text-primary); }
.reply-body p { margin-bottom: 8px; }

/* ── CERTIFICATES ──────────────────────────────── */
.certs-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; margin-bottom: 20px; }
.cert-card {
  background: linear-gradient(135deg, var(--surface) 0%, rgba(var(--primary-rgb),0.05) 100%);
  border: 1px solid var(--border-accent); border-radius: var(--radius);
  padding: 20px; text-align: center; cursor: pointer;
  box-shadow: var(--shadow);
  transition: var(--transition);
}
.cert-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(var(--primary-rgb),0.2); }
.cert-card-icon { font-size: var(--icon-lg); margin-bottom: 10px; color: var(--primary); }
.cert-card-title { font-size: 0.875rem; font-weight: 700; margin-bottom: 6px; color: var(--text-primary); }
.cert-card-student { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 2px; }
.cert-card-date { font-size: 0.75rem; color: var(--text-muted); }
.cert-card-number { font-size: 0.6875rem; color: var(--primary); margin-top: 6px; font-family: monospace; }

/* Certificate frame — a printable document, deliberately kept on a fixed
   white/ink palette so it looks the same on screen and on paper. Colors
   here are hand-mirrored from server/lib/certificates/layoutSpec.js (the
   PDF's source of truth) — keep the two in sync if either changes; there's
   no build step in this app to enforce it automatically. */
.certificate-frame {
  background: white; color: #1A1A1A;
  border: 8px solid #CC0000; border-radius: 6px;
  max-width: 700px; margin: 0 auto;
  padding: 50px 60px; text-align: center;
  box-shadow: 0 20px 60px rgba(30,42,56,0.35);
  position: relative; overflow: hidden;
}
.certificate-frame::before {
  content: ''; position: absolute; inset: 12px;
  border: 2px solid rgba(204,0,0,0.25); border-radius: 3px; pointer-events: none;
}
/* Watermark — same logo, low opacity, large + centered, mirrors the PDF's
   drawLogo() watermark treatment (server/lib/certificates/logoVector.js). */
.certificate-frame::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 480px; height: 480px; margin: -240px 0 0 -240px;
  background: url('/logo.svg') center / contain no-repeat;
  opacity: 0.06; transform: rotate(-18deg);
  pointer-events: none;
}
.certificate-frame > * { position: relative; z-index: 1; }
.cert-header-logo { margin-bottom: 20px; }
.cert-brand { font-size: 1.625rem; font-weight: 900; color: #1A1A1A; font-family: 'Inter', sans-serif; }
.cert-brand-sub { font-size: 0.8125rem; color: #666; margin-top: 4px; }
.cert-divider { width: 80px; height: 3px; background: #1967D2; margin: 20px auto; }
.cert-label { font-size: 0.875rem; color: #888; letter-spacing: 2px; text-transform: uppercase; margin: 10px 0; }
.cert-name { font-size: 2.25rem; font-weight: 800; color: #185ABC; font-family: 'Inter', sans-serif; margin: 8px 0; }
.cert-course { font-size: 1.25rem; font-weight: 700; color: #1A1A1A; margin: 8px 0; font-family: 'Inter', sans-serif; }
.cert-meta { display: flex; justify-content: center; gap: 40px; font-size: 0.8125rem; color: #555; margin: 20px 0; flex-wrap: wrap; }
.cert-meta-label { font-weight: 600; color: #1A1A1A; }
.cert-qr-row { margin: 16px 0 4px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.cert-qr { width: 84px; height: 84px; }
.cert-qr-caption { font-size: 0.6875rem; color: #999; letter-spacing: 0.5px; }
.cert-signature { margin-top: 24px; }
.cert-sig-line { width: 200px; height: 1px; background: #999; margin: 0 auto 8px; }
.cert-sig-name { font-size: 0.9375rem; font-weight: 700; color: #1A1A1A; }
.cert-sig-title { font-size: 0.75rem; color: #888; margin-top: 2px; }

/* ── SLIDE LIBRARY ─────────────────────────────── */
.slide-lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.slide-lib-card {
  position: relative; background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); overflow: hidden; cursor: pointer; transition: var(--transition);
}
.slide-lib-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.slide-lib-card.selected { outline: 2px solid var(--primary); outline-offset: -2px; }
.slide-lib-thumb-wrap { position: relative; width: 100%; aspect-ratio: 16/9; background: var(--surface-2); }
.slide-lib-thumb-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slide-lib-thumb-broken { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 2rem; color: var(--text-muted); }
.slide-lib-checkbox { position: absolute; top: 8px; left: 8px; width: 18px; height: 18px; z-index: 2; }
.slide-lib-fav-btn {
  position: absolute; top: 6px; right: 6px; z-index: 2; background: rgba(0,0,0,0.5);
  border: none; border-radius: 50%; width: 28px; height: 28px; display: flex;
  align-items: center; justify-content: center; cursor: pointer; color: #fff; padding: 0;
}
.slide-lib-fav-btn.active { color: var(--gold); }
.slide-lib-body { padding: 10px 12px; }
.slide-lib-title { font-size: 0.8125rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slide-lib-meta { font-size: 0.6875rem; color: var(--text-muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slide-lib-tags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }
.slide-lib-tag { font-size: 0.625rem; padding: 2px 6px; background: var(--surface-2); border-radius: 3px; color: var(--text-muted); }
.slide-lib-actions { display: flex; gap: 4px; margin-top: 8px; }

/* ── GRID/LIST VIEW TOGGLE ─────────────────────── */
/* Applied via a `.list-view` class on the grid container itself — see
   toggleCoursesView()/toggleCohortsView()/toggleSlideLibView() in their
   respective renderer/js/*.js files. Persisted per-page in localStorage
   (mll-view-courses/cohorts/slidelib), same pattern as the dark/light
   theme toggle. Reflows the existing card markup into a horizontal row
   instead of rendering a second template — same cards, same click
   handlers, just restyled. */

.courses-grid.list-view { grid-template-columns: 1fr; }
.courses-grid.list-view .course-card { display: flex; flex-direction: row; align-items: stretch; }
.courses-grid.list-view .course-card-thumb { width: 160px; height: auto; flex-shrink: 0; }
.courses-grid.list-view .course-card-level { top: 8px; right: 8px; }
.courses-grid.list-view .course-card-body { flex: 1; min-width: 0; padding: 14px 16px; }
.courses-grid.list-view .course-card-desc { -webkit-line-clamp: 1; }

#cohorts-grid.list-view { grid-template-columns: 1fr; }
#cohorts-grid.list-view .cohort-card {
  display: flex; flex-direction: row; align-items: center; gap: 16px; padding: 14px 20px;
}
#cohorts-grid.list-view .cohort-icon-wrap { margin-bottom: 0; }
#cohorts-grid.list-view .cohort-card-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
#cohorts-grid.list-view .cohort-name-row { flex-shrink: 0; min-width: 160px; }
#cohorts-grid.list-view .cohort-desc { margin-bottom: 0; flex: 1; min-width: 160px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#cohorts-grid.list-view .cohort-stats { flex-shrink: 0; }
#cohorts-grid.list-view .cohort-card-actions { flex-shrink: 0; margin-top: 0; }

.slide-lib-grid.list-view { grid-template-columns: 1fr; }
.slide-lib-grid.list-view .slide-lib-card { display: flex; flex-direction: row; align-items: center; }
.slide-lib-grid.list-view .slide-lib-thumb-wrap { width: 120px; aspect-ratio: 16/9; flex-shrink: 0; }
.slide-lib-grid.list-view .slide-lib-body { flex: 1; min-width: 0; }
.slide-lib-grid.list-view .slide-lib-fav-btn { top: 50%; right: 128px; transform: translateY(-50%); }
.slide-lib-grid.list-view .slide-lib-tags { display: none; }

/* ── REWARDS ───────────────────────────────────── */
.xp-bar-wrap { margin: 12px 0; }
.xp-bar-label { display: flex; justify-content: space-between; font-size: 0.75rem; color: var(--text-muted); margin-bottom: 6px; }
.xp-bar-track { height: 12px; background: var(--border); border-radius: 3px; overflow: hidden; }
.xp-bar-fill { height: 100%; background: linear-gradient(90deg, var(--primary), var(--primary-light)); border-radius: 3px; transition: width 0.6s ease; }
.badges-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.badge-item {
  background: var(--surface-2); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 14px; text-align: center;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}
.badge-item:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.badge-item.earned { border-color: var(--warning); background: rgba(var(--warning-rgb),0.05); }
.badge-item-icon { font-size: var(--icon-lg); margin-bottom: 8px; color: var(--warning); }
.badge-item-name { font-size: 0.75rem; font-weight: 700; color: var(--text-primary); }
.badge-item-desc { font-size: 0.6875rem; color: var(--text-muted); margin-top: 4px; }
.badge-item-xp { font-size: 0.6875rem; color: var(--warning); margin-top: 4px; font-weight: 600; }
.badge-item.locked { opacity: 0.5; }
.leaderboard-item {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-accent); margin-bottom: 8px;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
}
.leaderboard-item:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.leaderboard-item.me { border-color: var(--primary); background: rgba(var(--primary-rgb),0.05); }
.lb-rank { font-size: 1.125rem; font-weight: 900; width: 32px; text-align: center; flex-shrink: 0; }
.lb-rank.gold   { color: var(--gold); }
.lb-rank.silver { color: var(--silver); }
.lb-rank.bronze { color: var(--bronze); }
.lb-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--primary); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.875rem; flex-shrink: 0; }
.lb-name { flex: 1; font-weight: 600; }
.lb-xp { font-size: 0.8125rem; font-weight: 700; color: var(--primary); }
.lb-level { font-size: 0.6875rem; color: var(--text-muted); }

/* ── TABLES ────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
/* display:block + overflow-x:auto directly on every <table> (not just ones
   explicitly wrapped in .table-wrap, which several JS renderers — users.js's
   pending-signups list, gradebook.js, certificates.js, slides.js,
   analytics.js, content-standards.js — never added) so a table wider than
   its card on a phone/tablet scrolls within its own box instead of forcing
   the whole page to scroll sideways (or, on the ones with a border/padding
   right up against the table, just clipping the last column). thead/tbody/
   tr/th/td keep their normal table-part rendering regardless — only the
   outer <table> box becomes a block-level scroll container, so this is a
   no-op visually whenever a table already fits. */
table { display: block; overflow-x: auto; max-width: 100%; width: 100%; border-collapse: collapse; }
thead { border-bottom: 2px solid var(--border); }
th { text-align: left; padding: 10px 12px; font-size: 0.6875rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
td { padding: 11px 12px; font-size: 0.8125rem; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--surface-2); }
/* Users table row identity — avatar-sm + role-badge. Neither had a CSS
   rule anywhere (the JS emits `role-badge role-${role}` and
   `user-avatar-sm`; the only rule in this file was for `.user-role-badge`,
   a name nothing ever actually renders), so roles/avatars were rendering
   as unstyled plain text/initials in the Users table. */
.user-avatar-sm {
  width: 32px; height: 32px; min-width: 32px; min-height: 32px; aspect-ratio: 1 / 1;
  border-radius: 50%; overflow: hidden; flex-shrink: 0; align-self: center;
  background: var(--primary); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.75rem;
}
/* An uploaded avatar photo is an arbitrary user-supplied aspect ratio —
   object-fit:cover crops it to fill the fixed circle above instead of
   stretching/distorting it or (with no sizing at all) rendering at its
   raw upload resolution. */
.user-avatar-sm img { display: block; width: 100%; height: 100%; object-fit: cover; }
.role-badge { display: inline-block; padding: 3px 9px; border-radius: 10px; font-size: 0.6875rem; font-weight: 600; text-transform: capitalize; }
.role-badge.role-admin      { background: rgba(var(--danger-rgb),0.15); color: var(--danger); }
.role-badge.role-instructor { background: rgba(var(--info-rgb),0.15); color: var(--info); }
.role-badge.role-designer   { background: rgba(var(--warning-rgb),0.15); color: var(--warning); }
.role-badge.role-student    { background: rgba(var(--primary-rgb),0.15); color: var(--primary); }
.role-badge.role-parent     { background: rgba(var(--success-rgb),0.15); color: var(--success); }

/* ── PAGINATION ────────────────────────────────── */
.pagination {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-3);
  margin-top: var(--space-4); padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.pagination:empty { display: none; }
.pagination-info { font-size: 0.75rem; color: var(--text-muted); }
.pagination-controls { display: flex; align-items: center; gap: var(--space-3); }
.pagination-page { font-size: 0.8125rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; }

/* ── PROFILE ───────────────────────────────────── */
.profile-layout { display: grid; grid-template-columns: 260px 1fr; gap: 20px; }
.profile-card { text-align: center; }
.profile-avatar-wrap { padding: 20px 0; }
.profile-avatar { width: 80px; height: 80px; border-radius: 50%; background: var(--primary); color: white; font-size: 2rem; font-weight: 700; display: flex; align-items: center; justify-content: center; margin: 0 auto 12px; }
.profile-avatar-name { font-size: 1rem; font-weight: 700; margin-bottom: 6px; }
.profile-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.profile-stat { background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px; text-align: center; }
.profile-stat-value { font-size: 1.25rem; font-weight: 800; color: var(--primary); }
.profile-stat-label { font-size: 0.6875rem; color: var(--text-muted); }

/* ── SLIDE UPLOAD ──────────────────────────────── */
.upload-zone {
  border: 2px dashed var(--border-strong); border-radius: var(--radius);
  padding: 40px 20px; text-align: center; cursor: pointer;
  transition: var(--transition);
}
.upload-zone:hover, .upload-zone.drag-over { border-color: var(--primary); background: rgba(var(--primary-rgb),0.03); }
.upload-icon { font-size: var(--icon-lg); margin-bottom: 12px; color: var(--primary); }
.upload-zone p { color: var(--text-muted); margin-bottom: 8px; }

/* ── AI ASSISTANT ──────────────────────────────── */
.ai-layout { display: grid; grid-template-columns: 340px 1fr; gap: 20px; }
.ai-input-card { position: sticky; top: 0; max-height: calc(100vh - 120px); overflow-y: auto; }
.ai-output-card { animation: fadeIn 0.3s ease; }
.ai-output h1, .ai-output h2, .ai-output h3 { color: var(--primary); margin: 16px 0 8px; }
.ai-output p { margin-bottom: 12px; line-height: 1.7; }
.ai-output ul, .ai-output ol { padding-left: 20px; margin-bottom: 12px; }
.ai-output li { margin-bottom: 6px; }
.ai-output .section { background: var(--surface-2); border-radius: var(--radius-sm); padding: 14px; margin-bottom: 10px; }
.ai-output .section-heading { font-weight: 700; color: var(--primary); margin-bottom: 8px; font-size: 0.875rem; }
.ai-history-item { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: var(--radius-sm); cursor: pointer; font-size: 0.75rem; color: var(--text-muted); transition: var(--transition); }
.ai-history-item:hover { background: var(--surface-2); color: var(--text-primary); }
.ai-act-icon { font-size: var(--icon-md); color: var(--primary); flex-shrink: 0; }

/* ── PARENT PORTAL ─────────────────────────────── */
.student-overview-card {
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
  cursor: pointer; transition: var(--transition);
  box-shadow: var(--shadow);
}
.student-overview-card:hover { border-color: var(--primary); box-shadow: var(--shadow-lg); }
.student-card-header { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.student-card-avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--primary); color: white; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; font-weight: 700; }
.student-card-name { font-size: 1rem; font-weight: 700; }
.student-card-cohort { font-size: 0.75rem; color: var(--text-muted); }
.parent-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.parent-stat { background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px; text-align: center; }
.parent-stat-value { font-size: 1.25rem; font-weight: 800; color: var(--primary); }
.parent-stat-label { font-size: 0.6875rem; color: var(--text-muted); }

/* ── MODALS ────────────────────────────────────── */
.modal {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  display: none; align-items: center; justify-content: center;
  z-index: 500; padding: 20px;
}
.modal.open { display: flex; }
.modal-box {
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: var(--space-6);
  width: 100%; max-width: 460px; max-height: 90vh; overflow-y: auto; overflow-x: hidden;
  box-shadow: var(--shadow-lg);
  animation: modalIn 0.2s ease;
}
.modal-box.modal-lg { max-width: 600px; }
@keyframes modalIn { from { transform: scale(0.95); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.modal-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); }
.modal-header h3 { font-size: 1.0625rem; font-weight: 700; }
.modal-close { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; align-items: center; justify-content: center; line-height: 1; border-radius: var(--radius-sm); display: inline-flex; flex-shrink: 0; }
.modal-close:hover { color: var(--danger); }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--space-3); margin-top: var(--space-5); flex-wrap: wrap; }

/* ── POWERPOINT VIEWER ────────────────────────────── */
.pptx-viewer { display: flex; flex-direction: column; gap: 10px; }
.pptx-stage {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #000; border: 1px solid var(--border-accent); border-radius: var(--radius-sm); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.pptx-stage:focus { outline: 2px solid var(--primary); outline-offset: 2px; }
.pptx-slide-img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; transition: opacity 0.2s ease;
}
.pptx-controls {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pptx-slide-select { width: auto; min-width: 110px; }
.pptx-slide-count { font-size: 0.75rem; color: var(--text-muted); min-width: 50px; text-align: center; }

/* Fullscreen: native Fullscreen API target gets full-viewport sizing;
   .pptx-fullscreen-fallback covers browsers/contexts where the Fullscreen
   API is unavailable (e.g. an embedding iframe without allowfullscreen). */
.pptx-viewer.pptx-is-fullscreen,
.pptx-viewer.pptx-fullscreen-fallback {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0,0,0,0.95); padding: 20px;
  display: flex; flex-direction: column; justify-content: center;
}
.pptx-viewer.pptx-is-fullscreen .pptx-stage,
.pptx-viewer.pptx-fullscreen-fallback .pptx-stage { aspect-ratio: unset; flex: 1; }

/* ── TOASTS ────────────────────────────────────── */
#toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border-accent);
  color: var(--text-primary); font-size: 0.8125rem; font-weight: 500;
  box-shadow: var(--shadow-lg); min-width: 260px; pointer-events: all;
  animation: slideIn 0.3s ease, fadeOut 0.3s ease 3.2s forwards;
}
.toast.success { border-color: var(--success); }
.toast.error   { border-color: var(--danger); }
.toast.warning { border-color: var(--warning); }
.toast-msg { flex: 1; }
.toast-close { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 8px; min-width: 40px; min-height: 40px; align-items: center; justify-content: center; margin: -8px -8px -8px 0; border-radius: var(--radius-sm); display: inline-flex; }
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes fadeOut { to { opacity: 0; transform: translateX(100%); } }

/* ── EMPTY STATE ───────────────────────────────── */
.empty-state { text-align: center; padding: 48px 20px; color: var(--text-muted); }
.empty-icon { font-size: var(--icon-lg); margin-bottom: 12px; color: var(--border-strong); }
.empty-state p { font-size: 0.875rem; }

/* ── PROGRESS BARS ─────────────────────────────── */
.progress-bar-wrap { height: 8px; background: var(--border); border-radius: 2px; overflow: hidden; }
.progress-bar-fill { height: 100%; background: linear-gradient(90deg, var(--primary), var(--primary-light)); border-radius: 2px; transition: width 0.4s ease; }
/* Inline table-cell variant — renderGradebookTable()/renderGradebookOverviewTable()
   in gradebook.js reference this class but it had no rule anywhere, so the
   gradebook's per-student lesson-progress bar has never actually rendered
   (an invisible 0-height div next to the "X/Y (Z%)" text). */
.progress-bar-mini { height: 5px; width: 100%; max-width: 120px; background: var(--border); border-radius: 2px; overflow: hidden; margin-bottom: 4px; }
.progress-fill-mini { height: 100%; background: linear-gradient(90deg, var(--primary), var(--primary-light)); border-radius: 2px; transition: width 0.4s ease; }

/* ── MISC ──────────────────────────────────────── */
.flex-center { display: flex; align-items: center; gap: 10px; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.text-muted { color: var(--text-muted); }
.text-primary-c { color: var(--primary); }
.font-mono { font-family: 'Courier New', monospace; }
.spinner { display: inline-block; width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--primary); border-radius: 50%; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── QUESTION BUILDER ──────────────────────────── */
.question-item { background: var(--surface-2); border: 1px solid var(--border-accent); border-radius: var(--radius-sm); padding: 14px; margin-bottom: 12px; box-shadow: var(--shadow-sm); }
.question-item-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.option-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.option-row input[type="text"] { flex: 1; }
.option-row input[type="radio"] { flex-shrink: 0; accent-color: var(--primary); }

/* ── MY LEARNING ───────────────────────────────── */
.my-learning-card {
  background: var(--surface); border: 1px solid var(--border-accent);
  border-radius: var(--radius); padding: 18px; margin-bottom: 12px;
  display: flex; align-items: center; gap: 16px;
  box-shadow: var(--shadow);
  transition: var(--transition);
}
.my-learning-card:hover { border-color: var(--primary); box-shadow: var(--shadow-lg); }
.my-learning-thumb { width: 56px; height: 56px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; font-size: var(--icon-lg); flex-shrink: 0; color: #fff; }
.my-learning-info { flex: 1; min-width: 0; }
.my-learning-title { font-size: 0.875rem; font-weight: 700; margin-bottom: 4px; }
.my-learning-meta { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 8px; }

/* ── ANNOUNCEMENT ──────────────────────────────── */
.announcement-card { background: var(--surface); border: 1px solid var(--border-accent); border-radius: var(--radius); padding: 18px; margin-bottom: 12px; border-left: 4px solid var(--primary); box-shadow: var(--shadow); }
.announcement-title { font-size: 0.9375rem; font-weight: 700; margin-bottom: 8px; }
.announcement-body { font-size: 0.8125rem; color: var(--text-muted); line-height: 1.6; }
.announcement-body p { margin-bottom: 8px; }
.announcement-meta { font-size: 0.6875rem; color: var(--text-dim); margin-top: 10px; }

/* ── CALENDAR ──────────────────────────────────── */
.calendar-layout { display: grid; grid-template-columns: 1fr 300px; gap: 20px; align-items: start; }
.calendar-nav { display: flex; align-items: center; gap: 12px; }
.calendar-month-label { font-size: 0.9375rem; font-weight: 700; min-width: 160px; text-align: center; }
.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-top: 14px; }
.calendar-weekday { font-size: 0.6875rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase; text-align: center; padding: 4px 0; }
.calendar-day {
  min-height: 76px; border: 1px solid var(--border-accent); border-radius: var(--radius-sm);
  padding: 6px; cursor: pointer; transition: var(--transition); background: var(--surface-2);
}
.calendar-day:hover { border-color: var(--border-strong); }
.calendar-day.other-month { opacity: 0.45; }
.calendar-day.today { border-color: var(--primary); }
.calendar-day.selected { background: rgba(var(--primary-rgb),0.12); border-color: var(--primary); }
.calendar-day-num { font-size: 0.75rem; font-weight: 600; color: var(--text-primary); }
.calendar-day-dots { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 6px; }
.calendar-dot { width: 6px; height: 6px; border-radius: 50%; }
.calendar-dot.kind-event        { background: var(--info); }
.calendar-dot.kind-assignment   { background: var(--warning); }
.calendar-dot.kind-course-start { background: var(--success); }
.calendar-dot.kind-course-end   { background: var(--text-muted); }
.calendar-item {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px;
  border: 1px solid var(--border-accent); border-radius: var(--radius-sm); margin-bottom: 8px; background: var(--surface-2);
}
.calendar-item-marker { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex-shrink: 0; }
.calendar-item-title { font-size: 0.8125rem; font-weight: 700; }
.calendar-item-meta { font-size: 0.6875rem; color: var(--text-muted); margin-top: 2px; }
.calendar-item-actions { margin-left: auto; display: flex; gap: 4px; flex-shrink: 0; }
.calendar-upcoming-date { font-size: 0.6875rem; font-weight: 700; color: var(--primary); text-transform: uppercase; margin: 14px 0 6px; }
.calendar-upcoming-date:first-child { margin-top: 0; }

/* ── FEATURE PILLS (Admin Module Feature Toggle System) ───────────── */
.feature-pill-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.feature-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 12px; border-radius: 49px; border: 1px solid transparent;
  font-size: 0.6875rem; font-weight: 700; cursor: pointer; transition: var(--transition);
}
.feature-pill.on { background: var(--primary); color: #fff; }
.feature-pill.on:hover { background: var(--primary-dark); }
.feature-pill.off { background: var(--surface-2); color: var(--text-muted); border-color: var(--border-strong); }
.feature-pill.off:hover { color: var(--text-primary); border-color: var(--primary); }

/* Quill's own CSS (quill.snow.css, loaded from CDN — not ours to edit)
   hardcodes toolbar icon strokes/fills to #444 and picker text to #444,
   which reads fine on Quill's assumed white toolbar but goes near-invisible
   on our dark --surface-2. Recolor via the theme tokens instead — this
   covers every Quill instance in the app (lesson editor, lesson journal). */
:root[data-theme="dark"] .ql-toolbar.ql-snow {
  background: var(--surface-2);
  border-color: var(--border-strong);
}
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-stroke { stroke: var(--text-muted); }
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-fill,
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-stroke.ql-fill { fill: var(--text-muted); }
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-picker-label { color: var(--text-muted); }
:root[data-theme="dark"] .ql-toolbar.ql-snow button:hover .ql-stroke,
:root[data-theme="dark"] .ql-toolbar.ql-snow button.ql-active .ql-stroke,
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-picker-label:hover,
:root[data-theme="dark"] .ql-toolbar.ql-snow .ql-picker-label.ql-active { stroke: var(--primary); color: var(--primary); }
:root[data-theme="dark"] .ql-toolbar.ql-snow button:hover .ql-fill,
:root[data-theme="dark"] .ql-toolbar.ql-snow button.ql-active .ql-fill { fill: var(--primary); }
:root[data-theme="dark"] .ql-snow .ql-picker-options {
  background: var(--surface-2);
  border-color: var(--border-strong) !important;
}
:root[data-theme="dark"] .ql-snow .ql-picker-item { color: var(--text-muted); }
:root[data-theme="dark"] .ql-container.ql-snow { border-color: var(--border-strong); }
:root[data-theme="dark"] .ql-editor.ql-blank::before { color: var(--text-muted); }

/* Quill's color/background-color toolbar tools (and pasting rich text from
   Word/Google Docs) write literal inline styles onto individual spans, e.g.
   style="color: rgb(0, 0, 0)" — which beats .lesson-content's own
   `color: var(--text-primary)` class rule on specificity, so that text
   stays black-on-black in dark mode no matter what the theme tokens say.
   Applies to every place lesson/journal rich-text HTML gets rendered: the
   read-only .lesson-content view (courses.js's openLesson()) and any live
   Quill instance (.ql-editor — the lesson editor, lesson journal). Scoped
   to elements that actually carry an inline color so it doesn't flatten
   this file's own .lesson-content h2/h3/strong accent-color rules, which
   have no inline style to match. */
:root[data-theme="dark"] .lesson-content [style*="color"],
:root[data-theme="dark"] .ql-editor [style*="color"] {
  color: var(--text-primary) !important;
  background-color: transparent !important;
}

/* ── LESSON JOURNAL (Rich Text Editor Integration) ────────────────── */
.journal-panel { margin-bottom: 20px; }
.journal-quill-container { background: var(--surface); border: 1px solid var(--border-accent); border-radius: var(--radius-sm); min-height: 140px; box-shadow: var(--shadow-sm); }
.journal-status { font-size: 0.6875rem; color: var(--text-muted); font-weight: 600; min-width: 90px; text-align: right; }

/* ── VIDEO MEDIA PLAYER ────────────────────────────────────────────
   Plyr (loaded via CDN, see index.html) reads these custom properties for
   its own theming — keeps the player on-brand without touching its CSS. */
.video-player-wrap {
  --plyr-color-main: var(--primary);
  position: relative; background: #000;
  border: 1px solid var(--border-accent); border-radius: var(--radius-sm); overflow: hidden;
}
.video-player-wrap video { width: 100%; display: block; }
.video-buffering-spinner {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.35); pointer-events: none;
}
.video-buffering-spinner .spinner { border-color: rgba(255,255,255,0.3); border-top-color: #fff; }
.video-error-overlay {
  position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; background: rgba(0,0,0,0.92); color: #fff; text-align: center; padding: 24px;
}
.video-error-overlay .material-symbols-outlined { font-size: var(--icon-lg); color: var(--danger); }
.video-error-overlay p { max-width: 360px; font-size: 0.875rem; }

/* ── RESPONSIVE ────────────────────────────────── */
/* 1024px (not the old 600px) is the real device-width boundary that matters
   here: a phone in landscape can run up to ~930px wide, and every common
   tablet's PORTRAT width (iPad 768-834px, iPad Pro 12.9" 1024px) sits at or
   under this line too — so this is the one breakpoint that actually covers
   "phone or tablet," not just "narrow phone in portrait." Below it, the
   sidebar becomes an off-canvas drawer (toggled by #sidebar-toggle in
   app.js's toggleSidebar()) instead of a permanently-visible column eating
   240px of an already-tight viewport with no way to hide it — that gap
   (previously only <600px got this treatment) was the actual bug: a tablet
   or landscape phone landed in a dead zone with a static, non-collapsible
   sidebar permanently blocking part of the content.
   Landscape tablets/small laptops (1024px+) keep the classic always-visible
   sidebar — there's enough width there for both. */
@media (max-width: 1024px) {
  .charts-grid { grid-template-columns: 1fr; }
  .two-col-grid { grid-template-columns: 1fr; }
  .course-view-layout { grid-template-columns: 1fr; }
  .builder-layout { grid-template-columns: 1fr; }
  /* Sticky side panels only make sense next to a taller scrolling sibling
     in the two-column layout above this breakpoint — once columns stack,
     a "stuck" panel just pins itself over the content below it. */
  .builder-meta, .ai-input-card { position: static; max-height: none; }
  .ai-layout { grid-template-columns: 1fr; }
  .discussions-layout { grid-template-columns: 1fr; }
  .calendar-layout { grid-template-columns: 1fr; }
  .profile-layout { grid-template-columns: 1fr; }

  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; z-index: 200; transform: translateX(-100%); }
  .sidebar.open { transform: translateX(0); }
  .sidebar-toggle { display: block; }
  /* Tap-outside-to-close scrim — sits between the sidebar (200) and the
     rest of the page, only interactive/visible while the drawer is open. */
  .sidebar-backdrop {
    display: none; position: fixed; inset: 0; z-index: 199;
    background: rgba(0,0,0,0.45);
  }
  .sidebar-backdrop.open { display: block; }
}
@media (max-width: 600px) {
  #pages { padding: 16px; }
  .form-grid { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .course-view-layout { grid-template-columns: 1fr; }
  .parent-stats { grid-template-columns: 1fr 1fr; }
  .card, .modal-box { padding: 16px; }
  .modal { padding: 12px; }
  .builder-module-header { padding: 10px; }
}

/* ── PRINT (certificates) ──────────────────────── */
@media print {
  #sidebar, #topbar, #cert-viewer > div:last-child { display: none !important; }
  #main { overflow: visible; }
  #pages { padding: 0; }
  /* Border stays the same brand red as on-screen/PDF (not var(--primary),
     which would print blue) — and print-color-adjust is required for the
     watermark background-image + colored borders to survive most browsers'
     default "skip backgrounds when printing" behavior. */
  .certificate-frame {
    border: 8px solid #CC0000 !important; box-shadow: none !important;
    print-color-adjust: exact; -webkit-print-color-adjust: exact;
  }
}
