/**
 * MDT Central — global stylesheet
 * Extends Bootstrap 5.3
 *
 * Token architecture (UI_STANDARDS.md §4):
 *   1. Brand constants  --mdt-*  — raw palette; never consumed by components.
 *   2. Semantic tokens  --ctl-*  — the ONLY layer components consume.
 *      :root carries Operator Light (the no-attribute default, so standalone
 *      pages that load this file with no theming logic get it free). Five
 *      override blocks build the other sheets, keyed on <html data-style=""
 *      data-bs-theme="">. Block ORDER is load-bearing: the single-attribute
 *      blocks come first, the style+scheme combos after, so a later block
 *      always refines an earlier one at equal-or-higher specificity.
 *   3. Bootstrap bridge — --ctl-* mapped onto Bootstrap 5.3's --bs-* variables
 *      so native components (tooltips, popovers, offcanvas, toasts, modals,
 *      dropdowns) theme correctly with zero per-component dark overrides.
 *
 * Fonts arrive from /css/fonts.css (Oswald variable 200-700, Lato 300/400/700/900).
 */

/* ═══ Layer 1 — Brand constants (components never reference these) ═══ */
:root {
    --mdt-black: #000000;
    --mdt-white: #ffffff;
    /* Grey ramp */
    --mdt-grey-050: #f8f8f8;
    --mdt-grey-100: #f5f5f5;
    --mdt-grey-200: #dcdcdc;
    --mdt-grey-300: #c4c4c4;
    --mdt-grey-400: #a0a0a0;
    --mdt-grey-500: #858585;
    --mdt-grey-600: #5c5c5c;
    --mdt-grey-700: #3a3a3a;
    --mdt-grey-800: #2a2a2a;
    --mdt-grey-900: #161616;
    /* MDT green ramp (brand accent) */
    --mdt-green-100: #e7ecd3;
    --mdt-green-400: #9fbc50;
    --mdt-green-500: #86a33d;
    --mdt-green-600: #6d8730;
    --mdt-green-700: #5a7028;
    /* Refined Blue ramp */
    --mdt-blue-300: #6a9bff;
    --mdt-blue-400: #4b86ff;
    --mdt-blue-500: #2f6fed;
    --mdt-blue-600: #2258c9;
    --mdt-blue-700: #1b46a0;
    /* Status */
    --mdt-red-100: #fbebe9;
    --mdt-red-400: #e05a55;
    --mdt-red-500: #b4231f;
    --mdt-red-900: #381411; /* wash dark enough for red-400 text at 4.5:1 */
    --mdt-amber-100: #fbf3e0;
    --mdt-amber-500: #c98a1a;
    --mdt-amber-600: #93650f; /* 4.5:1 as text on the amber-100 wash */
    --mdt-amber-900: #332508;
}

/* ═══ Layer 2 — Semantic tokens: sheet 1/6, Operator Light (default) ═══ */
:root {
    /* Surfaces (Operator: warm-tinted neutrals) */
    --ctl-bg: #f6f6f4;
    --ctl-bg-alt: var(--mdt-white);
    --ctl-bg-elevated: var(--mdt-white);
    --ctl-bg-inset: var(--mdt-white);
    --ctl-bg-inverse: #141414;
    --ctl-bg-hover: #ecece7;
    /* Text */
    --ctl-fg: #141414;
    --ctl-fg-muted: var(--mdt-grey-600);
    --ctl-fg-subtle: #6e6e6e;
    --ctl-fg-faint: #a8a8a3; /* decorative/disabled ONLY — not AA */
    /* Borders */
    --ctl-border: #d8d8d2;
    --ctl-border-strong: #c8c8c2;
    /* Accent (MDT green; accent-fg per §4.5: black on green in green styles) */
    --ctl-accent: var(--mdt-green-500);
    --ctl-accent-hover: var(--mdt-green-600);
    --ctl-accent-press: var(--mdt-green-700);
    --ctl-accent-fg: #000000;
    --ctl-accent-text: var(--mdt-green-700);
    --ctl-accent-rgb: 134, 163, 61;
    --ctl-link: var(--mdt-green-700);
    --ctl-link-rgb: 90, 112, 40;
    --ctl-link-hover: #47591f;
    --ctl-link-hover-rgb: 71, 89, 31;
    /* RGB triplets of scheme surfaces/text (for rgba() composition + bridge) */
    --ctl-fg-rgb: 20, 20, 20;
    --ctl-bg-rgb: 246, 246, 244;
    --ctl-bg-alt-rgb: 255, 255, 255;
    --ctl-fg-muted-rgb: 92, 92, 92;
    /* Status (§4.3) — base / contrast-safe text / background wash */
    --ctl-danger: var(--mdt-red-500);
    --ctl-danger-text: var(--mdt-red-500);
    --ctl-danger-bg: var(--mdt-red-100);
    --ctl-danger-rgb: 180, 35, 31;
    --ctl-warning: var(--mdt-amber-500);
    --ctl-warning-text: var(--mdt-amber-600);
    --ctl-warning-bg: var(--mdt-amber-100);
    --ctl-warning-rgb: 201, 138, 26;
    --ctl-success: var(--mdt-green-600);
    --ctl-success-text: var(--mdt-green-700);
    --ctl-success-bg: var(--mdt-green-100);
    --ctl-success-rgb: 109, 135, 48;
    --ctl-info: var(--mdt-grey-600);
    --ctl-info-text: var(--mdt-grey-600);
    --ctl-info-bg: #f1f1f1;
    --ctl-info-rgb: 92, 92, 92;
    /* Shadows (dark schemes raise opacity, never geometry) */
    --ctl-shadow: rgba(0, 0, 0, 0.075);
    --ctl-shadow-hover: rgba(0, 0, 0, 0.1);
    /* Workflow status / risk text colors — legacy hues kept distinct (they
       encode different states), lightness dropped so each reads ≥4.5:1 as
       text on every light-sheet surface (worst case Refined Light #eef2f7);
       dark-sheet overrides live in the scheme blocks below. */
    --ctl-status-new: #117888;
    --ctl-status-assigned: #006adb;
    --ctl-status-in-progress: #a95700;
    --ctl-risk-high: #a95700;
    --ctl-risk-medium: #0264f4;

    /* ── Structure scales (§4.4) — style/scheme-invariant except radius ── */
    --ctl-radius: 0px;        /* Industrial/Operator sharp; Refined overrides.
                                 0px (not 0) so Bootstrap's calc() compositions
                                 of --bs-border-radius stay valid arithmetic. */
    --ctl-radius-lg: 0px;
    --ctl-radius-full: 999px;
    /* Spacing — 8pt ramp */
    --ctl-sp-1: 4px;
    --ctl-sp-2: 8px;
    --ctl-sp-3: 12px;
    --ctl-sp-4: 16px;
    --ctl-sp-5: 24px;
    --ctl-sp-6: 32px;
    --ctl-sp-7: 48px;
    --ctl-sp-8: 64px;
    --ctl-sp-9: 96px;
    --ctl-sp-10: 128px;
    /* Z-index scale — no literal z-index elsewhere (existing literals migrate
       in Phase B component rebuilds) */
    --ctl-z-sticky: 100;
    --ctl-z-sidebar: 200;
    --ctl-z-panel: 300;
    --ctl-z-dropdown: 500;
    --ctl-z-modal-backdrop: 900;
    --ctl-z-modal: 1000;
    --ctl-z-toast: 1100;
    --ctl-z-tooltip: 1200;
    /* Motion */
    --ctl-dur-fast: 120ms;
    --ctl-dur: 180ms;
    --ctl-dur-slow: 300ms;
    /* Focus ring — accent at 35% alpha, box-shadow form (§4.4) */
    --ctl-focus-ring: 0 0 0 3px rgba(var(--ctl-accent-rgb), 0.35);
    /* Layout */
    --ctl-sidebar-width: 230px;
    /* Second nav panel (single-layer drilldown, UI_STANDARDS §7) */
    --ctl-sidebar-panel-width: 260px;
    /* Content clamps — settings/form/reading pages; data surfaces run full width */
    --ctl-content-max: 68rem;
    --ctl-content-max-narrow: 46rem;
    --ctl-sidebar-collapsed: 52px;

    /* ── Typography (§2) ── */
    --ctl-font-display: 'Oswald', 'Arial Narrow', sans-serif;
    /* Body face: system stack for UI/table legibility (stakeholder test
       2026-07-20 — Lato read poorly at data densities). Oswald remains the
       display face; Lato stays available via --ctl-font-brand for
       brand-voice surfaces if wanted. */
    --ctl-font-body: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --ctl-font-brand: 'Lato', 'Helvetica Neue', Arial, sans-serif;
    /* 7-step app type scale (§2.1). --ctl-fs-body is the density-varying base
       UI size (§5: 15px comfortable / 13.5px compact). */
    --ctl-fs-display-lg: 40px;
    --ctl-fs-display-md: 28px;
    --ctl-fs-display-sm: 22px;
    --ctl-fs-body-lg: 16px;
    --ctl-fs-body: 15px;
    --ctl-fs-body-sm: 12.5px;
    --ctl-fs-caption: 11px;
    --ctl-lh-tight: 1.02;
    --ctl-lh-snug: 1.15;
    --ctl-lh-normal: 1.5;
    --ctl-lh-relaxed: 1.7;

    /* ── Density (§5) — comfortable defaults; compact overrides below ── */
    --ctl-control-pad-y: 0.475rem;  /* ≈40px control at 15px/1.5 + 1px borders */
    --ctl-control-pad-x: 0.625rem;
    --ctl-fs-label: 13px;
    --ctl-table-cell-pad-y: 10px;
    --ctl-section-pad: var(--ctl-sp-5);
}

/* ═══ Sheet 2/6 — Operator Dark (keys on scheme alone so pages that set
       only data-bs-theme="dark" still theme correctly) ═══ */
html[data-bs-theme="dark"] {
    --ctl-bg: #060606;
    --ctl-bg-alt: #0b0b0b;
    --ctl-bg-elevated: #151515;
    --ctl-bg-inset: #0e0e0c;
    --ctl-bg-inverse: #f6f6f4;
    --ctl-bg-hover: #1b1b19;
    --ctl-fg: var(--mdt-white);
    --ctl-fg-muted: #9a9a9a;
    /* #7d7d7d was 4.44:1 on bg-elevated #151515 (the lightest Operator-dark
       surface) — a hair under the §4.5 binding ≥4.5 rule for label text.
       Lightness-only nudge to #808080 → 4.62:1 (Task 06 precedent). */
    --ctl-fg-subtle: #808080;
    --ctl-fg-faint: var(--mdt-grey-600);
    --ctl-border: #2b2b27;
    --ctl-border-strong: #3a3a36;
    --ctl-accent-hover: var(--mdt-green-400);
    --ctl-accent-press: var(--mdt-green-600);
    --ctl-accent-text: var(--mdt-green-400);
    --ctl-link: var(--mdt-green-400);
    --ctl-link-rgb: 159, 188, 80;
    --ctl-link-hover: #b4cf6b;
    --ctl-link-hover-rgb: 180, 207, 107;
    --ctl-fg-rgb: 255, 255, 255;
    --ctl-bg-rgb: 6, 6, 6;
    --ctl-bg-alt-rgb: 11, 11, 11;
    --ctl-fg-muted-rgb: 154, 154, 154;
    --ctl-danger-text: var(--mdt-red-400);
    --ctl-danger-bg: var(--mdt-red-900);
    --ctl-warning-text: var(--mdt-amber-500);
    --ctl-warning-bg: var(--mdt-amber-900);
    --ctl-success-text: var(--mdt-green-400);
    --ctl-success-bg: #1c2410;
    --ctl-info: #9a9a9a;
    --ctl-info-text: #9a9a9a;
    --ctl-info-bg: #1e1e1e;
    --ctl-info-rgb: 154, 154, 154;
    --ctl-shadow: rgba(0, 0, 0, 0.45);
    --ctl-shadow-hover: rgba(0, 0, 0, 0.55);
    --ctl-status-new: #22d3ee;
    --ctl-status-assigned: #60a5fa;
    --ctl-status-in-progress: #fb923c;
    --ctl-risk-high: #fb923c;
    --ctl-risk-medium: #60a5fa;
}

/* ═══ Sheet 3/6 — Refined Blue Light ═══ */
html[data-style="refined"] {
    --ctl-bg: #eef2f7;
    --ctl-bg-alt: var(--mdt-white);
    --ctl-bg-elevated: var(--mdt-white);
    --ctl-bg-inset: #f5f8fb;
    --ctl-bg-inverse: #0b1a2e;
    --ctl-bg-hover: #e2e9f2;
    --ctl-fg: #0b1a2e;
    --ctl-fg-muted: #5a6b80;
    --ctl-fg-subtle: #5a6b80;
    --ctl-fg-faint: #9fb0c2;
    --ctl-border: #dbe2ea;
    --ctl-border-strong: #d3dde8;
    --ctl-accent: var(--mdt-blue-500);
    --ctl-accent-hover: var(--mdt-blue-600);
    --ctl-accent-press: var(--mdt-blue-700);
    --ctl-accent-fg: #ffffff; /* §4.5: white-on-blue passes 4.55:1 */
    /* accent-text decoupled from the fill (same pattern as the green styles):
       blue-500 reads 4.05:1 on the tinted page bg — blue-600 clears 4.5 on
       every Refined Light surface (Phase F certification). */
    --ctl-accent-text: var(--mdt-blue-600);
    --ctl-accent-rgb: 47, 111, 237;
    --ctl-link: var(--mdt-blue-600);
    --ctl-link-rgb: 34, 88, 201;
    --ctl-link-hover: var(--mdt-blue-700);
    --ctl-link-hover-rgb: 27, 70, 160;
    --ctl-fg-rgb: 11, 26, 46;
    --ctl-bg-rgb: 238, 242, 247;
    --ctl-bg-alt-rgb: 255, 255, 255;
    --ctl-fg-muted-rgb: 90, 107, 128;
    --ctl-radius: 3px;
    --ctl-radius-lg: 6px;
}

/* ═══ Sheet 4/6 — Refined Blue Dark ═══ */
html[data-style="refined"][data-bs-theme="dark"] {
    --ctl-bg: #0a1626;
    --ctl-bg-alt: #0c1827;
    --ctl-bg-elevated: #0f2138;
    --ctl-bg-inset: #0a1727;
    --ctl-bg-inverse: #eef2f7;
    --ctl-bg-hover: #13273e;
    --ctl-fg: #eaf1f8;
    --ctl-fg-muted: #8aa4c0;
    --ctl-fg-subtle: #7e96b0;
    --ctl-fg-faint: #5c7799;
    --ctl-border: #1e3550;
    --ctl-border-strong: #244260;
    --ctl-accent-hover: var(--mdt-blue-400);
    --ctl-accent-press: var(--mdt-blue-300);
    --ctl-accent-text: var(--mdt-blue-400);
    --ctl-link: var(--mdt-blue-400);
    --ctl-link-rgb: 75, 134, 255;
    --ctl-link-hover: var(--mdt-blue-300);
    --ctl-link-hover-rgb: 106, 155, 255;
    --ctl-fg-rgb: 234, 241, 248;
    --ctl-bg-rgb: 10, 22, 38;
    --ctl-bg-alt-rgb: 12, 24, 39;
    --ctl-fg-muted-rgb: 138, 164, 192;
}

/* ═══ Sheet 5/6 — Industrial Light ═══ */
html[data-style="industrial"] {
    --ctl-bg: var(--mdt-white);
    --ctl-bg-alt: var(--mdt-grey-100);
    --ctl-bg-elevated: var(--mdt-white);
    --ctl-bg-inset: var(--mdt-grey-050);
    --ctl-bg-inverse: #111111;
    --ctl-bg-hover: #eeeeee;
    --ctl-fg: #111111;
    --ctl-fg-muted: var(--mdt-grey-600);
    --ctl-fg-subtle: #6e6e6e;
    --ctl-fg-faint: var(--mdt-grey-400);
    --ctl-border: var(--mdt-grey-200);
    --ctl-border-strong: var(--mdt-grey-300);
    --ctl-fg-rgb: 17, 17, 17;
    --ctl-bg-rgb: 255, 255, 255;
    --ctl-bg-alt-rgb: 245, 245, 245;
}

/* ═══ Sheet 6/6 — Industrial Dark ═══ */
html[data-style="industrial"][data-bs-theme="dark"] {
    --ctl-bg: var(--mdt-black);
    --ctl-bg-alt: #0c0c0c;
    --ctl-bg-elevated: var(--mdt-grey-900);
    --ctl-bg-inset: #0d0d0d;
    --ctl-bg-inverse: var(--mdt-grey-100);
    --ctl-bg-hover: #1d1d1d;
    --ctl-fg: var(--mdt-white);
    --ctl-fg-muted: #9a9a9a;
    --ctl-fg-subtle: var(--mdt-grey-500);
    --ctl-fg-faint: var(--mdt-grey-600);
    --ctl-border: var(--mdt-grey-800);
    --ctl-border-strong: var(--mdt-grey-700);
    --ctl-accent-text: var(--mdt-green-500);
    --ctl-fg-rgb: 255, 255, 255;
    --ctl-bg-rgb: 0, 0, 0;
    --ctl-bg-alt-rgb: 12, 12, 12;
}

/* ═══ Density — compact (§5). Comfortable defaults live in :root. ═══ */
html[data-density="compact"] {
    --ctl-fs-body: 13.5px;
    --ctl-control-pad-y: 0.25rem;   /* ≈30px control — today's ultra-compact */
    --ctl-control-pad-x: 0.5rem;
    --ctl-fs-label: 12px;
    --ctl-table-cell-pad-y: 4px;
    --ctl-section-pad: var(--ctl-sp-3);
}

/* ═══ Layer 3 — Bootstrap 5.3 bridge ═══
   One block, resolved per-element against the cascaded --ctl values, so all
   six sheets flow through automatically. The html[data-bs-theme="dark"]
   selector is included to out-rank Bootstrap's own [data-bs-theme=dark]
   variable block regardless of stylesheet order. */
:root,
html[data-bs-theme="dark"] {
    --bs-body-bg: var(--ctl-bg);
    --bs-body-bg-rgb: var(--ctl-bg-rgb);
    --bs-body-color: var(--ctl-fg);
    --bs-body-color-rgb: var(--ctl-fg-rgb);
    --bs-body-font-family: var(--ctl-font-body);
    --bs-body-font-size: var(--ctl-fs-body);
    --bs-emphasis-color: var(--ctl-fg);
    --bs-emphasis-color-rgb: var(--ctl-fg-rgb);
    --bs-heading-color: var(--ctl-fg);
    --bs-secondary-color: var(--ctl-fg-muted);
    --bs-secondary-bg: var(--ctl-bg-alt);
    --bs-tertiary-color: var(--ctl-fg-subtle);
    --bs-tertiary-bg: var(--ctl-bg-alt);
    --bs-border-color: var(--ctl-border);
    --bs-border-radius: var(--ctl-radius);
    --bs-border-radius-sm: var(--ctl-radius);
    --bs-border-radius-lg: var(--ctl-radius-lg);
    --bs-border-radius-xl: var(--ctl-radius-lg);
    --bs-link-color: var(--ctl-link);
    --bs-link-color-rgb: var(--ctl-link-rgb);
    --bs-link-hover-color: var(--ctl-link-hover);
    --bs-link-hover-color-rgb: var(--ctl-link-hover-rgb);
    --bs-code-color: var(--ctl-accent-text);
    --bs-focus-ring-color: rgba(var(--ctl-accent-rgb), 0.35);
    /* Theme colors + utility triplets (.bg-*, .text-*, rgba washes) */
    --bs-primary: var(--ctl-accent);
    --bs-primary-rgb: var(--ctl-accent-rgb);
    --bs-secondary: var(--ctl-fg-muted);
    --bs-secondary-rgb: var(--ctl-fg-muted-rgb);
    --bs-success: var(--ctl-success);
    --bs-success-rgb: var(--ctl-success-rgb);
    --bs-danger: var(--ctl-danger);
    --bs-danger-rgb: var(--ctl-danger-rgb);
    --bs-warning: var(--ctl-warning);
    --bs-warning-rgb: var(--ctl-warning-rgb);
    --bs-info: var(--ctl-info);
    --bs-info-rgb: var(--ctl-info-rgb);
    --bs-light-rgb: var(--ctl-bg-alt-rgb); /* .bg-light → bg-alt in every sheet */
    /* Subtle system (alerts, .text-bg-*, list-group variants) */
    --bs-success-bg-subtle: var(--ctl-success-bg);
    --bs-success-text-emphasis: var(--ctl-success-text);
    --bs-success-border-subtle: var(--ctl-success-bg);
    --bs-danger-bg-subtle: var(--ctl-danger-bg);
    --bs-danger-text-emphasis: var(--ctl-danger-text);
    --bs-danger-border-subtle: var(--ctl-danger-bg);
    --bs-warning-bg-subtle: var(--ctl-warning-bg);
    --bs-warning-text-emphasis: var(--ctl-warning-text);
    --bs-warning-border-subtle: var(--ctl-warning-bg);
    --bs-info-bg-subtle: var(--ctl-info-bg);
    --bs-info-text-emphasis: var(--ctl-info-text);
    --bs-info-border-subtle: var(--ctl-info-bg);
}

/* Bootstrap components whose compiled vars are literals (not global-var
   references) — re-pointed at semantic tokens once, valid for all six sheets.
   These replace the deleted body.theme-dark per-component patches. */
.dropdown-menu {
    --bs-dropdown-bg: var(--ctl-bg-elevated);
    --bs-dropdown-color: var(--ctl-fg);
    --bs-dropdown-border-color: var(--ctl-border);
    --bs-dropdown-link-color: var(--ctl-fg);
    --bs-dropdown-link-hover-color: var(--ctl-fg);
    --bs-dropdown-link-hover-bg: var(--ctl-bg-hover);
    --bs-dropdown-link-active-color: var(--ctl-accent-fg);
    --bs-dropdown-link-active-bg: var(--ctl-accent);
    --bs-dropdown-divider-bg: var(--ctl-border);
    --bs-dropdown-header-color: var(--ctl-fg-subtle);
}

.modal {
    --bs-modal-bg: var(--ctl-bg-elevated);
    --bs-modal-color: var(--ctl-fg);
    --bs-modal-border-color: var(--ctl-border);
    --bs-modal-header-border-color: var(--ctl-border);
    --bs-modal-footer-border-color: var(--ctl-border);
}

.list-group {
    --bs-list-group-bg: var(--ctl-bg-elevated);
    --bs-list-group-color: var(--ctl-fg);
    --bs-list-group-border-color: var(--ctl-border);
    --bs-list-group-action-color: var(--ctl-fg);
    --bs-list-group-action-hover-color: var(--ctl-fg);
    --bs-list-group-action-hover-bg: var(--ctl-bg-hover);
    --bs-list-group-action-active-color: var(--ctl-fg);
    --bs-list-group-action-active-bg: var(--ctl-bg-hover);
    --bs-list-group-active-bg: var(--ctl-accent);
    --bs-list-group-active-border-color: var(--ctl-accent);
    --bs-list-group-active-color: var(--ctl-accent-fg);
    --bs-list-group-disabled-color: var(--ctl-fg-faint);
    --bs-list-group-disabled-bg: var(--ctl-bg-elevated);
}

.pagination {
    --bs-pagination-bg: var(--ctl-bg-elevated);
    --bs-pagination-color: var(--ctl-fg);
    --bs-pagination-border-color: var(--ctl-border);
    --bs-pagination-hover-bg: var(--ctl-bg-hover);
    --bs-pagination-hover-color: var(--ctl-fg);
    --bs-pagination-hover-border-color: var(--ctl-border);
    --bs-pagination-focus-bg: var(--ctl-bg-hover);
    --bs-pagination-focus-color: var(--ctl-fg);
    --bs-pagination-focus-box-shadow: var(--ctl-focus-ring);
    --bs-pagination-active-bg: var(--ctl-accent);
    --bs-pagination-active-border-color: var(--ctl-accent);
    --bs-pagination-active-color: var(--ctl-accent-fg);
    --bs-pagination-disabled-bg: var(--ctl-bg-elevated);
    --bs-pagination-disabled-color: var(--ctl-fg-faint);
    --bs-pagination-disabled-border-color: var(--ctl-border);
}

.table {
    /* Transparent so card surfaces (and row-hover set on <tr>) show through;
       sticky headers and pinned columns carry their own opaque backgrounds. */
    --bs-table-bg: transparent;
    --bs-table-color: var(--ctl-fg);
    --bs-table-border-color: var(--ctl-border);
    --bs-table-striped-bg: var(--ctl-bg-alt);
    --bs-table-striped-color: var(--ctl-fg);
    --bs-table-hover-bg: var(--ctl-bg-hover);
    --bs-table-hover-color: var(--ctl-fg);
}

.table-light {
    --bs-table-bg: var(--ctl-bg-alt);
    --bs-table-color: var(--ctl-fg);
    --bs-table-border-color: var(--ctl-border);
}

.nav-tabs {
    --bs-nav-link-color: var(--ctl-fg-muted);
    --bs-nav-link-hover-color: var(--ctl-fg);
    --bs-nav-tabs-border-color: var(--ctl-border);
    --bs-nav-tabs-link-active-color: var(--ctl-accent-text);
    --bs-nav-tabs-link-active-bg: var(--ctl-bg-elevated);
    --bs-nav-tabs-link-active-border-color: var(--ctl-border) var(--ctl-border) var(--ctl-bg-elevated);
    --bs-nav-tabs-link-hover-border-color: var(--ctl-bg-hover) var(--ctl-bg-hover) var(--ctl-border);
}

/* Primary button — accent fill with contrast-verified face (§4.5: black on
   brand green 7.32:1 in Industrial/Operator; white on blue 4.55:1 in Refined). */
.btn-primary {
    --bs-btn-color: var(--ctl-accent-fg);
    --bs-btn-bg: var(--ctl-accent);
    --bs-btn-border-color: var(--ctl-accent);
    --bs-btn-hover-color: var(--ctl-accent-fg);
    --bs-btn-hover-bg: var(--ctl-accent-hover);
    --bs-btn-hover-border-color: var(--ctl-accent-hover);
    --bs-btn-active-color: var(--ctl-accent-fg);
    --bs-btn-active-bg: var(--ctl-accent-press);
    --bs-btn-active-border-color: var(--ctl-accent-press);
    --bs-btn-disabled-color: var(--ctl-accent-fg);
    --bs-btn-disabled-bg: var(--ctl-accent);
    --bs-btn-disabled-border-color: var(--ctl-accent);
    --bs-btn-focus-shadow-rgb: var(--ctl-accent-rgb);
}

.btn-outline-primary {
    --bs-btn-color: var(--ctl-accent-text);
    --bs-btn-border-color: var(--ctl-accent);
    --bs-btn-hover-color: var(--ctl-accent-fg);
    --bs-btn-hover-bg: var(--ctl-accent);
    --bs-btn-hover-border-color: var(--ctl-accent);
    --bs-btn-active-color: var(--ctl-accent-fg);
    --bs-btn-active-bg: var(--ctl-accent-press);
    --bs-btn-active-border-color: var(--ctl-accent-press);
    --bs-btn-disabled-color: var(--ctl-fg-faint);
    --bs-btn-disabled-border-color: var(--ctl-border-strong);
    --bs-btn-focus-shadow-rgb: var(--ctl-accent-rgb);
}

/* Secondary per §6: 1px border-strong outline, transparent fill */
.btn-outline-secondary {
    --bs-btn-color: var(--ctl-fg-muted);
    --bs-btn-border-color: var(--ctl-border-strong);
    --bs-btn-hover-color: var(--ctl-fg);
    --bs-btn-hover-bg: var(--ctl-bg-hover);
    --bs-btn-hover-border-color: var(--ctl-border-strong);
    --bs-btn-active-color: var(--ctl-fg);
    --bs-btn-active-bg: var(--ctl-bg-hover);
    --bs-btn-active-border-color: var(--ctl-border-strong);
    --bs-btn-disabled-color: var(--ctl-fg-faint);
    --bs-btn-disabled-border-color: var(--ctl-border);
}

.btn-outline-danger {
    --bs-btn-color: var(--ctl-danger-text);
    --bs-btn-border-color: var(--ctl-danger);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--ctl-danger);
    --bs-btn-hover-border-color: var(--ctl-danger);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: var(--ctl-danger);
    --bs-btn-active-border-color: var(--ctl-danger);
    --bs-btn-disabled-color: var(--ctl-fg-faint);
    --bs-btn-disabled-border-color: var(--ctl-border-strong);
    --bs-btn-focus-shadow-rgb: var(--ctl-danger-rgb);
}

.btn-danger {
    --bs-btn-bg: var(--ctl-danger);
    --bs-btn-border-color: var(--ctl-danger);
    --bs-btn-hover-bg: color-mix(in srgb, var(--ctl-danger) 85%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--ctl-danger) 85%, #000);
    --bs-btn-active-bg: color-mix(in srgb, var(--ctl-danger) 75%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--ctl-danger) 75%, #000);
    --bs-btn-disabled-bg: var(--ctl-danger);
    --bs-btn-disabled-border-color: var(--ctl-danger);
    --bs-btn-focus-shadow-rgb: var(--ctl-danger-rgb);
}

.btn-warning {
    --bs-btn-color: #000000;
    --bs-btn-bg: var(--ctl-warning);
    --bs-btn-border-color: var(--ctl-warning);
    --bs-btn-hover-color: #000000;
    --bs-btn-hover-bg: color-mix(in srgb, var(--ctl-warning) 85%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--ctl-warning) 85%, #000);
    --bs-btn-active-color: #000000;
    --bs-btn-active-bg: color-mix(in srgb, var(--ctl-warning) 75%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--ctl-warning) 75%, #000);
    --bs-btn-disabled-color: #000000;
    --bs-btn-disabled-bg: var(--ctl-warning);
    --bs-btn-disabled-border-color: var(--ctl-warning);
    --bs-btn-focus-shadow-rgb: var(--ctl-warning-rgb);
}

/* ═══ Typography base (§2) ═══ */
/* Display utilities — Oswald caps. Page headers adopt these in Phase B;
   h1-h6 are deliberately NOT restyled globally here. */
.ctl-display-lg,
.ctl-display-md,
.ctl-display-sm {
    font-family: var(--ctl-font-display);
    font-weight: 700;
    line-height: var(--ctl-lh-tight);
    text-transform: uppercase;
    letter-spacing: -0.025em;
}
.ctl-display-lg { font-size: var(--ctl-fs-display-lg); }
.ctl-display-md { font-size: var(--ctl-fs-display-md); }
.ctl-display-sm { font-size: var(--ctl-fs-display-sm); }

/* Caption scale — Lato 700 uppercase labels */
.ctl-caption {
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-caption);
    font-weight: 700;
    line-height: var(--ctl-lh-snug);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* Content width clamps (UI_STANDARDS §8.1). Data surfaces (lists,
   dashboards, canvases) run full width; settings/form/reading pages clamp
   so large monitors don't stretch them into unreadable sprawl. */
.ctl-page-clamp {
    max-width: var(--ctl-content-max, 68rem);
    margin-inline: auto;
}
.ctl-page-clamp-narrow {
    max-width: var(--ctl-content-max-narrow, 46rem);
    margin-inline: auto;
}

/* ═══ Focus visibility (§4.4 / §9) — always visible on :focus-visible ═══ */
:focus-visible {
    outline: 3px solid rgba(var(--ctl-accent-rgb), 0.35);
    outline-offset: 1px;
}

/* Controls that already render the ring as a box-shadow (accent border +
   --ctl-focus-ring) suppress the outline — replacement present, not removed. */
.form-control:focus-visible,
.form-select:focus-visible,
.ai-chat-input:focus-visible {
    outline: none;
}

/* ═══ Reduced motion (§4.4) — non-essential motion collapses to 0 ═══ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Lock viewport — all scrolling handled by inner flex containers */
html, body {
    height: 100%;
    overflow: hidden;
    margin: 0;
}

body {
    background-color: var(--ctl-bg);
    color: var(--ctl-fg);
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-body);
}

/* Email preview frame — always-light iframe inside dark cards */
.email-preview-frame {
    background: #ffffff;
    border: 1px solid var(--ctl-border);
    border-radius: 6px;
    overflow: hidden;
    max-height: 500px;
    overflow-y: auto;
}
/* shortcut: scheme-keyed override — the frame content is pinned light (email
   renders on white), so the dark schemes need a stronger seam than tokens can
   express; revisit if the preview ever themes. */
html[data-bs-theme="dark"] .email-preview-frame {
    border-color: var(--ctl-border-strong);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}

/* Impersonation banner — solid danger fill, white text (≥5.9:1 in every sheet) */
.impersonation-banner {
    background: var(--ctl-danger);
    color: #fff;
    text-align: center;
    padding: 0.3rem 1rem;
    font-size: 0.8rem;
    position: sticky;
    top: 0;
    z-index: 9999; /* z literal kept: security banner must top everything, incl. Bootstrap modals and the --ctl-z scale */
}
.impersonation-banner a {
    color: #fff;
    text-decoration: underline;
}

/* Login page */
.login-container {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--ctl-bg) 0%, var(--ctl-bg-alt) 100%);
}

.login-card {
    width: 100%;
    max-width: 400px;
    border: none;
    border-radius: 1rem;
    box-shadow: 0 0.5rem 1rem var(--ctl-shadow-hover);
}

.login-card .card-header {
    background: transparent;
    border-bottom: none;
    padding-top: 2rem;
    text-align: center;
}

.login-logo {
    height: 44px;
    width: auto;
}

.login-core-label {
    margin-top: 0.4rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.5em;
    text-indent: 0.5em; /* re-center: compensates the trailing letter-space */
    color: var(--ctl-fg-muted);
}

.login-card .card-body {
    padding: 2rem;
}

.login-divider {
    display: flex;
    align-items: center;
    margin: 1.25rem 0;
    color: var(--ctl-fg-muted);
    font-size: 0.85rem;
}

.login-divider::before,
.login-divider::after {
    content: '';
    flex: 1;
    border-top: 1px solid var(--ctl-border);
}

.login-divider span {
    padding: 0 0.75rem;
}

/* Sidebar layout */
.wrapper {
    display: flex;
    width: 100%;
    height: 100%;
}

.sidebar {
    width: var(--ctl-sidebar-width);
    height: 100vh;
    background: #212529;
    position: fixed;
    left: 0;
    top: 0;
    z-index: var(--ctl-z-sidebar);
    transition: width 0.2s ease;
    display: flex;
    flex-direction: column;
    overflow: visible;
}

/* Sidebar header with toggle + brand */
.sidebar-header {
    display: flex;
    align-items: center;
    padding: 0.75rem;
    background: #1a1e21;
    gap: 0.5rem;
    min-height: 3.25rem;
}

.sidebar-toggle-btn {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.8);
    font-size: 1.25rem;
    padding: 0.25rem 0.4rem;
    cursor: pointer;
    border-radius: 0.25rem;
    flex-shrink: 0;
    line-height: 1;
}

.sidebar-toggle-btn:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.sidebar-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    white-space: nowrap;
    overflow: hidden;
    transition: opacity 0.2s;
    /* Now a real <a href="/dashboard"> (home button) — strip link chrome so the
       lockup looks identical to the old <span>. */
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.sidebar-brand .brand-logo {
    height: 24px;
    width: auto;
    display: block;
}

/* Mark-only variant shown when the sidebar is collapsed */
.sidebar-brand .brand-mark {
    display: none;
}

.sidebar-brand .brand-core {
    font-size: 0.6rem;
    font-weight: 600;
    letter-spacing: 0.45em;
    color: rgba(255, 255, 255, 0.55);
    margin-top: 0.3rem;
    line-height: 1;
}

/* Sidebar search */
.sidebar-search {
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.sidebar-search-input {
    display: flex;
    align-items: center;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 0.3rem;
    padding: 0.3rem 0.5rem;
    gap: 0.4rem;
}

.sidebar-search-input i {
    color: rgba(255, 255, 255, 0.4);
    font-size: 0.8rem;
    flex-shrink: 0;
}

.sidebar-search-input input {
    background: none;
    border: none;
    /* no outline:none — the global :focus-visible ring is the focus indicator */
    color: #fff;
    font-size: 0.8rem;
    width: 100%;
}

.sidebar-search-input input::placeholder {
    color: rgba(255, 255, 255, 0.35);
}

.sidebar-search-results {
    margin-top: 0.35rem;
    max-height: 250px;
    overflow-y: auto;
}

.sidebar-search-result {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.5rem;
    color: rgba(255, 255, 255, 0.8);
    text-decoration: none;
    font-size: 0.8rem;
    border-radius: 0.2rem;
}

.sidebar-search-result:hover,
.sidebar-search-result.active {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.sidebar-search-result i {
    font-size: 0.85rem;
    width: 1.1rem;
    text-align: center;
    flex-shrink: 0;
    opacity: 0.6;
}

.sidebar-search-path {
    display: block;
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.35);
    margin-top: 0.1rem;
}

.sidebar-search-empty {
    padding: 0.5rem;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.75rem;
    font-style: italic;
}

/* Hide search when sidebar collapsed */
.sidebar.collapsed .sidebar-search {
    display: none;
}

/* Sidebar menu area — the nav region that hosts the stacked rail layers.
   overflow:hidden so the admin layer is clipped while parked below and each
   rail owns its own vertical scroll. */
.sidebar-menu {
    flex: 1;
    min-height: 0;
    position: relative;
    overflow: hidden;
}

/* Sidebar navigation rail — both rails are absolute layers filling the nav
   region. The main rail sits at rest; the admin rail slides UP from the bottom
   to cover it (main stays put underneath — 'on top of', never 'replacing'). */
.sidebar-nav {
    padding: 0.5rem 0;
    margin: 0;
    position: absolute;
    inset: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

/* Admin rail: parked one full height below at rest, riding above the main rail
   when raised. Reads as a SHEET sliding over the main nav (stakeholder
   direction 2026-07-21: 'on top of, not replacing'): a step-lighter solid
   background, accent top edge, and upward shadow separate the two layers
   during and after the slide. */
.sidebar-nav[data-nav="admin"] {
    transform: translateY(100%);
    z-index: 2;
    background: #2a2f34;
    border-top: 2px solid var(--ctl-accent);
    box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.45);
}
.sidebar[data-nav-mode="admin"] .sidebar-nav[data-nav="admin"] {
    transform: translateY(0);
}

/* The covered main rail dims while the admin sheet is up — sells the layering
   and keeps the underlying nav from visually competing with the sheet. */
.sidebar-nav[data-nav="main"] {
    transition: filter var(--ctl-dur) ease;
}
.sidebar[data-nav-mode="admin"] .sidebar-nav[data-nav="main"] {
    filter: brightness(0.55);
}

/* Slide only on user toggles. .nav-anim is added by JS after first paint, so a
   direct admin-URL load renders with the layer already up and no animation.
   prefers-reduced-motion (global rule) zeroes the duration → jump-cut. */
.sidebar.nav-anim .sidebar-nav {
    transition: transform var(--ctl-dur) ease;
}

/* nav-group toggles are real <button>s — reset the UA chrome so they read as
   nav-links (accessibility: buttons carry aria-expanded/aria-controls). */
.sidebar .nav-link {
    color: rgba(255, 255, 255, 0.8);
    padding: 0.65rem 0.75rem;
    border-left: 3px solid transparent;
    transition: color 0.15s, background 0.15s;
    display: flex;
    align-items: center;
    white-space: nowrap;
    text-decoration: none;
    width: 100%;
    background: none;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    text-align: left;
    font: inherit;
    cursor: pointer;
}

/* An open group's rail entry wears the hover treatment for as long as its panel
   is open (shared declarations — .nav-group-open reuses :hover exactly). This is
   IN ADDITION to .group-active (active-page accent), not a replacement. */
.sidebar .nav-link:hover,
.nav-group.nav-group-open > .nav-group-toggle {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
    border-left-color: var(--ctl-accent);
}

.sidebar .nav-link.active {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
    border-left-color: var(--ctl-accent);
}

.sidebar .nav-link > i:first-child {
    width: 1.5rem;
    text-align: center;
    flex-shrink: 0;
    font-size: 1.1rem;
}

.nav-label {
    margin-left: 0.75rem;
    overflow: hidden;
    transition: opacity 0.2s;
}

/* Group active indicator — accent on left when a child page is active */
.nav-group.group-active > .nav-group-toggle {
    border-left-color: var(--ctl-accent);
    color: #fff;
}

/* Group chevron — the "opens a panel" affordance. Sized/weighted to be
   clearly legible on the dark rail (stakeholder finding 2026-07-21: at
   0.65rem/0.6 it read as absent); full strength + 90deg turn while the
   group's panel is open. */
.flyout-chevron {
    font-size: 0.8rem;
    margin-left: auto;
    transition: transform 0.2s, opacity 0.2s;
    opacity: 0.85;
}
.sidebar .nav-link:hover .flyout-chevron,
.nav-group.nav-group-open > .nav-group-toggle .flyout-chevron {
    opacity: 1;
}

/* Hidden data source for drill-down — never visible */
.sidebar-flyout {
    display: none !important;
}

/* Sidebar footer */
.sidebar-footer {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding: 0.25rem 0;
}

.sidebar-footer .nav-link {
    color: rgba(255, 255, 255, 0.8);
    padding: 0.65rem 0.75rem;
    display: flex;
    align-items: center;
    cursor: pointer;
}

.sidebar-footer .nav-link:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.sidebar-footer .nav-link i {
    width: 1.5rem;
    text-align: center;
    flex-shrink: 0;
    font-size: 1.1rem;
}

/* Collapsed state */
.sidebar.collapsed {
    width: var(--ctl-sidebar-collapsed);
}

.sidebar.collapsed .nav-label,
.sidebar.collapsed .flyout-chevron {
    opacity: 0;
    width: 0;
    margin: 0;
    overflow: hidden;
}

/* Collapsed header stacks the toggle above the MDT mark */
.sidebar.collapsed .sidebar-header {
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

.sidebar.collapsed .brand-logo,
.sidebar.collapsed .brand-core {
    display: none;
}

.sidebar.collapsed .brand-mark {
    display: block;
    height: 22px;
    width: auto;
}

.sidebar.collapsed .nav-link {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
    border-left-width: 0;
}

.sidebar.collapsed .sidebar-footer .nav-link {
    justify-content: center;
}

/* Main content */
.main-content {
    margin-left: var(--ctl-sidebar-width);
    width: calc(100% - var(--ctl-sidebar-width));
    height: 100%;
    display: flex;
    flex-direction: column;
    transition: margin-left 0.2s ease, width 0.2s ease;
    overflow: hidden;
    position: relative; /* positioning context for the swap-engine progress bar */
}

/* Swap-engine loading affordance (§6.1): thin accent bar pinned to the top of
   the content pane. app.js creeps it to ~75% during the request, snaps to 100%,
   then fades it out via .is-active toggling. */
.uee-nav-progress {
    position: absolute;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    background: var(--ctl-accent);
    z-index: var(--ctl-z-sticky);
    opacity: 0;
    pointer-events: none;
    transition: width 0.2s ease, opacity 0.3s ease;
}
.uee-nav-progress.is-active {
    opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
    .uee-nav-progress { transition: opacity 0.15s linear; }
}

.sidebar.collapsed ~ .main-content {
    margin-left: var(--ctl-sidebar-collapsed);
    width: calc(100% - var(--ctl-sidebar-collapsed));
}

/* The second panel is ALWAYS an overlay (UI_STANDARDS §8.2, stakeholder review
   2026-07-21): it floats over the content at every tier and never resizes or
   reflows the main page. No content-push rule at any breakpoint. On desktop the
   overlay carries no dim backdrop (persistent-chrome-adjacent) — the shadow +
   border on .sidebar-panel is the only separation; JS keeps the backdrop for
   the collapsed / tablet / phone tiers that already had it. */

.top-navbar {
    background: var(--ctl-bg-elevated);
    border-bottom: 1px solid var(--ctl-border);
    padding: 0.4rem 1rem;
    flex-shrink: 0;
    color: var(--ctl-fg);
}

/* Hierarchy breadcrumb */
.page-breadcrumb {
    display: flex;
    align-items: center;
    font-size: 0.8rem;
    gap: 0.25rem;
    min-width: 0;
    overflow: hidden;
}

.page-breadcrumb a,
.breadcrumb-item,
.breadcrumb-item a {
    color: var(--ctl-fg-muted);
    text-decoration: none;
    white-space: nowrap;
}

.page-breadcrumb a:hover {
    color: var(--ctl-accent-text);
}

.breadcrumb-sep,
.breadcrumb-separator {
    color: var(--ctl-fg-faint);
    flex-shrink: 0;
}

.breadcrumb-current {
    color: var(--ctl-fg);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.help-link {
    color: var(--ctl-fg-muted);
    font-size: 0.85rem;
    margin-left: 0.5rem;
    text-decoration: none;
    opacity: 0.6;
    transition: opacity 0.15s, color 0.15s;
}
.help-link:hover {
    color: var(--ctl-link);
    opacity: 1;
}

.navbar-user {
    font-size: 0.8rem;
    white-space: nowrap;
}

/* Navigation history dropdown */
.nav-history-wrapper {
    position: relative;
}

.nav-history-dropdown {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    min-width: 280px;
    max-width: min(360px, 92vw); /* §8 phone clamp — never wider than the viewport */
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow-hover);
    z-index: var(--ctl-z-dropdown);
    padding: 0.25rem 0;
}

.nav-history-wrapper.open .nav-history-dropdown {
    display: block;
}

.nav-history-title {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ctl-fg-muted);
    padding: 0.25rem 0.75rem;
}

.nav-history-item {
    display: block;
    padding: 0.3rem 0.75rem;
    text-decoration: none;
    color: var(--ctl-fg);
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-history-item:hover {
    background: var(--ctl-bg-hover);
    color: var(--ctl-accent-text);
}

.nav-history-crumb {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-history-empty {
    display: block;
    padding: 0.5rem 0.75rem;
    color: var(--ctl-fg-muted);
    font-size: 0.8rem;
    font-style: italic;
}

/* ── Ticket Presence ── */
.presence-banner {
    background: var(--ctl-info-bg); color: var(--ctl-info-text); font-size: 0.78rem;
    padding: 0.35rem 0.75rem; border-bottom: 1px solid var(--ctl-border);
}

/* ── AI Chat Panel ── */
/* z-index 1040 sits the panel above page content but BELOW Bootstrap's
   modal backdrop (1050) and modal (1055). When a modal opens it correctly
   blocks interaction with everything including the panel — which is what
   modal semantics require. AI's own confirmation flow uses inline UI
   (ConfirmationService), not Bootstrap modals, so this doesn't break the
   HIGH-risk OTP path. Closes gap.md #27.
   z literal intentionally kept — Bootstrap-stacking-order-sensitive. */
.ai-chat-panel {
    position: fixed; right: 0; top: 0; bottom: 0;
    width: var(--ai-panel-default-width, 400px);
    min-width: 300px; max-width: 80vw;
    transform: translateX(100%);
    background: var(--ctl-bg-elevated); border-left: 1px solid var(--ctl-border);
    box-shadow: -4px 0 16px var(--ctl-shadow-hover); z-index: 1040;
    display: flex; flex-direction: column;
    transition: transform 0.25s ease;
}
.ai-chat-panel.open { transform: translateX(0); }
.ai-chat-panel.resizing { transition: none; user-select: none; }

/* Mobile / narrow viewport — full-screen overlay, no resize, no pin.
   The breakpoint custom property is set inline from sys_setting ai.ui.mobile_breakpoint_px
   so admins can move it in /settings/system without a CSS rebuild. */
.ai-chat-panel.mobile-fullscreen {
    width: 100vw !important;
    max-width: 100vw !important;
    min-width: 0 !important;
    border-left: none;
    box-shadow: none;
}
.ai-chat-panel.mobile-fullscreen .ai-chat-resize,
.ai-chat-panel.mobile-fullscreen #aiChatPinBtn { display: none !important; }
.ai-chat-panel.mobile-fullscreen .ai-chat-input { font-size: 16px; /* iOS zoom-lock */ }
/* Touch targets — Apple HIG minimum 44pt / Google Material 48dp. Without
   these rules the .ai-chat-btn header buttons render ~22px tall, the
   .ai-chat-send button ~30px — both below the threshold for reliable
   finger tapping. Mobile-only so desktop sizing stays compact. Closes
   gap.md #25. */
.ai-chat-panel.mobile-fullscreen .ai-chat-btn,
.ai-chat-panel.mobile-fullscreen .ai-chat-send {
    min-height: 44px;
    min-width: 44px;
    padding: 0.5rem 0.75rem;
}
/* When the chat panel is mobile-fullscreen-open, hide the underlying scroll. */
body.ai-chat-mobile-open { overflow: hidden; }

/* Resize grab handle — left edge */
.ai-chat-resize {
    position: absolute; left: -4px; top: 0; bottom: 0; width: 8px;
    cursor: col-resize; z-index: 1;
    background: transparent;
}
.ai-chat-resize::after {
    content: ''; position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
    width: 3px; height: 32px; border-radius: 2px;
    background: var(--ctl-border);
    opacity: 0; transition: opacity 0.15s;
}
.ai-chat-resize:hover::after,
.ai-chat-panel.resizing .ai-chat-resize::after { opacity: 1; }

/* Pinned mode — panel pushes main content instead of overlapping */
.ai-chat-panel.pinned { box-shadow: none; border-left: 1px solid var(--ctl-border); }
.ai-chat-panel.pinned .ai-chat-pin-icon { transform: rotate(45deg); color: var(--ctl-accent-text); }
.main-content { transition: margin-left 0.2s ease, width 0.2s ease, margin-right 0.25s ease; }

.ai-chat-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--ctl-border);
    flex-shrink: 0;
}
.ai-chat-title { font-size: 0.85rem; font-weight: 600; color: var(--ctl-accent-text); }
.ai-chat-btn { background: none; border: none; color: var(--ctl-fg-muted); cursor: pointer; padding: 0.2rem 0.4rem; border-radius: 4px; font-size: 0.85rem; }
.ai-chat-btn:hover { background: var(--ctl-bg-hover); color: var(--ctl-fg); }

/* ============== Proactive nudge bell + feed ============== */
.ai-chat-header-actions { position: relative; }

.ai-nudge-btn { position: relative; }
.ai-nudge-badge {
    position: absolute; top: -2px; right: -2px;
    background: var(--ctl-danger); color: #fff;
    border-radius: 999px; padding: 0 5px;
    font-size: 0.6rem; font-weight: 700; line-height: 1.4;
    min-width: 16px; text-align: center; pointer-events: none;
}

.ai-nudge-feed {
    position: absolute; top: calc(0.6rem + 1.8rem); right: 0.5rem;
    width: min(340px, 92vw); max-height: 60vh; overflow-y: auto; /* §8 phone clamp */
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 8px;
    box-shadow: 0 8px 24px var(--ctl-shadow-hover);
    z-index: var(--ctl-z-dropdown); /* local to the panel's stacking context — just needs to top panel content */
}
.ai-nudge-feed-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--ctl-border);
    font-weight: 600; font-size: 0.85rem;
}
.ai-nudge-feed-list { padding: 0.25rem 0; }
.ai-nudge-feed-empty { padding: 1.5rem; text-align: center; }
.ai-nudge-feed-empty i { font-size: 2rem; color: var(--ctl-success-text); }

.ai-nudge-item {
    position: relative;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--ctl-border);
    border-left: 3px solid transparent;
}
.ai-nudge-item:hover { background: var(--ctl-bg-hover); }
.ai-nudge-item:last-child { border-bottom: none; }
.ai-nudge-item-header {
    display: flex; align-items: flex-start; gap: 0.4rem;
}
.ai-nudge-item-title {
    flex: 1; font-weight: 600; font-size: 0.82rem; line-height: 1.3;
}
.ai-nudge-item-title a { color: inherit; text-decoration: none; }
.ai-nudge-item-title a:hover { text-decoration: underline; }
.ai-nudge-item-body {
    font-size: 0.78rem; line-height: 1.4;
    color: var(--ctl-fg-muted); margin-top: 0.25rem;
}
.ai-nudge-item-meta {
    font-size: 0.7rem; color: var(--ctl-fg-muted); margin-top: 0.25rem;
}
.ai-nudge-sev-badge {
    font-size: 0.6rem; font-weight: 700; text-transform: uppercase;
    padding: 0.1rem 0.4rem; border-radius: 3px; flex-shrink: 0;
    align-self: center;
}
.ai-nudge-sev-info     { border-left-color: var(--ctl-info); }
.ai-nudge-sev-info     .ai-nudge-sev-badge { background: var(--ctl-info); color: var(--ctl-bg); }
.ai-nudge-sev-warning  { border-left-color: var(--ctl-warning); }
.ai-nudge-sev-warning  .ai-nudge-sev-badge { background: var(--ctl-warning); color: #000; }
.ai-nudge-sev-critical { border-left-color: var(--ctl-danger); }
.ai-nudge-sev-critical .ai-nudge-sev-badge { background: var(--ctl-danger); color: #fff; }
.ai-nudge-dismiss {
    position: relative;
    background: none; border: none; cursor: pointer;
    color: var(--ctl-fg-muted); padding: 0.1rem 0.3rem;
    font-size: 0.75rem; flex-shrink: 0;
    z-index: 2; /* sit above .stretched-link */
}
.ai-nudge-dismiss:hover { color: var(--ctl-danger-text); }

.ai-chat-messages {
    flex: 1; overflow-y: auto; padding: 0.75rem;
    display: flex; flex-direction: column; gap: 0.75rem;
    /* Contain iOS rubber-band scrolling so swiping past the top/bottom
       of the conversation doesn't bounce or pull-to-refresh the page
       underneath. body.ai-chat-mobile-open also locks body overflow,
       but that doesn't stop the inner scroll bleed without this rule.
       Closes gap.md #26. */
    overscroll-behavior: contain;
}
.ai-msg { max-width: 90%; padding: 0.5rem 0.75rem; border-radius: 0.75rem; font-size: 0.82rem; line-height: 1.5; word-break: break-word; }
.ai-msg-user { align-self: flex-end; background: var(--ctl-accent); color: var(--ctl-accent-fg); border-bottom-right-radius: 4px; }
.ai-msg-assistant { align-self: flex-start; background: var(--ctl-bg-alt); color: var(--ctl-fg); border-bottom-left-radius: 4px; }
.ai-msg-assistant code { font-size: 0.78rem; }
.ai-msg-assistant p { margin: 0 0 0.4rem 0; }
.ai-msg-assistant p:last-child { margin-bottom: 0; }
.ai-msg-assistant .ai-table { width: 100%; border-collapse: collapse; margin: 0.4rem 0; font-size: 0.78rem; }
.ai-msg-assistant .ai-table th,
.ai-msg-assistant .ai-table td { padding: 0.25rem 0.5rem; border: 1px solid var(--ctl-border); text-align: left; }
.ai-msg-assistant .ai-table th { background: var(--ctl-bg-hover); font-weight: 600; font-size: 0.75rem; }
.ai-msg-assistant .ai-list { margin: 0.3rem 0; padding-left: 1.3rem; }
.ai-msg-assistant .ai-list li { margin-bottom: 0.15rem; }
.ai-msg-assistant .ai-code-block { background: var(--ctl-bg-inset); color: var(--ctl-fg); border: 1px solid var(--ctl-border); padding: 0.5rem; border-radius: 0.4rem; font-size: 0.75rem; overflow-x: auto; margin: 0.4rem 0; white-space: pre-wrap; }
.ai-msg-assistant .ai-inline-code { background: var(--ctl-bg-hover); padding: 0.1rem 0.3rem; border-radius: 3px; font-size: 0.75rem; }
.ai-msg-assistant .ai-h1 { font-size: 0.9rem; display: block; margin-bottom: 0.3rem; }
.ai-msg-assistant .ai-h2 { font-size: 0.85rem; display: block; margin-bottom: 0.25rem; }
.ai-msg-assistant .ai-h3 { font-size: 0.82rem; display: block; margin-bottom: 0.2rem; }
.ai-msg-tool { align-self: flex-start; background: var(--ctl-info-bg); color: var(--ctl-info-text); font-size: 0.75rem; border-left: 3px solid var(--ctl-info); padding: 0.4rem 0.6rem; }
.ai-msg-typing { align-self: flex-start; color: var(--ctl-fg-muted); font-size: 0.8rem; font-style: italic; }

/* AI Thinking Indicator — animated dots with status and elapsed time */
.ai-msg-thinking {
    align-self: flex-start;
    background: var(--ctl-bg-alt);
    border-bottom-left-radius: 4px;
    padding: 0.5rem 0.75rem;
}
.ai-thinking-content {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--ctl-fg-muted);
}
.ai-thinking-status { font-style: italic; }
.ai-thinking-elapsed {
    font-size: 0.7rem;
    opacity: 0.6;
    font-variant-numeric: tabular-nums;
    min-width: 2em;
}
.ai-thinking-dots {
    display: inline-flex;
    gap: 3px;
    align-items: center;
}
.ai-thinking-dots span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ctl-accent);
    opacity: 0.4;
    animation: aiDotPulse 1.4s infinite ease-in-out both;
}
.ai-thinking-dots span:nth-child(1) { animation-delay: 0s; }
.ai-thinking-dots span:nth-child(2) { animation-delay: 0.2s; }
.ai-thinking-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes aiDotPulse {
    0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
    40% { opacity: 1; transform: scale(1.1); }
}

/* Voice Mode */
.ai-voice-overlay {
    position: absolute; inset: 0; z-index: 10;
    background: var(--ctl-bg-elevated);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 1.5rem; padding: 2rem;
}
.ai-voice-close {
    position: absolute; top: 0.75rem; right: 0.75rem;
    background: none; border: none; font-size: 1.2rem;
    color: var(--ctl-fg-muted); cursor: pointer;
}
.ai-voice-close:hover { color: var(--ctl-fg); }
/* Mute toggle — local-only TTS quieter for the session. Top-left mirror
   of the close button (top-right). v0.27.000 closes gap.md #15 Phase 1. */
.ai-voice-mute {
    position: absolute; top: 0.75rem; left: 0.75rem;
    background: none; border: none; font-size: 1.2rem;
    color: var(--ctl-fg-muted); cursor: pointer;
    min-height: 44px; min-width: 44px; /* mobile touch target */
}
.ai-voice-mute:hover { color: var(--ctl-fg); }
.ai-voice-mute.muted { color: var(--ctl-danger-text); }
.ai-voice-visual { position: relative; }
.ai-voice-ring {
    width: 120px; height: 120px; border-radius: 50%;
    border: 3px solid var(--ctl-border);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; transition: all 0.3s ease;
    background: var(--ctl-bg-alt);
}
.ai-voice-ring-inner {
    width: 48px; height: 48px; border-radius: 50%;
    background: var(--ctl-fg-muted);
    transition: all 0.3s ease;
}
/* Listening state */
.ai-voice-ring.listening {
    border-color: var(--ctl-danger);
    box-shadow: 0 0 0 0 rgba(var(--ctl-danger-rgb), 0.4);
    animation: voicePulse 1.5s infinite;
}
.ai-voice-ring.listening .ai-voice-ring-inner {
    background: var(--ctl-danger);
}
/* Processing state */
.ai-voice-ring.processing {
    border-color: var(--ctl-warning);
}
.ai-voice-ring.processing .ai-voice-ring-inner {
    background: var(--ctl-warning);
    animation: voiceSpin 1s linear infinite;
}
/* Speaking state */
.ai-voice-ring.speaking {
    border-color: var(--ctl-accent);
    box-shadow: 0 0 0 0 rgba(var(--ctl-accent-rgb), 0.3);
    animation: voicePulse 1s infinite;
}
.ai-voice-ring.speaking .ai-voice-ring-inner {
    background: var(--ctl-accent);
}
@keyframes voicePulse {
    0% { box-shadow: 0 0 0 0 currentColor; }
    70% { box-shadow: 0 0 0 15px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes voiceSpin {
    0% { transform: scale(1); }
    50% { transform: scale(0.8); }
    100% { transform: scale(1); }
}
.ai-voice-status {
    font-size: 0.9rem; color: var(--ctl-fg-muted);
    text-align: center; min-height: 1.4rem;
}
.ai-voice-transcript {
    font-size: 0.85rem; color: var(--ctl-fg);
    text-align: center; max-width: 90%; min-height: 2rem;
    font-style: italic; opacity: 0.8;
}

#aiChatVoiceBtn {
    color: var(--ctl-fg-muted); font-size: 0.9rem; flex-shrink: 0;
}
#aiChatVoiceBtn:hover { color: var(--ctl-accent-text); }

.ai-chat-input-area { flex-shrink: 0; padding: 0.5rem 0.75rem; border-top: 1px solid var(--ctl-border); }
.ai-chat-input-wrapper { display: flex; gap: 0.5rem; align-items: flex-end; }
.ai-chat-input {
    flex: 1; border: 1px solid var(--ctl-border); border-radius: 0.5rem;
    padding: 0.4rem 0.6rem; font-size: 0.82rem; resize: none; max-height: 100px;
    background: var(--ctl-bg-inset); color: var(--ctl-fg);
}
.ai-chat-input:focus { outline: none; border-color: var(--ctl-accent); box-shadow: var(--ctl-focus-ring); }
.ai-chat-send {
    background: var(--ctl-accent); color: var(--ctl-accent-fg); border: none; border-radius: 0.5rem;
    padding: 0.4rem 0.6rem; cursor: pointer; font-size: 0.85rem; flex-shrink: 0;
}
.ai-chat-send:hover { opacity: 0.9; }
.ai-chat-send:disabled { opacity: 0.5; cursor: not-allowed; }

.ai-chat-history { max-height: 200px; overflow-y: auto; border-bottom: 1px solid var(--ctl-border); }
.ai-chat-history-item { display: block; padding: 0.4rem 0.75rem; font-size: 0.78rem; cursor: pointer; color: var(--ctl-fg); text-decoration: none; border-bottom: 1px solid var(--ctl-border); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-chat-history-item:hover { background: var(--ctl-bg-hover); }

/* ── Portal ── */
.portal-nav { background: var(--ctl-bg-elevated); border-bottom: 1px solid var(--ctl-border); }
.portal-container { max-width: 960px; margin: 0 auto; padding: 2rem 1rem; }
.portal-card { transition: box-shadow 0.15s; }
.portal-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.08); }

/* ── Portal status progress strip ── */
.portal-progress { position: relative; }
.portal-progress-step { position: relative; }
/* connector line between steps (behind the dots) */
.portal-progress-step:not(:first-child)::before {
    content: "";
    position: absolute;
    top: 15px;
    left: -50%;
    width: 100%;
    height: 2px;
    background: var(--ctl-border);
    z-index: 0;
}
.portal-progress-step.done::before,
.portal-progress-step.current::before { background: var(--ctl-accent); }
.portal-progress-dot {
    position: relative;
    z-index: 1;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 600;
    background: var(--ctl-bg-elevated);
    border: 2px solid var(--ctl-border);
    color: var(--ctl-fg-muted);
}
.portal-progress-step.done .portal-progress-dot {
    background: var(--ctl-accent);
    border-color: var(--ctl-accent);
    color: var(--ctl-accent-fg);
}
.portal-progress-step.current .portal-progress-dot {
    border-color: var(--ctl-accent);
    color: var(--ctl-accent-text);
    box-shadow: 0 0 0 3px rgba(var(--ctl-accent-rgb), 0.15);
}
.portal-progress-step.current .portal-progress-label { font-weight: 600; color: var(--ctl-accent-text); }
.portal-progress-label { color: var(--ctl-fg-muted); }

/* ── Content images — constrain to container ── */
.card img, .rich-body img, .portal-container img, .kb-article-content img {
    max-width: 100%;
    height: auto;
}

/* ── Global Search ── */
.global-search-wrapper { position: relative; }
.global-search-dropdown {
    display: none; position: absolute; right: 0; top: 100%;
    width: min(380px, 92vw); background: var(--ctl-bg-elevated); /* §8 phone clamp */
    border: 1px solid var(--ctl-border); border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow-hover); z-index: var(--ctl-z-dropdown); padding: 0.5rem;
}
.global-search-wrapper.open .global-search-dropdown { display: block; }
.global-search-results { max-height: 320px; overflow-y: auto; margin-top: 0.25rem; }
.global-search-item {
    display: block; padding: 0.4rem 0.5rem; text-decoration: none;
    color: var(--ctl-fg); border-radius: 0.25rem; cursor: pointer;
}
.global-search-item:hover, .global-search-item.active { background: var(--ctl-bg-hover); color: var(--ctl-fg); }
.global-search-item .gs-title { font-size: 0.8rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.global-search-item .gs-subtitle { font-size: 0.7rem; color: var(--ctl-fg-muted); }
.global-search-item .gs-type { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ctl-accent-text); }
.global-search-footer { padding: 0.25rem 0.5rem 0; border-top: 1px solid var(--ctl-border); margin-top: 0.25rem; text-align: center; }

/* ── Notification indicator & dropdown ── */
.nav-notification-wrapper {
    position: relative;
}

.notification-toggle {
    position: relative;
}

.notification-count-badge {
    position: absolute;
    top: -2px;
    right: -4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: 0.6rem;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    color: #fff;
    background: var(--ctl-danger);
    border-radius: 8px;
}

.notification-dropdown {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    width: min(360px, 92vw); /* §8 phone clamp */
    max-height: 480px;
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow-hover);
    z-index: var(--ctl-z-dropdown);
    display: none;
    flex-direction: column;
}

.nav-notification-wrapper.open .notification-dropdown {
    display: flex;
}

.notification-dropdown-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--ctl-border);
}

.notification-dropdown-title {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ctl-fg-muted);
}

.notification-mark-all {
    color: var(--ctl-link);
    text-decoration: none;
    font-size: 0.85rem;
}

.notification-dropdown-body {
    flex: 1;
    overflow-y: auto;
    max-height: 380px;
}

.notification-dropdown-footer {
    padding: 0.4rem 0.75rem;
    border-top: 1px solid var(--ctl-border);
    text-align: center;
}

.notification-dropdown-footer a {
    font-size: 0.75rem;
    color: var(--ctl-link);
    text-decoration: none;
}

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    text-decoration: none;
    color: var(--ctl-fg);
    border-bottom: 1px solid var(--ctl-border);
    cursor: pointer;
    transition: background 0.1s;
}

.notif-item:hover {
    background: var(--ctl-bg-hover);
    color: var(--ctl-fg);
}

.notif-item.notif-unread {
    background: rgba(var(--ctl-accent-rgb), 0.06);
}

.notif-item .notif-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--ctl-bg-alt);
    font-size: 0.8rem;
    color: var(--ctl-accent-text);
}

.notif-item .notif-body {
    flex: 1;
    min-width: 0;
}

.notif-item .notif-title {
    font-size: 0.8rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.notif-item .notif-msg {
    font-size: 0.75rem;
    color: var(--ctl-fg-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.notif-item .notif-time {
    font-size: 0.65rem;
    color: var(--ctl-fg-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.notif-unread-dot {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ctl-accent);
    margin-top: 6px;
}

.notification-empty {
    text-align: center;
    padding: 1.5rem 0.75rem;
    color: var(--ctl-fg-muted);
    font-size: 0.8rem;
}

/* ── Bulk Actions ── */
.bulk-action-bar {
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-accent);
    border-radius: 0.375rem;
    margin-bottom: 0.5rem;
    box-shadow: 0 2px 8px rgba(var(--ctl-accent-rgb), 0.1);
}

.bulk-action-bar .bulk-count {
    color: var(--ctl-accent-text);
    font-size: 0.85rem;
}

.col-bulk-check {
    padding: 0.25rem 0.5rem !important;
    width: 36px;
    min-width: 36px;
    max-width: 36px;
}

.col-bulk-check .form-check-input {
    margin: 0;
    cursor: pointer;
}

/* Full notification list page */
.notification-list-full .notification-item {
    padding: 0.6rem 0.75rem;
    border-left: 3px solid transparent;
}

.notification-list-full .notification-item.notification-unread {
    background: rgba(var(--ctl-accent-rgb), 0.06);
    border-left-color: var(--ctl-accent);
}

.notification-list-full .notification-title {
    font-size: 0.85rem;
    font-weight: 500;
}

.notification-list-full .notification-message {
    font-size: 0.8rem;
}

.notification-list-full .notification-time {
    font-size: 0.75rem;
}

.notification-list-full .notification-icon {
    color: var(--ctl-accent-text);
    font-size: 1rem;
}

.notification-list-full .notification-unread-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ctl-accent);
    flex-shrink: 0;
    margin-top: 6px;
}

.content-wrapper {
    padding: var(--ctl-section-pad); /* §5: 24px comfortable / 12px compact */
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    /* Reserve the scrollbar lane permanently: content height changes (panels
       opening, tables expanding) must never shift centered/clamped layout
       horizontally as the scrollbar toggles (§8.2). */
    scrollbar-gutter: stable;
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--ctl-bg);
}

/* Pages with their own scroll regions suppress outer scroll */
.content-wrapper:has(.detail-page-body),
.content-wrapper:has(.table-scroll) {
    overflow: hidden;
}

/* Cards */
.card {
    border: 1px solid var(--ctl-border);
    border-radius: 0.5rem;
    box-shadow: 0 1px 3px var(--ctl-shadow);
    background: var(--ctl-bg-elevated);
}

.card-header {
    background: var(--ctl-bg-elevated);
    border-bottom: 1px solid var(--ctl-border);
    font-weight: 600;
}

/* Tables */
.table-responsive {
    border-radius: 0.5rem;
    overflow: visible;
}

/* Scrollable table body with sticky header */
.table-scroll {
    overflow: auto;
    flex: 1;
    min-height: 0;
}

.table-scroll .table {
    margin-bottom: 0;
    width: auto;
    min-width: 0;
    /* Separate borders so box-shadow on sticky cells isn't clipped */
    border-collapse: separate;
    border-spacing: 0;
}

/* No text wrapping in table cells — overflow shows as ellipsis with tooltip */
.table-scroll .table td,
.table-scroll .table th {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 300px;
}

.table-scroll .table thead th {
    position: sticky;
    top: 0;
    z-index: 10;
    border-bottom: 1px solid var(--ctl-border);
}

/* List page card fills available space — scoped via :has(.table-scroll) so
   the flex:1 + min-height:0 + overflow:hidden combo only applies to cards
   that actually wrap a scrollable table (list_table.php). Pages that stack
   multiple natural-height cards under .content-wrapper (e.g. /settings/system,
   which renders one card per setting group) would otherwise share flex:1 and
   collapse to ~2px each. The :has(.table-scroll) selector matches the same
   list-page-shaped content that .content-wrapper:has(.table-scroll) already
   keys off (line ~1679 above). */
.content-wrapper > .card:has(.table-scroll) {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.content-wrapper > .card:has(.table-scroll) > .card-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/* Row padding is density-driven (§5: 10px comfortable / 4px compact) */
.table > :not(caption) > * > * {
    padding-top: var(--ctl-table-cell-pad-y);
    padding-bottom: var(--ctl-table-cell-pad-y);
}

.table thead th:not(.col-header) {
    background: var(--ctl-bg-alt);
    font-weight: 500;
    text-transform: uppercase;
    font-size: var(--ctl-fs-caption);
    letter-spacing: 0.04em;
    color: var(--ctl-fg-muted);
}

.table thead th.col-header {
    background: var(--ctl-bg-alt);
}

.table tbody td {
    font-size: var(--ctl-fs-body);
    color: var(--ctl-fg);
}

.table tbody tr:hover {
    background-color: var(--ctl-bg-hover);
}

/* Vertical grid lines — shared list table only (scoped to the column-prefs
   table the list_table.php partial renders, so dashboards / detail tables
   stay borderless). Last column drops its right border. */
.table[data-pref-key] thead th,
.table[data-pref-key] tbody td,
.table[data-pref-key] tfoot td {
    border-right: 1px solid var(--ctl-border);
}

.table[data-pref-key] thead th:last-child,
.table[data-pref-key] tbody td:last-child,
.table[data-pref-key] tfoot td:last-child {
    border-right: none;
}

/* Table status bar */
.table-status-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
    border-top: 1px solid var(--ctl-border);
    background: var(--ctl-bg-alt);
    font-size: 0.8rem;
    color: var(--ctl-fg-muted);
    border-radius: 0 0 0.5rem 0.5rem;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.table-status-bar .status-left,
.table-status-bar .status-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.table-status-bar .per-page-select {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.table-status-bar .per-page-select select {
    width: auto;
    padding: 0.15rem 1.5rem 0.15rem 0.4rem;
    font-size: 0.8rem;
    border-color: var(--ctl-border-strong);
}

/* Column header dropdowns */
.col-header {
    padding: 0 !important;
}

.col-header-wrapper {
    position: relative;
}

.col-header-btn {
    font-weight: 500;
    text-transform: uppercase;
    font-size: var(--ctl-fs-caption);
    letter-spacing: 0.04em;
    color: var(--ctl-fg-muted);
    cursor: grab;
    padding: var(--ctl-table-cell-pad-y) 0.75rem;
    width: 100%;
    display: flex;
    align-items: center;
    white-space: nowrap;
    user-select: none;
}

.col-header-btn.has-filter {
    color: var(--ctl-accent-text);
}

.col-header-label {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.col-menu-trigger {
    cursor: pointer;
    color: var(--ctl-fg-muted);
    font-size: 0.55rem;
    padding: 0.1rem 0.2rem;
    border-radius: 0.15rem;
}

.col-menu-trigger:hover {
    color: var(--ctl-accent-text);
    background: rgba(var(--ctl-accent-rgb), 0.1);
}

.col-header-indicators {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
}

.col-indicator {
    font-size: 0.65rem;
}


/* The dropdown panel — fixed position to escape table overflow and sticky headers */
.col-dropdown {
    display: none;
    position: fixed;
    z-index: var(--ctl-z-dropdown);
    min-width: 220px;
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow);
    padding: 0.375rem 0;
    color: var(--ctl-fg);
}

.col-header-wrapper.open > .col-dropdown {
    display: block;
}

/* Pin / Hide icon row at top of column dropdown */
.col-dropdown-actions {
    display: flex;
    gap: 0.25rem;
    padding: 0.3rem 0.5rem;
    justify-content: flex-end;
}

.col-dropdown-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid var(--ctl-border);
    background: var(--ctl-bg-elevated);
    color: var(--ctl-fg-muted);
    border-radius: 0.25rem;
    cursor: pointer;
    font-size: 0.8rem;
}

.col-dropdown-action:hover {
    color: var(--ctl-accent-text);
    border-color: var(--ctl-accent);
    background: var(--ctl-bg-hover);
}

.col-dropdown-section {
    padding: 0.25rem 0;
}

.col-dropdown-label {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ctl-fg-muted);
    padding: 0.25rem 0.75rem;
}

.col-dropdown-divider {
    border-top: 1px solid var(--ctl-border);
    margin: 0.25rem 0;
}

.col-dropdown-item {
    display: flex;
    align-items: center;
    padding: 0.35rem 0.75rem;
    font-size: 0.85rem;
    color: var(--ctl-fg);
    text-decoration: none;
    cursor: pointer;
}

.col-dropdown-item:hover {
    background: var(--ctl-bg-hover);
    color: var(--ctl-fg);
}

.col-dropdown-item.active {
    color: var(--ctl-accent-text);
    font-weight: 500;
}

.col-dropdown-item.text-danger:hover {
    background: var(--ctl-danger-bg);
}

/* Text filter inside dropdown */
.col-filter-form {
    padding: 0.25rem 0.75rem;
}

/* Scrollable filter list inside dropdown */
.col-filter-scroll {
    max-height: 200px;
    overflow-y: auto;
}

/* Checkbox filters */
.col-dropdown-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.75rem;
    font-size: 0.85rem;
    cursor: pointer;
    margin: 0;
}

.col-dropdown-check:hover {
    background: var(--ctl-bg-hover);
}

.col-dropdown-check input[type="checkbox"] {
    margin: 0;
}

/* Column settings panel — hidden until JS restores state to prevent jitter on reload */
.col-settings-wrapper {
    position: relative;
    visibility: hidden;
}

.col-settings-panel {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    width: 260px;
    max-height: 70vh;
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow);
    z-index: var(--ctl-z-dropdown);
    padding: 0;
    color: var(--ctl-fg);
}

.col-settings-wrapper.open .col-settings-panel {
    display: flex;
    flex-direction: column;
}

.col-settings-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.35rem 0.75rem;
    border-bottom: 1px solid var(--ctl-border);
}

.col-settings-title {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ctl-fg-muted);
}

.col-settings-reset {
    background: none;
    border: none;
    color: var(--ctl-fg-muted);
    cursor: pointer;
    padding: 0.15rem;
    font-size: 0.85rem;
    line-height: 1;
}

.col-settings-reset:hover {
    color: var(--ctl-accent-text);
}

.col-settings-list {
    list-style: none;
    margin: 0;
    padding: 0.25rem 0;
    overflow-y: auto;
    flex: 1;
    min-height: 0;
}

.col-settings-item {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.75rem;
    font-size: 0.8rem;
    cursor: grab;
    transition: background 0.1s;
}

.col-settings-item:active {
    cursor: grabbing;
}

.col-settings-item.dragging {
    opacity: 0.5;
    background: var(--ctl-bg-hover);
}

.col-settings-item.drag-over {
    border-top: 2px solid var(--ctl-accent);
}

.col-settings-drag {
    color: var(--ctl-fg-faint);
    cursor: grab;
    flex-shrink: 0;
    touch-action: none;
}

.col-settings-label {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    cursor: pointer;
    margin: 0;
}

.col-settings-label input[type="checkbox"] {
    margin: 0;
}

.col-settings-pin {
    background: none;
    border: none;
    color: var(--ctl-fg-faint);
    cursor: pointer;
    padding: 0.1rem;
    font-size: 0.8rem;
    line-height: 1;
    flex-shrink: 0;
}

.col-settings-pin:hover,
.col-settings-pin.active {
    color: var(--ctl-accent-text);
}

.col-settings-footer {
    display: flex;
    gap: 0.35rem;
    padding: 0.4rem 0.75rem;
    border-top: 1px solid var(--ctl-border);
    background: var(--ctl-bg-elevated);
    justify-content: flex-end;
}

/* Pinned columns — sticky left inside single scrollable table */
.col-pinned {
    position: sticky;
    z-index: 2;
    background: var(--ctl-bg-elevated);
}

.table-scroll .table thead th.col-pinned {
    z-index: 12 !important;
    background: var(--ctl-bg-alt);
}

tbody tr:hover .col-pinned {
    background: var(--ctl-bg-hover) !important;
}

.col-pinned-last {
    border-right: 2px solid var(--ctl-border-strong) !important;
    box-shadow: 2px 0 4px var(--ctl-shadow);
}

/* Column resize handle */
.col-resize-handle {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 5px;
    cursor: col-resize;
    z-index: 20;
}

.col-resize-handle:hover,
.col-resize-handle.active {
    background: var(--ctl-accent);
    opacity: 0.4;
}

/* Dragging column headers */
.col-header.dragging-header {
    opacity: 0.3;
}

.col-drag-ghost {
    position: fixed;
    padding: 0.4rem 0.75rem;
    background: var(--ctl-accent);
    color: var(--ctl-accent-fg);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-radius: 0.25rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    pointer-events: none;
    z-index: var(--ctl-z-tooltip); /* ephemeral cursor-following ghost — topmost app layer */
    white-space: nowrap;
}

.col-header.drag-target-left::before {
    content: '';
    position: absolute;
    left: -1px;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--ctl-accent);
    z-index: 25;
}

.col-header.drag-target-right::after {
    content: '';
    position: absolute;
    right: -1px;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--ctl-accent);
    z-index: 25;
}

/* Fixed table layout when columns have explicit widths */
.table.col-resizable {
    table-layout: fixed;
}

.table.col-resizable th,
.table.col-resizable td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Prevent text selection during drag/resize */
body.col-resizing,
body.col-dragging {
    user-select: none;
}

body.col-resizing {
    cursor: col-resize !important;
}

body.col-dragging {
    cursor: grabbing !important;
}



/* Detail page — compact toolbar */
.detail-toolbar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.detail-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: none;
    background: none;
    color: var(--ctl-fg-muted);
    border-radius: 0.25rem;
    cursor: pointer;
    text-decoration: none;
    font-size: 0.95rem;
    transition: color 0.15s, background 0.15s;
}

.detail-tool:hover {
    color: var(--ctl-accent-text);
    background: var(--ctl-bg-hover);
}

/* The user-menu button carries an icon + the user's name — size it to its
   content instead of the fixed 2rem icon square, which made the label
   overflow onto whatever tool sat to its left. */
.detail-tool.navbar-user {
    width: auto;
    padding: 0 0.5rem;
}

.detail-tool.disabled {
    color: var(--ctl-fg-faint);
    pointer-events: none;
    cursor: default;
}

.detail-tool.text-warning:hover {
    background: var(--ctl-warning-bg);
}

.detail-tool.text-success:hover {
    background: var(--ctl-success-bg);
}

.detail-edit-actions {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-left: 0.5rem;
}

/* Detail page — fixed header, scrollable body */
.detail-page-header {
    flex-shrink: 0;
    border-bottom: 1px solid var(--ctl-border);
    padding-bottom: 0.35rem;
    margin-bottom: 0.5rem;
}

.detail-page-title {
    margin: 0 0 0 0.75rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--ctl-fg);
}

.detail-page-body {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    scrollbar-gutter: stable; /* §8.2: no horizontal shift when content grows */
}

/* Add-permission dropdown (edit mode only) */
.editing .perm-add-wrapper.detail-input {
    display: inline-flex !important;
}

.perm-add-dropdown {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    min-width: min(320px, 92vw); /* §8 phone clamp — never wider than the viewport */
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px var(--ctl-shadow-hover);
    z-index: var(--ctl-z-dropdown);
}

.perm-add-wrapper.open .perm-add-dropdown {
    display: block;
}

/* Detail page — horizontal field rows */
.detail-row {
    display: flex;
    align-items: baseline;
    padding: 0.15rem 0;
    border-bottom: 1px solid var(--ctl-border);
    gap: 0.5rem;
}

.detail-row:last-child {
    border-bottom: none;
}

.detail-section-title {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ctl-fg);
    border-bottom: 2px solid var(--ctl-border);
    padding-bottom: 0.25rem;
    padding-top: 0.75rem;
    margin-bottom: 0.15rem;
}

.detail-section-title:first-child {
    padding-top: 0;
}

.detail-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ctl-fg-subtle);
    white-space: nowrap;
    min-width: 7rem;
    flex-shrink: 0;
}

.detail-view {
    font-size: 0.85rem;
    flex: 1;
    min-width: 0;
    line-height: 1.3;
}

/* Edit mode */
.editing .detail-view {
    display: none !important;
}

/* Field-metadata slot (sync-ownership badges + future sibling pills). Sibling
   of .detail-view / .detail-input so it stays visible in both read AND edit
   modes — the user needs ownership context while editing, and the save-time
   confirmation prompt reads data-owner from these spans. */
.field-metadata-badges {
    flex-shrink: 0;
    font-size: 0.75rem;
    align-self: center;
}

.editing .detail-input {
    display: block !important;
    flex: 1;
    min-width: 0;
}

.editing .detail-input-only {
    display: flex !important;
}

/* Inputs inside detail rows: even tighter to match read-only row height */
.detail-row .form-control,
.detail-row .form-select {
    padding: 0.1rem 0.35rem;
    line-height: 1.3;
}

/* Clickable table rows */
.cursor-pointer {
    cursor: pointer;
}

/* Action buttons in tables */
.btn-group-sm .btn {
    padding: 0.25rem 0.5rem;
}

/* Status text colors */
.text-status-active { color: var(--ctl-success-text); font-weight: 500; }
.text-status-inactive { color: var(--ctl-fg-muted); }
.text-status-locked { color: var(--ctl-danger-text); font-weight: 500; }
.text-status-archived { color: var(--ctl-fg-muted); }
.text-status-new { color: var(--ctl-status-new); font-weight: 500; }
.text-status-assigned { color: var(--ctl-status-assigned); font-weight: 500; }
.text-status-in_progress { color: var(--ctl-status-in-progress); font-weight: 500; }
.text-status-pending { color: var(--ctl-fg-muted); }
.text-status-on_hold { color: var(--ctl-fg-muted); }
.text-status-resolved { color: var(--ctl-success-text); font-weight: 500; }
.text-status-closed { color: var(--ctl-fg-muted); }
.text-status-cancelled { color: var(--ctl-danger-text); }

/* Risk level text colors */
.text-risk-critical { color: var(--ctl-danger-text); font-weight: 600; }
.text-risk-high { color: var(--ctl-risk-high); font-weight: 500; }
.text-risk-medium { color: var(--ctl-risk-medium); }
.text-risk-low { color: var(--ctl-fg-muted); }

/* Forms — density-aware (§5). Comfortable (default) ≈40px controls / 15px UI
   font; html[data-density="compact"] restores today's ultra-compact values
   (≈30px controls / 13.5px). All values flow from the density tokens in the
   token sheets — no per-density rules here. */
.form-control, .form-select {
    padding: var(--ctl-control-pad-y) var(--ctl-control-pad-x);
    font-size: var(--ctl-fs-body);
    background-color: var(--ctl-bg-inset);
    color: var(--ctl-fg);
    border-color: var(--ctl-border-strong);
}

.form-control:focus, .form-select:focus {
    background-color: var(--ctl-bg-inset);
    color: var(--ctl-fg);
    border-color: var(--ctl-accent);
    box-shadow: var(--ctl-focus-ring);
}

.form-label {
    font-weight: 500;
    font-size: var(--ctl-fs-label);
    margin-bottom: 0.15rem;
}

.form-text {
    font-size: var(--ctl-fs-body-sm);
    margin-top: 0.1rem;
}

.required::after {
    content: " *";
    color: var(--ctl-danger-text);
}

/* Pagination */
.pagination {
    margin-bottom: 0;
}

/* Alerts */
.alert {
    border: none;
    border-radius: 0.5rem;
}

/* Flash messages container */
.flash-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1050; /* z literal kept: pinned to Bootstrap's modal-backdrop level (1050) so flashes sit with the modal stack */
    max-width: 400px;
}

.flash-container .alert {
    animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

/* Empty state */
.empty-state {
    text-align: center;
    padding: 3rem;
    color: var(--ctl-fg-muted);
}

.empty-state i {
    font-size: 3rem;
    margin-bottom: 1rem;
}

/* Loading spinner */
.spinner-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(var(--ctl-bg-rgb), 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999; /* z literal kept: blocking overlay must top Bootstrap's modal stack (1055+), above the --ctl-z scale */
}

/* ── Second nav panel (single-layer drilldown, UI_STANDARDS §7) ──────────────
   The panel sits at the rail's right edge (left:100% follows the rail width,
   collapsed or not) and ALWAYS floats over the content — it never pushes or
   reflows the main page at any tier (§8.2). Desktop: overlay, no backdrop.
   Collapsed / tablet: overlay flyout + dim backdrop. Phone: covers the
   off-canvas rail (full-width layer) with the drawer's own backdrop. */
.sidebar-panel {
    display: none;
    flex-direction: column;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 100%;
    width: var(--ctl-sidebar-panel-width);
    background: #1a1e21;
    border-left: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: var(--ctl-shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.35));
    z-index: var(--ctl-z-panel);
    overflow: hidden;
}

.sidebar.panel-open .sidebar-panel {
    display: flex;
}

.sidebar-panel-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.5rem 0.6rem 0.9rem;
    min-height: 3.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.sidebar-panel-title {
    flex: 1;
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-panel-close {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    font-size: 1rem;
    line-height: 1;
    padding: 0.35rem 0.45rem;
    cursor: pointer;
    border-radius: 0.25rem;
    flex-shrink: 0;
}

.sidebar-panel-close:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.sidebar-panel-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0.4rem 0;
}

.sidebar-panel-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.9rem;
    color: rgba(255, 255, 255, 0.8);
    text-decoration: none;
    border-left: 3px solid transparent;
    white-space: nowrap;
}

.sidebar-panel-link i {
    width: 1.25rem;
    text-align: center;
    flex-shrink: 0;
    opacity: 0.75;
}

.sidebar-panel-link:hover,
.sidebar-panel-link.active {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
    border-left-color: var(--ctl-accent);
}

/* SUBGROUP rows render as section headers INSIDE the panel (never a 3rd layer) */
.sidebar-panel-section + .sidebar-panel-section {
    margin-top: 0.35rem;
}

.sidebar-panel-section-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.5rem 0.9rem 0.3rem;
}

.sidebar-panel-section-title i {
    font-size: 0.75rem;
    opacity: 0.7;
}

/* Backdrop behind an overlay/flyout panel (tablet + collapsed-desktop only).
   JS un-hides it only in overlay tiers, so the presence of the attribute is
   the single source of truth for visibility. */
.sidebar-panel-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: calc(var(--ctl-z-panel) - 1);
}

.sidebar-panel-backdrop:not([hidden]) {
    display: block;
}

/* Footer nav toggle (Settings / Back) — inherits the .nav-link chrome */
.sidebar-nav-toggle .flyout-chevron {
    display: none;
}

/* Tablet (769–991px): collapsed icon rail; the second panel opens as an
   overlay flyout on tap; content never reflows (UI_STANDARDS §8). */
@media (min-width: 769px) and (max-width: 991px) {
    .sidebar {
        width: var(--ctl-sidebar-collapsed);
    }
    .sidebar .nav-label,
    .sidebar .flyout-chevron {
        opacity: 0;
        width: 0;
        margin: 0;
        overflow: hidden;
    }
    .sidebar-search {
        display: none;
    }
    .sidebar .sidebar-header {
        flex-direction: column;
        align-items: center;
        gap: 0.4rem;
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }
    .sidebar .brand-logo,
    .sidebar .brand-core {
        display: none;
    }
    .sidebar .brand-mark {
        display: block;
        height: 22px;
        width: auto;
    }
    .sidebar .nav-link {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
        border-left-width: 0;
    }
    #sidebarCollapseBtn {
        display: none;
    }
    .main-content,
    .sidebar.panel-open ~ .main-content {
        margin-left: var(--ctl-sidebar-collapsed);
        width: calc(100% - var(--ctl-sidebar-collapsed));
    }
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .sidebar {
        margin-left: calc(-1 * var(--ctl-sidebar-width));
        width: var(--ctl-sidebar-width) !important;
    }

    .sidebar.mobile-open {
        margin-left: 0;
    }

    /* Dim backdrop behind the open sidebar. Sits one step below the sidebar
       (--ctl-z-sidebar); taps land on .main-content, which the existing
       outside-click handler in app.js treats as close-sidebar. */
    .sidebar.mobile-open + .main-content::before {
        content: "";
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.4);
        z-index: calc(var(--ctl-z-sidebar) - 1);
    }

    .sidebar .sidebar-brand,
    .sidebar .nav-label,
    .sidebar .flyout-chevron {
        opacity: 1 !important;
        width: auto !important;
        margin-left: 0.75rem !important;
    }

    .sidebar .nav-link {
        justify-content: flex-start !important;
        padding-left: 0.75rem !important;
        border-left-width: 3px !important;
    }

    .sidebar-footer .nav-link {
        justify-content: flex-start !important;
    }

    /* Phone: the second panel is a push-in layer covering the off-canvas rail
       (UI_STANDARDS §7). The off-canvas backdrop already dims the content. */
    .sidebar-panel {
        left: 0;
        width: 100%;
        border-left: 0;
    }

    #sidebarCollapseBtn {
        display: none;
    }

    .main-content {
        margin-left: 0 !important;
        width: 100% !important;
    }

    /* Tighten spacing on mobile */
    .content-wrapper {
        padding: 0.75rem;
    }

    .content-wrapper .mb-4 {
        margin-bottom: 0.5rem !important;
    }

    .content-wrapper .mb-3 {
        margin-bottom: 0.25rem !important;
    }

    .content-wrapper h1.h3,
    .content-wrapper .h3 {
        font-size: 1.1rem;
    }

    .card-body {
        padding: 0.75rem;
    }

    .card-header {
        padding: 0.5rem 0.75rem;
    }

    .row.g-3 {
        --bs-gutter-y: 0.5rem;
    }

    .col-12.mt-4 {
        margin-top: 0.75rem !important;
    }

    /* Toolbar + top navbar compact */
    .top-navbar {
        padding: 0.3rem 0.5rem;
    }

    .page-breadcrumb {
        font-size: 0.75rem;
    }

    .navbar-user {
        display: none;
    }

    .detail-toolbar {
        margin-bottom: 0.5rem !important;
    }

    /* Detail page header: tighter on mobile */
    .detail-page-header {
        padding-bottom: 0.35rem;
        margin-bottom: 0.5rem;
    }

    .detail-label {
        min-width: 5.5rem;
        font-size: 0.7rem;
    }

    .detail-view {
        font-size: 0.8rem;
    }

    .detail-row {
        padding: 0.2rem 0;
    }

    .detail-page-title {
        font-size: 0.9rem;
        margin-left: 0.5rem;
    }

    .detail-section-title {
        font-size: 0.75rem;
    }
}

/* Rich editor */
.rich-editor {
    border: 1px solid var(--ctl-border);
    border-radius: 0.375rem;
    overflow: hidden;
}

.rich-editor:focus-within {
    border-color: var(--ctl-accent);
    box-shadow: var(--ctl-focus-ring);
}

.rich-toolbar {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.25rem 0.4rem;
    background: var(--ctl-bg-alt);
    border-bottom: 1px solid var(--ctl-border);
    flex-wrap: wrap;
}

.rich-toolbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border: none;
    background: none;
    color: var(--ctl-fg-muted);
    border-radius: 0.2rem;
    cursor: pointer;
    font-size: 0.8rem;
}

.rich-toolbar-btn:hover {
    background: var(--ctl-bg-hover);
    color: var(--ctl-fg);
}

.rich-toolbar-btn.active {
    background: var(--ctl-border);
    color: var(--ctl-accent-text);
}

.rich-toolbar-sep {
    width: 1px;
    height: 1.25rem;
    background: var(--ctl-border);
    margin: 0 0.2rem;
}

.rich-body {
    min-height: 120px;
    max-height: 400px;
    overflow-y: auto;
    padding: 0.5rem 0.75rem;
    font-size: 0.85rem;
    line-height: 1.6;
    background: var(--ctl-bg-inset);
    color: var(--ctl-fg);
    /* outline suppressed: the parent .rich-editor:focus-within border+ring is
       the visible focus indicator for this contenteditable region. */
    outline: none;
}

.rich-body:empty::before {
    content: attr(data-placeholder);
    color: var(--ctl-fg-faint);
    pointer-events: none;
}

.rich-body img {
    max-width: 100%;
    height: auto;
    border-radius: 0.25rem;
    margin: 0.25rem 0;
}

.rich-body a {
    color: var(--ctl-link);
}

.rich-dropzone {
    display: none;
    position: absolute;
    inset: 0;
    background: rgba(var(--ctl-accent-rgb), 0.08);
    border: 2px dashed var(--ctl-accent);
    border-radius: 0.375rem;
    z-index: 5;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: var(--ctl-accent-text);
    font-weight: 500;
    pointer-events: none;
}

.rich-editor.dragging .rich-dropzone {
    display: flex;
}

.rich-attachments {
    padding: 0.35rem 0.5rem;
    border-top: 1px solid var(--ctl-border);
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.rich-attachment {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.5rem;
    background: var(--ctl-bg-alt);
    border-radius: 0.25rem;
    font-size: 0.75rem;
    color: var(--ctl-fg-muted);
}

.rich-attachment-remove {
    cursor: pointer;
    color: var(--ctl-danger-text);
    font-size: 0.65rem;
}

.rich-attachment-remove:hover {
    color: var(--ctl-danger);
}

.rich-uploading {
    opacity: 0.5;
    font-style: italic;
}

/* API method labels */
.api-method {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 700;
    padding: 0.1rem 0.35rem;
    border-radius: 0.2rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-family: monospace;
}

.api-method-get { background: var(--ctl-success-bg); color: var(--ctl-success-text); }
.api-method-post { background: var(--ctl-info-bg); color: var(--ctl-info-text); }
.api-method-patch { background: var(--ctl-warning-bg); color: var(--ctl-warning-text); }
.api-method-delete { background: var(--ctl-danger-bg); color: var(--ctl-danger-text); }

.api-endpoint-row:hover {
    background: var(--ctl-bg-hover);
}

/* Ticket comments */
.ticket-comments {
    max-height: 50vh;
    overflow-y: auto;
}

.ticket-comment {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--ctl-border);
}

.ticket-comment:last-child {
    border-bottom: none;
}

.comment-header {
    display: flex;
    align-items: center;
    margin-bottom: 0.25rem;
}

.comment-body {
    font-size: 0.85rem;
    line-height: 1.5;
}

.comment-time {
    margin-top: 0.25rem;
}

.comment-internal {
    background: var(--ctl-warning-bg);
    border-left: 3px solid var(--ctl-warning);
}

.comment-system {
    background: var(--ctl-bg-alt);
    color: var(--ctl-fg-muted);
    font-style: italic;
}

.comment-system .comment-body {
    font-size: 0.8rem;
}

/* Ticket tags */
.ticket-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.ticket-tag-dot {
    display: inline-block;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    flex-shrink: 0;
}

.ticket-tag-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: inherit;
    font-size: 0.85rem;
    line-height: 1;
    padding: 0;
    margin-left: 0.1rem;
    cursor: pointer;
    opacity: 0.6;
}

.ticket-tag-remove:hover {
    opacity: 1;
}

/* Print styles */
@media print {
    .sidebar,
    .top-navbar,
    .btn,
    .pagination {
        display: none !important;
    }

    .main-content {
        margin-left: 0;
        width: 100%;
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   MRP PLANNER WORKBENCH
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Time-Phased Grid ─────────────────────────────────────────────────── */
.mrp-grid { border-collapse: separate; border-spacing: 0; }
.mrp-grid th, .mrp-grid td { padding: 0.25rem 0.5rem; text-align: right; white-space: nowrap; font-size: 0.8rem; border-bottom: 1px solid var(--ctl-border); }
.mrp-grid .mrp-grid-label { text-align: left; font-weight: 500; position: sticky; left: 0; z-index: 5; background: var(--ctl-bg-elevated); min-width: 180px; }
.mrp-grid .mrp-grid-header-label { text-align: left; position: sticky; left: 0; z-index: 11; background: var(--ctl-bg-alt); min-width: 180px; }
.mrp-grid .mrp-grid-header { text-align: center; font-size: 0.7rem; text-transform: uppercase; color: var(--ctl-fg-muted); font-weight: 500; min-width: 80px; }
.mrp-grid .mrp-grid-row-demand td { background: rgba(var(--bs-primary-rgb), 0.03); }
.mrp-grid .mrp-grid-row-supply td { background: rgba(var(--bs-success-rgb), 0.03); }
.mrp-grid .mrp-grid-row-planned td { background: rgba(var(--bs-info-rgb), 0.03); }
.mrp-grid .mrp-grid-row-projected td { border-top: 2px solid var(--ctl-border); }
.mrp-grid .mrp-grid-subrow td { font-size: 0.75rem; color: var(--ctl-fg-muted); }
.mrp-grid .mrp-grid-subrow .mrp-grid-label { font-weight: 400; }
.mrp-grid-cell.negative { color: var(--ctl-danger-text) !important; font-weight: 700; }
.mrp-grid-cell.has-planned { color: var(--ctl-accent-text); font-weight: 600; }

/* Planning fence indicators */
.mrp-fence-dtf { border-left: 2px dashed var(--ctl-warning); }
.mrp-fence-ptf { border-left: 2px dashed var(--ctl-info); }

/* ─── Demand Trace Path ────────────────────────────────────────────────── */
.trace-path { font-family: var(--bs-font-monospace); font-size: 0.8rem; }
.trace-path-segment { color: var(--ctl-link); cursor: pointer; text-decoration: none; }
.trace-path-segment:hover { text-decoration: underline; }
.trace-path-separator { color: var(--ctl-fg-muted); margin: 0 0.25rem; }
.trace-path-phantom { color: var(--ctl-warning-text); font-style: italic; }

/* ─── Demand Trace Tree ────────────────────────────────────────────────── */
.trace-tree-node { padding: 0.2rem 0; border-bottom: 1px solid var(--ctl-border); }
.trace-tree-toggle { cursor: pointer; user-select: none; }
.trace-tree-qty { font-weight: 600; min-width: 60px; display: inline-block; text-align: right; margin-right: 0.5rem; }
.trace-tree-doc { color: var(--ctl-fg-muted); font-size: 0.8rem; }

/* ─── MRP Exception Severity ──────────────────────────────────────────── */
.mrp-severity-critical { color: var(--ctl-danger-text); font-weight: 700; }
.mrp-severity-warning { color: var(--ctl-warning-text); font-weight: 600; }
.mrp-severity-informational { color: var(--ctl-fg-muted); }

/* ─── Safety Stock Delta Colors ────────────────────────────────────────── */
.ss-delta-increase { color: var(--ctl-danger-text); }
.ss-delta-decrease { color: var(--ctl-success-text); }
.ss-delta-zero { color: var(--ctl-fg-muted); }

/* ============================================================
   UEE Branded Toast + Modal — replaces native alert() / confirm()
   See window.uee.toast() and window.uee.confirm() in app.js.
   ============================================================ */

.uee-toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: var(--ctl-z-toast);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 420px;
    pointer-events: none;
}
.uee-toast {
    pointer-events: auto;
    padding: 0.75rem 2.5rem 0.75rem 1rem;
    border-radius: 0.5rem;
    background: var(--ctl-bg-elevated);
    color: var(--ctl-fg);
    border: 1px solid var(--ctl-border);
    border-left: 4px solid var(--ctl-accent);
    box-shadow: 0 4px 16px var(--ctl-shadow-hover);
    font-size: 0.875rem;
    line-height: 1.4;
    position: relative;
    cursor: pointer;
    animation: uee-toast-in 0.2s ease-out;
    word-wrap: break-word;
}
.uee-toast.is-leaving { animation: uee-toast-out 0.18s ease-in forwards; }
.uee-toast.success  { border-left-color: var(--ctl-success); }
.uee-toast.error    { border-left-color: var(--ctl-danger); }
.uee-toast.warning  { border-left-color: var(--ctl-warning); }
.uee-toast.info     { border-left-color: var(--ctl-info); }
.uee-toast-title {
    font-weight: 600;
    margin-bottom: 0.15rem;
    color: var(--ctl-fg);
}
.uee-toast-close {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    background: none;
    border: 0;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--ctl-fg-muted);
    padding: 0.15rem 0.4rem;
    cursor: pointer;
}
.uee-toast-close:hover { color: var(--ctl-fg); }
@keyframes uee-toast-in  { from { transform: translateX(110%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes uee-toast-out { to   { transform: translateX(110%); opacity: 0; } }

.uee-modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1090; /* z literal kept: must top the AI chat panel (1040) and Bootstrap's modal stack */
    display: flex; align-items: center; justify-content: center;
    animation: uee-modal-fade-in 0.15s ease-out;
}
.uee-modal {
    background: var(--ctl-bg-elevated);
    border-radius: 0.5rem;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    max-width: 460px;
    width: 90%;
    overflow: hidden;
    animation: uee-modal-pop-in 0.18s ease-out;
}
.uee-modal-header {
    padding: 0.85rem 1.25rem;
    border-bottom: 1px solid var(--ctl-border);
    font-weight: 600;
    color: var(--ctl-fg);
}
.uee-modal-body {
    padding: 1.25rem;
    color: var(--ctl-fg);
}
.uee-modal-footer {
    padding: 0.75rem 1.25rem;
    background: var(--ctl-bg-alt);
    border-top: 1px solid var(--ctl-border);
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}
@keyframes uee-modal-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes uee-modal-pop-in  { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }

/* === Section rail (record template) === */
/* Detail + create pages: left rail of schema sections, body pane where the
   selected sections stack in schema order. See partials/record_sections.php
   and js/record-sections.js. Values adapted from the approved v3 mockup. */

.rail-wrap {
    display: flex;
    border: 1px solid var(--ctl-border);
    border-radius: 0.5rem;
    background: var(--ctl-bg-elevated);
    box-shadow: 0 1px 3px var(--ctl-shadow);
    min-height: 20rem;
    /* No overflow:hidden here — it would make the wrap the sticky reference
       for .rail-nav and defeat the page-scroll stickiness. Corner clipping is
       handled by radii on .rail-nav itself. */
}

/* The nav is sticky inside the page's scroll container (.detail-page-body),
   with its own scrollbar past viewport height — the section list never
   scrolls out of view while the body pane (and any child tables below the
   form) scroll normally. The divider lives on .rail-body so it always spans
   the full wrap height regardless of nav height. */
.rail-nav {
    width: 11.5rem;
    flex-shrink: 0;
    padding: 0.5rem 0;
    background: var(--ctl-bg);
    position: sticky;
    top: 0;
    align-self: flex-start;
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
    border-radius: calc(0.5rem - 1px) 0 0 calc(0.5rem - 1px);
}

/* Minimize toggle — chevron strip at the top of the nav. Collapsed, the nav
   shrinks to a slim strip (items hidden); click anywhere on it to expand,
   matching the main sidebar's collapsed behavior. State in localStorage. */
.rail-collapse {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    border: none;
    background: none;
    color: var(--ctl-fg-muted);
    padding: 0.1rem 0.6rem 0.35rem;
    font-size: 0.75rem;
    cursor: pointer;
}

.rail-collapse:hover {
    color: var(--ctl-accent-text);
}

.rail-wrap.rail-collapsed .rail-nav {
    width: 1.75rem;
    overflow: hidden;
    cursor: pointer;
}

.rail-wrap.rail-collapsed .rail-item {
    display: none;
}

.rail-wrap.rail-collapsed .rail-collapse {
    justify-content: center;
    padding: 0.35rem 0;
}

.rail-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    text-align: left;
    border: none;
    background: none;
    padding: 0.4rem 0.8rem;
    font-size: 0.82rem;
    color: var(--ctl-fg-muted);
    cursor: pointer;
    border-left: 3px solid transparent;
    position: relative;
}

.rail-item:hover {
    color: var(--ctl-fg);
    background: var(--ctl-bg-hover);
}

.rail-item.on {
    color: var(--ctl-accent-text);
    border-left-color: var(--ctl-accent);
    background: rgba(var(--ctl-accent-rgb), 0.1);
    font-weight: 600;
}

.rail-item .rail-check {
    font-size: 0.8rem;
    width: 1.5rem;
    padding: 0.15rem 0.25rem 0.15rem 0;
    margin: -0.15rem 0;
    color: var(--ctl-fg-faint);
    border-radius: 0.2rem;
}

.rail-item .rail-check:hover {
    color: var(--ctl-accent-text);
    background: rgba(var(--ctl-accent-rgb), 0.15);
}

.rail-item.on .rail-check {
    color: var(--ctl-accent-text);
}

.rail-item .err-dot {
    position: absolute;
    right: 0.7rem;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--ctl-danger);
}

.rail-item.disabled {
    color: var(--ctl-fg-faint);
    pointer-events: none;
}

.rail-item.rail-all {
    border-bottom: 1px solid var(--ctl-border);
    margin-bottom: 0.35rem;
    padding-bottom: 0.45rem;
}

.rail-item.rail-all .rail-check {
    color: var(--ctl-fg-muted);
}

.rail-body {
    flex: 1;
    padding: 0.75rem 1rem;
    min-width: 0;
    border-left: 1px solid var(--ctl-border);
}

.rail-section {
    display: none;
    margin-bottom: 1.1rem;
}

.rail-section.on {
    display: block;
}

.rail-empty {
    display: none;
    color: var(--ctl-fg-muted);
    font-size: 0.85rem;
    padding: 2rem;
    text-align: center;
}

/* Two-column field grid inside a section on lg+. Multi-line text fields span
   both columns via .grid-col-span-2. */
.row-2col {
    display: grid;
    grid-template-columns: 1fr;
    column-gap: 2.5rem;
}

@media (min-width: 992px) {
    .row-2col {
        grid-template-columns: 1fr 1fr;
    }
    .row-2col .grid-col-span-2 {
        grid-column: 1 / -1;
    }
}

/* Multi-line text: label above, value below full width, scroll past ~14rem.
   Applies in both display and edit/create (textarea full width). */
.detail-row.detail-row-block {
    display: block;
}

.detail-row-block .detail-label {
    display: block;
    margin-bottom: 0.2rem;
}

.detail-row-block .detail-view {
    display: block;
    white-space: pre-wrap;
    background: var(--ctl-bg-inset);
    border: 1px solid var(--ctl-border);
    border-radius: 0.25rem;
    padding: 0.4rem 0.6rem;
    max-height: 14rem;
    overflow-y: auto;
}

.detail-row-block textarea.detail-input,
.detail-row-block textarea {
    display: block;
    width: 100%;
}

/* ── json_tree.php — recursive, typed view of arbitrary-shape JSON ──────── */
.json-tree {
    font-size: 0.85rem;
    line-height: 1.4;
}

/* Object: a stack of label / value rows. */
.json-tree-row {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding: 0.15rem 0;
    border-bottom: 1px solid var(--ctl-border);
}

.json-tree-row:last-child {
    border-bottom: none;
}

.json-tree-key {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ctl-fg-muted);
    min-width: 9rem;
    flex-shrink: 0;
}

.json-tree-val {
    flex: 1;
    min-width: 0;
    word-break: break-word;
}

/* Nested objects/lists indent under their key for visual hierarchy. */
.json-tree-val > .json-tree-object,
.json-tree-val > .json-tree-list {
    border-left: 2px solid var(--ctl-border);
    padding-left: 0.6rem;
    margin-top: 0.15rem;
}

/* List of objects: index-labeled blocks. */
.json-tree-list-item {
    display: flex;
    gap: 0.5rem;
    padding: 0.2rem 0;
}

.json-tree-list-item + .json-tree-list-item {
    border-top: 1px dashed var(--ctl-border);
}

.json-tree-index {
    font-size: 0.7rem;
    font-weight: 600;
    flex-shrink: 0;
    min-width: 2rem;
}

.json-tree-list-body {
    flex: 1;
    min-width: 0;
}

/* List of scalars: wrapping badge row. */
.json-tree-inline .badge {
    font-weight: 500;
}

/* Raw JSON fallback + the collapsible citation block. */
.json-tree-raw {
    font-size: 0.78rem;
    background: var(--ctl-bg-inset);
    border: 1px solid var(--ctl-border);
    border-radius: 0.25rem;
    padding: 0.5rem 0.7rem;
    max-height: 20rem;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.json-tree-rawtoggle summary {
    cursor: pointer;
    user-select: none;
}

/* Mobile: rail collapses to a wrapping chip row on top. */
@media (max-width: 768px) {
    .rail-wrap {
        flex-direction: column;
    }
    .rail-nav {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        gap: 0.25rem;
        border-bottom: 1px solid var(--ctl-border);
        padding: 0.5rem;
        position: static;
        max-height: none;
        overflow-y: visible;
    }
    .rail-body {
        border-left: none;
    }
    /* No minimize in chip-row mode — the chips ARE the compact form. */
    .rail-collapse {
        display: none;
    }
    .rail-wrap.rail-collapsed .rail-nav {
        width: 100%;
        overflow: visible;
        cursor: default;
    }
    .rail-wrap.rail-collapsed .rail-item {
        display: flex;
    }
    .rail-item {
        width: auto;
        border-left: none;
        border-radius: 1rem;
        border: 1px solid var(--ctl-border);
        padding: 0.2rem 0.7rem;
    }
    .rail-item.on {
        border-color: var(--ctl-accent);
    }
    .rail-item .err-dot {
        position: static;
        margin-left: 0.3rem;
    }
}

/* Field help — subtle question-mark tooltip beside a field label. Rendered by
   record_sections.php when a schema column carries a 'help' string. */
.field-help {
    color: var(--ctl-fg-muted);
    font-size: 0.7rem;
    cursor: help;
}
.field-help:hover {
    color: var(--ctl-accent-text);
}

/* ═══════════════════════════════════════════════════════════════════════════
   MDT CENTRAL COMPONENT KIT (UI_STANDARDS.md §6 — Phase B contracts)
   All values from --ctl-* tokens only; every class must hold in all six
   style/scheme sheets and both densities. Markup partners live in
   templates/partials/ (page_header.php, labeled_field.php, simple_table.php,
   empty_state.php, ...). JS partner for .ctl-popover is js/popover.js.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Page header (page_header.php — list + detail modes) ─────────────────── */
.ctl-page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ctl-sp-2) var(--ctl-sp-4);
    margin-bottom: var(--ctl-sp-4);
}

.ctl-page-header-title {
    margin: 0;
    font-family: var(--ctl-font-display);
    font-size: var(--ctl-fs-display-md);
    font-weight: 700;
    line-height: var(--ctl-lh-tight);
    text-transform: uppercase;
    letter-spacing: -0.025em;
    color: var(--ctl-fg);
    display: inline-flex;
    align-items: center;
    gap: var(--ctl-sp-2);
    min-width: 0;
}

/* Count badge riding inline with the title (--list mode) — body face, not
   Oswald, so the numeral doesn't inherit the display treatment. */
.ctl-page-header-title .badge,
.ctl-page-header-count {
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-caption);
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: var(--ctl-lh-snug);
}

.ctl-page-header-sub {
    margin: var(--ctl-sp-1) 0 0;
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-body-sm);
    font-weight: 400;
    line-height: var(--ctl-lh-normal);
    letter-spacing: normal;
    text-transform: none;
    color: var(--ctl-fg-muted);
}

/* 48×4 accent rule — the §4.4 heavy-accent signature bar. border/opacity
   reset so an <hr> renders identically to a <div>. */
.ctl-page-header-rule {
    width: 48px;
    height: 4px;
    background: var(--ctl-accent);
    border: 0;
    opacity: 1;
    margin: var(--ctl-sp-2) 0 0;
}

.ctl-page-header-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ctl-sp-2);
    margin-left: auto;
}

/* --list: sits directly above a table; tighter bottom gap, vertically
   centered so the count badge and actions align with the title midline. */
.ctl-page-header--list {
    align-items: center;
    margin-bottom: var(--ctl-sp-3);
}

/* --detail: mirrors the legacy .detail-page-header spacing (style.css) so the
   fixed-header/scrollable-body detail layout keeps its exact rhythm. */
.ctl-page-header--detail {
    flex-shrink: 0;
    border-bottom: 1px solid var(--ctl-border);
    padding-bottom: 0.35rem;
    margin-bottom: 0.5rem;
}

/* ── Labeled field (labeled_field.php — the only sanctioned control wrapper) */
.ctl-field {
    margin-bottom: var(--ctl-sp-3);
}

.ctl-field-label {
    display: block;
    font-size: var(--ctl-fs-label);
    font-weight: 500;
    margin-bottom: 0.15rem;
    color: var(--ctl-fg);
}

.ctl-field-help {
    margin-top: 0.1rem;
    font-size: var(--ctl-fs-body-sm);
    color: var(--ctl-fg-muted);
}

.ctl-field-error {
    margin-top: 0.1rem;
    font-size: var(--ctl-fs-body-sm);
    color: var(--ctl-danger-text);
}

/* ── Simple table (simple_table.php — list_table minus column prefs) ─────── */
/* Wrapper owns horizontal overflow (§8: tables scroll inside their own
   container, the page never scrolls sideways). Inner .table inherits the
   global table treatment above. Row-click affordance keys on data-row-url —
   the delegated navigator in app.js — so cursor and behavior always agree. */
.ctl-table-simple {
    overflow-x: auto;
}

.ctl-table-simple > .table {
    margin-bottom: 0;
}

.ctl-table-simple tr[data-row-url] {
    cursor: pointer;
}

/* Embedded/flush tables (§6): when a table sits edge-to-edge inside a card or
   scroll wrapper, its first/last cells carry the card's content padding so
   text aligns with sibling card-body content instead of touching the edge
   (stakeholder finding 2026-07-21: notification prefs, status management,
   schema browser). */
.ctl-table-simple > .table > :not(caption) > * > *:first-child,
.table-responsive > .table > :not(caption) > * > *:first-child,
.card > .card-body.p-0 .table > :not(caption) > * > *:first-child,
.card > .table > :not(caption) > * > *:first-child {
    padding-inline-start: var(--ctl-sp-4);
}
.ctl-table-simple > .table > :not(caption) > * > *:last-child,
.table-responsive > .table > :not(caption) > * > *:last-child,
.card > .card-body.p-0 .table > :not(caption) > * > *:last-child,
.card > .table > :not(caption) > * > *:last-child {
    padding-inline-end: var(--ctl-sp-4);
}

/* ── Empty state (empty_state.php) ───────────────────────────────────────── */
.ctl-empty-state {
    text-align: center;
    padding: var(--ctl-sp-7) var(--ctl-sp-5);
    color: var(--ctl-fg-muted);
}

.ctl-empty-state-icon {
    display: block;
    font-size: 2rem;
    line-height: 1;
    color: var(--ctl-fg-faint); /* decorative — the title carries the info */
    margin-bottom: var(--ctl-sp-3);
}

.ctl-empty-state-title {
    margin: 0 0 var(--ctl-sp-2);
    font-family: var(--ctl-font-display);
    font-size: var(--ctl-fs-display-sm);
    font-weight: 700;
    line-height: var(--ctl-lh-tight);
    text-transform: uppercase;
    letter-spacing: -0.025em;
    color: var(--ctl-fg);
}

.ctl-empty-state-body {
    max-width: 46ch;
    margin: 0 auto;
    color: var(--ctl-fg-muted);
}

.ctl-empty-state-action {
    margin-top: var(--ctl-sp-4);
}

/* ── Section label ───────────────────────────────────────────────────────── */
/* THE uppercase micro-label. The audit found 8 hand-rolled copies of this
   idiom (.nav-history-title, .notification-dropdown-title, .col-settings-title,
   .detail-label, .detail-section-title, .drilldown-title, .json-tree-key,
   .login-core-label); they migrate here in the conformance task. System stack
   (not Lato) per §2 stakeholder legibility decision. */
.ctl-section-label {
    margin: 0 0 var(--ctl-sp-2);
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-caption);
    font-weight: 700;
    line-height: var(--ctl-lh-snug);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ctl-fg-subtle);
}

/* ── Pagination (table_status_bar.php extended — one shared partial) ─────── */
/* Nav landmark wrapper. The inner list is Bootstrap .pagination; sizing here
   reproduces the status bar's `pagination-sm mb-0` look without the utility
   soup, and the accent override below themes the active page in all sheets. */
.ctl-pagination {
    display: flex;
    align-items: center;
}

.ctl-pagination .pagination {
    margin-bottom: 0;
    --bs-pagination-padding-y: 0.25rem;
    --bs-pagination-padding-x: 0.5rem;
    --bs-pagination-font-size: var(--ctl-fs-body-sm);
}

/* Active page was Bootstrap literal blue (#0d6efd) in every list. Accent fill
   + accent-fg glyph (§4.5: black-on-green 7.32:1, white-on-blue 4.55:1). */
.pagination {
    --bs-pagination-active-bg: var(--ctl-accent);
    --bs-pagination-active-border-color: var(--ctl-accent);
    --bs-pagination-active-color: var(--ctl-accent-fg);
    --bs-pagination-focus-box-shadow: var(--ctl-focus-ring);
}

/* ── Popover shell (js/popover.js — uee.popover.attach) ──────────────────── */
/* One anchored-panel primitive replacing the hand-rolled dropdown shells
   (.nav-history-dropdown migrated; notifications, gear panel, perm-add next).
   The panel is absolutely positioned inside a position:relative host (attach()
   ensures the host is positioned). JS toggles .open, and flips/aligns with the
   --above/--start modifiers after measuring the viewport. */
.ctl-popover {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 240px;
    max-width: min(92vw, 380px); /* §6 contract */
    background: var(--ctl-bg-elevated);
    color: var(--ctl-fg);
    border: 1px solid var(--ctl-border);
    border-radius: var(--ctl-radius);
    box-shadow: 0 4px 12px var(--ctl-shadow-hover);
    z-index: var(--ctl-z-dropdown);
}

.ctl-popover.open {
    display: block;
}

/* Shells whose body scrolls (notifications-style header/body/footer stacks)
   opt into a flex column via opts.flex. */
.ctl-popover--flex.open {
    display: flex;
    flex-direction: column;
}

.ctl-popover--above {
    top: auto;
    bottom: calc(100% + 4px);
}

.ctl-popover--start {
    right: auto;
    left: 0;
}

/* ── Form control accents (§4.5) ─────────────────────────────────────────── */
/* Bootstrap ships literal blue (#0d6efd) for checked checks/switches and a
   literal near-black select arrow. Overrides below route them through the
   accent tokens. Glyph colors can't use var() inside url(), so the SVGs are
   declared as custom properties and keyed the same way the token sheets are:
   glyph-on-accent follows the STYLE (accent-fg: black on MDT green for
   Industrial/Operator, white on blue for Refined — §4.5), neutral glyphs
   follow the SCHEME (light/dark).
   Contrast (computed 2026-07-21, WCAG 2.1):
     check/knob black on green #86a33d  7.32:1   white on blue #2f6fed 4.55:1
     select arrow #5c5c5c on light insets ≥6.27:1 (#fff 6.69, #f8f8f8 6.30,
       #f5f8fb 6.27); #9a9a9a on dark insets ≥6.41:1 (#0d0d0d 6.91,
       #0a1727 6.41, #0e0e0c 6.87)
   Accent-colored arrow was rejected: green on white is 2.87:1 (<3:1 UI
   graphics minimum), so the arrow stays neutral fg-muted-tone. The checked
   fill itself follows the primary-button precedent (§4.5): the glyph carries
   the ≥3:1 state contrast, not the fill boundary. */
:root {
    --ctl-check-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
    --ctl-radio-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23000'/%3e%3c/svg%3e");
    --ctl-dash-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
    --ctl-switch-knob-checked: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23000'/%3e%3c/svg%3e");
    --ctl-switch-knob: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%235c5c5c'/%3e%3c/svg%3e");
    --ctl-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%235c5c5c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

html[data-bs-theme="dark"] {
    --ctl-switch-knob: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239a9a9a'/%3e%3c/svg%3e");
    --ctl-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%239a9a9a' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

html[data-style="refined"] {
    --ctl-check-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
    --ctl-radio-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e");
    --ctl-dash-svg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
    --ctl-switch-knob-checked: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
}

.form-select {
    --bs-form-select-bg-img: var(--ctl-select-arrow);
}

.form-check-input:checked {
    background-color: var(--ctl-accent);
    border-color: var(--ctl-accent);
}

.form-check-input:focus {
    border-color: var(--ctl-accent);
    box-shadow: var(--ctl-focus-ring);
}

.form-check-input:checked[type="checkbox"] {
    --bs-form-check-bg-image: var(--ctl-check-svg);
}

.form-check-input:checked[type="radio"] {
    --bs-form-check-bg-image: var(--ctl-radio-svg);
}

.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--ctl-accent);
    border-color: var(--ctl-accent);
    --bs-form-check-bg-image: var(--ctl-dash-svg);
}

/* Switch knob: neutral when unchecked+focused (Bootstrap uses literal blue
   #86b7fe there), accent-fg when checked. Bootstrap's own dark-theme rule for
   unchecked-unfocused (higher specificity, translucent white) still applies —
   intentionally left alone, it's already neutral. */
.form-switch .form-check-input,
.form-switch .form-check-input:focus {
    --bs-form-switch-bg: var(--ctl-switch-knob);
}

.form-switch .form-check-input:checked {
    --bs-form-switch-bg: var(--ctl-switch-knob-checked);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ── WIDGET KIT ──  MDT Central dashboard widgets (stakeholder-signed 2026-07-22)
   Translates the approved KPI / pipeline / alert / queue sample treatments onto
   --ctl-* tokens: elevated-surface cards, 1px borders, radius token, §4.3 status
   washes for RAG/severity, fg-subtle micro-labels, Oswald tabular numerals, and
   a single-hue sequential ramp for pipeline segments. Works across all six
   sheets + both densities. Consumed by templates/partials/widgets/*.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Sequential ramp tokens (dataviz) ─────────────────────────────────────────
   Green ramp is the default (Operator + Industrial, light & dark); Refined
   overrides to the blue ramp. Steps 1-2 are light (dark ink), steps 3-4 are dark
   (white ink) — validated for contrast against the segment fill itself, so the
   ramp is scheme-invariant (segments carry their own background). */
:root {
    --ctl-seq-1: #e7ecd3;  --ctl-seq-1-ink: #141414;
    --ctl-seq-2: #9fbc50;  --ctl-seq-2-ink: #141414;
    --ctl-seq-3: #6d8730;  --ctl-seq-3-ink: #ffffff;
    --ctl-seq-4: #47591f;  --ctl-seq-4-ink: #ffffff;
}
html[data-style="refined"] {
    --ctl-seq-1: #d8e4fb;  --ctl-seq-1-ink: #0b1a2e;
    --ctl-seq-2: #6a9bff;  --ctl-seq-2-ink: #0b1a2e;
    --ctl-seq-3: #2258c9;  --ctl-seq-3-ink: #ffffff;
    --ctl-seq-4: #142f6b;  --ctl-seq-4-ink: #ffffff;
}

/* ── Card shell ─────────────────────────────────────────────────────────────*/
.ctl-widget {
    display: flex;
    flex-direction: column;
    gap: var(--ctl-sp-2);
    background: var(--ctl-bg-elevated);
    border: 1px solid var(--ctl-border);
    border-radius: var(--ctl-radius-lg);
    padding: var(--ctl-sp-4);
    box-shadow: 0 1px 2px var(--ctl-shadow);
    color: var(--ctl-fg);
    min-width: 0;
}
.ctl-widget--linked { position: relative; }
/* Whole-card drill-down: a stretched native anchor beneath the content. The
   [AI Ask] button (z-index above) stays clickable inside a linked card. */
.ctl-widget-drill {
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
}
.ctl-widget--linked:hover { border-color: var(--ctl-border-strong); box-shadow: 0 2px 6px var(--ctl-shadow-hover); }
.ctl-widget--linked:focus-within { box-shadow: var(--ctl-focus-ring); }

.ctl-widget-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ctl-sp-2);
    position: relative;
    z-index: 1;
    pointer-events: none; /* text falls through to a linked card's drill overlay */
}
.ctl-widget-microlabel {
    font-size: var(--ctl-fs-caption);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ctl-fg-subtle);
    line-height: var(--ctl-lh-snug);
}

/* [AI Ask] — small outlined button, above the drill overlay. */
.ctl-widget-ai-ask {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--ctl-font-body);
    font-size: var(--ctl-fs-caption);
    line-height: 1;
    padding: 3px 8px;
    background: transparent;
    color: var(--ctl-fg-muted);
    border: 1px solid var(--ctl-border-strong);
    border-radius: var(--ctl-radius);
    cursor: pointer;
    position: relative;
    z-index: 2;
    pointer-events: auto; /* re-enable over the header's pointer-events:none */
    transition: color var(--ctl-dur-fast), border-color var(--ctl-dur-fast);
}
.ctl-widget-ai-ask:hover,
.ctl-widget-ai-ask:focus-visible {
    color: var(--ctl-accent-text);
    border-color: var(--ctl-accent);
}

.ctl-widget-empty {
    margin: 0;
    color: var(--ctl-fg-muted);
    font-size: var(--ctl-fs-body-sm);
}

/* ── RAG chip (KPI) / severity chip (alerts) — status washes ────────────────*/
.ctl-widget-rag,
.ctl-widget-sev {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--ctl-fs-caption);
    font-weight: 600;
    line-height: 1;
    padding: 3px 8px;
    border-radius: var(--ctl-radius-full);
    white-space: nowrap;
}
.ctl-widget-rag-dot,
.ctl-widget-sev-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}
.ctl-widget-rag--success { background: var(--ctl-success-bg); color: var(--ctl-success-text); }
.ctl-widget-rag--warning { background: var(--ctl-warning-bg); color: var(--ctl-warning-text); }
.ctl-widget-rag--danger  { background: var(--ctl-danger-bg);  color: var(--ctl-danger-text); }
.ctl-widget-rag--info    { background: var(--ctl-info-bg);    color: var(--ctl-info-text); }
.ctl-widget-sev--danger  { background: var(--ctl-danger-bg);  color: var(--ctl-danger-text); }
.ctl-widget-sev--warning { background: var(--ctl-warning-bg); color: var(--ctl-warning-text); }
.ctl-widget-sev--info    { background: var(--ctl-info-bg);    color: var(--ctl-info-text); }

/* ── KPI card ───────────────────────────────────────────────────────────────*/
.ctl-widget-kpi-value {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--ctl-sp-2);
    position: relative;
    z-index: 1;
    pointer-events: none; /* clicks fall through to the drill overlay */
}
.ctl-widget-kpi-number {
    font-family: var(--ctl-font-display);
    font-size: var(--ctl-fs-display-md);
    font-weight: 600;
    line-height: var(--ctl-lh-tight);
    font-variant-numeric: tabular-nums;
    color: var(--ctl-fg);
}
.ctl-widget-kpi-unit {
    font-size: var(--ctl-fs-body-sm);
    font-weight: 500;
    color: var(--ctl-fg-muted);
}
.ctl-widget-kpi-target {
    font-size: var(--ctl-fs-caption);
    color: var(--ctl-fg-subtle);
    position: relative;
    z-index: 1;
    pointer-events: none;
}
.ctl-widget-fill {
    height: 4px;
    border-radius: var(--ctl-radius-full);
    background: var(--ctl-bg-hover);
    overflow: hidden;
    position: relative;
    z-index: 1;
}
.ctl-widget-fill-bar {
    height: 100%;
    background: var(--ctl-accent);
    border-radius: inherit;
}

/* Sparkline — server-built inline SVG, full width, crisp 2px non-scaling line. */
.ctl-widget-spark {
    display: block;
    width: 100%;
    height: 32px;
    margin-top: var(--ctl-sp-1);
    position: relative;
    z-index: 1;
    pointer-events: none;
}
.ctl-widget-spark-line {
    stroke: var(--ctl-accent);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}
.ctl-widget-spark-end { fill: var(--ctl-accent); }

/* ── Pipeline ───────────────────────────────────────────────────────────────*/
.ctl-widget-pipeline-track {
    display: flex;
    align-items: stretch;
    gap: 2px;
}
.ctl-widget-seg-col {
    flex: 1 1 0;
    min-width: 44px;
    display: flex;
    flex-direction: column;
    gap: var(--ctl-sp-1);
    text-decoration: none;
    color: inherit;
}
.ctl-widget-seg {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    border-radius: var(--ctl-radius);
    padding: var(--ctl-sp-1) var(--ctl-sp-2);
}
.ctl-widget-seg-count {
    font-family: var(--ctl-font-display);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.ctl-widget-seg-label {
    font-size: var(--ctl-fs-caption);
    color: var(--ctl-fg-muted);
    text-align: center;
    line-height: var(--ctl-lh-snug);
}
a.ctl-widget-seg-col:hover .ctl-widget-seg,
a.ctl-widget-seg-col:focus-visible .ctl-widget-seg { filter: brightness(0.94); }
a.ctl-widget-seg-col:focus-visible { outline: none; box-shadow: var(--ctl-focus-ring); border-radius: var(--ctl-radius); }
.ctl-widget-seg--1 { background: var(--ctl-seq-1); color: var(--ctl-seq-1-ink); }
.ctl-widget-seg--2 { background: var(--ctl-seq-2); color: var(--ctl-seq-2-ink); }
.ctl-widget-seg--3 { background: var(--ctl-seq-3); color: var(--ctl-seq-3-ink); }
.ctl-widget-seg--4 { background: var(--ctl-seq-4); color: var(--ctl-seq-4-ink); }

/* ── Alerts + Queues shared rows ────────────────────────────────────────────*/
.ctl-widget-alert-list,
.ctl-widget-queue-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.ctl-widget-alert-row,
.ctl-widget-queue-row {
    display: flex;
    align-items: center;
    gap: var(--ctl-sp-2);
    padding: var(--ctl-sp-2) 0;
    border-top: 1px solid var(--ctl-border);
    text-decoration: none;
    color: var(--ctl-fg);
    font-size: var(--ctl-fs-body-sm);
}
.ctl-widget-alert-list > li:first-child .ctl-widget-alert-row,
.ctl-widget-queue-list > li:first-child .ctl-widget-queue-row { border-top: 0; }
a.ctl-widget-alert-row:hover,
a.ctl-widget-queue-row:hover { background: var(--ctl-bg-hover); }
a.ctl-widget-alert-row:focus-visible,
a.ctl-widget-queue-row:focus-visible { outline: none; box-shadow: var(--ctl-focus-ring); }
.ctl-widget-alert-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ctl-widget-alert-time {
    color: var(--ctl-fg-subtle);
    font-size: var(--ctl-fs-caption);
    white-space: nowrap;
    flex: 0 0 auto;
}

/* ── Queues ─────────────────────────────────────────────────────────────────*/
.ctl-widget-queue-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctl-widget-queue-sla { color: var(--ctl-fg-subtle); font-size: var(--ctl-fs-caption); white-space: nowrap; flex: 0 0 auto; }
.ctl-widget-queue-sla--bad { color: var(--ctl-danger-text); font-weight: 600; }
.ctl-widget-queue-count {
    font-family: var(--ctl-font-display);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--ctl-fg);
    flex: 0 0 auto;
    min-width: 2ch;
    text-align: right;
}

/* ── Density: compact tightens padding + numeral scale (§5) ─────────────────*/
html[data-density="compact"] .ctl-widget { padding: var(--ctl-sp-3); gap: var(--ctl-sp-1); }
html[data-density="compact"] .ctl-widget-kpi-number { font-size: var(--ctl-fs-display-sm); }
html[data-density="compact"] .ctl-widget-seg { min-height: 28px; }

/* ═══════════════════════════════════════════════════════════════════════════
   PHASE F — Accessibility & density: touch targets + post-audit mobile rules
   (UI_STANDARDS §5 density, §8 responsive tiers, §9 AA touch targets)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Phone (< 768px) rules for components added after the original mobile block.
   The audit flagged these as having no phone handling. Data tables (incl. the
   MRP grid) already scroll inside their .table-scroll wrapper (§8); the toast
   stack, widget grid, and MRP grid density are addressed here. The swap-engine
   nav progress bar (.uee-nav-progress) was reviewed — a full-width 3px strip
   pinned to the top of .main-content needs no phone-specific rule. ────────── */
@media (max-width: 768px) {
    /* Toasts: inset to both edges instead of a fixed 420px lane that overflows
       narrow viewports. Stays top-anchored; container itself is click-through. */
    .uee-toast-container {
        left: 0.5rem;
        right: 0.5rem;
        max-width: none;
    }

    /* MRP workbench grid: horizontal scroll is contained by its .table-scroll
       wrapper; on phones tighten the sticky row-label gutter and cell type so
       more period columns fit before the user has to scroll sideways. */
    .mrp-grid .mrp-grid-label,
    .mrp-grid .mrp-grid-header-label {
        min-width: 120px;
    }
    .mrp-grid th,
    .mrp-grid td {
        font-size: 0.75rem;
        padding: 0.2rem 0.35rem;
    }

    /* Phase E dashboard widget grid: force a single column. (Bootstrap's col-12
       base already stacks these; this is an explicit guard so any widget span
       collapses to full width on phones regardless of its col-* classes.) */
    .dashboard-widget-grid > [class*="col-"] {
        flex: 0 0 100%;
        max-width: 100%;
    }

    /* Check / switch controls: comfortable density is forced on phones (§5), so
       enlarge the control and give its row a ≥44px tap zone (§9). Left as
       display:block to preserve Bootstrap's float/negative-margin form-check
       layout; the min-height + label padding supply the finger target. Dense
       table checkboxes (.col-bulk-check) are excluded so grid rows stay compact. */
    .form-check:not(.col-bulk-check) {
        min-height: 44px;
        padding-top: 0.25rem;
        padding-bottom: 0.25rem;
    }
    .form-check:not(.col-bulk-check) .form-check-input {
        width: 1.25rem;
        height: 1.25rem;
    }
    .form-switch:not(.col-bulk-check) .form-check-input {
        width: 2.25rem;
        height: 1.25rem;
    }
    .form-check:not(.col-bulk-check) .form-check-label {
        padding: 0.35rem 0;
    }
}

/* ── Coarse-pointer touch targets (§9 — extends the AI panel's 44px standard
   app-wide). Keyed on (pointer: coarse) so desktop pointer:fine visuals are
   never inflated. Two techniques: grow the control to ≥44px where the extra
   size is harmless (toolbar/icon buttons, pagination, rail items), or expand
   an invisible ::after hit area where the visual must stay compact (dense
   table header trigger, the small widget [AI Ask] pill). ─────────────────── */
@media (pointer: coarse) {
    /* Detail-page toolbar icon buttons (were 2rem) */
    .detail-tool {
        min-width: 44px;
        min-height: 44px;
    }

    /* Rich-editor toolbar buttons (were 1.75rem; toolbar wraps, so growth is safe) */
    .rich-toolbar-btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* Sidebar rail items (main rail on tablet tier, off-canvas rail on phone),
       footer items, and second-panel links */
    .sidebar .nav-link,
    .sidebar-footer .nav-link,
    .sidebar-panel-link {
        min-height: 44px;
    }

    /* Pagination page links */
    .page-link {
        min-width: 44px;
        min-height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Column header menu/filter trigger — the glyph must stay tiny inside the
       dense header, so expand the hit area with a centered ::after overlay. */
    .col-menu-trigger {
        position: relative;
    }
    .col-menu-trigger::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        min-width: 44px;
        min-height: 44px;
    }

    /* Widget [AI Ask] — keep the small outlined pill visual; expand its tap
       target with a centered ::after (the button is already position:relative). */
    .ctl-widget-ai-ask::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        min-width: 44px;
        min-height: 44px;
    }
}

/* Skip link (§9) — visually-hidden-focusable handles the hiding; this styles
   the focused state so keyboard users see a clear, branded affordance. */
.skip-link:focus {
    position: fixed;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--ctl-z-toast);
    background: var(--ctl-accent);
    color: var(--ctl-accent-fg);
    padding: 10px 18px;
    font-weight: 700;
    text-decoration: none;
    border-radius: var(--ctl-radius);
}

/* ── Usage Flow Map (merged from master #780, tokens migrated --uee → --ctl) ──
   Read-only workflow-style node graph of the app's screens. Mirrors the
   workflow-engine canvas visual language; hover/dim state driven by classes. */
#usage-flow-wrap {
    position: relative;
    height: calc(100vh - 220px);
    min-height: 480px;
    border: 1px solid var(--ctl-border);
    border-radius: var(--ctl-radius-lg);
    background: var(--ctl-bg);
    overflow: hidden;
}
#usage-flow-canvas {
    width: 100%;
    height: 100%;
    display: block;
    background: var(--ctl-bg);
}

/* Toolbar (zoom in/out/fit) pinned top-right inside the canvas wrap. */
#usage-flow-wrap .usage-flow-toolbar {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 5;
    display: flex;
    gap: 4px;
}

/* Empty-state overlay shown when the window has no navigation data. */
#usage-flow-wrap .usage-flow-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 4;
    pointer-events: none;
}

/* Node cards — same fill/stroke roles the WFE editor node rects use. */
.uflow-node {
    cursor: pointer;
    transition: opacity 0.12s ease;
}
.uflow-node .uflow-card {
    fill: var(--ctl-bg-elevated);
    stroke: var(--ctl-border-strong);
    stroke-width: 1.5;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.12));
}
.uflow-node:hover .uflow-card {
    stroke: var(--ctl-accent);
    stroke-width: 2;
}
.uflow-t1 {
    fill: var(--ctl-fg);
    font-size: 13px;
    font-weight: 600;
    pointer-events: none;
}
.uflow-t2 {
    fill: var(--ctl-fg-muted);
    font-size: 10px;
    pointer-events: none;
}

/* Edges default translucent; hover raises the connected ones and dims the rest. */
.uflow-edge {
    opacity: 0.55;
    transition: opacity 0.12s ease;
}
.uflow-edge.uflow-hot { opacity: 1; }
.uflow-edge.uflow-dim { opacity: 0.15; }
.uflow-node.uflow-dim { opacity: 0.15; }

/* Secondary ("crossover") edges — hidden until the shuffle toolbar button
   toggles .uflow-show-secondary on the SVG. Dashed + fainter so they never
   compete with the solid primary flow. */
.uflow-edge-secondary {
    display: none;
    stroke-dasharray: 6 5;
    opacity: 0.3;
}
svg.uflow-show-secondary .uflow-edge-secondary { display: initial; }
#flow-toggle-secondary.active {
    color: var(--ctl-accent-fg);
    background-color: var(--ctl-accent);
    border-color: var(--ctl-accent);
}
