@font-face{font-family:'Inter';src:url('/assets/fonts/inter/inter-variable.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap;}
@font-face{font-family:'JetBrains Mono';src:url('/assets/fonts/jetbrains-mono/jetbrainsmono-variable.woff2') format('woff2');font-weight:100 800;font-style:normal;font-display:swap;}

/* ===== core/tokens.css ===== */
/* ===================================================================
   DCS Design System - Design Tokens
   Version: 2.0.0

   Core design tokens including colors, typography, spacing, and themes.
   Supports light and dark themes via data-theme attribute on <html>:
   - <html data-theme="dark">  (default, student LMS)
   - <html data-theme="light"> (admin portal)
   =================================================================== */

/* ===================================================================
   1. SHARED TOKENS (Theme-Independent)
   =================================================================== */

:root {
    /* ----- Brand Colors ----- */
    --brand-primary: #00e5ff;
    --brand-primary-rgb: 0, 229, 255;
    --brand-primary-dark: #00b8cc;
    --brand-primary-light: #66f0ff;
    --brand-primary-alpha: rgba(0, 229, 255, 0.15);
    --brand-primary-alpha-strong: rgba(0, 229, 255, 0.30);

    --brand-secondary: #ff9f43;
    --brand-secondary-rgb: 255, 159, 67;
    --brand-secondary-dark: #e68a2e;
    --brand-secondary-light: #ffb76b;
    --brand-secondary-alpha: rgba(255, 159, 67, 0.15);

    /* ----- Status Colors (Base) ----- */
    --color-success: #10b981;
    --color-success-dark: #059669;
    --color-danger: #ef4444;
    --color-danger-dark: #dc2626;
    --color-warning: #f59e0b;
    --color-warning-dark: #d97706;
    --color-info: #3b82f6;
    --color-info-dark: #2563eb;

    /* ----- Spacing Scale ----- */
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 32px;
    --space-2xl: 48px;
    --space-3xl: 64px;

    /* ----- Typography ----- */
    --font-family-base: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-family-mono: 'JetBrains Mono', 'Fira Code', 'Monaco', 'Menlo', 'Consolas', monospace;

    --font-size-xs: 0.75rem;
    --font-size-sm: 0.875rem;
    --font-size-base: 1rem;
    --font-size-lg: 1.125rem;
    --font-size-xl: 1.25rem;
    --font-size-2xl: 1.5rem;
    --font-size-3xl: 2rem;
    --font-size-4xl: 2.5rem;

    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;

    --line-height-tight: 1.25;
    --line-height-base: 1.5;
    --line-height-relaxed: 1.75;

    /* ----- Border Radius ----- */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-2xl: 24px;
    --radius-full: 9999px;

    /* ----- Transitions ----- */
    --transition-fast: 150ms ease;
    --transition-base: 200ms ease;
    --transition-slow: 300ms ease;
    --transition-slower: 400ms ease;

    /* ----- Z-Index Scale ----- */
    --z-base: 0;
    --z-dropdown: 100;
    --z-sticky: 200;
    --z-fixed: 300;
    --z-modal-backdrop: 400;
    --z-modal: 500;
    --z-popover: 600;
    --z-tooltip: 700;
    --z-toast: 800;

    /* ----- Activity Type Colors ----- */
    --activity-assignment: #b45309;
    --activity-skill-check: #16a34a;
    --activity-question-set: #6366f1;
    --activity-page: #7c3aed;
    --activity-multi-page: #7c3aed;
    --activity-link: #1d4ed8;
    --activity-workplace: #0891b2;
    --activity-file: #0284c7;
    --activity-html: #be185d;
    --activity-header: #6b7280;
    --activity-video: #ef4444;
    --activity-typing: #10b981;

    /* ----- Grade Scale Colors ----- */
    --grade-color-b: #84cc16;
    --grade-color-d: #f97316;

    /* ----- Overlay Backgrounds ----- */
    --bg-overlay-dark: rgba(0, 0, 0, 0.8);
    --bg-overlay-medium: rgba(0, 0, 0, 0.5);
    /* Light dim for spotlight/coach-mark overlays — the de-emphasised area
       must stay legible enough to work in. */
    --bg-overlay-subtle: rgba(0, 0, 0, 0.35);
    --bg-overlay-light: rgba(255, 255, 255, 0.3);
    --bg-overlay-hover: rgba(255, 255, 255, 0.1);
    --bg-overlay-element: rgba(255, 255, 255, 0.08);
    --bg-scrim: rgba(0, 0, 0, 0.6);
    --border-overlay: rgba(255, 255, 255, 0.15);
    --border-overlay-light: rgba(255, 255, 255, 0.2);

    /* ----- Focus Ring Patterns ----- */
    --focus-ring: 0 0 0 3px rgba(var(--brand-primary-rgb), 0.15);
    --focus-ring-success: 0 0 0 3px rgba(16, 185, 129, 0.15);
    --focus-ring-danger: 0 0 0 3px rgba(239, 68, 68, 0.15);

    /* ----- Text on Colored Backgrounds ----- */
    --text-on-brand: #ffffff;
    --text-on-success: #ffffff;
    --text-on-danger: #ffffff;
    --text-on-warning: #000000;
    --text-on-info: #ffffff;
    --text-on-overlay: #ffffff;
    --text-on-overlay-muted: rgba(255, 255, 255, 0.6);
    --text-on-overlay-subtle: rgba(255, 255, 255, 0.4);

    /* ----- Container Widths ----- */
    --container-sm: 640px;
    --container-md: 768px;
    --container-lg: 1024px;
    --container-xl: 1280px;
    --container-2xl: 1536px;
}

/* ===================================================================
   2. DARK THEME (Default)
   =================================================================== */

:root,
[data-theme="dark"] {
    color-scheme: dark;

    /* Text */
    --text-primary: #e6f1ff;
    --text-secondary: #a8b2d1;
    --text-muted: #8892b0;
    --text-light: #ccd6f6;
    --text-inverse: #0a192f;

    /* Backgrounds */
    --bg-body: #0a192f;
    --bg-body-rgb: 10, 25, 47;
    --bg-surface: #112240;
    --bg-surface-rgb: 17, 34, 64;
    --bg-elevated: #1d3461;
    --bg-input: #233554;
    --bg-hover: #304066;
    --bg-active: #3d4f7c;
    --bg-overlay: rgba(2, 12, 27, 0.85);

    /* Background Pattern (none for dark theme) */
    --bg-pattern: none;
    --bg-pattern-size: auto;

    /* Borders */
    --border-light: #233554;
    --border-medium: #304066;
    --border-dark: #4d5b7c;
    --border-secondary: #2a3a5c;
    --border-focus: var(--brand-primary);

    /* Shadows */
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
    --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.25);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-xl: 0 12px 48px rgba(0, 0, 0, 0.4);
    --shadow-glow: 0 0 20px rgba(var(--brand-primary-rgb), 0.3);

    /* Status Colors (Neon for dark) */
    --color-success-text: #00ff9d;
    --color-success-bg: rgba(16, 185, 129, 0.15);
    --color-danger-text: #ff6b7a;
    --color-danger-bg: rgba(239, 68, 68, 0.15);
    --color-warning-text: #ffc107;
    --color-warning-bg: rgba(245, 158, 11, 0.15);
    --color-info-text: #60a5fa;
    --color-info-bg: rgba(59, 130, 246, 0.15);

    /* 3D gizmo axis colours — label the Move/Rotate/Scale handles in the 3D
       Composer tutorial. Tuned per theme so the legend stays legible. */
    --axis-x: #f87171;
    --axis-y: #4ade80;
    --axis-z: #60a5fa;

    /* Purple Color (for random/randomized indicators) */
    --color-purple: #a78bfa;
    --color-purple-bg: rgba(139, 92, 246, 0.15);
    --color-purple-bg-subtle: rgba(139, 92, 246, 0.08);
    --color-purple-border: rgba(139, 92, 246, 0.3);
    --color-purple-text: #c4b5fd;

    /* Badge tier colors (used by typing module badges + future tiered badges) */
    --color-bronze-bg: rgba(194, 120, 68, 0.18);
    --color-bronze-text: #e9a880;
    --color-silver-bg: rgba(180, 190, 200, 0.18);
    --color-silver-text: #d4dce4;

    /* Game canvas background (typing games render a darker frame around the
       canvas — visually distinct from the LMS chrome but theme-consistent). */
    --game-canvas-bg: #0d1117;

    /* Full-screen modal scrim (results/stretch-break overlays). Same value in
       both themes — it darkens whatever is behind the modal. */
    --overlay-scrim: rgba(0, 0, 0, 0.85);

    /* Typing: virtual-keyboard visual chrome. The keyboard visual is
       always-dark in both themes (matches the RGB-keyboard aesthetic). */
    --keyboard-bg: #1a1a2e;
    --keyboard-key-bg: #2d2d44;
    --keyboard-key-border: #3d3d5c;
    --keyboard-key-muted: #888;

    /* Typing: pedagogical finger-zone colors. Color-coded pedagogy (matching
       printed charts + hand overlays), identical in both themes. */
    --finger-pinky-l: #FF0055;
    --finger-ring-l: #FF6600;
    --finger-middle-l: #FFFF00;
    --finger-index-l: #00FF00;
    --finger-index-r: #00FFFF;
    --finger-middle-r: #0088FF;
    --finger-ring-r: #8800FF;
    --finger-pinky-r: #FF00FF;
    --finger-thumb: #FFFFFF;

    /* Student Notebook v2 handwriting (Task 10). A handwriting page is paper
       — it is rendered on screen, snapshotted to PNG, and printed to PDF, and
       all three must show the identical colour. This is a deliberate,
       teacher-ratified exception to the token theme system (same class as
       the File Management Simulator's intentionally Windows-coloured
       Explorer chrome): these seven values are IDENTICAL in both the dark
       and light theme blocks below, on purpose. Do not "fix" this in a
       future token audit by diverging them per theme — ink must stay
       independent of theme and of render target. `color` values stored in
       stroke JSON are palette KEYS (ink/blue/red/green/highlight), never raw
       colours — see shared/includes/notebook/constants.php. */
    --notebook-paper: #fdfdfa;
    --notebook-paper-line: #e4e4dd;
    --notebook-ink-ink: #1b1b1f;
    --notebook-ink-blue: #1d4ed8;
    --notebook-ink-red: #b91c1c;
    --notebook-ink-green: #15803d;
    --notebook-ink-highlight: #fde68a;

    /* Urgency Colors */
    --urgency-critical: #ff4757;
    --urgency-critical-bg: #2d1414;
    --urgency-high: #ff7f50;
    --urgency-high-bg: #2d1e14;
    --urgency-medium: #ffa502;
    --urgency-medium-bg: #2d2614;
    --urgency-low: #2ed573;
    --urgency-low-bg: #14281d;

    /* Forms */
    --input-bg: var(--bg-input);
    --input-border: var(--border-medium);
    --input-text: var(--text-primary);
    --input-placeholder: var(--text-muted);
    --input-focus-border: var(--brand-primary);
    --input-focus-shadow: 0 0 0 3px rgba(var(--brand-primary-rgb), 0.15);

    /* Buttons */
    --btn-primary-bg: var(--brand-primary);
    --btn-primary-text: #0a192f;
    --btn-primary-hover: var(--brand-primary-dark);
    --btn-secondary-bg: var(--bg-input);
    --btn-secondary-text: var(--text-primary);
    --btn-secondary-hover: var(--bg-hover);
    --btn-secondary-border: var(--border-medium);

    /* Links */
    --link-color: var(--brand-primary);
    --link-hover: var(--brand-primary-light);

    /* Cards */
    --card-bg: var(--bg-surface);
    --card-border: var(--border-light);
    --card-header-bg: var(--bg-input);

    /* Microsoft Office app accents (doc-example component). Brand colours —
       identical in both themes by design. */
    --office-word: #2b579a;
    --office-excel: #217346;
    --office-powerpoint: #b7472a;
    --office-access: #a4373a;
}

/* ===================================================================
   3. LIGHT THEME
   =================================================================== */

[data-theme="light"] {
    color-scheme: light;

    /* Text - Ink Black for high contrast */
    --text-primary: #0f172a;
    --text-secondary: #334155;
    --text-muted: #64748b;
    --text-light: #94a3b8;
    --text-inverse: #ffffff;

    /* Backgrounds - Ice White */
    --bg-body: #f8fafc;
    --bg-body-rgb: 248, 250, 252;
    --bg-surface: #ffffff;
    --bg-surface-rgb: 255, 255, 255;
    --bg-elevated: #ffffff;
    --bg-input: #ffffff;
    --bg-hover: #f1f5f9;
    --bg-active: #e2e8f0;
    --bg-overlay: rgba(15, 23, 42, 0.5);

    /* Background Pattern - Subtle dot grid */
    --bg-pattern: radial-gradient(#cbd5e1 1px, transparent 1px);
    --bg-pattern-size: 24px 24px;

    /* Borders - Sharper for light theme */
    --border-light: #e2e8f0;
    --border-medium: #cbd5e1;
    --border-dark: #94a3b8;
    --border-secondary: #d7dee9;
    --border-focus: var(--brand-primary-dark);

    /* Shadows - No glow in light theme */
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
    --shadow-xl: 0 12px 48px rgba(0, 0, 0, 0.15);
    --shadow-glow: none;

    /* Status Colors (Softer for light) */
    --color-success-text: #059669;
    --color-success-bg: rgba(16, 185, 129, 0.1);
    --color-danger-text: #dc2626;
    --color-danger-bg: rgba(239, 68, 68, 0.1);
    --color-warning-text: #d97706;
    --color-warning-bg: rgba(245, 158, 11, 0.1);
    --color-info-text: #2563eb;
    --color-info-bg: rgba(59, 130, 246, 0.1);

    /* 3D gizmo axis colours — see the dark block. Darkened for white surfaces. */
    --axis-x: #dc2626;
    --axis-y: #15803d;
    --axis-z: #2563eb;

    /* Purple Color (for random/randomized indicators) */
    --color-purple: #8b5cf6;
    --color-purple-bg: rgba(139, 92, 246, 0.1);
    --color-purple-bg-subtle: rgba(139, 92, 246, 0.05);
    --color-purple-border: rgba(139, 92, 246, 0.2);
    --color-purple-text: #7c3aed;

    /* Badge tier colors (light theme — deeper text + softer background) */
    --color-bronze-bg: rgba(194, 120, 68, 0.14);
    --color-bronze-text: #a85d2a;
    --color-silver-bg: rgba(120, 134, 152, 0.14);
    --color-silver-text: #475569;

    /* Game canvas background — keep dark even on light theme. Typing games
       render on the same dark backdrop in both themes so their visuals stay
       coherent; only the LMS chrome around them re-themes. */
    --game-canvas-bg: #0d1117;

    /* Full-screen modal scrim (results/stretch-break overlays). Same value in
       both themes — it darkens whatever is behind the modal. */
    --overlay-scrim: rgba(0, 0, 0, 0.85);

    /* Typing: virtual-keyboard visual chrome — always-dark in both themes. */
    --keyboard-bg: #1a1a2e;
    --keyboard-key-bg: #2d2d44;
    --keyboard-key-border: #3d3d5c;
    --keyboard-key-muted: #888;

    /* Typing: pedagogical finger-zone colors — identical in both themes. */
    --finger-pinky-l: #FF0055;
    --finger-ring-l: #FF6600;
    --finger-middle-l: #FFFF00;
    --finger-index-l: #00FF00;
    --finger-index-r: #00FFFF;
    --finger-middle-r: #0088FF;
    --finger-ring-r: #8800FF;
    --finger-pinky-r: #FF00FF;
    --finger-thumb: #FFFFFF;

    /* Student Notebook v2 handwriting (Task 10) — identical in both themes.
       See the dark block above for the full rationale: a handwriting page is
       paper, gets printed, and must match on screen, in its PNG snapshot and
       in the PDF. Do not diverge these per theme. */
    --notebook-paper: #fdfdfa;
    --notebook-paper-line: #e4e4dd;
    --notebook-ink-ink: #1b1b1f;
    --notebook-ink-blue: #1d4ed8;
    --notebook-ink-red: #b91c1c;
    --notebook-ink-green: #15803d;
    --notebook-ink-highlight: #fde68a;

    /* Urgency Colors */
    --urgency-critical: #dc2626;
    --urgency-critical-bg: #fef2f2;
    --urgency-high: #ea580c;
    --urgency-high-bg: #fff7ed;
    --urgency-medium: #d97706;
    --urgency-medium-bg: #fffbeb;
    --urgency-low: #16a34a;
    --urgency-low-bg: #f0fdf4;

    /* Forms */
    --input-bg: var(--bg-input);
    --input-border: var(--border-medium);
    --input-text: var(--text-primary);
    --input-placeholder: var(--text-muted);
    --input-focus-border: var(--brand-primary-dark);
    --input-focus-shadow: 0 0 0 3px rgba(var(--brand-primary-rgb), 0.1);

    /* Buttons - Adjusted for light theme */
    --btn-primary-bg: #00b8cc;
    --btn-primary-text: #ffffff;
    --btn-primary-hover: #009db3;
    --btn-secondary-bg: #ffffff;
    --btn-secondary-text: var(--text-primary);
    --btn-secondary-hover: var(--bg-hover);
    --btn-secondary-border: var(--border-medium);

    /* Links */
    --link-color: var(--brand-primary-dark);
    --link-hover: var(--brand-primary);

    /* Cards */
    --card-bg: var(--bg-surface);
    --card-border: var(--border-light);
    --card-header-bg: var(--bg-hover);

    /* Microsoft Office app accents (doc-example component). Brand colours —
       identical in both themes by design. */
    --office-word: #2b579a;
    --office-excel: #217346;
    --office-powerpoint: #b7472a;
    --office-access: #a4373a;

    /* Adjusted brand colors for contrast */
    --brand-primary: #00b8cc;
    --brand-secondary: #e68a2e;
}

/* ===================================================================
   4. COMPATIBILITY ALIASES
   These provide common alternative names for design tokens.
   Prefer using the canonical names above when writing new code.
   =================================================================== */

:root,
[data-theme="dark"],
[data-theme="light"] {
    /* Accent = Brand (common alias) */
    --accent-primary: var(--brand-primary);
    --accent-primary-dark: var(--brand-primary-dark);

    /* Border aliases */
    --border-primary: var(--border-medium);
    --border-subtle: var(--border-light);
    --border-default: var(--border-medium);
    /* Legacy alias: `var(--border-color)` is used ~128× across the student site
       (incl. header.php on every page). Without this it was invalid-at-computed-
       value and every card/panel border silently fell back to currentcolor. */
    --border-color: var(--border-medium);

    /* Background aliases */
    --bg-secondary: var(--bg-hover);
    --bg-tertiary: var(--bg-input);
    /* Used by the Daily Briefing page since 2026-03 but never defined — the
       card headers/items silently rendered transparent in both themes.
       Aliased 2026-07-02 so they finally get their intended tinting. */
    --bg-subtle: var(--bg-elevated);
    --bg-muted: var(--bg-hover);

    /* Status aliases (shorter names) */
    --status-success-bg: var(--color-success-bg);
    --status-success-text: var(--color-success-text);
    --status-danger-bg: var(--color-danger-bg);
    --status-danger-text: var(--color-danger-text);
    --status-warning-bg: var(--color-warning-bg);
    --status-warning-text: var(--color-warning-text);
    --status-info-bg: var(--color-info-bg);
    --status-info-text: var(--color-info-text);

    /* Overlay/Dark background for media players, badges on dark */
    --overlay-dark: var(--bg-overlay-dark);
    --text-on-dark: var(--text-on-brand);
}


/* ===== core/base.css ===== */
/* ===================================================================
   DCS Design System - Base Styles
   Version: 2.0.0

   Reset, typography, and foundational element styles.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. CSS RESET (Modern Minimal)
   =================================================================== */

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

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    scroll-behavior: smooth;
}

body {
    min-height: 100vh;
    font-family: var(--font-family-base);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-normal);
    line-height: var(--line-height-base);
    color: var(--text-primary);
    background-color: var(--bg-body);
    background-image: var(--bg-pattern);
    background-size: var(--bg-pattern-size, auto);
    transition: background-color var(--transition-base), color var(--transition-base);
}

/* Remove default list styles */
ul, ol {
    list-style: none;
}

/* Remove default anchor styles */
a {
    color: inherit;
    text-decoration: none;
}

/* Prevent img from overflowing */
img, picture, video, canvas, svg {
    display: block;
    max-width: 100%;
    height: auto;
}

/* Remove built-in form typography */
input, button, textarea, select {
    font: inherit;
    color: inherit;
}

/* Remove default button styles */
button {
    background: none;
    border: none;
    cursor: pointer;
}

/* Avoid text overflow */
p, h1, h2, h3, h4, h5, h6 {
    overflow-wrap: break-word;
}

/* Remove default table spacing */
table {
    border-collapse: collapse;
    border-spacing: 0;
}

/* Hidden attribute support */
[hidden] {
    display: none !important;
}

/* ===================================================================
   2. TYPOGRAPHY
   =================================================================== */

/* ----- Headings ----- */
h1, h2, h3, h4, h5, h6 {
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
    margin-bottom: var(--space-md);
}

h1 {
    font-size: var(--font-size-4xl);
}

h2 {
    font-size: var(--font-size-3xl);
}

h3 {
    font-size: var(--font-size-2xl);
}

h4 {
    font-size: var(--font-size-xl);
}

h5 {
    font-size: var(--font-size-lg);
}

h6 {
    font-size: var(--font-size-base);
}

/* ----- Paragraphs & Body Text ----- */
p {
    margin-bottom: var(--space-md);
    color: var(--text-secondary);
}

.lead {
    font-size: var(--font-size-lg);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

.small, small {
    font-size: var(--font-size-sm);
}

.text-xs {
    font-size: var(--font-size-xs);
}

.text-muted {
    color: var(--text-muted);
}

.text-light {
    color: var(--text-light);
}

/* ----- Links ----- */
a {
    color: var(--link-color);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--link-hover);
}

a:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Underlined link variant */
.link-underline {
    text-decoration: underline;
    text-underline-offset: 2px;
}

.link-underline:hover {
    text-decoration-color: var(--brand-primary);
}

/* ----- Text Utilities ----- */
.text-center { text-align: center; }
.text-left { text-align: left; }
.text-right { text-align: right; }

.font-normal { font-weight: var(--font-weight-normal); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }

.uppercase { text-transform: uppercase; }
.lowercase { text-transform: lowercase; }
.capitalize { text-transform: capitalize; }

.truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.line-clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.line-clamp-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ----- Monospace / Code ----- */
/* No ligatures: the mono font draws != as ≠ and => as an arrow, and
   students must see the characters they type. */
code, kbd, pre, samp {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
    font-variant-ligatures: none;
}

code {
    padding: 2px 6px;
    background: var(--bg-input);
    border-radius: var(--radius-sm);
    color: var(--brand-primary);
}

pre {
    padding: var(--space-md);
    background: var(--bg-input);
    border-radius: var(--radius-md);
    overflow-x: auto;
    margin-bottom: var(--space-md);
}

pre code {
    padding: 0;
    background: none;
}

kbd {
    padding: 2px 6px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-xs);
}

/* ----- Horizontal Rule ----- */
hr {
    border: none;
    height: 1px;
    background: var(--border-light);
    margin: var(--space-xl) 0;
}

/* ===================================================================
   3. SELECTION
   =================================================================== */

::selection {
    background: var(--brand-primary-alpha-strong);
    color: var(--text-primary);
}

/* ===================================================================
   4. SCROLLBAR (Webkit)
   =================================================================== */

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--bg-body);
}

::-webkit-scrollbar-thumb {
    background: var(--border-medium);
    border-radius: var(--radius-full);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--border-dark);
}

/* Firefox scrollbar */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--border-medium) var(--bg-body);
}

/* ===================================================================
   5. FOCUS STATES
   =================================================================== */

:focus {
    outline: none;
}

:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}


/* ===== core/utilities.css ===== */
/* ===================================================================
   DCS Design System - Utility Classes
   Version: 2.0.0

   Layout, spacing, display, and visibility utility classes.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. LAYOUT UTILITIES
   =================================================================== */

.container {
    width: 100%;
    max-width: var(--container-xl);
    margin-inline: auto;
    padding-inline: var(--space-md);
}

.container-sm { max-width: var(--container-sm); }
.container-md { max-width: var(--container-md); }
.container-lg { max-width: var(--container-lg); }
.container-2xl { max-width: var(--container-2xl); }

/* ===================================================================
   2. SPACING UTILITIES
   =================================================================== */

/* Margin */
.m-0 { margin: 0; }
.m-xs { margin: var(--space-xs); }
.m-sm { margin: var(--space-sm); }
.m-md { margin: var(--space-md); }
.m-lg { margin: var(--space-lg); }
.m-xl { margin: var(--space-xl); }
.m-2xl { margin: var(--space-2xl); }

.mt-0 { margin-top: 0; }
.mt-xs { margin-top: var(--space-xs); }
.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mt-lg { margin-top: var(--space-lg); }
.mt-xl { margin-top: var(--space-xl); }
.mt-2xl { margin-top: var(--space-2xl); }

.mr-0 { margin-right: 0; }
.mr-xs { margin-right: var(--space-xs); }
.mr-sm { margin-right: var(--space-sm); }
.mr-md { margin-right: var(--space-md); }
.mr-lg { margin-right: var(--space-lg); }
.mr-xl { margin-right: var(--space-xl); }

.mb-0 { margin-bottom: 0; }
.mb-xs { margin-bottom: var(--space-xs); }
.mb-sm { margin-bottom: var(--space-sm); }
.mb-md { margin-bottom: var(--space-md); }
.mb-lg { margin-bottom: var(--space-lg); }
.mb-xl { margin-bottom: var(--space-xl); }
.mb-2xl { margin-bottom: var(--space-2xl); }

.ml-0 { margin-left: 0; }
.ml-xs { margin-left: var(--space-xs); }
.ml-sm { margin-left: var(--space-sm); }
.ml-md { margin-left: var(--space-md); }
.ml-lg { margin-left: var(--space-lg); }
.ml-xl { margin-left: var(--space-xl); }

.mx-0 { margin-left: 0; margin-right: 0; }
.mx-auto { margin-left: auto; margin-right: auto; }
.mx-xs { margin-left: var(--space-xs); margin-right: var(--space-xs); }
.mx-sm { margin-left: var(--space-sm); margin-right: var(--space-sm); }
.mx-md { margin-left: var(--space-md); margin-right: var(--space-md); }

.my-0 { margin-top: 0; margin-bottom: 0; }
.my-xs { margin-top: var(--space-xs); margin-bottom: var(--space-xs); }
.my-sm { margin-top: var(--space-sm); margin-bottom: var(--space-sm); }
.my-md { margin-top: var(--space-md); margin-bottom: var(--space-md); }
.my-lg { margin-top: var(--space-lg); margin-bottom: var(--space-lg); }
.my-xl { margin-top: var(--space-xl); margin-bottom: var(--space-xl); }

/* Padding */
.p-0 { padding: 0; }
.p-xs { padding: var(--space-xs); }
.p-sm { padding: var(--space-sm); }
.p-md { padding: var(--space-md); }
.p-lg { padding: var(--space-lg); }
.p-xl { padding: var(--space-xl); }
.p-2xl { padding: var(--space-2xl); }

.pt-0 { padding-top: 0; }
.pt-xs { padding-top: var(--space-xs); }
.pt-sm { padding-top: var(--space-sm); }
.pt-md { padding-top: var(--space-md); }
.pt-lg { padding-top: var(--space-lg); }
.pt-xl { padding-top: var(--space-xl); }

.pr-0 { padding-right: 0; }
.pr-xs { padding-right: var(--space-xs); }
.pr-sm { padding-right: var(--space-sm); }
.pr-md { padding-right: var(--space-md); }
.pr-lg { padding-right: var(--space-lg); }
.pr-xl { padding-right: var(--space-xl); }

.pb-0 { padding-bottom: 0; }
.pb-xs { padding-bottom: var(--space-xs); }
.pb-sm { padding-bottom: var(--space-sm); }
.pb-md { padding-bottom: var(--space-md); }
.pb-lg { padding-bottom: var(--space-lg); }
.pb-xl { padding-bottom: var(--space-xl); }

.pl-0 { padding-left: 0; }
.pl-xs { padding-left: var(--space-xs); }
.pl-sm { padding-left: var(--space-sm); }
.pl-md { padding-left: var(--space-md); }
.pl-lg { padding-left: var(--space-lg); }
.pl-xl { padding-left: var(--space-xl); }

.px-0 { padding-left: 0; padding-right: 0; }
.px-xs { padding-left: var(--space-xs); padding-right: var(--space-xs); }
.px-sm { padding-left: var(--space-sm); padding-right: var(--space-sm); }
.px-md { padding-left: var(--space-md); padding-right: var(--space-md); }
.px-lg { padding-left: var(--space-lg); padding-right: var(--space-lg); }
.px-xl { padding-left: var(--space-xl); padding-right: var(--space-xl); }

.py-0 { padding-top: 0; padding-bottom: 0; }
.py-xs { padding-top: var(--space-xs); padding-bottom: var(--space-xs); }
.py-sm { padding-top: var(--space-sm); padding-bottom: var(--space-sm); }
.py-md { padding-top: var(--space-md); padding-bottom: var(--space-md); }
.py-lg { padding-top: var(--space-lg); padding-bottom: var(--space-lg); }
.py-xl { padding-top: var(--space-xl); padding-bottom: var(--space-xl); }

/* ===================================================================
   3. DISPLAY UTILITIES
   =================================================================== */

.d-none { display: none; }
.d-block { display: block; }
.d-inline { display: inline; }
.d-inline-block { display: inline-block; }
.d-flex { display: flex; }
.d-inline-flex { display: inline-flex; }
.d-grid { display: grid; }

/* Flexbox utilities */
.flex-row { flex-direction: row; }
.flex-row-reverse { flex-direction: row-reverse; }
.flex-column { flex-direction: column; }
.flex-column-reverse { flex-direction: column-reverse; }
.flex-wrap { flex-wrap: wrap; }
.flex-nowrap { flex-wrap: nowrap; }
.flex-1 { flex: 1; }
.flex-auto { flex: auto; }
.flex-none { flex: none; }
.flex-grow-0 { flex-grow: 0; }
.flex-grow-1 { flex-grow: 1; }
.flex-shrink-0 { flex-shrink: 0; }
.flex-shrink-1 { flex-shrink: 1; }

.justify-start { justify-content: flex-start; }
.justify-end { justify-content: flex-end; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-around { justify-content: space-around; }
.justify-evenly { justify-content: space-evenly; }

.align-start { align-items: flex-start; }
.align-end { align-items: flex-end; }
.align-center { align-items: center; }
.align-baseline { align-items: baseline; }
.align-stretch { align-items: stretch; }

.align-self-start { align-self: flex-start; }
.align-self-end { align-self: flex-end; }
.align-self-center { align-self: center; }
.align-self-stretch { align-self: stretch; }

.gap-0 { gap: 0; }
.gap-xs { gap: var(--space-xs); }
.gap-sm { gap: var(--space-sm); }
.gap-md { gap: var(--space-md); }
.gap-lg { gap: var(--space-lg); }
.gap-xl { gap: var(--space-xl); }
.gap-2xl { gap: var(--space-2xl); }

/* ===================================================================
   4. VISIBILITY & SCREEN READER
   =================================================================== */

.visually-hidden,
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Tab-stop parking spot (2026-09-10): an empty, tabindex="-1" element a
   page focuses on load so the FIRST Tab lands on the control right after it
   in the DOM (the grading pages park it before "Use suggestion"). Never in
   the tab order itself, never visible. */
.focus-anchor {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
    outline: none;
}

.visible { visibility: visible; }
.invisible { visibility: hidden; }

/* ===================================================================
   5. POSITION UTILITIES
   =================================================================== */

.position-static { position: static; }
.position-relative { position: relative; }
.position-absolute { position: absolute; }
.position-fixed { position: fixed; }
.position-sticky { position: sticky; }

.top-0 { top: 0; }
.right-0 { right: 0; }
.bottom-0 { bottom: 0; }
.left-0 { left: 0; }
.inset-0 { inset: 0; }

/* ===================================================================
   6. WIDTH & HEIGHT UTILITIES
   =================================================================== */

.w-auto { width: auto; }
.w-full { width: 100%; }
.w-screen { width: 100vw; }
.w-min { width: min-content; }
.w-max { width: max-content; }
.w-fit { width: fit-content; }

.h-auto { height: auto; }
.h-full { height: 100%; }
.h-screen { height: 100vh; }
.h-min { height: min-content; }
.h-max { height: max-content; }
.h-fit { height: fit-content; }

.min-w-0 { min-width: 0; }
.min-w-full { min-width: 100%; }
.max-w-full { max-width: 100%; }
.max-w-none { max-width: none; }

.min-h-0 { min-height: 0; }
.min-h-full { min-height: 100%; }
.min-h-screen { min-height: 100vh; }

/* ===================================================================
   7. OVERFLOW UTILITIES
   =================================================================== */

.overflow-auto { overflow: auto; }
.overflow-hidden { overflow: hidden; }
.overflow-visible { overflow: visible; }
.overflow-scroll { overflow: scroll; }
.overflow-x-auto { overflow-x: auto; }
.overflow-y-auto { overflow-y: auto; }
.overflow-x-hidden { overflow-x: hidden; }
.overflow-y-hidden { overflow-y: hidden; }

/* ===================================================================
   8. Z-INDEX UTILITIES
   =================================================================== */

.z-0 { z-index: 0; }
.z-10 { z-index: 10; }
.z-20 { z-index: 20; }
.z-30 { z-index: 30; }
.z-40 { z-index: 40; }
.z-50 { z-index: 50; }
.z-auto { z-index: auto; }

/* ===================================================================
   9. CURSOR UTILITIES
   =================================================================== */

.cursor-auto { cursor: auto; }
.cursor-default { cursor: default; }
.cursor-pointer { cursor: pointer; }
.cursor-wait { cursor: wait; }
.cursor-text { cursor: text; }
.cursor-move { cursor: move; }
.cursor-not-allowed { cursor: not-allowed; }

/* ===================================================================
   10. USER SELECT UTILITIES
   =================================================================== */

.select-none { user-select: none; }
.select-text { user-select: text; }
.select-all { user-select: all; }
.select-auto { user-select: auto; }

/* ===================================================================
   11. POINTER EVENTS UTILITIES
   =================================================================== */

.pointer-events-none { pointer-events: none; }
.pointer-events-auto { pointer-events: auto; }

/* ===================================================================
   12. BORDER RADIUS UTILITIES
   =================================================================== */

.rounded-none { border-radius: 0; }
.rounded-sm { border-radius: var(--radius-sm); }
.rounded { border-radius: var(--radius-md); }
.rounded-md { border-radius: var(--radius-md); }
.rounded-lg { border-radius: var(--radius-lg); }
.rounded-xl { border-radius: var(--radius-xl); }
.rounded-2xl { border-radius: var(--radius-2xl); }
.rounded-full { border-radius: var(--radius-full); }

/* ===================================================================
   13. SHADOW UTILITIES
   =================================================================== */

.shadow-none { box-shadow: none; }
.shadow-xs { box-shadow: var(--shadow-xs); }
.shadow-sm { box-shadow: var(--shadow-sm); }
.shadow { box-shadow: var(--shadow-md); }
.shadow-md { box-shadow: var(--shadow-md); }
.shadow-lg { box-shadow: var(--shadow-lg); }
.shadow-xl { box-shadow: var(--shadow-xl); }
.shadow-glow { box-shadow: var(--shadow-glow); }

/* ===================================================================
   14. OPACITY UTILITIES
   =================================================================== */

.opacity-0 { opacity: 0; }
.opacity-25 { opacity: 0.25; }
.opacity-50 { opacity: 0.5; }
.opacity-75 { opacity: 0.75; }
.opacity-100 { opacity: 1; }

/* ===================================================================
   15. TRANSITION UTILITIES
   =================================================================== */

.transition-none { transition: none; }
.transition-fast { transition: all var(--transition-fast); }
.transition { transition: all var(--transition-base); }
.transition-slow { transition: all var(--transition-slow); }

/* ===================================================================
   16. TEXT UTILITIES
   =================================================================== */

.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-justify { text-align: justify; }

.text-uppercase { text-transform: uppercase; }
.text-lowercase { text-transform: lowercase; }
.text-capitalize { text-transform: capitalize; }
.text-normal-case { text-transform: none; }

.text-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.text-break {
    word-wrap: break-word;
    word-break: break-word;
}

.whitespace-normal { white-space: normal; }
.whitespace-nowrap { white-space: nowrap; }
.whitespace-pre { white-space: pre; }
.whitespace-pre-wrap { white-space: pre-wrap; }

/* Font weight */
.font-normal { font-weight: var(--font-weight-normal); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }

/* Font size */
.text-xs { font-size: var(--font-size-xs); }
.text-sm { font-size: var(--font-size-sm); }
.text-base { font-size: var(--font-size-base); }
.text-lg { font-size: var(--font-size-lg); }
.text-xl { font-size: var(--font-size-xl); }
.text-2xl { font-size: var(--font-size-2xl); }
.text-3xl { font-size: var(--font-size-3xl); }
.text-4xl { font-size: var(--font-size-4xl); }

/* Text colors */
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-muted { color: var(--text-muted); }
.text-light { color: var(--text-light); }
.text-brand { color: var(--brand-primary); }
.text-success { color: var(--color-success-text); }
.text-danger { color: var(--color-danger-text); }
.text-warning { color: var(--color-warning-text); }
.text-info { color: var(--color-info-text); }

/* ===================================================================
   17. SURFACE UTILITIES (Content Containment)
   =================================================================== */

/* Glass surface - translucent background for headers/widgets over custom backgrounds */
.surface-glass {
    background-color: rgba(var(--bg-surface-rgb), 0.90);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
}

/* Lighter glass variant */
.surface-glass-light {
    background-color: rgba(var(--bg-surface-rgb), 0.75);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
}

/* Text shadow for readability over images (use sparingly) */
.text-shadow-contrast {
    text-shadow:
        0 1px 3px rgba(0, 0, 0, 0.8),
        0 2px 8px rgba(0, 0, 0, 0.6);
}

/* Stronger shadow for light backgrounds */
.text-shadow-contrast-strong {
    text-shadow:
        0 2px 4px rgba(0, 0, 0, 0.9),
        0 4px 12px rgba(0, 0, 0, 0.7);
}

/* ===================================================================
   18. BACKGROUND UTILITIES
   =================================================================== */

.bg-body { background-color: var(--bg-body); }
.bg-surface { background-color: var(--bg-surface); }
.bg-elevated { background-color: var(--bg-elevated); }
.bg-input { background-color: var(--bg-input); }
.bg-hover { background-color: var(--bg-hover); }
.bg-transparent { background-color: transparent; }

/* ===================================================================
   19. PRINT UTILITIES
   =================================================================== */

@media print {
    /* Hide non-essential elements */
    .no-print,
    .sidebar,
    .navbar,
    .nav,
    .btn-fab,
    .toast-container,
    .focus-mode-toggle {
        display: none !important;
    }

    /* Force light mode colors for printing */
    body {
        background: white !important;
        color: black !important;
    }

    .card {
        border: 1px solid #ccc !important;
        box-shadow: none !important;
        break-inside: avoid;
    }

    /* Expand accordions */
    .accordion-content,
    .collapse {
        display: block !important;
        max-height: none !important;
        overflow: visible !important;
    }

    /* Show URLs after links */
    a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 0.8em;
        color: #666;
    }

    /* Page break controls */
    .page-break-before { page-break-before: always; }
    .page-break-after { page-break-after: always; }
    .avoid-break { break-inside: avoid; }
}

/* ===================================================================
   20. REDUCED MOTION
   =================================================================== */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}


/* ===== components/buttons.css ===== */
/* ===================================================================
   DCS Design System - Button Components
   Version: 2.0.0

   Button styles including variants, sizes, and states.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE BUTTON
   =================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-lg);
    font-family: var(--font-family-base);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-base);
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    user-select: none;
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    transition: all var(--transition-base);
    appearance: none;
}

.btn:hover {
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(0);
}

.btn:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

/* Script-moved focus cue (2026-09-10): "Use suggestion" on the grading pages
   hands focus to Save & Next so Enter saves and moves on. :focus-visible stays
   dark when a script moves focus after a mouse click, so the page adds this
   class until the button blurs. Text-primary on the page surface is readable
   in both themes on every button colour. */
.btn.is-next-up {
    outline: 3px solid var(--text-primary);
    outline-offset: 3px;
    animation: btn-next-up 0.9s ease-in-out 2;
}

@keyframes btn-next-up {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.05); }
}

.btn:disabled,
.btn.disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
    transform: none;
}

/* ===================================================================
   2. PRIMARY BUTTON
   =================================================================== */

.btn-primary {
    color: var(--btn-primary-text);
    background-color: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
}

.btn-primary:hover {
    background-color: var(--btn-primary-hover);
    border-color: var(--btn-primary-hover);
    box-shadow: var(--shadow-md), var(--shadow-glow);
}

.btn-primary:active {
    background-color: var(--brand-primary-dark);
    border-color: var(--brand-primary-dark);
}

/* ===================================================================
   3. SECONDARY BUTTON
   =================================================================== */

.btn-secondary {
    color: var(--btn-secondary-text);
    background-color: var(--btn-secondary-bg);
    border-color: var(--btn-secondary-border);
}

.btn-secondary:hover {
    background-color: var(--btn-secondary-hover);
    border-color: var(--brand-primary);
    box-shadow: var(--shadow-sm);
}

.btn-secondary:active {
    background-color: var(--bg-active);
}

/* ===================================================================
   4. OUTLINE VARIANTS
   =================================================================== */

.btn-outline-primary {
    color: var(--brand-primary);
    background-color: transparent;
    border-color: var(--brand-primary);
}

.btn-outline-primary:hover {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    box-shadow: var(--shadow-glow);
}

.btn-outline-secondary {
    color: var(--text-secondary);
    background-color: transparent;
    border-color: var(--border-medium);
}

.btn-outline-secondary:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
    border-color: var(--border-dark);
}

/* ===================================================================
   5. STATUS BUTTONS
   =================================================================== */

/* Success */
.btn-success {
    color: var(--text-on-success);
    background-color: var(--color-success);
    border-color: var(--color-success);
}

.btn-success:hover {
    background-color: var(--color-success-dark);
    border-color: var(--color-success-dark);
    box-shadow: var(--shadow-md);
}

.btn-outline-success {
    color: var(--color-success);
    background-color: transparent;
    border-color: var(--color-success);
}

.btn-outline-success:hover {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

/* Danger */
.btn-danger {
    color: var(--text-on-danger);
    background-color: var(--color-danger);
    border-color: var(--color-danger);
}

.btn-danger:hover {
    background-color: var(--color-danger-dark);
    border-color: var(--color-danger-dark);
    box-shadow: var(--shadow-md);
}

.btn-outline-danger {
    color: var(--color-danger);
    background-color: transparent;
    border-color: var(--color-danger);
}

.btn-outline-danger:hover {
    color: var(--text-on-danger);
    background-color: var(--color-danger);
}

/* Warning */
.btn-warning {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
    border-color: var(--color-warning);
}

.btn-warning:hover {
    background-color: var(--color-warning-dark);
    border-color: var(--color-warning-dark);
    box-shadow: var(--shadow-md);
}

.btn-outline-warning {
    color: var(--color-warning);
    background-color: transparent;
    border-color: var(--color-warning);
}

.btn-outline-warning:hover {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

/* Info */
.btn-info {
    color: var(--text-on-info);
    background-color: var(--color-info);
    border-color: var(--color-info);
}

.btn-info:hover {
    background-color: var(--color-info-dark);
    border-color: var(--color-info-dark);
    box-shadow: var(--shadow-md);
}

.btn-outline-info {
    color: var(--color-info);
    background-color: transparent;
    border-color: var(--color-info);
}

.btn-outline-info:hover {
    color: var(--text-on-info);
    background-color: var(--color-info);
}

/* ===================================================================
   6. GHOST BUTTON (No background or border)
   =================================================================== */

.btn-ghost {
    color: var(--text-secondary);
    background-color: transparent;
    border-color: transparent;
}

.btn-ghost:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.btn-ghost-primary {
    color: var(--brand-primary);
    background-color: transparent;
    border-color: transparent;
}

.btn-ghost-primary:hover {
    background-color: var(--brand-primary-alpha);
}

/* ===================================================================
   7. LINK BUTTON (Looks like a link)
   =================================================================== */

.btn-link {
    color: var(--link-color);
    background-color: transparent;
    border-color: transparent;
    padding: 0;
    font-weight: var(--font-weight-medium);
}

.btn-link:hover {
    color: var(--link-hover);
    text-decoration: underline;
    transform: none;
}

/* ===================================================================
   8. SIZE VARIANTS
   =================================================================== */

.btn-xs {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-xs);
    border-radius: var(--radius-sm);
}

.btn-sm {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    border-radius: var(--radius-sm);
}

.btn-lg {
    padding: var(--space-md) var(--space-xl);
    font-size: var(--font-size-lg);
    border-radius: var(--radius-lg);
}

.btn-xl {
    padding: var(--space-lg) var(--space-2xl);
    font-size: var(--font-size-xl);
    border-radius: var(--radius-lg);
}

/* ===================================================================
   9. FULL WIDTH BUTTON
   =================================================================== */

.btn-block {
    display: flex;
    width: 100%;
}

/* ===================================================================
   10. ICON BUTTON (Square)
   =================================================================== */

.btn-icon {
    padding: var(--space-sm);
    aspect-ratio: 1;
}

.btn-icon.btn-xs {
    padding: var(--space-xs);
}

.btn-icon.btn-sm {
    padding: 6px;
}

.btn-icon.btn-lg {
    padding: var(--space-md);
}

/* Circle variant */
.btn-icon-circle {
    padding: var(--space-sm);
    aspect-ratio: 1;
    border-radius: var(--radius-full);
}

/* ===================================================================
   11. BUTTON GROUP
   =================================================================== */

.btn-group {
    display: inline-flex;
    vertical-align: middle;
}

.btn-group > .btn {
    position: relative;
    flex: 0 1 auto;
    border-radius: 0;
}

.btn-group > .btn:first-child {
    border-top-left-radius: var(--radius-md);
    border-bottom-left-radius: var(--radius-md);
}

.btn-group > .btn:last-child {
    border-top-right-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}

.btn-group > .btn:not(:first-child) {
    margin-left: -2px;
}

.btn-group > .btn:hover,
.btn-group > .btn:focus,
.btn-group > .btn:active,
.btn-group > .btn.active {
    z-index: 1;
}

/* Vertical button group */
.btn-group-vertical {
    display: inline-flex;
    flex-direction: column;
    vertical-align: middle;
}

.btn-group-vertical > .btn {
    border-radius: 0;
}

.btn-group-vertical > .btn:first-child {
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
}

.btn-group-vertical > .btn:last-child {
    border-bottom-left-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}

.btn-group-vertical > .btn:not(:first-child) {
    margin-top: -2px;
}

/* ===================================================================
   12. LOADING STATE
   =================================================================== */

.btn-loading {
    position: relative;
    pointer-events: none;
    color: transparent !important;
}

.btn-loading::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    top: 50%;
    left: 50%;
    margin-top: -8px;
    margin-left: -8px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: var(--radius-full);
    animation: btn-spinner 0.6s linear infinite;
}

.btn-loading.btn-primary::after,
.btn-loading.btn-success::after,
.btn-loading.btn-danger::after,
.btn-loading.btn-info::after {
    border-color: var(--text-on-brand);
    border-right-color: transparent;
}

@keyframes btn-spinner {
    to {
        transform: rotate(360deg);
    }
}

/* ===================================================================
   13. PILL SHAPE
   =================================================================== */

.btn-pill {
    border-radius: var(--radius-full);
}

/* ===================================================================
   14. WITH BADGE/COUNT
   =================================================================== */

.btn-badge {
    position: relative;
}

.btn-badge__count {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    font-size: 11px;
    font-weight: var(--font-weight-bold);
    line-height: 18px;
    text-align: center;
    color: var(--text-on-danger);
    background-color: var(--color-danger);
    border-radius: var(--radius-full);
}

/* ===================================================================
   15. CLOSE BUTTON
   =================================================================== */

.btn-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    color: var(--text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.btn-close:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.btn-close::before {
    content: '\00d7';
    font-size: 24px;
    line-height: 1;
}

/* ===================================================================
   16. FLOATING ACTION BUTTON (FAB)
   =================================================================== */

.btn-fab {
    position: fixed;
    bottom: var(--space-xl);
    right: var(--space-xl);
    width: 56px;
    height: 56px;
    padding: 0;
    font-size: var(--font-size-xl);
    color: var(--btn-primary-text);
    background-color: var(--btn-primary-bg);
    border: none;
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-fixed);
}

.btn-fab:hover {
    transform: scale(1.1);
    box-shadow: var(--shadow-xl), var(--shadow-glow);
}

.btn-fab.btn-sm {
    width: 40px;
    height: 40px;
    font-size: var(--font-size-base);
}

/* ===================================================================
   12. CLOSE BUTTON (Bootstrap .btn-close replacement)
   =================================================================== */

.btn-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    color: var(--text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    position: relative;
}

.btn-close::before,
.btn-close::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 2px;
    background-color: currentColor;
    border-radius: 1px;
}

.btn-close::before {
    transform: rotate(45deg);
}

.btn-close::after {
    transform: rotate(-45deg);
}

.btn-close:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.btn-close:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

/* White variant for dark backgrounds */
.btn-close-white {
    color: var(--text-on-overlay-muted);
}

.btn-close-white:hover {
    color: var(--text-on-overlay);
    background-color: var(--bg-overlay-hover);
}

/* Small variant */
.btn-close-sm {
    width: 24px;
    height: 24px;
}

.btn-close-sm::before,
.btn-close-sm::after {
    width: 12px;
}

/* Large variant */
.btn-close-lg {
    width: 40px;
    height: 40px;
}

.btn-close-lg::before,
.btn-close-lg::after {
    width: 20px;
    height: 2.5px;
}


/* ===== components/forms.css ===== */
/* ===================================================================
   DCS Design System - Form Components
   Version: 2.0.0

   Form elements: inputs, textareas, selects, checkboxes, radios, etc.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. FORM LAYOUT
   =================================================================== */

.form-group {
    margin-bottom: var(--space-lg);
}

.form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
}

.form-row > * {
    flex: 1;
    min-width: 200px;
}

/* ===================================================================
   2. LABELS
   =================================================================== */

.form-label {
    display: block;
    margin-bottom: var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
}

.form-label--required::after {
    content: ' *';
    color: var(--color-danger);
}

/* Inline label with icon */
.form-label--inline {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/* ===================================================================
   3. TEXT INPUTS & TEXTAREAS
   =================================================================== */

.form-control {
    display: block;
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-normal);
    line-height: var(--line-height-base);
    color: var(--input-text);
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    transition: border-color var(--transition-base),
                box-shadow var(--transition-base),
                background-color var(--transition-base);
    appearance: none;
}

.form-control::placeholder {
    color: var(--input-placeholder);
    opacity: 1;
}

.form-control:hover {
    border-color: var(--border-dark);
}

.form-control:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
    background-color: var(--bg-body);
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--bg-hover);
    opacity: 0.7;
    cursor: not-allowed;
}

/* Size variants */
.form-control--sm {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    border-radius: var(--radius-sm);
}

.form-control--lg {
    padding: var(--space-md) var(--space-lg);
    font-size: var(--font-size-lg);
    border-radius: var(--radius-lg);
}

/* Textarea specific */
textarea.form-control {
    min-height: 120px;
    resize: vertical;
}

textarea.form-control--auto-resize {
    resize: none;
    overflow: hidden;
}

/* ===================================================================
   4. INPUT WITH ICON
   =================================================================== */

.input-wrapper {
    position: relative;
}

.input-icon {
    position: absolute;
    left: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    color: var(--brand-primary);
    font-size: var(--font-size-lg);
    pointer-events: none;
    z-index: 1;
}

.input-icon--right {
    left: auto;
    right: var(--space-md);
}

/* Input with left icon */
.input-wrapper .form-control--icon-left {
    padding-left: calc(var(--space-md) * 3);
}

/* Input with right icon */
.input-wrapper .form-control--icon-right {
    padding-right: calc(var(--space-md) * 3);
}

/* Input with both icons */
.input-wrapper .form-control--icon-both {
    padding-left: calc(var(--space-md) * 3);
    padding-right: calc(var(--space-md) * 3);
}

/* ===================================================================
   5. SELECT
   =================================================================== */

.form-select {
    display: block;
    width: 100%;
    padding: var(--space-sm) var(--space-xl) var(--space-sm) var(--space-md);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-normal);
    line-height: var(--line-height-base);
    color: var(--input-text);
    background-color: var(--input-bg);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238892b0' 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 var(--space-md) center;
    background-size: 16px;
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    appearance: none;
    cursor: pointer;
    transition: border-color var(--transition-base),
                box-shadow var(--transition-base);
}

/* Light theme dropdown arrow */
[data-theme="light"] .form-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}

.form-select:hover {
    border-color: var(--border-dark);
}

.form-select:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.form-select:disabled {
    background-color: var(--bg-hover);
    opacity: 0.7;
    cursor: not-allowed;
}

/* Size variants */
.form-select--sm {
    padding: var(--space-xs) var(--space-xl) var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
}

.form-select--lg {
    padding: var(--space-md) var(--space-2xl) var(--space-md) var(--space-lg);
    font-size: var(--font-size-lg);
}

/* ===================================================================
   6. CHECKBOX & RADIO
   =================================================================== */

.form-check {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    min-height: 24px;
    cursor: pointer;
}

.form-check-input {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    margin-top: 2px;
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    appearance: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.form-check-input[type="checkbox"] {
    border-radius: var(--radius-sm);
}

.form-check-input[type="radio"] {
    border-radius: var(--radius-full);
}

.form-check-input:hover {
    border-color: var(--brand-primary);
}

.form-check-input:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.form-check-input:checked {
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

/* Checkbox checkmark */
.form-check-input[type="checkbox"]:checked {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a192f' stroke-width='3'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 14px;
}

/* Radio dot */
.form-check-input[type="radio"]:checked {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='6' fill='%230a192f'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px;
}

.form-check-input:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.form-check-label {
    font-size: var(--font-size-base);
    color: var(--text-primary);
    cursor: pointer;
    user-select: none;
}

.form-check-input:disabled + .form-check-label {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Inline checkboxes/radios */
.form-check--inline {
    display: inline-flex;
    margin-right: var(--space-lg);
}

/* ===================================================================
   7. SWITCH / TOGGLE
   =================================================================== */

.form-switch {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    cursor: pointer;
}

.form-switch-input {
    position: relative;
    width: 48px;
    height: 26px;
    background-color: var(--bg-input);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-full);
    appearance: none;
    cursor: pointer;
    transition: all var(--transition-base);
}

.form-switch-input::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    background-color: var(--text-muted);
    border-radius: var(--radius-full);
    transition: all var(--transition-base);
}

.form-switch-input:hover {
    border-color: var(--brand-primary);
}

.form-switch-input:focus {
    outline: none;
    box-shadow: var(--input-focus-shadow);
}

.form-switch-input:checked {
    background-color: var(--brand-primary-alpha);
    border-color: var(--brand-primary);
}

.form-switch-input:checked::before {
    transform: translateX(22px);
    background-color: var(--brand-primary);
}

.form-switch-input:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.form-switch-label {
    font-size: var(--font-size-base);
    color: var(--text-primary);
    user-select: none;
}

/* ===================================================================
   8. INPUT GROUP (Addons)
   =================================================================== */

.input-group {
    display: flex;
    align-items: stretch;
}

.input-group .form-control {
    flex: 1;
    border-radius: 0;
}

.input-group .form-control:first-child {
    border-top-left-radius: var(--radius-md);
    border-bottom-left-radius: var(--radius-md);
}

.input-group .form-control:last-child {
    border-top-right-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}

.input-group-text {
    display: flex;
    align-items: center;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-base);
    color: var(--text-muted);
    background-color: var(--bg-input);
    border: 2px solid var(--input-border);
    white-space: nowrap;
}

.input-group-text:first-child {
    border-right: none;
    border-top-left-radius: var(--radius-md);
    border-bottom-left-radius: var(--radius-md);
}

.input-group-text:last-child {
    border-left: none;
    border-top-right-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}

/* ===================================================================
   9. FORM VALIDATION STATES
   =================================================================== */

/* Valid state */
.form-control.is-valid,
.form-select.is-valid {
    border-color: var(--color-success);
}

.form-control.is-valid:focus,
.form-select.is-valid:focus {
    border-color: var(--color-success);
    box-shadow: var(--focus-ring-success);
}

/* Invalid state */
.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--color-danger);
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    border-color: var(--color-danger);
    box-shadow: var(--focus-ring-danger);
}

/* Feedback messages */
.form-feedback {
    display: block;
    margin-top: var(--space-xs);
    font-size: var(--font-size-sm);
}

.form-feedback--valid {
    color: var(--color-success-text);
}

.form-feedback--invalid {
    color: var(--color-danger-text);
}

/* Help text */
.form-text {
    display: block;
    margin-top: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* ===================================================================
   10. FLOATING LABELS
   =================================================================== */

.form-floating {
    position: relative;
}

.form-floating > .form-control {
    padding: var(--space-lg) var(--space-md) var(--space-sm);
}

.form-floating > .form-control::placeholder {
    color: transparent;
}

.form-floating > .form-label {
    position: absolute;
    top: 0;
    left: 0;
    padding: var(--space-md);
    pointer-events: none;
    transform-origin: left top;
    transition: all var(--transition-fast);
    margin-bottom: 0;
}

.form-floating > .form-control:focus ~ .form-label,
.form-floating > .form-control:not(:placeholder-shown) ~ .form-label {
    transform: scale(0.8) translateY(-8px);
    color: var(--brand-primary);
}

/* ===================================================================
   11. FILE INPUT
   =================================================================== */

.form-file {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.form-file-input {
    display: none;
}

.form-file-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-lg);
    background-color: var(--bg-input);
    border: 2px dashed var(--border-medium);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-base);
    text-align: center;
}

.form-file-label:hover {
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.form-file-label i {
    font-size: var(--font-size-2xl);
    color: var(--brand-primary);
}

.form-file-text {
    color: var(--text-secondary);
}

.form-file-name {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* ===================================================================
   12. RANGE / SLIDER
   =================================================================== */

.form-range {
    width: 100%;
    height: 8px;
    background: var(--bg-input);
    border-radius: var(--radius-full);
    appearance: none;
    cursor: pointer;
}

.form-range::-webkit-slider-thumb {
    width: 20px;
    height: 20px;
    background: var(--brand-primary);
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    appearance: none;
    box-shadow: var(--shadow-sm);
    transition: transform var(--transition-fast);
}

.form-range::-webkit-slider-thumb:hover {
    transform: scale(1.1);
}

.form-range::-moz-range-thumb {
    width: 20px;
    height: 20px;
    background: var(--brand-primary);
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    box-shadow: var(--shadow-sm);
}

.form-range:focus {
    outline: none;
}

.form-range:focus::-webkit-slider-thumb {
    box-shadow: var(--shadow-sm), var(--input-focus-shadow);
}

/* ===================================================================
   13. DATE & TIME INPUTS
   =================================================================== */

/* Native date/time input styling */
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control,
input[type="month"].form-control,
input[type="week"].form-control {
    position: relative;
}

/* Webkit calendar picker styling */
input[type="date"].form-control::-webkit-calendar-picker-indicator,
input[type="time"].form-control::-webkit-calendar-picker-indicator,
input[type="datetime-local"].form-control::-webkit-calendar-picker-indicator {
    cursor: pointer;
    padding: var(--space-xs);
    margin-right: calc(var(--space-xs) * -1);
    border-radius: var(--radius-sm);
    opacity: 0.7;
    transition: opacity var(--transition-fast);
    filter: invert(0.5);
}

[data-theme="dark"] input[type="date"].form-control::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="time"].form-control::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="datetime-local"].form-control::-webkit-calendar-picker-indicator {
    filter: invert(0.8);
}

input[type="date"].form-control::-webkit-calendar-picker-indicator:hover,
input[type="time"].form-control::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"].form-control::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
}

/* Custom datetime wrapper */
.datetime-input {
    position: relative;
}

.datetime-input .form-control {
    padding-right: calc(var(--space-md) * 3);
}

.datetime-input-icon {
    position: absolute;
    right: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

/* Date range picker */
.date-range {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.date-range-separator {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

/* ===================================================================
   14. DRAG & DROP FILE UPLOAD
   =================================================================== */

.dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--space-2xl);
    background-color: var(--bg-input);
    border: 2px dashed var(--border-medium);
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: all var(--transition-base);
    text-align: center;
}

.dropzone:hover {
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.dropzone.is-dragover {
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    box-shadow: var(--shadow-glow);
}

.dropzone.is-dragover .dropzone-icon {
    transform: scale(1.1);
    color: var(--brand-primary);
}

.dropzone-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.dropzone-icon {
    font-size: 48px;
    color: var(--text-muted);
    margin-bottom: var(--space-md);
    transition: all var(--transition-base);
}

.dropzone-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.dropzone-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-md);
}

.dropzone-hint {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.dropzone-btn {
    margin-top: var(--space-md);
}

/* Compact dropzone */
.dropzone-compact {
    flex-direction: row;
    gap: var(--space-md);
    padding: var(--space-lg);
}

.dropzone-compact .dropzone-icon {
    font-size: 32px;
    margin-bottom: 0;
}

.dropzone-compact .dropzone-content {
    text-align: left;
}

/* File preview list */
.dropzone-previews {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin-top: var(--space-lg);
}

.dropzone-preview {
    position: relative;
    width: 100px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.dropzone-preview-image {
    width: 100%;
    height: 80px;
    object-fit: cover;
    background-color: var(--bg-input);
}

.dropzone-preview-info {
    padding: var(--space-xs);
}

.dropzone-preview-name {
    font-size: var(--font-size-xs);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dropzone-preview-size {
    font-size: 10px;
    color: var(--text-muted);
}

.dropzone-preview-remove {
    position: absolute;
    top: var(--space-xs);
    right: var(--space-xs);
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    color: var(--text-on-overlay);
    background-color: var(--bg-scrim);
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.dropzone-preview:hover .dropzone-preview-remove {
    opacity: 1;
}

.dropzone-preview-remove:hover {
    background-color: var(--color-danger);
}

.dropzone-preview-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background-color: var(--bg-input);
}

.dropzone-preview-progress-bar {
    height: 100%;
    background-color: var(--brand-primary);
    transition: width var(--transition-base);
}

/* Error state */
.dropzone.has-error {
    border-color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.dropzone-error {
    color: var(--color-danger-text);
    font-size: var(--font-size-sm);
    margin-top: var(--space-sm);
}

/* ===================================================================
   15. COLOR PICKER
   =================================================================== */

input[type="color"].form-control-color {
    width: 48px;
    height: 42px;
    padding: var(--space-xs);
    border-radius: var(--radius-md);
    cursor: pointer;
}

input[type="color"].form-control-color::-webkit-color-swatch-wrapper {
    padding: 0;
}

input[type="color"].form-control-color::-webkit-color-swatch {
    border: none;
    border-radius: var(--radius-sm);
}

/* Color picker with input */
.color-picker {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.color-picker-preview {
    width: 42px;
    height: 42px;
    border-radius: var(--radius-md);
    border: 2px solid var(--border-medium);
    cursor: pointer;
}

/* ===================================================================
   16. SEARCH INPUT
   =================================================================== */

.search-input {
    position: relative;
}

.search-input .form-control {
    padding-left: calc(var(--space-md) * 2.5);
    padding-right: calc(var(--space-md) * 2.5);
}

.search-input-icon {
    position: absolute;
    left: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

.search-input-clear {
    position: absolute;
    right: var(--space-sm);
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0;
    transition: all var(--transition-fast);
}

.search-input .form-control:not(:placeholder-shown) + .search-input-icon + .search-input-clear,
.search-input .form-control:focus + .search-input-icon + .search-input-clear {
    opacity: 1;
}

.search-input-clear:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

/* ===================================================================
   17. NUMBER INPUT WITH STEPPER
   =================================================================== */

.number-input {
    display: flex;
    align-items: stretch;
}

.number-input .form-control {
    border-radius: 0;
    text-align: center;
    -moz-appearance: textfield;
}

.number-input .form-control::-webkit-inner-spin-button,
.number-input .form-control::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.number-input-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    background-color: var(--bg-input);
    border: 2px solid var(--input-border);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.number-input-btn:hover {
    background-color: var(--bg-hover);
    border-color: var(--brand-primary);
    color: var(--brand-primary);
}

.number-input-btn:first-child {
    border-right: none;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
}

.number-input-btn:last-child {
    border-left: none;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

/* ===================================================================
   18. OTP / PIN INPUT
   =================================================================== */

.otp-input {
    display: flex;
    gap: var(--space-sm);
    justify-content: center;
}

.otp-input-field {
    width: 48px;
    height: 56px;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    text-align: center;
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    transition: all var(--transition-base);
}

.otp-input-field:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.otp-input-field.filled {
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

/* ===================================================================
   19. RICH TEXT EDITOR WRAPPER
   =================================================================== */

.editor-wrapper {
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.editor-wrapper:focus-within {
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    padding: var(--space-sm);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
}

.editor-toolbar-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--text-secondary);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.editor-toolbar-btn:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.editor-toolbar-btn.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.editor-toolbar-divider {
    width: 1px;
    height: 24px;
    margin: 0 var(--space-xs);
    background-color: var(--border-light);
}

.editor-content {
    min-height: 200px;
    padding: var(--space-md);
    background-color: var(--bg-body);
}

.editor-content:focus {
    outline: none;
}

.editor-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-xs) var(--space-sm);
    background-color: var(--bg-input);
    border-top: 1px solid var(--border-light);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   20. LIGHT THEME ICON OVERRIDES
   =================================================================== */

/* Light theme checkbox checkmark - white stroke for visibility on cyan bg */
[data-theme="light"] .form-check-input[type="checkbox"]:checked {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
}

/* Light theme radio dot - white fill for visibility on cyan bg */
[data-theme="light"] .form-check-input[type="radio"]:checked {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='6' fill='%23ffffff'/%3E%3C/svg%3E");
}


/* ===== components/cards.css ===== */
/* ===================================================================
   DCS Design System - Card Components
   Version: 2.0.0

   Card layouts and variations.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE CARD
   =================================================================== */

.card {
    position: relative;
    display: flex;
    flex-direction: column;
    background-color: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: all var(--transition-base);
}

/* ===================================================================
   2. CARD SECTIONS
   =================================================================== */

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--card-header-bg);
    border-bottom: 1px solid var(--card-border);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.card-header:first-child {
    border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
}

.card-title {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.card-subtitle {
    margin: var(--space-xs) 0 0;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.card-body {
    flex: 1 1 auto;
    padding: var(--space-lg);
}

.card-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    background-color: var(--card-header-bg);
    border-top: 1px solid var(--card-border);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.card-footer:last-child {
    border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px);
}

/* ===================================================================
   3. CARD TEXT ELEMENTS
   =================================================================== */

.card-text {
    margin-bottom: var(--space-md);
    color: var(--text-secondary);
}

.card-text:last-child {
    margin-bottom: 0;
}

.card-link {
    color: var(--link-color);
}

.card-link:hover {
    color: var(--link-hover);
}

.card-link + .card-link {
    margin-left: var(--space-md);
}

/* ===================================================================
   4. CARD IMAGE
   =================================================================== */

.card-img {
    width: 100%;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.card-img-bottom {
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.card-img-overlay {
    position: absolute;
    inset: 0;
    padding: var(--space-lg);
    border-radius: var(--radius-lg);
    background: linear-gradient(to top, var(--bg-overlay-dark) 0%, transparent 100%);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}

.card-img-overlay .card-title,
.card-img-overlay .card-text {
    color: var(--text-on-overlay);
}

/* ===================================================================
   5. INTERACTIVE CARD
   =================================================================== */

.card-interactive {
    cursor: pointer;
}

.card-interactive:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--brand-primary);
}

.card-interactive:active {
    transform: translateY(0);
}

/* Clickable entire card */
.card-link-wrapper {
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* ===================================================================
   6. CARD VARIANTS
   =================================================================== */

/* Elevated card */
.card-elevated {
    box-shadow: var(--shadow-lg);
    border: none;
}

.card-elevated:hover {
    box-shadow: var(--shadow-xl);
}

/* Outlined card */
.card-outlined {
    background-color: transparent;
    box-shadow: none;
}

/* Flat card (no shadow) */
.card-flat {
    box-shadow: none;
}

/* Glow effect (for dark theme) */
.card-glow {
    border-color: var(--brand-primary-alpha);
}

.card-glow:hover {
    box-shadow: var(--shadow-glow);
    border-color: var(--brand-primary);
}

/* ===================================================================
   7. STATUS CARDS
   =================================================================== */

.card-success {
    border-color: var(--color-success);
    background-color: var(--color-success-bg);
}

.card-success .card-header {
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
    color: var(--color-success-text);
}

.card-danger {
    border-color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.card-danger .card-header {
    background-color: var(--color-danger-bg);
    border-color: var(--color-danger);
    color: var(--color-danger-text);
}

.card-warning {
    border-color: var(--color-warning);
    background-color: var(--color-warning-bg);
}

.card-warning .card-header {
    background-color: var(--color-warning-bg);
    border-color: var(--color-warning);
    color: var(--color-warning-text);
}

.card-info {
    border-color: var(--color-info);
    background-color: var(--color-info-bg);
}

.card-info .card-header {
    background-color: var(--color-info-bg);
    border-color: var(--color-info);
    color: var(--color-info-text);
}

/* ===================================================================
   8. CARD SIZING
   =================================================================== */

.card-compact .card-header,
.card-compact .card-footer {
    padding: var(--space-sm) var(--space-md);
}

.card-compact .card-body {
    padding: var(--space-md);
}

.card-spacious .card-header,
.card-spacious .card-footer {
    padding: var(--space-lg) var(--space-xl);
}

.card-spacious .card-body {
    padding: var(--space-xl);
}

/* ===================================================================
   9. CARD GRID
   =================================================================== */

.card-grid {
    display: grid;
    gap: var(--space-lg);
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.card-grid-sm {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.card-grid-lg {
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
}

/* ===================================================================
   10. CARD DECK (Equal height)
   =================================================================== */

.card-deck {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg);
}

.card-deck > .card {
    flex: 1 0 0%;
    min-width: 280px;
}

/* ===================================================================
   11. HORIZONTAL CARD
   =================================================================== */

.card-horizontal {
    flex-direction: row;
}

.card-horizontal .card-img {
    width: 200px;
    min-width: 200px;
    object-fit: cover;
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
}

.card-horizontal .card-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

@media (max-width: 576px) {
    .card-horizontal {
        flex-direction: column;
    }

    .card-horizontal .card-img {
        width: 100%;
        min-width: auto;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }
}

/* ===================================================================
   12. STAT CARD
   =================================================================== */

.card-stat {
    text-align: center;
}

.card-stat .card-body {
    padding: var(--space-xl);
}

.card-stat-value {
    font-size: var(--font-size-4xl);
    font-weight: var(--font-weight-bold);
    color: var(--brand-primary);
    line-height: 1;
    margin-bottom: var(--space-sm);
}

.card-stat-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
}

.card-stat-icon {
    font-size: var(--font-size-3xl);
    color: var(--brand-primary);
    margin-bottom: var(--space-md);
    opacity: 0.7;
}

/* ===================================================================
   13. PROFILE CARD
   =================================================================== */

.card-profile {
    text-align: center;
}

.card-profile-avatar {
    width: 80px;
    height: 80px;
    margin: calc(var(--space-lg) * -1) auto var(--space-md);
    border-radius: var(--radius-full);
    border: 3px solid var(--card-bg);
    box-shadow: var(--shadow-md);
    object-fit: cover;
}

.card-profile-name {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-xs);
}

.card-profile-role {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* ===================================================================
   14. CARD WITH RIBBON/BADGE
   =================================================================== */

.card-ribbon {
    position: absolute;
    top: var(--space-md);
    right: calc(var(--space-md) * -1);
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.card-ribbon::before {
    content: '';
    position: absolute;
    right: 0;
    bottom: -6px;
    border: 3px solid var(--brand-primary-dark);
    border-right-color: transparent;
    border-bottom-color: transparent;
}

.card-badge {
    position: absolute;
    top: var(--space-sm);
    left: var(--space-sm);
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    border-radius: var(--radius-sm);
}

/* ===================================================================
   15. COLLAPSIBLE CARD
   =================================================================== */

.card-collapsible .card-header {
    cursor: pointer;
    user-select: none;
}

.card-collapsible .card-header::after {
    content: '\f078'; /* FontAwesome chevron-down */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    transition: transform var(--transition-base);
}

.card-collapsible.is-collapsed .card-header::after {
    transform: rotate(-90deg);
}

.card-collapsible.is-collapsed .card-body,
.card-collapsible.is-collapsed .card-footer {
    display: none;
}

/* ===================================================================
   16. LOADING STATE
   =================================================================== */

.card-loading {
    position: relative;
    pointer-events: none;
}

.card-loading::after {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--bg-overlay);
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.card-skeleton {
    background: linear-gradient(90deg,
        var(--bg-input) 25%,
        var(--bg-hover) 50%,
        var(--bg-input) 75%
    );
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s infinite;
    border-radius: var(--radius-sm);
}

@keyframes skeleton-loading {
    0% {
        background-position: 200% 0;
    }
    100% {
        background-position: -200% 0;
    }
}

/* ===================================================================
   17. COURSE CARD (LMS Specific)
   =================================================================== */

.card-course {
    overflow: hidden;
}

.card-course .card-img {
    height: 160px;
    object-fit: cover;
}

.card-course .card-body {
    padding: var(--space-md) var(--space-lg) var(--space-sm);
}

/* Course metadata */
.card-course-meta {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.card-course-meta i {
    color: var(--brand-primary);
}

.card-course-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.card-course-instructor {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-md);
}

/* Progress bar flushed to bottom - no footer border */
.card-course .card-footer {
    padding: 0;
    background: none;
    border: none;
}

.card-course .progress {
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    height: 6px;
}

.card-course .progress-bar {
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* Progress info above bar */
.card-course-progress {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.card-course-progress-percent {
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
}

/* Course status badge */
.card-course-badge {
    position: absolute;
    top: var(--space-sm);
    right: var(--space-sm);
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-sm);
}

.card-course-badge-new {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.card-course-badge-updated {
    color: var(--text-on-info);
    background-color: var(--color-info);
}

.card-course-badge-due {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

/* Completed course overlay */
.card-course.is-completed::after {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--color-success-bg);
    pointer-events: none;
    border-radius: var(--radius-lg);
}

.card-course.is-completed .card-course-badge {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.card-course.is-completed .card-course-badge::before {
    content: '\f00c'; /* FontAwesome check */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    margin-right: var(--space-xs);
}


/* ===== components/alerts.css ===== */
/* ===================================================================
   DCS Design System - Alert Components
   Version: 2.0.0

   Alerts, notifications, toasts, and banners.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE ALERT
   =================================================================== */

.alert {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    margin-bottom: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    border-left: 4px solid var(--border-dark);
}

.alert-icon {
    flex-shrink: 0;
    font-size: var(--font-size-lg);
    line-height: 1.4;
}

.alert-content {
    flex: 1;
    min-width: 0;
}

.alert-title {
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-xs);
}

.alert-message {
    color: var(--text-secondary);
}

.alert-message a {
    color: inherit;
    text-decoration: underline;
    font-weight: var(--font-weight-medium);
}

.alert-message a:hover {
    color: var(--text-primary);
}

/* ===================================================================
   2. ALERT VARIANTS
   =================================================================== */

/* Success */
.alert-success {
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
    border-left-color: var(--color-success);
}

.alert-success .alert-icon {
    color: var(--color-success-text);
}

.alert-success .alert-title {
    color: var(--color-success-text);
}

/* Danger / Error */
.alert-danger,
.alert-error {
    background-color: var(--color-danger-bg);
    border-color: var(--color-danger);
    border-left-color: var(--color-danger);
}

.alert-danger .alert-icon,
.alert-error .alert-icon {
    color: var(--color-danger-text);
}

.alert-danger .alert-title,
.alert-error .alert-title {
    color: var(--color-danger-text);
}

/* Warning */
.alert-warning {
    background-color: var(--color-warning-bg);
    border-color: var(--color-warning);
    border-left-color: var(--color-warning);
}

.alert-warning .alert-icon {
    color: var(--color-warning-text);
}

.alert-warning .alert-title {
    color: var(--color-warning-text);
}

/* Info */
.alert-info {
    background-color: var(--color-info-bg);
    border-color: var(--color-info);
    border-left-color: var(--color-info);
}

.alert-info .alert-icon {
    color: var(--color-info-text);
}

.alert-info .alert-title {
    color: var(--color-info-text);
}

/* ===================================================================
   3. DISMISSIBLE ALERT
   =================================================================== */

.alert-dismissible {
    padding-right: calc(var(--space-lg) + 32px);
}

.alert-close {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    color: var(--text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0.7;
    transition: all var(--transition-fast);
}

.alert-close:hover {
    opacity: 1;
    background-color: var(--bg-hover);
}

.alert-close::before {
    content: '\00d7';
    font-size: 20px;
    line-height: 1;
}

/* ===================================================================
   4. ALERT SIZES
   =================================================================== */

.alert-sm {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-xs);
}

.alert-sm .alert-icon {
    font-size: var(--font-size-base);
}

.alert-lg {
    padding: var(--space-lg) var(--space-xl);
    font-size: var(--font-size-base);
}

.alert-lg .alert-icon {
    font-size: var(--font-size-xl);
}

/* ===================================================================
   5. INLINE ALERT (No margin)
   =================================================================== */

.alert-inline {
    margin-bottom: 0;
}

/* ===================================================================
   6. ALERT WITH ACTIONS
   =================================================================== */

.alert-actions {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.alert-actions .btn {
    font-size: var(--font-size-sm);
}

/* ===================================================================
   7. TOAST NOTIFICATIONS
   =================================================================== */

.toast-container {
    position: fixed;
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: var(--space-lg);
    pointer-events: none;
}

/* Positioning */
.toast-container--top-right {
    top: 0;
    right: 0;
}

.toast-container--top-left {
    top: 0;
    left: 0;
}

.toast-container--top-center {
    top: 0;
    left: 50%;
    transform: translateX(-50%);
}

.toast-container--bottom-right {
    bottom: 0;
    right: 0;
}

.toast-container--bottom-left {
    bottom: 0;
    left: 0;
}

.toast-container--bottom-center {
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    min-width: 300px;
    max-width: 420px;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-elevated);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    pointer-events: auto;
    animation: toast-slide-in 0.3s ease;
}

.toast.is-hiding {
    animation: toast-slide-out 0.3s ease forwards;
}

@keyframes toast-slide-in {
    from {
        opacity: 0;
        transform: translateX(100%);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes toast-slide-out {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(100%);
    }
}

/* Left positioned toasts */
.toast-container--top-left .toast,
.toast-container--bottom-left .toast {
    animation-name: toast-slide-in-left;
}

.toast-container--top-left .toast.is-hiding,
.toast-container--bottom-left .toast.is-hiding {
    animation-name: toast-slide-out-left;
}

@keyframes toast-slide-in-left {
    from {
        opacity: 0;
        transform: translateX(-100%);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes toast-slide-out-left {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(-100%);
    }
}

/* Center positioned toasts */
.toast-container--top-center .toast,
.toast-container--bottom-center .toast {
    animation-name: toast-slide-in-center;
}

@keyframes toast-slide-in-center {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.toast-icon {
    flex-shrink: 0;
    font-size: var(--font-size-lg);
}

.toast-content {
    flex: 1;
    min-width: 0;
}

.toast-title {
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-xs);
}

.toast-message {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.toast-close {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    color: var(--text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.toast-close:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.toast-close::before {
    content: '\00d7';
    font-size: 16px;
    line-height: 1;
}

/* Toast progress bar */
.toast-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    background-color: var(--brand-primary);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    animation: toast-progress 5s linear forwards;
}

@keyframes toast-progress {
    from {
        width: 100%;
    }
    to {
        width: 0;
    }
}

/* Toast variants */
.toast-success {
    border-left: 4px solid var(--color-success);
}

.toast-success .toast-icon {
    color: var(--color-success-text);
}

.toast-danger,
.toast-error {
    border-left: 4px solid var(--color-danger);
}

.toast-danger .toast-icon,
.toast-error .toast-icon {
    color: var(--color-danger-text);
}

.toast-warning {
    border-left: 4px solid var(--color-warning);
}

.toast-warning .toast-icon {
    color: var(--color-warning-text);
}

.toast-info {
    border-left: 4px solid var(--color-info);
}

.toast-info .toast-icon {
    color: var(--color-info-text);
}

/* ===================================================================
   8. BANNER (Full-width notification)
   =================================================================== */

.banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-lg);
    text-align: center;
    font-size: var(--font-size-sm);
}

.banner-dismissible {
    padding-right: calc(var(--space-lg) + 40px);
}

.banner-close {
    position: absolute;
    right: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    color: inherit;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0.7;
    transition: opacity var(--transition-fast);
}

.banner-close:hover {
    opacity: 1;
}

.banner-close::before {
    content: '\00d7';
    font-size: 20px;
}

/* Banner variants */
.banner-primary {
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
}

.banner-secondary {
    background-color: var(--brand-secondary);
    color: var(--text-on-brand);
}

.banner-success {
    background-color: var(--color-success);
    color: var(--text-on-success);
}

.banner-danger {
    background-color: var(--color-danger);
    color: var(--text-on-danger);
}

.banner-warning {
    background-color: var(--color-warning);
    color: var(--text-on-warning);
}

.banner-info {
    background-color: var(--color-info);
    color: var(--text-on-info);
}

/* ===================================================================
   9. CALLOUT (Highlighted section)
   =================================================================== */

.callout {
    padding: var(--space-lg);
    background-color: var(--bg-input);
    border-radius: var(--radius-md);
    border-left: 4px solid var(--brand-primary);
}

.callout-title {
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-sm);
    color: var(--text-primary);
}

.callout-content {
    color: var(--text-secondary);
}

/* Callout variants */
.callout-success {
    border-left-color: var(--color-success);
    background-color: var(--color-success-bg);
}

.callout-danger {
    border-left-color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.callout-warning {
    border-left-color: var(--color-warning);
    background-color: var(--color-warning-bg);
}

.callout-info {
    border-left-color: var(--color-info);
    background-color: var(--color-info-bg);
}

/* ===================================================================
   10. EMPTY STATE
   =================================================================== */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--space-3xl) var(--space-xl);
    text-align: center;
}

.empty-state-icon {
    font-size: 64px;
    color: var(--text-muted);
    margin-bottom: var(--space-lg);
    opacity: 0.5;
}

.empty-state-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.empty-state-message {
    font-size: var(--font-size-base);
    color: var(--text-muted);
    max-width: 400px;
    margin-bottom: var(--space-lg);
}

.empty-state-actions {
    display: flex;
    gap: var(--space-sm);
}

/* ===================================================================
   11. URGENCY ALERTS (for LMS deadlines)
   =================================================================== */

.alert-urgency-critical {
    background-color: var(--urgency-critical-bg);
    border-color: var(--urgency-critical);
    border-left-color: var(--urgency-critical);
}

.alert-urgency-critical .alert-icon,
.alert-urgency-critical .alert-title {
    color: var(--urgency-critical);
}

.alert-urgency-high {
    background-color: var(--urgency-high-bg);
    border-color: var(--urgency-high);
    border-left-color: var(--urgency-high);
}

.alert-urgency-high .alert-icon,
.alert-urgency-high .alert-title {
    color: var(--urgency-high);
}

.alert-urgency-medium {
    background-color: var(--urgency-medium-bg);
    border-color: var(--urgency-medium);
    border-left-color: var(--urgency-medium);
}

.alert-urgency-medium .alert-icon,
.alert-urgency-medium .alert-title {
    color: var(--urgency-medium);
}

.alert-urgency-low {
    background-color: var(--urgency-low-bg);
    border-color: var(--urgency-low);
    border-left-color: var(--urgency-low);
}

.alert-urgency-low .alert-icon,
.alert-urgency-low .alert-title {
    color: var(--urgency-low);
}

/* ── Session-ended banner (heartbeat.js showSessionExpiredBanner, 2026-09-02) ──
   Injected at the top of the page the moment the student's session dies, so
   typed work is never lost to a surprise redirect on the next Submit. */
.session-expired-banner {
    position: sticky;
    top: 0;
    z-index: 1050;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    background-color: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-bottom: 2px solid var(--color-warning);
    font-size: var(--font-size-sm);
}

.session-expired-banner a {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
}

/* ── Task draft notice (assignment.php draft safety net, 2026-09-02) ── */
.draft-notice {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    margin-bottom: var(--space-sm);
    border-radius: var(--radius-md);
    background-color: var(--color-info-bg);
    color: var(--color-info-text);
    font-size: var(--font-size-sm);
}

/* ── Persistent auto-verification notes under the submission banner ── */
.verification-notes {
    padding: var(--space-md) var(--space-lg);
    margin-bottom: var(--space-lg);
    border-radius: var(--radius-md);
    background-color: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-left: 4px solid var(--color-warning);
}

.verification-notes h4 {
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-base);
}

.verification-notes ul {
    margin: 0;
    padding-left: var(--space-lg);
}

.verification-notes li + li {
    margin-top: var(--space-xs);
}

.submission-form.is-locked {
    opacity: 0.6;
    pointer-events: none;
}


/* ===== components/tables.css ===== */
/* ===================================================================
   DCS Design System - Table Components
   Version: 2.0.0

   Data tables with sorting, responsive, and interactive features.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE TABLE
   =================================================================== */

.table {
    width: 100%;
    margin-bottom: var(--space-lg);
    color: var(--text-primary);
    vertical-align: middle;
    border-collapse: collapse;
}

.table > :not(caption) > * > * {
    padding: var(--space-md) var(--space-md);
    background-color: transparent;
    border-bottom: 1px solid var(--border-light);
}

.table > thead {
    vertical-align: bottom;
}

.table > thead > tr > th {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background-color: var(--bg-input);
    border-bottom: 2px solid var(--border-medium);
}

.table > tbody > tr:last-child > * {
    border-bottom: none;
}

/* ===================================================================
   2. TABLE VARIANTS
   =================================================================== */

/* Striped rows */
.table-striped > tbody > tr:nth-of-type(odd) > * {
    background-color: var(--bg-input);
}

/* Hover effect */
.table-hover > tbody > tr:hover > * {
    background-color: var(--bg-hover);
}

/* Bordered */
.table-bordered > :not(caption) > * > * {
    border: 1px solid var(--border-light);
}

.table-bordered > thead > tr > th {
    border-bottom-width: 2px;
}

/* Borderless */
.table-borderless > :not(caption) > * > * {
    border-bottom: none;
}

/* ===================================================================
   3. TABLE SIZING
   =================================================================== */

/* Compact */
.table-sm > :not(caption) > * > * {
    padding: var(--space-sm) var(--space-sm);
    font-size: var(--font-size-sm);
}

/* Spacious */
.table-lg > :not(caption) > * > * {
    padding: var(--space-lg) var(--space-md);
}

/* ===================================================================
   4. RESPONSIVE TABLE
   =================================================================== */

.table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Custom scrollbar for responsive tables */
.table-responsive::-webkit-scrollbar {
    height: 6px;
}

.table-responsive::-webkit-scrollbar-track {
    background: var(--bg-input);
    border-radius: var(--radius-full);
}

.table-responsive::-webkit-scrollbar-thumb {
    background: var(--border-medium);
    border-radius: var(--radius-full);
}

.table-responsive::-webkit-scrollbar-thumb:hover {
    background: var(--border-dark);
}

/* Firefox scrollbar */
.table-responsive {
    scrollbar-width: thin;
    scrollbar-color: var(--border-medium) var(--bg-input);
}

/* Stacked layout on mobile */
.table-stacked {
    border: none;
}

@media (max-width: 768px) {
    .table-stacked,
    .table-stacked thead,
    .table-stacked tbody,
    .table-stacked th,
    .table-stacked td,
    .table-stacked tr {
        display: block;
    }

    .table-stacked thead {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        border: 0;
    }

    .table-stacked tbody > tr {
        margin-bottom: var(--space-md);
        background-color: var(--bg-surface);
        border: 1px solid var(--border-light);
        border-radius: var(--radius-md);
    }

    .table-stacked tbody > tr > td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: var(--space-sm) var(--space-md);
        border-bottom: 1px solid var(--border-light);
    }

    .table-stacked tbody > tr > td:last-child {
        border-bottom: none;
    }

    .table-stacked tbody > tr > td::before {
        content: attr(data-label);
        font-weight: var(--font-weight-semibold);
        font-size: var(--font-size-sm);
        color: var(--text-muted);
        text-transform: uppercase;
        letter-spacing: 0.5px;
    }
}

/* ===================================================================
   5. SORTABLE TABLE
   =================================================================== */

.table-sortable > thead > tr > th {
    cursor: pointer;
    user-select: none;
    position: relative;
    padding-right: var(--space-xl);
}

.table-sortable > thead > tr > th:hover {
    background-color: var(--bg-hover);
}

.table-sortable > thead > tr > th::after {
    content: '';
    position: absolute;
    right: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid var(--text-muted);
    opacity: 0.3;
}

.table-sortable > thead > tr > th[data-sort="asc"]::after {
    border-top: none;
    border-bottom: 5px solid var(--brand-primary);
    opacity: 1;
}

.table-sortable > thead > tr > th[data-sort="desc"]::after {
    border-top: 5px solid var(--brand-primary);
    opacity: 1;
}

/* Non-sortable column */
.table-sortable > thead > tr > th.no-sort {
    cursor: default;
    padding-right: var(--space-md);
}

.table-sortable > thead > tr > th.no-sort::after {
    display: none;
}

/* ===================================================================
   6. SELECTABLE ROWS
   =================================================================== */

.table-selectable > tbody > tr {
    cursor: pointer;
}

.table-selectable > tbody > tr.selected > * {
    background-color: var(--brand-primary-alpha);
}

.table-selectable > tbody > tr:hover.selected > * {
    background-color: var(--brand-primary-alpha-strong);
}

/* Checkbox column */
.table th.col-checkbox,
.table td.col-checkbox {
    width: 48px;
    text-align: center;
    padding-left: var(--space-md);
    padding-right: var(--space-sm);
}

/* ===================================================================
   7. STATUS ROW COLORS
   =================================================================== */

.table > tbody > tr.table-success > * {
    background-color: var(--color-success-bg);
}

.table > tbody > tr.table-danger > * {
    background-color: var(--color-danger-bg);
}

.table > tbody > tr.table-warning > * {
    background-color: var(--color-warning-bg);
}

.table > tbody > tr.table-info > * {
    background-color: var(--color-info-bg);
}

/* ===================================================================
   8. TABLE CARD (Table inside a card)
   =================================================================== */

.table-card {
    background-color: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.table-card .table {
    margin-bottom: 0;
}

.table-card .table > thead > tr > th:first-child {
    border-top-left-radius: var(--radius-lg);
}

.table-card .table > thead > tr > th:last-child {
    border-top-right-radius: var(--radius-lg);
}

/* ===================================================================
   9. TABLE HEADER TOOLBAR
   =================================================================== */

.table-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-md) var(--space-lg);
    background-color: var(--card-header-bg);
    border-bottom: 1px solid var(--card-border);
}

.table-toolbar-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.table-toolbar-actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.table-search {
    width: 250px;
}

/* ===================================================================
   10. TABLE FOOTER / PAGINATION
   Note: For standalone pagination, use .pagination from navigation.css.
   These classes are table-specific for the footer context.
   =================================================================== */

.table-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--card-header-bg);
    border-top: 1px solid var(--card-border);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.table-info {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.table-pagination {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.table-pagination-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    background-color: transparent;
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.table-pagination-btn:hover {
    background-color: var(--bg-hover);
    border-color: var(--brand-primary);
    color: var(--brand-primary);
}

.table-pagination-btn.active {
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
    color: var(--btn-primary-text);
}

.table-pagination-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ===================================================================
   11. COLUMN TYPES
   =================================================================== */

/* Numeric column (right-aligned) */
.col-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Date column */
.col-date {
    white-space: nowrap;
}

/* Actions column */
.col-actions {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

/* Status column */
.col-status {
    width: 120px;
}

/* Truncate long text */
.col-truncate {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ===================================================================
   12. EXPANDABLE ROWS
   =================================================================== */

.table-expandable > tbody > tr.expandable-row {
    cursor: pointer;
}

.table-expandable > tbody > tr.expandable-row > td:first-child::before {
    content: '\f054'; /* FontAwesome chevron-right */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-xs);
    margin-right: var(--space-sm);
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.table-expandable > tbody > tr.expandable-row.is-expanded > td:first-child::before {
    transform: rotate(90deg);
}

.table-expandable > tbody > tr.expandable-content {
    display: none;
}

.table-expandable > tbody > tr.expandable-content.is-visible {
    display: table-row;
}

.table-expandable > tbody > tr.expandable-content > td {
    padding: var(--space-lg);
    background-color: var(--bg-input);
}

/* ===================================================================
   13. LOADING STATE
   =================================================================== */

.table-loading {
    position: relative;
    pointer-events: none;
}

.table-loading::after {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--bg-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
}

.table-loading > tbody {
    opacity: 0.5;
}

/* Skeleton rows */
.table-skeleton td {
    padding: var(--space-md);
}

.table-skeleton-cell {
    height: 20px;
    background: linear-gradient(90deg,
        var(--bg-input) 25%,
        var(--bg-hover) 50%,
        var(--bg-input) 75%
    );
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s infinite;
    border-radius: var(--radius-sm);
}

/* ===================================================================
   14. EMPTY TABLE STATE
   =================================================================== */

.table-empty {
    text-align: center;
    padding: var(--space-3xl) var(--space-xl);
}

.table-empty-icon {
    font-size: 48px;
    color: var(--text-muted);
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

.table-empty-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.table-empty-message {
    color: var(--text-muted);
    margin-bottom: var(--space-lg);
}

/* ===================================================================
   15. FIXED HEADER
   =================================================================== */

.table-fixed-header {
    max-height: 500px;
    overflow-y: auto;
}

.table-fixed-header > table > thead {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
}

.table-fixed-header > table > thead > tr > th {
    box-shadow: 0 1px 0 var(--border-medium);
}

/* ===================================================================
   16. GRADEBOOK TABLE (LMS Specific)
   =================================================================== */

.table-gradebook {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table-gradebook table {
    min-width: 800px;
}

/* Frozen first column (Student Name) */
.table-gradebook th:first-child,
.table-gradebook td:first-child {
    position: sticky;
    left: 0;
    z-index: calc(var(--z-sticky) + 1);
    background-color: var(--bg-surface);
    min-width: 180px;
    max-width: 220px;
}

.table-gradebook thead th:first-child {
    z-index: calc(var(--z-sticky) + 2);
    background-color: var(--bg-input);
}

/* Shadow indicator for scrolled state */
.table-gradebook th:first-child::after,
.table-gradebook td:first-child::after {
    content: '';
    position: absolute;
    top: 0;
    right: -8px;
    bottom: 0;
    width: 8px;
    background: linear-gradient(to right, rgba(0, 0, 0, 0.1), transparent);
    opacity: 0;
    transition: opacity var(--transition-fast);
    pointer-events: none;
}

.table-gradebook.is-scrolled th:first-child::after,
.table-gradebook.is-scrolled td:first-child::after {
    opacity: 1;
}

/* Grade cells - centered and fixed width */
.table-gradebook .col-grade {
    width: 80px;
    min-width: 80px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* Assignment header - rotated for space efficiency */
.table-gradebook .col-assignment-header {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    transform: rotate(180deg);
    height: 120px;
    padding: var(--space-sm) var(--space-xs);
    font-size: var(--font-size-xs);
    white-space: nowrap;
}

/* Grade input in cell */
.table-gradebook .grade-input {
    width: 60px;
    padding: var(--space-xs);
    text-align: center;
    font-size: var(--font-size-sm);
    background-color: var(--bg-body);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
}

.table-gradebook .grade-input:focus {
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
    outline: none;
}

/* Grade status colors */
.table-gradebook .grade-passing {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
}

.table-gradebook .grade-failing {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

.table-gradebook .grade-missing {
    color: var(--color-warning-text);
    background-color: var(--color-warning-bg);
}

.table-gradebook .grade-excused {
    color: var(--text-muted);
    font-style: italic;
}

/* Custom scrollbar for gradebook */
.table-gradebook::-webkit-scrollbar {
    height: 6px;
}

.table-gradebook::-webkit-scrollbar-track {
    background: var(--bg-input);
    border-radius: var(--radius-full);
}

.table-gradebook::-webkit-scrollbar-thumb {
    background: var(--border-medium);
    border-radius: var(--radius-full);
}

.table-gradebook::-webkit-scrollbar-thumb:hover {
    background: var(--border-dark);
}


/* ===== components/modals.css ===== */
/* ===================================================================
   DCS Design System - Modal Components
   Version: 2.0.0

   Modal dialogs, overlays, and lightboxes.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. MODAL BACKDROP
   =================================================================== */

.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal-backdrop);
    background-color: var(--bg-overlay);
    opacity: 0;
    transition: opacity var(--transition-base);
}

.modal-backdrop.is-visible {
    opacity: 1;
}

/* ===================================================================
   2. MODAL CONTAINER
   =================================================================== */

/* DCS custom modal (use .dcs-modal class for custom modals) */
.dcs-modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
    overflow-y: auto;
}

.dcs-modal.show {
    display: flex;
}

/* Bootstrap modal backdrop compatibility */
.modal-backdrop.show {
    opacity: 1;
}

/* Prevent body scroll when modal is open */
body.modal-open {
    overflow: hidden;
}

/* ===================================================================
   3. MODAL DIALOG
   =================================================================== */

/* Base modal dialog styling - works with Bootstrap */
.modal-dialog {
    position: relative;
    width: 100%;
    max-width: 500px;
    margin: 1.75rem auto;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
}

.modal-content {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-xl);
}

/* DCS custom modal dialog with animations */
.dcs-modal .modal-dialog {
    max-height: calc(100vh - var(--space-2xl) * 2);
    display: flex;
    flex-direction: column;
}

/* Size variants */
.modal-sm .modal-dialog {
    max-width: 360px;
}

.modal-lg .modal-dialog {
    max-width: 720px;
}

.modal-xl .modal-dialog {
    max-width: 960px;
}

.modal-fullscreen .modal-dialog {
    max-width: none;
    width: calc(100vw - var(--space-lg) * 2);
    height: calc(100vh - var(--space-lg) * 2);
    max-height: none;
    border-radius: var(--radius-lg);
}

/* Centered content (for small dialogs) */
.modal-centered {
    align-items: center;
}

/* ===================================================================
   4. MODAL SECTIONS
   =================================================================== */

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-lg) var(--space-xl);
    border-bottom: 1px solid var(--border-light);
    flex-shrink: 0;
}

.modal-title {
    margin: 0;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.modal-title i {
    color: var(--brand-primary);
}

.modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    margin: calc(var(--space-sm) * -1);
    color: var(--text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.modal-close:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.modal-close::before {
    content: '\00d7';
    font-size: 28px;
    line-height: 1;
}

.modal-body {
    flex: 1 1 auto;
    padding: var(--space-xl);
    overflow-y: auto;
}

.modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-sm);
    padding: var(--space-lg) var(--space-xl);
    border-top: 1px solid var(--border-light);
    flex-shrink: 0;
}

/* Footer with left-aligned secondary action */
.modal-footer-spread {
    justify-content: space-between;
}

/* ===================================================================
   5. CONFIRMATION MODAL
   =================================================================== */

.modal-confirm .modal-dialog {
    max-width: 420px;
    text-align: center;
}

.modal-confirm .modal-body {
    padding: var(--space-2xl) var(--space-xl);
}

.modal-confirm-icon {
    font-size: 64px;
    margin-bottom: var(--space-lg);
}

.modal-confirm-icon.icon-success {
    color: var(--color-success);
}

.modal-confirm-icon.icon-danger {
    color: var(--color-danger);
}

.modal-confirm-icon.icon-warning {
    color: var(--color-warning);
}

.modal-confirm-icon.icon-info {
    color: var(--color-info);
}

.modal-confirm-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.modal-confirm-message {
    color: var(--text-secondary);
    margin-bottom: 0;
}

.modal-confirm .modal-footer {
    justify-content: center;
    border-top: none;
    padding-top: 0;
}

/* ===================================================================
   6. ALERT MODAL (Success/Error feedback)
   =================================================================== */

.modal-alert .modal-dialog {
    max-width: 380px;
}

.modal-alert .modal-header {
    border-bottom: none;
    padding-bottom: 0;
}

.modal-alert .modal-body {
    text-align: center;
    padding-top: var(--space-md);
}

.modal-alert .modal-footer {
    border-top: none;
    justify-content: center;
}

/* ===================================================================
   7. FORM MODAL
   =================================================================== */

.modal-form .modal-body {
    padding: var(--space-lg) var(--space-xl);
}

.modal-form .form-group:last-child {
    margin-bottom: 0;
}

/* ===================================================================
   8. IMAGE/MEDIA MODAL (Lightbox)
   =================================================================== */

.modal-media {
    padding: var(--space-md);
}

.modal-media .modal-dialog {
    max-width: 90vw;
    max-height: 90vh;
    background-color: transparent;
    border: none;
    box-shadow: none;
}

.modal-media .modal-body {
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-media-image {
    max-width: 100%;
    max-height: 80vh;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xl);
}

.modal-media-close {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-on-overlay);
    background-color: var(--bg-overlay-medium);
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.modal-media-close:hover {
    background-color: var(--bg-overlay-dark);
}

.modal-media-close::before {
    content: '\00d7';
    font-size: 28px;
}

/* Navigation arrows for galleries */
.modal-media-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-on-overlay);
    background-color: var(--bg-overlay-medium);
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.modal-media-nav:hover {
    background-color: var(--bg-overlay-dark);
}

.modal-media-prev {
    left: var(--space-md);
}

.modal-media-next {
    right: var(--space-md);
}

/* ===================================================================
   9. SIDE PANEL / DRAWER
   =================================================================== */

.modal-drawer {
    justify-content: flex-end;
    padding: 0;
}

.modal-drawer .modal-dialog {
    max-width: 480px;
    height: 100vh;
    max-height: 100vh;
    margin: 0;
    border-radius: 0;
    transform: translateX(100%);
}

.modal-drawer.is-open .modal-dialog,
.modal-drawer.show .modal-dialog {
    transform: translateX(0);
}

/* Left drawer */
.modal-drawer-left {
    justify-content: flex-start;
}

.modal-drawer-left .modal-dialog {
    transform: translateX(-100%);
}

.modal-drawer-left.is-open .modal-dialog,
.modal-drawer-left.show .modal-dialog {
    transform: translateX(0);
}

/* Drawer sizes */
.modal-drawer-sm .modal-dialog {
    max-width: 320px;
}

.modal-drawer-lg .modal-dialog {
    max-width: 640px;
}

.modal-drawer-xl .modal-dialog {
    max-width: 800px;
}

/* ===================================================================
   10. STACKED MODALS
   =================================================================== */

.modal + .modal {
    z-index: calc(var(--z-modal) + 10);
}

.modal + .modal + .modal {
    z-index: calc(var(--z-modal) + 20);
}

.modal-backdrop + .modal-backdrop {
    z-index: calc(var(--z-modal-backdrop) + 10);
}

/* ===================================================================
   11. LOADING STATE
   =================================================================== */

.modal-loading .modal-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 200px;
}

.modal-spinner {
    width: 48px;
    height: 48px;
    border: 4px solid var(--border-medium);
    border-top-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: modal-spin 0.8s linear infinite;
    margin-bottom: var(--space-md);
}

@keyframes modal-spin {
    to {
        transform: rotate(360deg);
    }
}

.modal-loading-text {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

/* ===================================================================
   12. SCROLLABLE MODAL BODY
   =================================================================== */

.modal-scrollable .modal-dialog {
    display: flex;
    flex-direction: column;
}

.modal-scrollable .modal-body {
    overflow-y: auto;
}

/* ===================================================================
   13. ANIMATION VARIANTS
   =================================================================== */

/* Fade only (no transform) */
.modal-fade .modal-dialog {
    transform: none;
    opacity: 0;
}

.modal-fade.is-open .modal-dialog,
.modal-fade.show .modal-dialog {
    opacity: 1;
}

/* Slide up */
.modal-slide-up .modal-dialog {
    transform: translateY(50px);
}

.modal-slide-up.is-open .modal-dialog,
.modal-slide-up.show .modal-dialog {
    transform: translateY(0);
}

/* Zoom */
.modal-zoom .modal-dialog {
    transform: scale(0.8);
}

.modal-zoom.is-open .modal-dialog,
.modal-zoom.show .modal-dialog {
    transform: scale(1);
}

/* ===================================================================
   14. MODAL WITH TABS
   =================================================================== */

.modal-tabs .modal-header {
    flex-direction: column;
    align-items: stretch;
    padding-bottom: 0;
}

.modal-tabs .modal-header-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-md);
}

.modal-tabs .tab-list {
    margin: 0 calc(var(--space-xl) * -1);
    padding: 0 var(--space-xl);
    border-bottom: none;
}

/* ===================================================================
   15. KEYBOARD TRAP INDICATOR
   =================================================================== */

.modal-dialog:focus {
    outline: none;
}

.modal-dialog:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

/* ===================================================================
   16. SWEETALERT2 THEME LOCK
   ===================================================================
   SweetAlert2 v11 auto-switches its popup to dark colors via
   @media(prefers-color-scheme: dark) when the OS is in dark mode,
   regardless of the LMS theme. On a forced-light page (admin) with
   an OS in dark mode, this produced white text on a white background
   inside <select> dropdowns because the native <option> elements
   inherited the popup's white color while rendering on a light page.
   These overrides re-bind swal2's theme variables to the LMS theme so
   the popup follows data-theme, not the OS.
   =================================================================== */

[data-theme="light"] .swal2-popup {
    --swal2-background: #fff;
    --swal2-color: var(--text-primary);
    --swal2-input-background: var(--bg-input);
    --swal2-input-color: var(--input-text);
    --swal2-validation-message-background: var(--color-warning-bg);
    --swal2-validation-message-color: var(--color-warning-text);
    --swal2-footer-border-color: var(--border-subtle);
}

[data-theme="dark"] .swal2-popup {
    --swal2-background: var(--bg-elevated);
    --swal2-color: var(--text-primary);
    --swal2-input-background: var(--bg-input);
    --swal2-input-color: var(--input-text);
    --swal2-validation-message-background: var(--color-warning-bg);
    --swal2-validation-message-color: var(--color-warning-text);
    --swal2-footer-border-color: var(--border-subtle);
}

/* Native <option> elements inside swal2-select inherit color from the
   <select>. Force the option list to match the input pair so the OS
   dropdown is readable regardless of the OS color scheme. */
[data-theme="light"] .swal2-popup .swal2-select option {
    background-color: var(--bg-input);
    color: var(--input-text);
}

[data-theme="dark"] .swal2-popup .swal2-select option {
    background-color: var(--bg-input);
    color: var(--input-text);
}


/* ===== components/dropdowns.css ===== */
/* ===================================================================
   DCS Design System - Dropdown Components
   Version: 2.0.0

   Dropdown menus, multi-select, and contextual menus.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. DROPDOWN CONTAINER
   =================================================================== */

.dropdown {
    position: relative;
    display: inline-block;
}

/* ===================================================================
   2. DROPDOWN TOGGLE
   =================================================================== */

.dropdown-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    cursor: pointer;
}

.dropdown-toggle::after {
    content: '';
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid currentColor;
    transition: transform var(--transition-fast);
}

.dropdown.is-open .dropdown-toggle::after {
    transform: rotate(180deg);
}

/* No caret variant */
.dropdown-toggle.no-caret::after {
    display: none;
}

/* ===================================================================
   3. DROPDOWN MENU
   =================================================================== */

.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: var(--z-dropdown);
    min-width: 200px;
    max-width: 320px;
    padding: var(--space-xs) 0;
    margin-top: var(--space-xs);
    background-color: var(--bg-elevated);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity var(--transition-fast),
                visibility var(--transition-fast),
                transform var(--transition-fast);
}

.dropdown.is-open .dropdown-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* Right-aligned menu */
.dropdown-menu-right {
    left: auto;
    right: 0;
}

/* Top-aligned (opens upward) */
.dropdown-menu-top {
    top: auto;
    bottom: 100%;
    margin-top: 0;
    margin-bottom: var(--space-xs);
    transform: translateY(10px);
}

.dropdown.is-open .dropdown-menu-top {
    transform: translateY(0);
}

/* ===================================================================
   4. DROPDOWN ITEMS
   =================================================================== */

.dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background: none;
    border: none;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.dropdown-item:hover {
    background-color: var(--bg-hover);
    color: var(--brand-primary);
}

.dropdown-item:focus {
    outline: none;
    background-color: var(--bg-hover);
}

.dropdown-item:active {
    background-color: var(--bg-active);
}

/* Disabled state */
.dropdown-item.disabled,
.dropdown-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Active/selected item */
.dropdown-item.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

/* Item with icon */
.dropdown-item i,
.dropdown-item .dropdown-icon {
    width: 20px;
    text-align: center;
    color: var(--text-muted);
    flex-shrink: 0;
}

.dropdown-item:hover i,
.dropdown-item:hover .dropdown-icon {
    color: var(--brand-primary);
}

/* Item with badge */
.dropdown-item-badge {
    margin-left: auto;
    font-size: var(--font-size-xs);
    padding: 2px 6px;
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
    color: var(--text-muted);
}

/* ===================================================================
   5. DROPDOWN DIVIDER
   =================================================================== */

.dropdown-divider {
    height: 1px;
    margin: var(--space-xs) 0;
    background-color: var(--border-light);
}

/* ===================================================================
   6. DROPDOWN HEADER
   =================================================================== */

.dropdown-header {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* ===================================================================
   7. DROPDOWN WITH SEARCH
   =================================================================== */

.dropdown-search {
    padding: var(--space-sm) var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.dropdown-search-input {
    width: 100%;
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--input-text);
    background-color: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
}

.dropdown-search-input:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

/* Scrollable dropdown body */
.dropdown-body {
    max-height: 300px;
    overflow-y: auto;
}

/* ===================================================================
   8. MULTI-SELECT DROPDOWN
   =================================================================== */

.dropdown-multi .dropdown-item {
    padding-left: var(--space-sm);
}

.dropdown-multi .dropdown-item::before {
    content: '';
    width: 18px;
    height: 18px;
    margin-right: var(--space-sm);
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    transition: all var(--transition-fast);
}

.dropdown-multi .dropdown-item:hover::before {
    border-color: var(--brand-primary);
}

.dropdown-multi .dropdown-item.selected::before {
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a192f' stroke-width='3'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px;
}

/* Selected count in toggle */
.dropdown-selected-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

/* ===================================================================
   9. DROPDOWN FOOTER
   =================================================================== */

.dropdown-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border-top: 1px solid var(--border-light);
}

/* ===================================================================
   10. CONTEXT MENU
   =================================================================== */

.context-menu {
    position: fixed;
    z-index: var(--z-popover);
    min-width: 180px;
    padding: var(--space-xs) 0;
    background-color: var(--bg-elevated);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: scale(0.95);
    transform-origin: top left;
    transition: opacity var(--transition-fast),
                visibility var(--transition-fast),
                transform var(--transition-fast);
}

.context-menu.is-visible {
    opacity: 1;
    visibility: visible;
    transform: scale(1);
}

.context-menu-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.context-menu-item:hover {
    background-color: var(--bg-hover);
    color: var(--brand-primary);
}

.context-menu-item i {
    width: 16px;
    text-align: center;
    color: var(--text-muted);
}

.context-menu-item:hover i {
    color: var(--brand-primary);
}

.context-menu-item-shortcut {
    margin-left: auto;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.context-menu-divider {
    height: 1px;
    margin: var(--space-xs) 0;
    background-color: var(--border-light);
}

/* Danger item */
.context-menu-item.danger {
    color: var(--color-danger-text);
}

.context-menu-item.danger:hover {
    background-color: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.context-menu-item.danger i {
    color: var(--color-danger-text);
}

/* ===================================================================
   11. NESTED DROPDOWN (Submenu)
   =================================================================== */

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu > .dropdown-item::after {
    content: '';
    margin-left: auto;
    width: 0;
    height: 0;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 4px solid currentColor;
}

.dropdown-submenu .dropdown-menu {
    position: absolute;
    top: 0;
    left: 100%;
    margin-top: 0;
    margin-left: var(--space-xs);
    opacity: 0;
    visibility: hidden;
}

.dropdown-submenu:hover > .dropdown-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* Left-opening submenu */
.dropdown-submenu-left .dropdown-menu {
    left: auto;
    right: 100%;
    margin-left: 0;
    margin-right: var(--space-xs);
}

/* ===================================================================
   12. DROPDOWN SIZES
   =================================================================== */

.dropdown-sm .dropdown-menu {
    min-width: 140px;
    font-size: var(--font-size-xs);
}

.dropdown-sm .dropdown-item {
    padding: var(--space-xs) var(--space-sm);
}

.dropdown-lg .dropdown-menu {
    min-width: 280px;
}

.dropdown-lg .dropdown-item {
    padding: var(--space-md) var(--space-lg);
    font-size: var(--font-size-base);
}

/* ===================================================================
   13. MEGA DROPDOWN
   =================================================================== */

.dropdown-mega .dropdown-menu {
    min-width: 600px;
    padding: var(--space-lg);
}

.dropdown-mega-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg);
}

.dropdown-mega-column {
    /* Column content */
}

.dropdown-mega-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--border-light);
}

.dropdown-mega .dropdown-item {
    padding: var(--space-xs) 0;
    border-radius: var(--radius-sm);
}

.dropdown-mega .dropdown-item:hover {
    padding-left: var(--space-sm);
    background-color: transparent;
}

/* ===================================================================
   14. SELECT DROPDOWN (Custom select replacement)
   =================================================================== */

.select-dropdown {
    position: relative;
    width: 100%;
}

.select-dropdown-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-base);
    color: var(--input-text);
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-base);
}

.select-dropdown-toggle:hover {
    border-color: var(--border-dark);
}

.select-dropdown.is-open .select-dropdown-toggle {
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.select-dropdown-toggle::after {
    content: '';
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid var(--text-muted);
    transition: transform var(--transition-fast);
}

.select-dropdown.is-open .select-dropdown-toggle::after {
    transform: rotate(180deg);
}

.select-dropdown-placeholder {
    color: var(--input-placeholder);
}

.select-dropdown .dropdown-menu {
    width: 100%;
    max-height: 250px;
    overflow-y: auto;
}

/* ===================================================================
   15. TAGS/CHIPS IN MULTI-SELECT
   =================================================================== */

.select-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    padding: var(--space-xs);
    min-height: 42px;
    background-color: var(--input-bg);
    border: 2px solid var(--input-border);
    border-radius: var(--radius-md);
    cursor: text;
}

.select-tags:focus-within {
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
}

.select-tag {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 2px var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background-color: var(--bg-hover);
    border-radius: var(--radius-sm);
}

.select-tag-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.select-tag-remove:hover {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.select-tag-remove::before {
    content: '\00d7';
    font-size: 14px;
}

.select-tags-input {
    flex: 1;
    min-width: 100px;
    padding: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--input-text);
    background: none;
    border: none;
    outline: none;
}

.select-tags-input::placeholder {
    color: var(--input-placeholder);
}


/* ===== components/tabs.css ===== */
/* ===================================================================
   DCS Design System - Tab Components
   Version: 2.0.0

   Tabs, pills, and tabbed navigation.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. TAB LIST
   =================================================================== */

.tab-list {
    display: flex;
    gap: var(--space-xs);
    border-bottom: 2px solid var(--border-light);
    margin-bottom: var(--space-lg);
}

/* ===================================================================
   2. TAB ITEM
   =================================================================== */

.tab-item {
    position: relative;
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}

.tab-item:hover {
    color: var(--text-primary);
}

.tab-item:focus {
    outline: none;
}

.tab-item:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Active tab */
.tab-item.active {
    color: var(--brand-primary);
}

.tab-item.active::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 0;
    right: 0;
    height: 2px;
    background-color: var(--brand-primary);
}

/* Tab with icon */
.tab-item i {
    margin-right: var(--space-xs);
}

/* Tab with badge/count */
.tab-badge {
    margin-left: var(--space-xs);
    padding: 2px 8px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
}

.tab-item.active .tab-badge {
    background-color: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

/* Disabled tab */
.tab-item.disabled,
.tab-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* ===================================================================
   3. TAB CONTENT
   =================================================================== */

.tab-content {
    /* Container for tab panels */
}

.tab-panel {
    display: none;
    animation: tab-fade-in var(--transition-base);
}

.tab-panel.active {
    display: block;
}

@keyframes tab-fade-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ===================================================================
   4. PILL TABS (Rounded/filled style)
   =================================================================== */

.tab-list-pills {
    gap: var(--space-sm);
    border-bottom: none;
    background-color: var(--bg-input);
    padding: var(--space-xs);
    border-radius: var(--radius-md);
    width: fit-content;
}

.tab-list-pills .tab-item {
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-sm);
}

.tab-list-pills .tab-item:hover {
    background-color: var(--bg-hover);
}

.tab-list-pills .tab-item.active {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

.tab-list-pills .tab-item.active::after {
    display: none;
}

/* ===================================================================
   5. BORDERED TABS (Card-style)
   =================================================================== */

.tab-list-bordered {
    border-bottom: 1px solid var(--border-light);
}

.tab-list-bordered .tab-item {
    margin-bottom: -1px;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.tab-list-bordered .tab-item.active {
    color: var(--text-primary);
    background-color: var(--bg-surface);
    border-color: var(--border-light);
}

.tab-list-bordered .tab-item.active::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 1px;
    background-color: var(--bg-surface);
}

/* ===================================================================
   6. VERTICAL TABS
   =================================================================== */

.tab-vertical {
    display: flex;
    gap: var(--space-lg);
}

.tab-vertical .tab-list {
    flex-direction: column;
    border-bottom: none;
    border-right: 2px solid var(--border-light);
    margin-bottom: 0;
    padding-right: var(--space-md);
    min-width: 180px;
}

.tab-vertical .tab-item {
    text-align: left;
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-sm);
}

.tab-vertical .tab-item.active::after {
    top: 0;
    bottom: 0;
    left: auto;
    right: calc(var(--space-md) * -1 - 2px);
    width: 2px;
    height: auto;
}

.tab-vertical .tab-content {
    flex: 1;
}

/* ===================================================================
   7. SCROLLABLE TABS
   =================================================================== */

.tab-list-scroll {
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.tab-list-scroll::-webkit-scrollbar {
    display: none;
}

/* Scroll indicators */
.tab-scroll-container {
    position: relative;
}

.tab-scroll-btn {
    position: absolute;
    top: 0;
    bottom: 2px;
    width: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(90deg, var(--bg-body) 50%, transparent);
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    z-index: 1;
    transition: opacity var(--transition-fast);
}

.tab-scroll-btn:hover {
    color: var(--brand-primary);
}

.tab-scroll-btn-left {
    left: 0;
}

.tab-scroll-btn-right {
    right: 0;
    background: linear-gradient(-90deg, var(--bg-body) 50%, transparent);
}

.tab-scroll-btn.is-hidden {
    opacity: 0;
    pointer-events: none;
}

/* ===================================================================
   8. FULL WIDTH TABS
   =================================================================== */

.tab-list-full {
    width: 100%;
}

.tab-list-full .tab-item {
    flex: 1;
    text-align: center;
}

/* ===================================================================
   9. TAB SIZES
   =================================================================== */

/* Small tabs */
.tab-list-sm .tab-item {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-xs);
}

/* Large tabs */
.tab-list-lg .tab-item {
    padding: var(--space-md) var(--space-xl);
    font-size: var(--font-size-base);
}

/* ===================================================================
   10. SEGMENTED CONTROL
   =================================================================== */

.segmented-control {
    display: inline-flex;
    background-color: var(--bg-input);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    padding: 2px;
}

.segmented-item {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.segmented-item:hover {
    color: var(--text-primary);
}

.segmented-item.active {
    color: var(--text-primary);
    background-color: var(--bg-surface);
    box-shadow: var(--shadow-sm);
}

/* Segmented with icons only */
.segmented-icons .segmented-item {
    padding: var(--space-xs) var(--space-sm);
}

/* ===================================================================
   11. STEP TABS (Wizard/Progress)
   =================================================================== */

.tab-list-steps {
    gap: 0;
    border-bottom: none;
    counter-reset: step;
}

.tab-list-steps .tab-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-md);
}

.tab-list-steps .tab-item::before {
    counter-increment: step;
    content: counter(step);
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    background-color: var(--bg-input);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-full);
    transition: all var(--transition-base);
}

.tab-list-steps .tab-item.active::before {
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
    color: var(--btn-primary-text);
}

.tab-list-steps .tab-item.completed::before {
    content: '\f00c'; /* FontAwesome check */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    background-color: var(--color-success);
    border-color: var(--color-success);
    color: var(--text-on-success);
}

.tab-list-steps .tab-item.active::after {
    display: none;
}

/* Step connector line */
.tab-list-steps .tab-item:not(:last-child)::after {
    content: '';
    position: absolute;
    top: calc(var(--space-md) + 16px);
    left: calc(50% + 24px);
    right: calc(-50% + 24px);
    height: 2px;
    background-color: var(--border-medium);
}

.tab-list-steps .tab-item.completed:not(:last-child)::after {
    background-color: var(--color-success);
}

/* Step label */
.tab-step-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.tab-item.active .tab-step-label,
.tab-item.completed .tab-step-label {
    color: var(--text-primary);
}

/* ===================================================================
   12. ICON-ONLY TABS
   =================================================================== */

.tab-list-icons .tab-item {
    padding: var(--space-sm);
}

.tab-list-icons .tab-item i {
    margin-right: 0;
    font-size: var(--font-size-lg);
}

/* ===================================================================
   13. CLOSABLE TABS
   =================================================================== */

.tab-item-closable {
    padding-right: var(--space-sm);
}

.tab-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-left: var(--space-xs);
    font-size: 14px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0;
    transition: all var(--transition-fast);
}

.tab-item:hover .tab-close,
.tab-item.active .tab-close {
    opacity: 1;
}

.tab-close:hover {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.tab-close::before {
    content: '\00d7';
}

/* ===================================================================
   14. ADD TAB BUTTON
   =================================================================== */

.tab-add {
    padding: var(--space-sm);
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.tab-add:hover {
    color: var(--brand-primary);
    background-color: var(--bg-hover);
}

.tab-add::before {
    content: '+';
    font-size: var(--font-size-lg);
}

/* ===================================================================
   15. ANIMATED UNDERLINE
   =================================================================== */

.tab-list-animated {
    position: relative;
}

.tab-indicator {
    position: absolute;
    bottom: -2px;
    height: 2px;
    background-color: var(--brand-primary);
    transition: left var(--transition-base), width var(--transition-base);
}

.tab-list-animated .tab-item.active::after {
    display: none;
}


/* ===== components/badges.css ===== */
/* ===================================================================
   DCS Design System - Badge Components
   Version: 2.0.0

   Badges, tags, labels, and status indicators.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE BADGE
   =================================================================== */

.badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 8px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    line-height: 1.4;
    color: var(--text-primary);
    background-color: var(--bg-input);
    border-radius: var(--radius-sm);
    white-space: nowrap;
    vertical-align: middle;
}

/* ===================================================================
   2. COLOR VARIANTS
   =================================================================== */

.badge-primary {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

.badge-secondary {
    color: var(--text-primary);
    background-color: var(--bg-hover);
    border: 1px solid var(--border-medium);
}

.badge-success {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.badge-danger {
    color: var(--text-on-danger);
    background-color: var(--color-danger);
}

.badge-warning {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

.badge-info {
    color: var(--text-on-info);
    background-color: var(--color-info);
}

/* Soft/light variants */
.badge-soft-primary {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.badge-soft-success {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
}

.badge-soft-danger {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

.badge-soft-warning {
    color: var(--color-warning-text);
    background-color: var(--color-warning-bg);
}

.badge-soft-info {
    color: var(--color-info-text);
    background-color: var(--color-info-bg);
}

/* Outline variants */
.badge-outline {
    background-color: transparent;
    border: 1px solid currentColor;
}

.badge-outline-primary {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
    background-color: transparent;
}

.badge-outline-success {
    color: var(--color-success);
    border-color: var(--color-success);
    background-color: transparent;
}

.badge-outline-danger {
    color: var(--color-danger);
    border-color: var(--color-danger);
    background-color: transparent;
}

.badge-outline-warning {
    color: var(--color-warning);
    border-color: var(--color-warning);
    background-color: transparent;
}

.badge-outline-info {
    color: var(--color-info);
    border-color: var(--color-info);
    background-color: transparent;
}

/* ===================================================================
   3. SIZE VARIANTS
   =================================================================== */

.badge-sm {
    padding: 1px 6px;
    font-size: 10px;
}

.badge-lg {
    padding: 4px 12px;
    font-size: var(--font-size-sm);
}

/* ===================================================================
   4. PILL BADGE (Rounded)
   =================================================================== */

.badge-pill {
    border-radius: var(--radius-full);
    padding-left: 10px;
    padding-right: 10px;
}

/* ===================================================================
   5. DOT BADGE (Notification indicator)
   =================================================================== */

.badge-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border-radius: var(--radius-full);
}

.badge-dot-lg {
    width: 12px;
    height: 12px;
}

/* Positioned dot (on avatars, icons, etc.) */
.badge-dot-positioned {
    position: absolute;
    top: 0;
    right: 0;
}

/* Pulsing dot */
.badge-dot-pulse {
    animation: badge-pulse 2s infinite;
}

@keyframes badge-pulse {
    0% {
        box-shadow: 0 0 0 0 currentColor;
    }
    70% {
        box-shadow: 0 0 0 6px transparent;
    }
    100% {
        box-shadow: 0 0 0 0 transparent;
    }
}

/* ===================================================================
   6. COUNTER BADGE
   =================================================================== */

.badge-counter {
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-full);
    font-size: 11px;
    font-weight: var(--font-weight-bold);
}

/* Positioned counter (for notifications) */
.badge-counter-positioned {
    position: absolute;
    top: -6px;
    right: -6px;
}

/* Large number handling */
.badge-counter-max {
    /* For 99+ style */
}

/* ===================================================================
   7. WITH ICON
   =================================================================== */

.badge-icon {
    gap: var(--space-xs);
}

.badge-icon i {
    font-size: 10px;
}

/* Icon only badge */
.badge-icon-only {
    width: 24px;
    height: 24px;
    padding: 0;
}

.badge-icon-only i {
    font-size: 12px;
}

/* ===================================================================
   8. REMOVABLE BADGE (Tag style)
   =================================================================== */

.badge-removable {
    gap: var(--space-xs);
    padding-right: 4px;
}

.badge-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    margin-left: 2px;
    font-size: 12px;
    color: inherit;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0.7;
    transition: all var(--transition-fast);
}

.badge-remove:hover {
    opacity: 1;
    background-color: rgba(0, 0, 0, 0.1);
}

.badge-remove::before {
    content: '\00d7';
}

/* ===================================================================
   9. TAG INPUT BADGES
   =================================================================== */

.tag {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background-color: var(--bg-hover);
    border-radius: var(--radius-sm);
}

.tag-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.tag-remove:hover {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.tag-remove::before {
    content: '\00d7';
    font-size: 14px;
}

/* Tag colors */
.tag-primary {
    background-color: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

.tag-success {
    background-color: var(--color-success-bg);
    color: var(--color-success-text);
}

.tag-danger {
    background-color: var(--color-danger-bg);
    color: var(--color-danger-text);
}

/* ===================================================================
   10. STATUS BADGES
   =================================================================== */

.status {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background-color: currentColor;
}

.status-online {
    color: var(--color-success);
}

.status-offline {
    color: var(--text-muted);
}

.status-busy {
    color: var(--color-danger);
}

.status-away {
    color: var(--color-warning);
}

/* ===================================================================
   11. GRADE/SCORE BADGES (LMS specific)
   =================================================================== */

.badge-grade {
    min-width: 48px;
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    text-align: center;
    border-radius: var(--radius-sm);
}

.badge-grade-a {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.badge-grade-b {
    color: var(--text-on-warning);
    background-color: var(--grade-color-b);
}

.badge-grade-c {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

.badge-grade-d {
    color: var(--text-on-danger);
    background-color: var(--grade-color-d);
}

.badge-grade-f {
    color: var(--text-on-danger);
    background-color: var(--color-danger);
}

/* Percentage-based coloring */
.badge-score {
    font-variant-numeric: tabular-nums;
}

/* ===================================================================
   12. URGENCY BADGES (LMS deadlines)
   =================================================================== */

.badge-urgency-critical {
    color: var(--text-on-danger);
    background-color: var(--urgency-critical);
    animation: urgency-pulse 1.5s infinite;
}

@keyframes urgency-pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.7;
    }
}

.badge-urgency-high {
    color: var(--text-on-danger);
    background-color: var(--urgency-high);
}

.badge-urgency-medium {
    color: var(--text-on-warning);
    background-color: var(--urgency-medium);
}

.badge-urgency-low {
    color: var(--text-on-success);
    background-color: var(--urgency-low);
}

/* ===================================================================
   13. PROGRESS BADGE
   =================================================================== */

.badge-progress {
    position: relative;
    overflow: hidden;
    background-color: var(--bg-input);
}

.badge-progress-fill {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    background-color: var(--brand-primary);
    opacity: 0.3;
    transition: width var(--transition-base);
}

.badge-progress-text {
    position: relative;
    z-index: 1;
}

/* ===================================================================
   14. LABEL (Form/field labels)
   =================================================================== */

.label {
    display: inline-block;
    padding: 2px 8px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-radius: var(--radius-sm);
}

.label-new {
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
}

.label-beta {
    color: var(--text-on-info);
    background-color: var(--color-purple);
}

.label-pro {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

.label-required {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.label-optional {
    color: var(--text-muted);
    background-color: var(--bg-input);
}

/* ===================================================================
   15. CHIP (Selectable badge)
   =================================================================== */

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background-color: var(--bg-input);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.chip:hover {
    border-color: var(--brand-primary);
    background-color: var(--bg-hover);
}

.chip.selected {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.chip-avatar {
    width: 24px;
    height: 24px;
    margin-left: -4px;
    border-radius: var(--radius-full);
    object-fit: cover;
}

.chip-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    margin-right: -4px;
    color: inherit;
    background: none;
    border: none;
    border-radius: var(--radius-full);
    cursor: pointer;
    opacity: 0.7;
}

.chip-remove:hover {
    opacity: 1;
}

.chip-remove::before {
    content: '\00d7';
    font-size: 14px;
}

/* ===================================================================
   16. BADGE GROUP
   =================================================================== */

.badge-group {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

/* Overlapping badges */
.badge-group-overlap {
    gap: 0;
}

.badge-group-overlap .badge {
    margin-left: -8px;
    border: 2px solid var(--bg-body);
}

.badge-group-overlap .badge:first-child {
    margin-left: 0;
}

/* ===================================================================
   17. CTS CODE BADGE (combined-credit steps)
   Muted variant listing the CTS codes a step counts toward, e.g.
   "COM2105 + COM2115". See docs/implemented/combined-credit-steps.md.
   =================================================================== */

.step-codes-badge {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    background-color: var(--bg-elevated);
}


/* ===== components/progress.css ===== */
/* ===================================================================
   DCS Design System - Progress Components
   Version: 2.0.0

   Progress bars, spinners, loading states, and skeletons.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. PROGRESS BAR
   =================================================================== */

.progress {
    display: flex;
    height: 8px;
    overflow: hidden;
    font-size: var(--font-size-xs);
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
}

.progress-bar {
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
    color: var(--btn-primary-text);
    text-align: center;
    white-space: nowrap;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    transition: width var(--transition-slow);
}

/* ===================================================================
   2. PROGRESS BAR SIZES
   =================================================================== */

.progress-xs {
    height: 4px;
}

.progress-sm {
    height: 6px;
}

.progress-lg {
    height: 12px;
}

.progress-xl {
    height: 20px;
    font-size: var(--font-size-sm);
}

/* ===================================================================
   3. PROGRESS BAR COLORS
   =================================================================== */

.progress-bar-success {
    background-color: var(--color-success);
}

.progress-bar-danger {
    background-color: var(--color-danger);
}

.progress-bar-warning {
    background-color: var(--color-warning);
}

.progress-bar-info {
    background-color: var(--color-info);
}

/* Gradient progress bar */
.progress-bar-gradient {
    background: linear-gradient(90deg, var(--brand-primary), var(--brand-secondary));
}

/* ===================================================================
   4. STRIPED PROGRESS BAR
   =================================================================== */

.progress-bar-striped {
    background-image: linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.15) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.15) 50%,
        rgba(255, 255, 255, 0.15) 75%,
        transparent 75%,
        transparent
    );
    background-size: 16px 16px;
}

/* Animated stripes */
.progress-bar-animated {
    animation: progress-stripes 1s linear infinite;
}

@keyframes progress-stripes {
    0% {
        background-position: 16px 0;
    }
    100% {
        background-position: 0 0;
    }
}

/* ===================================================================
   5. PROGRESS WITH LABEL
   =================================================================== */

.progress-labeled {
    position: relative;
}

.progress-label {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

/* Label inside bar (for large progress) */
.progress-xl .progress-bar {
    position: relative;
}

.progress-xl .progress-bar-label {
    position: absolute;
    left: var(--space-sm);
    font-weight: var(--font-weight-semibold);
}

/* ===================================================================
   6. MULTI-SEGMENT PROGRESS
   =================================================================== */

.progress-stacked {
    display: flex;
}

.progress-stacked .progress-bar {
    border-radius: 0;
}

.progress-stacked .progress-bar:first-child {
    border-top-left-radius: var(--radius-full);
    border-bottom-left-radius: var(--radius-full);
}

.progress-stacked .progress-bar:last-child {
    border-top-right-radius: var(--radius-full);
    border-bottom-right-radius: var(--radius-full);
}

/* ===================================================================
   7. CIRCULAR PROGRESS
   =================================================================== */

.progress-circle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
}

.progress-circle-svg {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.progress-circle-bg {
    fill: none;
    stroke: var(--bg-input);
    stroke-width: 8;
}

.progress-circle-fill {
    fill: none;
    stroke: var(--brand-primary);
    stroke-width: 8;
    stroke-linecap: round;
    stroke-dasharray: 226; /* 2 * PI * radius (36) */
    stroke-dashoffset: 226;
    transition: stroke-dashoffset var(--transition-slow);
}

.progress-circle-label {
    position: absolute;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
}

/* Circle sizes */
.progress-circle-sm {
    width: 48px;
    height: 48px;
}

.progress-circle-sm .progress-circle-bg,
.progress-circle-sm .progress-circle-fill {
    stroke-width: 6;
}

.progress-circle-sm .progress-circle-label {
    font-size: var(--font-size-sm);
}

.progress-circle-lg {
    width: 120px;
    height: 120px;
}

.progress-circle-lg .progress-circle-label {
    font-size: var(--font-size-2xl);
}

/* Circle colors */
.progress-circle-success .progress-circle-fill {
    stroke: var(--color-success);
}

.progress-circle-danger .progress-circle-fill {
    stroke: var(--color-danger);
}

.progress-circle-warning .progress-circle-fill {
    stroke: var(--color-warning);
}

/* ===================================================================
   8. SPINNER
   =================================================================== */

.spinner {
    display: inline-block;
    width: 24px;
    height: 24px;
    border: 3px solid var(--border-medium);
    border-top-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: spinner-rotate 0.75s linear infinite;
}

@keyframes spinner-rotate {
    to {
        transform: rotate(360deg);
    }
}

/* Spinner sizes */
.spinner-xs {
    width: 14px;
    height: 14px;
    border-width: 2px;
}

.spinner-sm {
    width: 18px;
    height: 18px;
    border-width: 2px;
}

.spinner-lg {
    width: 36px;
    height: 36px;
    border-width: 4px;
}

.spinner-xl {
    width: 48px;
    height: 48px;
    border-width: 5px;
}

/* Spinner colors */
.spinner-primary {
    border-top-color: var(--brand-primary);
}

.spinner-secondary {
    border-top-color: var(--brand-secondary);
}

.spinner-success {
    border-top-color: var(--color-success);
}

.spinner-danger {
    border-top-color: var(--color-danger);
}

.spinner-light {
    border-color: var(--border-overlay);
    border-top-color: var(--text-on-overlay);
}

/* ===================================================================
   9. DOTS LOADER
   =================================================================== */

.loader-dots {
    display: inline-flex;
    gap: var(--space-xs);
}

.loader-dot {
    width: 8px;
    height: 8px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: loader-dots-bounce 1.4s infinite ease-in-out both;
}

.loader-dot:nth-child(1) {
    animation-delay: -0.32s;
}

.loader-dot:nth-child(2) {
    animation-delay: -0.16s;
}

@keyframes loader-dots-bounce {
    0%, 80%, 100% {
        transform: scale(0);
    }
    40% {
        transform: scale(1);
    }
}

/* ===================================================================
   10. PULSE LOADER
   =================================================================== */

.loader-pulse {
    width: 40px;
    height: 40px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: loader-pulse 1.2s infinite ease-in-out;
}

@keyframes loader-pulse {
    0% {
        transform: scale(0);
        opacity: 1;
    }
    100% {
        transform: scale(1);
        opacity: 0;
    }
}

/* ===================================================================
   11. BAR LOADER
   =================================================================== */

.loader-bar {
    width: 100%;
    height: 4px;
    background-color: var(--bg-input);
    overflow: hidden;
    border-radius: var(--radius-full);
}

.loader-bar::after {
    content: '';
    display: block;
    width: 40%;
    height: 100%;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: loader-bar-slide 1.5s infinite ease-in-out;
}

@keyframes loader-bar-slide {
    0% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(350%);
    }
}

/* ===================================================================
   12. SKELETON LOADER
   =================================================================== */

.skeleton {
    background: linear-gradient(
        90deg,
        var(--bg-input) 25%,
        var(--bg-hover) 50%,
        var(--bg-input) 75%
    );
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.5s infinite;
    border-radius: var(--radius-sm);
}

@keyframes skeleton-shimmer {
    0% {
        background-position: 200% 0;
    }
    100% {
        background-position: -200% 0;
    }
}

/* Skeleton shapes */
.skeleton-text {
    height: 16px;
    margin-bottom: var(--space-sm);
}

.skeleton-text:last-child {
    width: 70%;
}

.skeleton-title {
    height: 24px;
    width: 60%;
    margin-bottom: var(--space-md);
}

.skeleton-avatar {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-full);
}

.skeleton-avatar-sm {
    width: 32px;
    height: 32px;
}

.skeleton-avatar-lg {
    width: 64px;
    height: 64px;
}

.skeleton-image {
    width: 100%;
    height: 200px;
    border-radius: var(--radius-md);
}

.skeleton-button {
    width: 100px;
    height: 40px;
    border-radius: var(--radius-md);
}

.skeleton-card {
    padding: var(--space-lg);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
}

/* ===================================================================
   13. LOADING OVERLAY
   =================================================================== */

.loading-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-overlay);
    z-index: var(--z-dropdown);
    border-radius: inherit;
}

.loading-overlay-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
}

.loading-overlay-text {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* ===================================================================
   14. STEP PROGRESS (Wizard)
   =================================================================== */

.progress-steps {
    display: flex;
    justify-content: space-between;
    position: relative;
    counter-reset: step;
}

.progress-steps::before {
    content: '';
    position: absolute;
    top: 16px;
    left: 24px;
    right: 24px;
    height: 2px;
    background-color: var(--bg-input);
}

.progress-step {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    z-index: 1;
}

.progress-step-circle {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    background-color: var(--bg-surface);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-full);
    transition: all var(--transition-base);
}

.progress-step-circle::before {
    counter-increment: step;
    content: counter(step);
}

.progress-step-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-align: center;
}

/* Active step */
.progress-step.active .progress-step-circle {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.progress-step.active .progress-step-label {
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
}

/* Completed step */
.progress-step.completed .progress-step-circle {
    color: var(--text-on-success);
    background-color: var(--color-success);
    border-color: var(--color-success);
}

.progress-step.completed .progress-step-circle::before {
    content: '\f00c'; /* FontAwesome check */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
}

.progress-step.completed .progress-step-label {
    color: var(--text-primary);
}

/* Progress line fill */
.progress-steps-fill {
    position: absolute;
    top: 16px;
    left: 24px;
    height: 2px;
    background-color: var(--color-success);
    transition: width var(--transition-slow);
}

/* ===================================================================
   15. COURSE PROGRESS (LMS specific)
   =================================================================== */

.course-progress {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.course-progress-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.course-progress-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.course-progress-percent {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
}

.course-progress-stats {
    display: flex;
    gap: var(--space-md);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   16. UPLOAD PROGRESS
   =================================================================== */

.upload-progress {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.upload-progress-icon {
    font-size: var(--font-size-xl);
    color: var(--brand-primary);
}

.upload-progress-info {
    flex: 1;
    min-width: 0;
}

.upload-progress-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.upload-progress-size {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.upload-progress-bar {
    margin-top: var(--space-xs);
}

.upload-progress-cancel {
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--space-xs);
    transition: color var(--transition-fast);
}

.upload-progress-cancel:hover {
    color: var(--color-danger);
}


/* ===== components/navigation.css ===== */
/* ===================================================================
   DCS Design System - Navigation Components
   Version: 2.0.0

   Navbar, sidebar, breadcrumbs, pagination, and menus.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. NAVBAR
   =================================================================== */

.navbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-surface);
    border-bottom: 1px solid var(--border-light);
}

.navbar-brand {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    text-decoration: none;
}

.navbar-brand-logo {
    height: 32px;
    width: auto;
}

.navbar-nav {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.navbar-link {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.navbar-link:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.navbar-link.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.navbar-actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* Fixed navbar */
.navbar-fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-fixed);
}

/* Transparent navbar */
.navbar-transparent {
    background-color: transparent;
    border-bottom: none;
}

/* Dark navbar */
.navbar-dark {
    background-color: var(--bg-body);
}

/* ===================================================================
   2. SIDEBAR
   =================================================================== */

.sidebar {
    display: flex;
    flex-direction: column;
    width: 260px;
    height: 100vh;
    background-color: var(--bg-surface);
    border-right: 1px solid var(--border-light);
    overflow-y: auto;
}

.sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-lg);
    border-bottom: 1px solid var(--border-light);
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    text-decoration: none;
}

.sidebar-brand-logo {
    height: 28px;
    width: auto;
}

.sidebar-content {
    flex: 1;
    padding: var(--space-md);
    overflow-y: auto;
}

.sidebar-footer {
    padding: var(--space-md);
    border-top: 1px solid var(--border-light);
}

/* Sidebar nav */
.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.sidebar-section {
    margin-bottom: var(--space-lg);
}

.sidebar-section-title {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.sidebar-link {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.sidebar-link:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.sidebar-link.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.sidebar-link i {
    width: 20px;
    text-align: center;
    font-size: var(--font-size-base);
}

.sidebar-link-badge {
    margin-left: auto;
    padding: 2px 8px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

/* Collapsible sidebar */
.sidebar-collapsed {
    width: 64px;
}

.sidebar-collapsed .sidebar-brand-text,
.sidebar-collapsed .sidebar-link span,
.sidebar-collapsed .sidebar-section-title,
.sidebar-collapsed .sidebar-link-badge {
    display: none;
}

.sidebar-collapsed .sidebar-link {
    justify-content: center;
    padding: var(--space-sm);
}

.sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.sidebar-toggle:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

/* ===================================================================
   3. BREADCRUMBS
   =================================================================== */

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    padding: 0;
    margin: 0;
    font-size: var(--font-size-sm);
}

.breadcrumb-item {
    display: flex;
    align-items: center;
    color: var(--text-muted);
}

.breadcrumb-item a {
    color: var(--text-secondary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.breadcrumb-item a:hover {
    color: var(--brand-primary);
}

.breadcrumb-item + .breadcrumb-item::before {
    content: '/';
    padding-right: var(--space-xs);
    color: var(--text-muted);
}

.breadcrumb-item.active {
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
}

/* Breadcrumb with icons */
.breadcrumb-item i {
    margin-right: var(--space-xs);
}

/* Truncated breadcrumb */
.breadcrumb-truncate .breadcrumb-item {
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ===================================================================
   4. PAGINATION
   =================================================================== */

.pagination {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.pagination-item {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    background-color: transparent;
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    text-decoration: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.pagination-item:hover {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.pagination-item.active {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.pagination-item:disabled,
.pagination-item.disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Pagination prev/next */
.pagination-prev,
.pagination-next {
    font-size: var(--font-size-xs);
}

/* Pagination ellipsis */
.pagination-ellipsis {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    color: var(--text-muted);
}

/* Simple pagination */
.pagination-simple {
    gap: var(--space-md);
}

.pagination-simple .pagination-item {
    border: none;
    background: none;
}

/* ===================================================================
   5. PAGE HEADER
   =================================================================== */

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

.page-header-content {
    flex: 1;
}

.page-title {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--space-xs);
}

.page-description {
    font-size: var(--font-size-base);
    color: var(--text-muted);
    margin: 0;
}

.page-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* ===================================================================
   6. SUB-NAVIGATION (Horizontal)
   =================================================================== */

.subnav {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
    margin-bottom: var(--space-lg);
}

.subnav-link {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    text-decoration: none;
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.subnav-link:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.subnav-link.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

/* ===================================================================
   7. MENU (Vertical list)
   =================================================================== */

.menu {
    display: flex;
    flex-direction: column;
    padding: var(--space-xs) 0;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.menu-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    text-decoration: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.menu-item:hover {
    background-color: var(--bg-hover);
}

.menu-item.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.menu-item i {
    width: 20px;
    text-align: center;
    color: var(--text-muted);
}

.menu-item:hover i {
    color: var(--brand-primary);
}

.menu-item-badge {
    margin-left: auto;
}

.menu-divider {
    height: 1px;
    margin: var(--space-xs) 0;
    background-color: var(--border-light);
}

.menu-header {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Danger item */
.menu-item-danger {
    color: var(--color-danger-text);
}

.menu-item-danger:hover {
    background-color: var(--color-danger-bg);
}

.menu-item-danger i {
    color: var(--color-danger-text);
}

/* ===================================================================
   8. BOTTOM NAVIGATION (Mobile)
   =================================================================== */

.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: stretch;
    background-color: var(--bg-surface);
    border-top: 1px solid var(--border-light);
    z-index: var(--z-fixed);
}

.bottom-nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: var(--space-sm);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-decoration: none;
    transition: all var(--transition-fast);
}

.bottom-nav-item:hover,
.bottom-nav-item.active {
    color: var(--brand-primary);
}

.bottom-nav-item i {
    font-size: var(--font-size-lg);
}

.bottom-nav-item-badge {
    position: absolute;
    top: 4px;
    right: calc(50% - 20px);
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: 10px;
    font-weight: var(--font-weight-bold);
    color: var(--text-on-danger);
    background-color: var(--color-danger);
    border-radius: var(--radius-full);
}

/* ===================================================================
   9. STEPPER NAVIGATION
   =================================================================== */

.stepper {
    display: flex;
    align-items: flex-start;
}

.stepper-step {
    flex: 1;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.stepper-step:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 16px;
    left: calc(50% + 20px);
    right: calc(-50% + 20px);
    height: 2px;
    background-color: var(--border-medium);
}

.stepper-step.completed:not(:last-child)::after {
    background-color: var(--color-success);
}

.stepper-indicator {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    background-color: var(--bg-surface);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-full);
    z-index: 1;
    transition: all var(--transition-base);
}

.stepper-step.active .stepper-indicator {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.stepper-step.completed .stepper-indicator {
    color: var(--text-on-success);
    background-color: var(--color-success);
    border-color: var(--color-success);
}

.stepper-step.completed .stepper-indicator::before {
    content: '\f00c'; /* FontAwesome check */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
}

.stepper-label {
    margin-top: var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.stepper-step.active .stepper-label {
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
}

/* Vertical stepper */
.stepper-vertical {
    flex-direction: column;
}

.stepper-vertical .stepper-step {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
}

.stepper-vertical .stepper-step:not(:last-child)::after {
    top: 32px;
    left: 16px;
    right: auto;
    bottom: 0;
    width: 2px;
    height: auto;
}

.stepper-vertical .stepper-label {
    margin-top: 0;
    margin-left: var(--space-md);
}

/* ===================================================================
   10. ANCHOR NAVIGATION (Scrollspy)
   =================================================================== */

.anchor-nav {
    position: sticky;
    top: var(--space-lg);
    padding-left: var(--space-md);
    border-left: 2px solid var(--border-light);
}

.anchor-nav-title {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: var(--space-sm);
}

.anchor-nav-link {
    display: block;
    padding: var(--space-xs) 0;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-decoration: none;
    transition: all var(--transition-fast);
}

.anchor-nav-link:hover {
    color: var(--text-primary);
}

.anchor-nav-link.active {
    color: var(--brand-primary);
    font-weight: var(--font-weight-medium);
}

/* Nested anchors */
.anchor-nav-nested {
    padding-left: var(--space-md);
}

.anchor-nav-nested .anchor-nav-link {
    font-size: var(--font-size-xs);
}

/* ===================================================================
   11. CUSTOM SCROLLBARS
   =================================================================== */

/* Sidebar scrollbar - thin and subtle */
.sidebar::-webkit-scrollbar,
.sidebar-content::-webkit-scrollbar {
    width: 4px;
}

.sidebar::-webkit-scrollbar-track,
.sidebar-content::-webkit-scrollbar-track {
    background: transparent;
}

.sidebar::-webkit-scrollbar-thumb,
.sidebar-content::-webkit-scrollbar-thumb {
    background: var(--border-light);
    border-radius: var(--radius-full);
}

.sidebar::-webkit-scrollbar-thumb:hover,
.sidebar-content::-webkit-scrollbar-thumb:hover {
    background: var(--border-medium);
}

/* Firefox sidebar scrollbar */
.sidebar,
.sidebar-content {
    scrollbar-width: thin;
    scrollbar-color: var(--border-light) transparent;
}

/* ===================================================================
   12. FOCUS MODE
   =================================================================== */

/* Focus mode - hide sidebar completely for distraction-free work */
body.focus-mode .sidebar {
    width: 0;
    padding: 0;
    overflow: hidden;
    border: none;
}

body.focus-mode .sidebar * {
    opacity: 0;
    visibility: hidden;
}

/* Navbar becomes minimal in focus mode */
body.focus-mode .navbar {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    padding: var(--space-sm) var(--space-lg);
}

body.focus-mode .navbar-nav {
    display: none;
}

/* Main content expands */
body.focus-mode .main-content {
    max-width: var(--container-xl);
    margin: 0 auto;
    padding: var(--space-xl);
}

/* Focus mode toggle button */
.focus-mode-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.focus-mode-toggle:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

body.focus-mode .focus-mode-toggle {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

/* Exit focus mode hint */
body.focus-mode::before {
    content: 'Press Esc to exit focus mode';
    position: fixed;
    bottom: var(--space-lg);
    left: 50%;
    transform: translateX(-50%);
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    opacity: 0;
    transition: opacity var(--transition-base);
    pointer-events: none;
    z-index: var(--z-toast);
}

body.focus-mode:hover::before {
    opacity: 1;
}


/* ===== components/avatars.css ===== */
/* ===================================================================
   DCS Design System - Avatar Components
   Version: 2.0.0

   User avatars, initials, groups, and status indicators.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE AVATAR
   =================================================================== */

.avatar {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    background-color: var(--bg-hover);
    border-radius: var(--radius-full);
    overflow: hidden;
    flex-shrink: 0;
}

.avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ===================================================================
   2. SIZE VARIANTS
   =================================================================== */

.avatar-xs {
    width: 24px;
    height: 24px;
    font-size: 10px;
}

.avatar-sm {
    width: 32px;
    height: 32px;
    font-size: var(--font-size-xs);
}

.avatar-lg {
    width: 56px;
    height: 56px;
    font-size: var(--font-size-lg);
}

.avatar-xl {
    width: 80px;
    height: 80px;
    font-size: var(--font-size-2xl);
}

.avatar-2xl {
    width: 120px;
    height: 120px;
    font-size: var(--font-size-3xl);
}

/* ===================================================================
   3. SHAPE VARIANTS
   =================================================================== */

.avatar-rounded {
    border-radius: var(--radius-md);
}

.avatar-square {
    border-radius: 0;
}

/* ===================================================================
   4. COLOR VARIANTS
   =================================================================== */

.avatar-primary {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

.avatar-secondary {
    color: var(--text-primary);
    background-color: var(--bg-input);
}

.avatar-success {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.avatar-danger {
    color: var(--text-on-danger);
    background-color: var(--color-danger);
}

.avatar-warning {
    color: var(--text-on-warning);
    background-color: var(--color-warning);
}

.avatar-info {
    color: var(--text-on-info);
    background-color: var(--color-info);
}

/* Soft color variants */
.avatar-soft-primary {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.avatar-soft-success {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
}

.avatar-soft-danger {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

/* ===================================================================
   5. INITIALS AVATAR
   =================================================================== */

.avatar-initials {
    text-transform: uppercase;
    letter-spacing: -1px;
    user-select: none;
}

/* Auto-color based on initials (use with JS) */
.avatar-auto-color {
    /* Colors assigned via inline style or data attribute */
}

/* ===================================================================
   6. STATUS INDICATOR
   =================================================================== */

.avatar-status {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 12px;
    height: 12px;
    border: 2px solid var(--bg-body);
    border-radius: var(--radius-full);
}

/* Status sizes based on avatar size */
.avatar-xs .avatar-status {
    width: 8px;
    height: 8px;
    border-width: 1px;
}

.avatar-sm .avatar-status {
    width: 10px;
    height: 10px;
}

.avatar-lg .avatar-status {
    width: 14px;
    height: 14px;
    border-width: 3px;
}

.avatar-xl .avatar-status,
.avatar-2xl .avatar-status {
    width: 18px;
    height: 18px;
    border-width: 3px;
}

/* Status colors */
.avatar-status-online {
    background-color: var(--color-success);
}

.avatar-status-offline {
    background-color: var(--text-muted);
}

.avatar-status-busy {
    background-color: var(--color-danger);
}

.avatar-status-away {
    background-color: var(--color-warning);
}

/* Pulsing online status */
.avatar-status-online.pulse {
    animation: status-pulse 2s infinite;
}

@keyframes status-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.5);
    }
    70% {
        box-shadow: 0 0 0 6px rgba(16, 185, 129, 0);
    }
    100% {
        box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
    }
}

/* ===================================================================
   7. AVATAR WITH BADGE
   =================================================================== */

.avatar-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    font-size: 10px;
    font-weight: var(--font-weight-bold);
    line-height: 18px;
    color: var(--text-on-danger);
    background-color: var(--color-danger);
    border: 2px solid var(--bg-body);
    border-radius: var(--radius-full);
    text-align: center;
}

.avatar-xs .avatar-badge {
    min-width: 14px;
    height: 14px;
    font-size: 8px;
    line-height: 14px;
    padding: 0 3px;
    top: -2px;
    right: -2px;
}

/* ===================================================================
   8. AVATAR GROUP
   =================================================================== */

.avatar-group {
    display: inline-flex;
    flex-direction: row-reverse;
}

.avatar-group .avatar {
    margin-left: -12px;
    border: 2px solid var(--bg-body);
    transition: all var(--transition-fast);
}

.avatar-group .avatar:last-child {
    margin-left: 0;
}

.avatar-group .avatar:hover {
    z-index: 1;
    transform: translateY(-2px);
}

/* Group sizes */
.avatar-group-sm .avatar {
    margin-left: -8px;
}

.avatar-group-lg .avatar {
    margin-left: -16px;
}

/* More indicator */
.avatar-group-more {
    background-color: var(--bg-input);
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

/* Stacked vertically */
.avatar-group-vertical {
    flex-direction: column;
}

.avatar-group-vertical .avatar {
    margin-left: 0;
    margin-top: -12px;
}

.avatar-group-vertical .avatar:first-child {
    margin-top: 0;
}

/* ===================================================================
   9. AVATAR WITH TEXT
   =================================================================== */

.avatar-text {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
}

.avatar-text-content {
    display: flex;
    flex-direction: column;
}

.avatar-text-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    line-height: 1.3;
}

.avatar-text-subtitle {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    line-height: 1.3;
}

/* Reversed (text first) */
.avatar-text-reverse {
    flex-direction: row-reverse;
    text-align: right;
}

/* ===================================================================
   10. PLACEHOLDER/FALLBACK AVATAR
   =================================================================== */

.avatar-placeholder {
    color: var(--text-muted);
    background-color: var(--bg-input);
}

.avatar-placeholder i {
    font-size: 60%;
}

/* ===================================================================
   11. CLICKABLE AVATAR
   =================================================================== */

.avatar-clickable {
    cursor: pointer;
    transition: all var(--transition-fast);
}

.avatar-clickable:hover {
    transform: scale(1.05);
    box-shadow: var(--shadow-md);
}

.avatar-clickable:active {
    transform: scale(1);
}

/* ===================================================================
   12. BORDERED AVATAR
   =================================================================== */

.avatar-bordered {
    border: 2px solid var(--border-medium);
}

.avatar-bordered-primary {
    border-color: var(--brand-primary);
}

.avatar-bordered-success {
    border-color: var(--color-success);
}

.avatar-bordered-thick {
    border-width: 3px;
}

/* ===================================================================
   13. AVATAR WITH OVERLAY
   =================================================================== */

.avatar-overlay {
    position: relative;
}

.avatar-overlay::after {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--bg-overlay-medium);
    border-radius: inherit;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.avatar-overlay:hover::after {
    opacity: 1;
}

.avatar-overlay-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: var(--text-on-overlay);
    font-size: var(--font-size-lg);
    z-index: 1;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.avatar-overlay:hover .avatar-overlay-icon {
    opacity: 1;
}

/* ===================================================================
   14. UPLOAD AVATAR
   =================================================================== */

.avatar-upload {
    position: relative;
    cursor: pointer;
}

.avatar-upload-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.avatar-upload-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-scrim);
    border-radius: inherit;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.avatar-upload:hover .avatar-upload-overlay {
    opacity: 1;
}

.avatar-upload-icon {
    color: var(--text-on-overlay);
    font-size: var(--font-size-lg);
}

/* ===================================================================
   15. AVATAR RING (Progress/Activity)
   =================================================================== */

.avatar-ring {
    position: relative;
    padding: 3px;
}

.avatar-ring::before {
    content: '';
    position: absolute;
    inset: 0;
    border: 3px solid var(--brand-primary);
    border-radius: var(--radius-full);
}

/* Gradient ring */
.avatar-ring-gradient::before {
    border: 3px solid transparent;
    background: linear-gradient(45deg, var(--brand-primary), var(--brand-secondary)) border-box;
    -webkit-mask:
        linear-gradient(#fff 0 0) padding-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
}

/* ===================================================================
   16. SKELETON AVATAR
   =================================================================== */

.avatar-skeleton {
    background: linear-gradient(
        90deg,
        var(--bg-input) 25%,
        var(--bg-hover) 50%,
        var(--bg-input) 75%
    );
    background-size: 200% 100%;
    animation: avatar-skeleton 1.5s infinite;
}

@keyframes avatar-skeleton {
    0% {
        background-position: 200% 0;
    }
    100% {
        background-position: -200% 0;
    }
}

/* ===================================================================
   17. PROFILE AVATAR (Large with edit option)
   =================================================================== */

.profile-avatar {
    position: relative;
    display: inline-block;
}

.profile-avatar .avatar {
    width: 100px;
    height: 100px;
    font-size: var(--font-size-3xl);
}

.profile-avatar-edit {
    position: absolute;
    bottom: 4px;
    right: 4px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border: 2px solid var(--bg-body);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.profile-avatar-edit:hover {
    background-color: var(--brand-primary-dark);
    transform: scale(1.1);
}


/* ===== components/lists.css ===== */
/* ===================================================================
   DCS Design System - List Components
   Version: 2.0.0

   List groups, activity feeds, and timeline components.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. LIST GROUP
   =================================================================== */

.list-group {
    display: flex;
    flex-direction: column;
    padding: 0;
    margin: 0;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.list-group-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md) var(--space-lg);
    color: var(--text-primary);
    text-decoration: none;
    background-color: transparent;
    border-bottom: 1px solid var(--border-light);
    transition: background-color var(--transition-fast);
}

.list-group-item:last-child {
    border-bottom: none;
}

/* Interactive list items */
a.list-group-item,
button.list-group-item {
    cursor: pointer;
}

a.list-group-item:hover,
button.list-group-item:hover {
    background-color: var(--bg-hover);
}

.list-group-item.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.list-group-item:disabled,
.list-group-item.disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* ===================================================================
   2. LIST GROUP VARIANTS
   =================================================================== */

/* Flush (no outer borders/radius) */
.list-group-flush {
    border: none;
    border-radius: 0;
}

.list-group-flush .list-group-item:first-child {
    border-top: 1px solid var(--border-light);
}

/* Horizontal */
.list-group-horizontal {
    flex-direction: row;
}

.list-group-horizontal .list-group-item {
    border-bottom: none;
    border-right: 1px solid var(--border-light);
}

.list-group-horizontal .list-group-item:last-child {
    border-right: none;
}

/* Numbered */
.list-group-numbered {
    counter-reset: list-item;
}

.list-group-numbered .list-group-item::before {
    counter-increment: list-item;
    content: counter(list-item) ".";
    width: 24px;
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
}

/* ===================================================================
   3. LIST GROUP ITEM CONTENT
   =================================================================== */

.list-group-item-content {
    flex: 1;
    min-width: 0;
}

.list-group-item-title {
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    margin-bottom: 2px;
}

.list-group-item-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin: 0;
}

.list-group-item-action {
    flex-shrink: 0;
}

/* ===================================================================
   4. LIST GROUP STATUS COLORS
   =================================================================== */

.list-group-item-success {
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
}

.list-group-item-danger {
    background-color: var(--color-danger-bg);
    border-color: var(--color-danger);
}

.list-group-item-warning {
    background-color: var(--color-warning-bg);
    border-color: var(--color-warning);
}

.list-group-item-info {
    background-color: var(--color-info-bg);
    border-color: var(--color-info);
}

/* ===================================================================
   5. ACTIVITY FEED
   =================================================================== */

.activity-feed {
    display: flex;
    flex-direction: column;
}

.activity-item {
    display: flex;
    gap: var(--space-md);
    padding: var(--space-md) 0;
}

.activity-item:not(:last-child) {
    border-bottom: 1px solid var(--border-light);
}

.activity-icon {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-sm);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-full);
}

.activity-icon-success {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
}

.activity-icon-danger {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

.activity-icon-warning {
    color: var(--color-warning-text);
    background-color: var(--color-warning-bg);
}

.activity-content {
    flex: 1;
    min-width: 0;
}

.activity-title {
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.activity-title strong {
    font-weight: var(--font-weight-semibold);
}

.activity-time {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.activity-description {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    margin-top: var(--space-xs);
}

/* ===================================================================
   6. TIMELINE
   =================================================================== */

.timeline {
    position: relative;
    padding-left: var(--space-xl);
}

.timeline::before {
    content: '';
    position: absolute;
    top: 0;
    left: 11px;
    bottom: 0;
    width: 2px;
    background-color: var(--border-light);
}

.timeline-item {
    position: relative;
    padding-bottom: var(--space-xl);
}

.timeline-item:last-child {
    padding-bottom: 0;
}

.timeline-marker {
    position: absolute;
    left: calc(var(--space-xl) * -1);
    top: 0;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-body);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-full);
    z-index: 1;
}

.timeline-marker i {
    font-size: 10px;
    color: var(--text-muted);
}

/* Marker colors */
.timeline-item.completed .timeline-marker {
    background-color: var(--color-success);
    border-color: var(--color-success);
}

.timeline-item.completed .timeline-marker i {
    color: var(--text-on-success);
}

.timeline-item.active .timeline-marker {
    background-color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.timeline-item.active .timeline-marker i {
    color: var(--btn-primary-text);
}

.timeline-item.error .timeline-marker {
    background-color: var(--color-danger);
    border-color: var(--color-danger);
}

.timeline-item.error .timeline-marker i {
    color: var(--text-on-danger);
}

.timeline-content {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
}

.timeline-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.timeline-time {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
}

.timeline-body {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* Compact timeline */
.timeline-compact .timeline-item {
    padding-bottom: var(--space-md);
}

.timeline-compact .timeline-content {
    background: none;
    border: none;
    padding: 0;
}

/* ===================================================================
   7. DESCRIPTION LIST
   =================================================================== */

.description-list {
    display: grid;
    gap: var(--space-md);
}

.description-list dt {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
}

.description-list dd {
    font-size: var(--font-size-base);
    color: var(--text-primary);
    margin: 0;
}

/* Horizontal layout */
.description-list-horizontal {
    grid-template-columns: minmax(120px, auto) 1fr;
    align-items: baseline;
}

.description-list-horizontal dt {
    text-align: right;
    padding-right: var(--space-md);
}

/* Striped */
.description-list-striped dt,
.description-list-striped dd {
    padding: var(--space-sm) var(--space-md);
}

.description-list-striped > *:nth-child(4n+1),
.description-list-striped > *:nth-child(4n+2) {
    background-color: var(--bg-input);
}

/* ===================================================================
   8. CHECKLIST
   =================================================================== */

.checklist {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.checklist-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
}

.checklist-checkbox {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    margin-top: 2px;
}

.checklist-content {
    flex: 1;
}

.checklist-label {
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    cursor: pointer;
}

.checklist-item.completed .checklist-label {
    color: var(--text-muted);
    text-decoration: line-through;
}

.checklist-meta {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-top: 2px;
}

/* ===================================================================
   9. MEDIA LIST (Items with thumbnails)
   =================================================================== */

.media-list {
    display: flex;
    flex-direction: column;
}

.media-item {
    display: flex;
    gap: var(--space-md);
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.media-item:last-child {
    border-bottom: none;
}

.media-item:hover {
    background-color: var(--bg-hover);
}

.media-thumbnail {
    flex-shrink: 0;
    width: 64px;
    height: 64px;
    border-radius: var(--radius-md);
    overflow: hidden;
    background-color: var(--bg-input);
}

.media-thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media-content {
    flex: 1;
    min-width: 0;
}

.media-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.media-title a {
    color: inherit;
    text-decoration: none;
}

.media-title a:hover {
    color: var(--brand-primary);
}

.media-description {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.media-meta {
    display: flex;
    gap: var(--space-md);
    margin-top: var(--space-xs);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   10. FILE LIST
   =================================================================== */

.file-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.file-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.file-item:hover {
    border-color: var(--brand-primary);
    background-color: var(--bg-hover);
}

.file-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-lg);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-md);
}

.file-info {
    flex: 1;
    min-width: 0;
}

.file-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.file-meta {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.file-actions {
    display: flex;
    gap: var(--space-xs);
}

/* File type icons */
.file-icon-pdf { color: var(--color-danger); background-color: var(--color-danger-bg); }
.file-icon-doc { color: var(--color-info); background-color: var(--color-info-bg); }
.file-icon-xls { color: var(--color-success); background-color: var(--color-success-bg); }
.file-icon-img { color: var(--color-purple); background-color: var(--color-purple-bg); }
.file-icon-zip { color: var(--color-warning); background-color: var(--color-warning-bg); }

/* ===================================================================
   11. NOTIFICATION LIST
   =================================================================== */

.notification-list {
    display: flex;
    flex-direction: column;
}

.notification-item {
    display: flex;
    gap: var(--space-md);
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
    transition: background-color var(--transition-fast);
}

.notification-item:hover {
    background-color: var(--bg-hover);
}

.notification-item.unread {
    background-color: var(--brand-primary-alpha);
}

.notification-item.unread::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background-color: var(--brand-primary);
}

.notification-avatar {
    flex-shrink: 0;
}

.notification-content {
    flex: 1;
    min-width: 0;
}

.notification-text {
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.notification-text strong {
    font-weight: var(--font-weight-semibold);
}

.notification-time {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   12. ASSIGNMENT LIST (LMS specific)
   =================================================================== */

.assignment-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.assignment-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.assignment-item:hover {
    border-color: var(--brand-primary);
}

.assignment-status {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
}

.assignment-status-pending { background-color: var(--color-warning); }
.assignment-status-submitted { background-color: var(--color-info); }
.assignment-status-graded { background-color: var(--color-success); }
.assignment-status-late { background-color: var(--color-danger); }

.assignment-info {
    flex: 1;
    min-width: 0;
}

.assignment-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.assignment-course {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.assignment-due {
    flex-shrink: 0;
    text-align: right;
}

.assignment-due-date {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.assignment-due-label {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.assignment-due.urgent .assignment-due-date {
    color: var(--color-danger);
}

/* ===================================================================
   13. STACKED LIST
   =================================================================== */

.stacked-list {
    display: flex;
    flex-direction: column;
}

.stacked-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.stacked-list-item:last-child {
    border-bottom: none;
}

.stacked-list-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.stacked-list-value {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

/* ===================================================================
   14. SIMPLE LIST
   =================================================================== */

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

.simple-list li {
    padding: var(--space-sm) 0;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-light);
}

.simple-list li:last-child {
    border-bottom: none;
}

/* Bullet list */
.bullet-list li {
    position: relative;
    padding-left: var(--space-lg);
}

.bullet-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: calc(var(--space-sm) + 6px);
    width: 6px;
    height: 6px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}


/* ===== components/hero.css ===== */
/* ===================================================================
   DCS Design System - Hero Components
   Version: 2.0.0

   Hero sections, banners, and landing page layouts.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE HERO
   =================================================================== */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 400px;
    padding: var(--space-3xl) var(--space-lg);
    background-color: var(--bg-surface);
    overflow: hidden;
}

.hero-content {
    position: relative;
    z-index: 2;
    max-width: var(--container-lg);
    text-align: center;
}

.hero-title {
    font-size: clamp(2rem, 5vw, var(--font-size-4xl));
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: var(--line-height-tight);
    margin-bottom: var(--space-md);
}

.hero-subtitle {
    font-size: clamp(1rem, 2.5vw, var(--font-size-xl));
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
    margin-bottom: var(--space-xl);
    max-width: 700px;
    margin-left: auto;
    margin-right: auto;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    justify-content: center;
}

/* ===================================================================
   2. HERO SIZE VARIANTS
   =================================================================== */

.hero-sm {
    min-height: 300px;
    padding: var(--space-2xl) var(--space-lg);
}

.hero-lg {
    min-height: 500px;
    padding: var(--space-3xl) var(--space-lg);
}

.hero-xl {
    min-height: 600px;
    padding: var(--space-3xl) var(--space-lg);
}

.hero-fullscreen {
    min-height: 100vh;
}

/* ===================================================================
   3. HERO WITH BACKGROUND IMAGE
   =================================================================== */

.hero-image {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Dark overlay for readability */
.hero-image::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(10, 25, 47, 0.7) 0%,
        rgba(10, 25, 47, 0.85) 100%
    );
    z-index: 1;
}

[data-theme="light"] .hero-image::before {
    background: linear-gradient(
        to bottom,
        rgba(255, 255, 255, 0.85) 0%,
        rgba(248, 250, 252, 0.95) 100%
    );
}

/* Overlay opacity variants */
.hero-overlay-light::before {
    background: rgba(10, 25, 47, 0.5);
}

.hero-overlay-dark::before {
    background: rgba(10, 25, 47, 0.9);
}

[data-theme="light"] .hero-overlay-light::before {
    background: rgba(255, 255, 255, 0.7);
}

[data-theme="light"] .hero-overlay-dark::before {
    background: rgba(255, 255, 255, 0.95);
}

/* ===================================================================
   4. HERO WITH GRADIENT
   =================================================================== */

.hero-gradient {
    background: linear-gradient(
        135deg,
        var(--bg-body) 0%,
        var(--bg-surface) 50%,
        var(--bg-elevated) 100%
    );
}

.hero-gradient-brand {
    background: linear-gradient(
        135deg,
        rgba(var(--brand-primary-rgb), 0.1) 0%,
        var(--bg-body) 50%,
        rgba(var(--brand-secondary-rgb), 0.1) 100%
    );
}

/* ===================================================================
   5. HERO WITH PATTERN
   =================================================================== */

.hero-pattern {
    background-image:
        radial-gradient(var(--border-light) 1px, transparent 1px);
    background-size: 32px 32px;
}

.hero-pattern-dots {
    background-image:
        radial-gradient(var(--brand-primary-alpha) 2px, transparent 2px);
    background-size: 24px 24px;
}

.hero-pattern-grid {
    background-image:
        linear-gradient(var(--border-light) 1px, transparent 1px),
        linear-gradient(90deg, var(--border-light) 1px, transparent 1px);
    background-size: 48px 48px;
}

/* ===================================================================
   6. HERO ALIGNMENT
   =================================================================== */

.hero-left {
    justify-content: flex-start;
}

.hero-left .hero-content {
    text-align: left;
}

.hero-left .hero-actions {
    justify-content: flex-start;
}

.hero-right {
    justify-content: flex-end;
}

.hero-right .hero-content {
    text-align: right;
}

.hero-right .hero-actions {
    justify-content: flex-end;
}

/* ===================================================================
   7. SPLIT HERO (Image + Content)
   =================================================================== */

.hero-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2xl);
    padding: var(--space-2xl);
    text-align: left;
}

.hero-split .hero-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    text-align: left;
}

.hero-split .hero-actions {
    justify-content: flex-start;
}

.hero-split-media {
    display: flex;
    align-items: center;
    justify-content: center;
}

.hero-split-media img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xl);
}

/* Reverse order */
.hero-split-reverse {
    direction: rtl;
}

.hero-split-reverse > * {
    direction: ltr;
}

@media (max-width: 768px) {
    .hero-split {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .hero-split .hero-content {
        text-align: center;
        order: 1;
    }

    .hero-split .hero-actions {
        justify-content: center;
    }

    .hero-split-media {
        order: 2;
    }

    .hero-split-reverse .hero-content {
        order: 1;
    }
}

/* ===================================================================
   8. HERO DECORATIONS
   =================================================================== */

/* Floating shapes */
.hero-shapes::after {
    content: '';
    position: absolute;
    width: 400px;
    height: 400px;
    border-radius: 50%;
    background: radial-gradient(
        circle,
        var(--brand-primary-alpha) 0%,
        transparent 70%
    );
    top: -100px;
    right: -100px;
    z-index: 0;
    pointer-events: none;
}

.hero-shapes::before {
    content: '';
    position: absolute;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    background: radial-gradient(
        circle,
        var(--brand-secondary-alpha) 0%,
        transparent 70%
    );
    bottom: -50px;
    left: -50px;
    z-index: 0;
    pointer-events: none;
}

/* Glow effect */
.hero-glow {
    position: relative;
}

.hero-glow .hero-title {
    text-shadow: 0 0 40px var(--brand-primary-alpha);
}

/* ===================================================================
   9. HERO BADGE/ANNOUNCEMENT
   =================================================================== */

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-xs) var(--space-md);
    margin-bottom: var(--space-lg);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border: 1px solid var(--brand-primary-alpha-strong);
    border-radius: var(--radius-full);
}

.hero-badge i {
    font-size: var(--font-size-xs);
}

.hero-badge-new {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
}

/* ===================================================================
   10. HERO STATS
   =================================================================== */

.hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xl);
    justify-content: center;
    margin-top: var(--space-2xl);
    padding-top: var(--space-xl);
    border-top: 1px solid var(--border-light);
}

.hero-stat {
    text-align: center;
}

.hero-stat-value {
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-bold);
    color: var(--brand-primary);
    line-height: 1;
}

.hero-stat-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-top: var(--space-xs);
}

/* ===================================================================
   11. HERO SCROLL INDICATOR
   =================================================================== */

.hero-scroll {
    position: absolute;
    bottom: var(--space-xl);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: color var(--transition-fast);
    z-index: 2;
}

.hero-scroll:hover {
    color: var(--brand-primary);
}

.hero-scroll-icon {
    width: 24px;
    height: 40px;
    border: 2px solid currentColor;
    border-radius: var(--radius-full);
    position: relative;
}

.hero-scroll-icon::before {
    content: '';
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 4px;
    height: 8px;
    background-color: currentColor;
    border-radius: var(--radius-full);
    animation: hero-scroll-bounce 2s infinite;
}

@keyframes hero-scroll-bounce {
    0%, 100% {
        transform: translateX(-50%) translateY(0);
        opacity: 1;
    }
    50% {
        transform: translateX(-50%) translateY(10px);
        opacity: 0.5;
    }
}

/* ===================================================================
   12. HERO VIDEO BACKGROUND
   =================================================================== */

.hero-video {
    position: relative;
}

.hero-video-bg {
    position: absolute;
    inset: 0;
    overflow: hidden;
    z-index: 0;
}

.hero-video-bg video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hero-video::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(10, 25, 47, 0.7);
    z-index: 1;
}

/* ===================================================================
   13. FEATURE GRID (For Landing Pages)
   =================================================================== */

.feature-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-xl);
    padding: var(--space-2xl) 0;
}

.feature-item {
    text-align: center;
    padding: var(--space-lg);
}

.feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: var(--space-md);
    font-size: var(--font-size-2xl);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-lg);
}

.feature-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.feature-description {
    font-size: var(--font-size-base);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

/* Feature grid variants */
.feature-grid-3 {
    grid-template-columns: repeat(3, 1fr);
}

.feature-grid-4 {
    grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 768px) {
    .feature-grid-3,
    .feature-grid-4 {
        grid-template-columns: 1fr;
    }
}

/* Horizontal feature */
.feature-item-horizontal {
    display: flex;
    text-align: left;
    gap: var(--space-md);
}

.feature-item-horizontal .feature-icon {
    flex-shrink: 0;
    margin-bottom: 0;
}

/* ===================================================================
   14. TESTIMONIAL SECTION
   =================================================================== */

.testimonial-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--space-lg);
}

.testimonial {
    padding: var(--space-xl);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
}

.testimonial-quote {
    font-size: var(--font-size-lg);
    font-style: italic;
    color: var(--text-primary);
    line-height: var(--line-height-relaxed);
    margin-bottom: var(--space-lg);
    position: relative;
    padding-left: var(--space-lg);
}

.testimonial-quote::before {
    content: '\f10d'; /* FontAwesome quote-left */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-style: normal;
    position: absolute;
    left: 0;
    top: 0;
    font-size: var(--font-size-lg);
    color: var(--brand-primary);
    opacity: 0.5;
}

.testimonial-author {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.testimonial-avatar {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-full);
    object-fit: cover;
}

.testimonial-name {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.testimonial-role {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* Featured testimonial */
.testimonial-featured {
    grid-column: span 2;
    text-align: center;
    padding: var(--space-2xl);
}

.testimonial-featured .testimonial-quote {
    font-size: var(--font-size-xl);
    padding-left: 0;
}

.testimonial-featured .testimonial-quote::before {
    position: static;
    display: block;
    margin-bottom: var(--space-md);
    font-size: var(--font-size-2xl);
}

.testimonial-featured .testimonial-author {
    justify-content: center;
}

@media (max-width: 768px) {
    .testimonial-featured {
        grid-column: span 1;
    }
}

/* ===================================================================
   15. CTA SECTION
   =================================================================== */

.cta-section {
    padding: var(--space-3xl) var(--space-lg);
    text-align: center;
    background-color: var(--bg-surface);
    border-radius: var(--radius-xl);
}

.cta-section-gradient {
    background: linear-gradient(
        135deg,
        var(--brand-primary-alpha) 0%,
        var(--bg-surface) 50%,
        var(--brand-secondary-alpha) 100%
    );
}

.cta-title {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.cta-description {
    font-size: var(--font-size-lg);
    color: var(--text-secondary);
    margin-bottom: var(--space-xl);
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
}

.cta-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    justify-content: center;
}

/* Inline CTA */
.cta-inline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-xl);
    padding: var(--space-xl);
    text-align: left;
}

.cta-inline .cta-content {
    flex: 1;
}

.cta-inline .cta-title {
    margin-bottom: var(--space-xs);
}

.cta-inline .cta-description {
    margin-bottom: 0;
    max-width: none;
}

@media (max-width: 768px) {
    .cta-inline {
        flex-direction: column;
        text-align: center;
    }

    .cta-inline .cta-actions {
        width: 100%;
    }
}


/* ===== components/accordion.css ===== */
/* ===================================================================
   DCS Design System - Accordion Components
   Version: 2.0.0

   Collapsible content sections, FAQs, and expandable panels.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE ACCORDION
   =================================================================== */

.accordion {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.accordion-item {
    border-bottom: 1px solid var(--border-light);
}

.accordion-item:last-child {
    border-bottom: none;
}

/* ===================================================================
   2. ACCORDION HEADER / TRIGGER
   =================================================================== */

.accordion-header {
    margin: 0;
}

.accordion-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: var(--space-md) var(--space-lg);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    text-align: left;
    background-color: var(--bg-surface);
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.accordion-trigger:hover {
    background-color: var(--bg-hover);
}

.accordion-trigger:focus {
    outline: none;
    background-color: var(--bg-hover);
}

.accordion-trigger:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: -2px;
}

/* Accordion icon */
.accordion-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    color: var(--text-muted);
    transition: transform var(--transition-base);
    flex-shrink: 0;
}

.accordion-icon::before {
    content: '\f078'; /* FontAwesome chevron-down */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
}

/* Expanded state */
.accordion-item.is-open .accordion-trigger {
    color: var(--brand-primary);
}

.accordion-item.is-open .accordion-icon {
    transform: rotate(180deg);
    color: var(--brand-primary);
}

/* ===================================================================
   3. ACCORDION CONTENT / PANEL
   =================================================================== */

.accordion-content {
    display: none;
    overflow: hidden;
}

.accordion-item.is-open .accordion-content {
    display: block;
}

.accordion-body {
    padding: 0 var(--space-lg) var(--space-lg);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

/* Animated expand (requires JS to set max-height) */
.accordion-content-animated {
    display: block;
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--transition-slow);
}

.accordion-item.is-open .accordion-content-animated {
    max-height: 1000px; /* Adjust based on content */
}

/* ===================================================================
   4. ACCORDION VARIANTS
   =================================================================== */

/* Flush - no outer border */
.accordion-flush {
    border: none;
    border-radius: 0;
}

.accordion-flush .accordion-item {
    border-radius: 0;
}

.accordion-flush .accordion-item:first-child .accordion-trigger {
    border-radius: 0;
}

.accordion-flush .accordion-item:last-child .accordion-trigger {
    border-radius: 0;
}

/* Separated - gap between items */
.accordion-separated {
    border: none;
    gap: var(--space-sm);
}

.accordion-separated .accordion-item {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

/* Bordered - prominent borders */
.accordion-bordered .accordion-item {
    border-left: 3px solid var(--border-medium);
}

.accordion-bordered .accordion-item.is-open {
    border-left-color: var(--brand-primary);
}

/* ===================================================================
   5. ACCORDION SIZES
   =================================================================== */

.accordion-sm .accordion-trigger {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
}

.accordion-sm .accordion-body {
    padding: 0 var(--space-md) var(--space-md);
    font-size: var(--font-size-sm);
}

.accordion-lg .accordion-trigger {
    padding: var(--space-lg) var(--space-xl);
    font-size: var(--font-size-lg);
}

.accordion-lg .accordion-body {
    padding: 0 var(--space-xl) var(--space-xl);
}

/* ===================================================================
   6. ACCORDION WITH ICONS
   =================================================================== */

.accordion-trigger-icon {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.accordion-trigger-icon i {
    width: 24px;
    text-align: center;
    color: var(--brand-primary);
}

/* Plus/minus icon variant */
.accordion-plus .accordion-icon::before {
    content: '+';
    font-family: inherit;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-normal);
}

.accordion-plus .accordion-item.is-open .accordion-icon::before {
    content: '−';
}

.accordion-plus .accordion-item.is-open .accordion-icon {
    transform: none;
}

/* ===================================================================
   7. FAQ ACCORDION
   =================================================================== */

.faq {
    max-width: var(--container-md);
    margin: 0 auto;
}

.faq-title {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    text-align: center;
    margin-bottom: var(--space-xl);
}

.faq-subtitle {
    font-size: var(--font-size-base);
    color: var(--text-muted);
    text-align: center;
    margin-bottom: var(--space-2xl);
}

.faq .accordion-trigger {
    font-weight: var(--font-weight-semibold);
}

.faq .accordion-body {
    color: var(--text-secondary);
}

/* FAQ categories */
.faq-category {
    margin-bottom: var(--space-2xl);
}

.faq-category-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 2px solid var(--brand-primary);
}

/* ===================================================================
   8. NESTED ACCORDION
   =================================================================== */

.accordion-nested {
    margin-top: var(--space-md);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.accordion-nested .accordion-trigger {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    background-color: var(--bg-input);
}

.accordion-nested .accordion-body {
    padding: 0 var(--space-md) var(--space-md);
    font-size: var(--font-size-sm);
}

/* ===================================================================
   9. ACCORDION STATES
   =================================================================== */

/* Disabled */
.accordion-item.is-disabled .accordion-trigger {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Loading */
.accordion-item.is-loading .accordion-trigger::after {
    content: '';
    width: 16px;
    height: 16px;
    margin-left: var(--space-sm);
    border: 2px solid var(--border-medium);
    border-top-color: var(--brand-primary);
    border-radius: 50%;
    animation: accordion-spin 0.6s linear infinite;
}

@keyframes accordion-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ===================================================================
   10. COLLAPSIBLE SECTIONS (Single item)
   =================================================================== */

.collapsible {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.collapsible-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: var(--space-md) var(--space-lg);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    text-align: left;
    background-color: var(--bg-surface);
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.collapsible-trigger:hover {
    background-color: var(--bg-hover);
}

.collapsible-icon {
    transition: transform var(--transition-base);
}

.collapsible-icon::before {
    content: '\f078';
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.collapsible.is-open .collapsible-icon {
    transform: rotate(180deg);
}

.collapsible-content {
    display: none;
    padding: 0 var(--space-lg) var(--space-lg);
}

.collapsible.is-open .collapsible-content {
    display: block;
}

/* ===================================================================
   11. EXPANDABLE TEXT
   =================================================================== */

.expandable-text {
    position: relative;
}

.expandable-text-content {
    overflow: hidden;
    max-height: 100px;
    transition: max-height var(--transition-slow);
}

.expandable-text.is-expanded .expandable-text-content {
    max-height: 2000px;
}

.expandable-text-gradient {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 60px;
    background: linear-gradient(to bottom, transparent, var(--bg-body));
    pointer-events: none;
    transition: opacity var(--transition-base);
}

.expandable-text.is-expanded .expandable-text-gradient {
    opacity: 0;
}

.expandable-text-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    margin-top: var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--brand-primary);
    background: none;
    border: none;
    cursor: pointer;
    transition: color var(--transition-fast);
}

.expandable-text-toggle:hover {
    color: var(--brand-primary-dark);
}

/* ===================================================================
   12. DETAILS/SUMMARY (Native HTML)
   =================================================================== */

details.accordion-native {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
}

details.accordion-native + details.accordion-native {
    margin-top: var(--space-sm);
}

details.accordion-native summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    background-color: var(--bg-surface);
    cursor: pointer;
    list-style: none;
    transition: background-color var(--transition-fast);
}

details.accordion-native summary::-webkit-details-marker {
    display: none;
}

details.accordion-native summary::after {
    content: '\f078';
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    transition: transform var(--transition-base);
}

details.accordion-native[open] summary::after {
    transform: rotate(180deg);
}

details.accordion-native summary:hover {
    background-color: var(--bg-hover);
}

details.accordion-native > div {
    padding: 0 var(--space-lg) var(--space-lg);
    color: var(--text-secondary);
}

/* ===================================================================
   13. COURSE CONTENT ACCORDION (LMS Specific)
   =================================================================== */

.course-content-accordion .accordion-item {
    background-color: var(--bg-surface);
}

.course-content-accordion .accordion-trigger {
    padding: var(--space-md) var(--space-lg);
}

.course-section-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    flex: 1;
}

.course-section-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

.course-section-title {
    font-weight: var(--font-weight-semibold);
}

.course-section-meta {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.course-section-progress {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.course-section-progress i {
    color: var(--color-success);
}

/* Lesson list inside accordion */
.course-lesson-list {
    display: flex;
    flex-direction: column;
}

.course-lesson-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.course-lesson-item:last-child {
    border-bottom: none;
}

.course-lesson-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--text-muted);
    background-color: var(--bg-input);
    border-radius: var(--radius-sm);
}

.course-lesson-item.is-completed .course-lesson-icon {
    color: var(--text-on-success);
    background-color: var(--color-success);
}

.course-lesson-item.is-completed .course-lesson-icon::before {
    content: '\f00c';
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
}

.course-lesson-item.is-current .course-lesson-icon {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

.course-lesson-info {
    flex: 1;
}

.course-lesson-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.course-lesson-item.is-completed .course-lesson-title {
    color: var(--text-muted);
}

.course-lesson-duration {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.course-lesson-badge {
    padding: 2px var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-sm);
}


/* ===== components/footer.css ===== */
/* ===================================================================
   DCS Design System - Footer Components
   Version: 2.0.0

   Site footers, link columns, and bottom navigation.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE FOOTER
   =================================================================== */

.footer {
    background-color: var(--bg-surface);
    border-top: 1px solid var(--border-light);
    padding: var(--space-2xl) var(--space-lg);
}

.footer-container {
    max-width: var(--container-xl);
    margin: 0 auto;
}

/* ===================================================================
   2. FOOTER GRID LAYOUT
   =================================================================== */

.footer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-xl);
}

/* Brand column - wider */
.footer-brand-column {
    grid-column: span 2;
}

@media (max-width: 768px) {
    .footer-brand-column {
        grid-column: span 1;
    }
}

/* ===================================================================
   3. FOOTER BRAND
   =================================================================== */

.footer-brand {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.footer-brand-logo {
    height: 32px;
    width: auto;
}

.footer-brand-name {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.footer-brand-description {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    line-height: var(--line-height-relaxed);
    max-width: 300px;
}

/* ===================================================================
   4. FOOTER COLUMNS
   =================================================================== */

.footer-column {
    display: flex;
    flex-direction: column;
}

.footer-column-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: var(--space-md);
}

.footer-links {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.footer-link {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.footer-link:hover {
    color: var(--brand-primary);
}

.footer-link i {
    width: 20px;
    margin-right: var(--space-xs);
}

/* Link with badge */
.footer-link-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
}

.footer-link-badge .badge {
    font-size: 10px;
    padding: 2px 6px;
}

/* ===================================================================
   5. FOOTER SOCIAL LINKS
   =================================================================== */

.footer-social {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.footer-social-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    font-size: var(--font-size-base);
    color: var(--text-muted);
    background-color: var(--bg-input);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.footer-social-link:hover {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

/* Colored social icons */
.footer-social-link-facebook:hover {
    background-color: #1877f2;
}

.footer-social-link-twitter:hover {
    background-color: #1da1f2;
}

.footer-social-link-instagram:hover {
    background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
}

.footer-social-link-linkedin:hover {
    background-color: #0a66c2;
}

.footer-social-link-youtube:hover {
    background-color: #ff0000;
}

.footer-social-link-github:hover {
    background-color: #333;
}

/* ===================================================================
   6. FOOTER NEWSLETTER
   =================================================================== */

.footer-newsletter {
    margin-top: var(--space-lg);
}

.footer-newsletter-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.footer-newsletter-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-md);
}

.footer-newsletter-form {
    display: flex;
    gap: var(--space-sm);
}

.footer-newsletter-input {
    flex: 1;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--input-text);
    background-color: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-md);
    transition: border-color var(--transition-fast);
}

.footer-newsletter-input:focus {
    outline: none;
    border-color: var(--input-focus-border);
}

.footer-newsletter-input::placeholder {
    color: var(--input-placeholder);
}

.footer-newsletter-btn {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--btn-primary-text);
    background-color: var(--btn-primary-bg);
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.footer-newsletter-btn:hover {
    background-color: var(--btn-primary-hover);
}

@media (max-width: 480px) {
    .footer-newsletter-form {
        flex-direction: column;
    }

    .footer-newsletter-btn {
        width: 100%;
    }
}

/* ===================================================================
   7. FOOTER BOTTOM / COPYRIGHT
   =================================================================== */

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding-top: var(--space-xl);
    margin-top: var(--space-xl);
    border-top: 1px solid var(--border-light);
}

.footer-copyright {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.footer-legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
}

.footer-legal-link {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.footer-legal-link:hover {
    color: var(--brand-primary);
}

.footer-legal-divider {
    color: var(--border-medium);
}

@media (max-width: 576px) {
    .footer-bottom {
        flex-direction: column;
        text-align: center;
    }
}

/* ===================================================================
   8. FOOTER VARIANTS
   =================================================================== */

/* Dark footer */
.footer-dark {
    background-color: var(--bg-body);
}

/* Minimal footer */
.footer-minimal {
    padding: var(--space-lg);
    text-align: center;
}

.footer-minimal .footer-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
}

.footer-minimal .footer-links {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
}

.footer-minimal .footer-bottom {
    border-top: none;
    margin-top: 0;
    padding-top: 0;
    justify-content: center;
}

/* Centered footer */
.footer-centered {
    text-align: center;
}

.footer-centered .footer-grid {
    justify-items: center;
}

.footer-centered .footer-brand-description {
    margin-left: auto;
    margin-right: auto;
}

.footer-centered .footer-links {
    align-items: center;
}

.footer-centered .footer-social {
    justify-content: center;
}

/* ===================================================================
   9. FOOTER WITH BACKGROUND
   =================================================================== */

.footer-gradient {
    background: linear-gradient(
        to bottom,
        var(--bg-body),
        var(--bg-surface)
    );
    border-top: none;
}

.footer-pattern {
    background-image: radial-gradient(var(--border-light) 1px, transparent 1px);
    background-size: 24px 24px;
}

/* ===================================================================
   10. FOOTER APP DOWNLOAD
   =================================================================== */

.footer-app-links {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.footer-app-link {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background-color: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: all var(--transition-fast);
}

.footer-app-link:hover {
    border-color: var(--brand-primary);
    background-color: var(--bg-hover);
}

.footer-app-link i {
    font-size: var(--font-size-xl);
    color: var(--text-primary);
}

.footer-app-link-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.footer-app-link-label {
    font-size: 10px;
    color: var(--text-muted);
}

.footer-app-link-store {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

/* ===================================================================
   11. FOOTER CONTACT INFO
   =================================================================== */

.footer-contact {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.footer-contact-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.footer-contact-item i {
    width: 16px;
    color: var(--brand-primary);
    margin-top: 2px;
}

.footer-contact-item a {
    color: var(--text-secondary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.footer-contact-item a:hover {
    color: var(--brand-primary);
}

/* ===================================================================
   12. FOOTER LANGUAGE SELECTOR
   =================================================================== */

.footer-language {
    position: relative;
    margin-top: var(--space-md);
}

.footer-language-btn {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    background-color: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.footer-language-btn:hover {
    border-color: var(--brand-primary);
}

.footer-language-btn i {
    color: var(--text-muted);
}

/* ===================================================================
   13. STICKY FOOTER
   =================================================================== */

/* Ensure footer stays at bottom */
.page-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.page-wrapper .main-content {
    flex: 1;
}

/* ===================================================================
   14. BACK TO TOP BUTTON
   =================================================================== */

.back-to-top {
    position: fixed;
    bottom: var(--space-xl);
    right: var(--space-xl);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
    border: none;
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(20px);
    transition: all var(--transition-base);
    z-index: var(--z-fixed);
}

.back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.back-to-top:hover {
    background-color: var(--brand-primary-dark);
    transform: translateY(-2px);
}

.back-to-top i {
    font-size: var(--font-size-lg);
}

/* On pages where the raise-hand FAB owns the bottom-right corner
   (activity/task pages), stack the back-to-top button above it:
   the FAB is ~72px tall at bottom var(--space-xl). */
.back-to-top--above-fab {
    bottom: calc(var(--space-xl) + 72px + var(--space-md));
}

@media (max-width: 768px) {
    .back-to-top--above-fab {
        /* Mobile FAB: bottom var(--space-md), icon-only ~68px tall */
        bottom: calc(var(--space-md) + 68px + var(--space-sm));
        right: var(--space-md);
    }
}

@media (prefers-reduced-motion: reduce) {
    .back-to-top {
        transition: none;
    }

    .back-to-top:hover {
        transform: none;
    }
}

/* ===================================================================
   15. LMS FOOTER (Specific)
   =================================================================== */

.footer-lms {
    padding: var(--space-lg);
}

.footer-lms .footer-bottom {
    padding-top: var(--space-md);
    margin-top: var(--space-md);
}

.footer-lms-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    justify-content: center;
}

.footer-lms-link {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-decoration: none;
}

.footer-lms-link:hover {
    color: var(--brand-primary);
}

/* Powered by badge */
.footer-powered {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.footer-powered-logo {
    height: 16px;
    width: auto;
    opacity: 0.7;
}


/* ===== components/calendar.css ===== */
/* ===================================================================
   DCS Design System - Calendar Components
   Version: 2.0.0

   Calendars, date pickers, and schedule displays.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. BASE CALENDAR
   =================================================================== */

.calendar {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* ===================================================================
   2. CALENDAR HEADER
   =================================================================== */

.calendar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
}

.calendar-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.calendar-nav {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.calendar-nav-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--text-secondary);
    background: none;
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.calendar-nav-btn:hover {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.calendar-today-btn {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    background: none;
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.calendar-today-btn:hover {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
}

/* ===================================================================
   3. CALENDAR WEEKDAYS
   =================================================================== */

.calendar-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
}

.calendar-weekday {
    padding: var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Weekend columns */
.calendar-weekday:first-child,
.calendar-weekday:last-child {
    color: var(--text-light);
}

/* ===================================================================
   4. CALENDAR DAYS GRID
   =================================================================== */

.calendar-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
}

.calendar-day {
    position: relative;
    min-height: 80px;
    padding: var(--space-xs);
    border-right: 1px solid var(--border-light);
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.calendar-day:nth-child(7n) {
    border-right: none;
}

.calendar-day:hover {
    background-color: var(--bg-hover);
}

/* Day number */
.calendar-day-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    border-radius: var(--radius-full);
    margin-bottom: var(--space-xs);
}

/* Different month days */
.calendar-day-other .calendar-day-number {
    color: var(--text-light);
}

.calendar-day-other {
    background-color: var(--bg-body);
}

/* Today */
.calendar-day-today .calendar-day-number {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

/* Selected day */
.calendar-day-selected {
    background-color: var(--brand-primary-alpha);
}

.calendar-day-selected .calendar-day-number {
    color: var(--brand-primary);
    font-weight: var(--font-weight-bold);
}

/* Weekend days */
.calendar-day:nth-child(7n),
.calendar-day:nth-child(7n-6) {
    background-color: var(--bg-body);
}

/* ===================================================================
   5. CALENDAR EVENTS
   =================================================================== */

.calendar-events {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
}

.calendar-event {
    padding: 2px var(--space-xs);
    font-size: 11px;
    font-weight: var(--font-weight-medium);
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    border-radius: var(--radius-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: opacity var(--transition-fast);
}

.calendar-event:hover {
    opacity: 0.85;
}

/* Event colors */
.calendar-event-success {
    background-color: var(--color-success);
}

.calendar-event-danger {
    background-color: var(--color-danger);
}

.calendar-event-warning {
    background-color: var(--color-warning);
    color: var(--text-on-warning);
}

.calendar-event-info {
    background-color: var(--color-info);
}

/* More events indicator */
.calendar-more {
    font-size: 10px;
    color: var(--text-muted);
    padding: 2px var(--space-xs);
}

.calendar-more:hover {
    color: var(--brand-primary);
}

/* ===================================================================
   6. MINI CALENDAR (Date Picker Style)
   =================================================================== */

.calendar-mini {
    width: 280px;
}

.calendar-mini .calendar-header {
    padding: var(--space-sm) var(--space-md);
}

.calendar-mini .calendar-title {
    font-size: var(--font-size-base);
}

.calendar-mini .calendar-day {
    min-height: auto;
    padding: var(--space-xs);
    border: none;
    text-align: center;
}

.calendar-mini .calendar-day-number {
    margin: 0 auto;
}

.calendar-mini .calendar-events {
    display: none;
}

/* Event indicator dots for mini calendar */
.calendar-mini .calendar-day.has-events::after {
    content: '';
    position: absolute;
    bottom: 2px;
    left: 50%;
    transform: translateX(-50%);
    width: 4px;
    height: 4px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

/* ===================================================================
   7. CALENDAR VIEW MODES
   =================================================================== */

.calendar-view-toggle {
    display: flex;
    gap: var(--space-xs);
    padding: 2px;
    background-color: var(--bg-input);
    border-radius: var(--radius-md);
}

.calendar-view-btn {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.calendar-view-btn:hover {
    color: var(--text-primary);
}

.calendar-view-btn.active {
    color: var(--btn-primary-text);
    background-color: var(--brand-primary);
}

/* ===================================================================
   8. WEEK VIEW
   =================================================================== */

.calendar-week {
    display: grid;
    grid-template-columns: 60px repeat(7, 1fr);
}

.calendar-week-times {
    border-right: 1px solid var(--border-light);
}

.calendar-week-time {
    height: 60px;
    padding: var(--space-xs);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-align: right;
    border-bottom: 1px solid var(--border-light);
}

.calendar-week-column {
    border-right: 1px solid var(--border-light);
}

.calendar-week-column:last-child {
    border-right: none;
}

.calendar-week-slot {
    height: 60px;
    border-bottom: 1px solid var(--border-light);
    position: relative;
}

.calendar-week-slot:hover {
    background-color: var(--bg-hover);
}

/* Week view event */
.calendar-week-event {
    position: absolute;
    left: 2px;
    right: 2px;
    padding: var(--space-xs);
    font-size: var(--font-size-xs);
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    border-radius: var(--radius-sm);
    overflow: hidden;
    z-index: 1;
}

/* ===================================================================
   9. AGENDA/LIST VIEW
   =================================================================== */

.calendar-agenda {
    max-height: 400px;
    overflow-y: auto;
}

.calendar-agenda-date {
    position: sticky;
    top: 0;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
}

.calendar-agenda-date-today {
    color: var(--brand-primary);
}

.calendar-agenda-event {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.calendar-agenda-event:hover {
    background-color: var(--bg-hover);
}

.calendar-agenda-time {
    flex-shrink: 0;
    width: 60px;
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.calendar-agenda-indicator {
    flex-shrink: 0;
    width: 4px;
    height: 100%;
    min-height: 40px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

.calendar-agenda-content {
    flex: 1;
    min-width: 0;
}

.calendar-agenda-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.calendar-agenda-details {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   10. DATE PICKER DROPDOWN
   =================================================================== */

.datepicker {
    position: relative;
}

.datepicker-input {
    padding-right: calc(var(--space-md) * 3);
}

.datepicker-icon {
    position: absolute;
    right: var(--space-md);
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

.datepicker-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: var(--space-xs);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-dropdown);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: all var(--transition-fast);
}

.datepicker.is-open .datepicker-dropdown {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* ===================================================================
   11. DATE RANGE PICKER
   =================================================================== */

.daterange {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.daterange-separator {
    color: var(--text-muted);
}

.daterange-dropdown {
    display: flex;
    gap: var(--space-lg);
    padding: var(--space-md);
}

.daterange-presets {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    padding-right: var(--space-lg);
    border-right: 1px solid var(--border-light);
}

.daterange-preset {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    text-align: left;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.daterange-preset:hover {
    background-color: var(--bg-hover);
    color: var(--text-primary);
}

.daterange-preset.active {
    background-color: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

/* ===================================================================
   12. LMS ASSIGNMENT CALENDAR
   =================================================================== */

.calendar-assignment {
    padding: 2px var(--space-xs);
    font-size: 11px;
    border-radius: var(--radius-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Assignment types */
.calendar-assignment-question-set {
    color: var(--color-info-text);
    background-color: var(--color-info-bg);
}

.calendar-assignment-homework {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.calendar-assignment-project {
    color: var(--brand-secondary);
    background-color: var(--brand-secondary-alpha);
}

.calendar-assignment-exam {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

/* Due indicator */
.calendar-assignment-due {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.calendar-assignment-due::before {
    content: '\f017'; /* FontAwesome clock */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 400;
    font-size: 10px;
}

/* Overdue */
.calendar-assignment-overdue {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
}

/* Completed */
.calendar-assignment-completed {
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
    text-decoration: line-through;
    opacity: 0.7;
}

/* ===================================================================
   13. COURSE SCHEDULE
   =================================================================== */

.schedule {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.schedule-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
}

.schedule-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.schedule-day {
    padding: var(--space-md) var(--space-lg);
    border-bottom: 1px solid var(--border-light);
}

.schedule-day:last-child {
    border-bottom: none;
}

.schedule-day-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-sm);
}

.schedule-day-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.schedule-day-date {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.schedule-items {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.schedule-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm);
    background-color: var(--bg-body);
    border-radius: var(--radius-md);
}

.schedule-item-time {
    flex-shrink: 0;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--brand-primary);
}

.schedule-item-content {
    flex: 1;
}

.schedule-item-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.schedule-item-location {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   14. UPCOMING DATES WIDGET
   =================================================================== */

.upcoming-dates {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
}

.upcoming-dates-title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-md);
}

.upcoming-date-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.upcoming-date-item:last-child {
    border-bottom: none;
}

.upcoming-date-calendar {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    background-color: var(--bg-input);
    border-radius: var(--radius-md);
    flex-shrink: 0;
}

.upcoming-date-month {
    font-size: 10px;
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
    text-transform: uppercase;
}

.upcoming-date-day {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1;
}

.upcoming-date-content {
    flex: 1;
    min-width: 0;
}

.upcoming-date-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.upcoming-date-details {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.upcoming-date-badge {
    flex-shrink: 0;
}


/* ===== components/comments.css ===== */
/* ===================================================================
   DCS Design System - Comments & Discussion Components
   Version: 2.0.0

   Comment threads, discussion forums, and conversation UI.
   Requires: tokens.css to be loaded first.
   =================================================================== */

/* ===================================================================
   1. COMMENTS CONTAINER
   =================================================================== */

.comments {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

.comments-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.comments-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.comments-count {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    font-weight: var(--font-weight-normal);
    margin-left: var(--space-sm);
}

.comments-sort {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* ===================================================================
   2. SINGLE COMMENT
   =================================================================== */

.comment {
    display: flex;
    gap: var(--space-md);
}

.comment-avatar {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    object-fit: cover;
}

.comment-avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background-color: var(--brand-primary-alpha);
    color: var(--brand-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-full);
    text-transform: uppercase;
}

.comment-content {
    flex: 1;
    min-width: 0;
}

.comment-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-bottom: var(--space-xs);
}

.comment-author {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.comment-author:hover {
    color: var(--brand-primary);
}

.comment-badge {
    padding: 2px var(--space-xs);
    font-size: 10px;
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-sm);
    text-transform: uppercase;
}

.comment-badge-instructor {
    color: var(--brand-secondary);
    background-color: var(--brand-secondary-alpha);
}

.comment-badge-op {
    color: var(--color-info-text);
    background-color: var(--color-info-bg);
}

.comment-time {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.comment-edited {
    font-size: var(--font-size-xs);
    color: var(--text-light);
    font-style: italic;
}

.comment-body {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

.comment-body p {
    margin-bottom: var(--space-sm);
}

.comment-body p:last-child {
    margin-bottom: 0;
}

/* Code in comments */
.comment-body code {
    padding: 2px var(--space-xs);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    background-color: var(--bg-input);
    border-radius: var(--radius-sm);
}

.comment-body pre {
    padding: var(--space-md);
    margin: var(--space-sm) 0;
    background-color: var(--bg-input);
    border-radius: var(--radius-md);
    overflow-x: auto;
}

.comment-body pre code {
    padding: 0;
    background: none;
}

/* Quoted text */
.comment-body blockquote {
    margin: var(--space-sm) 0;
    padding: var(--space-sm) var(--space-md);
    border-left: 3px solid var(--brand-primary);
    background-color: var(--bg-input);
    color: var(--text-muted);
    font-style: italic;
}

/* ===================================================================
   3. COMMENT ACTIONS
   =================================================================== */

.comment-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-top: var(--space-sm);
}

.comment-action {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 0;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    transition: color var(--transition-fast);
}

.comment-action:hover {
    color: var(--brand-primary);
}

.comment-action i {
    font-size: var(--font-size-sm);
}

/* Upvote/like with count */
.comment-action-votes {
    padding: var(--space-xs) var(--space-sm);
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
}

.comment-action-votes.is-voted {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.comment-vote-count {
    margin-left: var(--space-xs);
    font-weight: var(--font-weight-semibold);
}

/* ===================================================================
   4. NESTED REPLIES
   =================================================================== */

.comment-replies {
    margin-top: var(--space-md);
    margin-left: calc(40px + var(--space-md));
    padding-left: var(--space-lg);
    border-left: 2px solid var(--border-light);
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.comment-replies .comment-avatar {
    width: 32px;
    height: 32px;
}

.comment-replies .comment-avatar-placeholder {
    width: 32px;
    height: 32px;
    font-size: var(--font-size-xs);
}

/* Collapse replies toggle */
.comment-collapse {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    margin-top: var(--space-sm);
    padding: var(--space-xs) 0;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
}

.comment-collapse:hover {
    color: var(--brand-primary);
}

.comment-collapse i {
    transition: transform var(--transition-fast);
}

.comment-collapse.is-collapsed i {
    transform: rotate(-90deg);
}

/* ===================================================================
   5. COMMENT FORM
   =================================================================== */

.comment-form {
    display: flex;
    gap: var(--space-md);
}

.comment-form-avatar {
    flex-shrink: 0;
}

.comment-form-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.comment-form-input {
    width: 100%;
    padding: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--input-text);
    background-color: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-lg);
    resize: vertical;
    min-height: 80px;
    transition: all var(--transition-base);
}

.comment-form-input:focus {
    border-color: var(--input-focus-border);
    box-shadow: var(--input-focus-shadow);
    outline: none;
}

.comment-form-input::placeholder {
    color: var(--input-placeholder);
}

.comment-form-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.comment-form-tools {
    display: flex;
    gap: var(--space-xs);
}

.comment-form-tool {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.comment-form-tool:hover {
    color: var(--brand-primary);
    background-color: var(--bg-hover);
}

.comment-form-actions {
    display: flex;
    gap: var(--space-sm);
}

/* Inline reply form */
.comment-reply-form {
    margin-top: var(--space-md);
    margin-left: calc(40px + var(--space-md));
}

.comment-reply-form .comment-form-input {
    min-height: 60px;
}

/* ===================================================================
   6. DISCUSSION THREAD
   =================================================================== */

.discussion {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.discussion-header {
    padding: var(--space-lg);
    border-bottom: 1px solid var(--border-light);
}

.discussion-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.discussion-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.discussion-meta-item {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.discussion-meta-item i {
    color: var(--brand-primary);
}

.discussion-body {
    padding: var(--space-lg);
}

.discussion-content {
    font-size: var(--font-size-base);
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

.discussion-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.discussion-tag {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
}

.discussion-tag:hover {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.discussion-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-input);
    border-top: 1px solid var(--border-light);
}

.discussion-stats {
    display: flex;
    gap: var(--space-lg);
}

.discussion-stat {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.discussion-stat i {
    font-size: var(--font-size-base);
}

/* ===================================================================
   7. DISCUSSION LIST (Forum View)
   =================================================================== */

.discussion-list {
    display: flex;
    flex-direction: column;
}

.discussion-list-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-md) var(--space-lg);
    border-bottom: 1px solid var(--border-light);
    transition: background-color var(--transition-fast);
}

.discussion-list-item:hover {
    background-color: var(--bg-hover);
}

.discussion-list-item:last-child {
    border-bottom: none;
}

.discussion-list-votes {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
    min-width: 48px;
}

.discussion-list-vote-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.discussion-list-vote-btn:hover {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.discussion-list-vote-btn.is-voted {
    color: var(--brand-primary);
}

.discussion-list-vote-count {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.discussion-list-content {
    flex: 1;
    min-width: 0;
}

.discussion-list-title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.discussion-list-title:hover {
    color: var(--brand-primary);
}

.discussion-list-excerpt {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.discussion-list-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    font-size: var(--font-size-xs);
    color: var(--text-light);
}

.discussion-list-stats {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
    text-align: center;
    min-width: 64px;
}

.discussion-list-stat-value {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.discussion-list-stat-label {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* Pinned discussion */
.discussion-list-item.is-pinned {
    background-color: var(--brand-primary-alpha);
}

.discussion-list-item.is-pinned .discussion-list-title::before {
    content: '\f08d'; /* FontAwesome thumbtack */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    margin-right: var(--space-xs);
    color: var(--brand-primary);
}

/* Answered/resolved */
.discussion-list-item.is-resolved {
    border-left: 3px solid var(--color-success);
}

.discussion-list-item.is-resolved .discussion-list-title::before {
    content: '\f00c'; /* FontAwesome check */
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    margin-right: var(--space-xs);
    color: var(--color-success);
}

/* ===================================================================
   8. COMMENT STATES
   =================================================================== */

/* Highlighted/best answer */
.comment-highlighted {
    padding: var(--space-md);
    background-color: var(--color-success-bg);
    border: 1px solid var(--color-success);
    border-radius: var(--radius-lg);
    margin-left: calc(-1 * var(--space-md));
    margin-right: calc(-1 * var(--space-md));
}

.comment-highlighted::before {
    content: 'Best Answer';
    display: inline-block;
    padding: var(--space-xs) var(--space-sm);
    margin-bottom: var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-success-text);
    background-color: var(--color-success-bg);
    border-radius: var(--radius-sm);
}

/* Deleted comment */
.comment-deleted {
    opacity: 0.5;
}

.comment-deleted .comment-body {
    font-style: italic;
    color: var(--text-light);
}

/* Pending moderation */
.comment-pending {
    padding: var(--space-md);
    background-color: var(--color-warning-bg);
    border: 1px dashed var(--color-warning);
    border-radius: var(--radius-lg);
    margin-left: calc(-1 * var(--space-md));
    margin-right: calc(-1 * var(--space-md));
}

/* New/unread */
.comment-new::before {
    content: '';
    position: absolute;
    left: calc(-1 * var(--space-md));
    top: 0;
    bottom: 0;
    width: 3px;
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
}

.comment-new {
    position: relative;
}

/* ===================================================================
   9. INLINE COMMENTS (Code Review Style)
   =================================================================== */

.inline-comments {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    margin: var(--space-sm) 0;
}

.inline-comments-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-sm) var(--space-md);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.inline-comments-list {
    padding: var(--space-sm);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.inline-comment {
    display: flex;
    gap: var(--space-sm);
    padding: var(--space-sm);
    background-color: var(--bg-body);
    border-radius: var(--radius-sm);
}

.inline-comment-avatar {
    width: 24px;
    height: 24px;
    border-radius: var(--radius-full);
    flex-shrink: 0;
}

.inline-comment-content {
    flex: 1;
    min-width: 0;
}

.inline-comment-header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-xs);
}

.inline-comment-author {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.inline-comment-time {
    font-size: 10px;
    color: var(--text-light);
}

.inline-comment-body {
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
}

/* ===================================================================
   10. ANNOTATION COMMENTS
   =================================================================== */

.annotation {
    position: relative;
}

.annotation-marker {
    position: absolute;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: transform var(--transition-fast);
    z-index: 10;
}

.annotation-marker:hover {
    transform: scale(1.1);
}

.annotation-popup {
    position: absolute;
    width: 280px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-popover);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: all var(--transition-fast);
}

.annotation-marker:focus + .annotation-popup,
.annotation-popup:hover,
.annotation.is-active .annotation-popup {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.annotation-popup-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-sm) var(--space-md);
    background-color: var(--bg-input);
    border-bottom: 1px solid var(--border-light);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.annotation-popup-close {
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
}

.annotation-popup-close:hover {
    color: var(--text-primary);
}

.annotation-popup-body {
    padding: var(--space-md);
    max-height: 200px;
    overflow-y: auto;
}

/* ===================================================================
   11. COMMENT REACTIONS
   =================================================================== */

.comment-reactions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-top: var(--space-sm);
}

.comment-reaction {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 2px var(--space-sm);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    background-color: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.comment-reaction:hover {
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.comment-reaction.is-reacted {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-color: var(--brand-primary);
}

.comment-reaction-emoji {
    font-size: var(--font-size-sm);
}

.comment-reaction-count {
    font-weight: var(--font-weight-medium);
}

/* Add reaction button */
.comment-add-reaction {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    background-color: var(--bg-input);
    border: 1px dashed var(--border-medium);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.comment-add-reaction:hover {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
    border-style: solid;
}

/* ===================================================================
   12. EMPTY STATE
   =================================================================== */

.comments-empty {
    text-align: center;
    padding: var(--space-2xl) var(--space-lg);
}

.comments-empty-icon {
    font-size: var(--font-size-4xl);
    color: var(--text-light);
    margin-bottom: var(--space-md);
}

.comments-empty-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.comments-empty-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-lg);
}

/* ===================================================================
   13. RESPONSIVE
   =================================================================== */

@media (max-width: 768px) {
    .comment-replies {
        margin-left: var(--space-md);
        padding-left: var(--space-md);
    }

    .comment-reply-form {
        margin-left: 0;
    }

    .discussion-list-item {
        flex-direction: column;
        gap: var(--space-sm);
    }

    .discussion-list-votes {
        flex-direction: row;
        width: auto;
    }

    .discussion-list-stats {
        flex-direction: row;
        gap: var(--space-md);
        width: auto;
    }

    .discussion-footer {
        flex-direction: column;
        gap: var(--space-sm);
    }

    .discussion-stats {
        width: 100%;
        justify-content: space-around;
    }
}

@media (max-width: 576px) {
    .comment-header {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-xs);
    }

    .comment-actions {
        flex-wrap: wrap;
    }

    .comment-form {
        flex-direction: column;
    }

    .comment-form-avatar {
        display: none;
    }

    .discussion-meta {
        flex-direction: column;
        align-items: flex-start;
    }
}


/* ===== components/file-viewer.css ===== */
/* ===================================================================
   File Viewer Component
   Fullscreen modal for previewing submission files (images, PDFs,
   code, Office documents, PSD files).
   =================================================================== */

/* ----- Overlay / Backdrop ----- */
.file-viewer-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    background: var(--bg-overlay-dark);
    display: flex;
    flex-direction: column;
    opacity: 0;
    transition: opacity var(--transition-base);
}

.file-viewer-overlay.visible {
    opacity: 1;
}

/* ----- Header Toolbar ----- */
.file-viewer-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-lg);
    background: var(--bg-scrim);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--border-overlay);
    flex-shrink: 0;
    min-height: 48px;
    color: var(--text-on-overlay);
}

.file-viewer-filename {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.file-viewer-filesize {
    font-size: var(--font-size-xs);
    color: var(--text-on-overlay-subtle);
    white-space: nowrap;
}

.file-viewer-spacer {
    flex: 1;
}

.file-viewer-actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
}

.file-viewer-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-overlay-light);
    border-radius: var(--radius-sm);
    background: var(--bg-overlay-element);
    color: var(--text-on-overlay);
    font-size: var(--font-size-xs);
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
    line-height: 1;
}

.file-viewer-btn:hover {
    background: var(--bg-overlay-hover);
    color: var(--text-on-overlay);
}

.file-viewer-btn-close {
    font-size: var(--font-size-lg);
    padding: var(--space-xs) var(--space-sm);
    border: none;
    background: transparent;
}

.file-viewer-btn-close:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

/* ----- Body / Content Area ----- */
.file-viewer-body {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    min-height: 0;
}

/* ----- Loading State ----- */
.file-viewer-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    color: var(--text-on-overlay-muted);
    font-size: var(--font-size-sm);
}

.file-viewer-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--border-overlay);
    border-top-color: var(--brand-primary);
    border-radius: var(--radius-full);
    animation: file-viewer-spin 0.8s linear infinite;
}

@keyframes file-viewer-spin {
    to { transform: rotate(360deg); }
}

/* ----- Error State ----- */
.file-viewer-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    text-align: center;
    padding: var(--space-xl);
    max-width: 400px;
}

.file-viewer-error-icon {
    font-size: 2.5rem;
    color: var(--color-danger);
}

.file-viewer-error-message {
    color: var(--text-on-overlay-muted);
    font-size: var(--font-size-sm);
}

/* ----- Image Viewer ----- */
.file-viewer-image-container {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    cursor: grab;
}

.file-viewer-image-container.dragging {
    cursor: grabbing;
}

.file-viewer-image-container img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    transition: transform 0.1s ease;
    user-select: none;
    -webkit-user-drag: none;
}

.file-viewer-image-container.zoomed img {
    max-width: none;
    max-height: none;
}

/* Zoom Control Bar */
.file-viewer-zoom-bar {
    position: absolute;
    bottom: var(--space-lg);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    background: var(--bg-overlay-dark);
    backdrop-filter: blur(8px);
    border-radius: var(--radius-full);
    border: 1px solid var(--border-overlay);
}

.file-viewer-zoom-bar .file-viewer-btn {
    border: none;
    background: transparent;
    font-size: var(--font-size-sm);
    padding: var(--space-xs);
    min-width: 28px;
}

.file-viewer-zoom-level {
    font-size: var(--font-size-xs);
    color: var(--text-on-overlay-muted);
    min-width: 40px;
    text-align: center;
    user-select: none;
}

/* ----- PDF Viewer ----- */
.file-viewer-pdf {
    width: 100%;
    height: 100%;
}

/* Content-rendering exception: PDF iframe needs white background */
.file-viewer-pdf iframe {
    width: 100%;
    height: 100%;
    border: none;
    background: #fff;
}

/* ----- Code Viewer ----- */
/* Content-rendering exception: code editor uses its own dark background */
.file-viewer-code {
    width: 100%;
    height: 100%;
    overflow: auto;
    background: #1e1e1e;
}

.file-viewer-code pre {
    margin: 0;
    padding: var(--space-lg);
    min-height: 100%;
}

.file-viewer-code pre code {
    font-family: var(--font-family-mono);
    font-size: 13px;
    line-height: 1.6;
    tab-size: 4;
}

/* ----- Document Viewer (DOCX) ----- */
/* Word pages, drawn by docx-preview inside a sandboxed frame (dcs-file-viewer.js).
   The frame is transparent; the pages carry the document's own colours. */
.file-viewer-docx {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
}

/* Text-only fallback when the page layout cannot be drawn.
   Content-rendering exception: document viewer renders on white paper background */
.file-viewer-document {
    width: 100%;
    height: 100%;
    overflow: auto;
    padding: var(--space-xl);
    display: flex;
    justify-content: center;
}

.file-viewer-document-inner {
    max-width: 800px;
    width: 100%;
    background: #fff;
    color: #1a1a2e;
    padding: var(--space-2xl) var(--space-xl);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-xl);
    min-height: 100%;
}

.file-viewer-document-inner img {
    max-width: 100%;
    height: auto;
}

.file-viewer-document-inner table {
    border-collapse: collapse;
    width: 100%;
    margin: var(--space-md) 0;
}

.file-viewer-document-inner table td,
.file-viewer-document-inner table th {
    border: 1px solid #cbd5e1;
    padding: var(--space-sm) var(--space-md);
}

/* ----- Spreadsheet Viewer (XLSX) ----- */
/* Content-rendering exception: spreadsheet content renders on white like a real spreadsheet */
.file-viewer-spreadsheet {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Styled sheet, painted by ExcelJS inside a sandboxed frame (dcs-file-viewer.js).
   The frame carries the workbook's own cell colours; it fills the space under
   the sheet tabs and scrolls its own content. */
.file-viewer-xlsx {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    border: none;
    background: #fff;
}

.file-viewer-sheet-tabs {
    display: flex;
    gap: 1px;
    padding: 0 var(--space-md);
    background: var(--bg-overlay-medium);
    flex-shrink: 0;
    overflow-x: auto;
}

.file-viewer-sheet-tab {
    padding: var(--space-sm) var(--space-lg);
    background: var(--bg-overlay-element);
    color: var(--text-on-overlay-muted);
    border: none;
    border-top: 2px solid transparent;
    cursor: pointer;
    font-size: var(--font-size-xs);
    white-space: nowrap;
    transition: all var(--transition-fast);
}

.file-viewer-sheet-tab:hover {
    background: var(--bg-overlay-hover);
    color: var(--text-on-overlay);
}

.file-viewer-sheet-tab.active {
    background: var(--bg-overlay-hover);
    color: var(--text-on-overlay);
    border-top-color: var(--brand-primary);
}

.file-viewer-sheet-content {
    flex: 1;
    overflow: auto;
    background: #fff;
}

.file-viewer-sheet-content table {
    border-collapse: collapse;
    font-size: var(--font-size-sm);
    color: #1a1a2e;
    min-width: 100%;
}

.file-viewer-sheet-content th {
    position: sticky;
    top: 0;
    background: #f1f5f9;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-xs);
    text-align: center;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid #e2e8f0;
    min-width: 80px;
    z-index: 1;
}

.file-viewer-sheet-content td {
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid #e2e8f0;
    white-space: nowrap;
    max-width: 300px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.file-viewer-sheet-content tr:hover td {
    background: #f8fafc;
}

/* Row header (first column with row numbers) */
.file-viewer-sheet-content td:first-child {
    background: #f1f5f9;
    font-weight: var(--font-weight-medium);
    text-align: center;
    font-size: var(--font-size-xs);
    color: #64748b;
    min-width: 40px;
    position: sticky;
    left: 0;
}

/* ----- PSD Viewer ----- */
.file-viewer-psd {
    width: 100%;
    height: 100%;
    display: flex;
    overflow: hidden;
}

.file-viewer-psd-preview {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: auto;
    min-width: 0;
}

.file-viewer-psd-preview img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.file-viewer-psd-layers {
    width: 280px;
    flex-shrink: 0;
    background: var(--bg-overlay-medium);
    border-left: 1px solid var(--border-overlay);
    overflow-y: auto;
    padding: var(--space-md);
}

.file-viewer-psd-layers-title {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-on-overlay-subtle);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--space-md);
}

.psd-layer-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--text-on-overlay);
}

.psd-layer-item:hover {
    background: var(--bg-overlay-element);
}

.psd-layer-visibility {
    color: var(--text-on-overlay-subtle);
    font-size: 10px;
    width: 16px;
    text-align: center;
    flex-shrink: 0;
}

.psd-layer-visibility.visible {
    color: var(--brand-primary);
}

.psd-layer-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.psd-layer-opacity {
    color: var(--text-on-overlay-subtle);
    font-size: 10px;
    flex-shrink: 0;
}

.psd-layer-group {
    padding-left: var(--space-md);
}

/* ----- Video / Audio Viewer (Plyr) ----- */
.file-viewer-media {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
    overflow: hidden;
}

.file-viewer-video video,
.file-viewer-video .plyr {
    max-width: 100%;
    max-height: 100%;
    width: auto;
}

.file-viewer-audio .plyr,
.file-viewer-audio audio {
    width: 100%;
    max-width: 560px;
}

/* ----- ZIP Archive Listing ----- */
.file-viewer-zip {
    width: 100%;
    max-width: 720px;
    height: 100%;
    margin: 0 auto;
    overflow: auto;
    padding: var(--space-xl);
    color: var(--text-on-overlay);
}

.file-viewer-zip-heading {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-on-overlay-subtle);
    margin-bottom: var(--space-md);
}

.file-viewer-zip-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.file-viewer-zip-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-xs) var(--space-sm);
    border-bottom: 1px solid var(--border-overlay);
    font-size: var(--font-size-xs);
}

.file-viewer-zip-path {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-family-mono);
}

.file-viewer-zip-size {
    flex-shrink: 0;
    white-space: nowrap;
    color: var(--text-on-overlay-subtle);
}

/* ----- Unsupported File / Info Card ----- */
.file-viewer-unsupported {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
    text-align: center;
    padding: var(--space-2xl);
    max-width: 360px;
}

.file-viewer-unsupported-icon {
    width: 72px;
    height: 72px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-overlay-element);
    border-radius: var(--radius-lg);
    font-size: 2rem;
    color: var(--text-on-overlay-subtle);
}

.file-viewer-unsupported-name {
    font-weight: var(--font-weight-semibold);
    color: var(--text-on-overlay);
    word-break: break-all;
}

.file-viewer-unsupported-meta {
    font-size: var(--font-size-sm);
    color: var(--text-on-overlay-subtle);
}

.file-viewer-unsupported .file-viewer-btn {
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-sm);
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border-color: var(--brand-primary);
    font-weight: var(--font-weight-medium);
}

.file-viewer-unsupported .file-viewer-btn:hover {
    background: var(--brand-primary-light);
}

/* ----- Navigation Arrows (Multi-file) ----- */
.file-viewer-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-overlay-medium);
    border: 1px solid var(--border-overlay);
    border-radius: var(--radius-full);
    color: var(--text-on-overlay);
    font-size: var(--font-size-lg);
    cursor: pointer;
    transition: all var(--transition-fast);
    z-index: 1;
}

.file-viewer-nav:hover {
    background: var(--bg-overlay-dark);
    color: var(--text-on-overlay);
}

.file-viewer-nav-prev {
    left: var(--space-lg);
}

.file-viewer-nav-next {
    right: var(--space-lg);
}

/* ----- Size Warning Banner ----- */
.file-viewer-warning {
    padding: var(--space-xs) var(--space-lg);
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    font-size: var(--font-size-xs);
    text-align: center;
    flex-shrink: 0;
}

/* ----- "View file" Button (used on grade.php submission card) ----- */
.file-view-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
    border: 1px solid var(--brand-primary);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    transition: all var(--transition-fast);
    text-decoration: none;
}

.file-view-btn:hover {
    background: var(--brand-primary-alpha-strong);
}

/* ----- Responsive ----- */
@media (max-width: 640px) {
    .file-viewer-header {
        padding: var(--space-sm);
        gap: var(--space-sm);
    }

    .file-viewer-psd-layers {
        display: none;
    }

    .file-viewer-zoom-bar {
        bottom: var(--space-md);
    }

    .file-viewer-nav {
        width: 36px;
        height: 36px;
    }

    .file-viewer-nav-prev {
        left: var(--space-sm);
    }

    .file-viewer-nav-next {
        right: var(--space-sm);
    }
}


/* ===== components/icon-picker.css ===== */
/* ===================================================================
   Icon Picker Component
   Dropdown/popover for selecting FontAwesome icons.
   =================================================================== */

/* Trigger Button */
.icon-picker-trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    background: var(--bg-input);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    cursor: pointer;
    font-size: var(--font-size-sm);
    transition: border-color var(--transition-fast), background-color var(--transition-fast);
    min-height: 38px;
}

.icon-picker-trigger:hover {
    border-color: var(--brand-primary);
    background: var(--bg-hover);
}

.icon-picker-trigger .icon-preview {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: var(--text-primary);
}

.icon-picker-trigger .icon-preview.empty {
    color: var(--text-muted);
}

.icon-picker-trigger .icon-picker-label {
    color: var(--text-secondary);
}

.icon-picker-trigger .icon-picker-caret {
    margin-left: var(--space-xs);
    font-size: 0.65rem;
    color: var(--text-muted);
}

/* Dropdown Panel */
.icon-picker-dropdown {
    position: fixed;
    z-index: 9999;
    width: 360px;
    max-height: 420px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    display: none;
    flex-direction: column;
    overflow: hidden;
}

.icon-picker-dropdown.open {
    display: flex;
}

/* Search Header */
.icon-picker-search {
    padding: var(--space-sm);
    border-bottom: 1px solid var(--border-light);
    display: flex;
    gap: var(--space-xs);
}

.icon-picker-search input {
    flex: 1;
    padding: var(--space-xs) var(--space-sm);
    background: var(--bg-input);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    color: var(--input-text);
    font-size: var(--font-size-sm);
    outline: none;
}

.icon-picker-search input::placeholder {
    color: var(--input-placeholder);
}

.icon-picker-search input:focus {
    border-color: var(--brand-primary);
}

.icon-picker-clear {
    padding: var(--space-xs) var(--space-sm);
    background: none;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--font-size-xs);
    white-space: nowrap;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.icon-picker-clear:hover {
    color: var(--color-danger-text);
    border-color: var(--color-danger-text);
}

/* Icon Grid Area */
.icon-picker-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-sm);
}

.icon-picker-category {
    margin-bottom: var(--space-sm);
}

.icon-picker-category-name {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: var(--space-xs) 0;
    margin-bottom: var(--space-xs);
}

.icon-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, 40px);
    gap: var(--space-xs);
}

.icon-picker-item {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--text-secondary);
    font-size: 1.1rem;
    transition: background-color var(--transition-fast), color var(--transition-fast);
    border: 1px solid transparent;
}

.icon-picker-item:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.icon-picker-item.selected {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
    border-color: var(--brand-primary);
}

/* No results */
.icon-picker-no-results {
    text-align: center;
    padding: var(--space-lg);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}


/* ===== components/composer-review.css ===== */
/* ===================================================================
   3D Composer — Teacher Review Page
   =================================================================== */

.review-container {
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    height: calc(100vh - 60px);
}

.review-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--space-md);
    flex-shrink: 0;
}

.review-header h1 {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.review-header h1 i {
    color: var(--brand-primary);
}

.review-meta {
    display: flex;
    gap: var(--space-md);
    align-items: center;
}

.review-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    background: var(--color-info-bg);
    color: var(--color-info-text);
    padding: 0.375rem 0.875rem;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.review-body {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: var(--space-md);
    min-height: 0;
}

.review-viewport {
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--border-light);
    min-height: 0;
}

.review-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    overflow-y: auto;
}

.review-card {
    background: var(--card-bg);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
}

.review-card h3 {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    margin: 0 0 var(--space-sm) 0;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Legacy single screenshot (backward compat) */
.review-screenshot {
    width: 100%;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-light);
}

/* Render gallery */
.review-render-gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-xs);
}

.review-render-thumb {
    display: block;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-light);
    overflow: hidden;
    aspect-ratio: 16 / 9;
    transition: border-color var(--transition-fast);
}

.review-render-thumb:hover {
    border-color: var(--brand-primary);
}

.review-render-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.review-detail {
    display: flex;
    justify-content: space-between;
    padding: 0.25rem 0;
    font-size: var(--font-size-sm);
}

.review-detail dt {
    color: var(--text-muted);
}

.review-detail dd {
    color: var(--text-primary);
    font-weight: 500;
    margin: 0;
}

.no-scene-msg {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--text-muted);
    font-size: var(--font-size-lg);
}


/* ===== components/translation-badge.css ===== */
/* ===================================================================
   Translation Badge
   Small inline indicator showing content is machine-translated.
   =================================================================== */

.translation-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
    color: var(--text-muted);
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-sm);
    background: var(--bg-elevated);
    cursor: pointer;
}

.translation-badge i {
    font-size: 0.625rem;
}


/* ===== components/step-bookends.css ===== */
/* Step Bookends modal — three sections at Start, two at Submit.
   Tokens-only per lms-ui-implementation rules. */

.bookend-section {
    padding: var(--space-md) 0;
    border-bottom: 1px solid var(--border-subtle);
}
.bookend-section:last-child { border-bottom: none; }

.bookend-section-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}
.bookend-section-hint {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin-bottom: var(--space-sm);
}

/* Implementation intention: two short inputs styled as a sentence. */
.bookend-intention-row {
    display: flex;
    gap: var(--space-sm);
    align-items: center;
    flex-wrap: wrap;
}
.bookend-intention-row .bookend-keyword {
    color: var(--text-secondary);
    font-weight: 500;
}
.bookend-intention-row input {
    flex: 1 1 12rem;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    padding: var(--space-xs) var(--space-sm);
}

/* Time estimate slider */
.bookend-estimate-row {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}
.bookend-estimate-row input[type="range"] { flex: 1; }
.bookend-estimate-value {
    min-width: 4rem;
    text-align: right;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

/* Confidence pips — 5 clickable circles */
.bookend-confidence-pips {
    display: flex;
    gap: var(--space-sm);
    justify-content: space-between;
    max-width: 24rem;
}
.bookend-confidence-pip {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    border: 2px solid var(--border-default);
    background: var(--bg-elevated);
    color: var(--text-primary);
    font-weight: 600;
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease;
}
.bookend-confidence-pip:hover {
    border-color: var(--brand-primary);
}
.bookend-confidence-pip.is-selected {
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border-color: var(--brand-primary);
}
.bookend-confidence-labels {
    display: flex;
    justify-content: space-between;
    max-width: 24rem;
    margin-top: var(--space-xs);
    color: var(--text-muted);
    font-size: 0.75rem;
}

/* Reflection textarea */
.bookend-reflection textarea {
    width: 100%;
    min-height: 5rem;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    padding: var(--space-sm);
    font-family: inherit;
    resize: vertical;
}
.bookend-reflection-counter {
    text-align: right;
    color: var(--text-muted);
    font-size: 0.75rem;
}

/* Skip link in modal footer */
.bookend-skip {
    color: var(--text-muted);
    background: transparent;
    border: none;
    text-decoration: underline;
    cursor: pointer;
    font-size: 0.875rem;
}
.bookend-skip:hover { color: var(--text-primary); }

/* Content quality survey field (rides the submit modal — migration 127) */
/* The comment question sits above the input as its own line — it used to be
   the input's placeholder, where it was cut off at narrow widths. */
.bookend-comment-hint {
    margin-top: var(--space-md);
    margin-bottom: 0;
}

.bookend-content-comment {
    width: 100%;
    margin-top: var(--space-sm);
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
}

.bookend-content-comment::placeholder {
    color: var(--input-placeholder);
}


/* ===== components/documentchecker-wizard.css ===== */
/* DocumentChecker Wizard — tokens only, dual-theme safe */

.dc-wizard-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    min-height: 420px;
}

.dc-wizard-steps {
    display: flex;
    justify-content: space-between;
    gap: var(--space-xs);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-subtle);
}

.dc-wizard-step {
    flex: 1;
    text-align: center;
    color: var(--text-muted);
    font-size: var(--text-sm);
    padding: var(--space-xs);
}

.dc-wizard-step.is-active {
    color: var(--text-primary);
    font-weight: 600;
    border-bottom: 2px solid var(--brand-primary);
}

.dc-wizard-step.is-done {
    color: var(--color-success-text);
}

.dc-wizard-pane {
    display: none;
}

.dc-wizard-pane.is-active {
    display: block;
}

.dc-upload-dropzone {
    padding: var(--space-lg);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    border: 2px dashed var(--border-subtle);
    border-radius: var(--radius-md);
    text-align: center;
    cursor: pointer;
}

.dc-upload-dropzone.is-dragover {
    border-color: var(--brand-primary);
    background: var(--bg-hover);
}

.dc-property-tree {
    background: var(--bg-surface);
    color: var(--text-primary);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    max-height: 480px;
    overflow-y: auto;
}

.dc-property-group {
    margin-bottom: var(--space-md);
}

.dc-property-group-title {
    font-weight: 600;
    margin-bottom: var(--space-xs);
    color: var(--text-primary);
}

.dc-property-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
}

.dc-property-item:hover {
    background: var(--bg-hover);
}

.dc-property-item input[type="checkbox"] {
    margin-top: 0.25rem;
}

.dc-property-label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.dc-property-preview {
    font-size: var(--text-sm);
    color: var(--text-muted);
    font-family: var(--font-mono);
}

.dc-config-row {
    display: grid;
    grid-template-columns: 1.5fr 1fr 0.8fr 2fr;
    gap: var(--space-sm);
    align-items: center;
    padding: var(--space-sm);
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text-primary);
}

.dc-config-row:last-child { border-bottom: none; }

.dc-preview-results {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.dc-preview-result {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--space-sm);
    align-items: center;
    padding: var(--space-sm);
    border-radius: var(--radius-sm);
}

.dc-preview-result.is-pass {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.dc-preview-result.is-fail {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.dc-preview-aggregate {
    padding: var(--space-md);
    background: var(--bg-elevated);
    color: var(--text-primary);
    border-radius: var(--radius-md);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: var(--text-lg);
}


/* ===== components/verification-upload.css ===== */
/* Verification Upload Wizard — 4-step modal UI */

.verification-upload-entry {
    display: flex;
    gap: var(--space-sm);
    align-items: center;
    margin-top: var(--space-md);
    margin-bottom: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-surface);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
}

.verification-upload-entry .form-hint {
    color: var(--text-secondary);
}

.verification-upload-wizard {
    padding: var(--space-md);
    color: var(--text-primary);
}

.verification-upload-wizard .vuw-step {
    display: block;
}

.verification-upload-wizard .vuw-step[hidden] {
    display: none;
}

.verification-upload-wizard h3 {
    color: var(--text-primary);
    margin-bottom: var(--space-md);
    font-size: var(--font-size-lg);
}

.verification-upload-wizard label {
    display: block;
    margin-bottom: var(--space-md);
    color: var(--text-primary);
}

.verification-upload-wizard input[type="file"] {
    display: block;
    margin-top: var(--space-xs);
    color: var(--text-primary);
    background: var(--bg-input);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: var(--space-xs) var(--space-sm);
    width: 100%;
    font-size: var(--font-size-sm);
}

.verification-upload-wizard .vuw-actions {
    display: flex;
    gap: var(--space-sm);
    justify-content: flex-end;
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-color);
}

.verification-upload-wizard .alert ul {
    margin: var(--space-xs) 0 0 var(--space-lg);
    color: var(--color-danger-text);
}

.verification-upload-wizard .alert-success ul {
    color: var(--color-success-text);
}

.verification-upload-wizard pre.code-block {
    max-height: 400px;
    overflow: auto;
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: var(--space-md);
    font-size: var(--font-size-sm);
    font-family: var(--font-family-mono, monospace);
}


/* ===== components/interactive-video.css ===== */
/* ===================================================================
   Interactive Video — shared component styles

   Used by:
   - src/web/digitalcs.ca/public_html/php/activities/interactive_video.php (player, dark theme)
   - src/web/admin.digitalcs.ca/public_html/php/lms_courses/edit_interactive_video.php (editor, light theme)

   Selectors use feature-scoped prefixes (.iv-*, .ivq-*, plus Plyr
   overrides) so cross-surface conflicts don't occur. Player runs only
   on digitalcs.ca; editor runs only on admin.digitalcs.ca; tokens
   resolve per-theme at runtime.

   See docs/plans/archive/2026-05-26-interactive-video-ui-polish-{design,plan}.md
   =================================================================== */

/* ===================================================================
   Player styles (interactive_video.php)
   =================================================================== */

/* ── Shared styles ───────────────────────────────────────────────────────── */
.iv-page {
    max-width: 1000px;
    margin: 0 auto;
}

.iv-page--playlist {
    max-width: 1400px;
}

.iv-header {
    margin-bottom: var(--space-lg);
}

.iv-page .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-md);
    transition: color var(--transition-fast);
}

.iv-page .back-link:hover {
    color: var(--brand-primary);
}

.iv-title-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-lg);
    flex-wrap: wrap;
}

.iv-header h1 {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    margin: 0;
    flex: 1;
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.iv-header h1 i {
    color: var(--activity-interactive-video, var(--brand-primary));
}

.iv-meta {
    display: flex;
    align-items: center;
    gap: var(--space-lg);
    margin-top: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.iv-meta-item {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.iv-meta-item.completed {
    color: var(--color-success);
}

/* ── Video container ─────────────────────────────────────────────────────── */
.iv-page .video-container {
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    overflow: hidden;
    margin-bottom: var(--space-lg);
}

.iv-page .video-wrapper {
    position: relative;
    width: 100%;
    background: var(--game-canvas-bg); /* was #000 — near-black backdrop for video letterboxing; identical in both themes */
}

/* Full screen takes this whole wrapper (Plyr fullscreen.container), so the
   question overlay beside the player shows there too. Plyr's own
   .plyr:fullscreen sizing no longer matches, so these rules repeat it. The
   fallback class is Plyr's fixed-position stand-in where the Fullscreen API
   is missing (iPhone). */
.iv-page .video-wrapper:fullscreen #playerContainer,
.iv-page .video-wrapper:fullscreen .plyr,
.iv-page .video-wrapper:fullscreen .plyr video,
.iv-page .video-wrapper.plyr--fullscreen-fallback #playerContainer,
.iv-page .video-wrapper.plyr--fullscreen-fallback .plyr {
    height: 100%;
}

.iv-page .video-wrapper:fullscreen .plyr--hide-controls,
.iv-page .video-wrapper.plyr--fullscreen-fallback .plyr--hide-controls {
    cursor: none;
}

@media (min-width: 1024px) {
    .iv-page .video-wrapper:fullscreen .plyr__captions {
        font-size: var(--plyr-font-size-xlarge, 21px);
    }
}

.plyr {
    --plyr-color-main: var(--brand-primary);
}

.plyr--video {
    border-radius: 0;
}

/* ── Question dots on the progress bar (renderQuestionMarkers) ───────────── */
.iv-page .ivq-marker {
    position: absolute;
    top: 50%;
    width: 11px;
    height: 11px;
    border: 2px solid var(--bg-body);
    border-radius: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 3; /* above the seek input (z-index 2), like Plyr's own markers */
}

.iv-page .ivq-marker--open {
    background: var(--color-warning);
}

.iv-page .ivq-marker--done {
    background: var(--color-success);
}

.iv-page .ivq-marker--note {
    background: var(--color-info);
}

/* ── Question overlay ────────────────────────────────────────────────────── */
.iv-page .question-overlay {
    position: absolute;
    inset: 0;
    background: var(--bg-overlay-dark); /* was rgba(0, 0, 0, 0.85) — closest token is 0.8 opacity */
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.iv-page .question-overlay.active {
    opacity: 1;
    pointer-events: all;
}

.iv-page .question-card {
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    max-width: 600px;
    width: 90%;
    max-height: 80%;
    overflow-y: auto;
}

.iv-page .question-card h3 {
    margin: 0 0 var(--space-lg) 0;
    color: var(--text-primary);
    font-size: var(--font-size-lg);
}

/* Note card (information-only pause, migration 189). The body is
   .activity-content, so text and Prism code blocks use the Page styles;
   these rules only fit them inside the card. Title and Continue stay put;
   only the body scrolls, so Continue is never hidden below the fold. */
.iv-page .note-card {
    display: flex;
    flex-direction: column;
    max-width: 720px;
    max-height: 90%;
    overflow: hidden;
}

.iv-page .note-card h3,
.iv-page .note-card .btn-continue {
    flex-shrink: 0;
}

.iv-page .note-card h3 i {
    color: var(--color-info-text);
    margin-right: var(--space-xs);
}

.iv-page .note-card .note-body {
    color: var(--text-primary);
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.iv-page .note-card .note-body pre[class*="language-"] {
    margin: 0 0 var(--space-md) 0;
}

.iv-page .note-card .note-body > :last-child {
    margin-bottom: 0;
}

/* MC choices */
.mc-choice {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
    color: var(--text-primary);
}

.mc-choice:hover {
    background: var(--bg-hover);
    border-color: var(--brand-primary);
}

.mc-choice input[type="radio"]:checked + span {
    color: var(--brand-primary);
    font-weight: var(--font-weight-semibold);
}

/* T/F buttons */
.tf-buttons {
    display: flex;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.tf-btn {
    flex: 1;
    padding: var(--space-lg);
    border: 2px solid var(--border-light);
    border-radius: var(--radius-lg);
    background: transparent;
    color: var(--text-primary);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.tf-btn:hover {
    border-color: var(--brand-primary);
}

.tf-btn.selected {
    border-color: var(--brand-primary);
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

/* SA input */
.sa-input {
    width: 100%;
    padding: var(--space-md);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    background: var(--bg-input);
    color: var(--input-text);
    font-size: var(--font-size-base);
    margin-bottom: var(--space-lg);
}

/* Submit button */
.btn-submit-answer {
    width: 100%;
    padding: var(--space-md);
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    margin-top: var(--space-md);
    transition: background var(--transition-fast);
}

.btn-submit-answer:hover {
    background: var(--brand-primary-dark);
}

.btn-submit-answer:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Feedback */
.iv-page .feedback {
    padding: var(--space-md);
    border-radius: var(--radius-md);
    margin-top: var(--space-md);
    font-weight: var(--font-weight-medium);
}

.iv-page .feedback.correct {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.iv-page .feedback.incorrect {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.iv-page .feedback.info {
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

/* Continue button */
.btn-continue {
    width: 100%;
    padding: var(--space-md);
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border: none;
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    margin-top: var(--space-md);
    transition: background var(--transition-fast);
}

.btn-continue:hover {
    background: var(--brand-primary-dark);
}

/* ── Question progress indicator ─────────────────────────────────────────── */
.iv-page .question-progress {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
}

.iv-page .question-progress i {
    color: var(--brand-primary);
}

/* ── Attribution ("Video by CrashCourse · YouTube") ──────────────────────── */
.iv-page .video-attribution {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
}

.iv-page .video-attribution-single {
    padding: var(--space-md) var(--space-lg);
    margin-bottom: 0;
}

.iv-page .video-attribution a {
    color: inherit;
    text-decoration: underline;
}

.iv-page .video-attribution a:hover,
.iv-page .video-attribution a:focus-visible {
    color: var(--text-primary);
}

/* ── Description ─────────────────────────────────────────────────────────── */
.iv-page .video-description {
    padding: var(--space-lg);
    border-top: 1px solid var(--border-color);
}

.iv-page .video-description h3 {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--space-sm) 0;
}

.iv-page .video-description-content {
    color: var(--text-secondary);
    line-height: 1.6;
}

.iv-page .video-description-content p:last-child {
    margin-bottom: 0;
}

/* ── Completion section ──────────────────────────────────────────────────── */
.iv-page .completion-section {
    text-align: center;
    padding: var(--space-xl);
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    margin-top: var(--space-lg);
}

.iv-page .completion-section.completed {
    background: var(--color-success-bg);
    border-color: var(--color-success);
}

.iv-page .completion-icon {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    color: var(--color-success);
}

.iv-page .completion-section h3 {
    margin: 0 0 var(--space-sm) 0;
    font-size: var(--font-size-lg);
    color: var(--text-primary);
}

.iv-page .completion-section p {
    margin: 0 0 var(--space-lg) 0;
    color: var(--text-muted);
}

/* NOTE: These button rules are scoped under .iv-page to preserve the
   pre-refactor implicit page-scope. They were originally inside the
   inline <style> block in interactive_video.php and only applied to
   the IV page; scoping under .iv-page maintains that boundary now
   that the rules live in the global dcs.css bundle. Future cleanup
   could move IV buttons to use the shared components/buttons.css
   patterns directly — out of scope for this refactor ship. */
/* ── Buttons ─────────────────────────────────────────────────────────────── */
.iv-page .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-xl);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-base);
}

.iv-page .btn-primary {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.iv-page .btn-primary:hover {
    background: var(--brand-primary-dark);
}

.iv-page .btn-secondary {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
}

.iv-page .btn-secondary:hover {
    background: var(--bg-hover);
}

.iv-page .btn-success {
    background: var(--color-success);
    color: var(--text-on-success);
}

.iv-page .btn-success:hover {
    /* TODO: opacity hack carryover from original inline block.
       lms-ui-implementation.md bans opacity-as-substitute-for-tokens;
       a future cleanup should swap to a darker --color-success token
       or a filter-based approach. */
    opacity: 0.9;
}

.iv-page .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ── Empty state ─────────────────────────────────────────────────────────── */
.iv-page .empty-video {
    padding: var(--space-2xl);
    text-align: center;
    color: var(--text-muted);
}

.iv-page .empty-video i {
    font-size: 4rem;
    margin-bottom: var(--space-lg);
    opacity: 0.5;
}

.iv-page .empty-video p {
    margin: 0;
    font-size: var(--font-size-lg);
}

/* ── Playlist layout ─────────────────────────────────────────────────────── */
/* Selectors below only match when interactive_video.php renders playlist mode;
   they're safe to ship unconditionally. */
.iv-page .playlist-layout {
    display: grid;
    grid-template-columns: 1fr 350px;
    gap: var(--space-xl);
}

@media (max-width: 1024px) {
    .playlist-layout {
        grid-template-columns: 1fr;
    }
}

.iv-page .playlist-progress-summary {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.iv-page .progress-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.iv-page .progress-bar-container {
    width: 200px;
    height: 8px;
    background: var(--bg-tertiary);
    border-radius: 4px;
    overflow: hidden;
}

.iv-page .progress-bar-fill {
    height: 100%;
    background: var(--brand-primary);
    border-radius: 4px;
    transition: width 0.3s ease;
}

.iv-page .current-video-info {
    padding: var(--space-lg);
    border-top: 1px solid var(--border-color);
}

.iv-page .current-video-number {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--space-xs);
}

.iv-page .current-video-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.iv-page .video-nav-buttons {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.iv-page .video-nav-buttons .btn {
    flex: 1;
}

/* Playlist Sidebar */
.iv-page .playlist-sidebar {
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    overflow: hidden;
}

/* Scoped under .iv-page: .sidebar-header collides with the global rule
   in components/navigation.css; .sidebar-title / .sidebar-count are
   generic enough to risk future collisions. Pre-refactor these were
   inline-scoped to the IV page; preserve that boundary. */
.iv-page .sidebar-header {
    padding: var(--space-md) var(--space-lg);
    border-bottom: 1px solid var(--border-color);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.iv-page .sidebar-title {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.iv-page .sidebar-count {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.iv-page .playlist-items {
    max-height: 500px;
    overflow-y: auto;
}

.iv-page .playlist-section-header {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--bg-muted);
    border-bottom: 1px solid var(--border-subtle);
    position: sticky;
    top: 0;
    z-index: 1;
}

.iv-page .playlist-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-subtle);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.iv-page .playlist-item:hover {
    background: var(--bg-hover);
}

.iv-page .playlist-item:last-child {
    border-bottom: none;
}

.iv-page .playlist-item.current {
    background: var(--brand-primary-alpha);
    border-left: 3px solid var(--brand-primary);
}

.iv-page .playlist-item.completed .item-status {
    color: var(--color-success);
}

.iv-page .playlist-item.locked {
    opacity: 0.6;
    cursor: not-allowed;
}

.iv-page .item-status {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    flex-shrink: 0;
}

.iv-page .item-status.not-started {
    background: var(--bg-tertiary);
    color: var(--text-muted);
}

.iv-page .item-status.in-progress {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

.iv-page .item-status.completed {
    background: var(--color-success-bg);
    color: var(--color-success);
}

.iv-page .item-status.current {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.iv-page .item-status.locked {
    background: var(--bg-tertiary);
    color: var(--text-muted);
}

.iv-page .item-thumb {
    width: 64px;
    height: 36px;
    background: var(--bg-tertiary);
    border-radius: var(--radius-xs);
    overflow: hidden;
    flex-shrink: 0;
}

.iv-page .item-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.iv-page .item-info {
    flex: 1;
    min-width: 0;
}

.iv-page .item-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.iv-page .item-duration {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* ===================================================================
   Editor styles (edit_interactive_video.php) — Task B
   ===================================================================
   The editor runs on admin.digitalcs.ca (light theme only). Generic
   class names that the inline <style> block historically used
   (.activity-editor, .editor-header, .form-section, .mode-option,
   .source-option, .library-*, .playlist-*, .setting-row, .toggle-*,
   etc.) are also used by other editors (edit_page.php, edit_task.php,
   edit_question_set.php, …) each with their own inline copies. To
   prevent the global dcs.css bundle from leaking IV-specific
   tweaks into those editors, every editor-side rule is scoped under
   `.iv-editor` — a class added to the page wrapper alongside
   .activity-editor in edit_interactive_video.php.

   `.ivq-*` selectors (interactive video questions) are already
   feature-scoped and remain unprefixed.

   --iv-accent maps to the activity-type accent color
   (was $typeColor = #ef4444 PHP-interpolated in the inline block;
   identical to --color-danger / --activity-video). Local property so
   future re-theming is one-line.
   =================================================================== */

.iv-editor {
    /* Local accent — was $typeColor = '#ef4444' interpolated by PHP */
    --iv-accent: var(--color-danger);
    /* ~12.5% alpha tint (was #ef444420) and ~6% alpha tint (was #ef444410) */
    --iv-accent-tint-strong: color-mix(in srgb, var(--iv-accent) 13%, transparent);
    --iv-accent-tint-soft: color-mix(in srgb, var(--iv-accent) 6%, transparent);
}

/* True/False answer radios rendered by the question-form JS template.
   Previously the JS interpolated `accent-color: ${typeColor}` from a
   PHP→JS bridge; now driven by the local --iv-accent custom property. */
.iv-editor input[type="radio"][name="ivqTFAnswer"] {
    accent-color: var(--iv-accent);
}

/* Editor Layout */
.iv-editor.activity-editor {
    max-width: 1200px;
    margin: 0 auto;
}

.iv-editor .editor-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.iv-editor .editor-icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    font-size: 1.75rem;
    background-color: var(--iv-accent-tint-strong); /* was #ef444420 — closest */
    color: var(--iv-accent);
}

.iv-editor .editor-title-section {
    flex: 1;
}

.iv-editor .editor-title-section h1 {
    font-size: var(--font-size-xl);
    margin: 0 0 var(--space-xs) 0;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.iv-editor .editor-title-input {
    flex: 1;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    border: 1px solid transparent;
    background: transparent;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    min-width: 200px;
}

.iv-editor .editor-title-input:hover {
    border-color: var(--border-color);
    background: var(--bg-surface);
}

.iv-editor .editor-title-input:focus {
    outline: none;
    border-color: var(--brand-primary);
    background: var(--bg-surface);
}

.iv-editor .editor-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.iv-editor .editor-meta a {
    color: var(--text-secondary);
    text-decoration: none;
}

.iv-editor .editor-meta a:hover {
    color: var(--brand-primary);
}

.iv-editor .editor-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

/* Form Sections */
.iv-editor .form-section {
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    margin-bottom: var(--space-lg);
}

.iv-editor .form-section-title {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-md);
}

.iv-editor .form-section-title i {
    color: var(--iv-accent);
}

/* Mode Toggle — large clickable cards */
.iv-editor .mode-toggle {
    display: flex;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.iv-editor .mode-option {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-lg);
    border: 2px solid var(--border-light);
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: all 0.2s ease;
    background: var(--bg-surface);
}

.iv-editor .mode-option:hover {
    border-color: var(--brand-primary);
    background: var(--bg-hover);
}

.iv-editor .mode-option.selected {
    border-color: var(--iv-accent);
    background: var(--iv-accent-tint-soft); /* was #ef444410 — closest */
}

.iv-editor .mode-option i {
    font-size: 2.5rem;
    color: var(--text-primary);
}

.iv-editor .mode-option.selected i {
    color: var(--iv-accent);
}

.iv-editor .mode-option-label {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.iv-editor .mode-option-desc {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-align: center;
}

.iv-editor .mode-option input[type="radio"] {
    display: none;
}

/* Mode content panels */
.iv-editor .mode-panel {
    display: none;
}

.iv-editor .mode-panel.active {
    display: block;
}

/* Source Toggle (within single video mode) */
.iv-editor .source-toggle {
    display: flex;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.iv-editor .source-option {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-lg);
    border: 2px solid var(--border-light);
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: all 0.2s ease;
    background: var(--bg-surface);
}

.iv-editor .source-option:hover {
    border-color: var(--brand-primary);
    background: var(--bg-hover);
}

.iv-editor .source-option.selected {
    border-color: var(--iv-accent);
    background: var(--iv-accent-tint-soft); /* was #ef444410 — closest */
}

.iv-editor .source-option i {
    font-size: 2.5rem;
    color: var(--text-primary);
}

.iv-editor .source-option.selected i {
    color: var(--iv-accent);
}

.iv-editor .source-option-label {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.iv-editor .source-option-desc {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-align: center;
}

.iv-editor .source-option input[type="radio"] {
    display: none;
}

/* Source Fields */
.iv-editor .source-fields {
    display: none;
}

.iv-editor .source-fields.active {
    display: block;
}

/* YouTube URL parsing */
.iv-editor .youtube-parsed {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-muted);
    border-radius: var(--radius-md);
    margin-top: var(--space-md);
}

.iv-editor .youtube-parsed.hidden {
    display: none;
}

.iv-editor .youtube-parsed img {
    width: 120px;
    height: auto;
    border-radius: var(--radius-sm);
}

.iv-editor .youtube-parsed-info {
    flex: 1;
}

.iv-editor .youtube-parsed-id {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    font-family: monospace;
}

.iv-editor .youtube-parsed-status {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--color-success);
    font-weight: var(--font-weight-medium);
}

/* Video Preview */
.iv-editor .video-preview {
    margin-top: var(--space-lg);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--game-canvas-bg); /* was #000 — near-black backdrop for video letterboxing */
}

.iv-editor .video-preview.hidden {
    display: none;
}

/* Library Video Selector */
.iv-editor .library-filter-info {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md);
    background: var(--bg-hover);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-lg);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.iv-editor .library-filter-info i {
    color: var(--brand-primary);
}

.iv-editor .library-empty {
    text-align: center;
    padding: var(--space-2xl);
    color: var(--text-muted);
}

.iv-editor .library-empty i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

.iv-editor .library-empty h4 {
    margin-bottom: var(--space-sm);
    color: var(--text-secondary);
}

.iv-editor .library-empty p {
    margin-bottom: var(--space-lg);
}

.iv-editor .library-video-grid {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    max-height: 400px;
    overflow-y: auto;
    padding-right: var(--space-sm);
}

.iv-editor .library-module-header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--bg-hover);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    margin-top: var(--space-sm);
    position: sticky;
    top: 0;
    z-index: 1;
}

.iv-editor .library-module-header:first-child {
    margin-top: 0;
}

.iv-editor .library-module-header i {
    color: var(--brand-primary);
}

.iv-editor .library-video-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm);
    border: 2px solid var(--border-light);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all 0.15s;
    background: var(--bg-surface);
}

.iv-editor .library-video-item:hover {
    border-color: var(--brand-primary);
    background: var(--bg-hover);
}

.iv-editor .library-video-item.selected {
    border-color: var(--iv-accent);
    background: var(--iv-accent-tint-soft); /* was #ef444410 — closest */
}

.iv-editor .library-video-thumb {
    position: relative;
    width: 120px;
    height: 68px;
    background: var(--bg-input);
    border-radius: var(--radius-sm);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.iv-editor .library-video-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.iv-editor .library-video-thumb i {
    font-size: 1.5rem;
    color: var(--text-muted);
}

.iv-editor .library-video-duration {
    position: absolute;
    bottom: 4px;
    right: 4px;
    background: var(--bg-overlay-dark); /* was rgba(0, 0, 0, 0.8) */
    color: var(--text-on-brand); /* was white */
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 0.6875rem;
    font-weight: 500;
}

.iv-editor .library-video-info {
    flex: 1;
    min-width: 0;
}

.iv-editor .library-video-title {
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.iv-editor .library-video-check {
    color: var(--iv-accent);
    font-size: 1.25rem;
    opacity: 0;
    transition: opacity 0.15s;
}

.iv-editor .library-video-item.selected .library-video-check {
    opacity: 1;
}

/* Playlist Selector */
.iv-editor .playlist-selector {
    margin-bottom: var(--space-lg);
}

.iv-editor .playlist-selector select {
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    background: var(--bg-surface);
    color: var(--text-primary);
}

/* Playlist Preview */
.iv-editor .playlist-preview {
    background: var(--bg-muted);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-top: var(--space-md);
}

.iv-editor .playlist-preview.hidden {
    display: none;
}

.iv-editor .playlist-preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--border-light);
}

.iv-editor .playlist-preview-title {
    font-weight: var(--font-weight-semibold);
}

.iv-editor .playlist-preview-count {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.iv-editor .playlist-item-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    max-height: 300px;
    overflow-y: auto;
}

/* Note: .playlist-item also defined under .iv-page (player) above with
   different padding/background; scope under .iv-editor keeps editor's
   version local to the editor surface. */
.iv-editor .playlist-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm);
    background: var(--bg-surface);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.15s;
}

.iv-editor .playlist-item:hover {
    background: var(--bg-hover);
}

.iv-editor .playlist-item.excluded {
    opacity: 0.5;
}

.iv-editor .playlist-item-checkbox {
    width: 20px;
    height: 20px;
    cursor: pointer;
    accent-color: var(--iv-accent);
}

.iv-editor .playlist-item-number {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--iv-accent-tint-strong); /* was #ef444420 — closest */
    color: var(--iv-accent);
    border-radius: 50%;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
}

.iv-editor .playlist-item-thumb {
    width: 60px;
    height: 34px;
    background: var(--bg-tertiary);
    border-radius: var(--radius-xs);
    overflow: hidden;
}

.iv-editor .playlist-item-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.iv-editor .playlist-item-info {
    flex: 1;
    min-width: 0;
}

.iv-editor .playlist-item-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.iv-editor .playlist-item-duration {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* Empty state */
.iv-editor .empty-playlists {
    text-align: center;
    padding: var(--space-2xl);
    color: var(--text-muted);
}

.iv-editor .empty-playlists i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

/* Settings */
.iv-editor .setting-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-md) 0;
    border-bottom: 1px solid var(--border-subtle);
}

.iv-editor .setting-row:last-child {
    border-bottom: none;
}

.iv-editor .setting-row.hidden {
    display: none;
}

.iv-editor .setting-label {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.iv-editor .setting-label strong {
    font-size: var(--font-size-sm);
}

.iv-editor .setting-label small {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

.iv-editor .toggle-switch {
    position: relative;
    width: 44px;
    height: 24px;
}

.iv-editor .toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.iv-editor .toggle-slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background-color: var(--bg-tertiary);
    transition: 0.2s;
    border-radius: 24px;
}

.iv-editor .toggle-slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: var(--text-on-brand); /* was white — small indicator knob */
    transition: 0.2s;
    border-radius: 50%;
}

.iv-editor input:checked + .toggle-slider {
    background-color: var(--iv-accent);
}

.iv-editor input:checked + .toggle-slider:before {
    transform: translateX(20px);
}

.iv-editor .threshold-input {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.iv-editor .threshold-input input {
    width: 60px;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    text-align: center;
    font-size: var(--font-size-sm);
}

.iv-editor .points-input {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.iv-editor .points-input input {
    width: 80px;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    text-align: center;
    font-size: var(--font-size-sm);
}

/* Visibility toggle */
.iv-editor .visibility-toggle {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.iv-editor .visibility-toggle input[type="checkbox"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

/* Info text */
.iv-editor .form-info {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-md);
    background-color: var(--bg-info-subtle);
    border: 1px solid var(--border-info);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    margin-top: var(--space-lg);
}

.iv-editor .form-info i {
    color: var(--color-info);
    margin-top: 2px;
}

/* ── Questions List — .ivq-* selectors are already feature-scoped ───────── */

.ivq-questions-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.ivq-question-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-hover);
    border-radius: var(--radius-md);
    border: 1px solid var(--border-light);
}

.ivq-question-item .ivq-drag-handle {
    cursor: grab;
    color: var(--text-muted);
    opacity: 0;
    transition: opacity var(--transition-fast);
    flex-shrink: 0;
}

.ivq-question-item:hover .ivq-drag-handle {
    opacity: 1;
}

.ivq-question-item.sortable-ghost {
    opacity: 0.4;
    background: var(--brand-primary-alpha);
}

.ivq-question-item.sortable-chosen {
    background: var(--bg-active);
    cursor: grabbing;
}

.ivq-timestamp-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    background: var(--iv-accent-tint-strong, color-mix(in srgb, var(--color-danger) 13%, transparent)); /* was #ef444420 — closest */
    color: var(--iv-accent, var(--color-danger));
    border-radius: var(--radius-sm);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
}

.ivq-type-badge {
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-full);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

.ivq-type-badge.type-multichoice {
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

.ivq-type-badge.type-truefalse {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

.ivq-type-badge.type-shortanswer {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.ivq-type-badge.type-note {
    background: var(--bg-elevated);
    color: var(--text-secondary);
}

.ivq-question-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
}

.ivq-question-points {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    white-space: nowrap;
}

.ivq-question-actions {
    display: flex;
    gap: var(--space-xs);
}

.ivq-question-actions .btn {
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
}

/* Question Form */
.ivq-question-form {
    border: 2px solid var(--iv-accent, var(--color-danger));
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    margin-top: var(--space-md);
    background: var(--bg-surface);
}

.ivq-question-form.hidden { display: none; }

.ivq-form-row {
    margin-bottom: var(--space-md);
}

.ivq-form-row label {
    display: block;
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-xs);
    color: var(--text-primary);
}

.ivq-form-row .form-hint {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-top: var(--space-xs);
}

/* Note body: monospace so ``` code fences line up while typing */
.ivq-note-body {
    font-family: var(--font-family-mono);
    font-variant-ligatures: none;
    font-size: var(--font-size-sm);
}

/* Choice items */
.ivq-choice-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
}

.ivq-choice-item input[type="text"] {
    flex: 1;
}

.ivq-choice-item input[type="radio"],
.ivq-choice-item input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--iv-accent, var(--color-danger));
}

.ivq-answer-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
}

.ivq-answer-item input[type="text"] {
    flex: 1;
}

.ivq-empty-state {
    text-align: center;
    padding: var(--space-xl);
    color: var(--text-muted);
}

.ivq-empty-state i {
    font-size: 2.5rem;
    opacity: 0.4;
    margin-bottom: var(--space-sm);
}

.ivq-form-actions {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-light);
}

.ivq-section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-md);
}

.ivq-save-bar {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-sm);
    margin-top: var(--space-md);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-light);
}


/* ===== components/activity-editors.css ===== */
/* ===================================================================
   Activity Editors — shared component CSS for the structural
   activity editors (HTML element + file).

   Used by:
   - src/web/admin.digitalcs.ca/public_html/php/lms_courses/edit_html_element.php
     (.html-editor — html_section activity)
   - src/web/admin.digitalcs.ca/public_html/php/lms_courses/edit_file.php
     (.file-editor — file activity)

   Each editor has its own wrapper class. Generic class names that
   the original inline <style> blocks used (.activity-editor,
   .editor-header, .editor-icon, .editor-title-section,
   .editor-title-input, .editor-meta, .editor-actions, .form-section,
   .form-section-title, .save-status, .editor-container, .file-info-card,
   .file-icon, .file-details, .file-name, .file-meta, .file-actions,
   .no-file-message, .visibility-toggle, .file-upload-area,
   .description-editor-container, etc.) are also used by other editors
   (edit_page.php, edit_task.php, edit_question_set.php,
   edit_interactive_video.php, …) each with their own inline copies.
   To prevent the global dcs.css bundle from leaking edits across
   editors, every rule below is scoped under its wrapper class.

   Feature-prefixed selectors (#fileInput) and library selectors
   (.tox-tinymce) are left unscoped.

   --html-accent / --file-accent map to the activity-type accent tokens
   in tokens.css (originally interpolated by PHP `$typeColor`).

   Migrated from inline <style> blocks 2026-05-28.
   =================================================================== */

.html-editor {
    /* Local accent — was $typeColor = '#be185d' interpolated by PHP */
    --html-accent: var(--activity-html);
    /* ~12.5% alpha tint (was #be185d20) */
    --html-accent-tint-strong: color-mix(in srgb, var(--html-accent) 13%, transparent);
}

.file-editor {
    /* Local accent — was $typeColor = '#0284c7' interpolated by PHP */
    --file-accent: var(--activity-file);
    /* ~12.5% alpha tint (was #0284c720) */
    --file-accent-tint-strong: color-mix(in srgb, var(--file-accent) 13%, transparent);
}

/* ===================================================================
   Shared editor chrome — identical rules across both editors
   Migrated from:
   - edit_html_element.php lines 64-197
   - edit_file.php lines 83-332
   =================================================================== */

/* Editor Layout — both editors share the same wrapper, only max-width differs */
.html-editor.activity-editor,
.file-editor.activity-editor {
    margin: 0 auto;
}

.html-editor.activity-editor {
    max-width: 1200px;
}

.file-editor.activity-editor {
    max-width: 900px;
}

.html-editor .editor-header,
.file-editor .editor-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

/* Editor icon — accent background+color differ per editor via local custom properties */
.html-editor .editor-icon,
.file-editor .editor-icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    font-size: 1.75rem;
}

.html-editor .editor-icon {
    background-color: var(--html-accent-tint-strong); /* was #be185d20 — closest */
    color: var(--html-accent); /* was #be185d */
}

.file-editor .editor-icon {
    background-color: var(--file-accent-tint-strong); /* was #0284c720 — closest */
    color: var(--file-accent); /* was #0284c7 */
}

.html-editor .editor-title-section,
.file-editor .editor-title-section {
    flex: 1;
}

.html-editor .editor-title-section h1,
.file-editor .editor-title-section h1 {
    font-size: var(--font-size-xl);
    margin: 0 0 var(--space-xs) 0;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.html-editor .editor-title-input,
.file-editor .editor-title-input {
    flex: 1;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    border: 1px solid transparent;
    background: transparent;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    min-width: 200px;
}

.html-editor .editor-title-input:hover,
.file-editor .editor-title-input:hover {
    border-color: var(--border-color);
    background: var(--bg-surface);
}

.html-editor .editor-title-input:focus,
.file-editor .editor-title-input:focus {
    outline: none;
    border-color: var(--brand-primary);
    background: var(--bg-surface);
}

.html-editor .editor-meta,
.file-editor .editor-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.html-editor .editor-meta a,
.file-editor .editor-meta a {
    color: var(--text-secondary);
    text-decoration: none;
}

.html-editor .editor-meta a:hover,
.file-editor .editor-meta a:hover {
    color: var(--brand-primary);
}

/* Editor actions — gap differs per editor (md vs sm) */
.html-editor .editor-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.file-editor .editor-actions {
    display: flex;
    gap: var(--space-sm);
}

/* Form Sections — background differs slightly (--bg-surface vs --bg-card) */
.html-editor .form-section,
.file-editor .form-section {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    margin-bottom: var(--space-lg);
}

.html-editor .form-section {
    background: var(--bg-surface);
}

.file-editor .form-section {
    background: var(--card-bg); /* was var(--bg-card) — undefined token; --card-bg is the canonical alias of --bg-surface */
}

.html-editor .form-section-title,
.file-editor .form-section-title {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-md);
}

/* Section-title icon: HTML editor uses its accent; file editor uses --brand-primary */
.html-editor .form-section-title i {
    color: var(--html-accent); /* was #be185d */
}

.file-editor .form-section-title i {
    color: var(--brand-primary);
}

/* ===================================================================
   HTML Element Editor (.html-editor) — extras
   Migrated from: edit_html_element.php lines 64-197
   =================================================================== */

/* Status indicator */
.html-editor .save-status {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.html-editor .save-status.saving {
    color: var(--color-warning-text); /* was --warning-color — undefined; -text variant is theme-tuned for status-on-surface readability */
}

.html-editor .save-status.saved {
    color: var(--color-success-text);
}

.html-editor .save-status.error {
    color: var(--color-danger-text);
}

/* Editor container */
.html-editor .editor-container {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* ===================================================================
   File Activity Editor (.file-editor) — extras
   Migrated from: edit_file.php lines 83-332
   =================================================================== */

/* File Info Card */
.file-editor .file-info-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-lg);
    display: flex;
    align-items: center;
    gap: var(--space-lg);
}

.file-editor .file-icon {
    width: 64px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-input);
    border-radius: var(--radius-md);
    font-size: 2rem;
    color: var(--text-muted);
}

.file-editor .file-details {
    flex: 1;
}

.file-editor .file-name {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-lg);
    margin-bottom: var(--space-xs);
    word-break: break-all;
}

.file-editor .file-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    display: flex;
    gap: var(--space-md);
    flex-wrap: wrap;
}

.file-editor .file-meta span {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.file-editor .file-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.file-editor .no-file-message {
    text-align: center;
    padding: var(--space-xl);
    color: var(--text-muted);
}

.file-editor .no-file-message i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    display: block;
}

/* Visibility Toggle */
.file-editor .visibility-toggle {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md);
    background: var(--bg-surface);
    border-radius: var(--radius-md);
}

.file-editor .visibility-toggle label {
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.file-editor .visibility-toggle span {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.file-editor .visibility-toggle input[type="checkbox"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

/* File Upload */
.file-editor .file-upload-area {
    border: 2px dashed var(--border-medium);
    border-radius: var(--radius-md);
    padding: var(--space-xl);
    text-align: center;
    cursor: pointer;
    transition: all var(--transition-fast);
    margin-top: var(--space-md);
}

.file-editor .file-upload-area:hover {
    border-color: var(--brand-primary);
    /* was var(--brand-primary-alpha) — only defined for dark theme (dark cyan rgba), so it would render as
       a dark-cyan wash on the white admin light-theme background. color-mix derives the tint locally from
       the theme-aware --brand-primary instead. */
    background: color-mix(in srgb, var(--brand-primary) 12%, transparent);
}

.file-editor .file-upload-area.dragover {
    border-color: var(--brand-primary);
    background: color-mix(in srgb, var(--brand-primary) 12%, transparent);
}

.file-editor .file-upload-area i {
    font-size: 2.5rem;
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
}

.file-editor .file-upload-area p {
    margin: 0;
    color: var(--text-secondary);
}

.file-editor .file-upload-area .hint {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-top: var(--space-xs);
}

/* Scoped under .file-editor to prevent collisions with any future page that
   reuses id="fileInput" for a different element. */
.file-editor #fileInput {
    display: none;
}

/* Description Editor — the file editor uses a plain <textarea class="form-control">
   (file descriptions render as plain-text preview on the course page), so the
   former .description-editor-container / TinyMCE rules were removed. */

/* Builder HTML source editor (2026-09-16) — the "Edit HTML" mode of the page
   editor and the task editor (edit_page.php / edit_task.php), and the
   per-version instruction textareas. Feature-prefixed, unscoped on purpose:
   the same textarea appears in more than one editor. */
.builder-html-source {
    width: 100%;
    min-height: 480px;
    resize: vertical;
    padding: var(--space-md);
    font-family: var(--font-family-mono);
    font-variant-ligatures: none;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--input-text);
    background: var(--bg-input);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-md);
    tab-size: 2;
    white-space: pre;
    overflow: auto;
}

.builder-html-source:focus {
    outline: none;
    border-color: var(--brand-primary);
}

.builder-html-source-hint {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin: var(--space-xs) 0 0;
}

/* Edit Text mode: the rendered preview itself is contenteditable (builder-inplace.js) */
.builder-inplace-editing {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
    cursor: text;
    min-height: 200px;
}

.builder-inplace-hint {
    margin: var(--space-sm) 0 0;
}


/* ===== components/grading-widgets.css ===== */
/* ===================================================================
   Grading Widgets — shared component CSS for the module / grading-category
   widgets in the admin course builder.

   Used by:
   - lms_courses/modules.php        (module library: status badge + category editor)
   - lms_courses/gradebook_setup.php (per-step gradebook: module label badge)
   - lms_courses/index.php          (course builder: interactive module badge +
                                      module-editor category editor)

   Before this component each of the three had its own inline <style> copy of
   .module-badge and a near-identical category editor under different class
   names (.category-item / .category-row). This unifies them:

   - .module-badge is one base pill with two opt-in variants:
       .module-badge--status       (success/warning, via .is-active/.is-inactive)
       .module-badge--interactive  (hover-fill + reveal a trailing .fa-edit)
   - .grading-category-editor is the canonical module category editor (name +
     weight + remove + running total), adopted by modules.php and index.php.
     The drag handle is optional (present only where Sortable is wired).

   gradebook_setup.php's .category-card is a DIFFERENT widget (a read-only card
   grouping graded activities) and is intentionally NOT part of this component.

   Class names here are distinctive (.module-badge, .grading-*) so they are
   safe to live in the global dcs.css bundle without colliding with the other
   editors' generic classes.

   Migrated from inline <style> blocks 2026-07-12.
   =================================================================== */

/* ----- Module badge ------------------------------------------------ */

.module-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    background-color: var(--brand-primary-alpha);
    color: var(--brand-primary);
    flex-shrink: 0;
}

/* Status variant — Active / Inactive (module library) */
.module-badge--status.is-active {
    background-color: var(--color-success-bg);
    color: var(--color-success);
}

.module-badge--status.is-inactive {
    background-color: var(--color-warning-bg);
    color: var(--color-warning);
}

/* Interactive variant — clickable edit trigger (course builder step cards) */
.module-badge--interactive {
    cursor: pointer;
    transition: all var(--transition-fast);
    border: 1px solid transparent;
}

.module-badge--interactive:hover {
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
    border-color: var(--brand-primary);
}

.module-badge--interactive .fa-edit {
    font-size: 0.7rem;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.module-badge--interactive:hover .fa-edit {
    opacity: 1;
}

/* ----- Module category editor -------------------------------------- */
/* Canonical editor for a module's grading categories (name + weight% +
   remove, feeding a running total validated against 100%). Adopted by
   modules.php (with a drag handle + Sortable) and index.php's module-editor
   modal (no drag handle). Distinctive class names so they are safe global.
   (`.percent-suffix` is only ever matched scoped under `.grading-cat-weight`
   so it can't leak into other pages that use that generic name.) */

.grading-cats {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    background-color: var(--bg-input);
    padding: var(--space-md);
}

.grading-cat {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-sm);
}

.grading-cat:last-child {
    margin-bottom: 0;
}

.grading-cat-drag {
    cursor: grab;
    color: var(--text-muted);
    padding: var(--space-xs);
}

.grading-cat-drag:active {
    cursor: grabbing;
}

.grading-cat-name {
    flex: 1;
}

.grading-cat-weight {
    width: 100px;
    position: relative;
}

.grading-cat-weight input {
    text-align: center;
    padding-right: 20px;
}

.grading-cat-weight .percent-suffix {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    pointer-events: none;
}

.grading-cat-actions {
    display: flex;
    gap: var(--space-xs);
}

/* Running weight total — colored valid/invalid pill under the category list */
.grading-cat-total {
    margin-top: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.grading-cat-total.is-valid {
    background-color: var(--color-success-bg);
    color: var(--color-success);
}

.grading-cat-total.is-invalid {
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
}


/* ===== components/step-mark.css ===== */
/* ===================================================================
   Step mark — how a step's mark is made, shown the same way to teacher
   and student (2026-09-11).

   Used by:
   - lms_step_progress/view.php (admin)  the step's activities grouped by
                                         gradebook category + the final-mark sums
   - php/gradebook.php (student)         each course's steps as collapses, the
                                         same groups and sums inside

   Text sizes and colours come from utilities on the markup where they can;
   what is here is layout, the score column and the step collapse.
   =================================================================== */

/* ----- Category groups --------------------------------------------- */

.step-mark-group + .step-mark-group {
    margin-top: var(--space-xl);
}

.step-mark-group-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 2px solid var(--border-color);
}

/* Score column: numbers line up down the group. */
.step-mark-score {
    min-width: 9rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
}

/* The category's average, worked out under its rows. */
.step-mark-formula {
    margin-top: var(--space-sm);
    padding: var(--space-xs) var(--space-md);
    border-left: 3px solid var(--border-color);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    font-variant-numeric: tabular-nums;
}

/* Final-mark sums: the category shares and the total. */
.step-mark-sums {
    margin-top: var(--space-md);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--border-color);
    font-variant-numeric: tabular-nums;
}

/* One line of the sums: name left, sum right (wraps under on a phone). */
.step-mark-line {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-md);
    padding: var(--space-xs) 0;
    color: var(--text-primary);
}

.step-mark-line + .step-mark-line {
    border-top: 1px solid var(--border-color);
}

/* ----- Item rows (student gradebook) -------------------------------- */

.step-mark-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-color);
}

.step-mark-row:last-child {
    border-bottom: none;
}

.step-mark-row-name {
    min-width: 0;
    color: var(--text-primary);
}

/* ----- Step collapse (student gradebook) ---------------------------- */

.step-mark-step {
    border-top: 1px solid var(--border-color);
}

.step-mark-step-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm) var(--space-md);
    padding: var(--space-md) var(--space-lg);
    color: var(--text-primary);
}

summary.step-mark-step-head {
    cursor: pointer;
    list-style: none;
}

summary.step-mark-step-head::-webkit-details-marker {
    display: none;
}

summary.step-mark-step-head:hover {
    background: var(--bg-hover);
}

summary.step-mark-step-head:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: -2px;
}

.step-mark-step-name {
    flex: 1;
    min-width: 12rem;
    font-weight: var(--font-weight-medium);
}

/* A released step's mark on its header. */
.step-mark-step-mark {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    font-variant-numeric: tabular-nums;
}

.step-mark-chevron {
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.step-mark-step[open] > summary .step-mark-chevron {
    transform: rotate(180deg);
}

/* Not started: a plain row, nothing to open. */
.step-mark-step.is-empty .step-mark-step-name {
    color: var(--text-muted);
    font-weight: var(--font-weight-normal);
}

.step-mark-step-body {
    padding: 0 var(--space-lg) var(--space-lg);
}

/* Phone: the step name gets its own line with the badge, mark and chevron
   under it (chevron on the right), and item names get the width back. */
@media (max-width: 640px) {
    .step-mark-step-name {
        flex-basis: 100%;
        min-width: 0;
    }

    .step-mark-chevron {
        margin-left: auto;
    }

    /* Sized to its content (up to half the row) so a mark stays on one line
       and the item name wraps instead. */
    .step-mark-score {
        min-width: 0;
        flex-shrink: 0;
        max-width: 50%;
    }
}


/* ===== components/question-bank.css ===== */
/* ===================================================================
   Question Bank — admin question-management styles

   Used by:
   - src/web/admin.digitalcs.ca/public_html/php/lms_question_bank/index.php
     (.qbank-page — admin question bank list/edit, light theme)

   Generic class names (.question-card, .answer-option, .empty-state,
   .form-row, .action-btn, etc.) are scoped under .qbank-page so they
   don't leak into other admin pages. Feature-prefixed names
   (.bloom-tab, .qs-filters) remain unscoped.

   See docs/plans/active/2026-05-28-question-set-css-extraction.md
   (Ship 6 of qs-audit-fixes).
   =================================================================== */

.qbank-page .qs-filters {
    display: flex;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    flex-wrap: wrap;
    align-items: flex-end;
}

.qbank-page .qs-filters .form-group {
    margin-bottom: 0;
}

.qbank-page .qs-filters .form-control,
.qbank-page .qs-filters .form-select {
    min-width: 180px;
}

.qbank-page .bloom-tabs {
    display: flex;
    gap: var(--space-xs);
    margin-bottom: var(--space-lg);
    border-bottom: 2px solid var(--border-light);
    padding-bottom: var(--space-sm);
}

.qbank-page .bloom-tab {
    padding: var(--space-sm) var(--space-lg);
    background: none;
    border: none;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    color: var(--text-muted);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    transition: all var(--transition-fast);
    position: relative;
}

.qbank-page .bloom-tab:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.qbank-page .bloom-tab.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.qbank-page .bloom-tab.active::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 0;
    right: 0;
    height: 2px;
    background-color: var(--brand-primary);
}

.qbank-page .bloom-tab .count {
    display: inline-block;
    padding: 0 6px;
    margin-left: 4px;
    font-size: var(--font-size-xs);
    background-color: var(--bg-input);
    border-radius: var(--radius-full);
}

.qbank-page .bloom-tab.active .count {
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
}

.qbank-page .question-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
    transition: all var(--transition-fast);
}

.qbank-page .question-card:hover {
    border-color: var(--border-medium);
    box-shadow: var(--shadow-sm);
}

.qbank-page .question-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-md);
    margin-bottom: var(--space-sm);
}

.qbank-page .question-badges {
    display: flex;
    gap: var(--space-xs);
    align-items: center;
    flex-wrap: wrap;
}

.qbank-page .question-type-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
}

.qbank-page .topic-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    background-color: var(--bg-input);
    color: var(--text-secondary);
}

.qbank-page .type-multichoice { background-color: var(--color-info-bg); color: var(--color-info-text); }
.qbank-page .type-truefalse { background-color: var(--color-success-bg); color: var(--color-success-text); }
.qbank-page .type-matching { background-color: var(--brand-primary-alpha); color: var(--brand-primary); }
.qbank-page .type-shortanswer { background-color: var(--color-warning-bg); color: var(--color-warning-text); }
.qbank-page .type-numerical { background-color: var(--color-danger-bg); color: var(--color-danger-text); }

.qbank-page .question-text {
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
}

.qbank-page .question-name {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-xs);
}

.qbank-page .question-preview {
    background-color: var(--bg-input);
    padding: var(--space-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.qbank-page .answer-option {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-xs) 0;
}

.qbank-page .answer-option.correct {
    color: var(--color-success);
}

.qbank-page .answer-option.correct::before {
    content: '\f00c';
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
}

.qbank-page .answer-option.incorrect::before {
    content: '\f00d';
    font-family: 'Font Awesome 7 Pro';
    font-weight: 900;
    color: var(--color-danger);
}

.qbank-page .action-buttons {
    display: flex;
    gap: var(--space-xs);
}

.qbank-page .action-btn {
    padding: var(--space-xs) var(--space-sm);
    background: none;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.qbank-page .action-btn:hover {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.qbank-page .action-btn.danger:hover {
    color: var(--color-danger);
    border-color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.qbank-page .empty-state {
    text-align: center;
    padding: var(--space-2xl);
    color: var(--text-muted);
}

.qbank-page .empty-state i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

/* Answer editor styles */
.qbank-page .answer-list {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    max-height: 300px;
    overflow-y: auto;
}

.qbank-page .answer-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm);
    border-bottom: 1px solid var(--border-light);
}

.qbank-page .answer-item:last-child {
    border-bottom: none;
}

.qbank-page .answer-item input[type="text"] {
    flex: 1;
}

.qbank-page .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-md);
}

.qbank-page .form-row-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: var(--space-md);
}

@media (max-width: 768px) {
    .qbank-page .form-row,
    .qbank-page .form-row-3 {
        grid-template-columns: 1fr;
    }

    .qbank-page .qs-filters {
        flex-direction: column;
    }

    .qbank-page .bloom-tabs {
        flex-wrap: wrap;
    }
}


/* ===== components/question-set.css ===== */
/* ===================================================================
   Question Set — shared component styles

   Used by:
   - src/web/digitalcs.ca/public_html/php/activities/question_set.php
     (.qs-page — student player wrapper, dark theme)
   - src/web/digitalcs.ca/public_html/php/question-set/take.php
     (.qs-take — student take-attempt UI, dark theme)
   - src/web/digitalcs.ca/public_html/php/question-set/review.php
     (.qs-review — student attempt review UI, dark theme)
   - src/web/admin.digitalcs.ca/public_html/php/lms_courses/edit_question_set.php
     (.qs-editor — teacher editor, light theme)

   Generic selectors (.btn, .question-card, .answer-option, etc.) are
   scoped under their wrapper class to prevent sitewide cascade
   pollution. Feature-prefixed selectors (.qs-*) remain unscoped.

   Student-side runtime (.qs-page, .qs-take, .qs-review) reads the dark
   theme tokens from digitalcs.ca's data-theme="dark" cascade. The
   teacher-side editor (.qs-editor) inherits admin.digitalcs.ca's light
   theme and additionally defines a local --qs-accent that the editor's
   icon chip uses (amber to preserve the pre-extraction visual).

   See docs/plans/active/2026-05-28-question-set-css-extraction.md
   (Ship 6 of qs-audit-fixes).
   =================================================================== */

/* === Editor accent ====================================================== */

/* Activity-type accent for the teacher-side editor. The legacy PHP
   variable $typeColor = '#f59e0b' was interpolated directly into the
   inline <style> block; it's now a CSS custom property on the wrapper.
   --color-warning has the same hex value, so the visual is preserved
   exactly. */
.qs-editor {
    --qs-accent: var(--color-warning);                                         /* was #f59e0b */
    --qs-accent-tint-strong: color-mix(in srgb, var(--qs-accent) 13%, transparent); /* was #f59e0b20 */
}

/* ===================================================================
   Shared question card body styles
   (take.php + review.php both render question text + code/pre/img the
   same way — deduplicated under both wrappers.)
   =================================================================== */
.qs-take .question-text img,
.qs-review .question-text img,
.qs-take .question-review-text img,
.qs-review .question-review-text img {
    max-width: 100%;
    border-radius: var(--radius-md);
    margin: var(--space-md) 0;
}

/* ============================================================
   Player wrapper (.qs-page)
   Migrated from: src/web/digitalcs.ca/public_html/php/activities/question_set.php lines 96-379
   ============================================================ */

.qs-page .qs-container {
    max-width: 900px;
    margin: 0 auto;
}

.qs-page .activity-header {
    margin-bottom: var(--space-xl);
}

.qs-page .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-md);
    transition: color var(--transition-fast);
}

.qs-page .back-link:hover {
    color: var(--brand-primary);
}

.qs-page .activity-header h1 {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    margin: 0 0 var(--space-md) 0;
}

.qs-page .activity-header h1 i {
    color: var(--brand-primary);
}

/* JS-rendered "Time expired!" message inside the in-progress notice */
.qs-page .qs-time-expired {
    color: var(--color-danger-text);
}

.qs-page .qs-info {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

.qs-page .qs-info-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--bg-surface);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.qs-page .qs-info-item i {
    color: var(--brand-primary);
}

.qs-page .qs-info-item.random-pool {
    background: var(--color-purple-bg);
    border: 1px solid var(--color-purple-border);
}

.qs-page .qs-info-item.random-pool i {
    color: var(--color-purple);
}

/* Question Set Overview Card */
.qs-page .qs-overview {
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    padding: var(--space-xl);
    margin-bottom: var(--space-xl);
}

.qs-page .qs-overview h2 {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--space-lg) 0;
}

.qs-page .qs-description {
    color: var(--text-secondary);
    margin-bottom: var(--space-xl);
    line-height: 1.6;
}

.qs-page .qs-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

.qs-page .qs-stat {
    text-align: center;
    padding: var(--space-lg);
    background: var(--bg-body);
    border-radius: var(--radius-md);
}

.qs-page .qs-stat-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--brand-primary);
    display: block;
}

.qs-page .qs-stat-label {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.qs-page .qs-stat.success .qs-stat-value {
    color: var(--color-success);
}

.qs-page .qs-stat.warning .qs-stat-value {
    color: var(--color-warning);
}

/* Start Question Set Button */
.qs-page .qs-start-area {
    text-align: center;
    padding: var(--space-lg) 0;
}

.qs-page .btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-xl);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-base);
}

.qs-page .btn-lg {
    padding: var(--space-lg) var(--space-2xl);
    font-size: var(--font-size-lg);
}

.qs-page .btn-primary {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.qs-page .btn-primary:hover {
    background: var(--brand-primary-dark);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.qs-page .btn-success {
    background: var(--color-success);
    color: var(--text-on-success);
}

.qs-page .btn-outline {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}

.qs-page .btn-outline:hover {
    background: var(--bg-hover);
    border-color: var(--brand-primary);
}

.qs-page .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Attempts History */
.qs-page .attempts-history {
    margin-top: var(--space-xl);
}

.qs-page .attempts-history h3 {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--space-md) 0;
}

.qs-page .attempt-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-md);
    background: var(--bg-body);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-sm);
}

.qs-page .attempt-info {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.qs-page .attempt-number {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.qs-page .attempt-date {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.qs-page .attempt-score {
    font-weight: var(--font-weight-bold);
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
}

.qs-page .attempt-score.pass {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.qs-page .attempt-score.fail {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.qs-page .attempt-score.best {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
}

.qs-page .best-badge {
    font-size: var(--font-size-xs);
    background: var(--brand-primary);
    color: var(--text-on-brand);
    padding: 2px 8px;
    border-radius: var(--radius-full);
    margin-left: var(--space-sm);
}

/* No attempts yet */
.qs-page .no-attempts {
    text-align: center;
    padding: var(--space-xl);
    color: var(--text-muted);
}

.qs-page .no-attempts i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    display: block;
}

/* Random pool info section */
.qs-page .pool-info {
    background: var(--color-purple-bg-subtle);
    border: 1px solid var(--color-purple-border);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-lg);
}

.qs-page .pool-info-title {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-purple);
    margin-bottom: var(--space-sm);
    font-size: var(--font-size-sm);
}

.qs-page .pool-info-text {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* ============================================================
   Take wrapper (.qs-take)
   Migrated from: src/web/digitalcs.ca/public_html/php/question-set/take.php lines 234-1073
   ============================================================ */

.qs-take .qs-container {
    max-width: 900px;
    margin: 0 auto;
}

/* Question Set Header */
.qs-take .qs-header {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    margin-bottom: var(--space-xl);
    position: sticky;
    top: 70px;
    z-index: 100;
}

.qs-take .qs-header-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-md);
}

.qs-take .qs-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0;
}

.qs-take .qs-timer {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--bg-body);
    border-radius: var(--radius-md);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    font-family: var(--font-mono);
}

.qs-take .qs-timer i {
    color: var(--brand-primary);
}

.qs-take .qs-timer.warning {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

.qs-take .qs-timer.danger {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
    animation: qs-take-pulse 1s infinite;
}

/* Renamed from generic "pulse" so it can't collide with other
   animations defined elsewhere in the cascade. */
@keyframes qs-take-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* Progress Bar */
.qs-take .qs-progress {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.qs-take .progress-bar-container {
    flex: 1;
    height: 8px;
    background: var(--bg-muted);
    border-radius: var(--radius-full);
    overflow: hidden;
}

.qs-take .progress-bar-fill {
    height: 100%;
    background: var(--brand-primary);
    border-radius: var(--radius-full);
    transition: width 0.3s ease;
}

.qs-take .progress-text {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    white-space: nowrap;
}

/* Question Navigation */
.qs-take .question-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-top: var(--space-md);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-light);
}

.qs-take .question-nav-btn {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.qs-take .question-nav-btn:hover {
    border-color: var(--brand-primary);
    color: var(--brand-primary);
}

.qs-take .question-nav-btn.answered {
    background: var(--color-success);
    border-color: var(--color-success);
    color: var(--text-on-success);
}

.qs-take .question-nav-btn.current {
    border-color: var(--brand-primary);
    box-shadow: var(--focus-ring);
}

.qs-take .question-nav-btn.flagged {
    background: var(--color-warning-bg);
    border-color: var(--color-warning);
    color: var(--color-warning-text);
}

/* Question Card */
.qs-take .question-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    margin-bottom: var(--space-lg);
    display: none;
}

.qs-take .question-card.active {
    display: block;
}

.qs-take .question-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--space-lg);
}

.qs-take .question-meta {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.qs-take .question-number {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
    background: var(--brand-primary-alpha);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
}

.qs-take .question-type {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.qs-take .question-points {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.qs-take .flag-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: var(--space-xs);
    transition: color var(--transition-fast);
}

.qs-take .flag-btn:hover {
    color: var(--color-warning);
}

.qs-take .flag-btn.flagged {
    color: var(--color-warning);
}

.qs-take .question-text {
    font-size: var(--font-size-base);
    color: var(--text-primary);
    line-height: 1.7;
    margin-bottom: var(--space-xl);
}

.qs-take .question-text code {
    background: var(--bg-muted);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.9em;
}

.qs-take .question-text pre {
    background: var(--bg-muted);
    padding: var(--space-md);
    border-radius: var(--radius-md);
    overflow-x: auto;
}

/* Answer Options */
.qs-take .answer-options {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.qs-take .answer-option {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-md);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.qs-take .answer-option:hover {
    border-color: var(--brand-primary);
    background: var(--brand-primary-alpha);
}

.qs-take .answer-option.selected {
    border-color: var(--brand-primary);
    background: var(--brand-primary-alpha);
}

.qs-take .answer-option input {
    margin-top: 3px;
}

.qs-take .answer-option-label {
    flex: 1;
    color: var(--text-primary);
    line-height: 1.5;
}

.qs-take .answer-option-key {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    background: var(--bg-muted);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    margin-right: var(--space-sm);
}

/* True/False specific */
.qs-take .tf-options {
    display: flex;
    gap: var(--space-md);
}

.qs-take .tf-option {
    flex: 1;
    padding: var(--space-lg);
    text-align: center;
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.qs-take .tf-option:hover {
    border-color: var(--brand-primary);
}

.qs-take .tf-option.selected {
    border-color: var(--brand-primary);
    background: var(--brand-primary-alpha);
}

.qs-take .tf-option i {
    font-size: 2rem;
    margin-bottom: var(--space-sm);
    display: block;
}

.qs-take .tf-option.true-opt i { color: var(--color-success); }
.qs-take .tf-option.false-opt i { color: var(--color-danger); }

/* Short Answer / Numerical */
.qs-take .text-answer {
    width: 100%;
    padding: var(--space-md);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    transition: border-color var(--transition-fast);
}

.qs-take .text-answer:focus {
    outline: none;
    border-color: var(--brand-primary);
}

.qs-take .text-answer.textarea {
    min-height: 120px;
    resize: vertical;
}

/* Matching */
.qs-take .matching-container {
    display: grid;
    gap: var(--space-md);
}

.qs-take .matching-pair {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.qs-take .matching-stem {
    flex: 1;
    padding: var(--space-md);
    background: var(--bg-muted);
    border-radius: var(--radius-md);
    color: var(--text-primary);
}

.qs-take .matching-arrow {
    color: var(--text-muted);
}

.qs-take .matching-select {
    flex: 1;
    padding: var(--space-md);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    cursor: pointer;
}

.qs-take .matching-select:focus {
    outline: none;
    border-color: var(--brand-primary);
}

/* Matching Cards Layout */
.qs-take .matching-cards {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-lg);
}

.qs-take .stem-column,
.qs-take .choice-column {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.qs-take .matching-stem-card {
    display: flex;
    align-items: stretch;
    gap: var(--space-sm);
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.qs-take .stem-content {
    flex: 1;
    padding: var(--space-md);
}

.qs-take .stem-content img {
    max-width: 100%;
    border-radius: var(--radius-sm);
}

.qs-take .stem-slot {
    flex: 1;
    min-height: 60px;
    border-left: 2px dashed var(--border-medium);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-sm);
    transition: background var(--transition-fast);
}

.qs-take .stem-slot.drag-over {
    background: var(--color-info-bg);
    border-left-color: var(--color-info);
}

.qs-take .stem-slot .drop-hint {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

.qs-take .matching-choice-card {
    padding: var(--space-md);
    border: 2px solid var(--border-medium);
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    cursor: grab;
    transition: all var(--transition-fast);
    user-select: none;
}

.qs-take .matching-choice-card:active {
    cursor: grabbing;
    opacity: 0.7;
}

.qs-take .matching-choice-card img {
    max-width: 100%;
    border-radius: var(--radius-sm);
}

.qs-take .matched-choice {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm);
    background: var(--color-success-bg);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.qs-take .matched-choice img {
    max-width: 80px;
    border-radius: var(--radius-sm);
}

.qs-take .unpair-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--font-size-lg);
    padding: 0 var(--space-xs);
    margin-left: auto;
}

.qs-take .unpair-btn:hover {
    color: var(--color-danger);
}

/* Timeline Layout — vertical at every width: the years run down a line with a
   drop zone beside each one, and the cards to drag sit in a column alongside.
   A horizontal row split the 900px container between every year, so an
   11-year timeline ran past the question card and a dropped description
   squeezed into a ~120px column. */
.qs-take .matching-timeline {
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: var(--space-lg);
    align-items: start;
}

.qs-take .timeline-bar {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    border-left: 3px solid var(--border-medium);
    padding-left: var(--space-lg);
}

.qs-take .timeline-position {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    position: relative;
}

/* Dot centred on the line: the line is the bar's 3px left border. */
.qs-take .timeline-position::after {
    content: '';
    position: absolute;
    left: calc(-1 * var(--space-lg) - 1.5px);
    top: 50%;
    transform: translate(-50%, -50%);
    width: 14px;
    height: 14px;
    border-radius: var(--radius-full);
    background: var(--border-medium);
    border: 2px solid var(--bg-body);
}

.qs-take .timeline-position.has-match::after {
    background: var(--color-success);
}

.qs-take .timeline-label {
    flex: 0 0 4.5rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
}

.qs-take .timeline-drop-zone {
    flex: 1;
    min-width: 0;
    min-height: 56px;
    border: 2px dashed var(--border-light);
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-sm);
    transition: background var(--transition-fast);
}

.qs-take .timeline-drop-zone .matched-choice {
    flex: 1;
}

.qs-take .timeline-drop-zone.drag-over {
    background: var(--color-info-bg);
    border-color: var(--color-info);
}

.qs-take .timeline-drop-zone .drop-hint {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

.qs-take .timeline-choices {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

/* Linked timeline — back-to-back timeline questions over the same years share
   one card (take.php). Each year's row holds a drop zone per question, sized by
   --timeline-columns (set inline from the longest choice), and the choice pools
   sit in a tray under their own columns. The tray sticks to the bottom of the
   window while the rows scroll, so no card has to be dragged off-screen. */
.qs-take .question-text .linked-question-text + .linked-question-text {
    margin-top: var(--space-sm);
}

.qs-take .timeline-linked {
    grid-template-columns: minmax(0, 1fr);
}

.qs-take .timeline-linked .timeline-position {
    display: grid;
    grid-template-columns: 4.5rem var(--timeline-columns);
    align-items: stretch;
}

.qs-take .timeline-linked .timeline-label {
    align-self: center;
}

.qs-take .timeline-choices-tray {
    position: sticky;
    bottom: 0;
    z-index: 1;
    display: grid;
    grid-template-columns: var(--timeline-columns);
    gap: var(--space-md);
    align-items: start;
    /* run edge to edge across the card (cancelling its padding) so the rows it
       covers are fully hidden, and line the pools up under their drop-zone
       columns: card padding + bar padding + line + label + gap */
    margin: 0 calc(-1 * var(--space-xl));
    padding: var(--space-md) var(--space-xl) var(--space-md) calc(var(--space-xl) + var(--space-lg) + 3px + 4.5rem + var(--space-md));
    background: var(--bg-surface);
    border-top: 1px solid var(--border-color);
}

.qs-take .timeline-choices-tray .timeline-choices {
    max-height: 30vh;
    overflow-y: auto;
}

.qs-take .timeline-choices-tray .matching-choice-card {
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
}

.qs-take .timeline-choices-heading {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

/* Responsive: stack on mobile */
@media (max-width: 768px) {
    .qs-take .matching-cards {
        grid-template-columns: 1fr;
    }

    .qs-take .matching-stem-card {
        flex-direction: column;
    }

    .qs-take .stem-slot {
        border-left: none;
        border-top: 2px dashed var(--border-medium);
        min-height: 50px;
    }

    .qs-take .matching-timeline {
        grid-template-columns: 1fr;
    }

    .qs-take .timeline-label {
        flex-basis: 3.5rem;
    }

    .qs-take .timeline-linked .timeline-position {
        grid-template-columns: minmax(0, 1fr);
    }

    /* stacked rows are tall — keep the dot beside the year, not mid-row */
    .qs-take .timeline-linked .timeline-position::after {
        top: calc(var(--font-size-sm) * 0.75);
    }

    .qs-take .timeline-choices-tray {
        position: static;
        grid-template-columns: minmax(0, 1fr);
        margin: 0;
        padding: var(--space-md) 0 0;
    }

    .qs-take .timeline-choices-tray .timeline-choices {
        max-height: none;
    }
}

/* Navigation Buttons */
.qs-take .question-nav-buttons {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: var(--space-xl);
    padding-top: var(--space-lg);
    border-top: 1px solid var(--border-light);
}

.qs-take .btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-base);
}

.qs-take .btn-primary {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.qs-take .btn-primary:hover {
    background: var(--brand-primary-dark);
}

.qs-take .btn-success {
    background: var(--color-success);
    color: var(--text-on-success);
}

.qs-take .btn-success:hover {
    background: var(--color-success-dark);
}

.qs-take .btn-outline {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}

.qs-take .btn-outline:hover {
    background: var(--bg-hover);
    border-color: var(--brand-primary);
}

.qs-take .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Time expired overlay
   (overlay/modal are appended to <body> via JS, so the .qs-take
   wrapper isn't an ancestor — left unscoped on purpose. Class name is
   already feature-specific enough to avoid collision.) */
.time-expired-overlay {
    position: fixed;
    inset: 0;
    background: var(--bg-overlay-dark);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.time-expired-modal {
    background: var(--bg-surface);
    border-radius: var(--radius-lg);
    padding: var(--space-2xl);
    text-align: center;
    max-width: 400px;
}

.time-expired-modal i {
    font-size: 4rem;
    color: var(--color-danger);
    margin-bottom: var(--space-lg);
}

.time-expired-modal h2 {
    color: var(--text-primary);
    margin-bottom: var(--space-md);
}

.time-expired-modal p {
    color: var(--text-secondary);
    margin-bottom: var(--space-xl);
}

/* File Upload */
.qs-take .upload-instructions {
    color: var(--text-secondary);
    margin-bottom: var(--space-md);
    font-style: italic;
}

.qs-take .file-upload-container {
    width: 100%;
}

.qs-take .file-upload-dropzone {
    border: 2px dashed var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-2xl);
    text-align: center;
    cursor: pointer;
    transition: all var(--transition-fast);
    position: relative;
}

.qs-take .file-upload-dropzone:hover,
.qs-take .file-upload-dropzone.dragover {
    border-color: var(--brand-primary);
    background: var(--brand-primary-alpha);
}

.qs-take .file-upload-dropzone .file-input-hidden {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.qs-take .dropzone-content i {
    font-size: 3rem;
    color: var(--text-muted);
    margin-bottom: var(--space-md);
}

.qs-take .dropzone-content p {
    color: var(--text-secondary);
    margin: 0;
}

.qs-take .dropzone-content .browse-link {
    color: var(--brand-primary);
    text-decoration: underline;
    cursor: pointer;
}

.qs-take .upload-limits {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-top: var(--space-sm) !important;
}

.qs-take .upload-progress {
    margin-top: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-muted);
    border-radius: var(--radius-md);
}

.qs-take .upload-progress .progress-bar-container {
    height: 6px;
    margin-bottom: var(--space-sm);
}

.qs-take .upload-progress .progress-text {
    font-size: var(--font-size-sm);
}

.qs-take .uploaded-files-list {
    display: grid;
    gap: var(--space-md);
    margin-top: var(--space-md);
}

.qs-take .uploaded-file {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
}

.qs-take .uploaded-file .file-preview {
    width: 60px;
    height: 60px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    flex-shrink: 0;
}

.qs-take .uploaded-file .file-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.qs-take .uploaded-file .file-icon {
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-muted);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}

.qs-take .uploaded-file .file-icon i {
    font-size: 1.5rem;
    color: var(--color-danger);
}

.qs-take .uploaded-file .file-info {
    flex: 1;
    min-width: 0;
}

.qs-take .uploaded-file .file-name {
    display: block;
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qs-take .uploaded-file .file-size {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.qs-take .btn-remove-file {
    background: none;
    border: none;
    padding: var(--space-sm);
    color: var(--text-muted);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: all var(--transition-fast);
}

.qs-take .btn-remove-file:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.qs-take .file-count-info {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-top: var(--space-md);
    text-align: center;
}

/* ============================================================
   Submit-result modal (SweetAlert content)
   Used by take.php submitAttempt() — rendered into body > .swal2-container
   so these classes are intentionally NOT scoped under .qs-take.
   ============================================================ */

.qs-submit-result-score {
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-bold);
    margin: var(--space-md) 0;
}

.qs-submit-result-score.pending {
    color: var(--color-warning-text);
}

.qs-submit-result-score.passed {
    font-size: var(--font-size-4xl);
    color: var(--color-success-text);
}

.qs-submit-result-score.failed {
    font-size: var(--font-size-4xl);
    color: var(--color-danger-text);
}

.qs-submit-result-detail {
    color: var(--text-secondary);
}

.qs-submit-result-pending {
    margin-top: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-warning-bg);
    border-radius: var(--radius-md);
    color: var(--color-warning-text);
}

.qs-submit-result-pending i {
    margin-right: var(--space-sm);
}

.qs-submit-result-message {
    margin-top: var(--space-sm);
    font-weight: var(--font-weight-medium);
}

.qs-submit-result-message.passed {
    color: var(--color-success-text);
}

.qs-submit-result-message.failed {
    color: var(--color-danger-text);
}

/* ============================================================
   Review wrapper (.qs-review)
   Migrated from: src/web/digitalcs.ca/public_html/php/question-set/review.php lines 182-680
   ============================================================ */

.qs-review .review-container {
    max-width: 900px;
    margin: 0 auto;
}

.qs-review .review-header {
    margin-bottom: var(--space-xl);
}

.qs-review .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-md);
    transition: color var(--transition-fast);
}

.qs-review .back-link:hover {
    color: var(--brand-primary);
}

.qs-review .review-header h1 {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    margin: 0 0 var(--space-sm) 0;
}

.qs-review .review-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.qs-review .best-attempt-label {
    color: var(--brand-primary);
}

/* Shared footnote text used inside .qs-page and .qs-review for small
   muted helper text below buttons / pending notices. */
.qs-page .qs-footnote,
.qs-review .qs-footnote {
    margin-top: var(--space-md);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

/* Inline hint shown next to a student's wrong answer indicating the
   correct choice. Rendered on a tinted-success background context. */
.qs-review .correct-answer-hint {
    color: var(--color-success-text);
}

/* Placeholder shown when detailed review is hidden for this question set. */
.qs-review .no-questions-placeholder {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    text-align: center;
    color: var(--text-muted);
}

.qs-review .no-questions-placeholder i {
    font-size: var(--font-size-3xl);
    margin-bottom: var(--space-md);
    display: block;
}

/* Results Summary Card */
.qs-review .results-summary {
    background: var(--bg-elevated);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-2xl);
    margin-bottom: var(--space-xl);
    text-align: center;
    box-shadow: var(--shadow-lg);
}

.qs-review .results-summary.passed {
    border-color: var(--color-success);
    background: var(--urgency-low-bg);
}

.qs-review .results-summary.failed {
    border-color: var(--color-danger);
    background: var(--urgency-critical-bg);
}

/* Light mode support (admin domain runs light, but the review page is
   student-side and could load against light if theme is overridden) */
[data-theme="light"] .qs-review .results-summary {
    background: var(--bg-surface);
    box-shadow: var(--shadow-lg);
}

[data-theme="light"] .qs-review .results-summary.passed {
    background: var(--urgency-low-bg);
}

[data-theme="light"] .qs-review .results-summary.failed {
    background: var(--urgency-critical-bg);
}

.qs-review .result-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-lg);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-lg);
}

.qs-review .result-badge.passed {
    background: var(--color-success);
    color: var(--text-on-success);
}

.qs-review .result-badge.failed {
    background: var(--color-danger);
    color: var(--text-on-danger);
}

.qs-review .result-score {
    font-size: 4rem;
    font-weight: var(--font-weight-bold);
    line-height: 1;
    margin-bottom: var(--space-sm);
}

.qs-review .passed .result-score {
    color: var(--color-success);
}

.qs-review .failed .result-score {
    color: var(--color-danger);
}

.qs-review .result-label {
    font-size: var(--font-size-lg);
    color: var(--text-secondary);
    margin-bottom: var(--space-xl);
}

.qs-review .result-stats {
    display: flex;
    justify-content: center;
    gap: var(--space-2xl);
    padding-top: var(--space-lg);
    border-top: 1px solid var(--border-light);
}

.qs-review .result-stat {
    text-align: center;
}

.qs-review .result-stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    display: block;
}

.qs-review .result-stat-label {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.qs-review .result-stat.correct .result-stat-value {
    color: var(--color-success);
}

.qs-review .result-stat.incorrect .result-stat-value {
    color: var(--color-danger);
}

/* Actions */
.qs-review .review-actions {
    display: flex;
    justify-content: center;
    gap: var(--space-md);
    margin-top: var(--space-xl);
}

.qs-review .btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-xl);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-base);
}

.qs-review .btn-primary {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.qs-review .btn-primary:hover {
    background: var(--brand-primary-dark);
}

.qs-review .btn-outline {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}

.qs-review .btn-outline:hover {
    background: var(--bg-hover);
    border-color: var(--brand-primary);
}

/* Question Review Cards */
.qs-review .questions-review {
    margin-top: var(--space-2xl);
}

.qs-review .questions-review h2 {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-lg);
}

.qs-review .question-review-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-lg);
    overflow: hidden;
}

.qs-review .question-review-card.correct {
    border-left: 4px solid var(--color-success);
}

.qs-review .question-review-card.incorrect {
    border-left: 4px solid var(--color-danger);
}

.qs-review .question-review-card.unanswered {
    border-left: 4px solid var(--text-muted);
}

.qs-review .question-review-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-md) var(--space-lg);
    background: var(--bg-muted);
    border-bottom: 1px solid var(--border-light);
}

.qs-review .question-review-meta {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.qs-review .question-review-number {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.qs-review .question-review-type {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: uppercase;
}

.qs-review .question-review-result {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.qs-review .question-review-result.correct {
    color: var(--color-success);
}

.qs-review .question-review-result.incorrect {
    color: var(--color-danger);
}

.qs-review .question-review-result.unanswered {
    color: var(--text-muted);
}

.qs-review .question-review-body {
    padding: var(--space-lg);
}

.qs-review .question-review-text {
    color: var(--text-primary);
    margin-bottom: var(--space-lg);
    line-height: 1.6;
}

/* Answer Display */
.qs-review .answer-display {
    margin-top: var(--space-md);
}

.qs-review .answer-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-sm) 0;
}

.qs-review .answer-label {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    min-width: 100px;
}

.qs-review .answer-value {
    flex: 1;
    font-size: var(--font-size-sm);
}

.qs-review .answer-value.correct {
    color: var(--color-success);
}

.qs-review .answer-value.incorrect {
    color: var(--color-danger);
}

/* Choice List Display */
.qs-review .choice-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.qs-review .choice-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.qs-review .choice-item.selected {
    background: var(--brand-primary-alpha);
    border: 1px solid var(--brand-primary-alpha-strong);
}

.qs-review .choice-item.correct-answer {
    background: var(--color-success-bg);
    border: 1px solid var(--color-success);
}

.qs-review .choice-item.selected.wrong {
    background: var(--color-danger-bg);
    border: 1px solid var(--color-danger);
}

.qs-review .choice-icon {
    margin-top: 2px;
}

.qs-review .choice-icon.correct {
    color: var(--color-success);
}

.qs-review .choice-icon.wrong {
    color: var(--color-danger);
}

.qs-review .choice-icon.neutral {
    color: var(--text-muted);
}

/* Pending Status */
.qs-review .results-summary.pending {
    border-color: var(--color-warning);
    background: var(--urgency-medium-bg);
}

[data-theme="light"] .qs-review .results-summary.pending {
    background: var(--urgency-medium-bg);
}

.qs-review .result-badge.pending {
    background: var(--color-warning);
    color: var(--text-on-warning);
}

.qs-review .pending .result-score {
    color: var(--color-warning);
}

.qs-review .pending-notice {
    margin-top: var(--space-lg);
    padding: var(--space-md) var(--space-lg);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning);
    border-radius: var(--radius-md);
    color: var(--color-warning-text);
    font-size: var(--font-size-sm);
}

.qs-review .pending-notice i {
    margin-right: var(--space-sm);
}

.qs-review .question-review-card.pending {
    border-left: 4px solid var(--color-warning);
}

.qs-review .question-review-result.pending {
    color: var(--color-warning);
}

.qs-review .result-stat.pending .result-stat-value {
    color: var(--color-warning);
}

/* Part marks: an answer that earned some but not all points (2026-09-17) */
.qs-review .question-review-card.partial {
    border-left: 4px solid var(--color-warning);
}

.qs-review .question-review-result.partial,
.qs-review .answer-value.partial,
.qs-review .result-stat.partial .result-stat-value {
    color: var(--color-warning-text);
}

/* Feedback Display */
.qs-review .feedback-box {
    margin-top: var(--space-md);
    padding: var(--space-md);
    /* Tints derived from brand to match the h4 heading inside the box
       (which uses var(--brand-primary)). The legacy rgba values were
       hard-coded indigo (99,102,241) — replaced with color-mix on the
       live brand token so the box re-themes correctly. */
    background: color-mix(in srgb, var(--brand-primary) 5%, transparent);
    border: 1px solid color-mix(in srgb, var(--brand-primary) 20%, transparent);
    border-radius: var(--radius-md);
}

.qs-review .feedback-box h4 {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-primary);
    margin: 0 0 var(--space-sm) 0;
}

.qs-review .feedback-box p {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    margin: 0;
    line-height: 1.6;
}

/* Explanation: the question's own stored text for the answer the student gave
   (2026-10-09). The info pair keeps it apart from the teacher's own comment
   in .feedback-box above. */
.qs-review .explanation-box {
    margin-top: var(--space-md);
    padding: var(--space-md);
    background: var(--color-info-bg);
    border: 1px solid color-mix(in srgb, var(--color-info) 30%, transparent);
    border-radius: var(--radius-md);
}

.qs-review .explanation-box h4 {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-info-text);
    margin: 0 0 var(--space-sm) 0;
}

.qs-review .explanation-box p {
    font-size: var(--font-size-sm);
    color: var(--color-info-text);
    margin: 0;
    line-height: 1.6;
}

.qs-review .explanation-box p + p {
    margin-top: var(--space-sm);
}

/* File Upload Display */
.qs-review .uploaded-files-review {
    display: grid;
    gap: var(--space-md);
    margin-top: var(--space-md);
}

.qs-review .uploaded-file-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm);
    background: var(--bg-muted);
    border-radius: var(--radius-md);
}

.qs-review .uploaded-file-item .file-preview {
    width: 80px;
    height: 80px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    flex-shrink: 0;
}

.qs-review .uploaded-file-item .file-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: pointer;
}

.qs-review .uploaded-file-item .file-icon {
    width: 80px;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-surface);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}

.qs-review .uploaded-file-item .file-icon i {
    font-size: 2rem;
    color: var(--color-danger);
}

.qs-review .uploaded-file-item .file-details {
    flex: 1;
}

.qs-review .uploaded-file-item .file-name {
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

.qs-review .uploaded-file-item .file-meta {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.qs-review .uploaded-file-item .file-link {
    color: var(--brand-primary);
    text-decoration: none;
}

.qs-review .uploaded-file-item .file-link:hover {
    text-decoration: underline;
}

/* ============================================================
   Editor wrapper (.qs-editor)
   Migrated from: src/web/admin.digitalcs.ca/public_html/php/lms_courses/edit_question_set.php lines 105-795
   Note: --qs-accent / --qs-accent-tint-strong are defined above
   (top of file) so the icon-chip rule below can reference them.
   ============================================================ */

.qs-editor.activity-editor {
    max-width: 1200px;
    margin: 0 auto;
}

.qs-editor .editor-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.qs-editor .editor-icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    font-size: 1.75rem;
    background-color: var(--qs-accent-tint-strong);
    color: var(--qs-accent);
}

.qs-editor .editor-title-section {
    flex: 1;
}

.qs-editor .editor-title-section h1 {
    font-size: var(--font-size-xl);
    margin: 0 0 var(--space-xs) 0;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.qs-editor .editor-title-input {
    flex: 1;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    border: 1px solid transparent;
    background: transparent;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    min-width: 200px;
}

.qs-editor .editor-title-input:hover {
    border-color: var(--border-color);
    background: var(--bg-surface);
}

.qs-editor .editor-title-input:focus {
    outline: none;
    border-color: var(--brand-primary);
    background: var(--bg-surface);
}

.qs-editor .editor-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.qs-editor .editor-meta a {
    color: var(--text-secondary);
    text-decoration: none;
}

.qs-editor .editor-meta a:hover {
    color: var(--brand-primary);
}

.qs-editor .editor-actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* Question Set Editor Content */
.qs-editor .question-set-content {
    display: flex;
    gap: var(--space-lg);
    min-height: 500px;
}

/* Two-panel layout */
.qs-editor .questions-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.qs-editor .settings-panel {
    width: 320px;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.qs-editor .panel-header {
    padding: var(--space-md) var(--space-lg);
    border-bottom: 1px solid var(--border-light);
    font-weight: var(--font-weight-semibold);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.qs-editor .panel-content {
    flex: 1;
    padding: var(--space-md);
    overflow-y: auto;
}

/* Questions List */
.qs-editor .questions-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.qs-editor .question-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-md);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.qs-editor .question-item:hover {
    border-color: var(--border-medium);
}

.qs-editor .question-item.dragging {
    opacity: 0.5;
}

.qs-editor .question-drag-handle {
    cursor: grab;
    color: var(--text-muted);
    padding: var(--space-xs);
}

.qs-editor .question-number {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    flex-shrink: 0;
}

.qs-editor .question-content {
    flex: 1;
    min-width: 0;
}

.qs-editor .question-text {
    margin-bottom: var(--space-xs);
    line-height: 1.4;
}

.qs-editor .question-meta {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

.qs-editor .question-type-badge {
    padding: 2px 8px;
    border-radius: var(--radius-full);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

.qs-editor .question-type-badge.multichoice { background-color: var(--color-info-bg); color: var(--color-info-text); }
.qs-editor .question-type-badge.truefalse { background-color: var(--color-success-bg); color: var(--color-success-text); }
.qs-editor .question-type-badge.matching { background-color: var(--brand-primary-alpha); color: var(--brand-primary); }
.qs-editor .question-type-badge.shortanswer { background-color: var(--color-warning-bg); color: var(--color-warning-text); }
.qs-editor .question-type-badge.numerical { background-color: var(--color-danger-bg); color: var(--color-danger-text); }

.qs-editor .question-actions {
    display: flex;
    gap: var(--space-xs);
}

.qs-editor .question-actions .btn {
    padding: var(--space-xs);
    line-height: 1;
}

/* Empty state */
.qs-editor .questions-empty {
    text-align: center;
    padding: var(--space-xl);
    color: var(--text-muted);
}

.qs-editor .questions-empty i {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

/* Question Bank Modal */
.qs-editor .question-bank-filters {
    display: flex;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
    flex-wrap: wrap;
}

.qs-editor .question-bank-filters select {
    min-width: 150px;
}

.qs-editor .question-bank-list {
    max-height: 400px;
    overflow-y: auto;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.qs-editor .question-bank-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-md);
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.qs-editor .question-bank-item:last-child {
    border-bottom: none;
}

.qs-editor .question-bank-item:hover {
    background-color: var(--bg-muted);
}

.qs-editor .question-bank-item.selected {
    background-color: var(--brand-primary-alpha);
}

.qs-editor .question-bank-item input[type="checkbox"] {
    margin-top: 4px;
}

/* Question Bank Modal Tabs */
.qs-editor .question-bank-tabs {
    display: flex;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
    padding-bottom: var(--space-sm);
}

.qs-editor .question-bank-tabs .tab-btn {
    padding: var(--space-sm) var(--space-md);
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    transition: all var(--transition-fast);
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.qs-editor .question-bank-tabs .tab-btn:hover {
    background-color: var(--bg-muted);
    color: var(--text-primary);
}

.qs-editor .question-bank-tabs .tab-btn.active {
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
}

/* Tab Content */
.qs-editor .tab-content {
    display: none;
}

.qs-editor .tab-content.active {
    display: block;
}

/* Random Questions Options */
.qs-editor .random-options {
    padding: var(--space-lg);
    background-color: var(--bg-muted);
    border-radius: var(--radius-md);
}

.qs-editor .random-count-group {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}

.qs-editor .random-count-group label {
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.qs-editor .random-count-group input {
    width: 100px;
}

.qs-editor .random-info {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.qs-editor .random-info i {
    color: var(--color-info);
}

/* The success/warning bg + border tints don't have dedicated -subtle
   tokens in tokens.css yet. color-mix on the live token gives the
   correct light/dark behavior without needing a new design decision. */
.qs-editor .random-info.success {
    border-color: var(--color-success);
    background-color: color-mix(in srgb, var(--color-success) 8%, transparent); /* was --bg-success-subtle (undefined) */
}

.qs-editor .random-info.success i {
    color: var(--color-success);
}

.qs-editor .random-info.warning {
    border-color: var(--color-warning);
    background-color: color-mix(in srgb, var(--color-warning) 8%, transparent); /* was --bg-warning-subtle (undefined) */
}

.qs-editor .random-info.warning i {
    color: var(--color-warning);
}

/* Settings form */
.qs-editor .settings-section {
    margin-bottom: var(--space-lg);
}

.qs-editor .settings-section-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    margin-bottom: var(--space-sm);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.qs-editor .settings-form-group {
    margin-bottom: var(--space-md);
}

.qs-editor .settings-form-group label {
    display: block;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-xs);
    color: var(--text-primary);
}

.qs-editor .settings-form-group input[type="number"],
.qs-editor .settings-form-group select {
    width: 100%;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    background-color: var(--bg-surface);
    color: var(--text-primary);
}

.qs-editor .settings-form-group .form-hint {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-top: var(--space-xs);
}

.qs-editor .settings-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-sm) 0;
}

.qs-editor .settings-toggle label {
    margin: 0;
}

/* Stats */
.qs-editor .qs-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-sm);
    padding: var(--space-md);
    background-color: var(--bg-surface);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-md);
}

.qs-editor .stat-item {
    text-align: center;
}

.qs-editor .stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    color: var(--brand-primary);
}

.qs-editor .stat-label {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* Status indicator
   The original block referenced --warning-color / --success-color /
   --danger-color, which aren't defined anywhere in tokens.css. Mapped
   to the actual semantic tokens (--color-warning etc.) — same intent. */
.qs-editor .save-status {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.qs-editor .save-status.saving { color: var(--color-warning); } /* was --warning-color (undefined) */
.qs-editor .save-status.saved { color: var(--color-success); }  /* was --success-color (undefined) */
.qs-editor .save-status.error { color: var(--color-danger); }   /* was --danger-color (undefined) */

/* Selection Mode Toggle */
.qs-editor .selection-mode-toggle {
    display: flex;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
    padding: var(--space-xs);
    background-color: var(--bg-muted);
    border-radius: var(--radius-md);
}

.qs-editor .selection-mode-toggle .mode-btn {
    flex: 1;
    padding: var(--space-sm) var(--space-md);
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: all var(--transition-fast);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
}

.qs-editor .selection-mode-toggle .mode-btn:hover {
    color: var(--text-primary);
    background-color: var(--bg-surface);
}

.qs-editor .selection-mode-toggle .mode-btn.active {
    background-color: var(--brand-primary);
    color: var(--text-on-brand);
    box-shadow: var(--shadow-sm);
}

/* Random Pool List */
.qs-editor .random-pools-container {
    display: none;
}

.qs-editor .random-pools-container.active {
    display: block;
}

.qs-editor .random-pool-item {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
    position: relative;
}

.qs-editor .random-pool-item:hover {
    border-color: var(--border-color);
}

.qs-editor .pool-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-sm);
}

.qs-editor .pool-title {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.qs-editor .pool-title i {
    color: var(--brand-primary);
}

.qs-editor .pool-remove {
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--space-xs);
    border-radius: var(--radius-sm);
}

/* Tint backing for hover state — was --bg-danger-subtle (undefined). */
.qs-editor .pool-remove:hover {
    color: var(--color-danger); /* was --danger-color (undefined) */
    background-color: color-mix(in srgb, var(--color-danger) 8%, transparent);
}

.qs-editor .pool-config {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-sm);
}

.qs-editor .pool-config select,
.qs-editor .pool-config input {
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    background-color: var(--bg-body);
    color: var(--text-primary);
}

.qs-editor .pool-count-row {
    grid-column: span 2;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-top: var(--space-xs);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--border-light);
}

.qs-editor .pool-count-row label {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    white-space: nowrap;
}

.qs-editor .pool-count-row input {
    width: 80px;
}

.qs-editor .pool-available {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-left: auto;
}

.qs-editor .pool-available.has-questions {
    color: var(--color-success); /* was --success-color (undefined) */
}

.qs-editor .pool-available.no-questions {
    color: var(--color-danger); /* was --danger-color (undefined) */
}

.qs-editor .add-pool-btn {
    width: 100%;
    padding: var(--space-md);
    border: 2px dashed var(--border-light);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: all var(--transition-fast);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
}

.qs-editor .add-pool-btn:hover {
    border-color: var(--brand-primary);
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

/* Fixed questions container */
.qs-editor .fixed-questions-container {
    display: block;
}

.qs-editor .fixed-questions-container.hidden {
    display: none;
}

/* Pool summary in panel
   Was --bg-info-subtle / --border-info (both undefined in tokens.css);
   replaced with color-mix on --color-info. */
.qs-editor .pool-summary {
    padding: var(--space-md);
    background-color: color-mix(in srgb, var(--color-info) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-info) 30%, transparent);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-md);
    font-size: var(--font-size-sm);
}

.qs-editor .pool-summary-title {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.qs-editor .pool-summary-title i {
    color: var(--color-info);
}

.qs-editor .pool-summary p {
    margin: 0;
    color: var(--text-secondary);
}

/* Responsive */
@media (max-width: 992px) {
    .qs-editor .editor-content {
        flex-direction: column;
    }

    .qs-editor .questions-panel {
        border-right: none;
        border-bottom: 1px solid var(--border-light);
    }

    .qs-editor .settings-panel {
        width: 100%;
    }
}


/* ===== components/tours.css ===== */
/* ============================================================================
   Guided Tours — Driver.js theme overrides
   ----------------------------------------------------------------------------
   Themes the Driver.js popover with DCS design tokens so guided tours match the
   student site (dark theme). Driver.js' own stylesheet is lazy-loaded from CDN
   by dcs-tours.js; these rules layer on top of it. Scoped to .dcs-tour-popover
   (set via Driver.js' popoverClass option) so nothing else is affected.
   See docs/planned/progressive-onboarding.md.
   ============================================================================ */

.driver-popover.dcs-tour-popover {
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-lg);
}

.dcs-tour-popover .driver-popover-title {
    color: var(--text-primary);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-xs);
}

.dcs-tour-popover .driver-popover-description {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    line-height: 1.5;
}

.dcs-tour-popover .driver-popover-progress-text {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

/* Driver.js draws the popover arrow with border-color on a pseudo-element;
   re-point those to the popover background so the arrow matches. */
.dcs-tour-popover .driver-popover-arrow-side-left.driver-popover-arrow { border-left-color: var(--bg-elevated); }
.dcs-tour-popover .driver-popover-arrow-side-right.driver-popover-arrow { border-right-color: var(--bg-elevated); }
.dcs-tour-popover .driver-popover-arrow-side-top.driver-popover-arrow { border-top-color: var(--bg-elevated); }
.dcs-tour-popover .driver-popover-arrow-side-bottom.driver-popover-arrow { border-bottom-color: var(--bg-elevated); }

/* Navigation buttons */
.dcs-tour-popover .driver-popover-navigation-btns {
    gap: var(--space-sm);
    padding-top: var(--space-md);
}

.dcs-tour-popover .driver-popover-next-btn,
.dcs-tour-popover .driver-popover-prev-btn {
    text-shadow: none;
    border-radius: var(--radius-sm);
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    transition: background var(--transition-fast), color var(--transition-fast);
}

.dcs-tour-popover .driver-popover-next-btn {
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border: 1px solid var(--brand-primary);
}

.dcs-tour-popover .driver-popover-next-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.dcs-tour-popover .driver-popover-prev-btn {
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}

.dcs-tour-popover .driver-popover-prev-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.dcs-tour-popover .driver-popover-close-btn {
    color: var(--text-muted);
    transition: color var(--transition-fast);
}

.dcs-tour-popover .driver-popover-close-btn:hover {
    color: var(--text-primary);
}


/* ===== components/questionnaire.css ===== */
/* ===================================================================
   Skills & Interests Questionnaire (activity_type: questionnaire)
   Scoped under .qnr- — ships in the global bundle (serve.php + dcs.css).
   Dual-theme: token pairs only.
   =================================================================== */

.qnr-back {
    max-width: 720px;
    margin: 0 auto var(--space-md);
}

.qnr-back .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--font-size-sm);
}

.qnr-back .back-link:hover {
    color: var(--brand-primary);
}

.qnr-card {
    background: var(--card-bg);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    max-width: 720px;
    margin: 0 auto;
}

.qnr-facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin: var(--space-lg) 0;
}

.qnr-fact {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
}

.qnr-progress {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.qnr-progress-bar {
    flex: 1;
    height: 8px;
    background: var(--bg-elevated);
    border-radius: var(--radius-full, 9999px);
    overflow: hidden;
}

.qnr-progress-fill {
    height: 100%;
    background: var(--brand-primary);
    border-radius: inherit;
    transition: width 0.25s ease;
}

.qnr-progress-label {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.qnr-question-icon {
    font-size: 1.75rem;
    color: var(--brand-primary);
    margin-bottom: var(--space-sm);
}

.qnr-question-text {
    font-size: var(--font-size-lg);
    color: var(--text-primary);
    margin-bottom: var(--space-lg);
}

.qnr-options {
    display: grid;
    gap: var(--space-sm);
}

.qnr-option {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    width: 100%;
    text-align: left;
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 2px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.qnr-option:hover {
    background: var(--bg-hover);
}

.qnr-option.selected {
    border-color: var(--brand-primary);
    background: var(--bg-active);
}

.qnr-option-icon {
    flex: 0 0 auto;
    width: 2.25rem;
    text-align: center;
    font-size: 1.25rem;
    color: var(--brand-primary);
}

.qnr-rate-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-sm);
}

.qnr-rate-row .qnr-option {
    flex-direction: column;
    text-align: center;
    gap: var(--space-xs);
}

.qnr-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: var(--space-xl);
}

.qnr-result-tracks {
    display: grid;
    gap: var(--space-md);
    margin: var(--space-lg) 0;
}

.qnr-result-track {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    background: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md) var(--space-lg);
}

.qnr-result-track-icon {
    font-size: 1.5rem;
    color: var(--brand-primary);
    width: 2.5rem;
    text-align: center;
}

.qnr-result-track-name {
    color: var(--text-primary);
    font-weight: 600;
}

.qnr-result-track-blurb {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.qnr-glossary-term {
    margin-bottom: var(--space-md);
    text-align: left;
}

@media (max-width: 600px) {
    .qnr-rate-row {
        grid-template-columns: repeat(2, 1fr);
    }
}


/* ===== components/accessibility.css ===== */
/* ===================================================================
   Accessibility modes (student site) — roadmap P5 trio, 2026-07-02
   - Dyslexia-friendly font:  <body data-font="dyslexic">
   - High-contrast mode:      <body data-contrast="high">  (dark theme)
   - Read-aloud control:      .dcs-read-aloud (injected by dcs-read-aloud.js)
   Preferences persist in lms_student_preferences and are applied
   server-side on <body> by the student header.
   =================================================================== */

/* ----- OpenDyslexic (OFL) — self-hosted; only downloads when the mode
        is active because nothing references the family otherwise ----- */
@font-face {
    font-family: 'OpenDyslexic';
    src: url('/assets/fonts/opendyslexic/OpenDyslexic-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'OpenDyslexic';
    src: url('/assets/fonts/opendyslexic/OpenDyslexic-Bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'OpenDyslexic';
    src: url('/assets/fonts/opendyslexic/OpenDyslexic-Italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

/* Font swap rides inheritance — elements that set their own family
   (FontAwesome icons, code/mono blocks, TinyMCE) keep theirs. The wider
   letterforms need a little extra breathing room. */
body[data-font="dyslexic"] {
    font-family: 'OpenDyslexic', var(--font-family-base, sans-serif);
    letter-spacing: 0.01em;
    line-height: 1.6;
}

body[data-font="dyslexic"] input,
body[data-font="dyslexic"] textarea,
body[data-font="dyslexic"] select,
body[data-font="dyslexic"] button {
    font-family: inherit;
}

/* ----- High contrast (dark student theme): re-declare the core token
        set at body level so every var() consumer picks it up ----- */
body[data-contrast="high"] {
    --bg-body: #000000;
    --bg-surface: #05080f;
    --bg-elevated: #0b101c;
    --bg-hover: #141c2e;
    --bg-active: #1b2540;
    --bg-input: #05080f;
    --card-bg: #05080f;
    --text-primary: #ffffff;
    --text-secondary: #eef2fa;
    --text-muted: #cdd6e6;
    --input-text: #ffffff;
    --input-placeholder: #aab6cc;
    --border-light: #55688c;
    --border-medium: #7288b0;
    --border-secondary: #64789f;
}

/* ----- Read-aloud control (injected above .activity-content) ----- */
.dcs-read-aloud {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.dcs-read-aloud button {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-full, 9999px);
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background 0.15s ease;
}

.dcs-read-aloud button:hover {
    background: var(--bg-hover);
}

.dcs-read-aloud button.is-speaking {
    border-color: var(--brand-primary);
    color: var(--brand-primary);
}

.dcs-read-aloud .dcs-read-aloud-status {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

@media (prefers-reduced-motion: no-preference) {
    .dcs-read-aloud button.is-speaking i {
        animation: dcs-read-pulse 1.2s ease-in-out infinite;
    }
    @keyframes dcs-read-pulse {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.45; }
    }
}


/* ===== components/content-upload-wizard.css ===== */
/* ===================================================================
   Content Upload Wizard
   4-step admin modal for uploading HTML content + AI/screenshot images.
   Selectors are prefixed `cuw-` to keep them isolated from the rest of
   the admin UI.
   =================================================================== */

/* ----- Modal scaffold ----- */
#content-upload-wizard {
    position: fixed;
    inset: 0;
    z-index: 1050;
    background: var(--bg-overlay-dark);
    overflow-y: auto;
}

.cuw-shell {
    max-width: 900px;
    margin: 40px auto;
    background: var(--bg-surface);
    color: var(--text-primary);
    border-radius: var(--radius-md);
    max-height: calc(100vh - 80px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.cuw-shell > .cuw-header,
.cuw-shell > .cuw-footer {
    padding: var(--space-md) var(--space-lg);
    flex-shrink: 0;
}
.cuw-shell > .cuw-header { border-bottom: 1px solid var(--border-light); }
.cuw-shell > .cuw-footer { border-top: 1px solid var(--border-light); display: flex; justify-content: space-between; align-items: center; }
.cuw-shell > .cuw-body { padding: var(--space-lg); flex: 1; overflow-y: auto; }

/* ----- Step indicator ----- */
.cuw-steps { display: flex; align-items: center; justify-content: center; gap: var(--space-sm); }
.cuw-step { display: flex; align-items: center; gap: var(--space-sm); }
.cuw-step-bubble {
    width: 28px; height: 28px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 0.8rem; font-weight: 600;
    background: var(--border-medium); color: var(--text-muted);
}
.cuw-step-bubble.is-active { background: var(--brand-primary); color: var(--text-on-brand); }
.cuw-step-bubble.is-done   { background: var(--color-success); color: var(--text-on-success, #fff); }
.cuw-step-bubble.is-done i { font-size: 0.7rem; }
.cuw-step-label { font-size: 0.85rem; color: var(--text-muted); }
.cuw-step.is-active .cuw-step-label { color: var(--text-primary); }
.cuw-step-connector {
    width: 40px; height: 2px;
    background: var(--border-medium);
    margin: 0 var(--space-sm);
}
.cuw-step-connector.is-done { background: var(--color-success); }

/* ----- Section headings / shared ----- */
.cuw-section-title { margin: 0 0 var(--space-md) 0; }
.cuw-muted-note { color: var(--text-muted); font-size: 0.9rem; }

/* ----- Panels ----- */
.cuw-panel {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
}
.cuw-panel-header { font-weight: 600; margin-bottom: var(--space-sm); display: flex; align-items: center; gap: 6px; }
.cuw-panel-hint { font-size: 0.8rem; color: var(--text-muted); margin-bottom: var(--space-sm); }

/* ----- Step 1: drop zones ----- */
.cuw-drop-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
.cuw-drop-zone {
    border: 2px dashed var(--border-medium);
    border-radius: var(--radius-md);
    padding: var(--space-lg);
    text-align: center;
    cursor: pointer;
}
.cuw-drop-zone:hover { border-color: var(--brand-primary); }
.cuw-drop-icon { font-size: 2rem; display: block; margin-bottom: var(--space-sm); }
.cuw-drop-icon.is-primary { color: var(--brand-primary); }
.cuw-drop-icon.is-muted   { color: var(--text-muted); }
.cuw-drop-title { font-weight: 600; margin-bottom: 4px; }
.cuw-drop-sub { font-size: 0.85rem; color: var(--text-muted); }
.cuw-file-list { margin-top: var(--space-md); font-size: 0.85rem; color: var(--text-secondary); }

/* ----- Step 2: editable chapter titles ----- */
.cuw-chapter-list { display: flex; flex-direction: column; gap: 6px; }
.cuw-chapter-row { display: flex; align-items: center; gap: var(--space-sm); font-size: 0.9rem; }
.cuw-chapter-num { font-weight: 600; color: var(--text-muted); min-width: 24px; }
.cuw-chapter-title {
    flex: 1;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    font-size: 0.9rem;
}
.cuw-chapter-title:focus { outline: none; border-color: var(--brand-primary); }
.cuw-chapter-filename { font-size: 0.75rem; color: var(--text-muted); min-width: 160px; text-align: right; }

/* ----- Step 2: placeholder summary ----- */
.cuw-placeholder-list { display: flex; flex-direction: column; gap: 6px; }
.cuw-placeholder-item { font-size: 0.9rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cuw-icon-image      { color: var(--brand-primary); }
.cuw-icon-screenshot { color: var(--color-info); }
.cuw-summary {
    background: var(--bg-elevated);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    font-size: 0.9rem;
}

/* ----- Inline tags ----- */
.cuw-tag { font-size: 0.75rem; padding: 2px 6px; border-radius: var(--radius-sm); display: inline-flex; align-items: center; gap: 4px; }
.cuw-tag-success { color: var(--color-success-text); background: var(--color-success-bg); }
.cuw-tag-warning { color: var(--color-warning-text); background: var(--color-warning-bg); }

/* ----- Alerts (Step 2 unmatched, Step 4 warnings) ----- */
.cuw-alert {
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
    font-size: 0.9rem;
}
.cuw-alert-warning { background: var(--color-warning-bg); color: var(--color-warning-text); }
.cuw-alert-danger  { background: var(--color-danger-bg);  color: var(--color-danger-text); }
.cuw-alert-info    { background: var(--color-info-bg);    color: var(--color-info-text); }
.cuw-alert-center  { text-align: center; }
.cuw-alert-title { font-weight: 600; margin-bottom: var(--space-xs); display: flex; align-items: center; gap: 6px; }
.cuw-alert-body  { margin-bottom: var(--space-sm); }
.cuw-alert-list  { margin: 0; padding-left: 1.25rem; }

/* ----- Step 3: progress bar ----- */
.cuw-progress {
    background: var(--bg-elevated);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
}
.cuw-progress.is-inline {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.cuw-progress.is-hidden { display: none; }
.cuw-upload-label { margin: 0; cursor: pointer; }
.cuw-btn-spinner { margin-right: 6px; }
.cuw-progress-row { display: flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-sm); }
.cuw-progress-track { background: var(--border-light); border-radius: var(--radius-full); height: 8px; overflow: hidden; }
.cuw-progress-bar {
    height: 100%;
    background: var(--brand-primary);
    border-radius: var(--radius-full);
    width: 0%;
    transition: width 0.3s;
}
.cuw-progress-bar.is-success { background: var(--color-success); }
.cuw-progress-bar.is-warning { background: var(--color-warning); }

/* ----- Step 3: image cards ----- */
.cuw-image-list { display: flex; flex-direction: column; gap: var(--space-md); }
.cuw-image-card {
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.cuw-image-card-head {
    padding: var(--space-sm) var(--space-md);
    background: var(--bg-hover);
    display: flex; align-items: center; justify-content: space-between;
}
.cuw-image-card-title { font-weight: 600; font-size: 0.9rem; display: flex; align-items: center; gap: 6px; }
.cuw-image-card-body {
    display: grid;
    grid-template-columns: 1fr 200px;
    gap: var(--space-md);
    padding: var(--space-md);
}
.cuw-image-desc { font-size: 0.85rem; color: var(--text-secondary); margin-bottom: var(--space-sm); }
.cuw-image-prompt {
    width: 100%;
    min-height: 60px;
    resize: vertical;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    padding: var(--space-xs);
    font-size: 0.8rem;
    font-family: var(--font-family-base);
}
.cuw-image-actions { margin-top: var(--space-xs); display: flex; gap: var(--space-xs); }
.cuw-image-preview {
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    min-height: 120px;
    background: var(--bg-elevated);
    overflow: hidden;
}
.cuw-image-preview .cuw-muted-note { font-size: 0.75rem; }
.cuw-image-preview img { max-width: 100%; max-height: 150px; cursor: pointer; }
.cuw-preview-loading { text-align: center; padding: var(--space-sm); }
.cuw-preview-loading .cuw-loading-label { font-size: 0.7rem; color: var(--text-muted); margin-top: 4px; }

/* Screenshot zones */
.cuw-screenshot-zone {
    border: 2px dashed var(--border-medium);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    text-align: center;
    cursor: pointer;
}
.cuw-screenshot-zone:hover { border-color: var(--brand-primary); }
.cuw-screenshot-hint { font-size: 0.7rem; color: var(--text-muted); margin-top: var(--space-xs); }

/* Failed generation (with upload-instead fallback) */
.cuw-failed {
    text-align: center;
    padding: var(--space-sm);
    display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.cuw-failed-icon { color: var(--color-danger); font-size: 1.2rem; }
.cuw-failed-msg  { color: var(--color-danger-text); font-size: 0.7rem; max-width: 180px; }
.cuw-failed-upload { margin: 0; cursor: pointer; font-size: 0.75rem; }

/* ----- Status pills ----- */
.cuw-status { font-size: 0.8rem; display: inline-flex; align-items: center; gap: 4px; }
.cuw-status-success { color: var(--color-success-text); }
.cuw-status-danger  { color: var(--color-danger-text); }
.cuw-status-pending { color: var(--brand-primary); }

/* ----- Step 4 ----- */
.cuw-step4 { text-align: center; padding: var(--space-lg) 0; }
.cuw-step4-icon { font-size: 3rem; color: var(--color-success); display: block; margin-bottom: var(--space-md); }
.cuw-stats { display: flex; justify-content: center; gap: var(--space-lg); margin-bottom: var(--space-lg); }
.cuw-stat-num { font-size: 1.5rem; font-weight: 700; }
.cuw-stat-label { font-size: 0.85rem; color: var(--text-muted); }
.cuw-cache-note { font-size: 0.85rem; color: var(--color-success-text); margin-bottom: var(--space-md); display: flex; align-items: center; justify-content: center; gap: 6px; }

/* ----- Download Images badge (on the editor toolbar button) ----- */
.cuw-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    margin-left: 6px;
    border-radius: var(--radius-full);
    background: var(--color-warning);
    color: var(--text-on-brand, #fff);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
    vertical-align: middle;
}

/* ----- Lightbox ----- */
#wizard-lightbox {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: var(--bg-overlay-dark);
    cursor: pointer;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
#wizard-lightbox.is-open { display: flex; }
#wizard-lightbox-img {
    max-width: 95%;
    max-height: 95%;
    border-radius: var(--radius-md);
    box-shadow: 0 0 40px var(--bg-overlay-medium);
}

/* ============================================================
   Animation row in Step 3 image cards (Task D3)
   ============================================================ */
/* (Animation-row styles removed 2026-07-30 — the Veo animated-infographics
   feature was retired; see CHANGELOG.) */


/* ===== components/announcement-carousel.css ===== */
/* Announcement Carousel
 *
 * The popup that surfaces new announcements to a student. The carousel was
 * dashboard-only at first; moved to a shared component once we needed the
 * popup to appear on every page-load (not just login). See
 * /shared/assets/js/announcement-carousel.js for behavior.
 */

.announcement-carousel {
    text-align: left;
}

.announcement-slide {
    display: none;
    padding: var(--space-md) 0;
}

.announcement-slide.active {
    display: block;
}

.announcement-header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.announcement-type-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 4px 12px;
    border-radius: var(--radius-full);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

.announcement-type-badge.info {
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

.announcement-type-badge.warning {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

.announcement-type-badge.success {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.announcement-type-badge.urgent {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.announcement-scope {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    margin-left: auto;
}

.announcement-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-sm);
    color: var(--text-primary);
}

.announcement-content {
    color: var(--text-secondary);
    line-height: 1.6;
}

/* Admin-authored rich text — restore sensible defaults for the tags TinyMCE
   emits. The student carousel inserts content via innerHTML (server-side
   sanitized at save), so normal HTML structure renders. */
.announcement-content p { margin: 0 0 var(--space-sm); }
.announcement-content p:last-child { margin-bottom: 0; }
.announcement-content strong { font-weight: var(--font-weight-bold); color: var(--text-primary); }
.announcement-content em { font-style: italic; }
.announcement-content ul, .announcement-content ol { margin: var(--space-sm) 0; padding-left: var(--space-lg); }
.announcement-content a { color: var(--brand-primary); text-decoration: underline; }

.announcement-attachment {
    margin-top: var(--space-md);
}

.announcement-attachment-image {
    display: block;
    max-width: 100%;
    max-height: 320px;
    margin: 0 auto;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-color);
    cursor: zoom-in;
    transition: transform var(--transition-fast);
}

.announcement-attachment-image:hover {
    transform: scale(1.01);
}

/* Lightbox — fullscreen overlay that opens when a student clicks an inline
   announcement image. Lives at <body> level so it stacks above SweetAlert2's
   own .swal2-container (z-index 1060). */
.ann-lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(0, 0, 0, 0.88);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-xl);
    cursor: zoom-out;
    animation: ann-lightbox-in 150ms ease-out;
}

.ann-lightbox.is-closing {
    animation: ann-lightbox-out 150ms ease-in forwards;
}

@keyframes ann-lightbox-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes ann-lightbox-out { from { opacity: 1; } to { opacity: 0; } }

.ann-lightbox-image {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius-md);
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.5);
    cursor: default;
}

.ann-lightbox-close {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.ann-lightbox-close:hover {
    background: rgba(255, 255, 255, 0.24);
}

.announcement-attachment-download {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--bg-muted);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    text-decoration: none;
    transition: all var(--transition-fast);
}

.announcement-attachment-download:hover {
    background: var(--bg-hover);
    border-color: var(--brand-primary);
    color: var(--brand-primary);
}

.announcement-attachment-name {
    font-weight: var(--font-weight-medium);
}

.announcement-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-lg);
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-color);
}

.carousel-nav-btn {
    background: var(--bg-muted);
    border: none;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all var(--transition-fast);
    color: var(--text-secondary);
}

.carousel-nav-btn:hover:not(:disabled) {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.carousel-nav-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.carousel-dots {
    display: flex;
    gap: var(--space-xs);
}

.carousel-dot {
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    background: var(--bg-muted);
    border: none;
    cursor: pointer;
    transition: all var(--transition-fast);
    padding: 0;
}

.carousel-dot.active {
    background: var(--brand-primary);
    width: 24px;
}

.carousel-counter {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.dismiss-checkbox {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-top: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

.dismiss-checkbox input {
    accent-color: var(--brand-primary);
}


/* ===== components/live-gradebook.css ===== */
/* ============================================================
   Live Gradebook (admin) — students × steps grid
   Cell colours = step status; number = current weighted mark.
   Token-only per lms-ui rules; validated pairs both themes.
   ============================================================ */

.lgb-controls {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.lgb-controls-left,
.lgb-controls-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.lgb-updated {
    color: var(--text-muted);
    font-size: 0.8rem;
    white-space: nowrap;
}

.lgb-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.lgb-chip {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 600;
    border: 1px solid var(--border-color);
}

.lgb-grid-wrap {
    overflow-x: auto;
    max-height: 70vh;
    overflow-y: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
}

.lgb-table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    font-size: 0.85rem;
}

.lgb-table th,
.lgb-table td {
    padding: 0.45rem 0.6rem;
    border-bottom: 1px solid var(--border-color);
    border-right: 1px solid var(--border-color);
    text-align: center;
    white-space: nowrap;
}

.lgb-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--bg-elevated);
    color: var(--text-primary);
    font-weight: 600;
}

.lgb-step-name {
    display: block;
    font-weight: 400;
    color: var(--text-muted);
    font-size: 0.7rem;
    max-width: 9rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lgb-sticky {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--bg-elevated);
    color: var(--text-primary);
    text-align: left;
    font-weight: 600;
}

.lgb-table thead th.lgb-sticky {
    z-index: 3;
}

.lgb-mark {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.lgb-course-col {
    background: var(--bg-active);
    color: var(--text-primary);
}

.lgb-cell-link {
    color: inherit;
    text-decoration: none;
    display: block;
}

.lgb-cell-link:hover {
    text-decoration: underline;
    color: inherit;
}

/* Inside the legend the pill is the chip's first element — no cell margin. */
.lgb-legend .lgb-pending {
    margin-left: 0;
}

.lgb-pending {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0 0.35rem;
    border-radius: var(--radius-sm);
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    font-size: 0.7rem;
    font-weight: 700;
}

/* Cell states — validated background/text token pairs */
.lgb-cell--not-started {
    background: var(--bg-surface);
    color: var(--text-muted);
}

.lgb-cell--in-progress {
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

.lgb-cell--submitted {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

.lgb-cell--reviewed {
    background: var(--bg-active);
    color: var(--text-primary);
}

.lgb-cell--released {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.lgb-cell--no-credit {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}


/* ===== components/database-map.css ===== */
/* ============================================================
   Database Map (admin Settings) — live schema visualization
   Clusters of table cards + SVG FK edges coloured by ON DELETE.
   Token-only per lms-ui rules; validated pairs both themes.
   ============================================================ */

.dbmap-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.dbmap-toolbar-left,
.dbmap-toolbar-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.dbmap-meta {
    color: var(--text-muted);
    font-size: 0.78rem;
    white-space: nowrap;
}

.dbmap-legend {
    display: inline-flex;
    gap: 0.6rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.dbmap-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.dbmap-swatch {
    display: inline-block;
    width: 14px;
    height: 3px;
    border-radius: 2px;
}

.dbmap-swatch--cascade { background: var(--color-danger-text); }
.dbmap-swatch--setnull { background: var(--color-warning-text); }
.dbmap-swatch--restrict { background: var(--text-muted); }

.dbmap-body {
    position: relative;
    padding: 0;
}

.dbmap-viewport {
    position: relative;
    overflow: hidden;
    height: 72vh;
    background: var(--bg-body);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    cursor: grab;
}

.dbmap-viewport--dragging {
    cursor: grabbing;
    user-select: none;
}

.dbmap-world {
    position: relative;
    transform-origin: 0 0;
    width: max-content;
    min-width: 100%;
    padding: 1.25rem;
}

.dbmap-edges {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    overflow: visible;
}

.dbmap-edges--hidden { display: none; }

.dbmap-edge {
    fill: none;
    stroke-width: 1.25;
    opacity: 0.35;
    pointer-events: stroke;
}

.dbmap-edge--cascade { stroke: var(--color-danger-text); }
.dbmap-edge--setnull { stroke: var(--color-warning-text); }
.dbmap-edge--restrict { stroke: var(--text-muted); }

.dbmap-edge--dim { opacity: 0.05; }

.dbmap-edge--hot {
    opacity: 0.95;
    stroke-width: 2.25;
}

.dbmap-clusters {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, minmax(230px, 1fr));
    gap: 1rem;
    z-index: 1;
}

.dbmap-cluster {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.75rem;
    align-self: start;
}

.dbmap-cluster h4 {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0 0 0.6rem;
}

.dbmap-cluster-count {
    color: var(--text-muted);
    font-weight: 400;
}

.dbmap-cluster-tables {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.dbmap-table {
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.35rem 0.55rem;
    cursor: pointer;
    transition: opacity 0.15s ease, border-color 0.15s ease;
}

.dbmap-table:hover {
    border-color: var(--brand-primary);
}

.dbmap-table--dim { opacity: 0.25; }

.dbmap-table--focus {
    border-color: var(--brand-primary);
    box-shadow: 0 0 0 2px var(--brand-primary);
}

.dbmap-table-name {
    display: block;
    font-family: var(--font-mono, monospace);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-primary);
    word-break: break-all;
}

.dbmap-table-meta {
    display: block;
    font-size: 0.68rem;
    color: var(--text-muted);
}

/* ---- Focus drawer ---- */

.dbmap-drawer {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(430px, 90%);
    background: var(--bg-elevated);
    border-left: 1px solid var(--border-color);
    box-shadow: var(--shadow-lg, 0 0 24px rgba(0, 0, 0, 0.25));
    z-index: 5;
    display: flex;
    flex-direction: column;
}

.dbmap-drawer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
}

.dbmap-drawer-header h3 {
    margin: 0;
    font-family: var(--font-mono, monospace);
    font-size: 1rem;
    color: var(--text-primary);
    word-break: break-all;
}

.dbmap-drawer-body {
    padding: 0.75rem 1rem 1.25rem;
    overflow-y: auto;
}

.dbmap-drawer-sub {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin-bottom: 0.75rem;
}

.dbmap-drawer-body h4 {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
    margin: 1rem 0 0.4rem;
}

.dbmap-cols {
    width: 100%;
    font-size: 0.78rem;
    border-collapse: collapse;
}

.dbmap-cols th {
    text-align: left;
    color: var(--text-secondary);
    font-weight: 600;
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color);
}

.dbmap-cols td {
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}

.dbmap-col-name {
    font-family: var(--font-mono, monospace);
    color: var(--text-primary);
    word-break: break-all;
}

.dbmap-col-type {
    color: var(--text-muted);
    font-family: var(--font-mono, monospace);
    font-size: 0.72rem;
    word-break: break-all;
}

.dbmap-notnull {
    color: var(--color-danger-text);
    font-weight: 700;
}

.dbmap-rel-list {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.78rem;
}

.dbmap-rel-list li {
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-secondary);
}

.dbmap-rel-link {
    color: var(--brand-primary);
    font-family: var(--font-mono, monospace);
    text-decoration: none;
}

.dbmap-rel-link:hover { text-decoration: underline; }

/* ---- Badges ---- */

.dbmap-badge {
    display: inline-block;
    padding: 0.05rem 0.35rem;
    border-radius: var(--radius-sm);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    margin-left: 0.2rem;
    white-space: nowrap;
}

.dbmap-badge--pk {
    background: var(--brand-primary);
    color: var(--text-on-brand);
}

.dbmap-badge--uni {
    background: var(--color-info-bg);
    color: var(--color-info-text);
}

.dbmap-badge--idx {
    background: var(--bg-active);
    color: var(--text-primary);
}

.dbmap-badge--gen {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.dbmap-badge--enc {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.dbmap-badge--cascade {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.dbmap-badge--setnull {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

/* ---- Focus mode (mini-ERD of one table's neighborhood) ---- */

.dbmap-drawer-actions {
    display: flex;
    gap: 0.4rem;
}

.dbmap-focus-grid {
    position: relative;
    display: grid;
    grid-template-columns: minmax(260px, 1fr) minmax(300px, auto) minmax(260px, 1fr);
    gap: 4rem;
    align-items: start;
    z-index: 1;
    padding: 0.5rem;
}

.dbmap-focus-side {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.dbmap-focus-center {
    align-self: center;
}

.dbmap-focus-label {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.dbmap-erd-card {
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    cursor: pointer;
    max-width: 380px;
}

.dbmap-erd-card--center {
    border-color: var(--brand-primary);
    box-shadow: 0 0 0 2px var(--brand-primary);
    cursor: default;
}

.dbmap-erd-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    background: var(--bg-active);
    color: var(--text-primary);
    font-family: var(--font-mono, monospace);
    font-size: 0.82rem;
    font-weight: 700;
    padding: 0.4rem 0.6rem;
    border-bottom: 1px solid var(--border-color);
    word-break: break-all;
}

.dbmap-erd-more {
    color: var(--text-muted);
    font-size: 0.7rem;
}

.dbmap-erd-col {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.2rem 0.6rem;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.74rem;
    white-space: nowrap;
}

.dbmap-erd-col:last-child {
    border-bottom: none;
}

.dbmap-erd-colname {
    font-family: var(--font-mono, monospace);
    color: var(--text-primary);
}

.dbmap-erd-coltype {
    font-family: var(--font-mono, monospace);
    color: var(--text-muted);
    font-size: 0.68rem;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 11rem;
}

.dbmap-erd-col--more {
    color: var(--text-muted);
    font-style: italic;
}

.dbmap-edge--focus {
    opacity: 0.75;
    stroke-width: 1.75;
}

.dbmap-edge-label {
    fill: var(--text-muted);
    font-size: 10px;
    font-weight: 600;
    text-anchor: middle;
}


/* ===== components/ai-marking.css ===== */
/* ============================================================
   AI Marking (admin) — suggestion card on grade.php + AI status
   chips on submissions lists. Token-only per lms-ui rules;
   validated pairs both themes. docs/planned/ai-marking.md
   ============================================================ */

.ai-suggestion-card {
    background: var(--bg-elevated);
    border: 1px solid var(--brand-primary);
    border-radius: 8px;
    padding: 1rem 1.25rem;
    margin-bottom: 1.25rem;
}

.ai-suggestion-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.ai-suggestion-title {
    color: var(--brand-primary);
    font-weight: 600;
}

.ai-suggested-score {
    color: var(--text-primary);
    font-size: 1.1rem;
    margin: 0.5rem 0;
}

.ai-criteria-table {
    width: 100%;
    margin: 0.5rem 0;
    font-size: 0.9rem;
    color: var(--text-primary);
}

.ai-criteria-table th {
    color: var(--text-secondary);
    text-align: left;
    padding: 0.25rem 0.5rem;
}

.ai-criteria-table td {
    padding: 0.25rem 0.5rem;
    border-top: 1px solid var(--card-border);
    vertical-align: top;
}

.ai-reasoning,
.ai-suggestion-meta,
.ai-suggestion-empty {
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* An item the AI could not check: starred on the AI card and the marking form. */
.ai-teacher-check {
    color: var(--color-warning-text);
}

/* A draft made under older marking rules (audit B17): information only. */
.ai-teacher-check-note,
.ai-older-note {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0.25rem 0 0.5rem;
}

.ai-feedback-preview,
.ai-private-note {
    background: var(--bg-surface);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    margin: 0.5rem 0;
    color: var(--text-primary);
    font-size: 0.9rem;
}

.ai-attention {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-radius: 6px;
    padding: 0.5rem 0.8rem;
    margin-bottom: 0.5rem;
}

.ai-suggestion-actions {
    display: flex;
    gap: 0.5rem;
    margin: 0.75rem 0 0.25rem;
}

/* Status chips (submissions lists + card head) */
.ai-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 10px;
    font-size: 0.75rem;
    font-weight: 600;
}

.ai-badge.ai-complete { background: var(--brand-primary-alpha); color: var(--brand-primary); }
.ai-badge.ai-queued,
.ai-badge.ai-processing { background: var(--color-info-bg); color: var(--color-info-text); }
.ai-badge.ai-failed { background: var(--color-danger-bg); color: var(--color-danger-text); }
.ai-badge.ai-skipped { background: var(--color-warning-bg); color: var(--color-warning-text); }
/* Checks that couldn't run: the teacher's to check, neither pass nor fail (audit A4) */
.ai-badge.ai-teacher { background: var(--bg-hover); color: var(--text-primary); }


/* ===== components/comm-sim-review.css ===== */
/* ============================================================
   Communication Simulator — Teacher Review (grade.php)
   Scenario summary card, transcript thread, session stats,
   and the coaching card teachers see on grade.php. Token-only
   per lms-ui rules; validated pairs both themes. Mirrors the
   accent tokens the student-facing coaching panel uses
   (src/frontend/comm-sim/src/styles/comm-sim.css).
   ============================================================ */

/* ─── Scenario summary card ─────────────────────────────── */

.comm-sim-review-scenario {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.comm-sim-review-scenario-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
}

.comm-sim-review-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    background: var(--color-info-bg);
    color: var(--color-info-text);
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

.comm-sim-review-counterpart {
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.comm-sim-review-field-label {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: var(--space-xs);
}

.comm-sim-review-field-value {
    color: var(--text-primary);
    line-height: var(--line-height-relaxed);
}

.comm-sim-review-objectives {
    margin: 0;
    padding-left: 1.25rem;
    color: var(--text-primary);
    line-height: var(--line-height-relaxed);
}

.comm-sim-review-teacher-note {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-radius: var(--radius-md);
    padding: var(--space-md);
}

.comm-sim-review-teacher-note .comm-sim-review-field-label,
.comm-sim-review-teacher-note .comm-sim-review-field-value {
    color: var(--color-warning-text);
}

/* ─── Transcript thread ──────────────────────────────────── */

.comm-sim-review-thread {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.comm-sim-review-msg {
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-md);
    max-width: 85%;
}

.comm-sim-review-msg.is-student {
    background: var(--bg-elevated);
    color: var(--text-primary);
    align-self: flex-end;
}

.comm-sim-review-msg.is-counterpart {
    background: var(--bg-hover);
    color: var(--text-primary);
    align-self: flex-start;
}

.comm-sim-review-msg-meta {
    display: flex;
    gap: var(--space-sm);
    align-items: baseline;
    margin-bottom: var(--space-xs);
}

.comm-sim-review-msg-speaker {
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

.comm-sim-review-msg-time {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

.comm-sim-review-msg-subject {
    font-weight: var(--font-weight-bold);
    margin-bottom: var(--space-xs);
}

.comm-sim-review-msg-text {
    line-height: var(--line-height-relaxed);
    white-space: pre-wrap;
    word-break: break-word;
}

/* ─── Session stats line ─────────────────────────────────── */

.comm-sim-review-stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin-top: var(--space-md);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-light);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.comm-sim-review-stats span {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

.comm-sim-review-stats-note {
    margin: var(--space-xs) 0 0;
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

/* ─── Coaching card ───────────────────────────────────────── */

.comm-sim-review-coaching-section {
    margin-bottom: var(--space-md);
}

.comm-sim-review-coaching-section:last-child {
    margin-bottom: 0;
}

.comm-sim-review-coaching-section h4 {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.comm-sim-review-coaching-worked ul {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.comm-sim-review-coaching-worked li {
    color: var(--color-success-text);
    line-height: var(--line-height-relaxed);
}

.comm-sim-review-coaching-item {
    background: var(--bg-elevated);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-sm);
}

.comm-sim-review-coaching-item:last-child {
    margin-bottom: 0;
}

.comm-sim-review-coaching-item blockquote {
    margin: 0 0 var(--space-sm);
    background: var(--bg-hover);
    color: var(--text-primary);
    border-left: 3px solid var(--border-medium);
    border-radius: var(--radius-sm);
    padding: var(--space-sm) var(--space-md);
    font-style: italic;
}

.comm-sim-review-coaching-item p {
    margin: 0;
    color: var(--text-secondary);
    line-height: var(--line-height-relaxed);
}

.comm-sim-review-coaching-better {
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
    background: var(--color-info-bg);
    color: var(--color-info-text);
    border-radius: var(--radius-sm);
    padding: var(--space-sm) var(--space-md);
    margin-top: var(--space-sm);
}

.comm-sim-review-coaching-better-label {
    flex-shrink: 0;
    font-weight: var(--font-weight-semibold);
}

.comm-sim-review-coaching-trynext p {
    margin: 0;
    background: var(--color-success-bg);
    color: var(--color-success-text);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    line-height: var(--line-height-relaxed);
}

.comm-sim-review-coaching-error {
    color: var(--color-danger-text);
    font-size: var(--font-size-sm);
}

/* ─── Shared empty/fallback text ─────────────────────────── */

.comm-sim-review-empty {
    color: var(--text-muted);
    font-style: italic;
}


/* ===== components/notebook.css ===== */
/* ============================================================
   Student Notebook drawer (docs/implemented/student-notebook.md)
   Right-edge handle + non-modal drawer. Push layout ≥1200px,
   overlay below. Student site only (ids/classes are unique;
   this file ships in the shared bundle like all components).
   ============================================================ */

:root {
    --notebook-width: 400px;
}

/* --- Handle: fixed vertical tab on the right edge --- */
.notebook-handle {
    position: fixed;
    right: 0;
    top: 40%;
    z-index: 1035; /* under the drawer; both under SweetAlert2 (1060+) */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 12px 8px;
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-right: none;
    border-radius: 8px 0 0 8px;
    cursor: pointer;
}
.notebook-handle:hover {
    background: var(--bg-hover);
}
.notebook-handle-label {
    writing-mode: vertical-rl;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
body.notebook-open .notebook-handle {
    display: none;
}

/* --- Drawer --- */
.notebook-drawer {
    position: fixed;
    top: 0;
    right: 0;
    width: var(--notebook-width);
    max-width: 100vw;
    height: 100vh;
    height: 100dvh;
    z-index: 1040;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border-left: 1px solid var(--border-color);
    transform: translateX(100%);
    transition: transform 0.25s ease;
}
/* Author-origin display:flex above would otherwise beat the UA sheet's
   [hidden]{display:none} (origin outranks specificity) — restate it so the
   closed drawer is genuinely display:none: out of the tab order and the
   accessibility tree, not just translated off-screen. */
.notebook-drawer[hidden] {
    display: none;
}
body.notebook-open .notebook-drawer {
    transform: translateX(0);
}

.notebook-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
}
.notebook-title {
    margin: 0;
    font-size: 1rem;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 8px;
}
.notebook-title i {
    color: var(--brand-primary);
}
.notebook-close {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 1.1rem;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
}
.notebook-close:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

/* --- Always-visible actions row: Add section / Open full screen / Export
   PDF. Separate from .notebook-toolbar below, which HIDES itself when the
   student has at most one section — these three controls must stay
   reachable regardless of section count (Add Section is how a student with
   zero or one section gets to two). --- */
.notebook-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-color);
}
.notebook-add-btn {
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 0.8rem;
    cursor: pointer;
    white-space: nowrap;
}
.notebook-add-btn:hover {
    background: var(--bg-hover);
}
.notebook-actions a {
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 0.8rem;
    text-decoration: none;
    white-space: nowrap;
}
.notebook-actions a:hover {
    background: var(--bg-hover);
}

.notebook-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-color);
}
/* Same UA-sheet footgun as .notebook-drawer[hidden] above: the author-origin
   display:flex outranks the UA sheet's [hidden]{display:none} by origin, not
   specificity, so it must be restated here for the toolbar to actually
   disappear (not just collapse to an empty flex row) once section count
   drops to <= 1. */
.notebook-toolbar[hidden] {
    display: none;
}
.notebook-section-label {
    font-size: 0.8rem;
    color: var(--text-muted);
}
.notebook-section-select {
    flex: 1;
    min-width: 0;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 0.85rem;
}
.notebook-viewall-btn {
    background: var(--bg-input);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 0.8rem;
    cursor: pointer;
    white-space: nowrap;
}
.notebook-viewall-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.notebook-viewall-btn[aria-pressed="true"] {
    background: var(--brand-primary);
    color: var(--text-on-brand);
    border-color: var(--brand-primary);
}

.notebook-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 16px;
}
.notebook-editor-wrap {
    height: 100%;
}

/* Read-only ink preview: shown instead of the editor when the current
   section is kind='ink'. Drawing/editing pages is Task 9's; this is just a
   snapshot list plus a way out to the full-screen page. */
.notebook-ink-preview {
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 12px 14px;
}
.notebook-ink-preview ol {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.notebook-ink-preview img {
    max-width: 100%;
    display: block;
    border: 1px solid var(--border-color);
    border-radius: 6px;
}
.notebook-ink-preview a {
    color: var(--brand-primary);
    font-size: 0.85rem;
}

/* Missing-snapshot recovery (Task 11): swapped in for a page's <img> on load
   error (a 404'd snapshot — half-failed save, lost file) instead of a
   broken-image icon. Same "Open full screen to write" affordance the
   zero-pages empty state already offers. Used both here and in the
   read-only "View all" pane's ink pages (.notebook-viewall-content ol). */
.notebook-ink-missing-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
    background: var(--bg-elevated);
    border: 1px dashed var(--border-color);
    border-radius: 6px;
    padding: 16px 12px;
    color: var(--text-muted);
}
.notebook-ink-missing-card i {
    font-size: 1.25rem;
    color: var(--text-muted);
}
.notebook-ink-missing-card p {
    margin: 0;
    font-size: 0.8rem;
}
.notebook-ink-missing-card a {
    color: var(--brand-primary);
    font-size: 0.85rem;
}

/* Read-only "View all" study mode */
.notebook-viewall-section {
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 12px 14px;
    margin-bottom: 12px;
}
.notebook-viewall-section h3 {
    margin: 0 0 8px;
    font-size: 0.9rem;
    color: var(--brand-primary);
}
.notebook-viewall-section .notebook-viewall-content {
    color: var(--text-primary);
    font-size: 0.9rem;
    line-height: 1.6;
    overflow-wrap: break-word;
}
/* Ink pages inside View all share pageListItemEl()'s markup with
   .notebook-ink-preview above (notebook-sections.js) but had no sizing rule
   of their own — an unstyled <img> of the 2000px-wide snapshot PNG would
   render at natural size and overflow the card. Same list/image treatment
   as .notebook-ink-preview, scoped to this pane. */
.notebook-viewall-content ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.notebook-viewall-content img {
    max-width: 100%;
    display: block;
    border: 1px solid var(--border-color);
    border-radius: 6px;
}

.notebook-footer {
    padding: 8px 16px;
    border-top: 1px solid var(--border-color);
}
.notebook-status {
    font-size: 0.78rem;
    color: var(--text-muted);
}
.notebook-status.is-saving {
    color: var(--text-secondary);
}
.notebook-status.is-error {
    color: var(--color-danger-text);
}

/* --- Push layout on wide screens ---
   .student-main is `max-width: 1400px; width: 100%; margin: 0 auto`
   (header.php) — a bare margin-right only reclaims the few px of slack the
   viewport leaves beyond 1400, so content stayed under the drawer at common
   desktop widths (measured live: 120px of card + 392px of canvas under the
   drawer at 1440px). The open state must CAP the width to what actually
   clears the drawer; the auto left margin then soaks up any remainder. The
   1400px in min() mirrors header.php's base value. */
.student-main {
    transition: margin-right 0.25s ease, max-width 0.25s ease;
}
@media (min-width: 1200px) {
    body.notebook-open .student-main {
        max-width: min(1400px, calc(100% - var(--notebook-width)));
        margin-right: var(--notebook-width);
    }
}

@media (prefers-reduced-motion: reduce) {
    .notebook-drawer,
    .student-main {
        transition: none;
    }
}


/* ===== components/notebook-page.css ===== */
/* ============================================================
   Full-screen Student Notebook page (docs/superpowers/specs/
   2026-07-28-notebook-extensions-design.md; php/notebook.php).

   Two-pane layout — sidebar of sections + main editing surface —
   for the classroom's second-monitor use case (notebook on one
   screen, course material on the other). Distinct from the 400px
   drawer strip (components/notebook.css): this is a full-window
   surface, so it gets its own component file. `.notebook-status`
   (used for #notebookPageStatus) is intentionally NOT redefined
   here — it already ships in components/notebook.css and both
   files load in the same bundle.
   ============================================================ */

.notebook-page {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: var(--space-lg);
    align-items: stretch;
    min-height: 70vh;
}

/* --- Sidebar: section list --- */
.notebook-page-sidebar {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.notebook-page-sidebar-header {
    padding: var(--space-md) var(--space-lg);
    border-bottom: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.notebook-page-title {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}
.notebook-page-title i {
    color: var(--brand-primary);
}

/* Add-section control (Task 9) — same name/wording as the drawer's
   .notebook-add-btn (components/notebook.css), styled with this page's own
   tokens so it sits naturally in the sidebar header. */
.notebook-page-add-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    width: 100%;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background var(--transition-fast);
}
.notebook-page-add-btn:hover {
    background: var(--bg-hover);
}
.notebook-page-add-btn:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

.notebook-page-list {
    list-style: none;
    margin: 0;
    padding: var(--space-sm);
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.notebook-page-list-empty {
    padding: var(--space-md);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    line-height: 1.5;
}

/* Each row pairs the section-select button with its own move/rename/delete
   controls (Task 9) — buttons, not drag, so reordering stays keyboard- and
   touch-operable without extra work. */
.notebook-page-row {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.notebook-page-list-btn {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    flex: 1;
    min-width: 0;
    text-align: left;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-md);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}
.notebook-page-list-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.notebook-page-list-btn:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}
.notebook-page-list-btn.active {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
}
.notebook-page-list-btn i {
    width: 16px;
    text-align: center;
    flex-shrink: 0;
}
.notebook-page-list-btn span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.notebook-page-row-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
}
.notebook-page-row-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}
.notebook-page-row-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.notebook-page-row-btn:disabled {
    cursor: not-allowed;
    opacity: 0.35;
}
.notebook-page-row-btn.is-danger:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.notebook-page-sidebar-footer {
    padding: var(--space-sm) var(--space-lg);
    border-top: 1px solid var(--border-color);
}
.notebook-page-export-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--text-secondary);
    text-decoration: none;
    font-size: var(--font-size-sm);
}
.notebook-page-export-link:hover {
    color: var(--brand-primary);
}

/* --- Main pane: editor or ink placeholder --- */
.notebook-page-main {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
}

.notebook-page-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: var(--space-sm) var(--space-lg);
    border-bottom: 1px solid var(--border-color);
    flex-shrink: 0;
}

.notebook-page-body {
    flex: 1;
    min-height: 0;
    padding: var(--space-lg);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.notebook-page-editor-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* Base state: an empty dashed box, only ever visible for the rare case
   DCSNotebook.pageInk.mount() bails before building anything (see its
   !dcs.ink/!dcs.api guard). The moment mount() succeeds it adds .is-active
   below, which replaces this look entirely with the real toolbar/canvas/
   page-strip — there is no separate "loading" placeholder state, since
   buildShellDom() runs synchronously before any network request starts. */
.notebook-page-ink-wrap {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-elevated);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
    padding: var(--space-2xl);
}
/* Task 11: the real mounted ink UI (page strip + dcs.ink.mount()'s own
   toolbar/canvas) replaces the placeholder look above — no dashed border,
   no padding eating into canvas space, no centering a shrink-wrapped child. */
.notebook-page-ink-wrap.is-active {
    display: block;
    padding: 0;
    border: none;
    background: none;
}

.notebook-ink-page-shell {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    min-height: 0;
}

.notebook-ink-mount-target {
    flex: 1;
    min-height: 0;
}

.notebook-ink-page-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    flex-shrink: 0;
    padding-top: var(--space-sm);
    border-top: 1px solid var(--border-color);
}

.notebook-ink-page-strip-list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
}

.notebook-ink-page-strip-btn-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 var(--space-xs);
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}
.notebook-ink-page-strip-btn-num:hover {
    background: var(--bg-hover);
}
.notebook-ink-page-strip-btn-num:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}
.notebook-ink-page-strip-btn-num.active {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.notebook-ink-page-strip-actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
}

.notebook-ink-page-strip-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: var(--space-xs) var(--space-sm);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
    white-space: nowrap;
}
.notebook-ink-page-strip-btn:hover {
    background: var(--bg-hover);
}
.notebook-ink-page-strip-btn:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}
.notebook-ink-page-strip-btn.is-danger:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

@media (max-width: 700px) {
    .notebook-ink-page-strip {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ============================================================
   Ink canvas engine (Task 10; shared/assets/js/notebook-ink.js).

   DCSNotebook.ink.mount() builds this structure (toolbar + canvas
   wrap) inside whatever container it's given — here, that's
   #notebookPageInkWrap once Task 11 wires mountInk() to it, but
   the engine itself makes no assumption about its host. Sized to
   fill its container explicitly (width/height: 100%) rather than
   relying on the parent's centering, since .notebook-page-ink-wrap
   above centers a shrink-wrapped child by default.

   Ink/paper colours use the --notebook-paper*/--notebook-ink-*
   tokens (core/tokens.css) — the declared, teacher-ratified
   exception to the no-raw-colour rule: identical in both themes,
   because a handwriting page is paper and gets printed. Everything
   else here (toolbar chrome, buttons, gutter) uses ordinary
   theme-aware tokens like the rest of the design system.
   ============================================================ */
.notebook-ink {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    min-height: 0;
}

.notebook-ink-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-md);
    flex-shrink: 0;
}

.notebook-ink-tool-group,
.notebook-ink-color-group,
.notebook-ink-size-group,
.notebook-ink-history-group {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding-right: var(--space-md);
    border-right: 1px solid var(--border-color);
}
.notebook-ink-history-group {
    border-right: none;
    padding-right: 0;
}

.notebook-ink-tool-btn,
.notebook-ink-history-btn,
.notebook-ink-size-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: var(--bg-input);
    color: var(--input-text);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}
.notebook-ink-tool-btn:hover,
.notebook-ink-history-btn:hover,
.notebook-ink-size-btn:hover {
    background: var(--bg-hover);
}
.notebook-ink-tool-btn.active,
.notebook-ink-size-btn.active {
    background: var(--brand-primary-alpha);
    color: var(--brand-primary);
    border-color: var(--brand-primary);
}
.notebook-ink-history-btn.is-danger:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.notebook-ink-color-btn {
    width: 24px;
    height: 24px;
    border-radius: var(--radius-full);
    border: 2px solid var(--border-color);
    cursor: pointer;
    padding: 0;
}
.notebook-ink-color-btn.active {
    border-color: var(--brand-primary);
    box-shadow: var(--focus-ring);
}
.notebook-ink-color-ink { background: var(--notebook-ink-ink); }
.notebook-ink-color-blue { background: var(--notebook-ink-blue); }
.notebook-ink-color-red { background: var(--notebook-ink-red); }
.notebook-ink-color-green { background: var(--notebook-ink-green); }

.notebook-ink-canvas-wrap {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-elevated);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.notebook-ink-canvas {
    /* Sized in JS (CSS width/height) to fit notebook-ink-canvas-wrap at the
       fixed 1000:1294 logical page ratio; the paper/border look comes from
       the declared ink-page exception, not a theme token. */
    background: var(--notebook-paper);
    border: 1px solid var(--notebook-paper-line);
    box-shadow: var(--shadow-md);
    touch-action: none; /* the engine owns all pointer gestures on this canvas */
}

@media (max-width: 900px) {
    .notebook-page {
        grid-template-columns: 1fr;
    }
    .notebook-page-sidebar {
        max-height: 260px;
    }
}


/* ===== components/drills.css ===== */
/* Email Etiquette Drills (docs/superpowers/specs/2026-07-29-email-drills-design.md) */

.drill-card { padding: var(--space-lg); margin: var(--space-lg) 0; }

.drill-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm); flex-wrap: wrap; }
.drill-title { margin: 0; color: var(--text-primary); }

.drill-scenario { color: var(--text-secondary); margin: var(--space-sm) 0 var(--space-md); }
.drill-loading, .drill-unavailable { color: var(--text-muted); margin: 0; }

.drill-context-email { background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-md); margin-bottom: var(--space-md); }
.drill-context-meta { color: var(--text-muted); font-size: 0.85rem; margin-bottom: var(--space-sm); }
.drill-context-body { color: var(--text-primary); }

.drill-people { margin-bottom: var(--space-md); }
.drill-people-label { color: var(--text-muted); font-size: 0.85rem; margin-bottom: var(--space-xs); }
.drill-people-chips { display: flex; flex-wrap: wrap; gap: var(--space-sm); }

.drill-chip { display: inline-flex; align-items: center; gap: var(--space-sm); background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-xs) var(--space-sm); color: var(--text-primary); }
.drill-chip-who { display: flex; flex-direction: column; }
.drill-chip small { display: block; color: var(--text-muted); }
.drill-chip-placed { opacity: 0.55; }
.drill-chip-actions { display: inline-flex; gap: var(--space-xs); }
.drill-chip-add { background: var(--bg-hover); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 2px var(--space-sm); cursor: pointer; font-size: 0.8rem; }
.drill-chip-add:hover { background: var(--bg-active); }
.drill-chip-assigned { background: var(--bg-hover); }
.drill-chip-remove { background: none; border: none; color: var(--text-primary); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 2px; }

.drill-field-row { display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-xs) 0; border-bottom: 1px solid var(--border-color); }
.drill-field-label { flex: 0 0 4rem; color: var(--text-muted); }
.drill-field-chips { display: flex; flex-wrap: wrap; gap: var(--space-xs); flex: 1; min-height: 1.75rem; }
.drill-subject-input { flex: 1; background: var(--bg-input); color: var(--input-text); border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: var(--space-xs) var(--space-sm); }
.drill-subject-input::placeholder { color: var(--input-placeholder); }

.drill-mark { flex: 0 0 1.5rem; text-align: center; font-weight: 700; }
.drill-mark-ok { color: var(--color-success-text); }
.drill-mark-bad { color: var(--color-danger-text); }

.drill-hint { color: var(--color-danger-text); font-size: 0.9rem; margin: var(--space-xs) 0 var(--space-sm) 4.5rem; }

.drill-actions { display: flex; gap: var(--space-sm); margin-top: var(--space-md); }

/* .badge/.alert both set their own `display` (inline-flex / flex), which beats
   the UA [hidden] rule (author styles win over UA styles regardless of
   specificity) — without this override these three stay visibly rendered
   while `hidden` is true. Same footgun this repo has already hit twice in
   notebook.css. */
.drill-passed-badge[hidden],
.drill-takeaway[hidden],
.drill-error-strip[hidden] { display: none; }

@media (max-width: 640px) {
    .drill-field-row { flex-wrap: wrap; }
    .drill-hint { margin-left: 0; }
}


/* ===== components/raise-hand.css ===== */
/* ===================================================================
   Raise Hand FAB
   The floating "Raise Hand" help control, extracted 2026-08-31 from
   course.php's inline styles so the activity-page control
   (includes/activity_help_fab.php) renders identically. One class,
   two consumers:
     - course.php (course-level polling wiring)
     - includes/activity_help_fab.php (skill checks, assignments,
       check-ins, practical exams, pages, question sets)
   =================================================================== */

.raise-hand-fab {
    position: fixed;
    bottom: var(--space-xl);
    right: var(--space-xl);
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    border-radius: var(--radius-full);
    border: none;
    cursor: pointer;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    transition: all var(--transition-base);
    box-shadow: var(--shadow-lg);
}

.raise-hand-fab:not(.raised) {
    background: var(--brand-primary);
    color: #fff;
}

.raise-hand-fab:not(.raised):hover {
    background: var(--brand-primary-dark);
    transform: translateY(-2px);
    box-shadow: var(--shadow-xl);
}

.raise-hand-fab.raised {
    background: var(--color-warning);
    color: #1a1a1a;
    animation: pulse-hand 2s ease-in-out infinite;
}

.raise-hand-fab.raised:hover {
    background: #e6a000;
    transform: translateY(-2px);
    box-shadow: var(--shadow-xl);
}

@keyframes pulse-hand {
    0%, 100% {
        box-shadow: var(--shadow-lg), 0 0 0 0 rgba(251, 191, 36, 0.4);
    }
    50% {
        box-shadow: var(--shadow-lg), 0 0 0 8px rgba(251, 191, 36, 0);
    }
}

.raise-hand-fab .hand-icon {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.raise-hand-fab .hand-icon svg,
.raise-hand-fab .hand-icon img {
    width: 100%;
    height: 100%;
}

.raise-hand-fab .hand-icon i {
    font-size: 1.25rem;
}

.raise-hand-fab .hand-icon img {
    object-fit: contain;
}

.raise-hand-fab:disabled {
    opacity: 0.7;
    cursor: wait;
}

/* Self-contained spinner keyframes: course.php defines a page-local
   `spin`, but activity pages have no such definition, so the component
   carries its own name. */
.raise-hand-fab .spinner {
    width: 16px;
    height: 16px;
    border: 2px solid transparent;
    border-top-color: currentColor;
    border-radius: 50%;
    animation: raise-hand-spin 0.6s linear infinite;
}

@keyframes raise-hand-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Mobile responsiveness for raise hand */
@media (max-width: 768px) {
    .raise-hand-fab {
        bottom: var(--space-md);
        right: var(--space-md);
        padding: var(--space-sm) var(--space-md);
    }

    .raise-hand-fab .hand-text {
        display: none;
    }

    .raise-hand-fab .hand-icon {
        width: 36px;
        height: 36px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .raise-hand-fab {
        transition: none;
    }

    .raise-hand-fab:not(.raised):hover,
    .raise-hand-fab.raised:hover {
        transform: none;
    }

    .raise-hand-fab.raised {
        animation: none;
    }
}


/* ===== components/doc-example.css ===== */
/* ===================================================================
   Doc-Example — finished-document mock
   Shows students WHAT the finished Office document should look like
   (spec: docs/superpowers/specs/2026-08-31-doc-example-component-design.md).
   Document-only + slim app bar; deliberately NO ribbon/menu/window chrome.

   SANCTIONED THEME EXCEPTION: the document body surfaces are white with
   near-black text in BOTH themes — they depict a printed/on-screen
   artifact (same rationale as the notebook ink palette). The bar and
   caption use normal theme tokens.

   REAL-CASCADE HARDENING (2026-08-31 final review): these mocks render
   inside `.instructions-content.activity-content` on task pages, and
   content/activity-content.css is a SEPARATE stylesheet linked AFTER this
   bundle — it wins every (0,1,1)/(0,2,1)-specificity tie against a plain
   `.doc-example-page h3` / `.doc-example-page th` selector simply because
   it loads later. Every rule below that repaints color/background/border/
   padding on a heading or table cell also carries a `.doc-example`-
   ancestor-prefixed "hardening" twin (two classes, (0,2,1)) so it
   structurally OUTRANKS activity-content's (0,1,1) selectors instead of
   merely tying with them — no `!important` anywhere. `text-align` is
   deliberately left ONLY at the original (unprefixed, (0,1,1)) specificity
   throughout: its value already matches activity-content's own "left", and
   raising it would let a hardening rule outrank the `.de-center`/
   `.de-right` utilities below (both (0,2,0), correctly undefeated today).

   Table backgrounds paint CELL over ROW (CSS 2.1 §17.5.1) regardless of
   which selector "wins" the row's own background — so once every ordinary
   td/th below has its own explicit, winning background (the hardening
   rules), activity-content's `tr:nth-child(even)`/`tr:hover` striping can
   never show through; no extra "neutralizer" selector is needed for that.
   The one place a cell's OWN background can still lose is to another
   doc-example rule for the SAME cell — that's the `de-shaded` self-
   conflict fixed below.
   =================================================================== */

.doc-example {
    margin: var(--space-lg) 0;
    max-width: 720px;
}

.doc-example-bar {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    color: var(--text-on-brand);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    font-family: var(--font-family-mono, monospace);
}

.doc-example--word       .doc-example-bar { background: var(--office-word); }
.doc-example--excel      .doc-example-bar { background: var(--office-excel); }
.doc-example--powerpoint .doc-example-bar { background: var(--office-powerpoint); }
.doc-example--access     .doc-example-bar { background: var(--office-access); }

/* ---- Shared body surface: the white "artifact" (theme exception) ---- */
.doc-example-page,
.doc-example-sheet,
.doc-example-slide,
.doc-example-datasheet {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid var(--border-medium);
    border-top: none;
    overflow-x: auto;
    /* activity-content.css centres <figure> content (image figures); a
       document body is left-aligned by default — without this line every
       paragraph in every mock inherited centring. de-center/de-right still
       override per element. */
    text-align: left;
}

.doc-example-caption {
    padding: var(--space-sm) var(--space-md);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    font-style: italic;
}

/* ---- Word: printed page ---- */
.doc-example-page {
    padding: var(--space-2xl) var(--space-2xl);
    font-family: Georgia, 'Times New Roman', serif;
    font-size: var(--font-size-sm);
    line-height: 1.5;
}

.doc-example-page h1, .doc-example-page h2, .doc-example-page h3,
.doc-example-page p, .doc-example-page ul, .doc-example-page ol {
    color: #1a1a1a;
    margin: 0 0 0.75em 0;
}

/* Hardening: activity-content.css repaints h1-h4 `color` at (0,1,1), and
   h1/h2 additionally get a `border-bottom`+`padding-bottom` underline
   treatment there — both load after this bundle. Beat them outright at
   (0,2,1); margins stay governed by the rule above, unchanged. */
.doc-example .doc-example-page h1,
.doc-example .doc-example-page h2,
.doc-example .doc-example-page h3,
.doc-example .doc-example-page h4 {
    color: #1a1a1a;
    background: none;
    border: none;
    padding: 0;
}

.doc-example-page table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.75em 0;
}

.doc-example-page th, .doc-example-page td {
    border: 1px solid #444;
    padding: 0.35em 0.6em;
    text-align: left;
    color: #1a1a1a;
}

/* Hardening: activity-content's `.activity-content th` (background-color +
   color) and its shared `th, td` border/padding rule all tie at (0,1,1)
   with the rule above and win on source order. Re-assert background/
   color/border/padding at (0,2,1) — text-align stays on the rule above. */
.doc-example .doc-example-page th,
.doc-example .doc-example-page td {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #444;
    padding: 0.35em 0.6em;
}

/* ---- Excel: spreadsheet grid ---- */
.doc-example-sheet {
    padding: 0;
    font-family: Arial, 'Segoe UI', sans-serif;
    font-size: var(--font-size-sm);
}

.doc-example-sheet table {
    border-collapse: collapse;
    width: 100%;
}

/* activity-content.css gives every table a top/bottom margin; inside the
   sheet/datasheet bodies that reads as a stray white band above the label
   strip. The grid sits flush. */
.doc-example .doc-example-sheet table,
.doc-example .doc-example-datasheet table {
    margin: 0;
}

/* Notes under a grid (formula explanations, second-sheet summaries).
   Without these, activity-content's prose styling leaks in: centred,
   theme-coloured text and dark code chips on the white artifact. */
.doc-example .doc-example-sheet p,
.doc-example .doc-example-datasheet p {
    margin: 0.6em 0.9em;
    color: #444;
    font-size: 0.85em;
    text-align: left;
}

.doc-example .doc-example-page code,
.doc-example .doc-example-sheet code,
.doc-example .doc-example-datasheet code {
    background: #eef1f5;
    color: #1a1a1a;
    border: 1px solid #c7c7c7;
    border-radius: 3px;
    padding: 0 0.3em;
    font-family: var(--font-family-mono, monospace);
    font-size: 0.9em;
}

.doc-example-sheet td, .doc-example-sheet th {
    border: 1px solid #c7c7c7;
    padding: 0.25em 0.6em;
    color: #1a1a1a;
    background: #fff;
    text-align: left;
    white-space: nowrap;
}

/* Hardening — same reasoning as the page-variant block above. */
.doc-example .doc-example-sheet td,
.doc-example .doc-example-sheet th {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #c7c7c7;
    padding: 0.25em 0.6em;
}

/* Author-written label strips (spec fallback — chosen over CSS counters
   so labels always align with the authored grid). Raised to (0,3,0) — one
   `.doc-example` class higher than the (0,2,1) hardening rule above — so
   the label gutters stay grey even inside a `de-shaded` header row instead
   of being swept up by the hardening rule's background/color. */
.doc-example .doc-example-sheet .de-collabel,
.doc-example .doc-example-sheet .de-rowlabel {
    background: #e6e6e6;
    color: #444;
    font-weight: var(--font-weight-medium);
    text-align: center;
    min-width: 2em;
}

/* ---- PowerPoint: 16:9 slide ---- */
.doc-example-slide {
    aspect-ratio: 16 / 9;
    padding: 5% 7%;
    font-family: Arial, 'Segoe UI', sans-serif;
    display: flex;
    flex-direction: column;
    gap: 4%;
}

.doc-example-slide + .doc-example-slide {
    margin-top: var(--space-md);
    border-top: 1px solid var(--border-medium);
}

.doc-example-slide .de-slide-title {
    font-size: 1.4em;
    font-weight: var(--font-weight-bold);
    color: #1a1a1a;
}

.doc-example-slide .de-slide-body {
    color: #1a1a1a;
    font-size: 0.95em;
}

.doc-example-slide .de-slide-body ul { margin: 0; padding-left: 1.2em; }

/* Two Content layout: two side-by-side body zones in one slide. Authored as
   `<div class="de-slide-columns"><div>…</div><div>…</div></div>` inside the
   body zone, so body typography and the list rule above still apply. */
.doc-example-slide .de-slide-columns {
    display: flex;
    gap: 6%;
}

.doc-example-slide .de-slide-columns > div {
    flex: 1;
    min-width: 0;
}

/* Tables on a slide. Without these, activity-content.css's table styling
   leaks in exactly as it does for the page and sheet variants — `th` takes
   `--bg-hover`/`--text-primary` and rows take `--bg-surface` banding, all
   theme tokens, so a white slide renders light-on-light in dark mode. Same
   hardening specificity (0,2,1) and the same cell-over-row argument as the
   `de-shaded` block below: `tr:nth-child(even)`/`tr:hover` paint the row,
   these paint the cells on top. A PowerPoint table style is a shaded header
   row over plain rows, which is what this draws. */
.doc-example .doc-example-slide table {
    width: 100%;
    border-collapse: collapse;
    margin: 0;
    font-size: 0.85em;
}

.doc-example .doc-example-slide th,
.doc-example .doc-example-slide td {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #c7c7c7;
    padding: 0.25em 0.5em;
    text-align: left;
}

.doc-example .doc-example-slide th {
    background: #1f3864;
    color: #fff;
    font-weight: var(--font-weight-semibold);
}

/* Speaker-notes strip: PowerPoint's Notes view puts the notes below the
   slide. Notes are saved in the .pptx and are graded in most Digital Office
   presentation tasks, but they are not ON the slide — so a slide-only mock
   cannot show them at all. Authored as a sibling immediately after the slide
   it belongs to, still inside the same <figure>. */
.doc-example .de-slide-notes {
    background: #f7f7f7;
    color: #444;
    border: 1px solid var(--border-medium);
    border-top: 1px dashed #c7c7c7;
    font-family: Arial, 'Segoe UI', sans-serif;
    font-size: 0.85em;
    line-height: 1.5;
    padding: 0.7em 1em;
    text-align: left;
}

.doc-example .de-slide-notes p,
.doc-example .de-slide-notes strong { color: #444; }
.doc-example .de-slide-notes p { margin: 0; }

/* The `slide + slide` separator above cannot match across a notes strip;
   restore the gap so stacked slides still read as separate slides. */
.doc-example .de-slide-notes + .doc-example-slide {
    margin-top: var(--space-md);
}

/* ---- Access: datasheet view ---- */
.doc-example-datasheet {
    padding: 0;
    font-family: Arial, 'Segoe UI', sans-serif;
    font-size: var(--font-size-sm);
}

.doc-example-datasheet table {
    border-collapse: collapse;
    width: 100%;
}

.doc-example-datasheet th {
    background: #ececec;
    color: #1a1a1a;
    border: 1px solid #c7c7c7;
    padding: 0.3em 0.6em;
    font-weight: var(--font-weight-medium);
    text-align: left;
}

.doc-example-datasheet td {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #d9d9d9;
    padding: 0.3em 0.6em;
    white-space: nowrap;
}

/* Hardening — same reasoning as the page-variant block above. Protects the
   #ececec header background and the #d9d9d9 cell borders/padding. */
.doc-example .doc-example-datasheet th {
    background: #ececec;
    color: #1a1a1a;
    border: 1px solid #c7c7c7;
    padding: 0.3em 0.6em;
}

.doc-example .doc-example-datasheet td {
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #d9d9d9;
    padding: 0.3em 0.6em;
}

.doc-example-datasheet .de-recsel {
    background: #ececec;
    width: 1.4em;
    min-width: 1.4em;
}

/* Raised to (0,3,0) — same reasoning as de-collabel/de-rowlabel above, so
   the record-selector gutter isn't swept up by the datasheet td hardening
   rule's background. */
.doc-example .doc-example-datasheet .de-recsel {
    background: #ececec;
}

/* ---- Shared utilities ---- */
.doc-example .de-center  { text-align: center; }
.doc-example .de-right   { text-align: right; }
.doc-example .de-justify { text-align: justify; }

/* Paragraph-format depictions (added 2026-08-31 after Evan's visual pass —
   the Paragraph Formatting skill check labels these formats, so the mock
   must actually show them). */
.doc-example .de-indent-first   { text-indent: 2em; }
.doc-example .de-indent-hanging { padding-left: 2em; text-indent: -2em; }
.doc-example .de-spacing-double { line-height: 2; }

/* Fidelity closure set (2026-08-31, Evan's ruling): page chrome and chart
   placeholders so Page Layout / chart tasks can show what they check. */

/* One line with left- and right-aligned parts — the tab-stop look.
   Children are <span>s; a middle span sits centred when present. */
.doc-example .de-split {
    display: flex;
    justify-content: space-between;
    gap: 2em;
}

/* Header/footer strips inside the Word page. Thin, muted, separated from
   the body like Word's own header/footer zones. Compose with .de-center /
   .de-split for positioning within the strip. */
.doc-example .doc-example-page .de-page-header,
.doc-example .doc-example-page .de-page-footer {
    color: #666;
    font-size: 0.8em;
}

.doc-example .doc-example-page .de-page-header {
    border-bottom: 1px solid #ddd;
    padding-bottom: 0.4em;
    margin-bottom: 1.4em;
}

.doc-example .doc-example-page .de-page-footer {
    border-top: 1px solid #ddd;
    padding-top: 0.4em;
    margin-top: 1.4em;
}

/* Landscape page: letter-landscape proportions. Content-light pages show
   the wide-and-short shape; long content scrolls rather than distorting. */
.doc-example .doc-example-page--landscape {
    aspect-ratio: 11 / 8.5;
    overflow-y: auto;
}

/* Chart and picture/WordArt placeholders: honestly placeholders — a framed
   zone naming the object, never a fake rendering. Author writes an icon
   (fa-chart-column / fa-chart-pie / fa-image / fa-font), a bold name line,
   and a short description line inside. */
.doc-example .de-chart-placeholder,
.doc-example .de-picture-placeholder {
    border: 1px solid #c7c7c7;
    background: #f7f7f7;
    color: #444;
    text-align: center;
    padding: 1.6em 1em;
    margin: 0.75em 0;
    font-size: 0.9em;
}

.doc-example .de-chart-placeholder i,
.doc-example .de-picture-placeholder i {
    display: block;
    font-size: 2em;
    margin-bottom: 0.4em;
    color: #888;
}

.doc-example .de-shaded {
    background: #1f3864;
    color: #fff;
}

.doc-example .de-shaded * { color: #fff; }

/* .de-merged is a semantic marker for reviewers; real merging is colspan */
.doc-example .de-merged { font-style: normal; }

/* SELF-CASCADE hardening: `de-shaded` is authored on the `<tr>` (see e.g.
   A3-Sales-Report.html, Practical-Exam-Word-Processing-1.html), but a
   cell's own background always paints OVER its row's — so once every
   ordinary td/th above carries an explicit background (needed so
   activity-content's tr:nth-child/hover striping can never show through
   a transparent cell), that SAME opaque cell background also hides the
   `.de-shaded` row's navy underneath it. This is doc-example.css's own
   SHEET/DATASHEET white-on-white bug too: `.doc-example-sheet td` already
   sets `background:#fff` unconditionally, which was already covering
   `de-shaded`'s row-level navy before any of the hardening above existed.
   Fix: re-assert navy at CELL level, at (0,2,2) — one element higher than
   every (0,2,1) hardening rule above, so it always outranks them
   regardless of source order. Covers both row-applied (`tr.de-shaded`)
   and cell-applied (`th.de-shaded` / `td.de-shaded`) usage. De-collabel/
   de-rowlabel/de-recsel stay grey regardless of `de-shaded` — their
   (0,3,0) always outranks this (0,2,2) block. */
.doc-example tr.de-shaded > th,
.doc-example tr.de-shaded > td,
.doc-example tr > th.de-shaded,
.doc-example tr > td.de-shaded {
    background: #1f3864;
    color: #fff;
}

@media (max-width: 600px) {
    .doc-example-page { padding: var(--space-lg); }
}


/* ===== components/content-image-tools.css ===== */
/* ==========================================================================
   Builder image tools — Caption and Add example dialogs, the prompt beside
   every new image (spec D10), and the "Waiting for screenshots" list.
   Script: js/content-image-tools.js. Admin console only.
   ========================================================================== */

/* ---------- A new image beside the text it was made from ---------- */
.ci-compare {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-md);
    align-items: start;
    margin: 0 0 var(--space-md);
    text-align: left;
}

.ci-compare-image img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-md);
}

.ci-compare-text {
    min-width: 0;
}

.ci-compare-heading,
.ci-label,
.ci-waiting-title {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.ci-compare-source {
    margin: 0 0 var(--space-sm);
}

.ci-compare-source img {
    display: block;
    width: 6rem;
    height: auto;
    border-radius: var(--radius-sm);
}

.ci-compare-source figcaption,
.ci-sub {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
}

/* The prompt in full, line breaks kept, read-only, scrolls when long. */
.ci-prompt {
    margin: 0;
    padding: var(--space-sm);
    max-height: 16rem;
    overflow: auto;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-family: inherit;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    text-align: left;
}

@media (max-width: 640px) {
    .ci-compare {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---------- Dialog text and fields ---------- */
.ci-reason,
.ci-note,
.ci-warning {
    margin: 0 0 var(--space-md);
    font-size: var(--font-size-sm);
    text-align: left;
}

.ci-reason {
    color: var(--text-primary);
}

.ci-note {
    color: var(--text-secondary);
}

.ci-reason-warn,
.ci-warning {
    padding: var(--space-sm) var(--space-md);
    color: var(--color-warning-text);
    background: var(--color-warning-bg);
    border-radius: var(--radius-sm);
}

.ci-none {
    margin: 0;
    font-size: var(--font-size-sm);
    font-style: italic;
    color: var(--text-muted);
}

.ci-row {
    display: grid;
    gap: var(--space-xs);
    margin: 0 0 var(--space-md);
    text-align: left;
}

/* Now | New, stacked when narrow. */
.ci-field {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-xs) var(--space-md);
    margin: 0 0 var(--space-md);
    text-align: left;
}

.ci-field > .ci-label {
    grid-column: 1 / -1;
}

.ci-now-text {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

@media (max-width: 640px) {
    .ci-field {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* SweetAlert gives its fields margins and a fixed width; these sit in a grid. */
.swal2-popup .ci-input {
    width: 100%;
    max-width: 100%;
    height: auto;
    margin: 0;
    font-size: var(--font-size-sm);
}

.ci-prompt-used {
    margin: 0 0 var(--space-md);
    text-align: left;
}

.ci-prompt-used summary {
    cursor: pointer;
    margin-bottom: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* ---------- Waiting for screenshots (top of the editor preview) ----------
   It sits inside .activity-content, whose p/ul/li rules are (0,1,1), so every
   rule here starts with .ci-waiting to win. */
.ci-waiting {
    margin: 0 0 var(--space-lg);
    padding: var(--space-md);
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-primary);
}

.ci-waiting .ci-waiting-title {
    margin: 0 0 var(--space-sm);
}

.ci-waiting .ci-waiting-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ci-waiting .ci-waiting-item {
    margin: 0;
}

.ci-waiting .ci-waiting-item + .ci-waiting-item {
    margin-top: var(--space-sm);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--border-subtle);
}

.ci-waiting .ci-waiting-name {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
}

.ci-waiting .ci-prompt-used {
    margin-bottom: var(--space-sm);
}

.ci-waiting .ci-waiting-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}


/* ===== components/content-video-tools.css ===== */
/* ==========================================================================
   Builder video tools — Add video example: the picking bar, the "Video
   examples" list above the page, the brief / watch / caption dialogs, and the
   Caption and Remove buttons on a clip that is on the page. A [VIDEO N] or
   [SCREENCAST N] placeholder that is waiting gets its own rows in the list and
   the same buttons in the preview.
   Script: js/content-video-tools.js. Admin console only.
   The clip a student sees is styled in content/activity-content.css
   (.video-example).
   ========================================================================== */

/* ---------- Picking a place ---------- */
.cv-pick-bar {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    margin: 0 0 var(--space-md);
    padding: var(--space-sm) var(--space-md);
    color: var(--color-info-text);
    background: var(--color-info-bg);
    border: 1px solid var(--color-info);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

.cv-pick-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

/* Every block of the page is a target. The "Waiting for screenshots" box is not
   part of the page, so it is not one. */
.cv-picking > *:not(.ci-waiting) {
    cursor: pointer;
}

.cv-picking > *:not(.ci-waiting):hover {
    outline: 2px dashed var(--color-info);
    outline-offset: 4px;
}

/* The overlay tools would catch the click meant for the block under them. */
.cv-picking .cv-overlay {
    display: none;
}

/* ---------- The Video examples list (above the page preview) ---------- */
.cv-list-box {
    margin: var(--space-lg) var(--space-lg) 0;
    padding: var(--space-md);
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-primary);
}

.cv-list-title,
.cv-waiting-head,
.cv-label {
    display: block;
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    text-align: left;
}

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

/* Waiting rows sit above the rest, with a rule between the two lists. */
.cv-waiting-head {
    margin-top: var(--space-sm);
}

.cv-list-waiting {
    margin-bottom: var(--space-sm);
}

.cv-list-waiting + .cv-list > .cv-item:first-child {
    border-top: 1px solid var(--border-subtle);
}

.cv-item {
    display: flex;
    gap: var(--space-md);
    align-items: flex-start;
    padding: var(--space-sm) 0;
    border-top: 1px solid var(--border-subtle);
}

.cv-item:first-child {
    border-top: none;
}

.cv-poster {
    flex: 0 0 auto;
    width: 128px;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    background: var(--bg-muted);
    border-radius: var(--radius-sm);
}

.cv-item-body {
    flex: 1 1 auto;
    min-width: 0;
}

.cv-item-status,
.cv-item-brief {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.cv-failed {
    font-weight: var(--font-weight-semibold);
    color: var(--color-danger-text);
}

.cv-item-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-top: var(--space-xs);
}

.cv-spinner {
    display: inline-block;
    width: 0.9em;
    height: 0.9em;
    margin-right: var(--space-xs);
    vertical-align: -0.1em;
    border: 2px solid var(--border-medium);
    border-top-color: var(--color-info);
    border-radius: var(--radius-full);
    animation: cv-spin 0.9s linear infinite;
}

@keyframes cv-spin {
    to { transform: rotate(360deg); }
}

/* ---------- Dialog text and fields ---------- */
.cv-text,
.cv-sub,
.cv-warning,
.cv-ok {
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-sm);
    text-align: left;
    overflow-wrap: anywhere;
}

.cv-text {
    color: var(--text-primary);
}

.cv-sub {
    color: var(--text-secondary);
}

.cv-warning,
.cv-ok {
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-sm);
}

.cv-warning {
    color: var(--color-warning-text);
    background: var(--color-warning-bg);
}

.cv-ok {
    color: var(--color-success-text);
    background: var(--color-success-bg);
}

.cv-warning[hidden] {
    display: none;
}

.cv-field {
    margin: 0 0 var(--space-md);
    text-align: left;
}

/* SweetAlert gives its fields margins and a fixed width. */
.swal2-popup .cv-input {
    width: 100%;
    max-width: 100%;
    height: auto;
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
}

.cv-lengths {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin: 0 0 var(--space-md);
}

.cv-lengths .btn[aria-pressed="true"] {
    color: var(--text-on-brand);
    background: var(--brand-primary);
    border-color: var(--brand-primary);
}

.cv-watch {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    margin: 0 0 var(--space-sm);
    background: var(--bg-muted);
    border-radius: var(--radius-md);
}

.cv-brief-used {
    max-height: 9em;
    overflow: auto;
    margin: 0 0 var(--space-sm);
    padding: var(--space-sm);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-family: inherit;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    text-align: left;
}

/* ---------- Caption and Remove on a clip in the preview ---------- */
#contentPreview .video-example,
#contentPreview .video-placeholder {
    position: relative;
}

.cv-overlay {
    position: absolute;
    top: var(--space-sm);
    right: var(--space-sm);
    z-index: 2;
    display: flex;
    gap: var(--space-xs);
    opacity: 0;
    transition: opacity 0.2s;
}

.video-example:hover > .cv-overlay,
.video-example:focus-within > .cv-overlay,
.video-placeholder:hover > .cv-overlay,
.video-placeholder:focus-within > .cv-overlay {
    opacity: 1;
}

/* A waiting placeholder carries up to five buttons: they wrap inside the element. */
.video-placeholder > .cv-overlay {
    flex-wrap: wrap;
    justify-content: flex-end;
    max-width: calc(100% - 2 * var(--space-sm));
}

/* ---------- The small message at the foot of the screen ----------
   Above SweetAlert's own layer (1060), so it shows over an open dialog
   without closing it. */
.cv-toast {
    position: fixed;
    left: 50%;
    bottom: var(--space-xl);
    z-index: 2000;
    transform: translateX(-50%);
    max-width: min(480px, 92vw);
    padding: var(--space-sm) var(--space-lg);
    color: var(--text-primary);
    background: var(--bg-elevated);
    border: 1px solid var(--border-medium);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    font-size: var(--font-size-sm);
}

@media (max-width: 640px) {
    .cv-item {
        flex-direction: column;
    }
}


/* ===== components/sub-plan-page.css ===== */
/* ============================================================
   Sub plan page: what a substitute teacher reads from the link
   (digitalcs.ca/sub/) and what the admin Preview shows
   (docs/implemented/sub-plan.md, Part 3).

   One column, phone first, light theme only. The HTML comes from
   shared/includes/sub_plan_render.php: every class below is
   written there and nowhere else. The admin page's own styles
   are in components/sub-plan-admin.css.
   ============================================================ */

.sub-plan-page {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    width: 100%;
    max-width: var(--container-md);
    margin: 0 auto;
    padding: var(--space-md);
}

/* --- Top card: course name, dates, where the room is --- */
.sub-plan-header .card-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
}

.sub-plan-kicker {
    margin: 0;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.sub-plan-title {
    margin: 0;
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.sub-plan-dates {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

/* --- Label and value pairs: the header facts and the New students part --- */
.sub-plan-facts {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-sm) var(--space-lg);
    width: 100%;
    margin: 0;
}

.sub-plan-fact dt {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.sub-plan-fact dd {
    margin: 0;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

/* --- Section cards --- */
.sub-plan-heading {
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

/* The notes are the only part written for this one absence. */
.sub-plan-notes {
    border-color: var(--brand-primary);
}

/* Text from the editor. base.css takes the bullets off every list and greys
   every paragraph, so both are put back here. */
.sub-plan-body {
    line-height: var(--line-height-relaxed);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.sub-plan-body p {
    margin: 0 0 var(--space-sm);
    color: var(--text-primary);
}

.sub-plan-body ul,
.sub-plan-body ol {
    margin: 0 0 var(--space-sm);
    padding-left: var(--space-lg);
}

.sub-plan-body ul {
    list-style: disc;
}

.sub-plan-body ol {
    list-style: decimal;
}

.sub-plan-body li {
    margin-bottom: var(--space-xs);
}

.sub-plan-body h3,
.sub-plan-body h4 {
    margin: var(--space-md) 0 var(--space-xs);
    font-weight: var(--font-weight-semibold);
}

.sub-plan-body h3 {
    font-size: var(--font-size-lg);
}

.sub-plan-body h4 {
    font-size: var(--font-size-base);
}

/* A link here is often a phone number to tap. The brand link colour is too
   pale on white for that, so links are dark and underlined. */
.sub-plan-body a,
.sub-plan-facts a {
    color: var(--text-primary);
    text-decoration: underline;
}

.sub-plan-body > :first-child {
    margin-top: 0;
}

.sub-plan-body > :last-child {
    margin-bottom: 0;
}

.sub-plan-body + .sub-plan-blocks,
.sub-plan-body + .sub-plan-courses,
.sub-plan-body + .sub-plan-facts,
.sub-plan-body + .sub-plan-empty {
    margin-top: var(--space-md);
}

/* --- Block times: one row for each block or extra row --- */
.sub-plan-blocks,
.sub-plan-courses {
    margin: 0;
    padding: 0;
}

/* The label and the time share a line. When they do not fit (a narrow phone,
   a long block name), the time drops under the label and neither one breaks. */
.sub-plan-block {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-md);
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.sub-plan-block:last-child {
    border-bottom: 0;
}

.sub-plan-block-label {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.sub-plan-block-time {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--text-primary);
}

.sub-plan-block-note {
    flex-basis: 100%;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* A typed row (lunch, a prep block) is not a class, so it reads quieter. */
.sub-plan-block-extra .sub-plan-block-label {
    font-weight: var(--font-weight-normal);
    color: var(--text-secondary);
}

.sub-plan-block-extra .sub-plan-block-time {
    color: var(--text-secondary);
}

/* --- Courses --- */
.sub-plan-courses li {
    padding: var(--space-xs) 0;
    color: var(--text-primary);
}

/* --- New students: the access code is read out or typed, so it is large --- */
.sub-plan-code {
    display: inline-block;
    padding: var(--space-xs) var(--space-sm);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.08em;
    background-color: var(--bg-subtle);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    user-select: all;
}

/* --- Pictures under a section --- */
.sub-plan-gallery {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-md);
    margin-top: var(--space-md);
}

.sub-plan-figure {
    margin: 0;
}

.sub-plan-figure a {
    display: block;
}

.sub-plan-figure img {
    width: 100%;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.sub-plan-figure figcaption {
    margin-top: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* --- Nothing to show --- */
.sub-plan-empty {
    margin: 0;
    color: var(--text-secondary);
}

.sub-plan-unavailable .card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.sub-plan-unavailable p {
    margin: 0;
    color: var(--text-primary);
}

@media (min-width: 640px) {
    .sub-plan-page {
        gap: var(--space-lg);
        padding: var(--space-xl) var(--space-lg);
    }

    .sub-plan-facts,
    .sub-plan-gallery {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* utilities.css already hides .no-print and keeps a .card on one sheet. */
@media print {
    .sub-plan-page {
        max-width: none;
        padding: 0;
        gap: var(--space-sm);
    }

    .sub-plan-facts,
    .sub-plan-gallery {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .sub-plan-figure {
        break-inside: avoid;
    }
}


/* ===== components/sub-plan-admin.css ===== */
/* ============================================================
   Sub plan, admin page: the Absences tab and the Standing plan
   tab of /php/lms_sub_plan/index.php
   (docs/implemented/sub-plan.md, Part 4).

   The markup is in lms_sub_plan/_views/absences.php and
   _views/plan.php. The script is js/sub-plan-admin.js. What the
   sub reads, and the live part shown inside a section's editor,
   is styled in components/sub-plan-page.css.
   ============================================================ */

/* A fieldset is used for its legend only. */
.sub-absence-blocks,
.sub-section-editor fieldset {
    min-width: 0;
    padding: 0;
    border: 0;
}

.sub-absence-blocks legend,
.sub-section-editor legend {
    padding: 0;
}

/* --- Absences tab: the form --- */
.sub-absence-form-card form {
    max-width: var(--container-md);
}

/* --- Absences tab: the list --- */
.sub-absence-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    margin: 0;
    padding: 0;
}

.sub-absence {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-md) var(--space-lg);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

/* A link that no longer works: the row stays, but reads quieter. */
.sub-absence--ended {
    background-color: var(--bg-subtle);
}

.sub-absence--ended .sub-absence-dates {
    color: var(--text-secondary);
}

.sub-absence-main {
    display: flex;
    flex: 1 1 280px;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.sub-absence-dates {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.sub-absence-blocks-line {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.sub-absence-state {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.sub-absence-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
}

/* --- Dialogs: the link after a save, and the warnings before one --- */
.sub-link-box {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    text-align: left;
}

.sub-link-box p {
    margin: 0;
    color: inherit;
}

.sub-link-box .form-control {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
}

.sub-warning-list {
    margin: 0;
    padding-left: var(--space-lg);
    list-style: disc;
    text-align: left;
}

.sub-warning-list li {
    margin-bottom: var(--space-xs);
}

/* --- Standing plan tab: the header form --- */
.sub-header-form {
    max-width: var(--container-md);
}

/* Two fields to a row when there is room, one when there is not. */
.sub-header-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    column-gap: var(--space-md);
}

/* --- Standing plan tab: the sections --- */
.sub-plan-admin-lead {
    margin: 0;
    color: var(--text-secondary);
}

.sub-section-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.sub-section {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.sub-section-bar {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
}

/* The handle keeps its size when the icon has not loaded, and a finger on it
   drags the row and does not scroll the page. */
.sub-section-drag,
.sub-picture-drag {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    min-width: var(--space-xl);
    min-height: var(--space-xl);
    color: var(--text-muted);
    cursor: grab;
    touch-action: none;
}

/* The heading is the button that opens the editor. */
.sub-section-title {
    display: flex;
    flex: 1;
    align-items: center;
    gap: var(--space-sm);
    min-width: 0;
    padding: var(--space-xs) 0;
    font: inherit;
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    text-align: left;
    overflow-wrap: anywhere;
    background: none;
    border: 0;
    cursor: pointer;
}

.sub-section-title:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

.sub-section--hidden .sub-section-title {
    color: var(--text-muted);
}

.sub-section-chevron {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.sub-section--open .sub-section-chevron {
    transform: rotate(90deg);
}

.sub-section-editor {
    padding: var(--space-md) var(--space-lg) var(--space-lg);
    border-top: 1px solid var(--border-light);
}

/* The row being dragged, for sections and for pictures. */
.sub-sortable-ghost {
    opacity: 0.4;
}

/* --- Block times: a note for each block, then the extra rows --- */
.sub-block-note {
    margin-bottom: var(--space-sm);
}

.sub-block-note .form-label {
    margin-bottom: var(--space-xs);
}

.sub-extra-rows {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
}

.sub-extra-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end;
    gap: var(--space-sm);
    padding: var(--space-sm);
    background-color: var(--bg-subtle);
    border-radius: var(--radius-md);
}

.sub-extra-field,
.sub-picture-caption {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.sub-extra-field .form-text,
.sub-picture-caption .form-text {
    margin-top: 0;
}

/* --- The part of a self-filling section that the LMS writes --- */
.sub-section-live {
    padding: var(--space-md);
    background-color: var(--bg-subtle);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
}

/* --- Pictures on a section --- */
.sub-picture-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin: 0 0 var(--space-md);
    padding: 0;
}

.sub-picture {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm) var(--space-md);
    padding: var(--space-sm);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.sub-picture-thumb {
    width: 96px;
    height: 72px;
    object-fit: cover;
    background-color: var(--bg-muted);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
}

.sub-picture-caption {
    flex: 1 1 220px;
}

@media (min-width: 768px) {
    .sub-extra-row {
        grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 2fr) auto;
    }
}


/* ===== components/review-bar.css ===== */
/* ==========================================================================
   Review bar and review card (student view, review mode)

   Only a signed-in teacher in review mode sees these. The bar sits in the
   fixed slot the preview banner uses. Markup: includes/review_bar.php,
   includes/review_card.php and php/review.php on the student site.
   Feature doc: docs/implemented/content-review.md.
   ========================================================================== */

/* ── The bar ───────────────────────────────────────────────────────────── */

.review-bar {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: var(--z-fixed);
    padding: var(--space-sm) var(--space-lg);
    background: var(--bg-elevated);
    color: var(--text-primary);
    border-top: 3px solid var(--color-warning);
    box-shadow: var(--shadow-lg);
    font-size: var(--font-size-sm);
}

.review-bar-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm) var(--space-lg);
}

.review-bar-info,
.review-bar-versions,
.review-bar-actions,
.review-bar-form-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
}

.review-bar-step {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.review-bar-place,
.review-bar-label {
    color: var(--text-secondary);
}

.review-bar-version {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.review-bar-version:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

/* The primary button's pair: white on the brand colour cannot be read on the
   dark student site. */
.review-bar-version.is-current {
    border-color: var(--btn-primary-bg);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-text);
}

.review-bar-notice,
.review-bar-error {
    margin: var(--space-sm) 0 0;
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-md);
}

.review-bar-notice {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
}

.review-bar-error {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

.review-bar-form {
    display: grid;
    gap: var(--space-sm);
    margin-top: var(--space-sm);
}

.review-bar-form textarea {
    width: 100%;
    resize: vertical;
}

/* The hidden attribute must win over the display rules above. */
.review-bar [hidden] {
    display: none;
}

/* The page ends above the bar. review-bar.js sets the bar's real height. */
body.has-review-bar .student-main {
    padding-bottom: calc(var(--space-xl) + var(--review-bar-height, 5rem));
}

/* Raise Hand and Back to top are fixed at the bottom right, at or above the
   bar's layer. A bottom margin lifts a fixed element by that much, whatever
   its own bottom offset is, so they sit above the bar and not on Next. */
body.has-review-bar .raise-hand-fab,
body.has-review-bar .back-to-top {
    margin-bottom: var(--review-bar-height, 5rem);
}

@media (max-width: 767px) {
    .review-bar {
        padding: var(--space-sm);
    }

    body.has-review-bar .student-bottom-nav {
        bottom: var(--review-bar-height, 5rem);
    }

    body.has-review-bar .student-main {
        padding-bottom: calc(var(--space-xl) + var(--review-bar-height, 5rem) + 4rem);
    }
}

/* ── The review card (a link, a file or an HTML element) ───────────────── */

.review-card {
    max-width: 800px;
    margin: 0 auto;
}

.review-card-type {
    margin: 0 0 var(--space-xs);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
}

.review-card-title {
    margin: 0 0 var(--space-md);
    color: var(--text-primary);
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
}

.review-card-text,
.review-card-note {
    margin-bottom: var(--space-md);
    color: var(--text-secondary);
}

.review-card-target {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-xs);
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
    overflow-wrap: anywhere;
}

.review-card-actions {
    margin: var(--space-md) 0 0;
}

.review-card-html {
    padding: var(--space-md);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
}

/* ── The "student login is open" stop page ─────────────────────────────── */

.review-stop {
    max-width: var(--container-sm);
    margin: var(--space-3xl) auto;
    padding: 0 var(--space-lg);
}

.review-stop-title {
    margin: 0 0 var(--space-md);
    color: var(--text-primary);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
}

.review-stop p {
    color: var(--text-secondary);
}

.review-stop-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-lg);
}


/* ===== components/content-review-admin.css ===== */
/* ==========================================================================
   Content Review (admin console)

   The Steps and Feedback tabs of php/lms_content_review/index.php. Every
   class starts with cr- so nothing here reaches another page.
   Feature doc: docs/implemented/content-review.md.
   ========================================================================== */

/* The tabs are links here, not buttons. */
.cr-tab {
    text-decoration: none;
}

.cr-page {
    display: grid;
    gap: var(--space-md);
    margin-top: var(--space-lg);
}

/* ── The course picker ─────────────────────────────────────────────────── */

.cr-courses {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    gap: var(--space-sm);
}

.cr-course {
    display: grid;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    color: var(--text-primary);
    text-decoration: none;
}

.cr-course:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.cr-course.is-current {
    border-color: var(--brand-primary);
    box-shadow: var(--shadow-sm);
}

.cr-course-name {
    font-weight: var(--font-weight-semibold);
}

/* Muted text is too faint on the hover background. */
.cr-course:hover .cr-course-count {
    color: var(--text-primary);
}

.cr-course-count,
.cr-step-count,
.cr-note-where,
.cr-note-date {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

/* How much of the course is dealt with. A <progress> element, so the page
   needs no inline width. */
.cr-progress {
    display: block;
    width: 100%;
    height: var(--space-xs);
    border: 0;
    border-radius: var(--radius-full);
    background: var(--bg-active);
    overflow: hidden;
    appearance: none;
}

.cr-progress::-webkit-progress-bar {
    background: var(--bg-active);
}

.cr-progress::-webkit-progress-value {
    background: var(--color-success);
}

.cr-progress::-moz-progress-bar {
    background: var(--color-success);
}

/* ── One step ──────────────────────────────────────────────────────────── */

.cr-step-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    cursor: pointer;
}

.cr-step-name {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.cr-step-count {
    margin-left: auto;
}

.cr-step-facts,
.cr-step-statuses,
.cr-note-tags,
.cr-note-actions,
.cr-note-form-row,
.cr-filters-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
}

.cr-step-facts {
    gap: var(--space-xs) var(--space-lg);
    margin-bottom: var(--space-md);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

.cr-step-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.cr-items td {
    vertical-align: middle;
}

/* ── The feedback list ─────────────────────────────────────────────────── */

.cr-filters-row {
    align-items: flex-end;
    gap: var(--space-md);
}

.cr-filters-row .form-group {
    margin-bottom: 0;
}

.cr-note-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
}

.cr-note-item {
    display: block;
    font-weight: var(--font-weight-semibold);
}

.cr-note-text {
    margin: 0 0 var(--space-sm);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.cr-note-done {
    margin-bottom: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border-left: 3px solid var(--border-color);
    background: var(--bg-hover);
    border-radius: var(--radius-sm);
}

.cr-note-done p {
    margin: 0;
    overflow-wrap: anywhere;
}

.cr-note-done-label {
    display: block;
    margin-bottom: var(--space-xs);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.cr-note-form {
    display: grid;
    gap: var(--space-sm);
    margin-top: var(--space-sm);
}

.cr-note-form textarea {
    width: 100%;
    resize: vertical;
}

.cr-note-error {
    margin: 0;
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-md);
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
}

/* The hidden attribute must win over the display rules above. */
.cr-page [hidden] {
    display: none;
}


/* ===== components/growth-plan.css ===== */
/* ============================================================
   Growth plan: all styles for the feature, prefix gp-
   (spec: docs/planned/growth-plan.md).

   PAGE: what a principal reads from the private link
   (digitalcs.ca/growth-plan/) and what the teacher's Preview
   shows. One readable column, phone first, light theme only.
   The HTML comes from shared/includes/growth_plan_render.php:
   every class in this section is written there and nowhere else,
   except .gp-text, which the editor also uses for the teacher's
   words shown read-only, and .gp-unavailable and .gp-title, which
   the admin preview.php also writes for its "not available" card.

   EDITOR (at the end): the teacher's list page and editor
   (admin.digitalcs.ca/php/lms_growth_plan/), written in those
   pages and in growth-plan-admin.js. Its last section is the AI
   feedback card and the Reword modal.

   TODAY PAGE: the reminders in the "Needs you now" card are
   written in lms_briefing/index.php as .briefing-item rows
   (gp-reminder, gp-reminder-link, gp-reminder-snooze). They have
   no rules here: the Today page's row styles and the shared
   utilities lay them out, and growth-plan-reminders.js finds
   them by those class names.
   ============================================================ */

.gp-page {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    width: 100%;
    max-width: var(--container-md);
    margin: 0 auto;
    padding: var(--space-md);
}

.gp-plan {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

/* --- Top card: title, school year, the header lines, Print --- */
.gp-header .card-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
}

.gp-title {
    margin: 0;
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.gp-year {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}

/* Label and value pairs. */
.gp-facts {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-sm) var(--space-lg);
    width: 100%;
    margin: 0;
}

.gp-fact dt {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.gp-fact dd {
    margin: 0;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

/* --- Inquire, Implement, Impact --- */
.gp-phase-title {
    margin: 0 0 var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--border-light);
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.gp-section + .gp-section {
    margin-top: var(--space-lg);
}

.gp-section-title {
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

/* Outcome 1: ..., a quarter of the My Professional Learning grid, a dated reflection. */
.gp-subhead {
    margin: var(--space-md) 0 var(--space-xs);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.gp-subhead:first-child {
    margin-top: 0;
}

/* --- The teacher's words. base.css takes the bullets off every list and
       greys every paragraph, so both are put back here. The same rules style
       what the editor boxes allow: paragraphs, the two headings, bold, italic,
       underline, bulleted and numbered lists, and links. --- */
.gp-text {
    line-height: var(--line-height-relaxed);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.gp-text p {
    margin: 0 0 var(--space-sm);
    color: var(--text-primary);
}

/* The headings sit inside a section that already has its own, so they stay small. */
.gp-text h3,
.gp-text h4 {
    margin: var(--space-md) 0 var(--space-xs);
    font-size: var(--font-size-base);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.gp-text h3 {
    font-weight: var(--font-weight-bold);
}

.gp-text h4 {
    font-weight: var(--font-weight-semibold);
}

.gp-text > h3:first-child,
.gp-text > h4:first-child {
    margin-top: 0;
}

.gp-text strong,
.gp-text b {
    font-weight: var(--font-weight-bold);
}

.gp-text em,
.gp-text i {
    font-style: italic;
}

.gp-text u {
    text-decoration: underline;
}

.gp-text a {
    color: var(--link-color);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.gp-text a:hover {
    color: var(--link-hover);
}

.gp-text ul,
.gp-text ol {
    margin: 0 0 var(--space-sm);
    padding-left: var(--space-lg);
}

.gp-text ul {
    list-style: disc;
}

.gp-text ol {
    list-style: decimal;
}

.gp-text ul ul,
.gp-text ol ol,
.gp-text ul ol,
.gp-text ol ul {
    margin: var(--space-xs) 0 0;
}

.gp-text ul ul {
    list-style: circle;
}

.gp-text ol ol {
    list-style: lower-alpha;
}

.gp-text li {
    margin-bottom: var(--space-xs);
}

.gp-text > :last-child {
    margin-bottom: 0;
}

/* --- Desired outcomes --- */
.gp-outcomes {
    margin: 0;
    padding-left: var(--space-lg);
    list-style: disc;
    color: var(--text-primary);
}

.gp-outcomes li {
    margin-bottom: var(--space-xs);
    overflow-wrap: anywhere;
}

/* --- TQS connection: a heading for each competency, then its points --- */
.gp-tqs-group + .gp-tqs-group {
    margin-top: var(--space-md);
}

.gp-tqs-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gp-tqs-entry {
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.gp-tqs-entry:last-child {
    border-bottom: 0;
}

.gp-tqs-label {
    margin: 0 0 var(--space-xs);
}

.gp-tqs-code {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.gp-tqs-goal {
    margin-left: var(--space-xs);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.gp-tqs-note {
    margin-top: var(--space-sm);
    padding-left: var(--space-md);
    border-left: 3px solid var(--border-light);
}

.gp-tqs-note .gp-tqs-note-label {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

/* --- My Professional Learning: a 2 by 2 grid, one column on a phone --- */
.gp-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-md);
}

.gp-quadrant {
    min-width: 0;
    padding: var(--space-md);
    background-color: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

/* --- Ongoing reflection: one entry for each date --- */
.gp-reflection {
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.gp-reflection:last-child {
    border-bottom: 0;
}

/* --- A link that is not live --- */
.gp-unavailable .card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.gp-unavailable p {
    margin: 0;
    color: var(--text-primary);
}

@media (min-width: 640px) {
    .gp-page {
        gap: var(--space-lg);
        padding: var(--space-xl) var(--space-lg);
    }

    .gp-plan {
        gap: var(--space-lg);
    }

    .gp-facts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 768px) {
    .gp-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* utilities.css already hides .no-print, which the Print button wears. A phase
   can be longer than a sheet, so it may break across pages; the small blocks
   inside it may not. */
@media print {
    .gp-page {
        max-width: none;
        padding: 0;
        gap: var(--space-sm);
    }

    .gp-plan {
        gap: var(--space-sm);
    }

    /* A card is a flex column, and a flex container does not break across pages. */
    .gp-plan .gp-phase {
        display: block;
        break-inside: auto;
    }

    .gp-facts,
    .gp-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .gp-phase-title,
    .gp-section-title,
    .gp-subhead,
    .gp-text h3,
    .gp-text h4 {
        break-after: avoid;
    }

    /* A printed link cannot be clicked, so its address follows its words. */
    .gp-text a[href]::after {
        content: " (" attr(href) ")";
        font-size: var(--font-size-sm);
    }

    .gp-fact,
    .gp-quadrant,
    .gp-reflection,
    .gp-tqs-entry {
        break-inside: avoid;
    }
}

/* ============================================================
   EDITOR: the list page (index.php) and the editor (plan.php)
   in the admin console. Cards, buttons, form controls, badges,
   alerts and modals are the shared components; these classes
   only lay them out.
   ============================================================ */

/* A sentence that stands on its own in a card. */
.gp-lead {
    margin: 0;
    color: var(--text-primary);
}

/* --- The list page --- */
.gp-plan-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gp-plan-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm) var(--space-md);
    padding: var(--space-md) 0;
    border-bottom: 1px solid var(--border-light);
}

.gp-plan-row:first-child {
    padding-top: 0;
}

.gp-plan-row:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.gp-plan-row-main {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.gp-plan-row-year {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.gp-plan-row-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs) var(--space-md);
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.gp-missing .card-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-md);
}

/* The editor's top bar ([data-gp-toolbar]), the button row under
   each text field ([data-gp-field-actions]) and the stacks inside
   the cards use the shared flex and gap utilities, so they have no
   rule here. */

/* --- Plan details: one column on a phone, two from 768px --- */
.gp-details-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--space-lg);
}

.gp-date-row {
    display: flex;
    gap: var(--space-sm);
}

.gp-date-row .form-control {
    flex: 1 1 auto;
    min-width: 0;
}

.gp-date-input {
    max-width: 16rem;
}

/* --- One text field: its label, the box, and its button row --- */
.gp-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.gp-field-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-sm);
}

.gp-field-head .form-label,
.gp-field > .form-label {
    margin-bottom: 0;
}

.gp-textarea {
    min-height: 6rem;
    resize: vertical;
}

/* A long box is an editor. Its textarea holds HTML, so it stays hidden until the editor has started
   (growth-plan-admin.js removes this class then, or at once when TinyMCE is not on the page). */
.gp-rich-pending {
    display: none;
}

/* --- Read-only blocks: the TQS connection, a goal's TQS links, the reflections --- */
.gp-readonly-block {
    min-width: 0;
    padding: var(--space-md);
    background-color: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.gp-block-title {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--text-primary);
}

.gp-connection-group + .gp-connection-group {
    margin-top: var(--space-md);
}

.gp-connection-head {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.gp-connection-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gp-connection-entry {
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.gp-connection-entry:last-child {
    border-bottom: 0;
}

.gp-connection-note {
    margin-top: var(--space-xs);
    padding-left: var(--space-md);
    border-left: 3px solid var(--border-light);
}

/* --- Goals --- */
.gp-goal {
    margin: 0;
    border: 1px solid var(--border-medium);
}

.gp-goal-head {
    flex-wrap: wrap;
    gap: var(--space-sm);
}

.gp-goal-name {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs) var(--space-sm);
}

/* A goal's TQS links, each with its wording and its note. */
.gp-tqs-links {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin: 0 0 var(--space-md);
    padding: 0;
    list-style: none;
}

/* The list holds whitespace text nodes, which the empty pseudo-class counts as content; no <li> is the test. */
.gp-tqs-links:not(:has(> li)) {
    margin-bottom: 0;
}

.gp-tqs-link {
    min-width: 0;
    padding: var(--space-md);
    background-color: var(--card-bg);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.gp-tqs-link-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-xs) var(--space-sm);
    margin: 0 0 var(--space-xs);
}

.gp-tqs-link-label {
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.gp-tqs-link-title {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

/* "Show wording": a small toggle, the TQS words under it. */
.gp-wording {
    margin: 0 0 var(--space-sm);
}

.gp-wording summary {
    cursor: pointer;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    text-decoration: underline;
}

.gp-wording summary:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
}

.gp-wording .gp-text {
    margin-top: var(--space-xs);
    font-size: var(--font-size-sm);
}

/* --- My Professional Learning: the four quarters, two columns from 768px --- */
.gp-quarters {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

/* --- Impact: the dated reflections, then the form --- */
.gp-reflections {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gp-reflection-item {
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--border-light);
}

.gp-reflection-item:first-child {
    padding-top: 0;
}

.gp-reflection-item:last-child {
    border-bottom: 0;
}

.gp-reflection-item-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-sm);
    margin-bottom: var(--space-xs);
}

.gp-reflection-date {
    margin: 0;
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.gp-reflection-form {
    padding: var(--space-md);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

/* --- Share: each panel is a flex column from the utilities; the
   panel's small print sits on the column's gap, not its own margin --- */
.gp-share-panel .form-text {
    margin: 0;
}

/* --- The modals: Copy from..., Bring a goal forward, the TQS picker --- */
.gp-pick-year {
    margin: 0 0 var(--space-sm);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.gp-pick-group .gp-pick-entry + .gp-pick-entry {
    margin-top: var(--space-sm);
}

.gp-pick-entry {
    min-width: 0;
    padding: var(--space-md);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}

.gp-pick-entry-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-sm);
}

.gp-pick-title {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
    margin: 0;
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.gp-pick-meta {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-normal);
    color: var(--text-secondary);
}

/* A long earlier text scrolls in its own box, so the next one is in reach. */
.gp-pick-body {
    max-height: 16rem;
    margin-top: var(--space-sm);
    overflow-y: auto;
}

.gp-picker-preview {
    padding: var(--space-md);
    background-color: var(--bg-elevated);
    border-left: 3px solid var(--brand-primary);
    border-radius: var(--radius-sm);
}

@media (min-width: 768px) {
    .gp-details-grid,
    .gp-quarters,
    .gp-reword-columns {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* --- AI feedback and reword (plan.php, growth-plan-admin.js) ---
   The feedback card is above the editor on a phone and a tablet. From 1200px
   it sits to the right of the editor and stays in view while the teacher
   scrolls, so a note can be read next to the words it is about. The second
   column exists only while the card is showing. */
.gp-workspace-main {
    min-width: 0;
}

.gp-feedback-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gp-feedback-note {
    min-width: 0;
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.gp-feedback-note:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

/* Reword: the teacher's text and the suggestion side by side from 768px. */
.gp-reword-columns {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-md);
}

.gp-reword-columns .gp-pick-body {
    max-height: 24rem;
}

.gp-reword-suggested {
    background-color: var(--bg-elevated);
    border-left: 3px solid var(--brand-primary);
}

@media (min-width: 1200px) {
    .gp-workspace:has(> .gp-feedback:not([hidden])) {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 22rem;
        gap: var(--space-lg);
        align-items: start;
    }

    .gp-workspace > .gp-feedback {
        grid-column: 2;
        grid-row: 1;
        position: sticky;
        top: 4.5rem;
        max-height: calc(100vh - 6rem);
        margin-bottom: 0;
        overflow-y: auto;
    }

    .gp-workspace > .gp-workspace-main {
        grid-column: 1;
        grid-row: 1;
    }
}

/* With the card beside it the editor column is narrow until about 1450px, too
   narrow for two columns of fields: those grids stay one column while it shows. */
@media (min-width: 1200px) and (max-width: 1450px) {
    .gp-workspace:has(> .gp-feedback:not([hidden])) .gp-details-grid,
    .gp-workspace:has(> .gp-feedback:not([hidden])) .gp-quarters {
        grid-template-columns: 1fr;
    }
}


/* ===== layouts/admin.css ===== */
/* ===================================================================
   DCS Design System - Admin Layout
   Version: 2.0.0

   Admin dashboard layout with sidebar navigation.
   Requires: tokens.css, navigation.css, accordion.css
   =================================================================== */

/* ===================================================================
   1. ADMIN LAYOUT STRUCTURE
   =================================================================== */

.admin-layout {
    display: flex;
    min-height: 100vh;
}

.admin-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 260px;
    height: 100vh;
    background-color: var(--bg-body);
    border-right: 1px solid var(--border-light);
    display: flex;
    flex-direction: column;
    z-index: var(--z-fixed);
    transition: width var(--transition-base), transform var(--transition-base);
}

.admin-sidebar.is-collapsed {
    width: 70px;
}

.admin-main {
    flex: 1;
    /* A flex item's default min-width:auto let a wide table grow this column
       past the viewport, so .table-responsive never scrolled and the whole
       page did (Students list view, 2026-09-10). Zero lets it shrink to the
       space left of the sidebar and the wrappers scroll instead. */
    min-width: 0;
    margin-left: 260px;
    min-height: 100vh;
    background-color: var(--bg-surface);
    transition: margin-left var(--transition-base);
}

.admin-sidebar.is-collapsed ~ .admin-main {
    margin-left: 70px;
}

/* ===================================================================
   2. SIDEBAR HEADER
   =================================================================== */

.admin-sidebar-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-lg);
    border-bottom: 1px solid var(--border-light);
}

.admin-sidebar-logo {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    object-fit: contain;
    flex-shrink: 0;
}

.admin-sidebar-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    transition: opacity var(--transition-fast);
}

.admin-sidebar.is-collapsed .admin-sidebar-title {
    opacity: 0;
    width: 0;
}

/* ===================================================================
   3. SIDEBAR NAVIGATION
   =================================================================== */

.admin-sidebar-nav {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-md) 0;
}

.admin-nav-section {
    margin-bottom: var(--space-sm);
}

.admin-nav-section-title {
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    white-space: nowrap;
    overflow: hidden;
}

.admin-sidebar.is-collapsed .admin-nav-section-title {
    text-align: center;
    padding: var(--space-sm);
    font-size: 10px;
}

/* Nav item - parent with collapse */
.admin-nav-item {
    position: relative;
}

.admin-nav-link {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-lg);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: 0;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.admin-nav-link:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.admin-nav-link.active {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-right: 3px solid var(--brand-primary);
}

.admin-nav-link i {
    width: 20px;
    text-align: center;
    font-size: var(--font-size-base);
    flex-shrink: 0;
}

.admin-nav-link span {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    transition: opacity var(--transition-fast);
}

.admin-sidebar.is-collapsed .admin-nav-link span {
    opacity: 0;
    width: 0;
}

.admin-nav-link .nav-chevron {
    margin-left: auto;
    font-size: var(--font-size-xs);
    transition: transform var(--transition-fast);
}

.admin-nav-link[aria-expanded="true"] .nav-chevron {
    transform: rotate(90deg);
}

.admin-sidebar.is-collapsed .admin-nav-link .nav-chevron {
    display: none;
}

/* Badge on nav link */
/* Count badges are a soft brand pill, not an alarm: a number waiting is
   normal classroom state, not an error (Evan, 2026-09-03). Semantic red stays
   reserved for the .urgent modifier below. */
.admin-nav-link .admin-nav-badge {
    /* Selector carries two classes so it outranks `.admin-nav-link span`.
       A compact count chip. `.admin-nav-link span` gives every label
       flex: 1; without this override the badge span shared the row
       with the label, stretched into a wide pill and truncated the
       label ("Release ste") — teacher ruling 2026-09-10. */
    flex: 0 0 auto;
    margin-left: auto;
    min-width: 20px;
    height: 18px;
    line-height: 18px;
    padding: 0 6px;
    text-align: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
    border-radius: var(--radius-full);
}

.admin-nav-link.active .admin-nav-badge {
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
}

.admin-sidebar.is-collapsed .admin-nav-link .admin-nav-badge {
    position: absolute;
    top: 4px;
    right: 8px;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    padding: 0 4px;
    font-size: 10px;
}

/* Urgent badge: the one place a badge is allowed to be red, with a gentle pulse */
.admin-nav-badge.urgent {
    color: var(--color-danger-text);
    background-color: var(--color-danger-bg);
    animation: urgentPulse 2s ease-in-out infinite;
}

@keyframes urgentPulse {
    0%, 100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 var(--color-danger-bg);
    }
    50% {
        transform: scale(1.05);
        box-shadow: 0 0 0 4px transparent;
    }
}

@media (prefers-reduced-motion: reduce) {
    .admin-nav-badge.urgent {
        animation: none;
    }
}

/* Submenu */
.admin-nav-submenu {
    background-color: var(--bg-input);
    overflow: hidden;
    max-height: 0;
    transition: max-height var(--transition-base);
}

.admin-nav-submenu.show {
    max-height: 1000px;
}

.admin-nav-submenu .admin-nav-link {
    padding-left: calc(var(--space-lg) + 32px);
    font-size: var(--font-size-sm);
}

.admin-nav-submenu .admin-nav-link.active {
    background-color: var(--brand-primary-alpha);
}

/* Nested submenus */
.admin-nav-submenu .admin-nav-submenu {
    background-color: transparent;
}

.admin-nav-submenu .admin-nav-submenu .admin-nav-link {
    padding-left: calc(var(--space-lg) + 52px);
}

.admin-sidebar.is-collapsed .admin-nav-submenu {
    display: none;
}

/* ===================================================================
   4. SIDEBAR FOOTER
   =================================================================== */

.admin-sidebar-footer {
    padding: var(--space-md) var(--space-lg);
    border-top: 1px solid var(--border-light);
}

.admin-user-info {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.admin-user-avatar {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    background-color: var(--brand-primary);
    color: var(--color-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    flex-shrink: 0;
}

.admin-user-details {
    flex: 1;
    overflow: hidden;
    transition: opacity var(--transition-fast);
}

.admin-sidebar.is-collapsed .admin-user-details {
    opacity: 0;
    width: 0;
}

.admin-user-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.admin-user-role {
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: capitalize;
}

.admin-logout-btn {
    padding: var(--space-xs);
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.admin-logout-btn:hover {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

/* ===================================================================
   5. TOP HEADER BAR
   =================================================================== */

.admin-header {
    position: sticky;
    top: 0;
    display: flex;
    align-items: center;
    gap: var(--space-md);
    height: 60px;
    padding: 0 var(--space-lg);
    background-color: var(--bg-surface);
    border-bottom: 1px solid var(--border-light);
    z-index: var(--z-sticky);
}

.admin-header-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.admin-header-toggle:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.admin-header-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.admin-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-left: auto;
}

/* OpenRouter credit balance in the top bar's actions row, just left of the
   Help Queue hand (administrators, 2026-09-04). Filled in by the header's
   script from _handlers/llm/get_balance.php; stays hidden until a balance
   arrives. */
/* Status pills at the left of the header actions — the OpenRouter balance
   and the students-online count share one shape (2026-09-08). */
.admin-header-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    height: 32px;
    margin-right: var(--space-xs);
    padding: 0 var(--space-md);
    border: 1px solid transparent;
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
    background-color: var(--bg-subtle);
    text-decoration: none;
    white-space: nowrap;
    transition: all var(--transition-fast);
}

.admin-header-pill:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

/* Both pills paint after the page does and carry `hidden` until their fetch
   answers. The UA sheet's [hidden]{display:none} loses to an author-origin
   display rule (origin outranks specificity), so without this the pills show
   an "…" placeholder on every page load and keep showing it when the fetch
   fails — the same footgun already restated in notebook.css and drills.css.
   Found 2026-09-08 while adding the online pill; the balance pill had it too. */
.admin-header-pill[hidden] {
    display: none;
}

.admin-header-pill i {
    color: var(--brand-primary);
}

@media (max-width: 767px) {
    .admin-header-pill {
        display: none;
    }
}

/* OpenRouter balance: amber under the Credits-tab warning level. */
.admin-header-balance.is-low,
.admin-header-balance.is-low i {
    color: var(--color-warning-text);
}

.admin-header-balance.is-low {
    border-color: var(--color-warning);
}

/* Students online: the icon carries the live signal — green while anyone is
   working, muted once the room has emptied out. */
.admin-header-online i {
    color: var(--color-success-text);
}

.admin-header-online.is-empty i {
    color: var(--text-muted);
}

/* Student birthdays today (2026-10-29): shown only on a day with one. */
.admin-header-birthday i {
    color: var(--color-warning-text);
}

.admin-header-btn {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--text-muted);
    background: none;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.admin-header-btn:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.admin-header-btn .notification-dot {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    background-color: var(--color-danger);
    border-radius: var(--radius-full);
}

/* Notification badge with count */
.admin-header-btn .notification-badge {
    position: absolute;
    top: 2px;
    right: 2px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    font-size: 11px;
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--text-on-brand);
    background-color: var(--brand-primary);
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* A hand up is a normal thing to see, so the icon goes brand-coloured, not red. */
.admin-header-btn.has-notification {
    color: var(--brand-primary);
}

.admin-header-btn.has-notification:hover {
    background-color: var(--brand-primary-alpha);
}

/* ===================================================================
   6. MAIN CONTENT AREA
   =================================================================== */

.admin-content {
    padding: var(--space-xl);
}

.admin-page-header {
    margin-bottom: var(--space-xl);
}

.admin-page-title {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--space-xs);
}

.admin-page-description {
    font-size: var(--font-size-base);
    color: var(--text-muted);
    margin: 0;
}

/* ===================================================================
   7. STAT CARDS
   =================================================================== */

.admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

.admin-stat-card {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-lg);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    transition: all var(--transition-fast);
}

.admin-stat-card:hover {
    border-color: var(--border-medium);
    box-shadow: var(--shadow-md);
}

/* A stat that filters the list below it when clicked (Students -> Locked).
   Focus styling comes from the global :focus-visible rule in core/base.css. */
.admin-stat-card.stat-card-action {
    cursor: pointer;
}

.admin-stat-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    font-size: var(--font-size-xl);
}

.admin-stat-icon.stat-primary {
    color: var(--brand-primary);
    background-color: var(--brand-primary-alpha);
}

.admin-stat-icon.stat-success {
    color: var(--color-success);
    background-color: var(--color-success-bg);
}

.admin-stat-icon.stat-warning {
    color: var(--color-warning-text);
    background-color: var(--color-warning-bg);
}

.admin-stat-icon.stat-danger {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.admin-stat-icon.stat-info {
    color: var(--color-info-text);
    background-color: var(--color-info-bg);
}

.admin-stat-content {
    flex: 1;
}

.admin-stat-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1;
    margin-bottom: var(--space-xs);
}

.admin-stat-label {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}

/* ===================================================================
   8. DASHBOARD GRID
   =================================================================== */

.admin-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: var(--space-lg);
}

.admin-grid-col-6 {
    grid-column: span 6;
}

.admin-grid-col-12 {
    grid-column: span 12;
}

@media (max-width: 1024px) {
    .admin-grid-col-6 {
        grid-column: span 12;
    }
}

/* ===================================================================
   9. RESPONSIVE
   =================================================================== */

@media (max-width: 992px) {
    .admin-sidebar {
        transform: translateX(-100%);
    }

    .admin-sidebar.is-mobile-open {
        transform: translateX(0);
    }

    .admin-main {
        margin-left: 0 !important;
    }

    .admin-overlay {
        display: none;
        position: fixed;
        inset: 0;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: calc(var(--z-fixed) - 1);
    }

    .admin-sidebar.is-mobile-open ~ .admin-overlay {
        display: block;
    }
}

/* ===================================================================
   10. THEME TOGGLE BUTTON
   =================================================================== */

.admin-header-btn.theme-toggle {
    position: relative;
}

.admin-header-btn.theme-toggle #themeIconDark,
.admin-header-btn.theme-toggle #themeIconLight {
    position: absolute;
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

/* Initially hide appropriate icon based on theme */
.admin-header-btn.theme-toggle #themeIconLight {
    display: none;
}

.admin-header-btn.theme-toggle #themeIconDark {
    display: none;
}

/* Active icon colors */
.admin-header-btn.theme-toggle:hover #themeIconDark {
    color: var(--brand-secondary);
}

.admin-header-btn.theme-toggle:hover #themeIconLight {
    color: var(--color-warning-text);
}

/* ===================================================================
   11. DARK MODE ADJUSTMENTS
   =================================================================== */

[data-theme="dark"] .admin-sidebar {
    background-color: var(--bg-surface);
}

[data-theme="dark"] .admin-nav-submenu {
    background-color: var(--bg-body);
}

/* ===================================================================
   12. USER DROPDOWN MENU
   =================================================================== */

.admin-user-menu {
    position: relative;
}

.admin-user-btn {
    font-size: var(--font-size-lg);
}

.admin-user-dropdown {
    position: absolute;
    top: calc(100% + var(--space-xs));
    right: 0;
    min-width: 200px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: all var(--transition-fast);
    z-index: var(--z-dropdown);
}

.admin-user-dropdown.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.user-dropdown-header {
    padding: var(--space-md);
    border-bottom: 1px solid var(--border-light);
}

.user-dropdown-name {
    display: block;
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
}

.user-dropdown-role {
    display: block;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    text-transform: capitalize;
    margin-top: 2px;
}

.user-dropdown-divider {
    height: 1px;
    background-color: var(--border-light);
    margin: 0;
}

.user-dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    text-decoration: none;
    transition: all var(--transition-fast);
}

.user-dropdown-item:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.user-dropdown-item i {
    width: 16px;
    text-align: center;
    color: var(--text-muted);
}

.user-dropdown-item:hover i {
    color: var(--text-primary);
}

.user-dropdown-logout {
    color: var(--color-danger);
}

.user-dropdown-logout:hover {
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
}

.user-dropdown-logout i {
    color: var(--color-danger);
}


