/* ==========================================================
   ALICE Design System — alice.css
   Decision 011: No CSS framework. Single handwritten file.
   Decision 010: Okabe-Ito aligned palette. Triple-signal status.
   ========================================================== */

/* 1. CSS Reset */
*, *::before, *::after {
    box-sizing: border-box;
}

/* 2. CSS Custom Properties */
:root {
    --alice-blue: #185FA5;
    --alice-amber: #EF9F27;
    --alice-teal: #1D9E75;
    --alice-warning: #BA7517;
    --alice-gray: #888780;
    --alice-surface: #FFFFFF;
    --alice-bg: #F5F5F2;
    --alice-text: #1A1A1A;
    --alice-text-secondary: #555550;
    --alice-text-tertiary: #888880;
    --alice-border: #E0DFD8;
    --alice-border-strong: #C0BFB8;
    --alice-focus: #185FA5;

    /* Tints for status badges */
    --alice-teal-tint: #E6F5EF;
    --alice-amber-tint: #FFF5E0;
    --alice-gray-tint: #F0EFEC;
    --alice-blue-tint: #E8F0FA;

    --alice-border-secondary: #D0CFc8;
    --alice-border-tertiary: #E8E7E0;

    /* ── --color-* aliases ─────────────────────────────────────────
     * A handful of templates were written with `var(--color-surface)`,
     * `var(--color-border)`, etc. — variables that were never defined
     * anywhere, so their literal-fallback values (#fff / #ccc / #1A1A1A)
     * always won. That meant asset cards, reader cards, and a few other
     * surfaces stayed white in dark mode.
     *
     * Rather than rewrite every template, alias the missing names back
     * to the canonical `--alice-*` tokens. CSS custom properties resolve
     * lazily, so each `var(--color-surface)` site now follows the active
     * theme automatically. New templates should still use `--alice-*`
     * directly — keep these aliases only for backwards compatibility. */
    --color-surface: var(--alice-surface);
    --color-bg:      var(--alice-bg);
    --color-text:    var(--alice-text);
    --color-text-secondary: var(--alice-text-secondary);
    --color-border:  var(--alice-border);
    --color-border-strong: var(--alice-border-strong);

    /* Radii */
    --radius-md: 6px;
    --radius-lg: 10px;

    /* Map path / inactive elements */
    --alice-map-path:  #888880;
    --alice-map-muted: #C0BFB8;

    /* Hyperlink color */
    --link-color: #7ab8f5;   /* light blue, readable on navy, WCAG AA */

    /* Font stacks */
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
    --font-serif: Georgia, "Times New Roman", serif;

    /* Legacy accent colors referenced by .tessera-notice / .pill-* —
       defined here so the CSS doesn't fall back to "invisible" (per
       06_CSS_AUDIT §2.6 + cross-cutting audit Axis D). Okabe-Ito-safe. */
    --gold:   #FFB800;
    --orange: #FF8C00;

    /* ── Semantic color aliases (Tier-2, per architecture/UX.md §2.2)
       Components SHOULD reference --color-* tokens. Tenant theming
       overrides --color-brand* in base.html. Other semantic tokens
       are platform-locked. */
    --color-success:        var(--alice-teal);
    --color-success-bg:     var(--alice-teal-tint);
    --color-warning:        var(--alice-amber);
    --color-warning-bg:     var(--alice-amber-tint);
    --color-danger:         var(--alice-warning);   /* brownish-orange per DECISIONS O1 */
    --color-danger-bg:      #FFF0F0;
    --color-info:           var(--alice-blue);
    --color-info-bg:        var(--alice-blue-tint);
    --color-muted:          var(--alice-gray);
    --color-muted-bg:       var(--alice-gray-tint);
    --color-text-tertiary:  var(--alice-text-tertiary);
    --color-focus:          var(--alice-focus);
    --color-brand:          var(--alice-blue);       /* platform default; tenant overrides in base.html */
    --color-brand-tint:     var(--alice-blue-tint);  /* platform default; tenant overrides */
    --color-brand-fg:       #FFFFFF;
}

/* ── STANDARD (default) ─── already in :root ─────────── */
/* --alice-blue:    #185FA5  */
/* --alice-amber:   #EF9F27  */
/* --alice-teal:    #1D9E75  */
/* --alice-warning: #BA7517  */
/* --alice-gray:    #888780  */

/* ── DARK MODE ───────────────────────────────────── */
/* html.th-X selectors mirror body.th-X for the FOUC-prevention
   inline script in base.html, which sets the class on
   <html> before <body> is parsed. CSS variables cascade from
   the root, so all `body.th-X .child` compound rules elsewhere
   keep working unchanged. */
html.th-dark,
body.th-dark {
  --alice-blue:         #85B7EB;
  --alice-amber:        #EF9F27;
  --alice-teal:         #5DCAA5;
  --alice-warning:      #FAC775;
  --alice-gray:         #B4B2A9;
  --alice-surface:      #1E1E1E;
  --alice-bg:           #121212;
  --alice-text:         #E8E6E0;
  --alice-text-secondary:#A8A6A0;
  --alice-text-tertiary: #888880;
  --alice-border:       #3A3A38;
  --alice-border-strong:#555550;
  --alice-teal-tint:    #1A2E26;
  --alice-amber-tint:   #2E2618;
  --alice-gray-tint:    #2A2A28;
  --alice-blue-tint:    #1A2436;
  --alice-map-path:     #888880;
  --alice-map-muted:    #555550;
  --link-color:         #85B7EB;
}

/* ── LIGHT MODE ──────────────────────────────────── */
html.th-light,
body.th-light {
  --alice-blue:          #185FA5;
  --alice-amber:         #EF9F27;
  --alice-teal:          #1D9E75;
  --alice-surface:       #FFFFFF;
  --alice-bg:            #F5F5F2;
  --alice-text:          #1A1A1A;
  --alice-text-secondary:#555550;
  --alice-border:        #E0DFD8;
  --alice-border-strong: #C0BFB8;
  --alice-teal-tint:     #E6F5EF;
  --alice-amber-tint:    #FFF5E0;
  --alice-gray-tint:     #F0EFEC;
  --alice-blue-tint:     #E8F0FA;
  --alice-map-path:      #444440;
  --alice-map-muted:     #C0BFB8;
  --link-color:          #185FA5;
}

/* ── HIGH CONTRAST (theme) ──────────────────────────── */
html.th-hico,
body.th-hico {
  --alice-blue:          #0000EE;
  --alice-amber:         #FFDD00;
  --alice-teal:          #006600;
  --alice-warning:       #CC4400;
  --alice-gray:          #555555;
  --alice-surface:       #FFFFFF;
  --alice-bg:            #F0F0F0;
  --alice-text:          #000000;
  --alice-text-secondary:#111111;
  --alice-text-tertiary: #333333;
  --alice-border:        #000000;
  --alice-border-strong: #000000;
  --alice-border-secondary: #000000;
  --alice-border-tertiary:  #444444;
  --alice-map-path:      #000000;
  --alice-map-muted:     #888888;
  --alice-focus:         #0000EE;
  --link-color:          #0000EE;
  /* Light tints — explicit so they do NOT leak from the
     prefers-color-scheme: dark @media block, which would otherwise
     override them with very dark values (#1A2436 etc.) leaving
     black text unreadable on hover/active states. */
  --alice-blue-tint:     #DDEEFF;
  --alice-teal-tint:     #DDFFDD;
  --alice-amber-tint:    #FFF7CC;
  --alice-gray-tint:     #EEEEEE;
}

/* High contrast: heavier borders everywhere */
body.th-hico .card,
body.th-hico .nav,
body.th-hico .form-input,
body.th-hico .status-badge {
  border-width: 2px;
  border-color: var(--alice-border);
}

/* ── DEUTERANOPIA (accessibility overlay) ───────────── */
html.th-deut,
body.th-deut {
  --alice-blue:    #0072B2;   /* sky blue — unambiguous   */
  --alice-amber:   #F0E442;   /* yellow — distinct from blue */
  --alice-teal:    #009E73;   /* bluish green              */
  --alice-warning: #E69F00;   /* orange-gold               */
  --alice-focus:   #0072B2;
  --link-color:    #56B4E9;
}

/* ── PROTANOPIA (accessibility overlay) ─────────────── */
html.th-prot,
body.th-prot {
  --alice-blue:    #0072B2;
  --alice-amber:   #F0E442;
  --alice-teal:    #009E73;
  --alice-warning: #E69F00;
  --alice-focus:   #0072B2;
  --link-color:    #56B4E9;
}

/* ── TRITANOPIA (accessibility overlay) ─────────────── */
html.th-trit,
body.th-trit {
  --alice-blue:    #D55E00;   /* vermilion — distinct for trit */
  --alice-amber:   #CC79A7;   /* reddish purple                */
  --alice-teal:    #009E73;   /* green — unaffected            */
  --alice-warning: #D55E00;
  --alice-focus:   #009E73;
  --link-color:    #CC79A7;
}

/* ── DARK MODE + COLOR-BLIND COMBINATIONS ──────────────
   Per architecture/UX.md §4 + cross-cutting audit Axis C.
   Without these rules, a color-blind user who switches to
   dark mode sees the LIGHT-mode color-blind palette on a
   dark background — unreadable. These rules layer the
   dark-mode-aware color-blind palette so contrast stays
   accessible. WCAG fix. */
html.th-dark.th-deut,
body.th-dark.th-deut {
  --alice-blue:    #56B4E9;   /* light blue for dark + deut */
  --alice-warning: #E6B800;   /* gold for dark + deut */
  --alice-teal:    #009E73;   /* green-cyan; readable on dark */
  --alice-focus:   #56B4E9;
}
html.th-dark.th-prot,
body.th-dark.th-prot {
  /* Protanopia palette mirrors deuteranopia per Okabe-Ito */
  --alice-blue:    #56B4E9;
  --alice-warning: #E6B800;
  --alice-teal:    #009E73;
  --alice-focus:   #56B4E9;
}
html.th-dark.th-trit,
body.th-dark.th-trit {
  --alice-blue:    #CC79A7;   /* reddish-purple — distinguishable for trit on dark */
  --alice-warning: #E6B800;
  --alice-teal:    #009E73;
  --alice-focus:   #CC79A7;
}

/* ── HYPERLINK COLORS ───────────────────────────────── */
a {
  color: var(--link-color, #7ab8f5);
  text-decoration: none;
}
a:hover { text-decoration: underline; }

/*
 * WCAG AA contrast verification (4.5:1 body text, 3:1 large/UI):
 *
 * Standard:      #1A1A1A on #F5F5F2 = 14.5:1 ✓   Nav: #555550 on #FFFFFF = 7.2:1 ✓
 *                Btn: #FFFFFF on #185FA5 = 5.7:1 ✓  Error: #C13030 on #FFF0F0 = 5.1:1 ✓
 * Deuteranopia:  #1A1A1A on #F5F5F2 = 14.5:1 ✓   Btn: #FFFFFF on #0072B2 = 4.9:1 ✓
 * Protanopia:    #1A1A1A on #F5F5F2 = 14.5:1 ✓   Btn: #FFFFFF on #0072B2 = 4.9:1 ✓
 * Tritanopia:    #1A1A1A on #F5F5F2 = 14.5:1 ✓   Btn: #FFFFFF on #D55E00 = 4.6:1 ✓
 * High Contrast: #000000 on #F0F0F0 = 18.1:1 ✓   Btn: #FFFFFF on #0000EE = 8.6:1 ✓
 *                Focus: #0000EE outline = 8.6:1 ✓
 *
 * Badge text on badge tint backgrounds all exceed 4.5:1 in all themes.
 */

/* 3. Dark mode overrides — applied only when the user has not
   chosen an explicit theme. The :not() guard prevents OS=dark
   from briefly flashing dark colors on a user who has stored
   "th-light" in localStorage (the FOUC-prevention head script
   in base.html sets the class on <html> before first paint). */
@media (prefers-color-scheme: dark) {
    html:not(.th-dark):not(.th-light):not(.th-hico):not(.th-deut):not(.th-prot):not(.th-trit) {
        --alice-blue: #85B7EB;
        --alice-amber: #EF9F27;
        --alice-teal: #5DCAA5;
        --alice-warning: #FAC775;
        --alice-gray: #B4B2A9;
        --alice-surface: #1E1E1E;
        --alice-bg: #121212;
        --alice-text: #E8E6E0;
        --alice-text-secondary: #A8A6A0;
        --alice-text-tertiary: #888880;
        --alice-border: #3A3A38;
        --alice-border-strong: #555550;

        --alice-teal-tint: #1A2E26;
        --alice-amber-tint: #2E2618;
        --alice-gray-tint: #2A2A28;
        --alice-blue-tint: #1A2436;
    }
}

/* 4. Typography */
body {
    font-family: var(--font-sans);
    background-color: var(--alice-bg);
    color: var(--alice-text);
    margin: 0;
    padding: 0;
    line-height: 1.5;
}

h1, h2, h3 {
    color: var(--alice-text);
    margin-top: 1.5rem;
    margin-bottom: 0.75rem;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.1rem; }

.wordmark,
.nav__wordmark,
.login-wordmark {
    font-family: Georgia, "Times New Roman", serif;
    font-weight: normal;
    font-style: normal;
    color: var(--alice-text);
    letter-spacing: 0.05em;
}

/* 5. Layout utilities */
.container {
    max-width: 960px;
    margin: 0 auto;
    padding: 1.5rem 1rem;
}

.grid-2col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
}

/* 6. Navigation */
.nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.5rem;
    background-color: var(--alice-surface);
    border-bottom: 1px solid var(--alice-border);
}

















/* 7. Forms */
.form-group {
    margin-bottom: 1rem;
}

.form-label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--alice-text);
}

.form-input {
    width: 100%;
    padding: 0.6rem 0.75rem;
    font-size: 1rem;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background-color: var(--alice-surface);
    color: var(--alice-text);
    font-family: inherit;
}

.form-input:focus {
    outline: none;
    border-color: var(--color-brand, var(--alice-blue));
    box-shadow: 0 0 0 2px var(--color-brand-tint, var(--alice-blue-tint));
}

/* Mirror .form-input so every <textarea class="form-textarea"> respects
   the active theme. Without this baseline, browsers render textareas
   with the OS default (typically white-on-black or white-on-white),
   which fights dark mode. Selects also need it because some forms use
   <select class="form-select"> assuming the theme bleeds through. */
.form-textarea,
.form-select {
    width: 100%;
    padding: 0.6rem 0.75rem;
    font-size: 1rem;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background-color: var(--alice-surface);
    color: var(--alice-text);
    font-family: inherit;
}
.form-textarea:focus,
.form-select:focus {
    outline: none;
    border-color: var(--color-brand, var(--alice-blue));
    box-shadow: 0 0 0 2px var(--color-brand-tint, var(--alice-blue-tint));
}

.form-error {
    color: #C13030;
    background-color: #FFF0F0;
    border: 1px solid #C13030;
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

@media (prefers-color-scheme: dark) {
    html:not(.th-dark):not(.th-light):not(.th-hico):not(.th-deut):not(.th-prot):not(.th-trit) .form-error {
        color: #FF8A8A;
        background-color: #2E1A1A;
        border-color: #FF8A8A;
    }
}

.btn-primary {
    display: inline-block;
    width: auto;
    max-width: var(--btn-max-width, 300px);
    padding: 0.65rem 1.25rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-brand-fg, var(--alice-surface));
    background-color: var(--color-brand, var(--alice-blue));
    border: none;
    border-radius: 4px;
    cursor: pointer;
    text-align: center;
    text-decoration: none;
    font-family: inherit;
}

.btn-primary:hover {
    opacity: 0.9;
}

.btn-secondary {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    font-size: 0.85rem;
    color: var(--alice-text-secondary);
    background-color: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    cursor: pointer;
    text-align: center;
    text-decoration: none;
    font-family: inherit;
}

.btn-secondary:hover {
    border-color: var(--color-brand, var(--alice-blue));
    color: var(--color-brand, var(--alice-blue));
}

/* ── Admin tab pane ─────────────────────────────────────
   Used by the admin collection / record pages. White surface the
   active .pagina-tab-btn merges into, with side + bottom borders
   that complete the lexia-style card edge (the tab bar's
   border-bottom supplies the top edge of the card). The .hidden
   rule mirrors .pagina-panel.hidden so the `hidden` attribute
   correctly suppresses the pane. */
.admin-tab-pane {
    background: var(--alice-surface);
    border-left: 1px solid var(--alice-border);
    border-right: 1px solid var(--alice-border);
    border-bottom: 1px solid var(--alice-border);
    border-radius: 0 0 8px 8px;
    padding: 20px 22px;
    min-height: 200px;
}
.admin-tab-pane.hidden { display: none; }

/* On admin pages: pin inactive tab background to the page colour
   (--alice-bg). The active tab is var(--alice-surface) (white)
   from .pagina-tab-btn.active and merges with the .admin-tab-pane
   below it; inactive tabs should fade back into the page so the
   visual hierarchy "active = card edge, inactive = page" reads
   cleanly. Scoped via body.admin-page so the lexia tab bar is
   untouched. */
body.admin-page .pagina-tab-btn {
    background: var(--alice-bg);
}
body.admin-page .pagina-tab-btn.active {
    /* Override the rule above for the active state; the active tab
       must remain the same colour as the .admin-tab-pane (white)
       so the active-tab → pane junction reads as a single card. */
    background: var(--alice-surface);
}

/* ── Compact pill (links + small actions) ────────────────
   Used for cross-page nav (Dashboards / Collections), Edit
   toggles, and "back to X" affordances on admin pages. Stays
   visually distinct from primary CTAs (.btn-primary) and from
   plain inline links. Pair --accent for the active / call-to-
   action variant. */
.alice-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.85rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--alice-text-secondary);
    background-color: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 999px;
    cursor: pointer;
    text-decoration: none;
    font-family: inherit;
    line-height: 1.2;
    transition: color .15s, border-color .15s, background-color .15s;
}
.alice-pill:hover {
    border-color: var(--alice-blue);
    color: var(--alice-blue);
}
.alice-pill--accent {
    color: var(--alice-blue);
    border-color: var(--alice-blue);
}
.alice-pill--accent:hover {
    background-color: var(--alice-blue);
    color: var(--alice-surface);
}

/* Language pill variant — per specs/ux/DECISIONS.md O6 resolution.
   Used to indicate a language code (e.g., "EN", "ES") in lists like
   /admin/email-templates. Visually distinct from .nav-role-badge
   (which carries role/inbox-state semantics). Compact, monospace,
   muted neutral fill. */
.alice-pill--lang {
    font-family: var(--font-mono, ui-monospace, Menlo, Consolas, monospace);
    font-size: 0.75rem;
    padding: 2px 6px;
    border: 1px solid var(--alice-border);
    border-radius: 3px;
    background: var(--alice-gray-tint);
    color: var(--alice-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: default;
}
.alice-pill--lang:hover {
    /* No-op — language pill is read-only display, not interactive. */
    border-color: var(--alice-border);
    color: var(--alice-text-secondary);
}

/* ── Canonical pill variants (DECISIONS A18 + 07_COHERENCE_AUDIT)
   Five canonical variants compose with intent modifiers below to
   replace the legacy proliferation of ~17 pill / badge classes
   (.pill-ok, .grading-badge--*, .collab-status-pill, .cs-status-pill,
   .originality-badge, .template-badge, .nav-role-badge as status,
   .status-badge/.status-complete/.status-next/.status-skipped/etc.).
   Apply BOTH the variant class AND an intent modifier:
       .alice-pill .alice-pill--status .alice-pill--success
   Read-only by default; never use .alice-pill as a button. */

/* --status: semantic state at-rest (Active, Inactive, Draft, Failed, …) */
.alice-pill--status {
    font-weight: 600;
    cursor: default;
    user-select: none;
}
.alice-pill--status:hover {
    /* status pills are read-only — no hover affordance */
    border-color: var(--alice-border);
    color: inherit;
    background-color: inherit;
}

/* --count: notification count, monospace digit (e.g., "3 new", "12") */
.alice-pill--count {
    font-family: var(--font-mono);
    font-weight: 600;
    padding: 1px 8px;
    font-size: 0.78rem;
    background: var(--alice-gray-tint);
    color: var(--alice-text-secondary);
    border: 1px solid var(--alice-border);
    cursor: default;
}
.alice-pill--count:hover {
    border-color: var(--alice-border);
    color: var(--alice-text-secondary);
}

/* --tag: categorization (e.g., asset type, kind label) — neutral by default */
.alice-pill--tag {
    font-weight: 500;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    cursor: default;
}
.alice-pill--tag:hover {
    border-color: var(--alice-border);
    color: var(--alice-text-secondary);
}

/* --filter: toggleable active-filter chip (carries × to remove) */
.alice-pill--filter {
    font-weight: 500;
    background: var(--color-brand-tint, var(--alice-blue-tint));
    color: var(--color-brand, var(--alice-blue));
    border: 1px solid var(--color-brand, var(--alice-blue));
    cursor: pointer;
}
.alice-pill--filter:hover {
    background: var(--color-brand, var(--alice-blue));
    color: var(--color-brand-fg, #fff);
}

/* ── Intent modifiers ─────────────────────────────────────
   Add ONE of these alongside .alice-pill--status (or --tag where
   meaningful) to set the semantic color. Maps to platform-locked
   semantic tokens; tenants cannot change these. */
.alice-pill--success {
    color: var(--color-success);
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
}
.alice-pill--info {
    color: var(--color-info);
    background-color: var(--color-info-bg);
    border-color: var(--color-info);
}
.alice-pill--warning {
    color: var(--color-warning);
    background-color: var(--color-warning-bg);
    border-color: var(--color-warning);
}
.alice-pill--danger {
    color: var(--color-danger);
    background-color: var(--color-danger-bg);
    border-color: var(--color-danger);
}
.alice-pill--muted {
    color: var(--color-text-secondary);
    background-color: var(--color-muted-bg);
    border-color: var(--alice-border);
}

/* 8. Cards */
.card {
    background-color: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    padding: 1.25rem;
}



.card__title {
    margin: 0.5rem 0 0.35rem;
    font-size: 1.05rem;
}

.card__meta {
    font-size: 0.85rem;
    color: var(--alice-text-secondary);
    margin: 0 0 0.75rem;
}

.card__actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
}

.card__actions .btn-primary {
    width: auto;
    padding: 0.4rem 1rem;
    font-size: 0.85rem;
}

/* ── Hub cards ─────────────────────────────────────
   Tighter sibling of .card for *section landings* one
   level below the main /admin grid. The size delta is
   intentional: it teaches "depth = density" so users
   feel they have descended into a subsystem (e.g.
   /admin/max, /admin/system) without reading the URL.
   Use .hub-grid as the container and .hub-card for
   each routing tile; .hub-card__summary and
   .hub-card__cta style the body and the trailing
   "Manage →" / "Edit →" link. */
.hub-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    max-width: 1100px;
}

.hub-card {
    display: block;
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    padding: 18px 20px;
    background: var(--alice-surface);
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s ease, transform 0.15s ease;
}

.hub-card:hover {
    border-color: var(--alice-teal);
    transform: translateY(-1px);
    text-decoration: none;
}

.hub-card h2 {
    margin: 0 0 8px;
    font-size: 1.05rem;
}

.hub-card__summary {
    margin: 0 0 12px;
    color: var(--alice-text-secondary);
    font-size: 0.9rem;
    line-height: 1.4;
}

.hub-card__cta {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--alice-teal);
}

/* Warning-tinted hub card — color-only modifier, mirrors
   .card--warn for the destructive/special action on a sub-hub
   (e.g. Calculus on /admin/opus/{id}). */
.hub-card--warn {
    border-color: var(--alice-warning);
    background: var(--alice-amber-tint);
}
.hub-card--warn:hover {
    border-color: var(--alice-warning);
    filter: brightness(0.97);
}

/* 9. Progress bar */
.progress-track {
    height: 6px;
    background-color: var(--alice-gray-tint);
    border-radius: 3px;
    overflow: hidden;
    margin-top: 0.5rem;
}

.progress-fill {
    height: 100%;
    background-color: var(--alice-teal);
    border-radius: 3px;
    transition: width 0.3s ease;
}

.progress-label {
    font-size: 0.8rem;
    color: var(--alice-text-secondary);
    margin-top: 0.25rem;
    display: inline-block;
}

/* 10. Status badges */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.6rem;
    border-radius: 12px;
    font-size: 0.8rem;
    font-weight: 500;
    white-space: nowrap;
}

.status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.status-complete {
    background-color: var(--alice-teal-tint);
    color: var(--alice-teal);
}

.status-complete .status-dot {
    background-color: var(--alice-teal);
}

.status-next {
    background-color: var(--alice-amber-tint);
    color: var(--alice-warning);
}

.status-next .status-dot {
    background-color: var(--alice-amber);
}

/* Syllabus "Read" status dropdown — styled to look like the
   status-badge pill at rest, with a dropdown on click. */
select.syllabus-status-select {
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--alice-amber-tint);
    color: var(--alice-warning);
    border: none;
    border-radius: 12px;
    padding: 0.2rem 0.6rem;
    font-size: 0.8rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23BA7517'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 6px center;
    padding-right: 20px;
}
select.syllabus-status-select:focus {
    outline: 2px solid var(--alice-focus);
    outline-offset: 1px;
}

.status-skipped {
    background-color: var(--alice-gray-tint);
    color: var(--alice-gray);
}

.status-skipped .status-dot {
    background-color: var(--alice-gray);
}



.status-inprogress .status-dot {
    background-color: var(--alice-blue);
}

/* 11. Activity table */
.activity-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 0.75rem;
}

.activity-table th,
.activity-table td {
    text-align: left;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--alice-border);
    font-size: 0.9rem;
}

.activity-table th {
    font-weight: 600;
    color: var(--alice-text-secondary);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.activity-table tbody tr:hover {
    background-color: var(--alice-blue-tint);
}

/* 12. Login page */
.login-page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background-color: var(--alice-bg);
}

.login-card {
    background-color: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 10px;
    padding: 2rem 1.5rem;
    width: 100%;
    max-width: 340px;
    text-align: center;
}

.login-wordmark {
    font-size: 2rem;
    margin-bottom: 0.2rem;
}

.login-tagline {
    font-size: 0.8rem;
    color: var(--alice-text-secondary);
    font-style: italic;
    margin: 0 0 0.75rem;
}

.login-divider {
    height: 2px;
    background-color: var(--alice-amber);
    margin: 0 auto 1rem;
    width: 40%;
    border-radius: 1px;
}

.login-card .form-group {
    text-align: left;
}

.login-card .btn-primary {
    width: 100%;
    max-width: none;
    margin-top: 0.5rem;
}

/* 13. Language selector */


.lang-btn {
    background: none;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    padding: 0.25rem 0.75rem;
    font-size: 0.8rem;
    color: var(--alice-text-secondary);
    cursor: pointer;
    font-family: inherit;
}

.lang-btn:hover,
.lang-btn.active,
.lang-btn.lang-btn--active {
    border-color: var(--alice-blue);
    color: var(--alice-blue);
}

/* Accessibility notice */
.a11y-notice {
    margin-top: 2rem;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
    text-align: center;
    font-style: italic;
}

.subtitle {
    color: var(--alice-text-secondary);
    margin-top: -0.5rem;
}

/* ── Accessibility: Skip link ─────────────────────── */
.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 9999;
  padding: 0.5rem 1rem;
  background: var(--alice-blue);
  color: #fff;
  font-size: 14px;
  border-radius: 0 0 4px 4px;
  text-decoration: none;
  transition: top 0.1s;
}
.skip-link:focus {
  top: 0;
}

/* ── Accessibility: Focus indicators ──────────────── */
/* Visible focus indicator — applies to all interactive elements */
:focus-visible {
  outline: 3px solid var(--alice-focus, var(--alice-blue));
  outline-offset: 2px;
}

/* Never suppress focus outlines */
:focus:not(:focus-visible) {
  outline: none;
}

/* Screen-reader-only utility class */
.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;
}

/* ── Gear button ───────────────────────────────── */




/* ── Theme panel ───────────────────────────────── */
.theme-panel {
  position: fixed;
  top: 60px;
  right: 1rem;
  z-index: 500;
  width: 220px;
  background: var(--alice-surface);
  border: 0.5px solid var(--alice-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  padding: 1rem;
}
.theme-panel--hidden {
  display: none;
}




.theme-option {
  width: 100%;
  padding: 7px 10px;
  text-align: left;
  font-size: 13px;
  font-family: var(--font-sans);
  color: var(--alice-text);
  background: none;
  border: 0.5px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background 0.1s;
}
.theme-option:hover {
  background: var(--alice-bg);
}

.theme-option:focus-visible {
  outline: 3px solid var(--alice-focus, var(--alice-blue));
  outline-offset: 2px;
}


/* ── Site shell and top nav ─────────────────────────── */


/* (topnav rules moved to SPECS12 block below) */




.nav-link {
  display: flex; align-items: center;
  font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--alice-text-secondary); text-decoration: none;
  padding: 0 12px;
  border-bottom: 2px solid transparent;
  transition: color .18s, border-color .18s;
  cursor: pointer; background: none; border-top: none;
  border-left: none; border-right: none;
}
.nav-link:hover, .nav-link.active {
  color: var(--alice-text); border-bottom-color: var(--alice-amber);
}


.nav-role-badge {
  font-size: 10px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--alice-blue);
  background: var(--alice-blue-tint);
  border: 1px solid var(--alice-blue);
  border-radius: 10px; padding: 2px 8px;
}
body.th-dark .nav-role-badge {
  /* Dark-mode override: keep a high-contrast neutral grey background
     with the deep brand blue text so the badge stays readable when
     the pale dark-theme brand color (#85B7EB) would wash out. Uses
     the platform's text-secondary token instead of a hardcoded grey
     so HC and color-blind themes can override it. */
  background: var(--color-muted-bg);
  color: #0F3D6B;
  border-color: #0F3D6B;
}

/* ── SPECS27: Impersonation banner + UI ─────────────── */
.impersonation-banner {
    background: #ffe082;
    color: #5d4037;
    padding: 8px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-bottom: 2px solid #ffb300;
    font-size: 13px;
    /* Locked at the top so the warning never scrolls out of view.
       Sits just below the topnav when the topnav itself is locked. */
    position: sticky;
    top: 0;
    z-index: 499;
    box-shadow: 0 1px 8px rgba(0,0,0,0.08);
}
body.nav-locked .impersonation-banner {
    top: 44px;
}
body.th-dark .impersonation-banner {
    background: #ff9800;
    color: #1a1a1a;
}
body.th-hico .impersonation-banner {
    background: #ff00ff;
    color: #ffffff;
}
.impersonation-banner__form {
    margin: 0;
    flex-shrink: 0;
}

/* ── System Banner — global announcement strip ──────── */
/* Mirrors the impersonation banner mechanics (sticky at top under
   the topnav) but uses a reddish palette so it reads as a critical
   announcement. When both banners are visible the system banner
   stacks above the impersonation banner via normal document order
   plus a slightly higher z-index. */
.system-banner {
    background: #fde2e2;
    color: #7a1a1a;
    padding: 8px 16px;
    display: flex;
    align-items: center;
    gap: 10px;
    border-bottom: 2px solid #c0392b;
    font-size: 13px;
    font-weight: 500;
    position: sticky;
    top: 0;
    z-index: 500;
    box-shadow: 0 1px 8px rgba(192, 57, 43, 0.18);
}
body.nav-locked .system-banner {
    top: 44px;
}
.system-banner__icon {
    flex-shrink: 0;
    font-size: 16px;
    color: #c0392b;
}
.system-banner__msg {
    flex: 1 1 auto;
    white-space: pre-wrap;
    word-break: break-word;
}
body.th-dark .system-banner {
    background: #5a1818;
    color: #ffe6e6;
    border-bottom-color: #ff6b6b;
}
body.th-hico .system-banner {
    background: #c0392b;
    color: #ffffff;
    border-bottom-color: #ffffff;
}
/* When BOTH banners are visible, push the impersonation banner down
   below the system banner. The two stack natively because both are
   `position: sticky; top: 0` — the second sticky element in flow
   parks itself below the first. */

/* Brighter top menu while impersonating, per theme */
body.impersonating .topnav {
    background: #fff8e1;
    border-bottom: 2px solid #ffb300;
}
body.th-dark.impersonating .topnav {
    background: #4a3010;
}
body.th-hico.impersonating .topnav {
    background: #1a001a;
}

/* Impersonation start icon and popup */
.nav-imp-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}
.nav-imp-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px 8px;
    color: var(--alice-blue);
    display: inline-flex;
    align-items: center;
}
.nav-imp-toggle:hover { color: var(--alice-text); }
.nav-imp-popup {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 1000;
    min-width: 320px;
    max-width: 420px;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    padding: 8px;
}
.nav-imp-popup.hidden { display: none; }
.nav-imp-popup input[type="text"] {
    width: 100%;
    padding: 6px 8px;
    margin-bottom: 6px;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    box-sizing: border-box;
}
.nav-imp-result-form {
    margin: 0;
}
.nav-imp-result {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 6px 8px;
    cursor: pointer;
    font-size: 12px;
    border-radius: 4px;
    color: var(--alice-text);
}
.nav-imp-result:hover {
    background: var(--alice-blue-tint);
}

/* Return arrow next to role badge while impersonating */
.nav-imp-return-form {
    display: inline;
    margin: 0 0 0 4px;
}
.nav-imp-return {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--alice-blue);
    padding: 2px 6px;
    font-size: 16px;
    line-height: 1;
}
.nav-imp-return:hover {
    color: var(--alice-text);
}

/* ── Bookmark nav icon (jump to last visited lesson) ── */
.nav-bookmark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 8px;
}
.nav-bookmark svg {
    display: block;
}
.nav-bookmark--disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* ── Role switcher popup ───────────────────────────── */
.nav-role-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.nav-role-badge--switchable {
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.nav-role-badge--switchable:hover {
  background: var(--alice-blue);
  color: var(--alice-bg);
}
.nav-role-arrow {
  font-size: 9px;
  line-height: 1;
}
.nav-role-popup {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 1000;
  min-width: 220px;
  background: var(--alice-bg);
  border: 1px solid var(--alice-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.12);
  padding: 4px 0;
}
.nav-role-popup.hidden { display: none; }
.nav-role-popup form { margin: 0; }
.nav-role-popup-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 6px 12px;
  font-size: 12px;
  color: var(--alice-text);
  cursor: pointer;
}
.nav-role-popup-item:hover {
  background: var(--alice-blue-tint);
}
.nav-role-popup-item.active {
  font-weight: 700;
  color: var(--alice-blue);
}
body.th-hico .nav-role-badge {
  background: #FFFFFF;
}
body.th-hico .capstone-card {
  background: #EEEEEE;
}
body.th-hico .capstone-card--active {
  background: #FFFFFF;
}
.nav-email {
  font-size: 12px; color: var(--alice-text-secondary);
}

/* ── Burger button ─────────────────────────────────── */
.burger-btn {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: none; border: 1px solid var(--alice-border);
  border-radius: 6px; cursor: pointer; color: var(--alice-text-secondary);
  transition: color .18s, border-color .18s;
}
.burger-btn:hover { color: var(--alice-text); border-color: var(--alice-border-strong); }
.burger-btn svg { pointer-events: none; }

/* ── Burger panel ──────────────────────────────────── */
.burger-panel {
  position: absolute; top: 44px; right: 0; z-index: 300;
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-radius: 0 0 8px 8px;
  min-width: 220px; padding: 12px 0;
  box-shadow: -4px 4px 24px rgba(0,0,0,.15);
}
.burger-panel.hidden { display: none; }

.burger-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px; font-size: 13px; color: var(--alice-text-secondary);
  cursor: pointer; background: none; border: none; width: 100%;
  text-align: left; text-decoration: none;
  transition: background .12s;
  font-family: inherit;
}
.burger-item:hover { background: var(--alice-bg); }


/* ── Content container ─────────────────────────────── */
.content-container {
  max-width: var(--content-max-width, 960px);
  margin: 0 auto; padding: 0 16px;
}

/* ── Login shell ───────────────────────────────────── */
.login-shell {
  min-height: calc(100vh - 44px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
}

/* ── Cookie notice ─────────────────────────────────── */
.cookie-notice {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 400;
  background: var(--alice-surface);
  border-top: 1px solid var(--alice-border);
  padding: 12px 24px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; font-size: 13px; color: var(--alice-text-secondary);
}
.cookie-notice__text { margin: 0; }
.cookie-notice__ok {
  flex-shrink: 0; padding: 6px 18px;
  background: var(--alice-blue); border: none; border-radius: 6px;
  color: #fff; font-size: 13px; cursor: pointer;
}

/* ── Responsive: collapse nav links into burger ────── */
@media (max-width: 640px) {
  
  .nav-user .nav-role-badge { display: none; }
}

/* ── Breadcrumb ────────────────────────────────────── */
.breadcrumb {
  font-size: 12px;
  color: var(--alice-text-secondary);
  margin-bottom: 1.25rem;
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}
.breadcrumb a { color: var(--alice-text-secondary);
                text-decoration: none; }
.breadcrumb a:hover { color: var(--alice-text); }
.breadcrumb__sep { color: var(--alice-gray); }
.breadcrumb__current { color: var(--alice-text); }
body.nav-locked .breadcrumb {
    position: sticky;
    top: 44px;
    z-index: 490;
    background: var(--alice-bg);
}

/* ── Category selector ─────────────────────────────── */
.category-selector { margin-bottom: 1.5rem; }
.category-selector__label {
  font-size: 12px; font-weight: 500;
  color: var(--alice-text-secondary);
  letter-spacing: 0.06em; text-transform: uppercase;
  margin-bottom: 0.6rem;
}
.category-selector__options {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.category-btn {
  padding: 4px 10px; font-size: 11px;
  font-family: var(--font-sans);
  color: var(--alice-text); background: none;
  border: 0.5px solid var(--alice-border-secondary);
  border-radius: var(--radius-md); cursor: pointer;
  transition: background 0.1s, border-color 0.1s;
}
.category-btn:hover { background: var(--alice-bg); }
.category-btn--active {
  background: var(--alice-bg);
  border: 1.5px solid var(--alice-blue);
  color: var(--alice-blue); font-weight: 500;
}
.category-btn:focus-visible {
  outline: 3px solid var(--alice-focus, var(--alice-blue));
  outline-offset: 2px;
}

/* ── Map container ─────────────────────────────────── */
.map-container {
  border: 0.5px solid var(--alice-border-tertiary);
  border-radius: var(--radius-lg);
  overflow: hidden; margin-bottom: 1rem;
  background: var(--alice-surface);
}
.map-controls { display: flex; gap: 8px;
                margin-bottom: 0.75rem; }

/* ── Map legend (moved to SPECS13 block below) ────── */

/* ── Syllabus table ────────────────────────────────── */
.syllabus-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
.syllabus-table th {
  font-size: 11px; font-weight: 500;
  color: var(--alice-text-tertiary);
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 8px 12px; text-align: left;
  border-bottom: 0.5px solid var(--alice-border-tertiary);
}
.syllabus-table td {
  padding: 10px 12px;
  border-bottom: 0.5px solid var(--alice-border-tertiary);
  color: var(--alice-text); vertical-align: middle;
}
.syllabus-table tr:last-child td { border-bottom: none; }
.syllabus-table tr:hover td { background: var(--alice-bg); }

/* ── Admin table ────────────────────────────────── */
.admin-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
.admin-table th {
  font-size: 11px; font-weight: 500;
  color: var(--alice-text-tertiary);
  text-transform: uppercase; letter-spacing: .06em;
  padding: 8px 12px; text-align: left;
  border-bottom: 1px solid var(--alice-border);
}
.admin-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--alice-border-tertiary, var(--alice-border));
  vertical-align: middle;
}
.admin-table tr:hover td { background: var(--alice-bg); }

/* ── Admin form ─────────────────────────────────── */
.admin-form { max-width: 900px; }
.form-row {
  display: grid; grid-template-columns: 180px 1fr;
  gap: 8px; align-items: start; margin-bottom: 14px;
}

/* Search bar: input fills space, button fixed width, right-aligned */
.search-bar {
  display: flex; gap: 8px; align-items: center;
  margin-bottom: 14px;
}
.search-bar .form-input { flex: 1; }
.search-bar .btn-primary,
.search-bar .btn-secondary { flex-shrink: 0; }

/* Action bar: right-aligned row of buttons below tables */
.action-bar {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 12px;
}

/* ── Split columns (HISPANIA/BRITANNIA pattern) ─── */



/* ── Permission matrix ──────────────────────────── */
.matrix-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.matrix-table th { padding: 6px 10px; text-align: left;
                   background: var(--alice-bg); }
.matrix-table .fasciculus-row td {
  background: var(--alice-blue-tint);
  font-weight: 600; font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; padding: 4px 10px;
  color: var(--alice-blue);
}
.matrix-table td { padding: 5px 10px;
  border-bottom: 1px solid var(--alice-border-tertiary, var(--alice-border)); }

/* ── Badge ──────────────────────────────────────── */
.badge {
  display: inline-block; padding: 2px 8px;
  border-radius: 10px; font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
}





/* ── Flash message ──────────────────────────────── */
.flash-msg,
.flash {
  padding: 10px 16px; border-radius: 6px; font-size: 13px;
  margin-bottom: 16px;
}
.flash-msg.ok,
.flash-ok { background: var(--alice-teal-tint);
               border: 1px solid var(--alice-teal);
               color: var(--alice-teal); }
.flash-msg.err,
.flash-err { background: #FFF0F0;
               border: 1px solid #C13030;
               color: #C13030; }
.flash-warn { background: var(--alice-amber-tint);
               border: 1px solid var(--alice-warning);
               color: var(--alice-warning); }

/* ── Untranslated labels (legacy, kept for non-`t()` link callers) ── */


/* ── ALT+click label editing (EDIT_LINGUA mode) ──────
   The t() helper wraps every body-context label in
   <span class="alice-label" data-nuntius="CODE"> when edit_lingua is
   active. alice.js toggles the body.alt-down class while Alt is held
   so affordances appear only then, and on click with Alt held it
   navigates to /admin/nuntius/CODE without firing the underlying
   hyperlink/htmx action. */
.alice-label[data-nuntius] { cursor: inherit; }
.alice-label--missing[data-nuntius] {
  color: var(--alice-warning);
  text-decoration: underline dashed;
}
body.alt-down .alice-label[data-nuntius] {
  outline: 1px dashed var(--alice-warning);
  outline-offset: 2px;
  cursor: alias;
  background: rgba(186, 117, 23, 0.08);
}

/* Em-dash absence marker — per specs/ux/DECISIONS.md A8 generalization.
   Used for any "null / absence / no decision" cell or inline display
   (untranslated, no category, not protected, etc.). The aria-label
   carries the semantic ("not set", "not translated", "no category", …)
   so screen readers don't announce the literal em-dash glyph. */
.absence-mark {
  color: var(--alice-text-tertiary);
  font-weight: 400;
  font-style: normal;
}
/* Clickable em-dash — keep the at-rest visual identical to a static
   absence-mark; the action affordance shows only on hover/focus.
   Per specs/ux/DECISIONS.md "coherence fix Option B" — the user must
   not see two different glyphs for the same "absence" semantic, even
   when one happens to be inside an <a>. */
a.absence-mark,
button.absence-mark {
  text-decoration: none;
  cursor: pointer;
}
a.absence-mark:hover,
a.absence-mark:focus-visible,
button.absence-mark:hover,
button.absence-mark:focus-visible {
  background: rgba(24, 95, 165, 0.07);
  outline: none;
  border-radius: 3px;
}

/* Green check affirm marker — the parallel of .absence-mark for
   "yes / present / set" semantics. Replaces ad-hoc unstyled &#10003;
   spans and the legacy .protected-check class so a Yes always looks
   identical regardless of which column it lives in. */
.affirm-mark {
  color: var(--alice-teal);
  font-weight: 700;
  font-style: normal;
}

/* Edit-lingua toggle in topnav: small pencil icon + iOS-style switch.
   Visible only to EDIT_LINGUA holders; aria-pressed mirrors cookie state. */
.nav-edit-lingua {
  background: transparent;
  border: none;
  padding: 0;
  margin: 0 4px;
  cursor: pointer;
  color: inherit;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.nav-edit-lingua svg { width: 14px; height: 14px; }
.nav-edit-lingua:hover svg { color: var(--alice-warning); }
.nav-edit-lingua-switch {
  display: inline-flex;
  align-items: center;
  width: 26px;
  height: 14px;
  background: var(--alice-border);
  border-radius: 7px;
  position: relative;
  transition: background 0.2s;
  flex-shrink: 0;
}
.nav-edit-lingua-switch::before {
  content: "";
  position: absolute;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  transition: left 0.2s;
  box-shadow: 0 1px 2px rgba(0,0,0,0.25);
}
.nav-edit-lingua[aria-pressed="true"] .nav-edit-lingua-switch {
  background: var(--alice-warning);
}
.nav-edit-lingua[aria-pressed="true"] .nav-edit-lingua-switch::before {
  left: 14px;
}
.nav-edit-lingua[aria-pressed="true"] svg { color: var(--alice-warning); }

/* ── Record card (partials/record_views.html) ───────────────────
   Shared read-only record display used by lexia LIST/RECORD modes and
   the dashboard INDIVIDUAL/BOTH record card. Single source of truth so
   look-&-feel refinements propagate to every read-only record surface.
   Forms use partials/schema_form.html (.schema-grid) — the two share
   the same two-column rhythm and label weight on purpose. */
.record-card {
  border: 1px solid var(--alice-border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--alice-surface);
  margin: 0.5rem 0;
}
.record-card__head {
  background: var(--alice-gray-tint, #f3f4f6);
  padding: 0.5rem 0.8rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--alice-text);
  border-bottom: 1px solid var(--alice-border);
}
.record-card__fields {
  display: grid;
  grid-template-columns: minmax(120px, max-content) minmax(0, 1fr);
  column-gap: 1rem;
  row-gap: 0.45rem;
  align-items: start;
  margin: 0;
  padding: 0.7rem 0.85rem;
  font-size: 0.9rem;
}
.record-card__fields dt {
  font-weight: 600;
  color: var(--alice-text-secondary);
  text-align: right;
}
.record-card__fields dd {
  margin: 0;
  min-width: 0;
  word-break: break-word;
  overflow-wrap: anywhere;
}
.record-card__fields--nested {
  padding: 0.3rem 0;
  row-gap: 0.3rem;
  font-size: 0.86rem;
}
.record-card__group-label {
  font-weight: 600;
  color: var(--alice-text);
  grid-column: 1 / -1;
  border-top: 1px solid var(--alice-border-subtle, var(--alice-border));
  padding-top: 0.4rem;
  text-align: left;
}
.record-card__group { grid-column: 1 / -1; }
.record-card__empty { color: var(--alice-text-tertiary, #999); }
.record-card__md > :first-child { margin-top: 0; }
.record-card__md > :last-child  { margin-bottom: 0; }

/* Record list (lexia LIST mode browser) — matching visual accents:
   a light-gray header strip and zebra-free rows with a subtle hover. */
.record-list {
  list-style: none;
  margin: 0.7rem 0 0 0;
  padding: 0;
  max-height: 280px;
  overflow: auto;
  border: 1px solid var(--alice-border);
  border-radius: 6px;
}
.record-list__item {
  border-bottom: 1px solid var(--alice-border-subtle, var(--alice-border));
  padding: 0;
}
.record-list__item:last-child { border-bottom: none; }
.record-list__item a {
  display: block;
  padding: 0.45rem 0.7rem;
  text-decoration: none;
  font-size: 0.9rem;
  color: var(--alice-text);
}
.record-list__item a:hover { background: var(--alice-gray-tint, #f3f4f6); }

/* ── Markdown preview ──────────────────────────── */
.md-preview {
  margin-top: 6px; padding: 10px 14px;
  background: var(--alice-bg);
  border: 1px solid var(--alice-border);
  border-radius: 6px;
  font-size: 13px; color: var(--alice-text);
  line-height: 1.6; min-height: 40px;
  /* Prevent wide markdown (large images, long unbreakable URLs,
     long inline code) from inflating the parent .lingua-panel and
     pushing the save button off-screen. ALICE_ABOUT regression
     reproduced on /admin/nuntius/ALICE_ABOUT — see SPECS36+ admin
     fixes. */
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.md-preview h1,.md-preview h2,.md-preview h3 {
  color: var(--alice-text); margin-bottom: 8px;
}
.md-preview code {
  background: var(--alice-bg);
  padding: 1px 5px; border-radius: 3px;
}
/* Cap inline images and long pre/code blocks to the preview width so
   page-scale assets (NSF / NIH logos at native pixel size in
   ALICE_ABOUT) never widen the column. */
.md-preview img {
  max-width: 100%;
  height: auto;
}
.md-preview pre {
  max-width: 100%;
  overflow-x: auto;
  white-space: pre;
}
.md-preview table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

/* ── Calculus card ─────────────────────────────── */


/* Warning-tinted variant of the standard .card (used by the
   Calculus action on the admin opus actions page). Inherits all
   .card padding/border-radius/sizing — only the colors change. */
.card--warn {
  border-color: var(--alice-warning);
  background: var(--alice-amber-tint);
}
.card--warn:hover {
  filter: brightness(0.97);
}

.btn-calculus {
  background: var(--alice-warning); color: #fff;
  border: none; padding: 8px 20px; border-radius: 6px;
  font-weight: 600; cursor: pointer;
}


/* ── Modal ─────────────────────────────────────── */
.modal {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  z-index: 1000; display: flex;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,.5);
}
.modal.hidden { display: none; }
.modal-box {
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-radius: 10px; padding: 2rem;
  max-width: 480px; width: 90%;
}
.modal-actions {
  display: flex; gap: 8px; margin-top: 1rem;
}

/* ── NUNTIUS body ──────────────────────────────── */
.nuntius-body {
  line-height: 1.7; font-size: 15px;
}
.nuntius-body h1,.nuntius-body h2,.nuntius-body h3 {
  margin-top: 1.5rem; margin-bottom: 0.5rem;
}

/* ── Edge editor ───────────────────────────────── */
.edge-editor {
  margin-top: 1rem;
  border: 1px solid var(--alice-border);
  border-radius: 8px; padding: 1rem;
}
.edge-editor__hint {
  color: var(--alice-text-secondary);
  font-size: 13px; font-style: italic;
}

/* 14. Responsive overrides */
@media (max-width: 480px) {
    

    .grid-2col {
        grid-template-columns: 1fr;
    }

    .col-course {
        display: none;
    }

    .login-card {
        margin: 1rem;
    }
}

/* ── Submission text display ─────────────────── */
.submission-text {
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 6px; padding: 10px 14px;
  font-size: 13px; color: rgba(255,255,255,.8);
  line-height: 1.6; white-space: pre-wrap;
  max-height: 200px; overflow-y: auto;
  margin-bottom: 10px;
}

/* ── Tessera share view ──────────────────────── */
.tessera-notice {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; border-radius: 10px;
  background: rgba(212,168,67,.15);
  border: 1px solid rgba(212,168,67,.3);
  font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 16px;
}

/* ── Status pill ─────────────────────────────── */
.pill {
  display: inline-block; padding: 2px 8px;
  border-radius: 10px; font-size: 11px;
  font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase;
}
.pill-ok { background:rgba(0,120,100,.25); color:#4dd; }
.pill-warn { background:rgba(212,168,67,.2);  color:var(--gold); }
.pill-err { background:rgba(232,75,31,.2);   color:var(--orange); }

/* ── Lingua tabs ─────────────────────────────────── */
.lingua-tabs { margin-top: 1.5rem; }

.lingua-tab-bar {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-bottom: 1px solid var(--alice-border);
  margin-bottom: 0;
  position: sticky;
  top: 0;
  background: var(--alice-bg);
  z-index: 50;
  padding-top: 4px;
}
body.nav-locked .lingua-tab-bar {
  /* --lingua-tab-top is computed by alice.js (updateNavOffsets);
     falls back to 44px if no breadcrumb is present on the page. */
  top: var(--lingua-tab-top, 44px);
}
.lingua-tab-btn {
  padding: 6px 14px; font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  background: none; border: 1px solid transparent;
  border-bottom: none; border-radius: 4px 4px 0 0;
  cursor: pointer; color: var(--alice-text-secondary);
  transition: color .15s, background .15s;
  margin-bottom: -1px;
}
.lingua-tab-btn:hover { color: var(--alice-text); }
.lingua-tab-btn.active {
  background: var(--alice-surface);
  border-color: var(--alice-border);
  border-bottom-color: var(--alice-surface);
  color: var(--alice-blue); font-weight: 700;
}
.lingua-panel {
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-top: none;
  border-radius: 0 0 6px 6px;
  padding: 20px;
  /* Same overflow defense as .md-preview — prevents an inner runaway
     element (textarea content, rendered markdown) from inflating the
     panel and hiding controls at the right edge.
     `overflow-x: clip` (not hidden) because `hidden` makes this a
     scroll container, which breaks `position: sticky` for the
     EasyMDE editor toolbar inside. `clip` clips wide content the
     same way without creating a scroll container, so the
     focus-gated sticky toolbar rule (alice.css §EasyMDEContainer)
     keeps working on /admin/opus/{id}/lexia/{id}. */
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: clip;
}
.lingua-panel.hidden { display: none; }

.lingua-add-section {
  margin-top: 1.5rem;
  padding: 16px;
  border: 1px dashed var(--alice-border);
  border-radius: 6px;
}
.lingua-add-section h3 {
  margin-top: 0; font-size: 13px;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--alice-text-secondary);
}

/* ── Chip input ──────────────────────────────────── */
.chip-input { display: flex; flex-direction: column; gap: 8px; }
.chip-list {
  display: flex; flex-wrap: wrap; gap: 6px; min-height: 32px;
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px;
  background: rgba(0,85,164,.1);
  border: 1px solid var(--alice-blue);
  border-radius: 4px; font-size: 12px;
}
.chip-label {
  color: var(--alice-blue); text-decoration: none; max-width: 300px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip-label:hover { text-decoration: underline; }
.chip-remove {
  background: none; border: none; cursor: pointer;
  color: var(--alice-text-secondary); font-size: 12px;
  padding: 0 2px; line-height: 1;
}
.chip-remove:hover { color: var(--alice-text); }
.chip-entry { max-width: 480px; }

/* ── Button alignment (admin forms) ─────────────── */
.form-actions {
  display: flex; justify-content: flex-end;
  margin-top: 16px;
}

.form-actions .btn-primary,
.form-actions .btn-secondary,
.form-actions .btn-danger,
.admin-btn,
.admin-table .btn-primary,
.admin-table .btn-secondary,
.admin-table .btn-danger {
  max-width: var(--btn-max-width, 300px);
  width: auto;
  display: inline-block;
  margin-left: 8px;
}

/* ── Tall textarea ─────────────────────────── */
.form-textarea.tall { min-height: 200px; }

/* ── Lesson page progress chips ────────────── */






/* ── Lesson page tab bar ──────────────────── */
.pagina-tab-bar {
  display: flex; gap: 2px; flex-wrap: wrap;
  margin-bottom: 0;
  /* Bottom border lives on .tab-bar-row so it spans the full width
     including the progress widget on the right. */
}
.pagina-tab-btn {
  padding: 8px 18px; font-size: 13px; font-weight: 400;
  background: none; border: 1px solid transparent;
  border-bottom: none; border-radius: 4px 4px 0 0;
  cursor: pointer; color: var(--alice-text-secondary);
  transition: color .15s; margin-bottom: -1px;
  display: flex; align-items: center; gap: 6px;
  text-decoration: none;
}
.pagina-tab-btn:hover { color: var(--alice-text); }
.pagina-tab-btn.active {
  background: var(--alice-surface);
  border-color: var(--alice-border);
  border-bottom-color: var(--alice-surface);
  color: var(--alice-blue); font-weight: 700;
}
.tab-count {
  background: var(--alice-amber);
  color: var(--alice-surface);
  border-radius: 10px; font-size: 10px;
  padding: 1px 6px; font-weight: 700;
}
.tab-count-quiet {
  background: var(--alice-teal);
  color: var(--alice-surface);
  border-radius: 10px; font-size: 10px;
  padding: 1px 6px; font-weight: 700;
}
.ctx-pill {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  margin-right: 8px;
  border-radius: 4px;
  vertical-align: middle;
  user-select: none;
}
.ctx-pill svg { display: block; width: 22px; height: 22px; }
.ctx-pill--opus { background: var(--alice-teal-tint);  color: var(--alice-teal); }
.ctx-pill--lexia { background: var(--alice-amber-tint); color: var(--alice-warning); }
.asset-row.conflict {
  border-color: var(--alice-amber) !important;
  box-shadow: 0 0 0 2px var(--alice-amber-tint);
}
.asset-conflict-banner {
  background: var(--alice-amber-tint);
  color: var(--alice-warning);
  padding: 0.4rem 0.75rem;
  border-radius: 4px;
  font-size: 0.85em;
  margin-top: 0.5rem;
  display: flex; gap: 0.5rem; align-items: center;
}
.asset-reader-row > summary { list-style: none; }
.asset-reader-row > summary::-webkit-details-marker { display: none; }
.asset-reader-row > summary:hover { background: var(--alice-bg, #f5f5f2); }
.asset-reader-row[open] > summary { border-bottom: 1px solid var(--alice-border, #e0dfd8); }
.asset-add-details { margin-bottom: 0.75rem; }
.asset-add-toggle {
  display: flex; align-items: center;
  padding: 0.5rem 0.75rem;
  background: var(--alice-bg, #f5f5f2);
  border: 1px solid var(--alice-border, #e0dfd8);
  border-radius: 6px;
  font-weight: 600; font-size: 0.9em;
  color: var(--alice-blue);
  cursor: pointer; list-style: none;
}
.asset-add-toggle::-webkit-details-marker { display: none; }
.asset-add-details[open] > .asset-add-toggle {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  margin-bottom: 0;
}
.asset-add-details[open] > form {
  border: 1px solid var(--alice-border, #e0dfd8);
  border-top: none;
  border-radius: 0 0 6px 6px;
  padding: 0.75rem;
}

/* ── Lesson page panels (SPECS28: card treatment) ── */
.pagina-panel {
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-top: none;          /* the active tab supplies the top edge */
  border-radius: 0 0 8px 8px;
  padding: 20px 22px;
  min-height: 200px;
}
.pagina-panel.hidden { display: none; }
.pagina-tag {
  font-size: 14px; color: var(--alice-text-secondary);
  font-style: italic; margin-bottom: 1rem;
}
.pagina-content { font-size: 15px; line-height: 1.7; }
.pagina-content h1,
.pagina-content h2,
.pagina-content h3 { margin-top: 1.5rem; }
/* Responsive images — never overflow the content container */
.pagina-content img {
    max-width: 100%;
    height: auto;
}
/* Manual-course screenshots: border only for alice_manual images */
.pagina-content img[src*="alice_manual"] {
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    margin: 12px 0;
    box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

/* ── Collapsible SLO/Assessment ───────────── */
.pagina-collapsible {
  margin-top: 1.5rem;
  border: 1px solid var(--alice-border);
  border-radius: 6px; overflow: hidden;
}
.pagina-collapsible summary {
  padding: 10px 14px; cursor: pointer;
  font-weight: 600; font-size: 14px;
  background: var(--alice-bg);
  list-style: none; user-select: none;
}
.pagina-collapsible summary::-webkit-details-marker { display: none; }
.pagina-collapsible summary::before {
  content: '+ '; color: var(--alice-blue);
}
.pagina-collapsible[open] summary::before { content: '- '; }
.pagina-collapsible-body {
  padding: 14px; font-size: 14px; line-height: 1.6;
}

/* ── Asset notice ─────────────────────────── */


/* ── PDF embed ────────────────────────────── */



/* ── Video embed ──────────────────────────── */



/* ── Map inline ───────────────────────────── */


/* ── Survey embed ─────────────────────────── */
.survey-embed {
  width: 100%; height: 700px;
  border: 1px solid var(--alice-border); border-radius: 4px;
}

/* ── Submission form ──────────────────────── */
.pagina-submission {
  margin-top: 2rem; padding-top: 1.5rem;
  border-top: 1px solid var(--alice-border);
}
.pagina-existing-submission {
  background: var(--alice-bg);
  border: 1px solid var(--alice-border);
  border-radius: 6px; padding: 12px;
  margin-bottom: 12px; font-size: 13px;
}
.pagina-existing-submission pre {
  margin: 0; white-space: pre-wrap; word-break: break-word;
}

/* ── Next lessons ─────────────────────────── */
.pagina-next-section {
  margin-top: 0.75rem;
  padding-top: 0;
}
.pagina-next-list {
  display: flex; flex-direction: column; gap: 8px; margin-top: 8px;
}
.pagina-next-link {
  display: block; padding: 10px 14px;
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-radius: 6px; text-decoration: none;
  color: var(--alice-text); font-size: 14px;
  transition: border-color .15s, background .15s;
}
.pagina-next-link:hover {
  border-color: var(--alice-blue);
  background: rgba(0,85,164,.06);
  color: var(--alice-blue);
}
.pagina-empty {
  color: var(--alice-text-secondary); font-style: italic;
  font-size: 14px;
}

/* ── Capstone list ────────────────────────── */












/* ── Course page tab bar ──────────────────── */
.crs-tab-bar {
  display: flex; gap: 2px;
  margin-bottom: 0;       /* card attaches directly */
  /* Bottom border lives on .tab-bar-row so it spans the full row width. */
}
.crs-tab-btn {
  padding: 8px 20px; font-size: 13px; font-weight: 400;
  background: none; border: 1px solid transparent;
  border-bottom: none; border-radius: 4px 4px 0 0;
  cursor: pointer; color: var(--alice-text-secondary);
  margin-bottom: -1px; transition: color .15s;
  text-decoration: none; display: inline-flex; align-items: center; gap: 6px;
}
.crs-tab-btn:hover { color: var(--alice-text); }
.crs-tab-btn.active {
  background: var(--alice-surface);
  border-color: var(--alice-border);
  border-bottom-color: var(--alice-surface);
  color: var(--alice-blue); font-weight: 700;
}
/* SPECS28: course panels are cards attached under the active tab */
.crs-panel {
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-top: none;        /* the active tab supplies the top edge */
  border-radius: 0 0 8px 8px;
  padding: 20px 22px;
  min-height: 200px;
}
.crs-panel.hidden { display: none; }

/* ── Public home page grid ───────────────────────── */
.home-public-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 1.5rem;
}
@media (max-width: 640px) {
  .home-public-grid { grid-template-columns: 1fr; }
}

.home-panel {
  background: var(--alice-surface);
  border: 1px solid var(--alice-border);
  border-radius: 8px;
  padding: 20px 22px;
  display: flex; flex-direction: column; gap: 10px;
}
.home-panel__title {
  font-size: 13px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--alice-text-secondary);
  margin: 0;
}
.home-panel__body {
  flex: 1; font-size: 14px; line-height: 1.6;
  color: var(--alice-text);
}
.home-panel__body p { margin: 6px 0 0; }
.home-panel__body h1,
.home-panel__body h2,
.home-panel__body h3 {
  font-size: 15px; font-weight: 700;
  color: var(--alice-text); margin: 0 0 6px;
}
.home-panel__more {
  display: inline-block; font-size: 13px;
  color: var(--alice-blue); text-decoration: none;
  align-self: flex-start;
}
.home-panel__more:hover { text-decoration: underline; }


/* ── Textarea and preview fixes ──────────────────── */
.lingua-panel textarea,
.lingua-panel .form-textarea {
  width: 100%;
  box-sizing: border-box;
}
.md-preview:empty { display: none; }

/* ── Nuntius body content ───────────────────────────────────────────── */

.nuntius-body img {
    height: 60px;
    width: auto;
    vertical-align: middle;
    margin-right: 0.6rem;
}

.nuntius-body p {
    margin-block: 0.75rem;
}

.nuntius-body p:has(img) {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.nuntius-body a {
    color: var(--alice-blue);
}

.nuntius-body a:hover {
    text-decoration: underline;
}

.nuntius-body hr {
    border: none;
    border-top: 1px solid var(--alice-border);
    margin-block: 1.5rem;
}

/* ── Asset list (PDF / Video tab) ───────────────────────────── */

.asset-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

.asset-list-btn {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    width: 100%;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    padding: 10px 14px;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.15s, background 0.15s;
}

.asset-list-btn:hover,
.asset-list-btn.active {
    border-color: var(--alice-blue);
    background: var(--alice-blue-tint);
}

.asset-list-btn[aria-expanded="true"] {
    border-color: var(--alice-blue);
}







/* ── Asset viewer ────────────────────────────────────────────── */











/* ── AI Agent sidebar ────────────────────────────────────────── */

.agent-toggle-btn {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 300;
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--alice-blue);
    color: #fff;
    border: none;
    border-radius: 24px;
    padding: 10px 18px;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);
    transition: background 0.15s, box-shadow 0.15s;
}

.agent-toggle-btn:hover {
    opacity: 0.9;
    box-shadow: 0 4px 14px rgba(0,0,0,0.22);
}

.agent-toggle-label {
    white-space: nowrap;
}

.agent-panel {
    position: fixed;
    top: 0;
    /* 10 px clear of the viewport so the panel's internal scrollbar
       never gets shoved under the browser scrollbar. */
    right: 10px;
    width: 420px;
    min-width: 320px;
    max-width: 1200px;
    height: 100vh;
    background: var(--alice-surface);
    /* Hard border on every side — the panel now floats inside the
       viewport so the right border is visible too. */
    border: 2px solid var(--alice-border);
    box-shadow: -6px 0 24px rgba(0,0,0,0.18);
    z-index: 400;
    display: flex;
    flex-direction: column;
    /* No width transition — it would fight the drag-to-resize handler. */
}

/* When nav-lock is active the topnav (44px) + breadcrumb become sticky.
   Push the panel down by the combined height so the tab bar / close X
   aren't occluded. alice.js publishes the sum on <body> as
   --lingua-tab-top; we default to 0 when the JS hasn't run yet. */
body.nav-locked .agent-panel {
    top: var(--lingua-tab-top, 0px);
    height: calc(100vh - var(--lingua-tab-top, 0px));
}

/* Left-edge drag handle for live resize. */
.agent-panel-resizer {
    position: absolute;
    top: 0;
    left: -4px;
    width: 8px;
    height: 100%;
    cursor: col-resize;
    background: transparent;
    z-index: 401;
}
.agent-panel-resizer:hover,
.agent-panel-resizer:active {
    background: linear-gradient(
        to right, transparent, var(--alice-blue) 45%,
        var(--alice-blue) 55%, transparent);
    opacity: 0.35;
}

.agent-panel.hidden {
    display: none;
}

.agent-panel-header {
    display: flex;
    align-items: center;
    /* Title only; close button moved to the tab bar. Tighter padding
       so the header doesn't steal vertical space from the chat area. */
    padding: 8px 12px 6px;
    flex-shrink: 0;
}

.agent-panel-title {
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--alice-text);
}

.agent-panel-newchat,
.agent-panel-close {
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    cursor: pointer;
    line-height: 1;
    color: var(--alice-text);
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    flex-shrink: 0;
    transition: background 0.12s ease, color 0.12s ease,
                border-color 0.12s ease;
}

/* New-chat sits next to the close X; push the pair to the right edge
   of the tab bar via margin-left:auto on the first of the two. */
.agent-panel-newchat {
    margin-left: auto;
    margin-right: 4px;
}

.agent-panel-close {
    font-size: 1.15rem;
    font-weight: 700;
}

.agent-panel-newchat:hover {
    background: var(--alice-blue);
    color: #fff;
    border-color: var(--alice-blue);
}

.agent-panel-close:hover {
    background: #b00;
    color: #fff;
    border-color: #b00;
}

.agent-panel-newchat:focus-visible,
.agent-panel-close:focus-visible {
    outline: 2px solid var(--alice-blue);
    outline-offset: 2px;
}

.agent-messages {
    flex: 1;
    overflow-y: auto;
    /* Match .agent-form padding so the right edge of agent bubbles
       lines up with the right edge of the input textarea below. */
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.agent-msg {
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 0.85rem;
    line-height: 1.5;
    word-break: break-word;
}

.agent-msg--user {
    background: var(--alice-blue);
    color: #fff;
    align-self: flex-end;
    max-width: 88%;           /* questions stay compact + right-aligned */
    border-bottom-right-radius: 2px;
    /* Positioning context for the .agent-msg-copy button (same
       affordance as on assistant bubbles — admin can grab their
       own prompt back to the clipboard). */
    position: relative;
}

.agent-msg--agent {
    background: var(--alice-bg);
    color: var(--alice-text);
    border: 1px solid var(--alice-border);
    /* Stretch full column width so the right edge lines up with the
       input textarea's right edge below. */
    align-self: stretch;
    max-width: none;
    border-bottom-left-radius: 2px;
    /* Establish a positioning context for the .agent-msg-copy button
       so it can pin to the top-right corner of the bubble. */
    position: relative;
}

.agent-msg--thinking {
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
    border: 1px solid var(--alice-border);
    align-self: flex-start;
    font-style: italic;
}

.agent-msg--error {
    background: rgba(200,0,0,0.08);
    color: #b00;
    border: 1px solid rgba(200,0,0,0.2);
    align-self: flex-start;
}

/* "Use as edit plan" button — small primary chip below the bubble's
   top-right controls. Visible only on assistant bubbles when the
   panel data-can-edit-lexia="true". Click fires a single-call
   direct-edit run and streams events into the Flow tab. */
.agent-msg-useplan {
    float: right;
    margin: 6px 0 0 8px;
    padding: 3px 8px;
    border: 1px solid var(--alice-blue, #2563eb);
    border-radius: 12px;
    background: transparent;
    color: var(--alice-blue, #2563eb);
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    position: sticky;
    top: 4px;
    z-index: 2;
}
.agent-msg-useplan:hover {
    background: var(--alice-blue, #2563eb);
    color: #fff;
}

/* Tiny timestamp pinned to the bubble's top-left corner. 6pt is
   intentional — informative when wanted, invisible at a glance. The
   .agent-msg-time element is positioned absolutely so it doesn't
   push the bubble text and doesn't fight the sticky float of the
   .agent-msg-copy / .agent-msg-scrolltop controls on the right. */
.agent-msg-time {
    position: absolute;
    top: 3px;
    left: 6px;
    font-size: 8px;        /* ≈6pt, readable but unobtrusive */
    line-height: 1;
    color: rgba(0, 0, 0, 0.45);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.02em;
    pointer-events: auto;  /* allow hover for the title tooltip */
    user-select: none;
}
.agent-msg--user .agent-msg-time {
    color: rgba(255, 255, 255, 0.65);
}

.agent-form {
    padding: 12px;
    border-top: 1px solid var(--alice-border);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    /* Anchored at bottom of tab panel via flex parent (.agent-tab-panel
       is column flex, .agent-messages has flex:1). */
}

/* ── Per-round flaw cards (Phase A live FOO visibility) ─────────
   Each round opens with a header band and stacks one collapsible
   <details> per critic / reviewer / verifier / harmonizer that
   returns. End-of-round summary card appears under the stack. */
.agent-round-box {
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    margin: 8px 0;
    background: var(--alice-bg);
}
.agent-round-head {
    padding: 6px 10px;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--alice-text-secondary);
    border-bottom: 1px solid var(--alice-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.agent-round-actions {
    text-transform: none;
    font-weight: 500;
    letter-spacing: 0;
    font-size: 0.72rem;
}
.agent-round-actions a {
    color: var(--alice-blue);
    text-decoration: none;
}
.agent-round-actions a:hover { text-decoration: underline; }
.agent-flaws-card {
    border-bottom: 1px solid var(--alice-border);
    padding: 6px 10px;
}
.agent-flaws-card:last-child { border-bottom: none; }
.agent-flaws-card[open] { background: rgba(0,0,0,0.015); }
.agent-flaws-head {
    cursor: pointer;
    font-size: 0.85rem;
    list-style: none;
}
.agent-flaws-head::-webkit-details-marker { display: none; }
.agent-flaws-badge {
    display: inline-block;
    padding: 1px 6px;
    margin-left: 4px;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 600;
}
.agent-flaws-badge--substantive {
    background: rgba(200, 0, 0, 0.10); color: #b00;
}
.agent-flaws-badge--minor {
    background: rgba(245, 158, 11, 0.12); color: #b45309;
}
.agent-flaws-badge--ok {
    background: rgba(22, 163, 74, 0.10); color: #16a34a;
}
.agent-flaws-body {
    margin-top: 6px;
    font-size: 0.82rem;
    line-height: 1.45;
}
.agent-flaws-summary { margin: 4px 0 8px 0; }
.agent-flaws-section { margin: 4px 0; }
.agent-flaws-section-head {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--alice-text-secondary);
    text-transform: uppercase;
    letter-spacing: .04em;
}
.agent-flaws-section ul { margin: 4px 0 4px 16px; padding: 0; }
/* Prose card body — reasoner / writer / planner / etc. The
   server has already truncated; we just need to wrap nicely. */
.agent-prose {
    margin: 4px 0 0 0;
    padding: 6px 8px;
    font-family: inherit;
    font-size: 0.82rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    max-height: 320px;
    overflow-y: auto;
}
.agent-flaws-flag {
    margin: 6px 0 0 0;
    color: var(--alice-warning);
    font-weight: 600;
    font-size: 0.78rem;
}
.agent-round-summary {
    padding: 6px 10px;
    font-size: 0.82rem;
    background: var(--alice-surface);
    border-top: 1px solid var(--alice-border);
}

/* Cancel button shares the send-btn slot but signals destructive
   action with a red tint. Visible only while a /agent/stream call
   is in flight (toggled by JS on submit/finish). */
.agent-cancel-btn {
    background: rgba(176, 0, 0, 0.08);
    border-color: rgba(176, 0, 0, 0.35);
    color: #b00;
}
.agent-cancel-btn:hover {
    background: rgba(176, 0, 0, 0.18);
}

/* Opus-level AI Agent shortcut on /opus/{id}. Sits next to the
   chorus selector in the title row. Links to /opus/{id}/chat. */



/* ── Per-call modifiers strip (single/multi + reasoning slider) ── */
.agent-modifiers {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 6px;
    flex-wrap: wrap;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
}
.agent-mod-toggle {
    display: inline-flex;
    border: 1px solid var(--alice-border);
    border-radius: 999px;
    overflow: hidden;
}
.agent-mod-btn {
    background: transparent;
    border: none;
    padding: 3px 12px;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
    cursor: pointer;
}
.agent-mod-btn.active {
    background: var(--alice-blue);
    color: #fff;
}
.agent-mod-slider {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.agent-mod-label {
    font-weight: 600;
}
.agent-mod-slider input[type="range"] {
    width: 110px;
}
.agent-mod-level {
    display: inline-block;
    min-width: 48px;
    font-variant: small-caps;
    letter-spacing: .04em;
}

/* Wrapper establishes a positioning context for the floating send
   button. The wrapper's height grows with the textarea as the learner
   drags the resize grip, so the button tracks the textarea's bottom
   edge automatically. */
.agent-input-wrap {
    position: relative;
    display: block;
    width: 100%;
}

.agent-input {
    width: 100%;
    font-size: 0.9rem;
    /* Native resize grip would conflict with the floating send button
       hugging the right edge; panel height is driven by the side-panel
       drag handle instead. */
    resize: none;
    min-height: 96px;
    max-height: 40vh;
    line-height: 1.45;
    box-sizing: border-box;
    /* Right gutter reserves space for the floating send button so the
       last line of text never collides with it. */
    padding-right: 44px;
}

.agent-send-btn {
    position: absolute;
    /* 10 px from the textarea's right edge, tucked against the bottom. */
    right: 10px;
    bottom: 8px;
    width: 30px;
    height: 30px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--alice-blue);
    color: #fff;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    transition: background 0.12s ease, transform 0.12s ease;
}
.agent-send-btn:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
}
.agent-send-btn:active {
    transform: translateY(0);
}
.agent-send-btn:focus-visible {
    outline: 2px solid var(--alice-blue);
    outline-offset: 2px;
}
.agent-send-btn svg {
    margin-left: -1px;  /* optical nudge so the arrow looks centered */
}

@media (max-width: 600px) {
    .agent-panel { width: 100vw; }
    .agent-toggle-label { display: none; }
}

/* ── MAX agent panel: tabs, status line, history ────────────── */

.agent-tab-bar {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 8px 0 12px;
    border-bottom: 1px solid var(--alice-border);
    flex-shrink: 0;
}
.agent-tab-panel {
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: hidden;
}
.agent-tab-panel.hidden { display: none; }

.agent-status {
    display: flex;
    align-items: center;
    gap: 8px;
}
.agent-spinner {
    width: 12px;
    height: 12px;
    border: 2px solid var(--alice-border);
    border-top-color: var(--alice-blue);
    border-radius: 50%;
    animation: agent-spin 0.9s linear infinite;
    display: inline-block;
    flex-shrink: 0;
}
@keyframes agent-spin { to { transform: rotate(360deg); } }
.agent-status-round {
    color: var(--alice-text-secondary);
    font-size: 0.78rem;
}

/* Auto-apply chip: a small badge attached to an assistant bubble
   after the orchestrator's "ops" proposal has been auto-applied via
   /agent/apply. Colour-coded by outcome: ok=teal, err=red,
   no_purpose / no_ops=neutral. The bubble itself still shows the
   raw proposal JSON for audit + copy. */
.agent-msg-apply-chip {
    display: inline-block;
    margin-top: 0.5rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.3;
    border: 1px solid var(--alice-border-tertiary);
    background: var(--alice-gray-tint);
    color: var(--alice-text-secondary);
}



/* Editable proposal card — appended to assistant bubbles that
   carry a proposal_kind="ops" payload. Holds a textarea with the
   raw JSON so the admin can tweak titles / body / type before
   firing /agent/apply. Apply / Discard buttons sit below. */
.agent-msg-proposal-card {
    margin-top: 0.6rem;
    padding: 0.55rem 0.65rem;
    border: 1px solid var(--alice-border-tertiary, #ccc);
    border-left: 3px solid var(--alice-blue, #2563eb);
    border-radius: 6px;
    background: var(--alice-bg, #fafafa);
}
.agent-msg-proposal-head {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--alice-text, #333);
    margin-bottom: 0.35rem;
}
.agent-msg-proposal-title {
    display: inline-block;
}
.agent-msg-proposal-json {
    width: 100%;
    box-sizing: border-box;
    font-family: ui-monospace, SFMono-Regular, 'Consolas', monospace;
    font-size: 0.75rem;
    line-height: 1.4;
    padding: 6px 8px;
    border: 1px solid var(--alice-border-tertiary, #ccc);
    border-radius: 4px;
    background: #fff;
    color: var(--alice-text, #333);
    resize: vertical;
    min-height: 90px;
    max-height: 480px;
}
.agent-msg-proposal-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 0.45rem;
}
.agent-msg-proposal-btn {
    padding: 4px 12px;
    border-radius: 4px;
    font-size: 0.78rem;
    font-weight: 500;
    cursor: pointer;
    border: 1px solid transparent;
}
.agent-msg-proposal-btn--apply {
    background: var(--alice-blue, #2563eb);
    color: #fff;
    border-color: var(--alice-blue, #2563eb);
}
.agent-msg-proposal-btn--apply:hover:not(:disabled) {
    filter: brightness(1.05);
}
.agent-msg-proposal-btn--apply:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
.agent-msg-proposal-btn--discard {
    background: transparent;
    color: var(--alice-text-secondary, #777);
    border-color: var(--alice-border, #ddd);
}
.agent-msg-proposal-btn--discard:hover:not(:disabled) {
    background: var(--alice-bg-hover, rgba(0,0,0,0.04));
}
.agent-msg-proposal-status {
    font-size: 0.75rem;
    color: var(--alice-text-secondary, #777);
}
.agent-msg-proposal-status--ok {
    color: var(--alice-teal, #14b8a6);
    font-weight: 500;
}
.agent-msg-proposal-status--err {
    color: #922;
    font-weight: 500;
}

/* Copy-to-clipboard button on every assistant bubble. Pinned to the
   top-right corner of .agent-msg--agent. Quiet by default, hover
   brightens; flashes blue+check briefly on successful copy.
   `position: sticky` (with float:right) keeps the button visible at
   the top of the scrolling area while a tall bubble is being read.
   The button only leaves view when the bubble's bottom scrolls past
   the top of .agent-messages. */
.agent-msg-copy {
    position: sticky;
    top: 6px;
    float: right;
    margin-left: 8px;
    width: 26px;
    height: 26px;
    padding: 0;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border-tertiary);
    border-radius: 4px;
    color: var(--alice-text-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0.55;
    z-index: 2;
    transition: opacity .15s, color .15s, border-color .15s, background .15s;
}
.agent-msg-copy:hover {
    opacity: 1;
    color: var(--alice-blue);
    border-color: var(--alice-blue);
}
.agent-msg-copy--ok {
    opacity: 1;
    color: var(--alice-surface);
    background: var(--alice-teal);
    border-color: var(--alice-teal);
}
.agent-msg-copy svg { display: block; }

.agent-msg-chip {
    margin-top: 6px;
    padding: 2px 8px;
    font-size: 0.72rem;
    color: var(--alice-text-secondary);
    background: transparent;
    border-top: 1px dashed var(--alice-border);
    padding-top: 6px;
}

.agent-msg .lexia-link {
    color: var(--alice-blue);
    text-decoration: underline;
}

.agent-config-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
}
.agent-config-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}
.agent-config-label {
    width: 110px;
    font-size: 0.8rem;
    color: var(--alice-text-secondary);
    flex-shrink: 0;
}
.agent-config-label--link {
    color: var(--link-color);
    text-decoration: none;
    cursor: pointer;
}
.agent-config-label--link:hover { text-decoration: underline; }

/* Friendly-redirect banner shown on the home page when /opus/{id}
   bounces a user back from an inaccessible/missing course. Tinted
   callout — themes via existing CSS variables. */
.home-notice {
    margin: 0 0 1rem;
    padding: 12px 16px;
    border: 1px solid var(--alice-border);
    border-left: 4px solid var(--alice-warning);
    border-radius: 6px;
    background: var(--alice-amber-tint);
    color: var(--alice-text);
    font-size: 0.92rem;
    line-height: 1.5;
}
.home-notice[data-kind="opus_missing"] {
    border-left-color: var(--alice-gray);
    background: var(--alice-gray-tint);
}

/* Friendly error page — used by main.py's global HTTPException
   handler when a browser navigation hits a 4xx/5xx that wasn't
   redirected. Big status code as a visual cue, soft message,
   two-button action row. Themes via existing variables. */
.error-page {
    max-width: 640px;
    margin: 4rem auto;
    padding: 2.5rem 2rem;
    text-align: center;
}
.error-page__code {
    font-size: 4rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    color: var(--alice-text-tertiary);
    line-height: 1;
    margin-bottom: 0.75rem;
}
.error-page__title {
    margin: 0 0 0.5rem;
    font-size: 1.6rem;
}
.error-page__message {
    margin: 0 auto 0.5rem;
    max-width: 480px;
    color: var(--alice-text-secondary);
    line-height: 1.55;
}
.error-page__hint {
    margin: 0 auto 1.5rem;
    max-width: 480px;
    font-size: 0.88rem;
    color: var(--alice-text-tertiary);
    font-style: italic;
}
.error-page__actions {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

/* Grade page heading row — title on the left, nav pills on the
   right. Pills are small rounded outlined links that don't compete
   with the H1 visually but stay one click away from the two places
   an assessor typically wants next: the roster (to pick a different
   student) or the inbox (to pick a different submission). */
.grade-heading-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.grade-heading {
    margin: 0;
}
.grade-heading-pills {
    display: inline-flex;
    gap: 8px;
    flex-wrap: wrap;
}
.grade-pill {
    display: inline-block;
    padding: 4px 12px;
    border: 1px solid var(--alice-border-strong, var(--alice-border));
    border-radius: 999px;
    background: var(--alice-surface);
    color: var(--link-color);
    font-size: 0.82rem;
    line-height: 1.4;
    text-decoration: none;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.grade-pill:hover {
    border-color: var(--alice-blue);
    background: var(--alice-blue-tint);
    text-decoration: none;
}
.grade-pill:focus-visible {
    outline: 2px solid var(--alice-focus, var(--alice-blue));
    outline-offset: 2px;
}

.agent-config-row .form-select,
.agent-config-row .form-input {
    flex: 1;
    min-width: 0;
}
.agent-config-orphan {
    margin: 10px 0;
    padding: 8px 12px;
    background: rgba(217,119,6,0.12);
    color: #b45309;
    border: 1px solid rgba(217,119,6,0.25);
    border-radius: 6px;
    font-size: 0.78rem;
}
.agent-config-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--alice-border);
}
.agent-config-header {
    padding: 8px 10px;
    margin-bottom: 10px;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    font-size: 0.82rem;
    color: var(--alice-text);
}
.agent-config-status { font-size: 0.78rem; color: var(--alice-text-secondary); }
.agent-config-status.ok { color: #16a34a; }
.agent-config-status.err { color: #b00; }








/* ── Flow tab — agent execution graph + per-step cards ─────────
   :not(.hidden) qualifier is essential: an ID selector outranks
   the .hidden class on specificity, so without it the Flow tab
   would render its toolbar/graph/steps in EVERY tab. With it,
   `display: flex` only applies when the tab is the active one
   (no .hidden class), letting the default .hidden { display:none }
   actually hide it. */
#agent-tab-flow:not(.hidden) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.agent-flow-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--alice-border);
    flex-shrink: 0;
    font-size: 0.78rem;
}
.agent-flow-mode-pill {
    padding: 3px 10px;
    border-radius: 10px;
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.3px;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    color: var(--alice-text-secondary);
}
.agent-flow-mode-pill[data-mode="live"] {
    background: var(--alice-amber-tint);
    border-color: var(--alice-amber);
    color: var(--alice-warning);
}
.agent-flow-mode-pill[data-mode="history"] {
    background: var(--alice-teal-tint);
    border-color: var(--alice-teal);
    color: var(--alice-teal);
}
.agent-flow-follow {
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--alice-text-secondary);
    cursor: pointer;
}
.agent-flow-replay-controls {
    display: flex;
    align-items: center;
    gap: 4px;
}
.agent-flow-replay-controls.hidden { display: none; }
.agent-flow-ctrl-btn {
    width: 28px; height: 24px;
    padding: 0;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border-tertiary);
    border-radius: 4px;
    color: var(--alice-text-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color .12s, border-color .12s, background .12s;
}
.agent-flow-ctrl-btn:hover {
    color: var(--alice-blue);
    border-color: var(--alice-blue);
}
.agent-flow-ctrl-btn:active {
    background: var(--alice-bg);
}
.agent-flow-follow--disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.agent-flow-follow--disabled input { pointer-events: none; }
.agent-flow-step-counter {
    font-variant-numeric: tabular-nums;
    color: var(--alice-text-secondary);
    font-size: 0.72rem;
}
.agent-flow-graph {
    flex-shrink: 0;
    border-bottom: 1px solid var(--alice-border);
    background: var(--alice-bg);
}
.agent-flow-cy {
    width: 100%;
    height: 240px;
}
.agent-flow-steps {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Per-step highlight while scrubbing in history mode. */
.agent-flow-current-step {
    outline: 2px solid var(--alice-blue);
    outline-offset: 2px;
    background: rgba(59,130,246,0.04);
}
.agent-flow-dim-step { opacity: 0.55; }

/* Cards in the Flow tab use the native <details> element with `open`
   set by default (see _agentBuildCardElement). Click the card summary
   to collapse any individual card; per-round Collapse All / Expand
   All links toggle every card in that round. No custom CSS clamp
   needed — native details handles expand/collapse. */

/* Scroll-to-top button on long assistant bubbles. Mirrors the
   sticky-positioning on .agent-msg-copy so both ride the top of the
   bubble during scroll. */
.agent-msg-scrolltop {
    position: sticky;
    top: 6px;
    float: right;
    margin-left: 4px;
    width: 26px;
    height: 26px;
    padding: 0;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border-tertiary);
    border-radius: 4px;
    color: var(--alice-text-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0.55;
    z-index: 2;
    transition: opacity .15s, color .15s, border-color .15s;
}
.agent-msg-scrolltop:hover {
    opacity: 1;
    color: var(--alice-blue);
    border-color: var(--alice-blue);
}

/* ── Structured Raw tab + cross-tab jump highlight ──────────── */
.agent-raw-section {
    padding: 8px 12px;
    border-bottom: 1px solid var(--alice-border);
}
.agent-raw-section h4 {
    margin: 0 0 6px 0;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.agent-raw-entry {
    margin: 4px 0 4px 12px;
    border-left: 2px solid var(--alice-border);
    padding-left: 8px;
    transition: background-color .25s linear;
}
.agent-raw-entry summary {
    cursor: pointer;
    font-size: 0.78rem;
    color: var(--alice-text);
    padding: 2px 0;
}
.agent-raw-entry pre {
    margin: 4px 0 8px 0;
    padding: 6px 8px;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    font-size: 0.72rem;
    overflow-x: auto;
    white-space: pre-wrap;
}
.agent-raw-entry--card { border-left-color: var(--alice-amber); }
.agent-raw-entry--summary { border-left-color: var(--alice-teal); }
.agent-raw-entry--proposal { border-left-color: var(--alice-blue); }
.agent-raw-highlight {
    background-color: var(--alice-amber-tint);
}
.agent-card-raw-link {
    margin-left: 8px;
    font-size: 0.7rem;
    color: var(--alice-blue);
    text-decoration: none;
}
.agent-card-raw-link:hover { text-decoration: underline; }

/* Per-step timestamp in the Flow card header. Floats right so it
   never crowds the agent name + badge cluster on the left. Same
   muted treatment as the bubble timestamps. */
.agent-flow-step-time {
    float: right;
    margin-left: 8px;
    font-size: 0.7rem;
    color: var(--alice-text-secondary);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.02em;
    user-select: none;
}

.agent-raw-json {
    flex: 1;
    overflow: auto;
    margin: 0;
    padding: 12px;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 0.75rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--alice-text);
    background: var(--alice-bg);
    border: none;
}

/* Sticky toolbar at the top of the Raw tab — mirrors the Flow tab's
   replay controls in shape (small text buttons, separator dot) so
   the two panes feel like a pair. */
.agent-raw-toolbar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: var(--alice-bg);
    border-bottom: 1px solid var(--alice-border);
    font-size: 0.78rem;
}
.agent-raw-toolbtn {
    background: transparent;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 0.78rem;
    color: var(--alice-text);
    cursor: pointer;
    line-height: 1.2;
}
.agent-raw-toolbtn:hover {
    background: var(--alice-bg-hover, rgba(0,0,0,0.04));
}
.agent-raw-toolsep {
    color: var(--alice-text-secondary);
    margin: 0 2px;
}

.agent-history-list {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.agent-history-empty {
    color: var(--alice-text-secondary);
    font-style: italic;
    padding: 12px;
    text-align: center;
}

/* ── Thread attachments: + button, pending pills, drop overlay,
   Files tab, author chip, message attachments list ──────────── */

/* + button to the left of the textarea */
.agent-attach-btn {
    flex-shrink: 0;
    width: 28px; height: 28px;
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    background: var(--alice-bg-elevated, #fff);
    color: var(--alice-text-secondary);
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer; align-self: flex-end;
    margin-right: 4px; margin-bottom: 6px;
}
.agent-attach-btn:hover {
    border-color: var(--alice-blue, #2563eb);
    color: var(--alice-blue, #2563eb);
    background: var(--alice-blue-soft, #e7f0ff);
}
.agent-attach-btn:disabled {
    opacity: 0.4; cursor: not-allowed;
}

/* Primary (blue) variant — used on the modifiers row next to the
   Multi/Single toggle. Reads as the affordance for adding files
   without competing visually with the Send button. */
.agent-attach-btn--primary {
    background: var(--alice-blue, #2563eb);
    border-color: var(--alice-blue, #2563eb);
    color: #fff;
    align-self: center;
    margin-right: 4px; margin-bottom: 0;
}
.agent-attach-btn--primary:hover {
    background: #1d4ed8;
    border-color: #1d4ed8;
    color: #fff;
}
.agent-attach-btn--primary:focus-visible {
    outline: 2px solid var(--alice-blue, #2563eb);
    outline-offset: 2px;
}

/* Pending attachment pills above the textarea */
.agent-pending-attachments {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 6px 8px; margin-bottom: 6px;
    background: var(--alice-bg);
    border: 1px dashed var(--alice-border);
    border-radius: 6px;
}
.agent-pending-attachments[hidden] { display: none; }
.agent-pending-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 6px 3px 8px;
    background: var(--alice-bg-elevated, #fff);
    border: 1px solid var(--alice-border);
    border-radius: 12px;
    font-size: 0.78rem;
    max-width: 220px;
}
.agent-pending-pill__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.agent-pending-pill__meta {
    color: var(--alice-text-secondary);
    font-size: 0.72rem;
}
.agent-pending-pill__remove {
    border: none; background: transparent;
    color: var(--alice-text-secondary);
    font-size: 14px; line-height: 1;
    cursor: pointer; padding: 0 2px;
}
.agent-pending-pill__remove:hover {
    color: #cf1322;
}
.agent-pending-pill--uploading {
    opacity: 0.6;
}


/* Drag-and-drop overlay (covers #agent-messages while dragging) */
.agent-drop-overlay {
    position: absolute; inset: 0;
    background: rgba(231, 240, 255, 0.92);
    border: 2px dashed var(--alice-blue, #2563eb);
    border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    color: var(--alice-blue, #2563eb);
    font-weight: 500; font-size: 0.9rem;
    pointer-events: none;
    z-index: 80;
}
.agent-drop-overlay[hidden] { display: none; }
.agent-drop-overlay__inner {
    display: flex; flex-direction: column; align-items: center;
    gap: 8px; text-align: center;
}

/* The chat panel needs position:relative for the overlay to anchor. */
#agent-tab-chat { position: relative; }

/* Author chip above a USER message bubble */
.agent-msg__author {
    font-size: 0.72rem;
    color: var(--alice-text-secondary);
    margin-bottom: 2px;
    text-align: right;
}


/* Attachments rendered under a USER message bubble */
.agent-msg__attachments {
    display: flex; flex-wrap: wrap; gap: 6px;
    margin-top: 4px;
    justify-content: flex-end;
}
.agent-msg__attachment-link {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 6px;
    background: var(--alice-bg-elevated, #fff);
    border: 1px solid var(--alice-border);
    border-radius: 10px;
    font-size: 0.74rem;
    text-decoration: none;
    color: var(--alice-text, #1a1a1a);
    max-width: 200px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agent-msg__attachment-link:hover {
    border-color: var(--alice-blue, #2563eb);
    color: var(--alice-blue, #2563eb);
}






/* Files tab rows */
.agent-files-list {
    display: flex; flex-direction: column; gap: 6px;
    padding: 8px;
}
.agent-files-row {
    display: flex; align-items: center; gap: 8px;
    padding: 8px;
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    background: var(--alice-bg-elevated, #fff);
}
.agent-files-row__name {
    flex: 1 1 auto;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-weight: 500;
}
.agent-files-row__meta {
    font-size: 0.74rem;
    color: var(--alice-text-secondary);
}
.agent-files-row__actions {
    display: flex; gap: 4px; align-items: center;
}
.agent-files-row__btn {
    border: 1px solid var(--alice-border);
    background: transparent;
    border-radius: 4px;
    padding: 2px 8px;
    font-size: 0.78rem;
    cursor: pointer;
    color: var(--alice-text, #1a1a1a);
    text-decoration: none;
}
.agent-files-row__btn:hover {
    border-color: var(--alice-blue, #2563eb);
    color: var(--alice-blue, #2563eb);
}
.agent-files-row__btn--del:hover {
    border-color: #cf1322;
    color: #cf1322;
}
.agent-history-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    background: var(--alice-bg);
}
.agent-history-title {
    font-weight: 600;
    color: var(--alice-text);
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.agent-history-pill {
    display: inline-block;
    padding: 1px 7px;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    border-radius: 10px;
}
.agent-history-pill--opus {
    background: rgba(147, 51, 234, 0.12);
    color: #9333ea;
}
.agent-history-title:hover { text-decoration: underline; }
.agent-history-preview {
    color: var(--alice-text-secondary);
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.agent-history-meta {
    color: var(--alice-text-secondary);
    font-size: 0.72rem;
}
.agent-history-delete {
    align-self: flex-end;
    padding: 4px 10px;
    font-size: 0.78rem;
    background: transparent;
    color: var(--alice-text-secondary);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    cursor: pointer;
}
.agent-history-delete:hover {
    background: var(--alice-bg);
    color: var(--alice-text);
}
/* Admin-only hard-delete variant. Tinted red so it never gets
   confused with the soft-delete (Hide) button next to it. */
.agent-history-hard-delete {
    margin-left: 6px;
    color: #b00;
    border-color: rgba(176, 0, 0, 0.35);
}
.agent-history-hard-delete:hover {
    background: rgba(176, 0, 0, 0.08);
    color: #b00;
}

/* Hidden threads: collapsed <details> bands below active threads. */
.agent-history-hidden {
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background: transparent;
    font-size: 0.8rem;
    color: var(--alice-text-secondary);
}
.agent-history-hidden-summary {
    cursor: pointer;
    padding: 6px 10px;
    user-select: none;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 6px;
}
.agent-history-hidden-summary::-webkit-details-marker { display: none; }
.agent-history-hidden-summary::before {
    content: '\25B6';
    font-size: 0.6rem;
    transition: transform 0.15s ease;
    display: inline-block;
    flex-shrink: 0;
}
.agent-history-hidden[open] > .agent-history-hidden-summary::before {
    transform: rotate(90deg);
}
.agent-history-hidden-body {
    padding: 6px 10px 10px;
    border-top: 1px dashed var(--alice-border);
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.agent-history-unhide {
    align-self: flex-end;
    padding: 4px 10px;
    font-size: 0.78rem;
    background: transparent;
    color: var(--alice-blue);
    border: 1px solid var(--alice-blue);
    border-radius: 4px;
    cursor: pointer;
}
.agent-history-unhide:hover {
    background: var(--alice-blue);
    color: #fff;
}

/* ── Capstone cards (SPECS11) ───────────────────────────────── */

.capstone-card {
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 12px;
    background: var(--alice-surface);
    transition: border-color 0.15s;
}

.capstone-card--active {
    border-color: var(--alice-blue);
    background: var(--alice-blue-tint);
}

.capstone-card-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.capstone-star {
    font-size: 1.3rem;
    color: var(--alice-amber);
    flex-shrink: 0;
}

.capstone-star--empty {
    color: var(--alice-text-secondary);
}

.capstone-card-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

.capstone-card-tag {
    font-size: 0.82rem;
    color: var(--alice-text-secondary);
    margin: 0 0 10px 0;
}

.capstone-card-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
}

.capstone-active-label {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--alice-blue);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.btn-ghost {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--alice-text-secondary);
    padding: 4px 8px;
    border-radius: 4px;
    text-decoration: underline;
}

.btn-ghost:hover { color: var(--alice-text); }

/* ── Syllabus (SPECS11) ─────────────────────────────────────── */

.syllabus-no-capstone {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--alice-text-secondary);
}

.syllabus-tag {
    display: block;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
    margin-top: 2px;
}

/* ── Map inline container (SPECS11) ─────────────────────────── */

.map-container-inline {
    width: 100%;
    height: 540px;
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    margin-top: 12px;
}

/* ── Category selector (SPECS11) ────────────────────────────── */

.category-selector {
    margin-bottom: 12px;
}

.category-selector__label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--alice-text-secondary);
    margin-bottom: 6px;
}

.category-selector__options {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* ── Cytoscape map cursor (SPECS11) ─────────────────────────── */

#cy canvas {
    cursor: default;
}

/* ── Map controls bar ────────────────────────────────────────── */

.map-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    margin-bottom: 6px;
    flex-wrap: wrap;
}

.map-legend {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--alice-text-secondary);
}
.legend-sep {
    color: var(--alice-border);
    font-size: 14px;
    margin: 0 2px;
}
.legend-icon {
    font-size: 16px;
    font-weight: bold;
    color: var(--alice-text);
    line-height: 1;
}

.map-ctrl-btns {
    display: flex;
    align-items: center;
    gap: 6px;
}

.map-ctrl-btn {
    padding: 4px 10px;
    font-size: 11px;
    font-weight: 600;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    cursor: pointer;
    color: var(--alice-text-secondary);
    transition: border-color 0.12s, color 0.12s;
}

.map-ctrl-btn:hover {
    border-color: var(--alice-blue);
    color: var(--alice-text);
}



.map-toggle {
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: none; cursor: pointer; padding: 0;
}
.map-toggle-label {
    font-size: 11px; font-weight: 600;
    color: var(--alice-text-secondary);
}
.map-toggle-track {
    display: inline-flex; align-items: center;
    width: 32px; height: 18px;
    background: var(--alice-border); border-radius: 9px;
    flex-shrink: 0; transition: background 0.2s;
    position: relative;
}
.map-toggle--on .map-toggle-track { background: var(--alice-blue); }
.map-toggle-thumb {
    position: absolute; left: 2px;
    width: 14px; height: 14px; border-radius: 50%;
    background: #fff; transition: left 0.2s;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.map-toggle--on .map-toggle-thumb { left: 16px; }

.map-font-ctrl {
    display: inline-flex;
    border: 1px solid var(--alice-border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--alice-surface);
}
.map-font-btn {
    width: 26px; height: 26px;
    border: none; background: none;
    cursor: pointer;
    font-size: 15px; font-weight: 600; line-height: 1;
    color: var(--alice-text-secondary);
    display: flex; align-items: center; justify-content: center;
}
.map-font-btn:hover { color: var(--alice-text); background: var(--alice-blue-tint); }
.map-font-btn + .map-font-btn { border-left: 1px solid var(--alice-border); }

/* ── EasyMDE overrides for ALICE theme ───────────────────────── */

.EasyMDEContainer {
    border-radius: var(--radius-md);
    border-color: var(--alice-border);
}

.EasyMDEContainer .CodeMirror {
    background: var(--alice-surface);
    color: var(--alice-text);
    border-color: var(--alice-border);
    font-family: var(--font-mono, 'Courier New', monospace);
    font-size: 13px;
}

.EasyMDEContainer .editor-toolbar {
    background: var(--alice-bg);
    border-color: var(--alice-border);
}

.EasyMDEContainer .editor-toolbar button {
    color: var(--alice-text-secondary);
}

.EasyMDEContainer .editor-toolbar button:hover,
.EasyMDEContainer .editor-toolbar button.active {
    background: var(--alice-blue-tint);
    border-color: var(--alice-border);
    color: var(--alice-blue);
}

/* Sticky toolbar for the currently-focused EasyMDE editor.
   The .is-focused class is toggled on .EasyMDEContainer by
   CodeMirror focus/blur events in each page's MDE init code.
   The top offset reads --mde-sticky-top, which defaults to
   --lingua-tab-top (computed by alice.js as topnav+breadcrumb
   height). Pages with their own sticky bar above the editor
   (e.g. admin lexia's .lingua-tab-bar) override --mde-sticky-top
   to push the toolbar down accordingly. !important defeats
   EasyMDE's own `.editor-toolbar { position: relative }`. */
.EasyMDEContainer .editor-toolbar {
    position: relative !important;
}
.EasyMDEContainer.is-focused .editor-toolbar {
    position: sticky !important;
    top: var(--mde-sticky-top, var(--lingua-tab-top, 0px));
    z-index: 40;
    background: var(--alice-surface, #fff);
}

.EasyMDEContainer .editor-preview {
    background: var(--alice-surface);
    color: var(--alice-text);
    border-color: var(--alice-border);
}

/* ── Top navigation (SPECS12) ──────────────────────────────── */

.topnav {
    display: flex;
    align-items: stretch;
    height: 44px;
    background: var(--alice-surface);
    border-bottom: 1px solid var(--alice-border);
    z-index: 200;
    top: 0;
}

.topnav--locked {
    position: sticky;
    top: 0;
    z-index: 500;
    box-shadow: 0 1px 8px rgba(0,0,0,0.08);
}

.topnav-inner {
    display: flex;
    align-items: center;
    width: 100%;
    max-width: var(--content-max-width, 1200px);
    margin: 0 auto;
    padding: 0 16px;
    gap: 0;
    position: relative;
}

.topnav-wordmark {
    font-family: Georgia, "Times New Roman", serif;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--alice-text);
    text-decoration: none;
    margin-right: 24px;
    flex-shrink: 0;
}

.topnav-links {
    display: flex;
    align-items: stretch;
    flex: 1;
    gap: 0;
}

.nav-scroll-top {
    background: transparent;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    color: var(--alice-text-secondary);
    cursor: pointer;
    line-height: 0;
    padding: 4px 8px;
    margin-right: 8px;
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.nav-scroll-top:hover {
    color: var(--alice-text);
    border-color: var(--alice-text-secondary);
}
.nav-scroll-top.hidden { display: none; }

.topnav-user {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    margin-left: auto;
    font-size: 12px;
    color: var(--alice-text-secondary);
}

/* ── Burger category (collapsible, SPECS12) ───────────────── */

.burger-category {
    border-bottom: 1px solid var(--alice-border);
}

.burger-category:last-of-type { border-bottom: none; }

.burger-category-header {
    padding: 8px 16px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--alice-text-secondary);
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    user-select: none;
}

.burger-category-header::-webkit-details-marker { display: none; }

.burger-category-header::after {
    content: '+';
    font-size: 13px;
    font-weight: 400;
    color: var(--alice-text-secondary);
    transition: transform 0.15s;
}

.burger-category[open] .burger-category-header::after {
    content: '\2212';
}

.burger-category-body {
    padding-bottom: 4px;
}

.burger-sublabel {
    padding: 4px 16px 2px;
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--alice-text-secondary);
}

/* ── Burger toggle (nav lock switch, SPECS12) ─────────────── */

.burger-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
}

.burger-toggle-track {
    display: inline-flex;
    align-items: center;
    width: 32px;
    height: 18px;
    background: var(--alice-border);
    border-radius: 9px;
    flex-shrink: 0;
    transition: background 0.2s;
    position: relative;
}

.burger-toggle--on .burger-toggle-track {
    background: var(--alice-blue);
}

.burger-toggle-thumb {
    position: absolute;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    transition: left 0.2s;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.burger-toggle--on .burger-toggle-thumb {
    left: 16px;
}

/* ── Burger footer (SPECS12) ──────────────────────────────── */

.burger-footer {
    border-top: 1px solid var(--alice-border);
    padding-top: 4px;
    margin-top: 4px;
}

.burger-item--danger {
    color: var(--alice-warning);
}

.burger-item--active {
    font-weight: 700;
    color: var(--alice-blue);
}

/* ── Mobile: hide desktop nav links, show burger nav (SPECS12) ── */

@media (max-width: 640px) {
    .topnav-links { display: none; }
    .burger-category--mobile { display: block; }
}

@media (min-width: 641px) {
    .burger-category--mobile { display: none; }
}

/* ── Syllabus START/END row indicators (SPECS14) ───────────── */

.syllabus-row--capstone {
    background: rgba(239, 159, 39, 0.05);
}

.syllabus-row--start {
    background: rgba(29, 158, 117, 0.05);
}

.syllabus-start-mark {
    color: var(--alice-teal);
    font-size: 0.85rem;
    flex-shrink: 0;
}

.syllabus-title-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.syllabus-tag {
    display: block;
    font-size: 0.78rem;
    color: var(--alice-text-secondary);
    margin-top: 2px;
}

/* ── Pagina title bar (SPECS14) ──────────────────────────────── */

.pagina-title-bar {
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--alice-border);
}

.pagina-title {
    font-size: 1.4rem;
    font-weight: 700;
    margin: 0 0 4px 0;
    color: var(--alice-text);
    line-height: 1.2;
}

.pagina-title-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 2px solid var(--alice-amber);
    padding-bottom: 1px;
}

.pagina-title-link:hover { color: var(--alice-blue); }



/* ── Content tab edit button (SPECS14) ───────────────────────── */



/* ── Assessment tab with survey (SPECS14) ────────────────────── */

.pagina-assess-content + .pagina-submission,
.pagina-assess-content + .survey-section {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--alice-border);
}

.survey-section--with-submission {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--alice-border);
}

/* ── Segmented progress bar (SPECS15) ──────────────────────── */

.progress-bar-wrap {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Smaller floor so the tab bar has room on a single row even
       on narrower viewports. The wrap still grows to fit its
       labels, but we keep them compact via the smaller font sizes
       below. */
    min-width: 110px;
    flex-shrink: 0;
}

.progress-bar-track {
    display: flex;
    height: 4px;
    border-radius: 2px;
    overflow: hidden;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
}

.progress-seg {
    height: 100%;
    transition: width 0.3s ease;
    flex-shrink: 0;
}

.progress-seg--graded { background: var(--alice-teal); }
.progress-seg--submitted { background: var(--alice-amber); }
.progress-seg--read { background: var(--alice-blue); }
.progress-seg--pending { background: var(--alice-gray); }

.progress-labels {
    display: flex;
    align-items: center;
    gap: 3px;
    font-size: 7px;
    white-space: nowrap;
}

.progress-label {
    display: flex;
    align-items: center;
    gap: 2px;
    /* Override the older global .progress-label rule (font-size: 0.8rem)
       used by the single-color .progress-fill widget. Without this the
       percentages render at ~12.8px and overflow the tab-bar row. */
    font-size: 7px;
    margin-top: 0;
}

/* Each label color tracks its bar segment. Note that we use
   --alice-amber (NOT --alice-warning) for "submitted" so the label
   matches the bar segment colour in every theme — and crucially in
   tritanopia, where --alice-warning collapses to the same vermilion
   as --alice-blue (used by "read"), making the two columns
   indistinguishable. With --alice-amber the submitted label stays
   the reddish-purple #CC79A7 in trit, distinct from the read label. */
.progress-label--graded { color: var(--alice-teal); }
.progress-label--submitted { color: var(--alice-amber); }
.progress-label--read { color: var(--alice-blue); }
.progress-label--pending { color: var(--alice-gray); }

.progress-label-text {
    font-size: 6px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.progress-label-sep {
    color: var(--alice-gray);
    font-size: 7px;
}

/* ── Tab bar row (tabs + progress on same line) ──────────────── */

.tab-bar-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 0;
    border-bottom: 1px solid var(--alice-border);
}

.tab-bar-progress {
    flex-shrink: 0;
}

@media (max-width: 640px) {
    .progress-labels { display: none; }
    .progress-bar-track { height: 8px; }
    .progress-bar-wrap { min-width: 80px; }
}

/* ── Inline asset table (SPECS15) ──────────────────────────── */



.asset-inline-table {
    width: 100%;
    margin-bottom: 8px;
}

.asset-url-cell {
    max-width: 240px;
    overflow: hidden;
}

.asset-url-link {
    font-size: 11px;
    color: var(--alice-blue);
    word-break: break-all;
}

.asset-actions {
    white-space: nowrap;
    display: flex;
    gap: 4px;
}

.btn-ghost--danger {
    color: var(--alice-warning);
}

.btn-ghost--danger:hover {
    color: var(--alice-text);
    background: rgba(186, 117, 23, 0.08);
}

.asset-empty {
    font-size: 12px;
    color: var(--alice-text-secondary);
    font-style: italic;
    margin: 4px 0 8px 0;
}

.asset-add-details {
    margin-top: 8px;
}

.asset-add-summary {
    font-size: 12px;
    font-weight: 600;
    color: var(--alice-blue);
    cursor: pointer;
    padding: 4px 0;
    list-style: none;
    user-select: none;
}

.asset-add-summary::-webkit-details-marker { display: none; }

.asset-add-form {
    margin-top: 8px;
    padding: 12px;
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 6px;
}

.asset-edit-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 16px;
}

.asset-editing {
    background: var(--alice-amber-tint);
}

/* ── Nuntius protected column (SPECS15) ────────────────────── */

.nuntius-col-protected {
    width: 80px;
    text-align: center;
}



/* ── Admin collapsible sections ─────────────────────── */
.admin-section {
    margin: 8px 0;
}
.admin-section > summary {
    cursor: pointer;
    user-select: none;
    padding: 6px 0;
    list-style: none;
}
.admin-section > summary::-webkit-details-marker { display: none; }
.admin-section > summary h2,
.admin-section > summary h3 {
    font-size: 14px;
}
.admin-section > summary::before {
    content: '\25B6';
    display: inline-block;
    width: 16px;
    font-size: 10px;
    transition: transform 0.15s;
}
.admin-section[open] > summary::before {
    transform: rotate(90deg);
}

/* ── Reorder & action buttons right-aligned ─────────── */
.reorder-buttons {
    white-space: nowrap;
    text-align: right;
}
.admin-table .btn-ghost.btn-sm {
    padding: 2px 6px;
    font-size: 13px;
    min-width: 0;
}

/* ── Muted default-text column ──────────────────────── */
.text-muted {
    color: var(--alice-text-secondary);
    font-size: 12px;
}

/* ── Rubric editor (visual + JSON side by side) ─────── */
.rubric-editor {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 4px;
}
.rubric-editor-visual {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rubric-band-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background: var(--alice-bg);
}
.rubric-band-row-top {
    display: flex;
    align-items: center;
    gap: 4px;
}
.rubric-band-row .rubric-label {
    flex: 1;
}
.rubric-desc {
    width: 100%;
    font-size: 12px;
    padding: 4px 6px;
    resize: vertical;
}
.rubric-band-row input[type="number"] {
    width: 60px;
    padding: 4px;
    font-size: 12px;
}
.rubric-band-row input[type="text"] {
    flex: 1;
    padding: 4px;
    font-size: 12px;
}
.rubric-editor-json textarea {
    width: 100%;
    height: 100%;
    resize: vertical;
}

/* ── Inbox tabs (SPECS26) ───────────────────────────── */
.inbox-tab-bar {
    display: flex;
    flex-direction: row;
    gap: 4px;
    margin: 12px 0 0 0;
    border-bottom: 1px solid var(--alice-border);
}
.inbox-tab-bar .pagina-tab-btn {
    flex: 0 0 auto;
}


/* ── Home inbox card (SPECS26) ──────────────────────── */
/* SPECS28 fix: Grading page assessment cards. Each item lives in
   its own card so the page reads as a stack of independent units. */
.grade-card {
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    padding: 18px 22px;
    margin-bottom: 18px;
}
.grade-card-head {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--alice-border);
}
.grade-card-title {
    margin: 0;
    font-size: 16px;
}
.grade-prompt,
.grade-response {
    margin-bottom: 14px;
}

/* Prompt and Response visual boxes on the grading page.
   Each gets a distinct background so the assessor can
   instantly tell what is the prompt vs. the nauta's work. */
.grade-prompt-box,
.grade-response-box {
    margin-bottom: 16px;
    border-radius: 6px;
    overflow: hidden;
}
.grade-section-label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    padding: 6px 14px;
    margin: 0;
}
.grade-section-content {
    padding: 12px 14px;
    font-size: 14px;
    line-height: 1.6;
}
.grade-section-ts {
    float: right;
    font-size: 10px;
    font-weight: 400;
    opacity: 0.7;
}

/* Prompt: darker/muted background — this is reference material */
.grade-prompt-box .grade-section-label {
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
    border-bottom: 1px solid var(--alice-border);
}
.grade-prompt-box .grade-section-content {
    background: var(--alice-surface);
    color: var(--alice-text);
    border: 1px solid var(--alice-border);
    border-top: none;
    border-radius: 0 0 6px 6px;
}

/* Response: surface background — the nauta's work */
.grade-response-box .grade-section-label {
    background: var(--alice-blue-tint);
    color: var(--alice-blue);
    border-bottom: 1px solid var(--alice-border);
}
.grade-response-box .grade-section-content {
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-top: none;
    border-radius: 0 0 6px 6px;
}

/* Previous feedback: teal header — assessor's prior comments */
.grade-feedback-box .grade-section-label {
    background: var(--alice-teal-tint);
    color: var(--alice-teal);
    border-bottom: 1px solid var(--alice-border);
}
.grade-feedback-box .grade-section-content {
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-top: none;
    border-radius: 0 0 6px 6px;
}

/* "Previous feedback" callout. Uses a left-border accent on the
   surface color (same as the rest of the card) so the text remains
   readable in every theme. The previous .feedback-block rule painted
   over text in dark mode. */




/* SPECS28: Reusable inbox panel (used at home, opus, and pagina).
   The tab bar sits on the page background; only the table + pagination
   are wrapped in a card so the active tab visually attaches to it. */
.inbox-panel-component {
    margin: 1.5rem 0;
}
.inbox-panel-scope {
    margin: 0 0 8px 0;
    font-size: 13px;
    color: var(--alice-text-secondary);
}
.inbox-content-card {
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-top: none;       /* the active tab supplies the top edge */
    border-radius: 0 0 8px 8px;
    padding: 16px 18px;
    margin-top: 0;          /* sit just below the tab bar so its
                               border-bottom remains visible as a
                               horizontal divider, except where the
                               active tab punches into it via -2px
                               margin-bottom on the button */
}
/* Bare-mode wrapper used when the macro is rendered inside an
   already-card panel (opus and pagina detail). No background or
   border — the outer panel supplies the card. */
.inbox-content-bare {
    margin: 0;
}
.inbox-table {
    margin-top: 0;
}
/* TYPE column (first th/td) carries a pill from `inbox_kind_badge`.
   Without nowrap the pill wraps to two lines on narrower viewports —
   the user-visible "Pending grade" / "Graded by me" / etc. read as
   broken visual badges. Lock the column to a single line; the rest
   of the row can wrap as needed. Same rule covers Received, Sent,
   and Tokens (Workspace) tabs because all three render through the
   same .inbox-table macro. */
.inbox-table th:first-child,
.inbox-table td:first-child {
    white-space: nowrap;
}
.inbox-sort-link {
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}
.inbox-sort-link:hover {
    color: var(--alice-blue);
}
.inbox-pagination {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    justify-content: center;
}
.inbox-page-status {
    font-size: 12px;
    color: var(--alice-text-secondary);
    padding: 0 8px;
}
.inbox-page-disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
/* Sticky-top "assess in progress" rows: amber tint + accent stripe so
   an assessor's drafted-but-unfinalized work is impossible to miss
   among unclaimed pending-grade rows. */
.inbox-table tr.inbox-row-resume {
    background: var(--alice-amber-tint);
    box-shadow: inset 3px 0 0 var(--alice-amber);
}
.inbox-table tr.inbox-row-resume:hover {
    background: var(--alice-amber-tint);
    filter: brightness(0.97);
}
.inbox-table tr.inbox-row-resume .resume-hint {
    color: var(--alice-warning);
    font-weight: 600;
}

/* ── Student assessments (SPECS26) ──────────────────── */
.student-assessments {
    margin: 16px 0;
}

.assessment-next-round-header {
    background: var(--alice-blue-tint);
    color: var(--alice-blue);
    font-weight: 700;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .06em;
    padding: 10px 16px;
    margin: 20px 0 14px 0;
    border-radius: 6px 6px 0 0;
    border: 1px solid var(--alice-border);
    border-bottom: none;
}




.assessment-form {
    margin-top: 8px;
}


.assessment-submit-all {
    margin-top: 24px;
    padding-top: 16px;
    border-top: 2px solid var(--alice-border);
}

/* ── Per-opus default rubric editor ─────────────────── */
.rubric-default-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}
.rubric-default-table th,
.rubric-default-table td {
    padding: 4px 6px;
    text-align: left;
    border-bottom: 1px solid var(--alice-border);
}
.rubric-default-table th {
    font-weight: 600;
    color: var(--alice-text-secondary);
}
.rubric-default-table input[type="number"] {
    width: 50px;
    padding: 4px;
}
.rubric-default-table input[type="text"] {
    width: 100%;
    padding: 4px;
}

/* ── Item translation card ──────────────────────────── */
.item-lang-card {
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    padding: 12px;
    margin-bottom: 12px;
    background: var(--alice-bg);
}
.item-lang-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
    font-size: 12px;
}

.item-lang-card-slo {
    color: var(--alice-text-secondary);
}
.item-lang-default,
.item-lang-translated,
.item-lang-choices,
.item-lang-rubric {
    margin-bottom: 10px;
}
.default-prompt {
    font-size: 12px;
    color: var(--alice-text-secondary);
    background: var(--alice-bg);
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    padding: 6px 8px;
    white-space: pre-wrap;
    font-family: inherit;
    margin: 0;
}
.choices-trans-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.choices-trans-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.rubric-trans-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}
.rubric-trans-table th,
.rubric-trans-table td {
    padding: 4px 8px;
    text-align: left;
    border-bottom: 1px solid var(--alice-border);
}
.rubric-trans-table th {
    font-weight: 600;
    color: var(--alice-text-secondary);
}

/* ── Choices editor (radio/checkbox items) ──────────── */
.choices-editor {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.choices-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}


.choice-row .form-input {
    flex: 1;
}
.choices-row.hidden { display: none; }

/* ── Compact rubric display in translation lists ────── */



/* ── Pagina-empty paragraph ─────────────────────────── */
.pagina-empty {
    font-size: 12px;
    color: var(--alice-text-secondary);
    font-style: italic;
    margin: 4px 0 8px 0;
}

/* ── BONUM panel (SPECS29) ──────────────────────────── */




.bonum-add-file {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--alice-text);
}















/* ── Admin summary cards (used by bonum/usage.html) ─── */
.admin-summary-row {
    display: flex;
    gap: 16px;
    margin: 16px 0 24px 0;
    flex-wrap: wrap;
}
.admin-summary-card {
    flex: 1 1 160px;
    min-width: 140px;
    background: var(--alice-surface);
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    padding: 16px 20px;
}
.admin-summary-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--alice-text-secondary);
    margin-bottom: 6px;
}
.admin-summary-value {
    font-size: 22px;
    font-weight: 700;
    color: var(--alice-text);
}
.admin-help {
    color: var(--alice-text-secondary);
    font-size: 13px;
    max-width: 720px;
    margin: 8px 0 16px 0;
}

/* ── Warning / danger buttons (admin destructive ops) ──
   Styled to match .btn-secondary (light bordered button) with
   amber/red accents on text + border, instead of solid fills.
   This keeps the action row visually consistent with the
   neutral Manage button while still signalling severity. */


.btn-danger {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    font-size: 0.85rem;
    color: #c0392b;
    background-color: var(--alice-surface);
    border: 1px solid #c0392b;
    border-radius: 4px;
    cursor: pointer;
    text-align: center;
    text-decoration: none;
    font-family: inherit;
    transition: background-color .15s;
}
.btn-danger:hover {
    background-color: rgba(192, 57, 43, 0.08);
}
.btn-warn.btn-sm,
.btn-danger.btn-sm {
    padding: 0.25rem 0.65rem;
    font-size: 0.78rem;
}

/* ── Site footer (every page) ─────────────────────── */
.alice-footer {
    margin-top: 48px;
    padding: 16px 0;
    border-top: 1px solid var(--alice-border);
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
    font-size: 12px;
}
.alice-footer__inner {
    max-width: var(--content-max-width, 960px);
    margin: 0 auto;
    padding: 0 16px;
    text-align: center;
}

/* ── Admin opus list: visually separate destructive column ──
   Constructive actions (Manage) sit in their own narrow column;
   destructive actions (Archive, Delete) live in the rightmost
   column, marked with a thick left border and a faint warning
   tint so a careless cursor can't accidentally drift across the
   boundary. */
.opus-admin-table th.opus-destructive-col,
.opus-admin-table td.opus-destructive-col {
    border-left: 3px double #c0392b;
    background: rgba(192, 57, 43, 0.04);
    padding-left: 14px;
}
.opus-admin-table th.opus-destructive-col {
    color: #c0392b;
}

/* ── Opus delete modal (SPECS-admin destructive) ── */
.opus-delete-modal {
    position: fixed;
    inset: 0;
    z-index: 9000;
    display: flex;
    align-items: center;
    justify-content: center;
}
.opus-delete-modal.hidden {
    display: none;
}
.opus-delete-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
}
.opus-delete-modal__box {
    position: relative;
    background: var(--alice-surface);
    color: var(--alice-text);
    border: 2px solid var(--alice-warning, #c0392b);
    border-radius: 8px;
    padding: 24px 28px;
    max-width: 540px;
    width: calc(100% - 32px);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
    max-height: 90vh;
    overflow-y: auto;
}

/* ── Dense N×N matrix grids on /admin/opus/{id}/matrix ──
   Each matrix is wrapped in a bordered scroll container, with
   explicit visible gridlines so every cell is clearly delimited. */
.matrix-grid-wrap {
    overflow-x: auto;
    margin-bottom: 12px;
    border: 2px solid #888780;
    border-radius: 6px;
    background: var(--alice-surface);
    padding: 0;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.matrix-grid {
    border-collapse: collapse;
    font-size: 11px;
    font-family: var(--font-sans);
    border: 1px solid #888780;
}
.matrix-grid th,
.matrix-grid td {
    border: 1px solid #b8b8b0;
    padding: 3px 6px;
    text-align: center;
    min-width: 32px;
    height: 22px;
    white-space: nowrap;
}
.matrix-grid thead th,
.matrix-grid tbody th {
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
    font-weight: 600;
    border-color: #888780;
    position: sticky;
    z-index: 1;
}
.matrix-grid thead th { top: 0; }
.matrix-grid tbody th { left: 0; }
.matrix-corner {
    z-index: 2 !important;
    top: 0;
    left: 0;
}
.matrix-cell-set {
    background: var(--alice-blue-tint);
    color: var(--alice-blue);
    font-weight: 600;
}
.matrix-cell-diag {
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
}
.matrix-cell-inf {
    color: #a8a6a0;
    background: var(--alice-surface);
    font-style: italic;
}
.matrix-flat-details {
    margin: 0 0 24px 0;
}
.matrix-flat-details summary {
    cursor: pointer;
    color: var(--alice-text-secondary);
    font-size: 12px;
    padding: 4px 0;
    user-select: none;
}
.matrix-flat-details summary:hover {
    color: var(--alice-blue);
}
.matrix-flat-details[open] summary {
    margin-bottom: 8px;
}

/* ── Chorus membership dual-pane ──────────────────── */
.chorus-dual-pane {
    display: flex;
    gap: 0;
    margin-top: 16px;
    align-items: flex-start;
}
.chorus-pane {
    flex: 1 1 0;
    min-width: 0;
}
/* Available pane has 4 columns (Name, Email, Created, FERPA) vs.
   Members' 2 (Name, Email), so give it 1.3× the horizontal space. */
.chorus-pane--left {
    flex-grow: 1.3;
}
.chorus-pane h3 {
    margin: 0 0 8px 0;
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--alice-text-secondary);
}
.chorus-table-scroll {
    /* Fixed height so both panes (Available / Members) reserve the
       same vertical space regardless of row count. ≈10 rows of 34px
       (12px font + 9+9 padding + 1px border) plus the 31px header. */
    height: 380px;
    overflow-y: auto;
    border: 1px solid var(--alice-border);
    border-radius: 6px;
    background: var(--alice-surface);
}
.chorus-table-scroll .admin-table {
    margin: 0;
    font-size: 12px;
}
.chorus-actions-col {
    flex: 0 0 90px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 0 8px;
    min-height: 200px;
}
.chorus-action-btn {
    width: 80px;
    text-align: center;
}
.chorus-sortable {
    cursor: pointer;
    user-select: none;
}
.chorus-sortable:hover {
    color: var(--alice-blue);
}
@media (max-width: 768px) {
    .chorus-dual-pane { flex-direction: column; }
    .chorus-actions-col {
        flex-direction: row;
        min-height: auto;
        padding: 8px 0;
    }
}

/* ── Grading summary (assessor, Received tab) ────── */
.grading-summary {
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--alice-border);
}
.grading-summary-table {
    width: auto;
    min-width: 320px;
    font-size: 13px;
}
.grading-badge {
    display: inline-block;
    min-width: 22px;
    text-align: center;
    padding: 1px 6px;
    border-radius: 10px;
    font-weight: 700;
    font-size: 12px;
}
.grading-badge--ungraded {
    background: var(--alice-amber);
    color: #1a1a1a;
}
.grading-badge--zero {
    color: var(--alice-text-secondary);
}
.grading-filter-note {
    font-size: 12px;
    color: var(--alice-text-secondary);
    margin: 8px 0 0 0;
    font-style: italic;
}

/* ── Global in-app confirm modal ──────────────────── */
.alice-confirm {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
}
.alice-confirm.hidden { display: none; }
.alice-confirm__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
}
.alice-confirm__box {
    position: relative;
    background: var(--alice-surface);
    color: var(--alice-text);
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    padding: 24px 28px;
    max-width: 420px;
    width: calc(100% - 32px);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.alice-confirm__box p {
    margin: 0 0 16px 0;
    font-size: 14px;
    line-height: 1.5;
}
.alice-confirm__actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* ── Orchestration clipboard modal (COPY/PASTE substrate) ── */
.alice-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    padding: 24px;
}
.alice-modal {
    position: relative;
    background: var(--alice-surface);
    color: var(--alice-text);
    border: 1px solid var(--alice-border);
    border-radius: 8px;
    max-width: 800px;
    width: 100%;
    max-height: 80vh;
    overflow: hidden;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
    display: flex;
    flex-direction: column;
}
.alice-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px;
    border-bottom: 1px solid var(--alice-border);
}
.alice-modal__header h2 {
    margin: 0;
    font-size: 18px;
}
.alice-modal__close {
    background: transparent;
    border: 0;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    color: var(--alice-text);
    padding: 0 8px;
}
.alice-modal__body {
    padding: 16px 24px;
    overflow: auto;
}
.alice-modal__preview {
    border-top: 1px solid var(--alice-border);
    padding-top: 1em;
}

/* ── Assessor dashboard (Home page) ───────────────── */


.assessor-dashboard .admin-table {
    margin: 0;
    font-size: 13px;
}

/* ── Chorus selector (title-level dropdown) ──────── */
.title-chorus-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.title-chorus-row h1 {
    margin: 0;
}
.chorus-selector-form {
    flex-shrink: 0;
    margin: 0;
}

/* "Export LaTeX" button on the opus header. Visible only to
   nautae with PRODUCE_DOCUMENTS munus (template-gated). Quiet
   default state so it doesn't crowd the title; brightens on
   hover. The action downloads a ZIP — Content-Disposition is
   set by the server. */
.opus-export-latex-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background: var(--alice-surface);
    color: var(--alice-text);
    font-size: 0.78rem;
    font-weight: 500;
    text-decoration: none;
    flex-shrink: 0;
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s;
}
.opus-export-latex-btn:hover {
    background: var(--alice-bg-hover, rgba(0,0,0,0.04));
    border-color: var(--alice-blue, #2563eb);
    color: var(--alice-blue, #2563eb);
}
.chorus-selector-select {
    font-size: 12px;
    padding: 4px 8px;
    border: 1px solid var(--alice-border);
    border-radius: 4px;
    background: var(--alice-surface);
    color: var(--alice-text);
    cursor: pointer;
    font-family: inherit;
}
.chorus-selector-badge {
    font-size: 12px;
    padding: 3px 10px;
    border: 1px solid var(--alice-border);
    border-radius: 10px;
    background: var(--alice-bg);
    color: var(--alice-text-secondary);
    white-space: nowrap;
}
.chorus-role-line {
    font-size: 11px;
    color: var(--alice-text-secondary);
    margin-top: 4px;
    line-height: 1.4;
}
.chorus-role-line strong {
    color: var(--alice-text);
    font-weight: 600;
}
