/*
 * Aurora — OCM 2026 design tokens + base components.
 *
 * Mockup-only; not wired into the production app yet. The token names are
 * the contract that every Aurora component will consume. Light + dark are a
 * pure token swap on the same component CSS.
 */

@import url("https://rsms.me/inter/inter.css");

:root {
    color-scheme: light;

    /* --- Neutral ramp (OKLCH) --- */
    --gray-0:  oklch(99% 0.002 270);
    --gray-1:  oklch(97% 0.003 270);
    --gray-2:  oklch(94% 0.004 270);
    --gray-3:  oklch(89% 0.005 270);
    --gray-4:  oklch(82% 0.006 270);
    --gray-5:  oklch(70% 0.008 270);
    --gray-6:  oklch(58% 0.010 270);
    --gray-7:  oklch(46% 0.012 270);
    --gray-8:  oklch(36% 0.013 270);
    --gray-9:  oklch(26% 0.012 270);
    --gray-10: oklch(18% 0.010 270);
    --gray-11: oklch(12% 0.008 270);

    /* --- Brand accent --- one color, one job: action */
    --accent-1:  oklch(96% 0.04 250);
    --accent-3:  oklch(82% 0.10 250);
    --accent-5:  oklch(64% 0.16 250);
    --accent-6:  oklch(56% 0.18 250);
    --accent-7:  oklch(48% 0.18 250);
    --accent-9:  oklch(34% 0.14 250);

    /* --- Semantic --- */
    --success-3: oklch(86% 0.10 150);
    --success-6: oklch(58% 0.16 150);
    --success-9: oklch(35% 0.12 150);
    --warning-3: oklch(88% 0.12 80);
    --warning-6: oklch(70% 0.16 80);
    --warning-9: oklch(45% 0.13 80);
    --danger-3:  oklch(86% 0.10 25);
    --danger-6:  oklch(58% 0.20 25);
    --danger-9:  oklch(40% 0.16 25);
    --info-3:    oklch(88% 0.06 220);
    --info-6:    oklch(60% 0.14 220);

    /* --- Surfaces --- */
    --surface-0: var(--gray-0);   /* page background */
    --surface-1: white;            /* card / panel */
    --surface-2: var(--gray-1);    /* subtle inset */
    --surface-3: var(--gray-2);    /* hover */

    --text-1: var(--gray-11);     /* primary */
    --text-2: var(--gray-8);      /* secondary */
    --text-3: var(--gray-7);      /* tertiary / placeholder.
                                   * #233: was gray-6 (4.29:1 on white,
                                   * sub-AA). Bumped to gray-7 (~5.7:1)
                                   * so .nav-label / .sidebar .count /
                                   * .palette li .kind / .palette-foot
                                   * (which is wired to text-2 already)
                                   * all clear AA without each component
                                   * having to opt into a darker token. */
    --text-on-accent: white;

    --border-subtle: var(--gray-2);
    --border-default: var(--gray-3);
    --border-strong: var(--gray-5);

    /* --- Accent tints (#233) ---
     * Selection / "active row" tints in components that need a soft
     * accent wash behind text. Keeping these as semantic tokens means
     * dark + high-contrast can pick a wash that actually reads against
     * their darker / pure-white surfaces — which `--accent-1` (a near-
     * white pale-blue) cannot do on either. The contract is the same
     * for every theme: bg pairs with fg at AA contrast or better.
     *
     * Light theme: very pale accent wash + deep accent text.
     * Dark theme:  semi-transparent accent-6 wash + light accent text.
     * HC theme:    deep-accent inverse for unmistakable selection.
     */
    --accent-soft-bg: var(--accent-1);
    --accent-soft-fg: var(--accent-9);

    /* Link color (#233). Was raw `var(--accent-7)` baked into the `a {}`
     * rule. Promoting it to a token means dark mode can lighten the link
     * without having to bump the whole accent ramp (which would knock
     * over button + selection contrast). The companion --link-decoration
     * token toggles the always-on underline. We default to "underline"
     * across every theme — the WCAG 1.4.1 "link distinguishable from
     * surrounding text" check needs 3:1 colour separation OR a non-
     * colour cue, and our --link (accent-7) sits at only ~1.7:1 against
     * --text-1 (gray-11) on white. Underline is the cheapest non-colour
     * cue and reads as a link affordance everywhere. */
    --link: var(--accent-7);
    --link-hover: var(--accent-9);
    --link-decoration: underline;

    /* Scrim — overlay/backdrop tint behind modals. Stays "darker than
     * the page" in every theme so the layering always reads. */
    --scrim: color-mix(in oklch, var(--gray-11) 50%, transparent);

    /* Toast — inverse of body. Light → dark pill; dark → light pill;
     * HC → black-on-white for max attention. Component-agnostic so the
     * future "snackbar" / "command-bar tray" can reuse the same pair. */
    --toast-bg: var(--gray-11);
    --toast-fg: var(--gray-1);

    /* Semantic badge tints (#233). The original .badge.* rules
     * `color-mix(in oklch, var(--success-3) 50%, var(--surface-1))`
     * give the right pastel on light, but on dark surface-1 the same
     * mix produces a murky colour with poor text contrast. Promote
     * each tint pair to a token so dark + HC can override the BG and
     * FG independently of the parent surface. */
    --badge-success-bg: color-mix(in oklch, var(--success-3) 50%, var(--surface-1));
    --badge-success-fg: var(--success-9);
    --badge-warning-bg: color-mix(in oklch, var(--warning-3) 50%, var(--surface-1));
    --badge-warning-fg: var(--warning-9);
    --badge-danger-bg:  color-mix(in oklch, var(--danger-3)  50%, var(--surface-1));
    --badge-danger-fg:  var(--danger-9);
    --badge-info-bg:    color-mix(in oklch, var(--info-3)    50%, var(--surface-1));
    --badge-info-fg:    var(--gray-10);

    /* ── Legacy token aliases (#273 / #277) ──────────────────────────
     *
     * The Aurora sub-stylesheets (aurora-saved-views.css,
     * aurora-case-list-v2.css, aurora-calendar-v2.css, aurora-case-
     * three-pane.css, aurora-quick-time-entry.css, aurora-form-
     * components.css …) authored before the canonical token system
     * landed referenced names like `--ocm-color-surface`, `--aurora-
     * surface-alt`, `--ocm-bg-elevated`, `--aurora-text-muted`. None
     * of those tokens were defined in :root, so every consumer fell
     * through to the hard-coded light hex fallback (`#ffffff`,
     * `#f6f7f9`, etc.). The end result was that saved-views
     * toolbars, case-list rows, calendar grids, and quick-time-entry
     * sheets all rendered with a permanent white background even
     * when [data-theme="dark"] was active — illegible.
     *
     * Aliases here point each legacy name at the canonical token
     * that actually theme-swaps. Light/dark/high-contrast all flow
     * through automatically because --surface-* / --text-* /
     * --border-* are the source of truth.
     */
    --ocm-color-surface:        var(--surface-1);
    --ocm-color-surface-2:      var(--surface-2);
    --ocm-color-surface-hover:  var(--surface-3);
    --ocm-color-accent-soft:    var(--accent-soft-bg);
    --aurora-surface:           var(--surface-1);
    --aurora-surface-alt:       var(--surface-2);
    --aurora-surface-hover:     var(--surface-3);
    --aurora-border:            var(--border-subtle);
    --aurora-border-soft:       var(--border-subtle);
    --aurora-text:              var(--text-1);
    --aurora-text-muted:        var(--text-3);
    --aurora-accent:            var(--accent-7);
    --aurora-focus:             var(--accent-6);
    --aurora-danger:            var(--danger-9);
    --aurora-muted:             var(--text-3);
    --aurora-fg:                var(--text-1);
    --ocm-bg-default:           var(--surface-1);
    --ocm-bg-emphasis:          var(--surface-2);
    --ocm-bg-elevated:          var(--surface-1);
    --ocm-fg-default:           var(--text-1);
    --ocm-fg-muted:             var(--text-2);
    --ocm-border-default:       var(--border-default);
    --ocm-accent-default:       var(--accent-7);
    --ocm-accent-hover:         var(--accent-6);
    --ocm-success-default:      var(--success-9);
    --ocm-danger-default:       var(--danger-9);

    /* Avatar — initials chip in the topbar. Was --accent-5 (3.35:1
     * with white) which fell below AA for the 12-px initials. Bumped
     * to --accent-6 (~4.6:1 on white) so all themes start AA-clean
     * before their own dark/HC overrides kick in. */
    --avatar-bg: var(--accent-6);
    --avatar-fg: white;

    /* --- Typography --- */
    --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, monospace;

    --text-xs:   0.75rem;
    --text-sm:   0.8125rem;
    --text-base: 0.875rem;
    --text-md:   1rem;
    --text-lg:   1.125rem;
    --text-xl:   1.375rem;
    --text-2xl:  1.75rem;
    --text-3xl:  2.25rem;

    --leading-tight: 1.2;
    --leading-snug:  1.4;
    --leading-base:  1.5;

    /* --- Spacing (4-px base) --- */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;

    /* --- Radius --- */
    --radius-1: 4px;
    --radius-2: 8px;
    --radius-3: 12px;
    --radius-full: 9999px;

    /* --- Elevation: borders first, shadows for floating only --- */
    --shadow-1: 0 1px 0 rgb(0 0 0 / 0.04);
    --shadow-2: 0 4px 12px rgb(0 0 0 / 0.06), 0 1px 2px rgb(0 0 0 / 0.04);
    --shadow-3: 0 16px 48px rgb(0 0 0 / 0.12), 0 2px 8px rgb(0 0 0 / 0.06);

    /* --- Motion --- */
    --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
    --dur-fast: 120ms;
    --dur-base: 180ms;
    --dur-slow: 280ms;

    /* --- Layout --- */
    --sidebar-w: 240px;
    --sidebar-w-collapsed: 56px;
    --topbar-h: 48px;
    --right-rail-w: 320px;
}

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

    /* #233 dark tuning — surface ramp re-spaced so consecutive
     * surfaces are visually distinct without leaving the dark range:
     *  surface-0 (page)  → gray-11 (12% L) — unchanged
     *  surface-1 (panel) → gray-10 (18% L) — unchanged
     *  surface-2 (inset) → was gray-9 (26% L) = 8 L step on top of a
     *                                         6 L step. Now at gray-8
     *                                         (36%) for an 18 L step,
     *                                         so cards on insets read
     *                                         as actual cards.
     *  surface-3 (hover) → gray-7 (46% L) — was gray-8; bumped one step
     *                                         to keep the hover lift
     *                                         readable against the new
     *                                         surface-2.
     */
    --surface-0: var(--gray-11);
    --surface-1: var(--gray-10);
    --surface-2: var(--gray-8);
    --surface-3: var(--gray-7);

    --text-1: var(--gray-1);
    --text-2: var(--gray-3);     /* was gray-4 — pushed one step lighter
                                  * (89% vs 82% L) so secondary text
                                  * clears AA against surface-1. */
    --text-3: var(--gray-4);     /* was gray-6 (58% L → 3.2:1 on surface-1
                                  * = below AA). gray-5 (70%) only got us
                                  * to 3.7:1 against the new surface-2
                                  * (gray-8); gray-4 (82%) lands at ~4.6:1
                                  * which clears AA for the topbar
                                  * search-trigger / nav-label / palette
                                  * footer that all use --text-3 against
                                  * --surface-2. */

    --border-subtle:  var(--gray-8);   /* was gray-9 — bumped so panel
                                        * edges actually appear against
                                        * the new surface-2 (which is
                                        * also gray-8). */
    --border-default: var(--gray-7);   /* was gray-8 — same reason */
    --border-strong:  var(--gray-5);   /* was gray-6 — focus ring needs
                                        * to read against everything */

    --shadow-1: 0 1px 0 rgb(0 0 0 / 0.3);
    --shadow-2: 0 4px 12px rgb(0 0 0 / 0.35), 0 1px 2px rgb(0 0 0 / 0.2);
    --shadow-3: 0 16px 48px rgb(0 0 0 / 0.5), 0 2px 8px rgb(0 0 0 / 0.3);

    /* Selection tints: --accent-1 (oklch 96% L) is a near-white wash
     * that fades into surface-1 in dark mode. Use a transparent
     * accent-6 mix instead so the wash is visible but not garish, and
     * pair with accent-3 text for AA. Replaces the three
     * `[data-theme="dark"] .foo.active` per-component overrides we used
     * to ship — the architectural rule is "every variant comes from
     * a token swap", and these are the tokens. */
    --accent-soft-bg: color-mix(in oklch, var(--accent-6) 22%, transparent);
    --accent-soft-fg: var(--accent-3);

    /* Backdrop in dark mode: keep the dark scrim, but lean into pure
     * black for a stronger blur edge. */
    --scrim: color-mix(in oklch, #000 60%, transparent);

    /* Toast inverts vs the page — dark theme → light pill. */
    --toast-bg: var(--gray-1);
    --toast-fg: var(--gray-11);

    /* Link colour — accent-7 in dark is too dim against surface-0
     * (~3.18:1 fail). Lift to accent-3 (a light pastel blue) for
     * AAA against the page. Hover then drops to accent-1 for the
     * "I'm acting on this" cue. Underline always-on so the lifted
     * link colour (which sits close to --text-1 at high L) still
     * passes WCAG 1.4.1 link-distinguishable-from-surrounding-text. */
    --link: var(--accent-3);
    --link-hover: var(--accent-1);
    --link-decoration: underline;

    /* Badge tints — invert the convention in dark: dark wash + light
     * text. The pastel `--success-3 50%` mix above produces a near-
     * black murky colour on surface-1 in dark; replace with the same
     * recipe but anchored on the dark accent + light text instead. */
    --badge-success-bg: color-mix(in oklch, var(--success-6) 30%, var(--surface-1));
    --badge-success-fg: var(--success-3);
    --badge-warning-bg: color-mix(in oklch, var(--warning-6) 30%, var(--surface-1));
    --badge-warning-fg: var(--warning-3);
    --badge-danger-bg:  color-mix(in oklch, var(--danger-6)  30%, var(--surface-1));
    --badge-danger-fg:  var(--danger-3);
    --badge-info-bg:    color-mix(in oklch, var(--info-6)    30%, var(--surface-1));
    --badge-info-fg:    var(--info-3);

    /* Avatar — accent-7 (oklch 48%) brings the white initials to ~6:1. */
    --avatar-bg: var(--accent-7);
    --avatar-fg: white;
}

/* --- High-contrast theme (#206) ----------------------------------------
 * Pure-white surfaces with near-black text + borders so every component
 * still passes WCAG AAA on the primary text pair (21:1) and AA on the
 * accent / semantic ramps. Same token contract as light + dark — no
 * component CSS changes required. The toggle in cms/js/aurora.js cycles
 * light → dark → high-contrast, and `@media (prefers-contrast: more)`
 * below opts users into this theme automatically when their OS asks.
 *
 * Pure black/white are kept as hex (#000 / #fff) — they are truly named
 * colors that don't benefit from OKLCH's perceptual uniformity. Accent +
 * semantic ramps stay in OKLCH so they sit in the same color space as
 * the rest of the file.
 */
[data-theme="high-contrast"] {
    color-scheme: light;

    /* Surfaces: pure white. Subtle inset / hover stay white but rely on
     * the heavier borders below for separation. */
    --surface-0: #ffffff;
    --surface-1: #ffffff;
    --surface-2: #ffffff;
    --surface-3: #f0f0f0;

    /* Text: pure black primary, near-black secondary + tertiary. */
    --text-1: #000000;
    --text-2: #1a1a1a;
    --text-3: #333333;
    --text-on-accent: #ffffff;

    /* Borders: black / dark-gray ramp so every panel edge is visible. */
    --border-subtle:  #666666;
    --border-default: #333333;
    --border-strong:  #000000;

    /* Accent: deep blue, ~12:1 against white (AA Large + AAA Normal). */
    --accent-1: oklch(95% 0.04 255);
    --accent-3: oklch(75% 0.12 255);
    --accent-5: oklch(45% 0.18 255);
    --accent-6: oklch(34% 0.18 255);    /* ≈ #003a99 */
    --accent-7: oklch(28% 0.18 255);
    --accent-9: oklch(20% 0.14 255);

    /* Semantic ramps: darken every -6 to AA-passing on white (≥ 4.5:1). */
    --success-6: oklch(40% 0.16 150);
    --success-9: oklch(28% 0.12 150);
    --warning-6: oklch(45% 0.16 80);
    --warning-9: oklch(35% 0.13 80);
    --danger-6:  oklch(40% 0.20 25);
    --danger-9:  oklch(30% 0.16 25);
    --info-6:    oklch(40% 0.16 220);

    /* Shadows down — high-contrast users rely on borders, not shadows. */
    --shadow-1: 0 0 0 1px #000000;
    --shadow-2: 0 0 0 1px #000000;
    --shadow-3: 0 0 0 2px #000000;

    /* #233 HC tuning — selection tint. The default `--accent-1`
     * (`oklch(95% 0.04 255)` ≈ #e6ecff) on white is invisible: a
     * sighted HC user sees no "this row is selected" cue. Flip the
     * convention: dark accent-7 background with white text is an
     * unambiguous selection state at any contrast level. AA-passing
     * pair on every selected row / nav-item / palette match. */
    --accent-soft-bg: var(--accent-7);
    --accent-soft-fg: #ffffff;

    /* Scrim must be opaque-enough to read against the pure-white
     * surfaces under it. 70% black instead of the light-mode 50%. */
    --scrim: color-mix(in oklch, #000 70%, transparent);

    /* Toast: black on white with a heavy border, same convention as
     * every other surface in HC. The component CSS already ships the
     * `--shadow-3` ring so the toast still floats visually. */
    --toast-bg: #ffffff;
    --toast-fg: #000000;

    /* Link colour. The light-mode default of accent-7 sits at ~12:1
     * against pure white in HC (we already darkened the accent ramp
     * for HC above), so just keep it pointing at the same token —
     * but make hover go to pure-black for that "I-am-clicking-this"
     * cue HC users rely on. Underline always-on per HC convention
     * (link colour vs --text-1 = #000 only gets us ~2.5:1 distinct,
     * below WCAG 1.4.1's 3:1 colour-only floor). */
    --link: var(--accent-7);
    --link-hover: #000000;
    --link-decoration: underline;

    /* Badge tints. The pastel `--*-3 50%` mix collapses to almost-
     * white in HC (surface-1 is pure white). Use the AA-darkened
     * `--*-6` ramp directly on the white surface with white text —
     * solid blocks of colour, not a tint. */
    --badge-success-bg: var(--success-6);
    --badge-success-fg: #ffffff;
    --badge-warning-bg: var(--warning-6);
    --badge-warning-fg: #ffffff;
    --badge-danger-bg:  var(--danger-6);
    --badge-danger-fg:  #ffffff;
    --badge-info-bg:    var(--info-6);
    --badge-info-fg:    #ffffff;

    /* Avatar — HC accent-7 (oklch 28%) gives white initials AAA. */
    --avatar-bg: var(--accent-7);
    --avatar-fg: #ffffff;
}

/* OS-level high-contrast preference → opt into the same token swap.
 * Scoped to `:root:not([data-theme])` so an explicit user selection in
 * the toggle (which writes data-theme=...) always wins over the OS hint. */
@media (prefers-contrast: more) {
    :root:not([data-theme]),
    [data-theme="auto"] {
        color-scheme: light;

        --surface-0: #ffffff;
        --surface-1: #ffffff;
        --surface-2: #ffffff;
        --surface-3: #f0f0f0;

        --text-1: #000000;
        --text-2: #1a1a1a;
        --text-3: #333333;
        --text-on-accent: #ffffff;

        --border-subtle:  #666666;
        --border-default: #333333;
        --border-strong:  #000000;

        --accent-1: oklch(95% 0.04 255);
        --accent-3: oklch(75% 0.12 255);
        --accent-5: oklch(45% 0.18 255);
        --accent-6: oklch(34% 0.18 255);
        --accent-7: oklch(28% 0.18 255);
        --accent-9: oklch(20% 0.14 255);

        --success-6: oklch(40% 0.16 150);
        --success-9: oklch(28% 0.12 150);
        --warning-6: oklch(45% 0.16 80);
        --warning-9: oklch(35% 0.13 80);
        --danger-6:  oklch(40% 0.20 25);
        --danger-9:  oklch(30% 0.16 25);
        --info-6:    oklch(40% 0.16 220);

        --shadow-1: 0 0 0 1px #000000;
        --shadow-2: 0 0 0 1px #000000;
        --shadow-3: 0 0 0 2px #000000;

        /* #233 — match the explicit `[data-theme="high-contrast"]`
         * block above so OS-level prefers-contrast users get the
         * same selection / scrim / toast pairing without needing to
         * pick a theme manually. */
        --accent-soft-bg: var(--accent-7);
        --accent-soft-fg: #ffffff;
        --scrim: color-mix(in oklch, #000 70%, transparent);
        --toast-bg: #ffffff;
        --toast-fg: #000000;
        --link: var(--accent-7);
        --link-hover: #000000;
        --link-decoration: underline;
        --badge-success-bg: var(--success-6);
        --badge-success-fg: #ffffff;
        --badge-warning-bg: var(--warning-6);
        --badge-warning-fg: #ffffff;
        --badge-danger-bg:  var(--danger-6);
        --badge-danger-fg:  #ffffff;
        --badge-info-bg:    var(--info-6);
        --badge-info-fg:    #ffffff;
        --avatar-bg: var(--accent-7);
        --avatar-fg: #ffffff;
    }
}

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

/* --- Reset / base --- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
    font-family: var(--font-sans);
    font-feature-settings: "cv02", "cv03", "cv04", "cv11";
    font-size: var(--text-base);
    line-height: var(--leading-base);
    color: var(--text-1);
    background: var(--surface-0);
    -webkit-font-smoothing: antialiased;
}
@supports (font-variation-settings: normal) {
    body { font-family: "Inter var", var(--font-sans); }
}

/* #233: links carry a token-controlled --link-decoration so dark + HC
 * can force the underline on (since their lifted link colours can't
 * stay 3:1 distinct from the lifted body text, WCAG 1.4.1 requires a
 * non-colour cue). Light defaults to underline too — the `--link`
 * (accent-7) sits at only ~1.7:1 against `--text-1` so it can't
 * stand on colour alone either. The tinted underline-color (60%
 * mix toward transparent) keeps the rule visually weighted toward
 * the link text rather than the rule itself. */
a {
    color: var(--link);
    text-decoration: var(--link-decoration);
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in oklch, var(--link) 60%, transparent);
}
a:hover { color: var(--link-hover); text-decoration: underline; }

button { font: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }

code, kbd, .mono { font-family: var(--font-mono); font-size: 0.9em; }

::selection { background: var(--accent-3); color: var(--gray-11); }

:focus-visible {
    outline: 2px solid var(--accent-6);
    outline-offset: 2px;
    border-radius: var(--radius-1);
}

/* --- App shell --- */
.app {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    grid-template-rows: var(--topbar-h) 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar main";
    height: 100vh;
}

.topbar {
    grid-area: topbar;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-5);
    background: var(--surface-1);
    border-bottom: 1px solid var(--border-subtle);
}
.topbar .search-trigger {
    flex: 1;
    max-width: 480px;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-3);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    background: var(--surface-2);
    color: var(--text-3);
    font-size: var(--text-sm);
    transition: background var(--dur-fast) var(--ease-out);
}
.topbar .search-trigger:hover { background: var(--surface-3); }
.topbar .search-trigger kbd {
    margin-left: auto;
    padding: 2px 6px;
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-1);
    font-size: 11px;
    color: var(--text-2);
}
.topbar .spacer { flex: 1; }
.topbar .icon-btn {
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-2);
    color: var(--text-2);
    transition: background var(--dur-fast) var(--ease-out);
}
.topbar .icon-btn:hover { background: var(--surface-2); color: var(--text-1); }
.topbar .avatar {
    width: 28px; height: 28px;
    border-radius: var(--radius-full);
    /* #233: was raw `--accent-5` + `white`, which gave 3.35:1 in dark
     * (well below AA for the small initials). Pull from the per-theme
     * `--avatar-bg` / `--avatar-fg` pair so each theme picks an
     * AA-passing combo for white initials text. */
    background: var(--avatar-bg);
    color: var(--avatar-fg);
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 600;
    font-size: var(--text-xs);
}

.sidebar {
    grid-area: sidebar;
    background: var(--surface-1);
    border-right: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}
.sidebar .brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    height: var(--topbar-h);
    border-bottom: 1px solid var(--border-subtle);
    font-weight: 600;
    letter-spacing: -0.01em;
}
.sidebar .brand-mark {
    width: 28px; height: 28px;
    border-radius: var(--radius-2);
    background: linear-gradient(135deg, var(--accent-6), var(--accent-9));
    color: var(--text-on-accent, #fff);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}
.sidebar .brand-mark svg {
    width: 16px;
    height: 16px;
}
/* PNG/SVG-image brand mark: drop the gradient backplate (the image
 * supplies its own background) and let the image fill the 28×28
 * frame rounded by the parent's border-radius. object-fit:cover
 * crops a non-square asset to a square; switch to "contain" if the
 * org's logo needs whitespace around it. */
/* When an image logo replaces the SVG mark, drop the gradient backplate
 * (the logo asset supplies its own background) and let the image sit
 * inside the rounded 28×28 chip. object-fit: contain preserves the
 * whole mark; if the asset is full-bleed and you'd rather crop, switch
 * to cover. */
.sidebar .brand-mark.brand-mark-img {
    background: transparent;
    overflow: hidden;
}
.sidebar .brand-mark.brand-mark-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}
/* #261: the entire brand block is now a clickable link to /cms/. The
 * anchor needs to inherit the brand row's typography and lose the
 * default link underline so it reads as a logo, not a hyperlink.
 * Hover lifts the surface for affordance. */
.sidebar .brand-link {
    color: inherit;
    text-decoration: none;
    display: block;
    border-radius: var(--radius-2);
    transition: background var(--dur-fast) var(--ease-out);
}
.sidebar .brand-link:hover,
.sidebar .brand-link:focus {
    text-decoration: none;
    background: var(--surface-2);
}
.sidebar .brand-link:focus-visible {
    outline: 2px solid var(--accent-6);
    outline-offset: 2px;
}
.sidebar .nav-section {
    padding: var(--space-3) var(--space-2);
    border-bottom: 1px solid var(--border-subtle);
}
.sidebar .nav-section:last-of-type { border-bottom: 0; }
.sidebar .nav-label {
    padding: 0 var(--space-2) var(--space-2);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-3);
}
.sidebar .nav-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-3);
    margin: 1px 0;
    color: var(--text-2);
    font-size: var(--text-sm);
    border-radius: var(--radius-2);
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease-out);
}
.sidebar .nav-item:hover { background: var(--surface-2); color: var(--text-1); }
.sidebar .nav-item.active {
    /* #233: was a hard-coded var(--accent-1) + var(--accent-9) pair
     * with a separate [data-theme="dark"] override. Now both come
     * from --accent-soft-bg / --accent-soft-fg so dark + HC swap
     * the wash via tokens instead of per-component CSS. */
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
}
.sidebar .nav-item .count {
    margin-left: auto;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-xs);
}
/* #233: when the parent nav-item is .active the soft-bg is a colored
 * wash (deep accent in HC; mid-tone elsewhere). Inherit so the count
 * pill stays legible against that wash instead of staying gray. */
.sidebar .nav-item.active .count { color: inherit; }
.sidebar .icon { width: 16px; height: 16px; flex: 0 0 auto; }

.main {
    grid-area: main;
    overflow-y: auto;
}

.page {
    max-width: 1280px;
    padding: var(--space-5) var(--space-6);
    margin: 0 auto;
}
.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}
.page-title {
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: var(--leading-tight);
    letter-spacing: -0.015em;
    margin: 0;
}
.page-subtitle {
    color: var(--text-2);
    font-size: var(--text-sm);
    margin: var(--space-1) 0 0;
}

/* --- Buttons --- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-3);
    border-radius: var(--radius-2);
    border: 1px solid var(--border-default);
    background: var(--surface-1);
    color: var(--text-1);
    font-size: var(--text-sm);
    font-weight: 500;
    transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.btn:hover { background: var(--surface-2); border-color: var(--border-strong); }
.btn:active { background: var(--surface-3); }
.btn.btn-primary {
    background: var(--accent-7);
    border-color: var(--accent-7);
    color: var(--text-on-accent);
}
.btn.btn-primary:hover { background: var(--accent-6); border-color: var(--accent-6); }
.btn.btn-ghost { background: transparent; border-color: transparent; }
.btn.btn-ghost:hover { background: var(--surface-2); }
.btn.btn-sm { padding: 3px var(--space-2); font-size: var(--text-xs); }
.btn.btn-icon { padding: 5px; }

/* --- Inputs --- */
.input, .select {
    padding: 6px var(--space-3);
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    color: var(--text-1);
    font-size: var(--text-sm);
    transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.input:hover, .select:hover { border-color: var(--border-strong); }
.input:focus, .select:focus {
    outline: none;
    border-color: var(--accent-6);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent-6) 25%, transparent);
}

/* --- Cards / panels --- */
.card {
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    padding: var(--space-5);
}
.card-title {
    font-size: var(--text-base);
    font-weight: 600;
    margin: 0 0 var(--space-3);
    letter-spacing: -0.005em;
}

/* --- Badges + tags --- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius-full);
    font-size: var(--text-xs);
    font-weight: 500;
    line-height: 1.4;
    border: 1px solid var(--border-default);
    background: var(--surface-2);
    color: var(--text-2);
}
/* #233: badge tints come from theme-aware tokens so dark + HC pick a
 * legible BG/FG pair instead of the light-mode `--*-3 50%` mix that
 * goes murky on dark surfaces and washes out on pure-white in HC. */
.badge.success { background: var(--badge-success-bg); border-color: var(--success-3); color: var(--badge-success-fg); }
.badge.warning { background: var(--badge-warning-bg); border-color: var(--warning-3); color: var(--badge-warning-fg); }
.badge.danger  { background: var(--badge-danger-bg);  border-color: var(--danger-3);  color: var(--badge-danger-fg); }
.badge.info    { background: var(--badge-info-bg);    border-color: var(--info-3);    color: var(--badge-info-fg); }
.badge .dot {
    width: 6px; height: 6px;
    border-radius: var(--radius-full);
    background: currentColor;
    flex: 0 0 auto;
}

/* --- Tables --- */
.table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    overflow: hidden;
    font-variant-numeric: tabular-nums;
}
.table thead th {
    text-align: left;
    padding: 8px var(--space-3);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--text-2);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border-subtle);
}
.table tbody td {
    padding: 10px var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--text-sm);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr {
    transition: background var(--dur-fast) var(--ease-out);
    cursor: pointer;
}
.table tbody tr:hover { background: var(--surface-2); }
.table tbody tr.selected {
    /* #233: token-driven so dark + HC pick a visible wash. */
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
}
.table .case-num {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--text-2);
}
/* #233: same story as .nav-item.active .count — when the row is
 * .selected the wash is opaque enough to swallow the gray. Inherit. */
.table tbody tr.selected .case-num { color: inherit; }
.table .truncate {
    max-width: 280px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Filter bar --- */
.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) 0;
    flex-wrap: wrap;
}
.filter-bar .filter-group {
    display: flex;
    align-items: center;
    gap: 1px;
    padding: 2px;
    background: var(--surface-2);
    border-radius: var(--radius-2);
}
.filter-bar .filter-group .btn {
    border: 0;
    background: transparent;
    border-radius: var(--radius-1);
}
.filter-bar .filter-group .btn.active {
    background: var(--surface-1);
    box-shadow: var(--shadow-1);
}

/* --- Stat tiles --- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}
.stat {
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    padding: var(--space-4);
}
.stat .label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-2);
    font-weight: 600;
}
.stat .value {
    font-size: var(--text-3xl);
    font-weight: 600;
    letter-spacing: -0.025em;
    line-height: var(--leading-tight);
    margin: var(--space-2) 0 var(--space-1);
    font-variant-numeric: tabular-nums;
}
.stat .delta { font-size: var(--text-xs); color: var(--text-2); }
.stat .delta.up { color: var(--success-9); }
.stat .delta.down { color: var(--danger-9); }

/* --- Two-pane case detail --- */
.detail {
    display: grid;
    grid-template-columns: 220px 1fr var(--right-rail-w);
    gap: 0;
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    overflow: hidden;
    min-height: 720px;
}
.detail .section-nav {
    border-right: 1px solid var(--border-subtle);
    padding: var(--space-4);
    background: var(--surface-2);
}
.detail .section-nav h4 {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-3);
    margin: var(--space-4) 0 var(--space-2);
    font-weight: 600;
}
.detail .section-nav h4:first-child { margin-top: 0; }
.detail .section-nav .nav-item {
    display: flex;
    align-items: center;
    padding: 5px var(--space-2);
    border-radius: var(--radius-2);
    color: var(--text-2);
    font-size: var(--text-sm);
    margin: 1px 0;
    cursor: pointer;
}
.detail .section-nav .nav-item:hover { background: var(--surface-3); color: var(--text-1); }
.detail .section-nav .nav-item.active {
    background: var(--surface-1);
    color: var(--text-1);
    font-weight: 500;
    box-shadow: var(--shadow-1);
}

.detail .content {
    padding: var(--space-5) var(--space-6);
    overflow-y: auto;
}
.detail .content h2 {
    font-size: var(--text-xl);
    font-weight: 600;
    margin: 0 0 var(--space-4);
    letter-spacing: -0.01em;
}

.detail .right-rail {
    border-left: 1px solid var(--border-subtle);
    padding: var(--space-4);
    background: var(--surface-2);
    overflow-y: auto;
}
.detail .right-rail h4 {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-3);
    margin: 0 0 var(--space-3);
    font-weight: 600;
}

/* --- Field grid --- */
.field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-4) var(--space-5);
    margin-bottom: var(--space-5);
}
.field { display: flex; flex-direction: column; gap: 2px; }
.field .field-label {
    font-size: var(--text-xs);
    color: var(--text-2);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.field .field-value {
    font-size: var(--text-sm);
    padding: 4px 0;
    cursor: text;
    border-bottom: 1px solid transparent;
    transition: border-color var(--dur-fast) var(--ease-out);
}
.field .field-value:hover { border-bottom-color: var(--border-default); }
.field .field-value.editable::after {
    content: " ";
    color: var(--text-3);
}

/* --- Activity timeline --- */
.timeline { display: flex; flex-direction: column; gap: var(--space-3); }
.timeline-item {
    position: relative;
    padding-left: var(--space-5);
    font-size: var(--text-sm);
}
.timeline-item::before {
    content: "";
    position: absolute;
    left: 6px; top: 8px;
    width: 8px; height: 8px;
    background: var(--accent-6);
    border-radius: var(--radius-full);
    box-shadow: 0 0 0 3px var(--surface-2);
}
.timeline-item:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 9px; top: 16px;
    width: 2px; height: calc(100% - 4px);
    background: var(--border-default);
}
.timeline-item .who { font-weight: 500; }
.timeline-item .when { font-size: var(--text-xs); color: var(--text-3); }
.timeline-item .what { color: var(--text-2); margin-top: 2px; }

/* --- Command palette overlay --- */
.palette-overlay {
    position: fixed;
    inset: 0;
    /* #233: was hard-coded gray-11/50%. The scrim now comes from a
     * theme-aware token so dark mode can lean on pure-black for a
     * stronger blur edge and HC can use a 70% scrim that's still
     * readable against pure-white surfaces underneath. */
    background: var(--scrim);
    backdrop-filter: blur(4px);
    display: flex;
    justify-content: center;
    padding-top: 12vh;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out);
}
.palette-overlay.open { opacity: 1; pointer-events: auto; }

.palette {
    width: min(560px, 92vw);
    max-height: 60vh;
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-3);
    box-shadow: var(--shadow-3);
    display: flex;
    flex-direction: column;
    transform: translateY(-8px);
    transition: transform var(--dur-base) var(--ease-out);
}
.palette-overlay.open .palette { transform: translateY(0); }
.palette input {
    border: 0;
    border-bottom: 1px solid var(--border-subtle);
    background: transparent;
    padding: var(--space-4) var(--space-5);
    font-size: var(--text-md);
    outline: none;
    color: var(--text-1);
}
.palette ul { list-style: none; margin: 0; padding: var(--space-2); overflow-y: auto; }
.palette li {
    padding: 8px var(--space-3);
    border-radius: var(--radius-2);
    font-size: var(--text-sm);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    cursor: pointer;
    color: var(--text-1);
}
.palette li.active {
    /* #233: token-driven so dark + HC pick a visible wash. */
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
}
.palette li .kind { color: var(--text-3); font-size: var(--text-xs); margin-left: auto; }
/* #233: same inherit-when-active pattern as .nav-item / .table .selected. */
.palette li.active .kind { color: inherit; }
.palette li .icon { color: var(--text-2); }

/* #298 palette polish: each row now has a small breadcrumb crumb
 * above the action label so the user sees the destination structure
 * ("Cases ▸ My Open Cases") at a glance. */
.palette li .palette-label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.palette li .palette-crumb {
    color: var(--text-3);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1;
}
.palette li .palette-name {
    color: inherit;
    font-size: var(--text-sm);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.palette li.active .palette-crumb { color: inherit; opacity: 0.7; }

/* --- Hint footer for the palette ---
   a11y (#256): bumped from --text-3 (gray-6, 4.29:1) to --text-2 (gray-8,
   AA-passing 8.5:1) so axe's color-contrast rule passes against the
   #ffffff palette background. Same fix on the inline kbd: explicit
   var(--text-1) so the user-agent default white-on-light kbd colour
   (1.09:1) doesn't leak through. */
.palette-foot {
    border-top: 1px solid var(--border-subtle);
    padding: 6px var(--space-4);
    display: flex;
    gap: var(--space-4);
    font-size: var(--text-xs);
    color: var(--text-2);
}
.palette-foot kbd {
    padding: 1px 5px;
    border: 1px solid var(--border-default);
    border-radius: 3px;
    font-size: 10px;
    background: var(--surface-2);
    color: var(--text-1);
}

/* --- Toast --- */
.toast {
    position: fixed;
    bottom: var(--space-5);
    left: 50%;
    transform: translateX(-50%);
    /* #233: was hard-coded gray-11 / gray-1 which inverted wrongly in
     * dark + had no contrast in HC. Theme-aware tokens swap the pair
     * so the toast always looks "different from the page". */
    background: var(--toast-bg);
    color: var(--toast-fg);
    padding: 10px var(--space-4);
    border-radius: var(--radius-2);
    font-size: var(--text-sm);
    box-shadow: var(--shadow-3);
}

/* --- Utility --- */
/* #271: removed `.row { display: flex; align-items: center; gap: ... }`
 * because it overrode Bootstrap's `.row` class and broke the multi-
 * column layout used by megareport.php and other Bootstrap forms.
 * Bootstrap's column padding plus this rule's gap added up to >100%
 * width, forcing two col-6 cells onto separate rows. Aurora-specific
 * row utilities now use `.aurora-row`. */
.aurora-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.muted { color: var(--text-2); }
.subtle { color: var(--text-3); }
/* #233: when these helpers sit inside a row/item that has an opaque
 * accent wash applied (.active / .selected → --accent-soft-bg), the
 * grayed text fights the wash and drops below AA. Inherit so the
 * wash's --accent-soft-fg flows through to the helper text too. */
.active .muted, .active .subtle,
.selected .muted, .selected .subtle { color: inherit; }
.tabular { font-variant-numeric: tabular-nums; }
.divider {
    height: 1px;
    background: var(--border-subtle);
    margin: var(--space-4) 0;
}
.spacer { flex: 1; }

/* #202 — supervisor dashboard tiles
 * The same markup is also styled by the Bootstrap fallback in custom.css
 * for the legacy chrome (which doesn't load aurora.css). Keep selector
 * names in sync between the two so a future Aurora-only refactor can
 * delete the fallback cleanly.
 */
.ocm-supervisor-dashboard {
    padding: var(--space-4);
}
.ocm-sup-heading {
    font-size: var(--text-xl, 1.25rem);
    color: var(--text-1, #111);
    margin-bottom: var(--space-3);
}
.ocm-sup-intro {
    color: var(--text-2);
    margin-bottom: var(--space-4);
}
.ocm-sup-tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-3);
}
.ocm-sup-tile {
    background: var(--surface-2, #f5f7fa);
    border: 1px solid var(--border-default, #d0d7de);
    border-radius: var(--radius-2, 6px);
    padding: var(--space-3, 12px);
    box-shadow: var(--shadow-1, 0 1px 2px rgba(0,0,0,0.05));
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.ocm-sup-tile:hover {
    box-shadow: var(--shadow-2, 0 4px 8px rgba(0,0,0,0.1));
    transform: translateY(-1px);
}
.ocm-sup-tile-link {
    display: block;
    text-decoration: none;
    color: inherit;
}
.ocm-sup-tile-link:hover,
.ocm-sup-tile-link:focus {
    text-decoration: none;
    color: inherit;
}
.ocm-sup-tile-count {
    font-size: 2rem;
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.ocm-sup-tile-label {
    margin-top: 4px;
    font-size: var(--text-sm, 0.875rem);
    color: var(--text-2);
}
.ocm-sup-tone-info    { border-left: 4px solid #3182ce; }
.ocm-sup-tone-warning { border-left: 4px solid #d69e2e; }
.ocm-sup-tone-danger  { border-left: 4px solid #c53030; }
.ocm-sup-staff-table {
    margin-top: var(--space-3);
}
.ocm-sup-footnote {
    margin-top: var(--space-4);
}
/* --- Aurora chrome (#211 + #212) ----------------------------------------
 * Production rules layered on top of the mockup base. The mockup CSS
 * already ships .app / .sidebar / .topbar / .nav-item — these rules
 * cover the production-only concerns: the sidebar-collapse state, the
 * topbar avatar/notifications dropdowns, the empty-state placeholder
 * inside Saved views, and the pieces of legacy Bootstrap we need to
 * neutralise (`.wrapper` takes flex by default in custom.css; the
 * Aurora variant overrides to grid via the `.aurora-app` class). */

/* The body modifier keeps the legacy Bootstrap reset from interfering
 * with the grid app shell. */
.aurora-body { background: var(--surface-0); }

.aurora-app {
    /* mirror .app — the Aurora chrome wrapper carries both classes */
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    grid-template-rows: var(--topbar-h) 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar main";
    height: 100vh;
    /* #298: cubic-bezier on the column transition gives the collapse
     * a subtle physics curve. Default linear ease feels mechanical
     * for a 240→56px slide; this pairs an ease-out start with a
     * slight overshoot tail. */
    transition: grid-template-columns 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.aurora-app.collapsed {
    grid-template-columns: var(--sidebar-w-collapsed) 1fr;
}

/* #298: when collapsed, give the active nav item a 3px left stripe
 * so users can still see "where am I" without the label. The stripe
 * uses the accent ramp so it inherits theme color. */
.aurora-app.collapsed .aurora-sidebar .nav-item.active {
    position: relative;
}
.aurora-app.collapsed .aurora-sidebar .nav-item.active::before {
    content: "";
    position: absolute;
    left: -2px;
    top: 4px;
    bottom: 4px;
    width: 3px;
    border-radius: 2px;
    background: var(--accent-7);
}
.aurora-app.collapsed .aurora-sidebar .nav-label,
.aurora-app.collapsed .aurora-sidebar .nav-label-text,
.aurora-app.collapsed .aurora-sidebar .brand-label,
.aurora-app.collapsed .aurora-sidebar .count,
.aurora-app.collapsed .aurora-sidebar .aurora-empty-saved {
    display: none;
}
.aurora-app.collapsed .aurora-sidebar .nav-item {
    justify-content: center;
}

/* Sidebar nav links (anchors wrap each .nav-item) */
.aurora-sidebar .aurora-nav-link {
    color: inherit;
    text-decoration: none;
    display: block;
}
.aurora-sidebar .aurora-nav-link:hover { text-decoration: none; }

.aurora-sidebar .aurora-nav-button {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-3);
    margin: 1px 0;
    width: 100%;
    color: var(--text-2);
    background: none;
    border: 0;
    border-radius: var(--radius-2);
    font: inherit;
    font-size: var(--text-sm);
    text-align: left;
    cursor: pointer;
}
.aurora-sidebar .aurora-nav-button:hover {
    background: var(--surface-2);
    color: var(--text-1);
}

.aurora-sidebar .aurora-empty-saved {
    padding: 4px var(--space-3);
    color: var(--text-3);
    font-size: var(--text-xs);
    font-style: italic;
}

.aurora-sidebar .aurora-bottom-nav {
    margin-top: auto;
}

/* Topbar additions */
.aurora-topbar .aurora-sidebar-toggle {
    margin-right: var(--space-2);
    width: 32px;
    height: 32px;
}
.aurora-topbar .search-trigger-label {
    flex: 1;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Topbar dropdowns (notifications + account menu).
 *
 * #267: the wrapper stretches to the topbar's full height so the
 * dropdown panel anchors below the topbar's bottom border instead of
 * overlapping it. Previously align-items: center on .topbar collapsed
 * the wrapper to the button's height (32px), and "top: calc(100% + 6px)"
 * positioned the panel relative to the wrapper rather than the topbar
 * — meaning the panel started above the topbar's bottom edge. */
.aurora-dropdown {
    position: relative;
    display: inline-flex;
    align-items: center;
    align-self: stretch;
}
.aurora-dropdown .aurora-avatar-button {
    border: 0;
    cursor: pointer;
}
.aurora-dropdown-panel {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 240px;
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    box-shadow: var(--shadow-2);
    z-index: 80;
    padding: var(--space-2) 0;
}
.aurora-dropdown-panel[hidden] { display: none; }
.aurora-dropdown-head {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-xs);
    color: var(--text-2);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.aurora-dropdown-name {
    text-transform: none;
    font-size: var(--text-sm);
    color: var(--text-1);
    font-weight: 600;
    letter-spacing: 0;
}
.aurora-dropdown-sub {
    text-transform: none;
    font-size: var(--text-xs);
    color: var(--text-3);
    font-weight: 400;
    letter-spacing: 0;
}
.aurora-dropdown-body {
    padding: var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-2);
}
/* #267: bumped vertical padding so menu items have visible breathing
 * room between rows. At 6px y-padding the items ran together as one
 * block of text. */
.aurora-dropdown-item {
    display: block;
    padding: var(--space-2) var(--space-4);
    color: var(--text-1);
    font-size: var(--text-sm);
    text-decoration: none;
    line-height: 1.4;
}
.aurora-dropdown-item + .aurora-dropdown-item {
    margin-top: 1px;
}
.aurora-dropdown-item:hover {
    background: var(--surface-2);
    text-decoration: none;
}
.aurora-dropdown-item--danger { color: var(--danger-9); }
.aurora-dropdown-item--danger:hover { background: color-mix(in oklch, var(--danger-3) 30%, var(--surface-1)); }
.aurora-dropdown-sep {
    height: 1px;
    background: var(--border-subtle);
    margin: var(--space-2) 0;
}

/* #293 — Aurora inline SVG icon set (replaces literal emoji glyphs).
 *
 * Default sizing tuned for sidebar nav rows + topbar icon-buttons.
 * Authors can compose `aurora-icon--lg` / `aurora-icon--sm` /
 * `aurora-icon--inline` for context-specific sizing.
 *
 * Stroke width is set on the <svg> itself; everything else (color,
 * transition) inherits from the surrounding element so no rule needs
 * to know about the icon underneath. */
.aurora-icon {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    vertical-align: middle;
    transition: color var(--dur-fast) var(--ease-out);
}
.aurora-icon--sm     { width: 14px; height: 14px; }
.aurora-icon--lg     { width: 22px; height: 22px; }
.aurora-icon--xl     { width: 28px; height: 28px; }
.aurora-icon--inline { width: 16px; height: 16px; }

/* Sidebar nav rows give the icon its own slot (16x16). */
.sidebar .nav-item .icon .aurora-icon {
    width: 16px;
    height: 16px;
}

/* Topbar icon-buttons (32x32 outer) center an 18x18 icon. */
.topbar .icon-btn .aurora-icon {
    width: 18px;
    height: 18px;
}

.aurora-badge-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--danger-6);
    position: absolute;
    top: 4px;
    right: 4px;
}

/* Page padding inside the Aurora <main>.
 *
 * #266: <main> is a flex column with the page-wrap flexed to grow
 * (`flex: 1 0 auto`) so the breadcrumb that follows naturally lands
 * at the bottom of the viewport — even on short pages like the home
 * dashboard. Previously the breadcrumb sat immediately under the
 * dashboard content mid-page.
 *
 * #262 / #269: bumped horizontal padding from --space-6 (32px) to
 * --space-7 (48px) so headings on short pages don't crowd the sidebar
 * divider on narrower viewports.
 *
 * The bare `.aurora-breadcrumb` has `min-width: 0` to prevent the
 * grid track collapsing on narrow viewports. */
.aurora-main {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    min-height: 0;
}
/* Page-wrap width: the original 1280px cap left ~360px of dead margin
 * on either side of content on a 1920px desktop, while data-dense
 * tables (case_list, case detail) ran out of room and truncated
 * column headers. Bump the cap to 1680px so the content uses the
 * available horizontal real estate; on viewports narrower than ~1830px
 * the cap is irrelevant because viewport-minus-sidebar is already
 * smaller. Side padding shrinks from space-7 → space-6 to give back
 * another ~16px each side. Forms-heavy pages stay readable because
 * line length is naturally bounded by the widest field. */
.aurora-page-wrap {
    max-width: 1680px;
    padding: var(--space-5) var(--space-6);
    margin: 0 auto;
    width: 100%;
    flex: 1 0 auto;
}
.aurora-breadcrumb {
    padding: 0 var(--space-6) var(--space-5);
    max-width: 1680px;
    margin: 0 auto;
    width: 100%;
    flex: 0 0 auto;
    min-width: 0;
}
.aurora-breadcrumb .breadcrumb {
    background: transparent;
    color: var(--text-3);
    font-size: var(--text-xs);
    padding: 0;
    margin: 0;
    list-style: none;
}
/* #225 — documents grid ----------------------------------------------------
 *
 * Aurora Phase 5: card grid + preview pane that replaces the legacy
 * file_list table when `aurora_documents` is on. Tokens come from the
 * existing aurora.css ramp so light / dark / high-contrast themes pick
 * the right surfaces, borders, and text colors automatically.
 *
 * Layout: 1fr cards + a sticky right-side preview pane. Falls back to
 * a single column under 720px so phones get a stack of cards and the
 * preview pane re-flows below the grid.
 */
.ocm-doc-page {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-4);
    color: var(--text-1);
    font-family: var(--font-sans);
    position: relative;
}
.ocm-doc-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
}
.ocm-doc-title {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: 600;
    color: var(--text-1);
}
.ocm-doc-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
    flex-wrap: wrap;
}
.ocm-spacer { flex: 1 1 var(--space-4); }
.ocm-doc-count {
    font-size: var(--text-sm);
    color: var(--text-2);
    min-width: 6ch;
}

/* Buttons — minimal, scoped to the documents grid so the existing
 * Bootstrap .btn ladder elsewhere is not perturbed. */
.ocm-doc-page .ocm-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--surface-1);
    color: var(--text-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    padding: 6px var(--space-3);
    font-size: var(--text-sm);
    font-family: inherit;
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out);
}
.ocm-doc-page .ocm-btn:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: var(--border-strong);
}
.ocm-doc-page .ocm-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.ocm-doc-page .ocm-btn--primary {
    background: var(--accent-6);
    color: var(--text-on-accent);
    border-color: var(--accent-7);
}
.ocm-doc-page .ocm-btn--primary:hover:not(:disabled) {
    background: var(--accent-7);
    border-color: var(--accent-9);
}
.ocm-doc-page .ocm-btn--danger {
    color: var(--danger-9);
    border-color: var(--danger-3);
}
.ocm-doc-page .ocm-btn--danger:hover:not(:disabled) {
    background: var(--danger-3);
    color: var(--gray-11);
}

.ocm-doc-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--right-rail-w);
    gap: var(--space-4);
    align-items: start;
}
@media (max-width: 880px) {
    .ocm-doc-layout {
        grid-template-columns: 1fr;
    }
}

.ocm-doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--space-3);
    min-height: 200px;
}
.ocm-doc-grid-empty {
    grid-column: 1 / -1;
    padding: var(--space-6);
    text-align: center;
    color: var(--text-2);
    background: var(--surface-2);
    border: 1px dashed var(--border-default);
    border-radius: var(--radius-2);
}

.ocm-doc-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    cursor: pointer;
    transition: transform var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-fast) var(--ease-out);
}
.ocm-doc-card:hover {
    border-color: var(--accent-5);
    box-shadow: var(--shadow-2);
}
.ocm-doc-card:focus-visible {
    outline: 2px solid var(--accent-6);
    outline-offset: 2px;
}
.ocm-doc-card--selected {
    border-color: var(--accent-6);
    background: var(--accent-1);
    box-shadow: var(--shadow-2);
}

.ocm-doc-thumb {
    margin: 0;
    height: 120px;
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-1);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ocm-doc-thumb-img,
.ocm-doc-thumb-pdf {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border: 0;
}
.ocm-doc-thumb-icon {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: 0.05em;
    color: var(--text-2);
    background: var(--surface-1);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-1);
    border: 1px solid var(--border-default);
}

.ocm-doc-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.ocm-doc-name {
    margin: 0;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ocm-doc-name--editing {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    background: var(--surface-2);
    outline: 2px solid var(--accent-6);
    border-radius: var(--radius-1);
    padding: 1px 4px;
    cursor: text;
}
.ocm-doc-sub {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ocm-doc-select {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    width: 18px;
    height: 18px;
    accent-color: var(--accent-6);
    cursor: pointer;
}

/* Preview pane — sticky on wide screens so it stays visible while the
 * grid scrolls; flows into a card below the grid on narrow viewports. */
.ocm-doc-preview {
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    padding: var(--space-3);
    min-height: 320px;
    position: sticky;
    top: var(--space-4);
    max-height: calc(100vh - var(--topbar-h) - var(--space-6));
    overflow: auto;
}
.ocm-doc-preview[data-empty] {
    display: flex;
    align-items: center;
    justify-content: center;
}
.ocm-doc-preview-empty {
    margin: 0;
    color: var(--text-3);
    font-size: var(--text-sm);
    text-align: center;
}
.ocm-doc-preview-head {
    border-bottom: 1px solid var(--border-subtle);
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-2);
}
.ocm-doc-preview-name {
    margin: 0 0 2px 0;
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--text-1);
    word-break: break-word;
}
.ocm-doc-preview-sub {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--text-2);
}
.ocm-doc-preview-body {
    display: flex;
    align-items: center;
    justify-content: center;
}
.ocm-doc-preview-pdf {
    width: 100%;
    height: 70vh;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-1);
}
.ocm-doc-preview-img {
    max-width: 100%;
    max-height: 70vh;
    border-radius: var(--radius-1);
}
.ocm-doc-preview-fallback {
    text-align: center;
    color: var(--text-2);
    padding: var(--space-5) var(--space-3);
}

/* Drop overlay — shown via data-doc-drop-overlay (the JS toggles
 * `hidden` on the host node so we don't need an inline display:none). */
.ocm-drop-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: color-mix(in oklch, var(--accent-9) 55%, transparent);
    backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.ocm-drop-overlay-inner {
    background: var(--surface-1);
    border: 2px dashed var(--accent-6);
    border-radius: var(--radius-3);
    padding: var(--space-7);
    color: var(--text-1);
    font-size: var(--text-lg);
    font-weight: 500;
    box-shadow: var(--shadow-3);
}

/* Confirmation modal */
.ocm-doc-confirm {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgb(0 0 0 / 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
}
.ocm-doc-confirm-card {
    background: var(--surface-1);
    border-radius: var(--radius-3);
    padding: var(--space-5);
    max-width: 440px;
    width: 90%;
    box-shadow: var(--shadow-3);
    color: var(--text-1);
}
.ocm-doc-confirm-title {
    margin: 0 0 var(--space-2) 0;
    font-size: var(--text-lg);
    font-weight: 600;
}
.ocm-doc-confirm-msg {
    margin: 0 0 var(--space-4) 0;
    color: var(--text-2);
    font-size: var(--text-sm);
}
.ocm-doc-confirm-buttons {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
}

/* ── Aurora site-map / Browse OCM (#288) ────────────────────────────
 *
 * Replaces the legacy 6-column dense link-list site map with a
 * card grid grouped by domain. The Admin card spans two columns and
 * has its own 3-column sub-grid for sub-grouping the dense system
 * screens.
 */
.ocm-sitemap {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}
@media (max-width: 1100px) { .ocm-sitemap { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .ocm-sitemap { grid-template-columns: 1fr; } }
.ocm-sitemap__card {
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    padding: var(--space-4);
    transition: border-color var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-fast) var(--ease-out);
}
.ocm-sitemap__card:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-1);
}
.ocm-sitemap__card--wide {
    grid-column: span 3;
}
@media (max-width: 1100px) { .ocm-sitemap__card--wide { grid-column: span 2; } }
@media (max-width: 700px)  { .ocm-sitemap__card--wide { grid-column: span 1; } }
.ocm-sitemap__card-title {
    margin: 0 0 var(--space-3);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-1);
    letter-spacing: -0.005em;
}
.ocm-sitemap__group {
    margin: var(--space-3) 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-3);
}
.ocm-sitemap__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.ocm-sitemap__list li {
    margin: 0;
}
.ocm-sitemap__list a {
    display: block;
    padding: 6px var(--space-2);
    color: var(--text-1);
    text-decoration: none;
    font-size: var(--text-sm);
    border-radius: var(--radius-1);
    transition: background var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
}
.ocm-sitemap__list a:hover {
    background: var(--surface-2);
    color: var(--accent-7);
    text-decoration: none;
}
.ocm-sitemap__columns {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}
@media (max-width: 800px) { .ocm-sitemap__columns { grid-template-columns: 1fr; } }
.ocm-sitemap__reports ul,
.ocm-sitemap__reports ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.ocm-sitemap__reports li {
    margin: 0;
}
.ocm-sitemap__reports a {
    display: block;
    padding: 6px var(--space-2);
    color: var(--text-1);
    text-decoration: none;
    font-size: var(--text-sm);
    border-radius: var(--radius-1);
}
.ocm-sitemap__reports a:hover {
    background: var(--surface-2);
    color: var(--accent-7);
}

/* ── Aurora empty-state pattern (#296) ──────────────────────────────
 *
 * Extend the existing `.ocm-empty-state` to support an icon, a
 * 1-line description, and an inline CTA pointing to the action that
 * fills the void. Pages opt in by composing markup like:
 *
 *     <div class="ocm-empty-state">
 *       <div class="ocm-empty-state__icon">{lucide svg}</div>
 *       <p class="ocm-empty-state__title">No saved views yet</p>
 *       <p class="ocm-empty-state__hint">Pin one to surface it in the sidebar.</p>
 *       <a class="ocm-empty-state__cta" href="...">+ Save a view</a>
 *     </div>
 *
 * The bare-string variant `<div class="ocm-empty-state">No foo
 * yet</div>` keeps working — the new sub-elements are additive.
 */
.ocm-empty-state {
    text-align: center;
    color: var(--text-2);
    font-size: var(--text-sm);
    line-height: 1.55;
    padding: var(--space-5) var(--space-4);
}
.ocm-empty-state__icon {
    color: var(--text-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin: 0 auto var(--space-3);
    background: var(--surface-2);
    border-radius: var(--radius-full);
}
.ocm-empty-state__icon .aurora-icon {
    width: 22px;
    height: 22px;
}
.ocm-empty-state__title {
    margin: 0 0 var(--space-1);
    color: var(--text-1);
    font-size: var(--text-base);
    font-weight: 600;
}
.ocm-empty-state__hint {
    margin: 0 0 var(--space-3);
    color: var(--text-2);
    font-size: var(--text-sm);
}
.ocm-empty-state__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-3);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    background: var(--surface-1);
    color: var(--text-1);
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: 500;
}
.ocm-empty-state__cta:hover {
    background: var(--surface-2);
    border-color: var(--border-strong);
    text-decoration: none;
}

/* Inline empty-state used in dashboard panels — same tokens, smaller
 * footprint so it doesn't dominate a half-column card. */
.ocm-empty-state--inline {
    padding: var(--space-4) var(--space-3);
}
.ocm-empty-state--inline .ocm-empty-state__icon {
    width: 36px; height: 36px; margin-bottom: var(--space-2);
}

/* ── Calendar action bar + section hierarchy (#289, #290) ──────────
 *
 * Calendar pages render a top pagination row (Previous Day / Go to
 * date / Next Day) and four section cards (Today's Pending,
 * Actions, To Do List, Time Slip Log). Without help, every section
 * uses an h2 with its own card, so the page reads as a stack of
 * equal-weight blocks. Polish:
 *
 *   - Pagination becomes a clean toolbar with chip-shaped Prev/Next
 *     and a flush-right inline date input.
 *   - Section h2 (.hdt) becomes a smaller, lighter sub-section
 *     heading so the page-header stays the visual top.
 *   - The "Actions" sidebar gets a subtle inset background so it
 *     reads as a sidebar, not as the canvas.
 */
.aurora-page-wrap .pagination {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-2);
    padding: var(--space-2);
    margin: 0 0 var(--space-4) 0;
    list-style: none;
}
.aurora-page-wrap .pagination .page-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 4px var(--space-3);
    border-radius: var(--radius-1);
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-1);
    font-size: var(--text-sm);
    text-decoration: none;
    transition: background var(--dur-fast) var(--ease-out);
}
.aurora-page-wrap .pagination .page-link:hover {
    background: var(--surface-2);
    color: var(--text-1);
    border-color: var(--border-subtle);
}
.aurora-page-wrap .pagination .form-inline {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1 1 auto;
    justify-content: center;
}
.aurora-page-wrap .pagination .form-inline label {
    font-size: var(--text-sm);
    color: var(--text-2);
}
.aurora-page-wrap .pagination .ml-md-auto { margin-left: auto; }
.aurora-page-wrap .pagination .ml-auto    { margin-left: auto; }

/* Section h2 inside a calendar / activity / dashboard becomes a
 * smaller "section" heading that reads below the page header. */
.aurora-page-wrap h2.hdt {
    margin: var(--space-4) 0 var(--space-2);
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--text-1);
    letter-spacing: -0.005em;
}

/* Calendar Actions card — give it an inset background so it visually
 * reads as a sidebar / aside, not another primary content block. */
.aurora-page-wrap .col-sm:has(> .hdt:first-child) {
    /* no-op fallback for browsers without :has */
}
.aurora-page-wrap .col-sm > h2.hdt + .fas,
.aurora-page-wrap .col-sm > h2.hdt + form {
    margin-top: var(--space-2);
}

/* Intake form differentiation (#280): a subtle info-tinted top border
 * + a hint banner below the search form so users know intake creates
 * a NEW record vs the addressbook which finds an existing one. */
.aurora-page-wrap form[action*="intake2.php"] {
    border-top: 3px solid var(--success-6);
    padding-top: var(--space-3);
    border-radius: var(--radius-1);
}
.aurora-page-wrap form[action*="intake2.php"]::before {
    content: "Search first, then create a new record only if no existing contact matches.";
    display: block;
    font-size: var(--text-xs);
    color: var(--text-3);
    margin-bottom: var(--space-2);
}
.aurora-page-wrap form[action*="addressbook.php"] {
    border-top: 3px solid var(--accent-6);
    padding-top: var(--space-3);
    border-radius: var(--radius-1);
}
.aurora-page-wrap form[action*="addressbook.php"]::before {
    content: "Find an existing contact by name, phone, or SSN.";
    display: block;
    font-size: var(--text-xs);
    color: var(--text-3);
    margin-bottom: var(--space-2);
}

/* ── Aurora settings tabs (#302) ────────────────────────────────────
 *
 * System Settings split into 10 tabs grouped by configuration
 * category. Bootstrap 5's nav-tabs power the click-to-switch; this
 * stylesheet just gives the tab strip + content area Aurora-token-
 * native chrome instead of Bootstrap's defaults.
 *
 * The save bar at the bottom is sticky so a user changing settings
 * deep in a long tab can save without scrolling all the way back.
 */
.aurora-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin-bottom: var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
    padding-bottom: 0;
}
.aurora-tabs .nav-link {
    padding: 8px var(--space-3);
    border: 1px solid transparent;
    border-bottom: 0;
    border-radius: var(--radius-2) var(--radius-2) 0 0;
    background: transparent;
    color: var(--text-2);
    font-size: var(--text-sm);
    font-weight: 500;
    line-height: 1.4;
    transition: background var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
}
.aurora-tabs .nav-link:hover {
    background: var(--surface-2);
    color: var(--text-1);
}
.aurora-tabs .nav-link.active {
    background: var(--surface-1);
    color: var(--accent-7);
    border-color: var(--border-subtle);
    border-bottom-color: var(--surface-1);
    margin-bottom: -1px;
    position: relative;
    z-index: 1;
}
.aurora-tab-content {
    min-height: 60vh;
}
.aurora-save-bar {
    position: sticky;
    bottom: 0;
    background: var(--surface-0);
    padding: var(--space-3) 0;
    margin-top: var(--space-5);
    border-top: 1px solid var(--border-subtle);
    z-index: 5;
}
/* Settings-search target flash — when the user navigates to a
 * specific setting via #setting-foo the target gets a soft pulse so
 * they can find it within a busy tab. */
.aurora-tabs-target-flash {
    animation: aurora-settings-flash 1.4s ease-out;
}
@keyframes aurora-settings-flash {
    0%   { box-shadow: 0 0 0 4px var(--accent-soft-bg); }
    100% { box-shadow: 0 0 0 0 transparent; }
}

/* ── Aurora collapse / disclosure (#286) ────────────────────────────
 *
 * <details> / <summary> styled to match the design system. Used by
 * System Settings to hide the 8-input "Branding & icons" panel
 * behind a one-click expander, plus any other "advanced / optional"
 * surfaces.
 *
 * Replaces the implicit triangle marker with a chevron that rotates
 * when open. */
.ocm-collapse {
    cursor: pointer;
    padding: var(--space-3) var(--space-4);
}
.ocm-collapse > .ocm-collapse__summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding: 0;
    color: var(--text-1);
    font-weight: 500;
}
.ocm-collapse > .ocm-collapse__summary::-webkit-details-marker { display: none; }
.ocm-collapse > .ocm-collapse__summary::before {
    content: "▸";
    color: var(--text-3);
    font-size: var(--text-xs);
    transition: transform var(--dur-fast) var(--ease-out);
    flex: 0 0 auto;
}
.ocm-collapse[open] > .ocm-collapse__summary::before {
    transform: rotate(90deg);
}
.ocm-collapse__title {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-1);
}
.ocm-collapse__hint {
    color: var(--text-3);
    font-size: var(--text-sm);
    font-weight: 400;
}
.ocm-collapse__body {
    margin-top: var(--space-3);
}

/* ── Form polish (#297) ─────────────────────────────────────────────
 *
 * Visual upgrade to the legacy two-input phone control on
 * addressbook.php / intake2.php / contact.php. The underlying
 * <input name="area_code"> + <input name="phone"> stays (so the
 * backend still receives two separate values) but the visual
 * treatment merges them into a single rounded shell with an
 * inline divider, getting rid of the cramped pre-1995 look.
 *
 * The .maskt span wraps the whole control in the legacy markup;
 * we use that as the styling hook. */
.aurora-page-wrap .maskt {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-2);
    background: var(--surface-1);
    font-size: var(--text-sm);
    color: var(--text-2);
    transition: border-color var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-fast) var(--ease-out);
}
.aurora-page-wrap .maskt:focus-within {
    border-color: var(--accent-6);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent-6) 25%, transparent);
}
.aurora-page-wrap .maskt input.form-control,
.aurora-page-wrap .maskt input.form-control-sm {
    border: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    padding: 4px 2px !important;
    font-size: var(--text-sm) !important;
    color: var(--text-1) !important;
    min-width: 0;
}
.aurora-page-wrap .maskt input[name="area_code"] {
    width: 36px !important;
    text-align: center;
}
.aurora-page-wrap .maskt input[name="phone"] {
    width: 80px !important;
}

/* ── Aurora semantic colour utilities (#299) ────────────────────────
 *
 * Aurora ships full success / warning / danger / info OKLCH ramps
 * but most components only ever pull from the accent ramp. These
 * utility classes expose the semantic tokens for the sites that
 * actually want to communicate meaning (saved-toast → success,
 * approaching-deadline row tint → warning, destructive button →
 * danger, hint banner → info).
 *
 * Each utility composes the appropriate background-tint, foreground,
 * and border tokens so the surface reads as a coherent semantic
 * card without any per-component per-theme overrides.
 */
.ocm-tint-success {
    background: var(--badge-success-bg);
    color: var(--badge-success-fg, var(--success-9));
    border-color: var(--success-6);
}
.ocm-tint-warning {
    background: var(--badge-warning-bg);
    color: var(--badge-warning-fg, var(--warning-9));
    border-color: var(--warning-6);
}
.ocm-tint-danger {
    background: var(--badge-danger-bg);
    color: var(--badge-danger-fg, var(--danger-9));
    border-color: var(--danger-6);
}
.ocm-tint-info {
    background: var(--badge-info-bg);
    color: var(--badge-info-fg, var(--info-6));
    border-color: var(--info-6);
}

/* Compact pill badges using the same semantic tokens (drop-in for
 * Bootstrap's .badge.bg-success / .bg-warning / .bg-danger which
 * stay light-only). */
.ocm-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 10px;
    border-radius: var(--radius-full);
    font-size: var(--text-xs);
    font-weight: 500;
    line-height: 1.5;
    border: 1px solid transparent;
}
.ocm-pill--success { background: var(--badge-success-bg); color: var(--badge-success-fg, var(--success-9)); }
.ocm-pill--warning { background: var(--badge-warning-bg); color: var(--badge-warning-fg, var(--warning-9)); }
.ocm-pill--danger  { background: var(--badge-danger-bg);  color: var(--badge-danger-fg,  var(--danger-9));  }
.ocm-pill--info    { background: var(--badge-info-bg);    color: var(--badge-info-fg,    var(--info-6));    }

/* Bootstrap semantic backgrounds that we DO want to surface — make
 * the dark theme honour the same hue family rather than leaking
 * white. .bg-success / .bg-warning / .bg-danger / .bg-info rendered
 * via Bootstrap had stark hex values that read badly in dark. */
[data-theme="dark"] .bg-success { background-color: color-mix(in oklch, var(--success-6) 60%, var(--surface-1)) !important; color: var(--success-3); }
[data-theme="dark"] .bg-warning { background-color: color-mix(in oklch, var(--warning-6) 60%, var(--surface-1)) !important; color: var(--gray-11); }
[data-theme="dark"] .bg-danger  { background-color: color-mix(in oklch, var(--danger-6)  60%, var(--surface-1)) !important; color: var(--danger-3); }
[data-theme="dark"] .bg-info    { background-color: color-mix(in oklch, var(--info-6)    60%, var(--surface-1)) !important; color: var(--info-3); }

/* Activity compose form-action separator (#291). The Save / Save and
 * Close / Cancel button row gets a hairline divider above + tighter
 * grouping so it reads as the action affordance, not "another row of
 * fields". */
.aurora-page-wrap form .ocm-form-actions,
.aurora-page-wrap form .form-actions {
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-subtle);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* Inline "Text Highlighting" link inside Activity compose was a
 * power-user feature exposed at peer with primary form fields. Make
 * it look like a small textarea-toolbar control rather than a body
 * link. */
.aurora-page-wrap a[href*="text_highlighting"],
.aurora-page-wrap a.ocm-textarea-toolbar-link {
    display: inline-block;
    margin-top: var(--space-1);
    font-size: var(--text-xs);
    color: var(--text-3);
    text-decoration: none;
    padding: 2px var(--space-2);
    border-radius: var(--radius-1);
    background: var(--surface-2);
}
.aurora-page-wrap a[href*="text_highlighting"]:hover,
.aurora-page-wrap a.ocm-textarea-toolbar-link:hover {
    background: var(--surface-3);
    color: var(--text-1);
    text-decoration: none;
}

/* Case-detail activity rail — combine "+ New" with the empty-state
 * card so the empty state reads as intentional rather than lopsided.
 * (#275) The static-#219 rail wraps "+ New" link inside the rail's
 * default markup; rebalance the visual weight by giving the empty
 * <p> a centred icon + caption + button. */
.ocm-case-three-pane__rail .ocm-case-tl-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-3);
    color: var(--text-2);
    font-size: var(--text-sm);
    background: var(--surface-2);
    border: 1px dashed var(--border-default);
    border-radius: var(--radius-2);
    margin: var(--space-2) 0;
}

/* ── Aurora microinteractions (#300) ────────────────────────────────
 *
 * Apply a consistent hover + focus ring + transition treatment to
 * every interactive element. Three rules:
 *
 *   1. Every clickable element gets a 150ms ease-out background-color
 *      transition (subtle but perceptible, no layout shift).
 *   2. :focus-visible always shows the 2px outline + 2px offset
 *      pattern with the accent token. Not :focus, so mouse users
 *      don't see a ring after click.
 *   3. <main> content fades in 180ms on load — perceptual smoothness
 *      without faking SPA navigation.
 */

/* Universal smooth-hover for the most common click targets. The list
 * is intentionally narrow so we don't over-transition things like
 * <body> or <input> backgrounds. */
.btn,
.aurora-nav-link,
.aurora-nav-button,
.aurora-dropdown-item,
.aurora-sidebar .nav-item,
.topbar .icon-btn,
.aurora-page-header__action,
.ocm-home__kpi,
.ocm-home__list-link {
    transition:
        background-color var(--dur-fast) var(--ease-out),
        border-color var(--dur-fast) var(--ease-out),
        color var(--dur-fast) var(--ease-out),
        transform var(--dur-fast) var(--ease-out),
        box-shadow var(--dur-fast) var(--ease-out);
}

/* Unified focus ring. Mouse users see no outline (focus alone),
 * keyboard users see the ring (focus-visible). */
*:focus-visible {
    outline: 2px solid var(--accent-6);
    outline-offset: 2px;
    border-radius: var(--radius-1);
}
.btn:focus,
.aurora-nav-link:focus,
.aurora-dropdown-item:focus,
.topbar .icon-btn:focus {
    outline: none;
}

/* Subtle on-page-load fade-in for the main content column. Renders
 * once on each navigation; respect prefers-reduced-motion so users
 * who opt out of motion don't see the fade.  */
@keyframes aurora-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.aurora-main > .aurora-page-wrap {
    animation: aurora-fade-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@media (prefers-reduced-motion: reduce) {
    .aurora-main > .aurora-page-wrap { animation: none; }
    .aurora-app { transition: none; }
}

/* ── Aurora page-header component (#294) ────────────────────────────
 *
 * Every Aurora page should open with this same header bar:
 *
 *   <eyebrow>            <primary action>  <secondary action>
 *   Title
 *   Subtitle (optional)
 *   ────────────────────────────────────────────────────────
 *
 * The PHP helper pl_aurora_page_header() in cms/app/lib/
 * plAuroraComponents.php emits the markup. The hairline divider at
 * the bottom is rendered as a border, not a stroke, so the header
 * has the same height regardless of whether actions are present.
 */
.aurora-page-header {
    margin: 0 0 var(--space-5) 0;
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
}
.aurora-page-header__row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
}
.aurora-page-header__lead {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}
.aurora-page-header__eyebrow {
    font-size: var(--text-xs);
    color: var(--text-3);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.aurora-page-header__title {
    margin: 0;
    font-size: var(--text-2xl);
    font-weight: 600;
    color: var(--text-1);
    line-height: var(--leading-tight);
    letter-spacing: -0.015em;
}
.aurora-page-header__subtitle {
    margin: 0;
    color: var(--text-2);
    font-size: var(--text-sm);
}
.aurora-page-header__actions {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex: 0 0 auto;
}
.aurora-page-header__action {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* ── Aurora home dashboard (#295) ───────────────────────────────────
 *
 * Replaces the empty "Message Board" home with: greeting + 4 KPI
 * tiles + 2-column "Recent activity" / "Today's calendar" panels.
 * Pinned admin messages slide below the dashboard so they're still
 * surfaced but no longer dominate the most-visited page.
 *
 * Token usage:
 *   --surface-1   panel + KPI background
 *   --border-subtle   tile borders
 *   --space-*    inter-element rhythm
 *   --accent-*   KPI icon tints + hover lift
 *
 * Layout: a single CSS grid with three rows (greeting, KPIs, panels).
 * KPIs collapse to 2-up under 720px; panels stack under 900px. */
.ocm-home {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}
.ocm-home__greeting {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.ocm-home__title {
    font-size: var(--text-3xl);
    font-weight: 600;
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    color: var(--text-1);
    margin: 0;
}
.ocm-home__subtitle {
    color: var(--text-2);
    font-size: var(--text-base);
    margin: 0;
}

/* KPI tiles ---------------------------------------------------------- */
.ocm-home__kpis {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4);
}
@media (max-width: 1100px) {
    .ocm-home__kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.ocm-home__kpi {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    text-decoration: none;
    color: inherit;
    transition: transform var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out),
                box-shadow var(--dur-fast) var(--ease-out);
}
a.ocm-home__kpi:hover,
a.ocm-home__kpi:focus-visible {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-1);
    transform: translateY(-1px);
    text-decoration: none;
    color: inherit;
}
a.ocm-home__kpi:focus-visible {
    outline: 2px solid var(--accent-6);
    outline-offset: 2px;
}
.ocm-home__kpi-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-2);
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
}
.ocm-home__kpi-value {
    font-size: var(--text-2xl);
    font-weight: 600;
    color: var(--text-1);
    line-height: 1;
    letter-spacing: -0.015em;
}
.ocm-home__kpi-label {
    font-size: var(--text-sm);
    color: var(--text-2);
}

/* Panels (Recent activity + Today's calendar + optional Message Board) */
.ocm-home__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
}
@media (max-width: 900px) {
    .ocm-home__panels { grid-template-columns: 1fr; }
}
.ocm-home__panel {
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-3);
    overflow: hidden;
}
.ocm-home__panel--motd {
    grid-column: 1 / -1;
}
.ocm-home__panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
}
.ocm-home__panel-title {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-1);
    letter-spacing: -0.005em;
}
.ocm-home__panel-link {
    font-size: var(--text-sm);
    color: var(--link);
    text-decoration: none;
}
.ocm-home__panel-link:hover { text-decoration: underline; }

/* List rows inside panels (recent activity, today's calendar) ---------- */
.ocm-home__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.ocm-home__list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
}
.ocm-home__list-item:last-child { border-bottom: 0; }
.ocm-home__list-link {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    color: var(--text-1);
    text-decoration: none;
    font-size: var(--text-sm);
    line-height: 1.4;
}
.ocm-home__list-link:hover { color: var(--accent-7); text-decoration: none; }
.ocm-home__list-time {
    flex: 0 0 64px;
    font-variant-numeric: tabular-nums;
    color: var(--text-2);
    font-size: var(--text-xs);
}
.ocm-home__list-time--allday {
    font-style: italic;
    color: var(--text-3);
}
.ocm-home__list-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ocm-home__list-meta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex: 0 0 auto;
    font-size: var(--text-xs);
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}
.ocm-home__list-meta-link {
    color: var(--text-2);
    text-decoration: none;
}
.ocm-home__list-meta-link:hover { color: var(--accent-7); text-decoration: underline; }
.ocm-home__list-date { color: var(--text-3); }

/* Empty states -------------------------------------------------------- */
.ocm-home__empty {
    padding: var(--space-5) var(--space-4);
    text-align: center;
    color: var(--text-2);
    font-size: var(--text-sm);
}
.ocm-home__empty p { margin: 0 0 var(--space-2) 0; color: inherit; }
.ocm-home__empty-cta {
    display: inline-block;
    color: var(--link);
    font-size: var(--text-sm);
    text-decoration: none;
}
.ocm-home__empty-cta:hover { text-decoration: underline; }

/* Embedded message board content keeps the panel padding consistent
 * with the list rows above it. */
.ocm-home__motd {
    padding: var(--space-4);
    color: var(--text-1);
    font-size: var(--text-sm);
    line-height: 1.55;
}
.ocm-home__motd p,
.ocm-home__motd blockquote { margin: 0 0 var(--space-3) 0; }
.ocm-home__motd blockquote {
    padding-left: var(--space-4);
    border-left: 3px solid var(--border-subtle);
    color: var(--text-2);
    font-style: italic;
}

/* ── Dark + high-contrast Bootstrap component overrides (#272) ─────────
 *
 * The Aurora token system covers Aurora-native components, but the
 * legacy Bootstrap classes baked into many existing pages (`.card`,
 * `.bg-light`, `.text-muted`, `.table`, `.list-group-item`, …) ship
 * with hard-coded near-white backgrounds and dark text. In dark mode
 * those panels stay light and read as bright cards floating in a
 * dark page; many also lose contrast when the surrounding page text
 * shifts to light. The block below remaps the most-visible Bootstrap
 * surfaces to Aurora's theme-aware tokens so dark + high-contrast
 * users get a coherent, readable page without rewriting every
 * page-specific stylesheet. Light mode is untouched.
 */
[data-theme="dark"] body,
[data-theme="dark"] html {
    background: var(--surface-0) !important;
    color: var(--text-1);
}

/* Bootstrap surface utilities — the cards / wells / panels that
 * megareport.php, system-*.php and other forms use. */
[data-theme="dark"] .bg-light,
[data-theme="dark"] .bg-white {
    background-color: var(--surface-2) !important;
    color: var(--text-1);
}
[data-theme="dark"] .bg-dark {
    background-color: var(--surface-0) !important;
    color: var(--text-1);
}

/* Cards (#272). Bootstrap defaults: white bg, dark text, light border. */
[data-theme="dark"] .card {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-default);
}
[data-theme="dark"] .card .card-body {
    color: var(--text-1);
}
[data-theme="dark"] .card .card-body.bg-light {
    background-color: var(--surface-2) !important;
}
[data-theme="dark"] .card-header,
[data-theme="dark"] .card-footer {
    background-color: var(--surface-2);
    border-color: var(--border-subtle);
    color: var(--text-1);
}
[data-theme="dark"] .card-title { color: var(--text-1); }

/* Bootstrap text utilities. .text-muted's #6c757d sits at ~3:1 against
 * dark surfaces (below AA); remap to --text-3 which is the AA-clean
 * tertiary token in dark. */
[data-theme="dark"] .text-muted { color: var(--text-3) !important; }
[data-theme="dark"] .text-dark  { color: var(--text-1) !important; }
[data-theme="dark"] .text-body  { color: var(--text-1) !important; }
[data-theme="dark"] .text-secondary { color: var(--text-2) !important; }

/* Tables. Bootstrap's default is dark text on white. Map to surface-1
 * + text-1 in dark; alternating rows (.table-striped) pick up surface-2;
 * borders use the subtle token. */
[data-theme="dark"] .table {
    color: var(--text-1);
    background-color: var(--surface-1);
    border-color: var(--border-subtle);
    --bs-table-bg: var(--surface-1);
    --bs-table-color: var(--text-1);
    --bs-table-border-color: var(--border-subtle);
    --bs-table-striped-bg: var(--surface-2);
    --bs-table-striped-color: var(--text-1);
    --bs-table-hover-bg: var(--surface-3);
    --bs-table-hover-color: var(--text-1);
}
[data-theme="dark"] .table > :not(caption) > * > * {
    background-color: transparent;
    color: inherit;
    border-bottom-color: var(--border-subtle);
}
[data-theme="dark"] .table-light,
[data-theme="dark"] .table-light > th,
[data-theme="dark"] .table-light > td {
    background-color: var(--surface-2) !important;
    color: var(--text-1) !important;
}

/* List groups. */
[data-theme="dark"] .list-group {
    background-color: transparent;
    border-color: var(--border-subtle);
}
[data-theme="dark"] .list-group-item {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-subtle);
}
[data-theme="dark"] .list-group-item-action:hover,
[data-theme="dark"] .list-group-item-action:focus {
    background-color: var(--surface-2);
    color: var(--text-1);
}

/* Form controls outside the aurora-form-components gate (so legacy
 * pages with the Aurora chrome but without the form-components
 * toggle still render readable inputs in dark mode). The
 * aurora-form-components.css rules already use tokens; these are a
 * narrower fallback that matches by selector but only when in dark. */
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="search"],
[data-theme="dark"] input[type="email"],
[data-theme="dark"] input[type="password"],
[data-theme="dark"] input[type="number"],
[data-theme="dark"] input[type="url"],
[data-theme="dark"] input[type="tel"],
[data-theme="dark"] input[type="date"],
[data-theme="dark"] input[type="time"],
[data-theme="dark"] input[type="datetime-local"],
[data-theme="dark"] textarea,
[data-theme="dark"] select {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-default);
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
    color: var(--text-3);
    opacity: 1;
}

/* Headings inherit text colour but enforce the token here so legacy
 * pages with their own h1/h2 colour rules still flip in dark. */
[data-theme="dark"] h1, [data-theme="dark"] h2,
[data-theme="dark"] h3, [data-theme="dark"] h4,
[data-theme="dark"] h5, [data-theme="dark"] h6,
[data-theme="dark"] blockquote,
[data-theme="dark"] p,
[data-theme="dark"] label,
[data-theme="dark"] li,
[data-theme="dark"] dt, [data-theme="dark"] dd,
[data-theme="dark"] th, [data-theme="dark"] td {
    color: var(--text-1);
}

/* Borders + horizontal rules. */
[data-theme="dark"] hr {
    border-color: var(--border-subtle);
    color: var(--border-subtle);
    opacity: 1;
}
[data-theme="dark"] .border,
[data-theme="dark"] .border-dark {
    border-color: var(--border-default) !important;
}

/* Bootstrap dropdowns + alerts (used in legacy pages). */
[data-theme="dark"] .dropdown-menu {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-default);
}
[data-theme="dark"] .dropdown-item {
    color: var(--text-1);
}
[data-theme="dark"] .dropdown-item:hover,
[data-theme="dark"] .dropdown-item:focus {
    background-color: var(--surface-2);
    color: var(--text-1);
}
[data-theme="dark"] .alert {
    background-color: var(--surface-2);
    color: var(--text-1);
    border-color: var(--border-default);
}

/* Modals. */
[data-theme="dark"] .modal-content {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-default);
}
[data-theme="dark"] .modal-header,
[data-theme="dark"] .modal-footer {
    border-color: var(--border-subtle);
}

/* Megareport filter group labels (#279). Surface the AND-joined
 * group structure (Filter group A AND Filter group B AND …) so
 * users can see what they're configuring at a glance. */
.ocm-megareport-group {
    position: relative;
}
.ocm-megareport-group-label {
    position: absolute;
    top: -10px;
    left: 16px;
    padding: 0 var(--space-2);
    background: var(--surface-0);
    color: var(--text-3);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    z-index: 1;
}

/* Megareport sticky toolbar (#278). Lift Run Report into a sticky
 * toolbar at the top of the form so users don't have to scroll
 * through every filter group to submit. The submit row inside the
 * existing card-mb-4 gets sticky positioning. */
.aurora-page-wrap form#mega > .container-fluid > .card.mb-4:last-of-type {
    position: sticky;
    bottom: var(--space-3);
    z-index: 5;
    box-shadow: 0 4px 16px rgb(0 0 0 / 0.08);
}

/* Megareport form panels — custom.css hardcodes white bg for the
 * field-pane and saved-reports list, which leaves them blindingly
 * bright in dark mode. Override to surface tokens. */
[data-theme="dark"] .ocm-megareport-field-pane,
[data-theme="dark"] .ocm-megareport-saved {
    background-color: var(--surface-1) !important;
    color: var(--text-1);
    border-color: var(--border-default) !important;
}
[data-theme="dark"] .ocm-megareport-and {
    color: var(--danger-3);
}

/* Misc legacy hardcoded-white panels that the Aurora chrome inherits
 * (e.g. ocm-pb-rule cards, conflict cards, etc.). Use surface-2 so
 * they read as cards without dropping dark contrast. */
[data-theme="dark"] .ocm-pb-rule-card { background-color: var(--surface-2) !important; color: var(--text-1); }
[data-theme="dark"] .ocm-pb-rule-matched { background-color: var(--surface-3) !important; color: var(--text-1); }

/* Pagination. */
[data-theme="dark"] .page-link {
    background-color: var(--surface-1);
    color: var(--text-1);
    border-color: var(--border-subtle);
}
[data-theme="dark"] .page-item.active .page-link {
    background-color: var(--accent-7);
    border-color: var(--accent-7);
    color: var(--text-on-accent, #fff);
}
[data-theme="dark"] .page-item.disabled .page-link {
    background-color: var(--surface-1);
    color: var(--text-3);
}

/* ── E-signature status panel (Phase 4 follow-up) ─────────────────────
 * The documents page renders an envelope-status section beneath the
 * docs grid (cms/documents.php). Status badges are coloured by their
 * lifecycle state so reviewers can scan the table at a glance.
 */
.ocm-esign-panel {
    margin-top: 2rem;
    padding: 1rem;
    border-top: 1px solid var(--border-1, #e0e0e0);
}
.ocm-esign-panel h2 {
    font-size: 1.15rem;
    margin-bottom: 0.75rem;
}
.ocm-esign-panel h3 {
    font-size: 1rem;
    margin-top: 1rem;
    margin-bottom: 0.5rem;
}
.ocm-esign-send-form > * {
    margin-right: 0.5rem;
}
.ocm-esign-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.85em;
    font-weight: 500;
    text-transform: capitalize;
    background-color: var(--surface-2, #eee);
    color: var(--text-2, #333);
}
.ocm-esign-pending,
.ocm-esign-sent     { background-color: #fff3cd; color: #664d03; }
.ocm-esign-viewed,
.ocm-esign-started  { background-color: #cfe2ff; color: #084298; }
.ocm-esign-completed{ background-color: #d1e7dd; color: #0f5132; }
.ocm-esign-declined { background-color: #f8d7da; color: #842029; }
.ocm-esign-expired,
.ocm-esign-unknown  { background-color: #e2e3e5; color: #41464b; }
