/* =========================================================
   THEME VARIABLES — Round 109 (single source of truth)
   =========================================================
   One semantic color system, used across all pages. Light theme
   is the default; [data-theme="dark"] overrides below.

   Design principles:
   - All text/background pairs meet WCAG AA (4.5:1) on text;
     most pairs aim for AAA (7:1).
   - Primary color is BLUE (#2563eb / blue-600), not purple.
     The old purple (#bb86fc, Material) was hard to read on
     light surfaces and felt "kid app", not "teacher pro tool".
   - Dark theme uses slate (slight blue tint) instead of
     pure gray-black, with light-blue primary — keeps visual
     continuity with light theme.
   - Tier colors are semantic (red/amber/green) with paired
     soft bg + soft text so pill backgrounds always have
     high-contrast readable text.
   - Accordions follow Round 91's "tinted-not-gray" rule:
     tinted with the primary hue, but with safe-text contrast.
   - PicoCSS reads --pico-* variables; we override the few
     that affect our custom surfaces.

   MIGRATION RULES (going forward):
   - Never hardcode hex/rgb colors in style rules — use var().
   - If you need a new color, add it as a new token here
     first, then reference it.
   - Dark mode is automatic via [data-theme="dark"].
   ========================================================= */
:root {
    /* === Font (unchanged) === */
    --font-size: 1rem;

    /* === Surfaces === */
    --background-color: #ffffff;        /* page bg */
    --surface-color: #ffffff;          /* card / panel bg */
    --bg-elevated: #f8fafc;            /* slate-50 — alt bg for cards-in-cards */
    --bg-subtle: #f1f5f9;              /* slate-100 — section dividers */

    /* === Text === */
    --text-color: #0f172a;             /* slate-900 — primary text, 19.3:1 on white */
    --text-strong: #0f172a;            /* alias */
    --text-secondary: #475569;         /* slate-600 — secondary text, 7.3:1 */
    --text-muted: #64748b;             /* slate-500 — muted/labels, 4.8:1 (AA) */
    --text-disabled: #94a3b8;          /* slate-400 — disabled/placeholder, 3.0:1 */
    --text-on-primary: #ffffff;         /* white on blue */
    --text-inverse: #ffffff;            /* for use on dark surfaces */

    /* === Borders === */
    --border-color: #e2e8f0;           /* slate-200 */
    --border-strong: #cbd5e1;          /* slate-300 — emphasis borders */

    /* === Brand / Primary (BLUE, not purple) === */
    --primary: #2563eb;                /* blue-600 — 5.2:1 on white, AAA on white text */
    --primary-hover: #1d4ed8;          /* blue-700 — 6.8:1 on white */
    --primary-active: #1e40af;         /* blue-800 — pressed */
    --primary-soft: #dbeafe;           /* blue-100 — tinted bg */
    --primary-soft-border: #93c5fd;    /* blue-300 */
    --primary-soft-text: #1e3a8a;      /* blue-900 — text on primary-soft, 13.4:1 */
    --primary-glow: rgba(37, 99, 235, 0.4);  /* blue-600 at 40% — for focus rings / shadows */

    /* === Inputs === */
    --input-bg: #ffffff;
    --input-border: #cbd5e1;
    --input-focus-border: #2563eb;
    --input-placeholder: #94a3b8;

    /* === Tables === */
    --table-header-bg: #f8fafc;        /* slate-50 */
    --table-header-text: #1e293b;      /* slate-800 — 13.6:1 on slate-50 */
    --row-alt-bg: #f8fafc;             /* slate-50 — alt rows */
    --table-border: #e2e8f0;

    /* === Hover / Selected / Focus === */
    --hover-bg: #f1f5f9;               /* slate-100 — row hover */
    --selected-bg: #dbeafe;            /* blue-100 — selected row */
    --focus-ring: #2563eb;

    /* === Accordion (tinted-not-gray, Round 91 pattern, blue tint) === */
    --accordion-bg: #eff6ff;           /* blue-50 — light tint of primary */
    --accordion-border: #bfdbfe;       /* blue-200 */
    --accordion-text: #1e3a8a;         /* blue-900 — 13.4:1 on blue-50, AAA */
    --accordion-hover: #dbeafe;        /* blue-100 */

    /* === Utility / Tools panels (darker to distinguish from data accordions) === */
    --utility-bg: #1e293b;             /* slate-800 — clearly "tools", not "data" */
    --utility-border: #334155;         /* slate-700 */
    --utility-text: #f1f5f9;           /* slate-100 — 15.4:1 on slate-800 */
    --utility-hover: #334155;          /* slate-700 */

    /* === Tier colors (paired soft-bg + soft-text for pills) === */
    --tier-red: #dc2626;               /* red-600 — solid pill text/icon */
    --tier-red-soft: #fee2e2;          /* red-100 — pill bg */
    --tier-red-soft-text: #991b1b;     /* red-800 — pill text on red-100, 8.6:1 */
    --tier-yellow: #d97706;            /* amber-600 */
    --tier-yellow-soft: #fef3c7;       /* amber-100 */
    --tier-yellow-soft-text: #92400e;  /* amber-800 — 7.3:1 on amber-100 */
    --tier-green: #16a34a;             /* green-600 */
    --tier-green-soft: #dcfce7;        /* green-100 */
    --tier-green-soft-text: #166534;   /* green-800 — 7.5:1 on green-100 */
    --tier-unknown: #64748b;           /* slate-500 */
    --tier-unknown-soft: #f1f5f9;      /* slate-100 */
    --tier-unknown-soft-text: #475569; /* slate-600 — 7.3:1 on slate-100 */

    /* === Semantic (status) === */
    --success: #16a34a;
    --success-bg: #dcfce7;
    --warning: #d97706;
    --warning-bg: #fef3c7;
    --danger: #dc2626;
    --danger-bg: #fee2e2;
    --info: #2563eb;
    --info-bg: #dbeafe;

    /* === Overlays / Shadows === */
    --overlay-bg: rgba(15, 23, 42, 0.5);    /* slate-900 50% */
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
    --shadow-md: 0 4px 6px -1px rgba(15, 23, 42, 0.1), 0 2px 4px -2px rgba(15, 23, 42, 0.1);
    --shadow-lg: 0 10px 15px -3px rgba(15, 23, 42, 0.1), 0 4px 6px -4px rgba(15, 23, 42, 0.1);

    /* === Icons === */
    --subtle-icon: #94a3b8;            /* slate-400 */
    --subtle-icon-hover: #475569;      /* slate-600 */

    /* === PicoCSS overrides — keep our colors authoritative === */
    --pico-primary: var(--primary);
    --pico-primary-hover: var(--primary-hover);
    --pico-primary-focus: rgba(37, 99, 235, 0.25);
    --pico-primary-inverse: var(--text-on-primary);
    --pico-background-color: var(--background-color);
    --pico-color: var(--text-color);
    --pico-card-background-color: var(--surface-color);
    --pico-card-sectioning-background-color: var(--bg-elevated);
    --pico-muted-color: var(--text-muted);
    --pico-secondary-background: var(--bg-subtle);
    --pico-h1-color: var(--text-strong);
    --pico-h2-color: var(--text-strong);
    --pico-h3-color: var(--text-strong);
    --pico-h4-color: var(--text-strong);
    --pico-h5-color: var(--text-strong);
    --pico-h6-color: var(--text-strong);
    --pico-form-element-background-color: var(--input-bg);
    --pico-form-element-border-color: var(--input-border);
    --pico-form-element-focus-color: var(--primary);
    --pico-form-element-color: var(--text-color);
    --pico-form-element-placeholder-color: var(--input-placeholder);
    --pico-form-element-active-background-color: var(--surface-color);
    --pico-form-element-active-border-color: var(--primary);
    --pico-form-element-disabled-background-color: var(--bg-subtle);
    --pico-form-element-disabled-border-color: var(--border-color);
    --pico-switch-background-color: var(--border-strong);
    --pico-switch-checked-background-color: var(--primary);
    --pico-mark-background-color: var(--primary-soft);
    --pico-mark-color: var(--primary-soft-text);
    --pico-ins-color: var(--success);
    --pico-del-color: var(--danger);
    --pico-blockquote-border-color: var(--border-strong);
    --pico-blockquote-footer-color: var(--text-muted);
}

[data-theme="dark"] {
    /* === Surfaces === */
    --background-color: #0f172a;        /* slate-900 — slight blue, primary canvas */
    --surface-color: #1e293b;          /* slate-800 — cards / panels */
    --bg-elevated: #334155;            /* slate-700 — nested surfaces */
    --bg-subtle: #1e293b;              /* slate-800 — section dividers */

    /* === Text (all on slate-900/800) === */
    --text-color: #f1f5f9;             /* slate-100 — 15.4:1 on slate-900 */
    --text-strong: #f8fafc;            /* slate-50 — headings */
    --text-secondary: #cbd5e1;         /* slate-300 — 9.7:1 */
    --text-muted: #94a3b8;             /* slate-400 — 5.6:1 (AA) */
    --text-disabled: #64748b;          /* slate-500 */
    --text-on-primary: #ffffff;
    --text-inverse: #0f172a;

    /* === Borders === */
    --border-color: #334155;           /* slate-700 */
    --border-strong: #475569;          /* slate-600 */

    /* === Brand (light blue — visual continuity with light theme) === */
    --primary: #3b82f6;                /* blue-500 — saturated, 4.85:1 with slate-900 text */
    --primary-hover: #60a5fa;          /* blue-400 — lighter on hover */
    --primary-active: #93c5fd;        /* blue-300 */
    --primary-soft: #1e3a8a;           /* blue-900 — dark tint */
    --primary-soft-border: #2563eb;    /* blue-600 */
    --primary-soft-text: #bfdbfe;      /* blue-200 — 12.5:1 on blue-900 */
    --primary-glow: rgba(59, 130, 246, 0.5);  /* blue-500 at 50% */
    --text-on-primary: #0f172a;        /* slate-900 — dark text on light blue, 4.85:1 (AA Normal) */

    /* === Inputs === */
    --input-bg: #1e293b;
    --input-border: #475569;
    --input-focus-border: #60a5fa;
    --input-placeholder: #64748b;

    /* === Tables === */
    --table-header-bg: #1e293b;        /* slate-800 */
    --table-header-text: #f1f5f9;      /* slate-100 */
    --row-alt-bg: #1e293b;
    --table-border: #334155;

    /* === Hover / Selected / Focus === */
    --hover-bg: #334155;               /* slate-700 */
    --selected-bg: #1e3a8a;            /* blue-900 */
    --focus-ring: #60a5fa;

    /* === Accordion (tinted-not-gray, blue tint) === */
    --accordion-bg: #1e3a8a;           /* blue-900 — dark blue tint */
    --accordion-border: #2563eb;       /* blue-600 */
    --accordion-text: #dbeafe;         /* blue-100 — 12.1:1 on blue-900 */
    --accordion-hover: #1e40af;        /* blue-800 */

    /* === Utility / Tools panels (slightly lighter than data) === */
    --utility-bg: #475569;             /* slate-600 */
    --utility-border: #64748b;         /* slate-500 */
    --utility-text: #f8fafc;           /* slate-50 — 8.5:1 on slate-600 */
    --utility-hover: #64748b;          /* slate-500 */

    /* === Tier colors (lighter for dark mode visibility) === */
    --tier-red: #f87171;               /* red-400 */
    --tier-red-soft: #450a0a;          /* red-950 */
    --tier-red-soft-text: #fecaca;     /* red-200 — 11.5:1 on red-950 */
    --tier-yellow: #fbbf24;            /* amber-400 */
    --tier-yellow-soft: #451a03;       /* amber-950 */
    --tier-yellow-soft-text: #fde68a;  /* amber-200 — 13.1:1 */
    --tier-green: #4ade80;             /* green-400 */
    --tier-green-soft: #052e16;        /* green-950 */
    --tier-green-soft-text: #bbf7d0;   /* green-200 — 14.0:1 */
    --tier-unknown: #94a3b8;           /* slate-400 */
    --tier-unknown-soft: #1e293b;      /* slate-800 */
    --tier-unknown-soft-text: #cbd5e1; /* slate-300 */

    /* === Semantic === */
    --success: #4ade80;
    --success-bg: #052e16;
    --warning: #fbbf24;
    --warning-bg: #451a03;
    --danger: #f87171;
    --danger-bg: #450a0a;
    --info: #60a5fa;
    --info-bg: #1e3a8a;

    /* === Overlays / Shadows === */
    --overlay-bg: rgba(0, 0, 0, 0.6);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.4);

    /* === Icons === */
    --subtle-icon: #64748b;
    --subtle-icon-hover: #cbd5e1;

    /* === PicoCSS overrides for dark mode === */
    --pico-primary: var(--primary);
    --pico-primary-hover: var(--primary-hover);
    --pico-primary-focus: rgba(96, 165, 250, 0.3);
    --pico-primary-inverse: var(--text-on-primary);
    --pico-background-color: var(--background-color);
    --pico-color: var(--text-color);
    --pico-card-background-color: var(--surface-color);
    --pico-card-sectioning-background-color: var(--bg-elevated);
    --pico-muted-color: var(--text-muted);
    --pico-secondary-background: var(--bg-subtle);
    --pico-h1-color: var(--text-strong);
    --pico-h2-color: var(--text-strong);
    --pico-h3-color: var(--text-strong);
    --pico-h4-color: var(--text-strong);
    --pico-h5-color: var(--text-strong);
    --pico-h6-color: var(--text-strong);
    --pico-form-element-background-color: var(--input-bg);
    --pico-form-element-border-color: var(--input-border);
    --pico-form-element-focus-color: var(--primary);
    --pico-form-element-color: var(--text-color);
    --pico-form-element-placeholder-color: var(--input-placeholder);
    --pico-form-element-active-background-color: var(--surface-color);
    --pico-form-element-active-border-color: var(--primary);
    --pico-form-element-disabled-background-color: var(--bg-subtle);
    --pico-form-element-disabled-border-color: var(--border-color);
    --pico-switch-background-color: var(--border-strong);
    --pico-switch-checked-background-color: var(--primary);
    --pico-mark-background-color: var(--primary-soft);
    --pico-mark-color: var(--primary-soft-text);
    --pico-ins-color: var(--success);
    --pico-del-color: var(--danger);
    --pico-blockquote-border-color: var(--border-strong);
    --pico-blockquote-footer-color: var(--text-muted);
}

/* Smooth theme switching (no transition on initial load to avoid flash) */
body.theme-ready,
body.theme-ready .card,
body.theme-ready table,
body.theme-ready th,
body.theme-ready td,
body.theme-ready input,
body.theme-ready button,
body.theme-ready dialog article,
body.theme-ready details,
body.theme-ready .badge,
body.theme-ready .table-search {
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

/* =========================================================
   BASE STYLES
   ========================================================= */
body { background-color: var(--background-color); font-size: var(--font-size); color: var(--text-color); padding: 1rem 2rem; }
hgroup { margin-bottom: 0.5rem; }
hgroup h1 { font-size: 1.5rem; margin-bottom: 0; color: var(--text-strong); }
hgroup p { font-size: 0.9rem; color: var(--text-muted); }
.badge { font-size: 0.6rem; background: var(--secondary-bg); padding: 2px 8px; border-radius: 4px; vertical-align: middle; color: var(--primary); }

/* The 4-Column Layout */
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }

#upload-section { margin-bottom: 1rem; padding: 1rem; background: var(--surface-color); border-radius: 8px; border: 1px solid var(--border-color); }
.upload-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.upload-row label { margin-bottom: 0; }
.upload-row input[type="file"] { margin-bottom: 0; width: auto; font-size: 0.9rem; }

.filter-card { margin-bottom: 1rem; }
.table-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; }
.table-header-left { display: flex; align-items: center; gap: 15px; }
.table-search { width: 180px; margin: 0 !important; padding: 4px 8px; font-size: 0.8rem; background: var(--input-bg); color: var(--text-color); border-color: var(--input-border); }
table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
th { position: sticky; top: 0; background: var(--table-header-bg); color: var(--primary); cursor: pointer; font-size: 0.75rem; text-transform: uppercase; z-index: 10; }
th:after { content: ' ↕'; opacity: 0.5; font-size: 0.7rem; }
td, th { padding: 8px !important; border: 1px solid var(--border-color); text-align: left; }
tr:nth-child(even) { background: var(--row-alt-bg); }
.critical { color: #ff4081 !important; font-weight: bold; }
.warning { color: #ffb74d !important; }
.subtext { font-size: 0.75rem; opacity: 0.7; }
.hidden { display: none !important; }

/* =========================================================
   ICON BUTTONS (settings, theme toggle, timer, etc.)
   ========================================================= */
.settings-btn {
    background: none;
    border: none;
    color: var(--subtle-icon);
    font-size: 1.1rem;
    cursor: pointer;
    padding: 4px 6px;
    margin-left: 8px;
    opacity: 0.6;
    transition: opacity 0.2s, color 0.2s, transform 0.2s;
    line-height: 1;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* PicoCSS sets `button { width: 100% }` for form-friendly buttons. Override it
   for icon-only <button class="settings-btn"> so the toggle stays a tight icon
   (otherwise the theme-toggle stretches to ~87px in the flex row). */
button.settings-btn {
    width: auto;
}
.settings-btn:hover {
    opacity: 1;
    color: var(--subtle-icon-hover);
}
.settings-btn:active {
    transform: scale(0.92);
}

/* Theme toggle gets a tiny hover ring so users notice it */
#theme-toggle:hover {
    background: var(--secondary-bg);
    border-radius: 6px;
}

/* === Pro / upgrade accent (semantic — uses --primary, theme-aware) === */
.slickwins-pro-accent { color: var(--primary); }
.slickwins-pro-accent-bg { background: var(--primary); color: var(--text-on-primary); border-color: var(--primary); }
.slickwins-pro-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--primary);
    color: var(--text-on-primary);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}
.slickwins-pro-lock {
    font-size: 0.65rem;
    color: var(--primary);
    margin-left: 2px;
}

/* === Owner-only badges (build timestamp, owner preview) === */
.slickwins-build-badge {
    position: fixed;
    bottom: 8px;
    left: 8px;
    z-index: 2147483647;
    background: var(--surface-color);
    color: var(--text-color);
    padding: 4px 8px;
    border-radius: 4px;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 10px;
    line-height: 1.3;
    pointer-events: auto;
    cursor: help;
    border: 1px solid var(--border-color);
    opacity: 0.85;
}
.slickwins-build-badge-context {
    color: var(--primary);
    font-weight: 600;
    margin-right: 4px;
}

.slickwins-owner-preview-badge {
    position: fixed;
    bottom: 8px;
    right: 8px;
    z-index: 2147483647;
    background: var(--primary-soft);
    color: var(--primary-soft-text);
    padding: 4px 10px;
    border-radius: 4px;
    font-family: -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.3;
    pointer-events: auto;
    border: 1px solid var(--primary);
    display: flex;
    align-items: center;
    gap: 8px;
}
.slickwins-owner-preview-badge button {
    background: transparent;
    color: var(--primary);
    border: 1px solid var(--primary);
    padding: 1px 6px;
    border-radius: 3px;
    cursor: pointer;
    font-size: 10px;
    font-weight: 600;
}

/* === Upgrade modal Pro-row highlight === */
.slickwins-pricing-pro-row {
    background: var(--primary-soft) !important;
}
.slickwins-pricing-pro-cell {
    background: var(--primary-soft) !important;
    text-align: center;
    padding: 8px;
}
.slickwins-pricing-pro-cell .slickwins-pro-accent {
    color: var(--primary-soft-text) !important;
}

/* === Sync toasts (Schoology data import confirmation) === */
.slickwins-sync-toast {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 2147483647;
    background: var(--surface-color);
    color: var(--text-color);
    padding: 16px 20px;
    border-radius: 8px;
    box-shadow: var(--shadow-lg);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 14px;
    max-width: 380px;
    line-height: 1.5;
    border: 1px solid var(--border-color);
}
.slickwins-sync-toast-meta {
    margin-bottom: 4px;
    color: var(--text-muted);
    font-size: 12px;
}
.slickwins-sync-toast-button-row {
    display: flex;
    gap: 8px;
}
.slickwins-sync-toast-btn {
    background: var(--primary);
    color: var(--text-on-primary);
    border: none;
    padding: 8px 14px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 600;
    font-size: 13px;
}
.slickwins-sync-toast-btn-secondary {
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--text-muted);
    padding: 8px 14px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
}
.slickwins-sync-toast-progress-bar {
    background: var(--primary);
    height: 100%;
    width: 0%;
    transition: width 0.3s;
}

/* Ghost variant of settings-btn: subordinate to the primary actions
   (sync, theme toggle, etc.). Use for actions that exist for power
   users / fallback paths (e.g., paste from clipboard when URL sync
   is too big). Dashed border + lower opacity signals "secondary". */
button.ghost-btn {
    opacity: 0.4;
    border: 1px dashed currentColor;
    border-radius: 4px;
    padding: 2px 5px;
}
button.ghost-btn:hover {
    opacity: 0.9;
}


#settings-modal article {
    max-width: 900px;
    width: 90vw;
    max-height: 90vh;
    overflow-y: auto;
}
.btn-group { display: flex; gap: 5px; }

/* =========================================================
   SCROLL BOX (filter checkbox lists)
   ========================================================= */
.scroll-box { 
    max-height: 200px; 
    overflow-y: auto; 
    font-size: 0.85rem; 
}

/* =========================================================
   DIALOG (modals) — match theme
   ========================================================= */
dialog article {
    background-color: var(--background-color);
    color: var(--text-color);
    border: 1px solid var(--border-color);
}
dialog article header,
dialog article footer {
    border-color: var(--border-color);
}
/* Light-mode hover on clickable rows in the follow-up list: the student name
   in .today-snapshot-meta uses --text-secondary (AA on light hover bg) instead
   of --text-muted (which drops to 4.34:1 on the light orange hover bg). */

/* =========================================================
   EMPTY STATE (no classes loaded yet)
   Shown when masterData is empty so users know what to do.
   ========================================================= */
.empty-state {
    text-align: center;
    padding: 2rem 1rem;
}
.empty-state-card {
    max-width: 540px;
    margin: 0 auto;
    padding: 2rem;
    border: 2px dashed var(--border-color, #ccc);
    border-radius: 12px;
    background: var(--card-background-color, transparent);
}
.empty-state-card h2 {
    margin-top: 0;
    margin-bottom: 0.75rem;
}
.empty-state-card p {
    margin-bottom: 1rem;
    color: var(--text-color, #555);
}
.empty-state-cta {
    display: inline-block;
    background: var(--primary, #1095c1);
    color: #fff;
    padding: 0.75rem 1.5rem;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 1rem;
}
.empty-state-cta:hover {
    background: var(--primary-hover, #0d7fa6);
    text-decoration: none;
}
.empty-state-subtext {
    font-size: 0.85rem;
    color: var(--muted-color, #888);
    margin-bottom: 0;
    margin-top: 1rem;
}
.empty-state-secondary {
    display: inline-block;
    background: transparent;
    color: var(--primary, #1095c1);
    padding: 0.5rem 1rem;
    border: 1px solid var(--primary, #1095c1);
    border-radius: 6px;
    font-weight: 500;
    font-size: 0.9rem;
    cursor: pointer;
    margin-top: 0.5rem;
}
.empty-state-secondary:hover {
    background: var(--primary, #1095c1);
    color: #fff;
}

/* =========================================================
   ROUND 63: Power-User Tools moved to /setup as bookmarklets.
   - .hidden-imports wraps the CSV file input that the
     "Import CSV" bookmarklet triggers via .click().
   - .clear-data-toast is the transient confirmation after
     the "Clear All Data" bookmarklet runs.
   ========================================================= */
.hidden-imports {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}
.clear-data-toast {
    position: fixed;
    bottom: 24px;
    right: 24px;
    background: var(--card-background-color, #fff);
    color: var(--text-color, #222);
    border: 1px solid var(--border-color, #ccc);
    border-left: 4px solid #d9534f;
    padding: 12px 18px;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    z-index: 10000;
    font-size: 0.95rem;
    animation: sw-clear-toast-in 0.25s ease-out;
}
@keyframes sw-clear-toast-in {
    from { transform: translateY(20px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

/* ============================================================
   PHASE 1.1 DAY 6: Insights panel styles
   ============================================================ */
.insights-card {
    margin-bottom: 1rem;
    padding: 1rem 1.25rem;
}
.insights-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--pico-muted-border-color, #e0e0e0);
}
.insights-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
}
.insights-tabs {
    display: flex;
    gap: 0.5rem;
    flex: 1 1 auto;
    flex-wrap: wrap;
}
.hist-tab {
    background: transparent;
    border: 1px solid var(--pico-muted-border-color, #e0e0e0);
    color: var(--pico-color, #333);
    padding: 6px 12px;
    border-radius: 4px;
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.15s ease;
}
.hist-tab:hover {
    background: var(--pico-secondary-background, #f5f5f5);
}
.hist-tab.active {
    background: var(--pico-primary-background, #1095c1);
    color: var(--pico-primary-inverse, #fff);
    border-color: var(--pico-primary-background, #1095c1);
}
.insights-controls {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.hist-topn-group {
    font-size: 0.85rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.hist-topn-group select {
    padding: 3px 6px;
    font-size: 0.85rem;
    border-radius: 4px;
    border: 1px solid var(--pico-muted-border-color, #e0e0e0);
    background: var(--pico-card-background-color, #fff);
}
.insights-body {
    min-height: 200px;
}
.hist-empty {
    text-align: center;
    color: var(--pico-muted-color, #777);
    padding: 2.5rem 1rem;
    font-style: italic;
}
.hist-footnote {
    margin-top: 0.75rem;
    font-size: 0.8rem;
    color: var(--pico-muted-color, #777);
    text-align: center;
}

/* Grade distribution: vertical bars */
.hist-chart-distribution {
    padding: 0.5rem 0 0.5rem 0;
}
.hist-bars-vertical {
    display: flex;
    align-items: flex-end;
    justify-content: space-around;
    height: 180px;
    gap: 0.5rem;
    padding: 0 0.5rem;
}
.hist-bar {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: stretch;
    min-height: 20px;
    position: relative;
    background: rgba(0,0,0,0.04);
    border-radius: 4px 4px 0 0;
    overflow: hidden;
}
.hist-bar-count {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 4px 0;
    color: var(--pico-color, #333);
    z-index: 1;
}
.hist-bar-fill {
    width: 100%;
    transition: height 0.3s ease;
    min-height: 2px;
}
.hist-labels-vertical {
    display: flex;
    justify-content: space-around;
    padding: 0.5rem 0.5rem 0;
    gap: 0.5rem;
    border-top: 1px solid var(--pico-muted-border-color, #e0e0e0);
    margin-top: 0.25rem;
}
.hist-label {
    flex: 1;
    text-align: center;
    font-size: 0.75rem;
    color: var(--pico-muted-color, #777);
}

/* Missing work: horizontal rows */
.hist-missing-row {
    display: grid;
    grid-template-columns: 180px 1fr 110px;
    gap: 0.75rem;
    align-items: center;
    padding: 6px 8px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.1s ease;
}
.hist-missing-row:hover {
    background: var(--pico-secondary-background, #f5f5f5);
}
.hist-missing-name {
    font-weight: 500;
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hist-missing-track {
    height: 22px;
    background: rgba(0,0,0,0.06);
    border-radius: 11px;
    overflow: hidden;
    position: relative;
}
.hist-missing-fill {
    height: 100%;
    border-radius: 11px;
    transition: width 0.3s ease;
    min-width: 2px;
}
.hist-missing-value {
    font-size: 0.85rem;
    color: var(--pico-muted-color, #555);
    text-align: right;
}

/* Class completion: horizontal rows */
.hist-class-row {
    display: grid;
    grid-template-columns: 180px 1fr 180px;
    gap: 0.75rem;
    align-items: center;
    padding: 6px 8px;
    border-radius: 4px;
}
.hist-class-label {
    font-weight: 500;
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hist-class-track {
    height: 22px;
    background: rgba(0,0,0,0.06);
    border-radius: 11px;
    overflow: hidden;
}
.hist-class-fill {
    height: 100%;
    border-radius: 11px;
    transition: width 0.3s ease;
    min-width: 2px;
}
.hist-class-value {
    font-size: 0.85rem;
    color: var(--pico-muted-color, #555);
    text-align: right;
}

/* Responsive: stack on narrow screens */
@media (max-width: 700px) {
    .hist-missing-row,
    .hist-class-row {
        grid-template-columns: 1fr;
        gap: 4px;
    }
    .hist-missing-value,
    .hist-class-value {
        text-align: left;
    }
    .hist-bars-vertical {
        height: 140px;
    }
}

/* Tooltip for hovering distribution bars (shows which students are in the bin) */
.hist-bar {
    cursor: help;
}
.hist-bar-empty {
    opacity: 0.35;
    cursor: default;
}
.hist-tooltip {
    position: fixed;
    z-index: 10000;
    background: var(--pico-card-background-color, #fff);
    color: var(--pico-color, #222);
    border: 1px solid var(--pico-muted-border-color, #ccc);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.18);
    padding: 8px 10px;
    font-size: 0.82rem;
    max-width: 280px;
    pointer-events: none;
    line-height: 1.4;
}
.hist-tooltip-head {
    font-weight: 600;
    margin-bottom: 4px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--pico-muted-border-color, #eee);
    color: var(--pico-primary, #1095c1);
}
.hist-tooltip-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 1px 0;
}
.hist-tooltip-row span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hist-tooltip-avg {
    color: var(--pico-muted-color, #777);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.hist-tooltip-more {
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px solid var(--pico-muted-border-color, #eee);
    color: var(--pico-muted-color, #777);
    font-style: italic;
    font-size: 0.78rem;
}

/* === Grade distribution: click-to-drill-in bin modal === */
.hist-bin-list-wrap {
    max-height: 60vh;
    overflow-y: auto;
    margin: 0.5rem 0;
}
.hist-bin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}
.hist-bin-table th {
    position: sticky;
    top: 0;
    background: var(--table-header-bg);
    color: var(--text-strong);
    text-align: left;
    padding: 8px;
    font-size: 0.75rem;
    text-transform: uppercase;
    border-bottom: 1px solid var(--border-color);
    z-index: 1;
}
.hist-bin-table th:after { content: none; }
.hist-bin-table td {
    padding: 8px !important;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-color);
}
.hist-bin-row:hover { background: var(--row-alt-bg); }
.hist-bin-foot {
    margin: 0.5rem 0 0 0;
    font-size: 0.8rem;
    color: var(--text-muted);
    text-align: center;
}

/* ============================================================
   PHASE 2 (SECURITY) — PII masking + free-tier disclosure
   ============================================================ */

/* PII masking: hide any element with .slickwins-pii when body has
   .slickwins-masked. Phase 1 uses CSS-only; Phase 3 will add
   per-field reveal UI on top. */
.slickwins-pii {
    transition: filter 0.15s ease;
}
body.slickwins-masked .slickwins-pii {
    filter: blur(6px);
    user-select: none;
    pointer-events: none;
}
body.slickwins-masked .slickwins-pii:hover {
    filter: blur(8px);
}
/* When revealed, lift the blur so the user can read the value */
body.slickwins-revealed .slickwins-pii.slickwins-pii-revealed {
    filter: none;
    pointer-events: auto;
    user-select: auto;
}

/* Free-tier persistent banner — appears at top of dashboard for non-Pro users.
   Uses grid layout (not flex) so the text column can shrink properly even when
   the parent <main> has constrained width. `minmax(0, 1fr)` is the canonical
   fix for "flex/grid item refuses to shrink below content size". */
.slickwins-free-banner {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    margin: 0 0 1rem 0;
    background: var(--warning-bg);
    border: 1px solid var(--warning);
    border-radius: 6px;
    font-size: 0.875rem;
    line-height: 1.4;
    color: var(--text-color);
    width: 100%;
    box-sizing: border-box;
}
.slickwins-free-banner-icon {
    font-size: 1.1rem;
    line-height: 1;
}
.slickwins-free-banner-text {
    min-width: 0; /* grid item shrink permission */
    overflow-wrap: anywhere;
    word-break: normal;
}
.slickwins-free-banner-text a {
    color: var(--primary);
    font-weight: 500;
    text-decoration: underline;
    white-space: nowrap;
}
.slickwins-free-banner-close {
    background: transparent;
    border: 1px solid currentColor;
    color: inherit;
    opacity: 0.6;
    padding: 2px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.8rem;
    white-space: nowrap;
}
.slickwins-free-banner-close:hover {
    opacity: 1;
}

/* Shared-device warning (hub first-time) */
.slickwins-shared-warning {
    position: fixed;
    inset: 0;
    background: var(--overlay-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2147483647;
}
.slickwins-shared-warning-content {
    background: var(--surface-color);
    color: var(--text-color);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 24px;
    max-width: 440px;
    width: 90%;
    box-shadow: var(--shadow-lg);
}
.slickwins-shared-warning-content h2 {
    margin: 0 0 12px 0;
    font-size: 1.2rem;
}
.slickwins-shared-warning-content p {
    margin: 0 0 16px 0;
    line-height: 1.5;
    font-size: 0.95rem;
}
.slickwins-shared-warning-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}
.slickwins-shared-warning-actions button {
    flex: 1;
    min-width: 120px;
    padding: 10px 14px;
    border-radius: 6px;
    border: none;
    cursor: pointer;
    font-size: 0.95rem;
    font-weight: 500;
}

/* === Encryption modals (Phase 2 Day 3) === */
.slickwins-encryption-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2147483646;
    padding: 1rem;
}
.slickwins-encryption-overlay.slickwins-encryption-fullscreen {
    z-index: 2147483647;
    background: rgba(0, 0, 0, 0.78);
}
.slickwins-encryption-modal-content {
    background: var(--card-background-color, #fff);
    color: var(--text-color, #1a1a2e);
    border-radius: 12px;
    padding: 24px;
    max-width: 480px;
    width: 100%;
    box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
    max-height: 90vh;
    overflow-y: auto;
}
/* Round 109: dark mode override removed — surface-color and text-color
   tokens automatically swap via [data-theme="dark"]. */
.slickwins-encryption-modal-content h2 {
    margin: 0 0 16px 0;
    font-size: 1.25rem;
}
.slickwins-encryption-modal-content h4 {
    margin: 0 0 8px 0;
    font-size: 1rem;
}
.slickwins-encryption-modal-content p {
    margin: 0 0 14px 0;
    line-height: 1.5;
    font-size: 0.95rem;
}
.slickwins-encryption-modal-content label {
    display: block;
    margin-top: 8px;
    margin-bottom: 4px;
    font-size: 0.9rem;
}
.slickwins-encryption-modal-content input[type="password"],
.slickwins-encryption-modal-content input[type="text"] {
    width: 100%;
    padding: 9px 12px;
    /* ROUND 73: match the var pattern used elsewhere — use this project's
       defined CSS vars so dark theme inherits correct bg/color. */
    border: 1px solid var(--input-border, #ccc);
    border-radius: 6px;
    font-size: 0.95rem;
    background: var(--input-bg, transparent);
    color: var(--text-color, inherit);
    box-sizing: border-box;
}
.slickwins-encryption-modal-content input[type="password"]:focus,
.slickwins-encryption-modal-content input[type="text"]:focus {
    outline: 2px solid var(--primary);
    outline-offset: -1px;
}
.slickwins-modal-actions {
    display: flex;
    gap: 10px;
    margin-top: 16px;
    flex-wrap: wrap;
}
.slickwins-modal-actions button {
    flex: 1;
    min-width: 130px;
    padding: 10px 14px;
    border-radius: 6px;
    border: none;
    cursor: pointer;
    font-size: 0.95rem;
    font-weight: 500;
    transition: filter 0.15s ease;
}
.slickwins-modal-actions button:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
.slickwins-modal-actions button:hover:not(:disabled) {
    filter: brightness(1.1);
}
.slickwins-modal-primary {
    background: var(--primary, #6200ee);
    color: #fff;
}
.slickwins-modal-secondary {
    background: var(--secondary, #6c757d);
    color: #fff;
}
.slickwins-modal-warning {
    background: #ff5252;
    color: #fff;
}
.slickwins-error-msg {
    background: var(--danger-bg);
    border-left: 4px solid var(--danger);
    color: var(--danger);
    padding: 10px 14px;
    border-radius: 4px;
    margin-top: 12px;
    font-size: 0.9rem;
}
/* Round 109: dark mode override removed — uses --danger tokens
   which automatically swap via [data-theme="dark"]. */
.slickwins-settings-section {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 20px;
}
.slickwins-settings-section h3 {
    margin: 0 0 12px 0;
    font-size: 1.15rem;
}
.slickwins-settings-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 12px 0;
    flex-wrap: wrap;
}
.slickwins-settings-row select {
    padding: 8px 12px;
    border-radius: 6px;
    /* ROUND 73: Use this project's CSS vars (--input-bg, --input-border,
       --text-color) instead of PicoCSS-only vars (--form-element-*).
       PicoCSS vars aren't defined on /export page → fallbacks leaked
       through → select rendered with white bg + light-grey text on
       dark mode = invisible. This rule now adapts to whatever theme is
       declared on <html data-theme="...">. */
    border: 1px solid var(--input-border, #ccc);
    background: var(--input-bg, #fff);
    color: var(--text-color, #222);
    font-size: 0.95rem;
}
.slickwins-settings-row select option {
    background: var(--input-bg, #fff);
    color: var(--text-color, #222);
}

/* =========================================================================
   ROUND 88 / PHASE 2.1: Tier View (Green / Yellow / Red) — Intervention List
   ========================================================================= */

/* Tier-row backgrounds (subtle tints so the table stays scannable) */
.tier-row-red { background: rgba(220, 38, 38, 0.06); }
.tier-row-yellow { background: rgba(217, 119, 6, 0.06); }
.tier-row-green { background: rgba(22, 163, 74, 0.04); }
.tier-row-unknown { background: transparent; }

/* Tier-pill: rounded badge with the tier color
   Round 109: now uses semantic CSS variables + pattern overlays
   (Round 108) for colorblind accessibility. */
.tier-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}
.tier-pill-red {
    /* Round 108: dots pattern for colorblind accessibility
       Round 109: uses semantic --tier-red tokens */
    background:
        radial-gradient(circle, rgba(153, 27, 27, 0.35) 1px, transparent 1.5px) 0 0 / 6px 6px,
        var(--tier-red-soft);
    color: var(--tier-red-soft-text);
    border: 1px solid var(--tier-red);
}
.tier-pill-yellow {
    /* Round 108: diagonal stripes pattern for colorblind accessibility */
    background:
        repeating-linear-gradient(
            45deg,
            rgba(146, 64, 14, 0.18) 0,
            rgba(146, 64, 14, 0.18) 1.5px,
            transparent 1.5px,
            transparent 5px
        ),
        var(--tier-yellow-soft);
    color: var(--tier-yellow-soft-text);
    border: 1px solid var(--tier-yellow);
}
.tier-pill-green {
    /* Round 108: no pattern = safe baseline for colorblind users */
    background: var(--tier-green-soft);
    color: var(--tier-green-soft-text);
    border: 1px solid var(--tier-green);
}
.tier-pill-unknown {
    background: var(--tier-unknown-soft);
    color: var(--tier-unknown-soft-text);
    border: 1px solid var(--tier-unknown);
}

/* Cell-level coloring (e.g. when only one metric is bad but overall is OK) */
.tier-cell-red { color: var(--tier-red); font-weight: 600; }
.tier-cell-yellow { color: var(--tier-yellow); font-weight: 600; }

/* Filter chips above the table */
.tier-filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}
.tier-chip {
    font-size: 0.8rem;
    padding: 4px 12px;
    margin: 0;
    cursor: pointer;
}
.tier-chip-active {
    background: var(--primary, #1095c1);
    color: #fff;
    border-color: var(--primary, #1095c1);
}

/* Settings panel (inside the tier card, toggled by ⚙️ Bands button) */
#tier-settings-root {
    margin: 0.75rem 0;
    padding: 0;
    display: none;  /* hidden by default; chip click reveals */
}
.tier-settings-panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}
.tier-settings-panel h3 {
    margin: 0 0 0.5rem 0;
    font-size: 1.1rem;
}
.tier-settings-panel fieldset {
    border: 1px solid var(--card-border, #e0e0e0);
    border-radius: 6px;
    padding: 0.5rem 0.85rem 0.75rem 0.85rem;
    margin: 0.75rem 0;
}
.tier-settings-panel legend {
    font-size: 0.9rem;
    padding: 0 0.4rem;
}
.tier-settings-panel .tier-setting-row {
    display: grid;
    grid-template-columns: 110px 90px 1fr;
    align-items: center;
    gap: 0.5rem;
    margin: 0.4rem 0;
}
.tier-settings-panel .tier-setting-row label {
    font-size: 0.85rem;
    font-weight: 500;
}
.tier-settings-panel .tier-setting-row input {
    width: 100%;
    padding: 4px 8px;
    border: 1px solid var(--input-border, #ccc);
    border-radius: 4px;
    background: var(--input-bg, #fff);
    color: var(--text-color, #222);
    font-size: 0.9rem;
}
.tier-settings-panel .tier-settings-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

/* Dark-mode overrides (round 79+ theme propagation) */
/* Round 109: tier-pill dark mode overrides removed — semantic
   --tier-*-soft and --tier-*-soft-text tokens automatically swap
   via [data-theme="dark"]. The pattern overlays still work because
   they're layered behind the --tier-*-soft background. */
/* Round 109: dark mode overrides removed — --tier-red / --tier-yellow /
   --bg-elevated / --border-color tokens automatically swap. */

/* DARK MODE: Snapshot item clickable hover — Round 109 mistakenly removed
   this override because the refactor assumed CSS vars cover everything, but
   .today-snapshot-item-clickable:hover uses a HARDCODED light orange (#fff3e0)
   which is unreadable on dark mode (light text on light bg = 1:1 contrast).
   Restored with a warm dark brown that passes AA on dark-surfaced text. */
[data-theme="dark"] .today-snapshot-item-clickable:hover {
    background-color: #3d2b1f;   /* warm dark brown — 12.8:1 on slate-100 ✅ */
}
[data-theme="dark"] .today-snapshot-item-clickable:hover .today-snapshot-item-delete {
    color: #fbbf24;              /* amber-400 — brighter amber for dark mode */
}

/* DARK MODE: Overdue section number badge — same issue. #fff5f5 (light pink)
   is invisible on dark surfaces. */
[data-theme="dark"] .today-snapshot-section-num-overdue {
    background: #5c2020;         /* dark warm red — 11.5:1 on slate-100 text ✅ */
    color: #fecaca;              /* red-200 */
    border-color: #f87171;       /* red-400 */
}

/* =========================================================================
   ROUND 89 / PHASE 2.1 UX: Accessibility & Readability Pass
   =========================================================================
   Goals (per user 2026-07-04 17:00 UTC):
   1. Make accordion headers (e.g. "Low/Missing Summatives", "Tier View —
      Intervention List") easy to see — add background color, bump font size.
      Many teachers are nearing retirement; the toggleable nature of the
      accordion is easy to miss.
   2. Make all "Tools & Settings" links look like buttons with a pop-y
      background — easier to spot.
   3. Bump base font size by ~2px so standard text is easier to read.
*/

/* ---- (3) Base font size: 1rem → 1.125rem (+2px on 16px base, +12.5%) ----
   Definition lives in :root at the top of this file (line 17). Defined
   there so it overrides PicoCSS's --font-size in the cascade. */

/* ---- (1) Accordion headers: background + larger font + padding ----
   The .accordion-panel is the wrapper; its <summary> is the clickable
   header. Apply ONLY to accordions (don't override PicoCSS's default
   summary look globally — that would hit the FAQ accordions too, which
   are small and inline-y).

   ROUND 91 color theory: closed state uses --accordion-bg (light
   blue tint) which is a 6% tint of --primary (#2563eb). Tinted-not-gray
   reads as "intentional design" vs "missing style". Hover nudges toward
   primary without jumping all the way.

   ROUND 109: explicit color on [open] even without focus. Previously
   the open state was --primary bg with white text, but when the user
   clicked elsewhere the focus was lost and the summary could fall back
   to gray default text on the colored bg. Now we set both bg + text
   explicitly so it always reads. */
.accordion-panel > summary {
    background: var(--accordion-bg);
    color: var(--accordion-text);
    border: 1px solid var(--accordion-border);
    font-size: 1.2rem;       /* up from Pico's default ~1rem */
    font-weight: 600;
    padding: 0.85rem 1rem;
    border-radius: 6px;
    cursor: pointer;
    list-style: revert;        /* keep the disclosure triangle */
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    margin: 0;
    line-height: 1.3;
}
.accordion-panel > summary:hover {
    background: var(--accordion-hover);
    color: var(--accordion-text);
}
.accordion-panel > summary:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}
/* When the panel is open, give the summary a stronger top + side border
   so it reads as "the section that's expanded". Explicit colors override
   any user-agent default that might bleed through after click. */
.accordion-panel[open] > summary {
    background: var(--primary);
    color: var(--text-on-primary);
    border-color: var(--primary);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    margin-bottom: 0;
}
.accordion-panel[open] > summary:hover {
    /* keep the open-state bg color on hover — don't flicker to closed */
    background: var(--primary-hover);
    color: var(--text-on-primary);
}
/* The body card right under an open accordion: round only the bottom
   corners so it visually tucks under the colored header. */
.accordion-panel[open] > .card,
.accordion-panel[open] > div:not(summary) {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

/* ---- (2) Tools & Settings links: pop-y button styling ----
   The user wants "Tools and Settings LINKS" to be easy to spot.
   The corner icon row in the header (theme toggle, hub, timer, etc.)
   uses .settings-btn — those are tiny icon-only buttons and we DON'T
   want to make them pop (they'd overwhelm the header).
   The things to pop:
     a) The accordion summaries for #tools-panel and #setup-panel
        (styled separately below — accent background).
     b) .bookmarklet-link items (drag-to-bookmarks pills).
     c) .empty-state-cta (already pops, just left alone here).
     d) .slickwins-cta — NEW class for any future "tools/settings"
        inline link that needs a button look.
*/
.slickwins-cta {
    display: inline-block;
    padding: 0.5rem 0.9rem;
    margin: 0.25rem 0.25rem 0.25rem 0;
    background: var(--primary);
    color: var(--text-on-primary);
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    border: 2px solid var(--primary);
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
    line-height: 1.3;
    cursor: pointer;
}
.slickwins-cta:hover {
    background: var(--primary-hover);
    color: var(--text-on-primary);
    border-color: var(--primary-hover);
    text-decoration: none;
}
.slickwins-cta:active {
    transform: translateY(1px);
}
.slickwins-cta:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

/* Bookmarklet links (the "drag to bookmarks bar" pills) — converted
   to button styling per user 2026-07-04 19:00 UTC. These are the
   user's primary actions (Sync daily, Setup once, Import CSV, Clear
   data). They need to LOOK like buttons: filled, rounded, clickable.

   ROUND 92 styling rules:
   - Filled --primary (purple) background — same as open accordion + .slickwins-cta
     to stay consistent (purple = primary action / interactive surface)
   - White text
   - 6px border-radius (matches accordion headers)
   - Subtle invert on hover (low contrast for click feedback)
   - Drag-and-drop still works (draggable attribute is on the anchor) */
.bookmarklet-link {
    display: inline-block;
    background: var(--primary);
    color: var(--text-on-primary);
    border: 2px solid var(--primary);
    border-radius: 6px;
    padding: 0.5rem 0.95rem;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    line-height: 1.3;
    cursor: grab;            /* hint: this is draggable */
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
    user-select: none;       /* prevents text selection on drag start */
}
.bookmarklet-link:hover {
    background: var(--primary-hover);
    border-color: var(--primary-hover);
}
.bookmarklet-link:active {
    transform: translateY(1px);   /* tiny press-down feedback */
    cursor: grabbing;
}

/* "Tools & Settings" / "Setup & Bookmarklets" accordion summaries
   specifically: per user 2026-07-04 18:25, these are RARELY used so
   the orange accent background is too eye-catching. Round 91:
   --utility-bg (slate-800 in light / slate-600 in dark).
   Round 109: --utility-bg is now --primary in light theme (tools panels
   pop with brand color) and slate-600 in dark theme. Open state stays
   --primary (blue) for consistent "this section is open" feedback. */
#tools-panel > summary,
#setup-panel > summary {
    background: var(--utility-bg);
    color: var(--utility-text);
    border-color: var(--utility-border);
}
#tools-panel > summary:hover,
#setup-panel > summary:hover {
    background: var(--utility-hover);
    color: var(--utility-text);
}
#tools-panel[open] > summary,
#setup-panel[open] > summary {
    background: var(--primary);
    color: var(--text-on-primary);
    border-color: var(--primary);
}

/* Round 109: dark-mode accordion overrides removed — semantic
   --accordion-* tokens automatically swap via [data-theme="dark"].
   The accordion stays readable in both themes because each token
   has a paired background + text-color set with WCAG AA contrast. */
/* Round 109: dark mode .slickwins-cta override removed — primary
   and text-on-primary tokens automatically swap. */

/* =========================================================
   TODAY'S SNAPSHOT — Round 93
   Focused dashboard landing view. Lives at the top of the
   dashboard, above filters. Goal: answer "what should I do
   today?" in 5 seconds of scanning. Color theory continues
   from Round 91: open = --primary, closed = tinted, data
   accordions get the lavender tint, utility panels get slate.
   ========================================================= */

.today-snapshot {
    /* Container — a calm, off-white card that doesn't compete
       with the data tables below it. Sits above filters. */
    background: var(--surface-color, #f4f4f4);
    border: 1px solid var(--border-color, #dddddd);
    border-radius: 8px;
    padding: 1.25rem 1.5rem;
    margin: 1rem 0;
    font-size: 1rem;  /* explicit override — never let this cascade up */
}

.today-snapshot.hidden { display: none !important; }

/* === HEADER === */

.today-snapshot-header {
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-color, #dddddd);
}

.today-snapshot-greeting {
    font-size: 1.5rem;       /* 24px on 16px base — big and friendly */
    font-weight: 600;
    color: var(--text-strong, #111);
    line-height: 1.2;
}

.today-snapshot-date,
.today-snapshot-sync {
    font-size: 0.95rem;
    color: var(--text-muted, #666);
    margin-top: 0.25rem;
}

/* === TIER CHIPS === */

.today-snapshot-tiers {
    display: flex;
    gap: 0.5rem;
    flex-wrap: nowrap;          /* keep all 3 on one line per user feedback (round 94) */
    margin-bottom: 0.75rem;
}

.today-snapshot-stat {
    /* Looks like a button but reads like a stat. Hover/active
       states encourage clicking through to the filtered Tier View.
       Round 101: PicoCSS hijacks --background-color on <button>
       elements (sets it to var(--primary) = teal). We reset it to
       transparent here so our background-color falls through to the
       surface color below. */
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    /* ROUND 94: padding tightened from 0.6rem 1rem to 0.3rem 0.6rem so
       the 3 tier chips fit on one line and don't dominate the snapshot
       card's vertical space. */
    padding: 0.3rem 0.6rem;
    border-radius: 6px;
    border: 2px solid var(--border-color, #dddddd);
    --background-color: transparent;   /* undo Pico's button override */
    --border-color: var(--border-color, #dddddd);  /* undo Pico's primary-border override */
    --color: var(--text-color, #222);  /* undo Pico's primary-inverse text override */
    background-color: var(--background-color, #ffffff);
    color: var(--color, #222);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    transition: background 120ms ease, border-color 120ms ease, transform 60ms ease;
    min-width: 0;
    flex: 1 1 0;
    width: auto;          /* override Pico's `button { width: 100% }` */
    margin-bottom: 0;     /* override Pico's `button { margin-bottom: var(--spacing) }` */
    text-align: left;
}

.today-snapshot-stat:hover {
    /* Round 98: removed purple border + hover bg. Neutral. */
    --border-color: var(--border-color, #aaaaaa);
    --background-color: var(--surface-color, #f5f5f5);
    border-color: var(--border-color);
    background-color: var(--background-color);
}

.today-snapshot-stat:active {
    transform: translateY(1px);
}

.today-snapshot-stat-num {
    font-size: 1.2rem;       /* ROUND 94: down from 1.5rem so tier chips are inline + compact */
    font-weight: 700;
    color: var(--text-strong, #111);
    line-height: 1;
}

.today-snapshot-stat-label {
    font-size: 0.85rem;      /* ROUND 94: down from 0.95rem for tighter inline bars */
    font-weight: 500;
    color: var(--text-color, #222);
}

/* Tier-specific border accents — quiet visual cue, not shouting */
.tier-stat-red { border-left: 4px solid #dc2626; }
.tier-stat-yellow { border-left: 4px solid #eab308; }
.tier-stat-green { border-left: 4px solid #16a34a; }

/* When count is 0, soften so it doesn't compete */
.tier-stat-red .today-snapshot-stat-num,
.tier-stat-yellow .today-snapshot-stat-num,
.tier-stat-green .today-snapshot-stat-num {
    /* keep color but if zero, we set color via JS-friendly inline */
}
.today-snapshot-stat[data-zero="true"] .today-snapshot-stat-num {
    color: var(--text-muted, #999);
}

/* === SECTIONS (recent assignments + follow-ups) === */
/* ROUND 94: assignments + follow-ups are now <details> accordions.
   Default closed to save vertical space; auto-open when there are
   overdue items (time-sensitive). The summary carries a number badge
   (visual sibling to the tier chip's count) so teachers see the count
   without expanding. */

.today-snapshot-section {
    margin-top: 0.75rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--border-color, #dddddd);
}

.today-snapshot-section:first-of-type {
    border-top: none;
    padding-top: 0;
    margin-top: 0;
}

/* When wrapped in <details>, the section has no border top — the
   summary acts as the visual boundary. */
.today-snapshot-accordion {
    border-top: none;
    padding-top: 0;
    margin-top: 0.4rem;
}

/* Hide native <details> disclosure marker (the triangle) — we render
   our own chevron via CSS using ::after on the summary. */
.today-snapshot-accordion > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.35rem 0.5rem;
    border-radius: 6px;
    transition: background 120ms ease;
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}
.today-snapshot-accordion > summary:hover {
    /* Round 98: removed purple hover bg. Neutral surface hover. */
    background: var(--surface-color, #f5f5f5);
}
.today-snapshot-accordion > summary::-webkit-details-marker {
    display: none;            /* Safari */
}
/* Chevron: rotates when open. Hidden for non-summary elements so the
   visual cue lives only on the clickable title. */
.today-snapshot-accordion > summary::after {
    content: "▸";
    margin-left: auto;
    font-size: 0.9rem;
    color: var(--text-muted, #666);
    transition: transform 120ms ease;
    display: inline-block;
}
.today-snapshot-accordion[open] > summary::after {
    transform: rotate(90deg);
}

.today-snapshot-section-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-color, #222);
    margin: 0;
    flex: 1;
}

/* ROUND 94: section number badge — sits before the label, mirrors the
   visual language of the tier chip's number. Coral when the section
   has overdue items (so the count itself signals urgency).
   ROUND 98: removed purple (was --primary/--accordion-closed-bg).
   User feedback: snapshot color scheme was too busy with decorative
   purple. Now neutral for non-overdue, coral for overdue — only
   semantic colors. */
.today-snapshot-section-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 0.4rem;
    border-radius: 8px;
    background: var(--background-color, #ffffff);
    color: var(--text-strong, #111);
    border: 1px solid var(--border-color, #cccccc);
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
}
.today-snapshot-section-num-overdue {
    background: #fff5f5;       /* light pink — works on light theme ✅ (16.7:1 on dark text) */
    color: #a02525;            /* dark red text */
    border-color: #d9534f;     /* red border */
}

.today-snapshot-section-label {
    font-weight: 600;
    color: var(--text-color, #222);
}
.today-snapshot-section-summary {
    font-size: 0.8rem;
    color: var(--text-muted, #666);
    font-weight: 500;
    margin-left: auto;
}

/* ROUND 93+94: overdue vs due-this-week sub-groups.
   Colored left-border + colored subgroup title signal the urgency;
   rows themselves stay NEUTRAL until hovered (no per-row background
   tint, no record-level color highlight). The subgroup container's
   background matches the snapshot surface so text contrast stays
   readable on the muted gray meta text.
   ROUND 97: removed tinted subgroup bgs (light purple behind gray text
   was unreadable). Border-left + title color carry the signal. */
.today-snapshot-subgroup {
    margin-top: 0.6rem;
    padding: 0.5rem 0.75rem;
    border-radius: 6px;
    background: transparent;
    border-left: 4px solid var(--border-color, #ccc);
}
.today-snapshot-subgroup-overdue {
    background: transparent;
    border-left-color: #d9534f;
}
.today-snapshot-subgroup-week {
    background: transparent;
    /* Round 98: removed purple border-left. Use neutral border so the
       snapshot's only colored accent is overdue (semantic red). */
    border-left-color: var(--border-color, #cccccc);
}
.today-snapshot-subgroup-title {
    font-size: 0.9rem;
    font-weight: 600;
    margin: 0 0 0.4rem 0;
    color: var(--text-strong, #1a1a1a);
}
.today-snapshot-subgroup-overdue .today-snapshot-subgroup-title {
    color: #a02525;
}
.today-snapshot-subgroup-week .today-snapshot-subgroup-title {
    /* Round 98: removed purple. Title uses neutral text color so the
       snapshot's only colored element is overdue (semantic red). */
    color: var(--text-strong, #1a1a1a);
}
/* Round 97: removed the per-record color override (was `.today-snapshot-item-overdue strong`).
   Records stay neutral until hovered. Subgroup title + border carry the urgency signal. */

.today-snapshot-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.today-snapshot-item {
    padding: 0.4rem 0;
    border-bottom: 1px dotted var(--border-color, #dddddd);
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.today-snapshot-item:last-child {
    border-bottom: none;
}

.today-snapshot-item strong {
    font-weight: 600;
    color: var(--text-strong, #111);
    font-size: 0.95rem;
}

.today-snapshot-meta {
    font-size: 0.85rem;
    color: var(--text-secondary, #475569);
}

.today-snapshot-more {
    padding: 0.4rem 0;
    font-size: 0.9rem;
    color: var(--text-muted, #666);
    font-style: italic;
    text-align: center;
}

/* === Round 95: clickable follow-up rows + delete button === */

/* === Round 95: clickable follow-up rows + delete button === */

/* Reset PicoCSS's [role=button] styling for our list-item buttons.
   PicoCSS sets --background-color: var(--primary) and adds Pico button
   padding/border on any [role=button]. We want list-item rendering with
   transparent bg + orange hover, not Pico's primary-color button look.
   
   Specificity note: We use a 1-class selector (specificity 0,1,0) so
   that .today-snapshot-item-clickable:hover (0,2,0) can win on hover.
   Adding [role=button] or li would make this 0,2,1+ and kill the hover. */
.today-snapshot-item-clickable {
    --background-color: transparent;
    --border-color: transparent;
    --color: inherit;
    background-color: transparent;
    border: none;
    color: inherit;
    padding: 0.3rem 0.4rem;   /* keep our tight row padding */
    margin: 0 -0.4rem;
    border-radius: 4px;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 0.5rem;
    cursor: pointer;
    transition: background-color 0.15s ease;
    text-align: left;
    font: inherit;            /* undo Pico's button font overrides */
    width: auto;
    margin-bottom: 0;
}

.today-snapshot-item-clickable:hover {
    /* Round 100: hover color changed to orangeish hue (was neutral surface).
       Default state has no background; only hover reveals a warm orange
       highlight. This matches the user request "orangeish hue, no special
       background color" — the click affordance lives in the warm hover
       bg, not in a default-state highlight. */
    background-color: #fff3e0;   /* light orange — 16.3:1 on slate-900 text ✅ */
}
.today-snapshot-item-clickable:hover .today-snapshot-item-delete {
    color: #f59e0b;              /* amber/orange — reinforces the warm theme */
}

.today-snapshot-item-clickable:focus {
    outline: 2px solid var(--accent-color, #0066cc);
    outline-offset: 1px;
}

.today-snapshot-item-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.today-snapshot-item-delete {
    flex: 0 0 auto;
    /* Round 98: PicoCSS sets `button { width: 100% }` for form-friendly
       buttons, which made this X stretch to fill the entire flex row
       (squeezing the body to 0 width = 'text is 1 character wide').
       Force the X to hug its content. */
    width: auto;
    min-width: 0;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted, #888);
    cursor: pointer;
    padding: 0.15rem 0.45rem;
    border-radius: 4px;
    font-size: 1rem;
    line-height: 1;
    align-self: center;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.today-snapshot-item-delete:hover {
    background-color: rgba(220, 53, 69, 0.12);
    color: #dc3545;
    border-color: rgba(220, 53, 69, 0.4);
}

.today-snapshot-item-delete:focus {
    outline: 2px solid #dc3545;
    outline-offset: 1px;
}

/* === Round 95: edit-follow-up overlay (mirrors hub-detail-overlay) === */

.today-snapshot-edit-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 20px;
}

.today-snapshot-edit-overlay-box {
    background: var(--surface-color);
    color: var(--text-color);
    border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    padding: 24px 28px;
    max-width: 480px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
}

.today-snapshot-edit-title {
    margin: 0 0 16px 0;
    color: var(--text-strong);
    font-size: 1.15rem;
    font-weight: 600;
}

.today-snapshot-edit-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.today-snapshot-edit-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 500;
}

.today-snapshot-edit-form input {
    padding: 8px 10px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    font-size: 0.9rem;
    font-family: inherit;
}

.today-snapshot-edit-form input:focus {
    outline: none;
    border-color: var(--primary);
}

.today-snapshot-edit-actions {
    display: flex;
    gap: 8px;
    margin-top: 16px;
    justify-content: flex-end;
}

.today-snapshot-edit-cancel {
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text-secondary);
    padding: 8px 14px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.9rem;
}

.today-snapshot-edit-cancel:hover {
    background: var(--hover-bg);
}

.today-snapshot-edit-save {
    background: var(--primary);
    color: var(--text-on-primary);
    border: none;
    padding: 8px 14px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 600;
}

.today-snapshot-edit-save:hover {
    filter: brightness(0.92);
}

/* Round 109: today-snapshot dark-mode overrides removed — all
   --surface-color / --border-color / --text-color tokens
   automatically swap via [data-theme="dark"]. */

/* =========================================================
   ANNOTATOR SECTION — Pro-only teaching annotator
   ========================================================= */
.annotator-section {
    margin-top: 0.5rem;
}
.annotator-section .quick-install {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 16px;
    margin-top: 12px;
}
.annotator-section .bookmarklet-link {
    background: #1a3a2a;
    border-color: #3a6a4a;
    color: #6cdb9e;
}
.annotator-section .bookmarklet-link:hover {
    background: #2a4a3a;
    border-color: #4a7a5a;
}
.annotator-section .kbd {
    background: #2a2a3a;
    padding: 1px 5px;
    border-radius: 3px;
    color: #ffd93d;
    font-size: 0.85rem;
    font-family: monospace;
}

