/* =============================================================================
   Closina Theme - CSS Variable Token System (Phase U01)
   =============================================================================
   Load order: After MudBlazor + Syncfusion, before standardgrid.
   This file defines the design token system and global component overrides.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. Design Tokens (Light Mode)
   ----------------------------------------------------------------------------- */
:root {
    /* Primary Tokens - Emerald green (brand identity)
       Phase P02: Darkened from Emerald-600 (#059669, 3.77:1) to Emerald-700 (#047857, 5.48:1)
       for WCAG AA contrast compliance on filled buttons with white text. */
    --closina-primary: #047857;              /* Emerald-700 (5.48:1 on white — AA compliant) */
    --closina-primary-hover: #065f46;        /* Emerald-800 */
    --closina-primary-darker: #0a4d8c;        /* Blue-700 — AA on light bg ≥ 5:1 (Syncfusion pager link override, U69) */
    --closina-primary-light: rgba(4, 120, 87, 0.08);
    --closina-primary-border: rgba(4, 120, 87, 0.2);
    --closina-primary-text: #ffffff;
    --closina-secondary: #334155;            /* Slate-700 (neutral secondary) */
    --closina-secondary-hover: #1e293b;      /* Slate-800 */
    --closina-link: #047857;                /* Same as primary — AA compliant (5.48:1) */
    --closina-btn-height: 44px;              /* Touch-first (44px minimum) */

    /* Surface Tokens - Warm neutrals (not pure white) */
    --closina-surface: #ffffff;
    --closina-surface-hover: #f8f8f6;        /* Warm off-white */
    --closina-background: #f8f8f6;           /* Warm neutral page bg */
    --closina-border: rgba(0, 0, 0, 0.06);
    --closina-border-strong: rgba(0, 0, 0, 0.12);

    /* Overlay surface tokens — translucent backdrops for loading wrappers, radial gradients, sphere-graph backgrounds. */
    --closina-surface-overlay: rgba(255, 255, 255, 0.85);        /* SmartLoadingWrapper light-mode backdrop */
    --closina-surface-overlay-dark: rgba(15, 23, 42, 0.85);      /* Explicit dark companion (used when a component must pin dark regardless of theme) */
    --closina-surface-overlay-light: rgba(255, 255, 255, 0.05);  /* Subtle light-on-dark radial gradient tint */

    /* Text Tokens */
    --closina-text-primary: #1a1a1a;
    --closina-text-secondary: #6b7280;       /* Gray-500 */
    --closina-text-muted: #6e6e6e;           /* Neutral-500 adjusted (WCAG AA: 4.92:1 on white, 4.63:1 on warm bg) */
    /* Phase Z13 Sub-Phase A: dedicated token for inactive-tab labels — ≥5:1 contrast
       on --closina-background (#f8f8f6). Generic --closina-text-secondary (#6b7280)
       sits at 4.55:1 (AA-narrow), so SiblingSubNavShell inactive tabs use this
       darker slate. Measured: 5.76:1 vs #f8f8f6, 6.12:1 vs #ffffff. */
    --closina-text-tab-label: #5a6273;       /* Slate-darker (5.76:1 on #f8f8f6) */

    /* Radius Tokens */
    --closina-radius-sm: 8px;
    --closina-radius-md: 12px;
    --closina-radius-lg: 16px;
    --closina-radius-xl: 24px;
    --closina-radius-full: 9999px;           /* Pill buttons */

    /* Shadow Tokens (ultra-subtle - only for elevated overlays) */
    --closina-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
    --closina-shadow-md: 0 2px 4px rgba(0, 0, 0, 0.06);
    --closina-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.08);

    /* Layout Tokens */
    --closina-toolbar-height: 64px;
    --closina-sidebar-width: 240px;
    /* Phase U28: Hybrid topbar + sidebar shell tokens */
    --closina-layout-topbar-height: 56px;
    --closina-layout-topbar-height-xs: 48px;
    --closina-layout-sidebar-width: 260px;
    --closina-layout-sidebar-width-rail: 64px;
    /* Phase U31 Sub-Phase D: Mobile bottom navigation bar height */
    --closina-layout-bottom-nav-height: 56px;
    /* Phase U103: horizontal footprint of the fixed bottom-right helper FABs,
       measured inward from the VIEWPORT's right edge.
         24px  right inset  - CopilotWidget.razor:52 / FeedbackWidget.razor:33
       + 56px  diameter     - ClosinaFab.razor:131 defaults Size = MudSize.Large,
                              i.e. MudBlazor's large FAB, which is 56 wide by 56 tall.
       = 80px
       (NB: this comment deliberately contains no brace characters. Several ratchets
       extract the :root block by brace-matching over RAW css, so a brace inside a
       comment here truncates that block and makes tokens declared below it invisible -
       it reddened ContrastTextTokenConvention_Tests + FocusVisibleContrastConvention_Tests
       when first written this way.)
       Both FABs share right:24px and both are Large, so ONE column covers the whole
       stack at every breakpoint - the vertical offsets differ per band, the horizontal
       column does not. Consumed by the pager clearance rule (Fix 3b) in responsive.css.
       If a FAB's right inset or Size changes, change this token in the same commit -
       pinned by FabPagerClearanceConvention_Tests. */
    --closina-layout-fab-column: 80px;

    /* Transition */
    --closina-transition: 0.2s ease;
    --closina-transition-fast: 0.1s ease;
    --closina-transition-slow: 0.3s ease-in-out;

    /* Code Block Tokens */
    --closina-code-bg: #f5f5f5;
    --closina-code-text: #1a1a1a;

    /* Semantic Color Tokens */
    --closina-error: #d32f2f;
    --closina-error-light: rgba(211, 47, 47, 0.08);
    --closina-success-light: rgba(34, 197, 94, 0.08);
    --closina-info-light: rgba(33, 150, 243, 0.08);
    --closina-warning-light: rgba(255, 152, 0, 0.08);
    --closina-warning-darker: #c2410c;       /* Orange-700 — 5.18:1 white-on-bg (filled-warning BUTTON bg only, U69). 🚨 NOT for chips: Z38 Sub-Phase B DROPPED the chip half of this fill-darkening (see § 13 (a-2)) because #000 on #c2410c is only 4.06:1 — still sub-AA — so a dark filled warning CHIP must keep the bright #fbbf24 PaletteDark fill and take its contrast from the pinned #000 text (12.58:1) instead. Re-adding a chip selector here reddens Filled_Chip_Text_Token_Meets_AA_On_Its_Dark_Palette_Fill. */

    /* Status Indicator Tokens */
    --closina-status-success-bg: rgba(34, 197, 94, 0.1);
    --closina-status-warning-bg: rgba(251, 146, 60, 0.1);
    --closina-status-info-bg: rgba(6, 182, 212, 0.1);

    /* Semantic Text Color Tokens (Phase U06) */
    --closina-success: #22c55e;
    --closina-warning: #fb923c;
    --closina-info: #06b6d4;

    /* Faint Border Tokens (Phase U06) */
    --closina-border-faint: rgba(0, 0, 0, 0.03);
    --closina-border-header: rgba(0, 0, 0, 0.08);
    --closina-hover-faint: rgba(0, 0, 0, 0.02);

    /* Focus Tokens (Phase U60 Sub-Phase A — WCAG 1.4.11 non-text contrast)
       --closina-focus-ring is the high-contrast ring color (white on light backgrounds).
       --closina-focus-ring-offset is the halo at opposite tone, used as a box-shadow ring
       to guarantee ≥3:1 contrast against ANY background tier (Primary emerald, Error red,
       Warning amber, Info blue, Success green, Surface white/slate). */
    --closina-focus-ring: #ffffff;
    --closina-focus-ring-offset: rgba(0, 0, 0, 0.6);
    /* deprecated 2026-04-26 — use --closina-focus-ring (one-phase grace; remove in next phase) */
    --closina-focus-outline: #ffffff;

    /* Monospace Font Token */
    --closina-font-mono: 'Cascadia Code', 'Fira Code', Consolas, 'Courier New', monospace;

    /* Overlay & Scrollbar Tokens (P02) */
    --closina-overlay-hover: rgba(255, 255, 255, 0.1);
    --closina-overlay-active: rgba(255, 255, 255, 0.2);
    --closina-scrollbar-thumb: rgba(0, 0, 0, 0.2);
    --closina-fade-overlay: rgba(0, 0, 0, 0.08);
    --closina-fade-overlay-strong: rgba(0, 0, 0, 0.3);

    /* Social Platform Brand Colors (P02) */
    --closina-brand-whatsapp: #25D366;
    --closina-brand-whatsapp-chat-bg: #e5ddd5;
    --closina-brand-whatsapp-bubble: #dcf8c6;
    --closina-brand-linkedin: #0077B5;
    --closina-brand-facebook: #0084FF;
    --closina-brand-instagram-1: #833ab4;
    --closina-brand-instagram-2: #c13584;
    --closina-brand-instagram-3: #e1306c;
    --closina-brand-twitter: #000000;

    /* WCAG AA Text-Safe Semantic Colors (P02 R3-D)
       The base --closina-success/warning/info colors (#22c55e, #fb923c, #06b6d4) are
       bright variants suitable for backgrounds and chips but fail WCAG AA 4.5:1 contrast
       when used as text on white. These darker variants pass AA for text use. */
    --closina-success-text: #15803d;   /* Green-700: 5.02:1 on white — AA compliant */
    --closina-warning-text: #c2410c;   /* Orange-700: 5.18:1 on white — AA compliant */
    --closina-error-text: #b91c1c;     /* Red-700: 6.47:1 on white — AA compliant (Z32) */
    --closina-info-text: #0e7490;      /* Cyan-700: 4.62:1 on white */

    /* Typography Tokens (Phase U14d)
       Sans-serif stack matches MudBlazor's Inter-first approach.
       Weight/leading tokens prevent magic numbers in component CSS. */
    --closina-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --closina-font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
    --closina-font-weight-normal: 400;
    --closina-font-weight-medium: 500;
    --closina-font-weight-semibold: 600;
    --closina-font-weight-bold: 700;
    --closina-leading-tight: 1.2;
    --closina-leading-normal: 1.4;
    --closina-leading-relaxed: 1.6;
    --closina-leading-loose: 1.75;

    /* Z-Index Scale Tokens (Phase U14d)
       Centralized stacking order prevents z-index wars across CSS files.
       Values chosen to slot between MudBlazor's internal z-indexes. */
    --closina-z-base: 1;
    --closina-z-sticky: 100;
    --closina-z-dropdown: 1000;
    --closina-z-fixed: 1050;
    --closina-z-modal: 1300;
    --closina-z-tooltip: 1500;
    --closina-z-maximum: 10000;

    /* Chart Color Tokens (Phase U14d)
       Emerald-primary palette derivatives for data visualizations.
       8 distinct hues with sufficient contrast between adjacent colors.
       Designed to work on both light and dark backgrounds. */
    --closina-chart-1: #047857;    /* Emerald-700 (brand primary) */
    --closina-chart-2: #0891b2;    /* Cyan-600 */
    --closina-chart-3: #7c3aed;    /* Violet-600 */
    --closina-chart-4: #ea580c;    /* Orange-600 */
    --closina-chart-5: #0284c7;    /* Sky-600 */
    --closina-chart-6: #c026d3;    /* Fuchsia-600 */
    --closina-chart-7: #a16207;    /* Yellow-700 (U91: was Yellow-600 #ca8a04 = 2.94:1 vs white, below WCAG 1.4.11's 3:1 graphical threshold; #a16207 = 4.93:1). Mirror of ChartColorConstants.DefaultPalette[6]. */
    --closina-chart-8: #dc2626;    /* Red-600 */

    /* Badge & Alert Semantic Tokens (Phase U14d)
       Replaces hardcoded color values with tokenized alternatives. */
    --closina-badge-warning-bg: #BF360C;           /* Deep-orange for WCAG AA on white text (~5.3:1) */
    --closina-badge-info-bg: #0284c7;              /* Sky-600 for dark mode info badges (4.7:1 on white) */
    --closina-alert-button-pill: rgba(255, 255, 255, 0.18);  /* Semi-transparent pill bg for buttons in filled alerts */
    --closina-alert-dark-text: #000000;                       /* Solid black on BRIGHT filled fills: ALL filled severities in dark mode (warning/info/success/error fills go bright in dark → #000 = 7.6–12.6:1). NOT any LIGHT-mode filled severity anymore — light warning/info/success fills are all DARK (warning #c2410c → #000 = 4.06:1 sub-AA as of Phase Z34; info #0277BD = 4.38:1; success #2E7D32 = 4.10:1), so all three use --closina-alert-light-text (white). Light WARNING moved out of this token 2026-07-05 (Z34, palette #e65100 → #c2410c); light INFO moved 2026-06-02 (U91). SHARED beyond alerts as of Phase Z38 Sub-Phase B (2026-07-25): also the text of dark-mode filled CHIPS (primary 8.28:1 / success 12.05 / warning 12.58 / error 7.59 / info 9.80 / tertiary 11.28 — see section 13 (a-1)), so the "alert" in the name is historical; this is the one canonical black-on-a-bright-dark-fill value. 🚨 NOT for `secondary`: PaletteDark.Secondary #475569 is a DARK fill, where white passes at 7.58:1 and this token would REGRESS it to 2.77:1. */
    --closina-alert-light-text: #ffffff;                      /* Solid white on filled SUCCESS alerts + snackbars (F13 Sub-Phase E.4 a4b follow-up). MudBlazor's #2E7D32 success green is dark: #000 on it = 4.10:1 (fails AA 4.5:1); #fff = 5.13:1 (passes). */
    --closina-alert-dark-icon: rgba(0, 0, 0, 0.7);           /* Slightly lighter dark for alert icons */

    /* === Icon Size Tokens (U68 Sub-Phase E) ===
       Canonical icon-context font-sizes consumed by component CSS via the
       --closina-icon-* token names below, applied to .mud-icon-root /
       .mud-svg-icon and component-scoped icon selectors. Sizes are
       theme-invariant — no [data-theme="dark"] overrides; an icon does not
       change physical size when the user toggles dark mode. */
    --closina-icon-nav: 20px;            /* Sidebar / bottom-nav / dashboard tab icons */
    --closina-icon-header: 28px;         /* Page-header / hero / landing-feature-card icons */
    --closina-icon-inline: 16px;         /* Inline-with-text icons inside slim banner rows */
    --closina-icon-empty-state: 64px;    /* Empty-state hero icons (sphere graph, no-data placeholders) */
    --closina-icon-touch: 24px;          /* Touch-target chrome icons (path arrows, mobile chip glyphs) */
}

/* -----------------------------------------------------------------------------
   2. Dark Mode Tokens (Phase U01 Sub-Phase 5)
   ----------------------------------------------------------------------------- */
[data-theme="dark"] {
    --closina-primary: #10b981;              /* Brighter emerald for dark bg */
    --closina-primary-hover: #34d399;        /* Emerald-400 */
    /* --closina-primary-darker not redefined in dark mode — Syncfusion pager link
       override uses --closina-primary-light here instead (see WCAG override block). */
    --closina-primary-light: rgba(16, 185, 129, 0.12);
    --closina-primary-border: rgba(16, 185, 129, 0.25);
    --closina-primary-text: #0a0a0a;
    --closina-link: #34d399;
    --closina-secondary: #475569;            /* Slate-600 */
    --closina-secondary-hover: #64748b;      /* Slate-500 */
    --closina-surface: #0f172a;              /* Slate-900 */
    --closina-surface-hover: #1e293b;        /* Slate-800 */
    --closina-background: #020617;           /* Slate-950 */
    --closina-border: rgba(255, 255, 255, 0.22);      /* WCAG 1.4.11: ~3.1:1 on #0f172a (AA non-text contrast) */
    --closina-border-strong: rgba(255, 255, 255, 0.32);  /* WCAG 1.4.11: ~4.0:1 on #0f172a */
    --closina-text-primary: #f1f5f9;         /* Slate-100 */
    --closina-text-secondary: #94a3b8;       /* Slate-400 */
    --closina-text-muted: #8b95a5;           /* Slate-400/500 blend (WCAG AA: 4.57:1 on #0f172a) */
    /* Phase Z13 Sub-Phase A: dark companion for --closina-text-tab-label.
       Dark mode already passes ≥5:1 with --closina-text-secondary (#94a3b8 sits at
       7.87:1 on #020617 / 6.96:1 on #0f172a), so the dark variant reuses the same
       slate-400 value — no regression risk. Token is declared explicitly for
       symmetry with the light variant and to make future tuning per-channel safe. */
    --closina-text-tab-label: #94a3b8;       /* Slate-400 (7.87:1 on #020617) */

    /* Overlay surface tokens - dark theme overrides */
    --closina-surface-overlay: rgba(15, 23, 42, 0.85);           /* Slate-900 @ 85% — matches SmartLoadingWrapper dark branch */
    --closina-surface-overlay-light: rgba(255, 255, 255, 0.08);  /* Slightly stronger light tint for dark-mode radial gradients */

    /* Shadow overrides for dark mode - slightly more visible */
    --closina-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
    --closina-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.4);
    --closina-shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.5);

    /* Code Block Tokens (dark mode) */
    --closina-code-bg: #1e1e1e;
    --closina-code-text: #d4d4d4;

    /* Semantic Color Tokens (dark mode) */
    --closina-error: #ef5350;
    --closina-error-light: rgba(239, 83, 80, 0.12);
    --closina-success-light: rgba(74, 222, 128, 0.12);
    --closina-info-light: rgba(66, 165, 245, 0.12);
    --closina-warning-light: rgba(255, 183, 77, 0.12);

    /* Status Indicator Tokens (dark mode) */
    --closina-status-success-bg: rgba(74, 222, 128, 0.15);
    --closina-status-warning-bg: rgba(253, 186, 116, 0.15);
    --closina-status-info-bg: rgba(34, 211, 238, 0.15);

    /* Semantic Text Color Tokens (dark mode - Phase U06) */
    --closina-success: #4ade80;
    --closina-warning: #fdba74;
    --closina-info: #22d3ee;

    /* Faint Border Tokens (dark mode - Phase U06) */
    --closina-border-faint: rgba(255, 255, 255, 0.04);
    --closina-border-header: rgba(255, 255, 255, 0.10);
    --closina-hover-faint: rgba(255, 255, 255, 0.03);

    /* Focus Tokens (dark mode — Phase U60 Sub-Phase A)
       Slate-100 ring with white halo at 60% alpha to keep ≥3:1 contrast against
       dark surface tiers without overpowering the page. */
    --closina-focus-ring: #f1f5f9;
    --closina-focus-ring-offset: rgba(255, 255, 255, 0.6);
    /* deprecated 2026-04-26 — use --closina-focus-ring (one-phase grace; remove in next phase) */
    --closina-focus-outline: #f1f5f9;

    /* Overlay & Scrollbar Tokens (dark mode - P02) */
    --closina-overlay-hover: rgba(255, 255, 255, 0.15);
    --closina-overlay-active: rgba(255, 255, 255, 0.25);
    --closina-scrollbar-thumb: rgba(255, 255, 255, 0.2);
    --closina-fade-overlay: rgba(0, 0, 0, 0.3);
    --closina-fade-overlay-strong: rgba(0, 0, 0, 0.5);

    /* Social Platform Brand Colors (dark mode - P02) */
    --closina-brand-whatsapp-chat-bg: #1a2e23;
    --closina-brand-whatsapp-bubble: #1e4d2b;
    --closina-brand-twitter: #ffffff;

    /* WCAG AA Text-Safe Semantic Colors (dark mode - P02 R3-D)
       On dark backgrounds (#0f172a), the bright base variants already pass contrast,
       but use slightly muted variants for comfortable reading while still AA-compliant. */
    --closina-success-text: #4ade80;   /* Green-400: 10.25:1 on #0f172a */
    --closina-warning-text: #fdba74;   /* Orange-300: 10.59:1 on #0f172a */
    --closina-error-text: #f87171;     /* Red-400: 6.45:1 on #0f172a — AA compliant (Z32) */
    --closina-info-text: #22d3ee;      /* Cyan-400: 8.4:1 on #0f172a */

    /* Chart Color Tokens (dark mode - Phase U14d)
       Brighter variants for visibility on dark backgrounds. */
    --closina-chart-1: #10b981;    /* Emerald-500 (matches dark primary) */
    --closina-chart-2: #22d3ee;    /* Cyan-400 */
    --closina-chart-3: #a78bfa;    /* Violet-400 */
    --closina-chart-4: #fb923c;    /* Orange-400 */
    --closina-chart-5: #38bdf8;    /* Sky-400 */
    --closina-chart-6: #e879f9;    /* Fuchsia-400 */
    --closina-chart-7: #facc15;    /* Yellow-400 */
    --closina-chart-8: #f87171;    /* Red-400 */

    /* Badge & Alert Semantic Tokens (dark mode - Phase U14d) */
    --closina-alert-button-pill: rgba(255, 255, 255, 0.22);  /* Slightly more visible on dark */
}

/* -----------------------------------------------------------------------------
   2c. WCAG AA Color Contrast Overrides for MudBlazor Text (P02 R3-D)
   MudBlazor's .mud-success-text, .mud-warning-text, .mud-info-text classes
   use the palette colors (bright green/orange/cyan) that fail WCAG AA 4.5:1
   when rendered as foreground text on white/light backgrounds.
   Override these classes to use darker, AA-compliant variants for text.
   Background colors, chips, and buttons continue using the bright originals.
   ----------------------------------------------------------------------------- */
.mud-success-text {
    color: var(--closina-success-text) !important;
}

.mud-warning-text {
    color: var(--closina-warning-text) !important;
}

.mud-info-text {
    color: var(--closina-info-text) !important;
}

/* -----------------------------------------------------------------------------
   2b. Font Unification — Syncfusion → MudBlazor/Inter
   Syncfusion grids and scheduler use Bootstrap's system-ui font stack by default.
   Override to inherit the body font (Inter) for a unified appearance.
   ----------------------------------------------------------------------------- */
.e-grid,
.e-grid .e-headercell,
.e-grid .e-headercelldiv,
.e-grid .e-rowcell,
.e-grid .e-summarycell,
.e-grid .e-pager,
.e-grid .e-toolbar,
.e-grid .e-groupdroparea,
.e-grid .e-filterbar input,
.e-schedule,
.e-schedule .e-header-cells,
.e-schedule .e-header-date,
.e-schedule .e-header-day,
.e-schedule .e-navigate,
.e-schedule .e-date-header,
.e-schedule .e-appointment,
.e-schedule .e-appointment-details,
.e-schedule .e-time-cells-wrap,
.e-schedule .e-work-cells,
.e-schedule .e-resource-cells,
.e-schedule .e-toolbar-items,
.e-schedule .e-tbar-btn,
.e-schedule .e-agenda-item,
.e-schedule .e-quick-popup-wrapper {
    font-family: inherit !important;
}

/* -----------------------------------------------------------------------------
   3. Button Shape & Icon Contrast (Sub-Phase 1.4, revised Sub-Phase 7)
   ----------------------------------------------------------------------------- */

/* All buttons: 12px rounded rect, 44px touch target, smooth transition.
   Pill shape (9999px) is reserved for hero CTAs via .closina-pill or
   page-scoped CSS (e.g. Index.razor.css landing page buttons). */
.mud-button-root.mud-button-filled {
    border-radius: var(--closina-radius-md);
    box-shadow: none;
    min-height: var(--closina-btn-height);
    transition: all var(--closina-transition);
}

.mud-button-root.mud-button-filled:hover {
    box-shadow: var(--closina-shadow-sm);
    transform: translateY(-1px);
}

/* Outlined and text buttons: same 12px radius */
.mud-button-root.mud-button-outlined,
.mud-button-root.mud-button-text {
    border-radius: var(--closina-radius-md);
    min-height: var(--closina-btn-height);
    transition: all var(--closina-transition);
}

/* Utility class: apply pill shape to specific CTA buttons */
.closina-pill {
    border-radius: var(--closina-radius-full) !important;
}

/* Fix: Icons inside ALL filled buttons must inherit text color.
   MudBlazor sets .mud-svg-icon color to the theme primary, which clashes
   with filled backgrounds (e.g., emerald icon on emerald button = zero contrast).
   Covers all ButtonTier variants: Primary, Secondary, Danger, Success, Warning, Info. */
.mud-button-filled .mud-icon-root,
.mud-button-filled .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Fix: Icons inside outlined buttons must also inherit text color.
   Outlined buttons use semantic text colors that icons should match. */
.mud-button-outlined .mud-icon-root,
.mud-button-outlined .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Fix: Icons inside MudChip must inherit chip text color.
   Status pills use Color + Icon but MudBlazor doesn't propagate
   the chip's semantic color to the icon element. */
.mud-chip .mud-icon-root,
.mud-chip .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Fix: Icons inside MudFab must inherit button text color.
   FABs use Color property but icons render with default primary color. */
.mud-fab .mud-icon-root,
.mud-fab .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Fix (X03 long-tail sweep): icons inside a COLOR-FILLED MudAvatar must inherit the
   avatar's on-fill text color (white) — otherwise the global brand-primary icon rule
   paints a brand-green glyph on a brand-green avatar fill = invisible (confirmed on
   /m/ai-content Quick Action cards: solid emerald discs with no visible icon). The
   avatar sets its own contrasting text color (white-on-fill for Tier/Custom MudColors,
   the paired color for Hash mode), so `inherit` is always the correct contrast. */
.mud-avatar .mud-icon-root,
.mud-avatar .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Phase U50: ClosinaFab wrapper - white-on-emerald icon color for the
   brand-primary FAB. Strict-more-specific class-on-class selector overrides
   the `.mud-fab .mud-icon-root { color: inherit }` rule above for wrapper
   consumers; the inherit rule remains for any raw <MudFab> use (only
   permitted inside ClosinaFab.razor itself). */
.closina-fab .mud-icon-root {
    color: var(--closina-primary-text) !important; /* U50: adapts to dark mode via token */
}

/* Fix: Icons inside MudIconButton must inherit semantic color.
   Standalone icon buttons with Color parameter need icon to match. */
.mud-icon-button .mud-icon-root,
.mud-icon-button .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Fix: Icons inside MudToggleIconButton must inherit toggle state color. */
.mud-toggle-icon-button .mud-icon-root,
.mud-toggle-icon-button .mud-svg-icon {
    color: inherit !important;
    fill: currentColor !important;
}

/* Phase X03 / S5: a text-variant <MudAlert>'s built-in leading severity <MudIcon> is a bare
   .mud-icon-root, so the global brand-icon rule (main.css `svg.mud-icon-root → var(--closina-primary)`)
   colors it brand-emerald — e.g. a GREEN icon inside a RED `.mud-alert-text-error` alert
   (WCAG 1.4.1 use-of-color / Cat 22). S11-FU1's [0,2,0] override below only catches `.mud-*-text`-
   classed STANDALONE icons, not the alert's own severity icon. Give each text-variant severity its
   AA-compliant `-text` token (one ref resolves in both light + `[data-theme="dark"]`); the
   `.mud-alert-filled-*` icons stay white-on-fill (untouched). These `[0,2,0]` rules out-rank the
   `[0,1,1]` global rule and are registered in CssIconContrastSpecificityConvention_Tests
   ProtectedContainerClasses so that invariant is build-guarded. */
.mud-alert-text-error .mud-icon-root,
.mud-alert-text-error .mud-svg-icon {
    color: var(--closina-error-text) !important;
    fill: currentColor !important;
}
.mud-alert-text-warning .mud-icon-root,
.mud-alert-text-warning .mud-svg-icon {
    color: var(--closina-warning-text) !important;
    fill: currentColor !important;
}
.mud-alert-text-info .mud-icon-root,
.mud-alert-text-info .mud-svg-icon {
    color: var(--closina-info-text) !important;
    fill: currentColor !important;
}
.mud-alert-text-success .mud-icon-root,
.mud-alert-text-success .mud-svg-icon {
    color: var(--closina-success-text) !important;
    fill: currentColor !important;
}

/* Phase S11-FU1: standalone status icons (MudIcon Color="Error|Success|Warning|Info"
   NOT inside a button/chip/fab/alert container) must render their semantic color,
   not the brand emerald the [0,1,1] main.css brand rule would otherwise force.
   Class-on-class = [0,2,0] > [0,1,1]. Uses the AA-compliant -text token variants
   (Cat 22 Fill-Token-As-Text-Color, WCAG 1.4.3) since these are text-color icons on
   light surfaces. Mirrors the container-override mechanism above. */
.mud-icon-root.mud-error-text,
.mud-svg-icon.mud-error-text {
    color: var(--closina-error-text) !important;
    fill: currentColor !important;
}

.mud-icon-root.mud-success-text,
.mud-svg-icon.mud-success-text {
    color: var(--closina-success-text) !important;
    fill: currentColor !important;
}

.mud-icon-root.mud-warning-text,
.mud-svg-icon.mud-warning-text {
    color: var(--closina-warning-text) !important;
    fill: currentColor !important;
}

.mud-icon-root.mud-info-text,
.mud-svg-icon.mud-info-text {
    color: var(--closina-info-text) !important;
    fill: currentColor !important;
}

/* Icon buttons - keep circular but ensure touch target size */
.mud-button-root.mud-icon-btn {
    transition: all var(--closina-transition);
}

/* Fab buttons keep their circular shape */
.mud-fab {
    transition: all var(--closina-transition);
}

.mud-fab:hover {
    transform: translateY(-1px);
    box-shadow: var(--closina-shadow-md);
}

/* -----------------------------------------------------------------------------
   4. Shadow-to-Border Surface Treatment (Sub-Phase 1.5)
   ----------------------------------------------------------------------------- */

/* Elevation levels 1-3: no shadow, subtle border */
.mud-paper.mud-elevation-1,
.mud-paper.mud-elevation-2,
.mud-paper.mud-elevation-3 {
    box-shadow: none !important;
    border: 1px solid var(--closina-border);
}

/* Elevation levels 4-5: ultra-subtle shadow for dialogs/overlays only */
.mud-paper.mud-elevation-4,
.mud-paper.mud-elevation-5 {
    box-shadow: var(--closina-shadow-lg) !important;
    border: 1px solid var(--closina-border);
}

/* Warm background on main content area */
.mud-main-content {
    background-color: var(--closina-background);
}

/* Override ABP layout background to use warm neutral */
.abp-application-layout {
    background-color: var(--closina-background) !important;
}

/* Prevent horizontal overflow from off-screen drawers (HelpPanel, CopilotWidget).
   MudBlazor "closes" right-side drawers by positioning them at left:100% (off-screen)
   but keeps display:flex and visibility:visible. This causes ~420px horizontal scroll
   on all authenticated pages. overflow-x:hidden on html doesn't reliably clip these
   on all browsers (notably Chrome on Samsung Fold 6 exposes the drawer on unfold).
   Fix: fully collapse closed right drawers so they occupy zero layout space. */
.mud-drawer-pos-right.mud-drawer--closed {
    visibility: hidden;
    width: 0 !important;
    min-width: 0 !important;
    overflow: hidden;
}

/* Pin Copilot/Coach and Help Panel drawers to viewport height.
   MudBlazor temporary drawers use height:100% which inherits from the layout
   container. On long/scrollable pages, this makes the drawer match the document
   height instead of the viewport, forcing users to scroll the drawer to reach
   the input field. Fix: lock to viewport height with 100dvh (100vh fallback). */
.copilot-drawer,
.help-panel-drawer {
    height: 100vh !important;
    height: 100dvh !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    top: 0 !important;
    position: fixed !important;
}

/* Cards and papers get the border treatment */
.mud-card {
    border-radius: var(--closina-radius-md);
    overflow: hidden;
}

/* Dialog surfaces get larger radius */
.mud-dialog {
    border-radius: var(--closina-radius-lg) !important;
}

/* Input fields get medium radius */
.mud-input-outlined .mud-input-outlined-border {
    border-radius: var(--closina-radius-sm);
}

/* Select/dropdown menus */
.mud-popover .mud-list {
    border-radius: var(--closina-radius-sm);
}

/* Chip components get pill shape */
.mud-chip {
    border-radius: var(--closina-radius-full);
}

/* Alert components */
.mud-alert {
    border-radius: var(--closina-radius-md);
}

/* Flat-but-bordered surface utility (U100 SP-D, issue #4 border/overlay hygiene).
   Canonical replacement for the repeated `Elevation="0"` + inline
   `Style="border: 1px solid var(--closina-border); border-radius: var(--closina-radius-md);"`
   pattern (437 flat-but-bordered containers audit-measured). A single class instead of an
   inline style keeps the border on the ONE canonical token + de-collides a nested surface
   (opt in on the inner surface to drop its redundant border where two bordered surfaces
   butt together). Theme-aware by construction (both tokens redefine under [data-theme]). */
.closina-flat {
    border: 1px solid var(--closina-border);
    border-radius: var(--closina-radius-md);
    box-shadow: none;
}

/* De-collision (U100-FU border-hygiene Layer 2): a flat-bordered surface nested inside another
   flat-bordered surface drops its own border, so two 1px borders never stack into a doubled edge.
   SAFE because it is scoped to the opt-in `.closina-flat` MARKER (not a blanket `.bordered .bordered`
   rule — the marker is exactly what makes this precise instead of regression-prone). The group is
   already framed by the outer surface; the inner content is delineated by spacing/typography.
   Matches nothing today (no nested `.closina-flat` exists) — it is a forward-prevention rule that
   bites only as adoption grows, so it is zero-risk on landing. To keep an intentional nested border,
   give the inner surface a non-`.closina-flat` bordered treatment (a scoped border class, or MudPaper
   `Outlined`) rather than `.closina-flat`. */
.closina-flat .closina-flat {
    border: none;
}

/* Snackbar */
.mud-snackbar {
    border-radius: var(--closina-radius-md) !important;
}

/* Mobile snackbar layout (U100 SP-D, issue #3). MudBlazor's default toast is a fixed
   min-width:288px / max-width:500px anchored to a corner (right:24px), and its message uses
   `overflow-wrap: anywhere` — so on a phone a long two-value message (e.g. the timezone-mismatch
   toast "… (UTC+00:00) … vs … (UTC+00:00) …") squeezes into a ~90px column beside the inline
   "Update timezone" action button, wrapping to ~8 lines and SHATTERING "(UTC+00:00)" mid-token,
   while the fixed corner anchor overlays the page header/KPIs. On Xs (<600px), span the viewport
   with symmetric 8px gutters so the message gets the full width, and wrap at word boundaries
   instead of anywhere so timezone/offset tokens stay intact. Global config pins all toasts
   TopRight, but every corner is handled for robustness. */
@media (max-width: 599.98px) {
    /* `!important` (matching the snackbar border-radius rule above + the house pattern for
       overriding MudBlazor's stock snackbar CSS): MudBlazor sets `.mud-snackbar {min-width:288px;
       max-width:500px}` + `.mud-snackbar-location-* {right:24px}` at single-class specificity and
       loads later, so a plain override would tie-then-lose on source order. `!important` guarantees
       the full-width span wins across MudBlazor versions (the primary fix — a4b-confirmed 359px @375). */
    .mud-snackbar-location-top-right,
    .mud-snackbar-location-top-left,
    .mud-snackbar-location-top-center,
    .mud-snackbar-location-bottom-right,
    .mud-snackbar-location-bottom-left,
    .mud-snackbar-location-bottom-center {
        left: 8px !important;
        right: 8px !important;
        transform: none !important;
    }

    .mud-snackbar {
        min-width: 0 !important;
        max-width: none !important;
        width: 100% !important;
    }

    /* Descendant selector (0,2,0) so it beats MudBlazor's stock `.mud-snackbar-content-message`
       (0,1,0), which loads later and would otherwise win the specificity tie and keep
       `overflow-wrap: anywhere` (a4b-confirmed). */
    .mud-snackbar .mud-snackbar-content-message {
        overflow-wrap: break-word;
        word-break: normal;
    }
}

/* Filled success snackbar contrast — WCAG 1.4.3 (Phase F13 Sub-Phase E / F8;
   a4b follow-up 2026-05-21 — corrected text-color direction).
   MudBlazor 9.4.0 renders a Severity.Success + Variant.Filled snackbar as
   `<div class="mud-snackbar mud-snackbar-surface ... mud-alert-filled-success">`,
   with the message in `.mud-snackbar-content-message` and the dismiss/action in
   `.mud-snackbar-content-action`. The success surface is a DARK green (#2E7D32 =
   MudBlazor's --mud-palette-success) — NOT a bright emerald. Dark text fails AA on
   it: #000 measured 4.10:1 via runtime computed-style capture (< 4.5:1 normal-text
   minimum). Force the AA-passing --closina-alert-light-text token (solid #fff =
   5.13:1 on #2E7D32) on the snackbar surface and both content slots.
   INFO joined this group 2026-06-02 (same shape: light info snackbar fill is the DARK
   blue #0277BD, so #000 = 4.38:1 FAILS; #fff = 4.80:1 passes). NOTE: this rule is now
   effectively LIGHT-only for both severities — in DARK the success/info fills go BRIGHT
   (#4ade80 / #38bdf8) and the `[data-theme="dark"] .mud-snackbar.mud-alert-filled-{success,info}`
   rule above (spec 0,4,0) overrides this (0,3,0) back to #000. */
.mud-snackbar.mud-alert-filled-warning,
.mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-message,
.mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-action,
.mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-action > button,
.mud-snackbar.mud-alert-filled-warning .mud-snackbar-icon,
.mud-snackbar.mud-alert-filled-success,
.mud-snackbar.mud-alert-filled-success .mud-snackbar-content-message,
.mud-snackbar.mud-alert-filled-success .mud-snackbar-content-action,
.mud-snackbar.mud-alert-filled-success .mud-snackbar-content-action > button,
.mud-snackbar.mud-alert-filled-success .mud-snackbar-icon,
.mud-snackbar.mud-alert-filled-info,
.mud-snackbar.mud-alert-filled-info .mud-snackbar-content-message,
.mud-snackbar.mud-alert-filled-info .mud-snackbar-content-action,
.mud-snackbar.mud-alert-filled-info .mud-snackbar-content-action > button,
.mud-snackbar.mud-alert-filled-info .mud-snackbar-icon {
    color: var(--closina-alert-light-text);
}

.mud-snackbar.mud-alert-filled-warning .mud-svg-icon,
.mud-snackbar.mud-alert-filled-success .mud-svg-icon,
.mud-snackbar.mud-alert-filled-info .mud-svg-icon {
    color: inherit !important;
}

/* Filled semantic snackbar text in DARK mode (Phase U91 + sibling-fix, WCAG 1.4.3) — same
   root cause as the dark filled alert above: the generic `[data-theme="dark"] .mud-snackbar`
   / `.mud-alert` rules (0,2,0) override the per-severity color rules (0,1,0), leaving
   slate-100 (warning/info/error) or #fff (success — the unscoped `:576` rule, correct for
   light's DARK-green bg but WRONG on dark's BRIGHT-green #4ade80 = ~1.4:1) on a bright dark
   fill. Force the AA dark text token (#000) on the surface + both content slots + icon for
   all four severities. Selector specificity here is 0,4,0 (attr + 3 classes), which beats
   BOTH the generic dark rules (0,2,0) AND the light success-snackbar rule (`:576`, 0,3,0) in
   dark. LIGHT mode untouched — these are [data-theme="dark"]-scoped, so the light success
   snackbar keeps its #fff (`:576`) and warning/info keep #000. #000 on the four bright dark
   fills ≈ 12.5 / 9.8 / 12 / 7.6 :1. Widened from WARNING-only per user direction 2026-06-02. */
[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-message,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info .mud-snackbar-content-message,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success .mud-snackbar-content-message,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error .mud-snackbar-content-message,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-action,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info .mud-snackbar-content-action,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success .mud-snackbar-content-action,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error .mud-snackbar-content-action,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning .mud-snackbar-content-action > button,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info .mud-snackbar-content-action > button,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success .mud-snackbar-content-action > button,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error .mud-snackbar-content-action > button,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning .mud-snackbar-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info .mud-snackbar-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success .mud-snackbar-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error .mud-snackbar-icon {
    color: var(--closina-alert-dark-text);
}

[data-theme="dark"] .mud-snackbar.mud-alert-filled-warning .mud-svg-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-info .mud-svg-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-success .mud-svg-icon,
[data-theme="dark"] .mud-snackbar.mud-alert-filled-error .mud-svg-icon {
    color: inherit !important;
}

/* MudDivider - use theme border color for subtlety */
.mud-divider {
    border-color: var(--closina-border);
}

/* MudTabs - subtle border treatment */
.mud-tabs.mud-elevation-2 {
    border-radius: var(--closina-radius-md);
}

/* Expansion panels */
.mud-expand-panel {
    border-radius: var(--closina-radius-md) !important;
}

/* Tables - subtle borders */
.mud-table {
    border-radius: var(--closina-radius-md);
    overflow: hidden;
}

/* Announcement badge — WCAG 1.4.3 contrast fix (U09)
   MudBlazor deep-orange badge (rgb(230,81,0)) with white text = 3.79:1
   Required: 4.5:1. Darken to rgb(191,54,12) = ~5.3:1 on white. */
.mud-badge.mud-badge-warning,
.mud-badge[style*="deep-orange"],
.announcement-badge .mud-badge-content {
    background-color: var(--closina-badge-warning-bg) !important;
}

/* U100 SP-F: MudTabs count-badge overflow safety.
   A <MudTabPanel BadgeData="..."> renders a .mud-badge whose .mud-badge-content is
   absolutely positioned at the tab label's top-right. On a tab that clips its
   overflow (text-overflow ellipsis) or is tightly packed, a multi-digit count badge
   (e.g. "999+") gets clipped by the tab box or overlaps the next tab. Keep the badge
   fully visible: let it escape the tab's clip box and reserve trailing room on a
   badged tab. Pinned by TabCountBadgeConvention_Tests. */
.mud-tabs .mud-tab .mud-badge,
.mud-tabs .mud-tab .mud-badge-content {
    overflow: visible;
    white-space: nowrap;
}
.mud-tabs .mud-tab:has(.mud-badge-content) {
    padding-right: 20px;
}

/* Sidebar version link - visually subtle but clickable to open changelog (Phase U06) */
#menu-version-info {
    margin-top: 8px;
    border-top: 1px solid var(--closina-border);
    padding-top: 8px;
    opacity: 0.6;
    font-size: 0.75rem;
    position: relative;
    z-index: 0;
}

#menu-version-info:hover {
    opacity: 1;
}

/* -----------------------------------------------------------------------------
   5. Stat Card Styling (Sub-Phase 3.2)
   ----------------------------------------------------------------------------- */

/* CompactStatCard - Elevation="0" with border treatment */
.compact-stat-card {
    border: 1px solid var(--closina-border);
    border-radius: var(--closina-radius-md);
    transition: all var(--closina-transition);
    /* Stretch children to equal height so top edges align (UX R09).
       Overrides MudBlazor's align-center utility class. */
    align-items: stretch !important;
    /* Phase U100 Sub-Phase C: allow the card's flex content to shrink WITHIN its grid
       column so a long localized label / large value never forces the card (or the last
       card in a 4-up KPI strip) past the column edge. The default flex `min-width: auto`
       refuses to shrink a flex item below its content size, which pushed the rightmost
       stat card off the container edge (call-analytics 4th-card clip @1920) and ran the
       xs-stacked cards off-screen @375. `overflow: hidden` is the belt-and-suspenders
       clip guard so the strip wraps/shrinks instead of overflowing horizontally. */
    min-width: 0;
    overflow: hidden;
}

/* Each child centers its content within the stretched height */
.compact-stat-card .compact-stat-icon {
    display: flex;
    align-items: center;
    line-height: 1;
}

.compact-stat-card .compact-stat-label {
    display: flex;
    align-items: center;
    line-height: 1.2;
    /* Phase U100 Sub-Phase C: the label is the widest, most-variable child (localized
       captions vary in length) — let it shrink/wrap within the card instead of forcing
       the card wider than its grid column. */
    min-width: 0;
    overflow-wrap: anywhere;
}

.compact-stat-card .stat-card-value {
    display: flex;
    align-items: center;
}

/* Stat card value styling — visually matches heading sizes but uses body1 semantic
   to avoid heading hierarchy issues (P02 R3-H WCAG 1.3.1). */
.stat-card-value {
    font-size: var(--mud-typography-h5-size) !important;
    font-weight: var(--mud-typography-h5-weight) !important;
    line-height: var(--mud-typography-h5-lineheight) !important;
    letter-spacing: var(--mud-typography-h5-letterspacing) !important;
}

.stat-card-value-large {
    font-size: var(--mud-typography-h3-size) !important;
    font-weight: var(--mud-typography-h3-weight) !important;
    line-height: var(--mud-typography-h3-lineheight) !important;
    letter-spacing: var(--mud-typography-h3-letterspacing) !important;
}

.compact-stat-card:hover {
    border-color: var(--closina-border-strong);
}

/* PercentageStatCard containers get the same treatment */
.mud-paper.mud-elevation-0 {
    border: 1px solid var(--closina-border);
    border-radius: var(--closina-radius-md);
}

/* -----------------------------------------------------------------------------
   5b. Focus Indicators (WCAG 1.4.11 + 2.4.7 + 2.4.11)
   -----------------------------------------------------------------------------
   Phase U60 Sub-Phase A: Single canonical universal :focus-visible rule.
   Replaces the prior component-enumerated rule (Phase U07) that produced a
   1.27:1 contrast violation when emerald rings rendered against emerald button
   backgrounds. The new ring is high-contrast white/slate (light/dark) with a
   semi-opaque halo offset, guaranteeing ≥3:1 against every background tier.
   The universal selector cascades to all MudBlazor classes + native a +
   [tabindex="0"] + [role="button"] previously enumerated. */
*:focus-visible {
    outline: 2px solid var(--closina-focus-ring);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--closina-focus-ring-offset);
}

/* Phase U86 follow-up (2026-05-19, WCAG 2.4.7 cascade fix):
   Section 4 above declares `box-shadow: none !important` on .mud-paper.mud-elevation-{1,2,3}
   to enforce the shadow-to-border surface treatment. Pre-U86 this was harmless because
   MudCard surfaces were never focusable. Post-U86 the StandardCardList card receives
   `role="button"` + `tabindex="0"` when OnItemClick is wired — the `*:focus-visible`
   box-shadow halo (line 679) then has zero effect because of the `!important` upstream.
   Re-introduce the halo specifically for focusable MudPaper surfaces. */
.mud-paper.mud-elevation-1:focus-visible,
.mud-paper.mud-elevation-2:focus-visible,
.mud-paper.mud-elevation-3:focus-visible {
    box-shadow: 0 0 0 4px var(--closina-focus-ring-offset) !important;
}

/* U90 follow-up (WCAG 2.4.7 Focus Visible): MudToggleGroup items (.mud-toggle-item,
   e.g. the ConversationViewToggle Chat/Grid buttons) reset the UA outline, so the
   universal *:focus-visible ring above is suppressed — a keyboard user can't tell
   which option is focused (the inactive item showed zero affordance). Re-apply the
   canonical ring with the same tokens; inset offset avoids overlapping the adjacent
   grouped button. */
.mud-toggle-item:focus-visible {
    outline: 2px solid var(--closina-focus-ring) !important;
    outline-offset: -2px;
    box-shadow: 0 0 0 4px var(--closina-focus-ring-offset);
}

/* F33 P2 a4b follow-up (WCAG 2.4.7 Focus Visible + 1.4.11 Non-text Contrast): a standalone
   removable ClosinaChip is made keyboard-focusable (tabindex="0" + role="button") by the wrapper,
   but MudBlazor's own .mud-chip:focus-visible rule (higher specificity than the universal
   *:focus-visible above) leaves the root with a white outline that vanishes on the white chip
   surface (~1:1). Re-apply the canonical high-contrast ring with the same tokens — same pattern as
   the U90 .mud-toggle-item fix. Scoped to [tabindex="0"] so only the focusable removable chips match. */
.mud-chip[tabindex="0"]:focus-visible {
    outline: 2px solid var(--closina-focus-ring) !important;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--closina-focus-ring-offset);
}

/* Windows High Contrast / forced-colors mode: use the system text color so
   focus rings remain visible under user-driven palette overrides. */
@media (forced-colors: active) {
    *:focus-visible {
        outline-color: CanvasText;
    }
}

/* Print: focus indicators are interactive-state chrome and have no place on paper. */
@media print {
    *:focus-visible {
        outline: none;
        box-shadow: none;
    }
}

/* Phase U07: Text-variant primary buttons use link color for AA contrast.
   Phase P02: Primary now matches link (#047857, 5.48:1) — this override is
   still kept for explicitness but no longer corrects a contrast gap. */
.mud-button-text.mud-button-text-primary {
    color: var(--closina-link) !important;
}

/* -----------------------------------------------------------------------------
   6. Input Field Styling (Sub-Phase 3.3)
   ----------------------------------------------------------------------------- */

/* Select/dropdown popover menus */
.mud-popover {
    border-radius: var(--closina-radius-md) !important;
}

/* Autocomplete dropdown */
.mud-autocomplete .mud-popover {
    border-radius: var(--closina-radius-sm) !important;
}

/* -----------------------------------------------------------------------------
   7. Dark Mode Component Overrides (Phase U01 Sub-Phase 5)
   ----------------------------------------------------------------------------- */

/* Paper/card surfaces in dark mode */
[data-theme="dark"] .mud-paper {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-paper.mud-elevation-0 {
    background-color: var(--closina-surface);
}

/* Main content area dark background */
[data-theme="dark"] .mud-main-content {
    background-color: var(--closina-background);
}

[data-theme="dark"] .abp-application-layout.bg-light {
    background-color: var(--closina-background) !important;
}

/* Prevent white edge at page top — html element uses a different dark bg by default.
   Note: html[data-theme="dark"] targets html itself (the attribute IS on <html>).
   [data-theme="dark"] body targets body as a descendant. */
html[data-theme="dark"],
[data-theme="dark"] body {
    background-color: var(--closina-background) !important;
}

/* Cards and dialogs */
[data-theme="dark"] .mud-card {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-dialog {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

/* Button overrides for dark mode */
[data-theme="dark"] .mud-button-root.mud-button-filled-primary {
    background-color: var(--closina-primary) !important;
    color: var(--closina-primary-text) !important;
}

[data-theme="dark"] .mud-button-root.mud-button-filled-primary:hover {
    background-color: var(--closina-primary-hover) !important;
}

[data-theme="dark"] .mud-button-root.mud-button-outlined {
    border-color: var(--closina-border-strong);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-button-root.mud-button-text {
    color: var(--closina-text-primary);
}

/* Input borders and backgrounds */
[data-theme="dark"] .mud-input-outlined .mud-input-outlined-border {
    border-color: var(--closina-border-strong);
}

[data-theme="dark"] .mud-input {
    color: var(--closina-text-primary) !important;
}

[data-theme="dark"] .mud-input-label {
    color: var(--closina-text-secondary) !important;
}

[data-theme="dark"] .mud-input-control .mud-input-label-inputcontrol {
    color: var(--closina-text-secondary) !important;
}

[data-theme="dark"] .mud-input-filled {
    background-color: var(--closina-surface-hover) !important;
}

[data-theme="dark"] .mud-input-underline::after {
    border-bottom-color: var(--closina-primary) !important;
}

/* Select/dropdown in dark mode */
[data-theme="dark"] .mud-select .mud-input {
    color: var(--closina-text-primary) !important;
}

[data-theme="dark"] .mud-popover {
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border-strong) !important;
}

[data-theme="dark"] .mud-list {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-list-item:hover {
    background-color: var(--closina-surface-hover) !important;
}

[data-theme="dark"] .mud-list-item.mud-selected-item {
    background-color: var(--closina-primary-light) !important;
    color: var(--closina-primary) !important;
}

/* Dividers */
[data-theme="dark"] .mud-divider {
    border-color: var(--closina-border);
}

/* Table / MudTable dark mode */
[data-theme="dark"] .mud-table {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-table .mud-table-head .mud-table-cell {
    background-color: var(--closina-surface-hover);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-table .mud-table-body .mud-table-row:hover {
    background-color: var(--closina-surface-hover) !important;
}

[data-theme="dark"] .mud-table .mud-table-cell {
    border-bottom-color: var(--closina-border);
}

/* Tabs */
[data-theme="dark"] .mud-tabs {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-tabs .mud-tab {
    color: var(--closina-text-secondary);
}

[data-theme="dark"] .mud-tabs .mud-tab.mud-tab-active {
    color: var(--closina-primary);
}

/* Tab header / toolbar surface (U100 SP-A, issue #1 P1).
   MudBlazor renders the tab bar on a solid light surface that leaks solid WHITE in dark mode
   on status-filter tab strips (screenshot-confirmed: admin-member-list, transactions). The
   `.mud-tabs` root rule above colors the panel body but NOT the header/tab-bar surface. Bind the
   tab-bar surface to the Closina slate surface. The live rendered class in MudBlazor 9.4/9.7 is
   `.mud-tabs-tabbar` (+ its inner/wrapper) — CONFIRMED at the SP-A a4b exit gate (the strip
   rendered slate, proving this selector matches). The plan-named `.mud-tab-header` candidate was
   dropped in SP-D: it matches nothing in 9.4/9.7 and was inert. */
[data-theme="dark"] .mud-tabs .mud-tabs-tabbar {
    background-color: var(--closina-surface);
    border-color: var(--closina-border);
}

[data-theme="dark"] .mud-tabs .mud-tabs-tabbar-inner,
[data-theme="dark"] .mud-tabs .mud-tabs-tabbar-wrapper,
[data-theme="dark"] .mud-tabs .mud-tabs-tabbar-content {
    background-color: var(--closina-surface);
}

[data-theme="dark"] .mud-tabs .mud-tab:hover {
    background-color: var(--closina-surface-hover);
}

/* Drawer / Sidebar */
[data-theme="dark"] .mud-drawer {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-drawer-content {
    background-color: var(--closina-surface) !important;
}

/* AppBar */
[data-theme="dark"] .mud-appbar {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary);
}

/* Alerts */
[data-theme="dark"] .mud-alert {
    color: var(--closina-text-primary);
}

/* Filled-WARNING alert text MOVED to the light-text group below (Phase Z34, WCAG 1.4.3).
   The palette Warning fill darkened #e65100 → #c2410c (Routes.razor) to fix Color="Warning"
   text-on-white (3.79 → 5.18:1); that darker fill pushed #000-on-fill from 5.54:1 → 4.06:1
   (now sub-AA for normal text). Warning therefore joins the other DARK-fill severities
   (success #2e7d32, info #0277bd) and takes WHITE light-mode text (#fff on #c2410c = 5.18:1 ✅),
   exactly as INFO was moved out of this black-text rule on 2026-06-02. DARK mode is unaffected:
   the dark warning fill stays BRIGHT (#fbbf24), so the [data-theme="dark"] .mud-alert-filled-warning
   re-assertion below keeps #000 (≈12.5:1). */

/* DARK-mode re-assertion for ALL filled semantic alert text (Phase U91 + sibling-fix, WCAG 1.4.3).
   In DARK mode every filled semantic fill is BRIGHT (warning #fbbf24, info #38bdf8,
   success #4ade80, error #f87171). The generic `[data-theme="dark"] .mud-alert
   { color: --closina-text-primary }` rule (specificity 0,2,0, defined earlier in the dark
   Alerts block) silently out-ranks the per-severity `.mud-alert-filled-X { color: ... }`
   rules (0,1,0) — including the light-mode success rule (`:953`, #fff) and info/warning
   rule (`:934`, #000) — leaving slate-100/white text on a bright fill:
   warning 1.52:1, info 1.96, success 1.59, error 2.52 — ALL FAIL AA (measured U91).
   Re-assert the AA dark text token (#000) at matching (0,2,0) specificity, placed AFTER
   the generic dark .mud-alert rule so source order makes it win. #000 on the four bright
   dark fills ≈ 12.5 / 9.8 / 12 / 7.6 :1 (all pass). Dark-scoped ONLY — light treatments
   (info #000 on dark blue #0277BD; success #fff on dark green #2E7D32) are untouched.
   Originally WARNING-only (the F23 a4b finding); widened to info/success/error per user
   direction 2026-06-02 once re-measurement confirmed the identical defect class. */
[data-theme="dark"] .mud-alert-filled-warning,
[data-theme="dark"] .mud-alert-filled-info,
[data-theme="dark"] .mud-alert-filled-success,
[data-theme="dark"] .mud-alert-filled-error,
[data-theme="dark"] .mud-alert-filled-warning .mud-button-root,
[data-theme="dark"] .mud-alert-filled-info .mud-button-root,
[data-theme="dark"] .mud-alert-filled-success .mud-button-root,
[data-theme="dark"] .mud-alert-filled-error .mud-button-root {
    color: var(--closina-alert-dark-text);
}

[data-theme="dark"] .mud-alert-filled-warning .mud-alert-icon,
[data-theme="dark"] .mud-alert-filled-info .mud-alert-icon,
[data-theme="dark"] .mud-alert-filled-success .mud-alert-icon,
[data-theme="dark"] .mud-alert-filled-error .mud-alert-icon {
    color: var(--closina-alert-dark-icon);
}

/* Filled-success + filled-INFO + filled-WARNING alert (LIGHT) — all three have a DARK fill in
   light mode (success #2E7D32 green, info #0277BD blue, warning #c2410c orange) so they need
   WHITE text. #000 fails on all three (success 4.10:1, info 4.38:1, warning 4.06:1); #fff passes
   (success 5.13:1, info 4.80:1, warning 5.18:1). Info joined 2026-06-02; WARNING joined 2026-07-05
   (Phase Z34 — palette Warning darkened #e65100 → #c2410c, moved out of the black-text rule above).
   DARK mode is handled separately: in dark these fills go BRIGHT, so the
   `[data-theme="dark"] .mud-alert-filled-{success,info,warning}` rule above (spec 0,2,0) overrides
   this (0,1,0) to #000. F13 Sub-Phase E.4 lineage (success); U91 sibling-fix (info); Z34 (warning). */
.mud-alert-filled-warning,
.mud-alert-filled-warning .mud-button-root,
.mud-alert-filled-warning .mud-alert-icon,
.mud-alert-filled-success,
.mud-alert-filled-success .mud-button-root,
.mud-alert-filled-success .mud-alert-icon,
.mud-alert-filled-info,
.mud-alert-filled-info .mud-button-root,
.mud-alert-filled-info .mud-alert-icon {
    color: var(--closina-alert-light-text);
}

/* Icons inside filled alerts should inherit alert text color, not theme primary */
.mud-alert-filled-warning .mud-svg-icon,
.mud-alert-filled-info .mud-svg-icon,
.mud-alert-filled-error .mud-svg-icon,
.mud-alert-filled-success .mud-svg-icon {
    color: inherit !important;
}

/* Snackbar */
[data-theme="dark"] .mud-snackbar {
    color: var(--closina-text-primary);
}

/* Chips */
[data-theme="dark"] .mud-chip.mud-chip-default {
    background-color: var(--closina-surface-hover);
    color: var(--closina-text-primary);
}

/* Typography */
[data-theme="dark"] .mud-typography {
    color: var(--closina-text-primary);
}

[data-theme="dark"] .mud-typography-secondary {
    color: var(--closina-text-secondary) !important;
}

/* U09: .mud-secondary-text uses MudBlazor's --mud-palette-secondary (not --closina-text-secondary).
   Override to ensure readable contrast on dark backgrounds (was 2.36:1, now uses Slate-400 at ~5.4:1). */
[data-theme="dark"] .mud-secondary-text {
    color: var(--closina-text-secondary) !important;
}

/* Breadcrumbs */
[data-theme="dark"] .mud-breadcrumbs li {
    color: var(--closina-text-secondary);
}

[data-theme="dark"] .mud-breadcrumbs a {
    color: var(--closina-primary) !important;
}

/* Expansion panel */
[data-theme="dark"] .mud-expand-panel {
    background-color: var(--closina-surface);
    color: var(--closina-text-primary);
}

/* Progress bars */
[data-theme="dark"] .mud-progress-linear {
    background-color: var(--closina-surface-hover);
}

/* Skeleton loading */
[data-theme="dark"] .mud-skeleton {
    background-color: var(--closina-surface-hover) !important;
}

/* Tooltip */
[data-theme="dark"] .mud-tooltip {
    background-color: var(--closina-surface-hover) !important;
    color: var(--closina-text-primary) !important;
}

/* Body/HTML background for dark mode */
[data-theme="dark"] body,
[data-theme="dark"] body.abp-application-layout {
    background-color: var(--closina-background) !important;
    color: var(--closina-text-primary);
}

/* U09: MudBadge info color — sky-blue (#0ea5e9) with white text = 2.14:1 in dark mode.
   Darken to Sky-600 (#0284c7) for 4.7:1 contrast on white text. */
[data-theme="dark"] .mud-badge-info .mud-badge-content {
    background-color: var(--closina-badge-info-bg) !important;
}

/* U09: Admin shield badge — warning (amber) badge with primary icon = 1.52:1.
   Override icon color inside warning badges to dark text for contrast. */
[data-theme="dark"] .mud-badge-warning .mud-icon-root {
    color: var(--closina-primary-text) !important;
}

/* Stat card dark overrides */
[data-theme="dark"] .compact-stat-card {
    background-color: var(--closina-surface);
    border-color: var(--closina-border);
}

/* -----------------------------------------------------------------------------
   8. Syncfusion Grid Dark Mode Overrides (Phase U01 Sub-Phase 5.4)
   ----------------------------------------------------------------------------- */

/* Grid container */
[data-theme="dark"] .e-grid {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Grid header */
[data-theme="dark"] .e-grid .e-gridheader {
    background-color: var(--closina-surface-hover) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-grid .e-headercell {
    background-color: var(--closina-surface-hover) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-grid .e-headercelldiv {
    color: var(--closina-text-primary) !important;
}

/* Grid rows */
[data-theme="dark"] .e-grid .e-row,
[data-theme="dark"] .e-grid .e-altrow {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
}

[data-theme="dark"] .e-grid .e-altrow {
    background-color: var(--closina-surface) !important;
}

[data-theme="dark"] .e-grid .e-rowcell {
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Row hover */
[data-theme="dark"] .e-grid .e-row:hover .e-rowcell,
[data-theme="dark"] .e-grid .e-altrow:hover .e-rowcell {
    background-color: var(--closina-surface-hover) !important;
}

/* Grid toolbar */
[data-theme="dark"] .e-grid .e-toolbar {
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-grid .e-toolbar .e-tbar-btn {
    color: var(--closina-text-primary) !important;
}

/* Grid footer/pager */
[data-theme="dark"] .e-grid .e-gridpager {
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border) !important;
    color: var(--closina-text-secondary) !important;
}

[data-theme="dark"] .e-grid .e-pager {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-secondary) !important;
}

[data-theme="dark"] .e-grid .e-pager .e-numericitem {
    color: var(--closina-text-secondary) !important;
    background-color: transparent !important;
}

[data-theme="dark"] .e-grid .e-pager .e-numericitem.e-currentitem {
    background-color: var(--closina-primary) !important;
    color: var(--closina-primary-text) !important;
}

/* Grid aggregate footer */
[data-theme="dark"] .e-grid .e-gridfooter {
    background-color: var(--closina-surface-hover) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-grid .e-summarycell {
    color: var(--closina-text-primary) !important;
}

/* Grid selection highlight in dark mode */
[data-theme="dark"] .e-grid .e-selectionbackground {
    background-color: var(--closina-primary-light) !important;
}

/* Grid filter bar */
[data-theme="dark"] .e-grid .e-filterbar .e-filterbarcell {
    background-color: var(--closina-surface) !important;
}

[data-theme="dark"] .e-grid .e-filterbar input {
    color: var(--closina-text-primary) !important;
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border) !important;
}

/* Grid dialog/popup */
[data-theme="dark"] .e-grid .e-dialog {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Grid sort indicator */
[data-theme="dark"] .e-grid .e-icon-ascending::before,
[data-theme="dark"] .e-grid .e-icon-descending::before {
    color: var(--closina-primary) !important;
}

/* Custom grid toolbar dark mode */
[data-theme="dark"] .custom-grid-toolbar {
    background-color: var(--closina-surface-hover);
    border-bottom-color: var(--closina-border);
}

[data-theme="dark"] .sfgrid-container {
    background: var(--closina-surface);
}

/* Grid content area and table — Syncfusion defaults these to white */
[data-theme="dark"] .e-grid .e-gridcontent,
[data-theme="dark"] .e-grid .e-content {
    background-color: var(--closina-surface) !important;
}

[data-theme="dark"] .e-grid table.e-table {
    background-color: var(--closina-surface) !important;
}

/* Group drop area */
/* WCAG 1.4.3 (U89 a4b a11y G6): Syncfusion defaults the group-drop placeholder text to
   #6c757d, which is 4.45:1 on the light surface (#f8f9fa) — just under the 4.5:1 AA floor.
   Pin it to the secondary token (#6b7280 ≈ 4.59:1 in light mode); the dark-mode override
   below resolves the same token to its dark value. */
.e-grid .e-groupdroparea {
    color: var(--closina-text-secondary) !important;
}

/* U89 grouped-caption color dot — restores the Stage/Status chip color encoding that is
   otherwise lost when the grouped column leaves the data area (ShowGroupedColumn="false").
   Rendered by StandardGrid's CaptionTemplate via GroupCaptionColorResolver. */
.closina-group-caption-dot {
    font-size: 0.75rem !important;
    vertical-align: middle;
    margin-right: 6px;
}

[data-theme="dark"] .e-grid .e-groupdroparea {
    background-color: var(--closina-surface-hover) !important;
    color: var(--closina-text-secondary) !important;
    border-color: var(--closina-border) !important;
}

/* Pager container and navigation buttons — Syncfusion defaults these to white */
[data-theme="dark"] .e-grid .e-pagercontainer {
    background-color: var(--closina-surface) !important;
}

[data-theme="dark"] .e-grid .e-pager .e-mfirst,
[data-theme="dark"] .e-grid .e-pager .e-mprev,
[data-theme="dark"] .e-grid .e-pager .e-mnext,
[data-theme="dark"] .e-grid .e-pager .e-mlast,
[data-theme="dark"] .e-grid .e-pager .e-first,
[data-theme="dark"] .e-grid .e-pager .e-prev,
[data-theme="dark"] .e-grid .e-pager .e-next,
[data-theme="dark"] .e-grid .e-pager .e-last {
    background-color: transparent !important;
    color: var(--closina-text-secondary) !important;
}

[data-theme="dark"] .e-grid .e-pager .e-mfirst:hover,
[data-theme="dark"] .e-grid .e-pager .e-mprev:hover,
[data-theme="dark"] .e-grid .e-pager .e-mnext:hover,
[data-theme="dark"] .e-grid .e-pager .e-mlast:hover,
[data-theme="dark"] .e-grid .e-pager .e-first:hover,
[data-theme="dark"] .e-grid .e-pager .e-prev:hover,
[data-theme="dark"] .e-grid .e-pager .e-next:hover,
[data-theme="dark"] .e-grid .e-pager .e-last:hover {
    background-color: var(--closina-surface-hover) !important;
}

/* Pager icons (arrow SVGs) */
[data-theme="dark"] .e-grid .e-pager .e-icon-first::before,
[data-theme="dark"] .e-grid .e-pager .e-icon-prev::before,
[data-theme="dark"] .e-grid .e-pager .e-icon-next::before,
[data-theme="dark"] .e-grid .e-pager .e-icon-last::before {
    color: var(--closina-text-secondary) !important;
}

/* Pager "items per page" dropdown */
[data-theme="dark"] .e-grid .e-pager .e-ddl,
[data-theme="dark"] .e-grid .e-pager .e-ddl .e-input-group {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-grid .e-pager .e-ddl input.e-input {
    color: var(--closina-text-primary) !important;
}

/* Pager info text ("1 of 5 pages", "1 to 20 of 93 items") */
[data-theme="dark"] .e-grid .e-pager .e-pagerconstant,
[data-theme="dark"] .e-grid .e-pager .e-pagerexternalmsg,
[data-theme="dark"] .e-grid .e-pager .e-parentmsgbar {
    color: var(--closina-text-secondary) !important;
}

/* Pager page-size dropdown popup */
[data-theme="dark"] .e-ddl.e-popup,
[data-theme="dark"] .e-dropdownbase .e-list-item {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
}

[data-theme="dark"] .e-ddl.e-popup .e-list-item:hover,
[data-theme="dark"] .e-dropdownbase .e-list-item.e-hover {
    background-color: var(--closina-surface-hover) !important;
}

/* =============================================================================
   9b. Syncfusion Scheduler Overrides (SfSchedule) — U100 SP-A (issue #1 P1)
   Mirrors the .e-grid dark block above: SfSchedule ships bootstrap5-dark grays with no
   Closina brand override, so the 3 Scheduler pages (Member/Admin team calendars +
   Member appointments) render off-brand gray in dark mode. Map header cells, work/time
   cells, toolbar, and appointment surfaces to the equivalent --closina-* tokens. The
   runtime <link> bundle swap (app.js closinaTheme.setDark) covers cold-boot on all 3 pages.
   ============================================================================= */

[data-theme="dark"] .e-schedule {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Scheduler table container + wrappers */
[data-theme="dark"] .e-schedule .e-table-container,
[data-theme="dark"] .e-schedule .e-content-wrap,
[data-theme="dark"] .e-schedule .e-date-header-container,
[data-theme="dark"] .e-schedule .e-time-cells-wrap {
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border) !important;
}

/* Date / resource / all-day header cells (mirror .e-headercell → surface-hover) */
[data-theme="dark"] .e-schedule .e-header-cells,
[data-theme="dark"] .e-schedule .e-date-header,
[data-theme="dark"] .e-schedule .e-resource-cells,
[data-theme="dark"] .e-schedule .e-all-day-cells,
[data-theme="dark"] .e-schedule .e-all-day-appointment-section {
    background-color: var(--closina-surface-hover) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Time-axis labels (left gutter) */
[data-theme="dark"] .e-schedule .e-time-cells,
[data-theme="dark"] .e-schedule .e-time-slots {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-secondary) !important;
    border-color: var(--closina-border) !important;
}

/* Work / month / day-grid cells (mirror .e-rowcell → surface) */
[data-theme="dark"] .e-schedule .e-work-cells,
[data-theme="dark"] .e-schedule .e-work-days,
[data-theme="dark"] .e-schedule .e-month-cells,
[data-theme="dark"] .e-schedule .e-date-header-wrap table td {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

/* Alternate / work-hours shading */
[data-theme="dark"] .e-schedule .e-work-hours {
    background-color: var(--closina-surface-hover) !important;
}

/* Cell hover (mirror .e-row:hover → surface-hover) */
[data-theme="dark"] .e-schedule .e-work-cells:hover,
[data-theme="dark"] .e-schedule .e-month-cells:hover {
    background-color: var(--closina-surface-hover) !important;
}

/* Today / current-day + current-time indicator (mirror .e-currentitem → primary) */
[data-theme="dark"] .e-schedule .e-current-day {
    color: var(--closina-primary) !important;
}

[data-theme="dark"] .e-schedule .e-current-time,
[data-theme="dark"] .e-schedule .e-current-timeline {
    color: var(--closina-primary) !important;
    border-color: var(--closina-primary) !important;
}

[data-theme="dark"] .e-schedule .e-selected-cell,
[data-theme="dark"] .e-schedule .e-selection {
    background-color: var(--closina-primary-light) !important;
}

/* Scheduler toolbar (mirror .e-grid .e-toolbar → surface) */
[data-theme="dark"] .e-schedule .e-schedule-toolbar,
[data-theme="dark"] .e-schedule .e-schedule-toolbar .e-toolbar-items {
    background-color: var(--closina-surface) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-schedule .e-schedule-toolbar .e-tbar-btn,
[data-theme="dark"] .e-schedule .e-schedule-toolbar .e-tbar-btn-text,
[data-theme="dark"] .e-schedule .e-schedule-toolbar .e-icons {
    color: var(--closina-text-primary) !important;
}

[data-theme="dark"] .e-schedule .e-schedule-toolbar .e-active-view .e-tbar-btn-text {
    color: var(--closina-primary) !important;
}

/* Appointment surfaces (mirror .e-selectionbackground → primary) */
[data-theme="dark"] .e-schedule .e-appointment {
    background-color: var(--closina-primary) !important;
    color: var(--closina-primary-text) !important;
    border-color: var(--closina-primary) !important;
}

[data-theme="dark"] .e-schedule .e-appointment .e-subject,
[data-theme="dark"] .e-schedule .e-appointment .e-time,
[data-theme="dark"] .e-schedule .e-appointment .e-location {
    color: var(--closina-primary-text) !important;
}

[data-theme="dark"] .e-schedule .e-more-indicator,
[data-theme="dark"] .e-schedule .e-more-appointments {
    color: var(--closina-primary) !important;
}

/* Scheduler popups / quick-info + event editor (mirror .e-grid .e-dialog → surface) */
[data-theme="dark"] .e-schedule .e-quick-popup-wrapper,
[data-theme="dark"] .e-quick-popup-wrapper,
[data-theme="dark"] .e-schedule-dialog.e-dialog,
[data-theme="dark"] .e-schedule .e-more-popup-wrapper {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border-color: var(--closina-border) !important;
}

[data-theme="dark"] .e-quick-popup-wrapper .e-popup-header,
[data-theme="dark"] .e-quick-popup-wrapper .e-popup-content,
[data-theme="dark"] .e-schedule .e-more-popup-wrapper .e-more-event-popup {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
}

/* =============================================================================
   10. Syncfusion Chart Overrides (SfChart)
   ============================================================================= */

/* Font standardization - inherit Inter across all chart text */
.e-chart text,
.e-chart .e-chart-title,
.e-chart .e-axis-title,
.e-chart .e-axis-label,
.e-chart .e-legend-text,
.e-chart .e-datalabel,
.e-chart tspan {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
}

/* Chart area background */
.e-chart {
    background: transparent !important;
}

/* Dark mode - Syncfusion charts */
[data-theme="dark"] .e-chart {
    background: transparent !important;
}

/* Chart SVG background rect (Syncfusion sets fill="#FFFFFF" inline) */
[data-theme="dark"] .e-chart rect[id*="ChartBorder"] {
    fill: var(--closina-surface) !important;
}

/* Axis labels */
[data-theme="dark"] .e-chart .e-axis-label,
[data-theme="dark"] .e-chart text[id*="AxisLabel"],
[data-theme="dark"] .e-chart text[id*="axislabel"] {
    fill: var(--closina-text-secondary) !important;
}

/* Axis titles */
[data-theme="dark"] .e-chart .e-axis-title,
[data-theme="dark"] .e-chart text[id*="AxisTitle"],
[data-theme="dark"] .e-chart text[id*="axistitle"] {
    fill: var(--closina-text-primary) !important;
}

/* Chart title */
[data-theme="dark"] .e-chart .e-chart-title,
[data-theme="dark"] .e-chart text[id*="_ChartTitle"] {
    fill: var(--closina-text-primary) !important;
}

/* Legend text */
[data-theme="dark"] .e-chart .e-legend-text,
[data-theme="dark"] .e-chart text[id*="_chart_legend_text"] {
    fill: var(--closina-text-secondary) !important;
}

/* Grid lines */
[data-theme="dark"] .e-chart line[id*="MajorGridLine"],
[data-theme="dark"] .e-chart line[id*="MajorTickLine"] {
    stroke: var(--closina-border) !important;
}

/* Axis lines */
[data-theme="dark"] .e-chart line[id*="AxisLine"] {
    stroke: var(--closina-border-strong) !important;
}

/* Tooltip */
[data-theme="dark"] .e-chart-tooltip,
[data-theme="dark"] .e-chart .e-tooltip-wrap {
    background-color: var(--closina-surface) !important;
    color: var(--closina-text-primary) !important;
    border: 1px solid var(--closina-border) !important;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
}

/* Crosshair label */
[data-theme="dark"] .e-chart rect[id*="Crosshair"] {
    fill: var(--closina-surface) !important;
}

/* =============================================================================
   11. MudBlazor Chart Overrides (MudChart)
   ============================================================================= */

/* Font standardization - inherit Inter on MudChart SVG text */
.mud-chart text,
.mud-chart .mud-chart-legend-item {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
}

/* Dark mode - MudChart */
[data-theme="dark"] .mud-chart text {
    fill: var(--closina-text-secondary) !important;
}

/* MudChart grid/axis lines */
[data-theme="dark"] .mud-chart line,
[data-theme="dark"] .mud-chart .mud-chart-line {
    stroke: var(--closina-border) !important;
}

/* MudChart legend text */
[data-theme="dark"] .mud-chart .mud-chart-legend-item .mud-typography {
    color: var(--closina-text-secondary) !important;
}

/* =============================================================================
   11b. UnifiedInbox Bell Arrival Pulse (Phase F127 Sub-Phase G - Decision 7)
   =============================================================================
   ONE-SHOT attention treatment fired when a notification ARRIVES via SignalR.
   Deliberately finite - iteration count 1, 600ms - and driven by a transient
   flag rather than by the unread count. A count-driven trigger would be
   permanently true against a large backlog, giving an always-on signal, which
   is the wallpaper failure mode Sub-Phase G exists to end. Contrast
   .pulsing-badge in standardgrid.css, which pulses infinitely while its count
   is nonzero - correct for a manual refresh affordance, wrong for arrivals.
   Scale only, no translation, to stay clear of vestibular triggers.
   ============================================================================= */

.mud-badge.bell-arrival-pulse {
    animation: bell-arrival 600ms ease-in-out 1;
}

@keyframes bell-arrival {
    0% {
        transform: scale(1);
    }
    40% {
        transform: scale(1.35);
    }
    100% {
        transform: scale(1);
    }
}

/* =============================================================================
   12. Reduced Motion Support (Phase U07 - WCAG 2.3.3)
   =============================================================================
   When the user has requested reduced motion in their OS settings, disable or
   minimize all CSS transitions and animations. This prevents vestibular
   disorders from being triggered by motion in the UI.
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
    /* Override Closina transition tokens to instant */
    :root {
        --closina-transition: 0.01s ease;
        --closina-transition-fast: 0.01s ease;
        --closina-transition-slow: 0.01s ease;
    }

    /* Disable all CSS transitions globally */
    *,
    *::before,
    *::after {
        transition-duration: 0.01s !important;
        animation-duration: 0.01s !important;
        animation-iteration-count: 1 !important;
    }

    /* Disable MudBlazor hover transforms (button lift, fab rise) */
    .mud-button-root:hover,
    .mud-fab:hover {
        transform: none !important;
    }

    /* Disable MudBlazor progress bar animation for indeterminate state */
    .mud-progress-linear-indeterminate .mud-progress-linear-bar {
        animation: none !important;
    }

    /* Disable skeleton shimmer animation */
    .mud-skeleton {
        animation: none !important;
    }

    /* Disable Syncfusion grid animations */
    .e-grid .e-rowcell,
    .e-grid .e-row,
    .e-grid .e-altrow {
        transition: none !important;
    }

    /* Disable pulsing badge animation (RefreshButtonWithBadge) */
    .pulsing-badge {
        animation: none !important;
    }

    /* Disable the UnifiedInbox bell arrival pulse (Phase F127 Sub-Phase G).
       The blanket animation-iteration-count: 1 above does NOT suppress this one -
       it merely runs a finite animation once, which for a one-shot pulse is the
       whole animation. WCAG 2.3.3 wants it gone, so a NAMED per-class override is
       required, exactly as .pulsing-badge above needs one. */
    .bell-arrival-pulse {
        animation: none !important;
    }

    /* Disable loading progress bar animation */
    .loading-progress-bar {
        animation: none !important;
    }

    /* Disable drawer slide animations */
    .mud-drawer {
        transition-duration: 0.01s !important;
    }

    /* Disable dialog backdrop fade */
    .mud-overlay {
        transition-duration: 0.01s !important;
    }
}

/* -----------------------------------------------------------------------------
   12. AI Chat Markdown Content (Phase C23)
   Styles for rendered markdown inside Copilot/Coach chat bubbles.
   ----------------------------------------------------------------------------- */
.coach-markdown-content {
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--closina-text-primary);
}

.coach-markdown-content p {
    margin: 0 0 0.5rem 0;
}

.coach-markdown-content p:last-child {
    margin-bottom: 0;
}

.coach-markdown-content ul,
.coach-markdown-content ol {
    padding-left: 1.25rem;
    margin: 0 0 0.5rem 0;
}

.coach-markdown-content li {
    margin-bottom: 0.2rem;
}

.coach-markdown-content strong {
    font-weight: 600;
}

.coach-markdown-content code {
    background-color: var(--closina-code-bg);
    color: var(--closina-code-text);
    font-family: var(--closina-font-mono);
    padding: 0.1rem 0.3rem;
    border-radius: var(--closina-radius-sm);
    font-size: 0.85em;
}

/* OAuth consent-disclosure scope tokens - Phase S54 Sub-Phase D, WCAG 1.4.3 AA fix
   found at the exit /a4b, 2026-08-11.

   A BARE <code> on these pages inherits the vendored Bootstrap magenta, which measures
   3.97:1 on the dark card - an AA failure at the 4.5:1 floor - and exactly 4.50:1 on white,
   i.e. passing only because the surface is pure white, with no margin for any tint.

   Fixed by adopting the SAME themed token pair the two existing house code surfaces already
   use rather than minting a new colour: 15.96:1 light, 11.24:1 dark, both recomputed from the
   hex values rather than taken on trust.

   Scoped to a class, deliberately NOT a global [data-theme="dark"] code override: dark-mode
   bare code fails app-wide, but every surface that renders code heavily already scopes its own
   treatment - see .coach-markdown-content code above and help-center.css - so a global rule
   would be a wide blast radius that fights those two rather than joining them.

   Do NOT instead mirror data-bs-theme onto the html element: it reads as the tidier one-liner
   but switches Bootstrap's entire vendored dark palette at once and routes around Cat 22. */
.closina-scope-token {
    background-color: var(--closina-code-bg);
    color: var(--closina-code-text);
    font-family: var(--closina-font-mono);
    padding: 0.1rem 0.3rem;
    border-radius: var(--closina-radius-sm);
    /* 0.9em, NOT the 0.85em copied from .coach-markdown-content code. Adopting that value
       verbatim shrank these tokens 12.25px to 11.9px, which is the wrong direction for the one
       string on the page a reviewer reads character-by-character and cross-checks against the
       consent screen. No WCAG criterion sets a minimum font size, so this is legibility rather
       than conformance - and there is ample contrast headroom to spend on it at 15.96:1 light
       and 11.25:1 dark. */
    font-size: 0.9em;
    /* Preserved from the bare-code baseline: the googleapis.com/auth/... strings are long and
       unbreakable, so without this they drive horizontal overflow at narrow widths. */
    overflow-wrap: break-word;
}

.coach-markdown-content h1,
.coach-markdown-content h2,
.coach-markdown-content h3,
.coach-markdown-content h4 {
    font-weight: 600;
    margin: 0.75rem 0 0.35rem 0;
}

.coach-markdown-content h1 { font-size: 1.1rem; }
.coach-markdown-content h2 { font-size: 1.05rem; }
.coach-markdown-content h3 { font-size: 1rem; }
.coach-markdown-content h4 { font-size: 0.925rem; }

.coach-markdown-content blockquote {
    border-left: 3px solid var(--closina-border-strong);
    padding-left: 0.75rem;
    margin: 0.5rem 0;
    color: var(--closina-text-secondary);
}

.coach-markdown-content a {
    color: var(--closina-link);
    text-decoration: none;
}

.coach-markdown-content a:hover {
    text-decoration: underline;
}

/* -----------------------------------------------------------------------------
   14. Top Banners (Announcement, App Update)
   ----------------------------------------------------------------------------- */

/* Banners are inline in BasePageWrapper — no position:fixed needed.
   Zero out margins/radius for edge-to-edge appearance. */
.announcement-banner,
.app-update-banner {
    margin: 0 !important;
    border-radius: 0 !important;
}

/* Banner overflow indicator */
.banner-overflow-indicator {
    background: var(--closina-surface);
    color: var(--closina-text-secondary);
    border-bottom: 1px solid var(--closina-border);
    padding: 4px 16px;
    font-size: 0.8125rem;
    text-align: center;
}

[data-theme="dark"] .banner-overflow-indicator {
    background: var(--closina-surface);
    color: var(--closina-text-secondary);
    border-bottom-color: var(--closina-border);
}

/* Config Health Banner — inline in AdminPageWrapper, same pattern as CompactSecurityBar */
.config-health-banner {
    border-radius: var(--closina-radius-sm);
}

.config-health-banner .mud-alert-message {
    width: 100%;
}

/* Config Health Banner: Touch spacing between expand button and close icon.
   House UX-S05 adjacency convention (>=8px) — NOT WCAG 2.5.8, which is the 24x24 size
   minimum and has no 8px figure in it at all. Re-cited Phase Z39. */
@media (max-width: 959px) {
    .config-health-banner .mud-alert-close-button {
        margin-left: 8px !important;
    }
}

/* =============================================================================
   Phase U15d: ClosinaTheme Shell — iOS Safe-Area Insets + Admin Banner
   ============================================================================= */

/* iOS Safe-Area: Ensure MudAppBar respects the notch / Dynamic Island on iOS.
   env(safe-area-inset-top) evaluates to 0 on non-iOS devices — no visual impact. */
.closina-appbar {
    padding-top: env(safe-area-inset-top);
}

/* Phase U28: Hybrid top-bar shell wrapper. Inherits iOS safe-area from .closina-appbar,
   adds a subtle bottom border separating the top bar from the sidebar/content.
   Retest Fix 1: box-sizing border-box + explicit height so the 1px bottom border
   is absorbed into the spec'd 56px height (was rendering at 57px). */
.closina-topbar {
    padding-top: env(safe-area-inset-top);
    min-height: var(--closina-layout-topbar-height);
    height: var(--closina-layout-topbar-height);
    box-sizing: border-box;
    border-bottom: 1px solid var(--closina-border);
    box-shadow: var(--closina-shadow-sm);
    z-index: var(--closina-z-sticky);
}

[data-theme="dark"] .closina-topbar {
    border-bottom-color: var(--closina-border-strong);
}

/* Toolbar gutter override pinning hamburger icon center to rail center (x=32px).
   MudToolbar's default left gutter is 16px at <600px and 24px at ≥600px (Material
   Design "regular" variant). Combined with MudIconButton's internal padding (12px
   normal, 16px at touch breakpoints) and the 24px hamburger icon (MudBlazor
   default), the natural center lands at 24+12+12=48 on desktop / 24+16+12=52 on
   tablet / 16+16+12=44 on mobile — all right of the rail-icon center at 32.
   Pulling the toolbar gutter to 8px (desktop) / 4px (tablet+mobile) lands hamburger
   center exactly on 32, in the same column as every nav-link icon below. Right
   gutter intentionally untouched. */
.closina-topbar.mud-appbar > .mud-toolbar {
    padding-left: 4px;
}
@media (min-width: 960px) {
    .closina-topbar.mud-appbar > .mud-toolbar {
        padding-left: 8px;
    }
}

/* Phase U28: Named topbar slots. Brand hugs left, search is anchored center via
   flex-grow on the two spacers MainLayout already ships; widgets hug right. */
.closina-topbar-brand,
.closina-topbar-search,
.closina-topbar-widgets {
    flex-shrink: 0;
}

/* Brand wordmark — the "Closina" logotype: Fraunces, bold, token-sourced.
   Used by the landing hero (replaces an ad-hoc Bootstrap `fw-bold` utility).
   The top bar has its own size-tuned variant, .closina-topbar-wordmark, below. */
.closina-wordmark {
    font-family: var(--closina-font-display);
    font-weight: var(--closina-font-weight-bold, 700) !important;
    font-variation-settings: "opsz" 36, "SOFT" 30, "WONK" 0;
    letter-spacing: -0.01em;
}

.closina-topbar-wordmark {
    font-family: var(--closina-font-display);
    font-weight: var(--closina-font-weight-bold, 700);
    font-variation-settings: "opsz" 24, "SOFT" 30, "WONK" 0;
    color: inherit;
    letter-spacing: -0.02em;
    user-select: none;
    white-space: nowrap;
}

.closina-topbar-search {
    justify-content: center;
}

/* Phase U31C: ProfileMenu avatar trigger — reset native button chrome so the
   ClosinaAvatar renders as a bare circular click target. */
.closina-profile-menu-trigger {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    padding: 4px;
}

/* Phase U60 Sub-Phase A: removed component-scoped :focus-visible override —
   the universal *:focus-visible rule (section 5b) now provides high-contrast
   white/slate ring + halo, identical visual outcome with WCAG 1.4.11 compliance. */

/* UX-S04: enforce the house 44x44 touch floor on mobile + tablet. That floor is
   PLATFORM CONVENTION (Apple HIG 44pt / Material 48dp), not a WCAG bar — WCAG
   2.5.5 Target Size (Enhanced) is 44x44 at Level AAA and we do not claim AAA.
   The conformance bar we grade against is WCAG 2.5.8 Target Size (Minimum),
   Level AA, 24x24, at all pointer inputs including mouse.
   ClosinaAvatar Small is 32px + 4px button padding = 40px on desktop, which
   CLEARS the 24x24 AA floor and is therefore not a finding at desktop; it is
   only under the house touch floor, so at touch breakpoints we widen the
   trigger to 44x44 (avatar stays 32px; padding grows to 6px each side).
   U55 follow-up; re-cited Phase Z39 (was mislabelled "WCAG 2.5.5 AA"). */
@media (max-width: 959px) {
    .closina-profile-menu-trigger {
        min-width: 44px;
        min-height: 44px;
        padding: 6px;
    }
}

/* Phase U31C: ProfileMenu user-info header — prevents long names / emails from
   blowing out the menu width. */
.closina-profile-menu-header {
    max-width: 260px;
}

.closina-profile-menu-header .mud-typography {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Phase U53 Sub-Phase D: Xs viewport scroll for the avatar dropdown. At Xs
   the menu folds in 3 widget items (Language / Tenant / Theme) plus the
   3 consolidated entries + Logout + header — total 8 items can exceed
   short-screen viewport heights (foldables, landscape phones). Cap at 80vh
   with native scroll so Logout stays reachable. The popover selector targets
   the immediate sibling of the trigger (MudMenu renders the popover as a
   following-sibling fragment). */
@media (max-width: 599px) {
    .closina-profile-menu-trigger + .mud-popover {
        max-height: 80vh;
        overflow-y: auto;
    }
}

/* Phase U92-FU1 (2026-07-11): ActionOverflow Xs overflow (MudPopover-based). The
   relative container anchors the MudPopover to the trigger (AnchorOrigin/TransformOrigin
   position relative to a positioned ancestor). */
.closina-action-overflow {
    position: relative;
    display: inline-flex;
    align-items: center;
}

/* Give the popover a sensible min-width so the stacked cluster controls (member-filter,
   view-toggle, refresh) don't collapse to the trigger width. */
.closina-action-overflow-popover.mud-popover {
    min-width: 240px;
}

/* Phase U92-FU1 (2026-07-11): ActionOverflow Xs trigger. A RAW single-element
   <button> activator (keyboard-safe — a deterministic _open toggle drives a
   MudPopover; see ActionOverflow.razor for why MudMenu could not host these form
   controls for keyboard). Mirrors the .closina-profile-menu-trigger native-chrome
   reset, sized as a compact icon button. The trigger only renders at Xs (<=599px),
   so the house 44x44 touch floor applies unconditionally (platform convention, not
   WCAG 2.5.5 — that is AAA and not claimed; the AA bar is 2.5.8's 24x24). Focus ring comes from
   the universal *:focus-visible rule (section 5b). */
.closina-action-overflow-trigger {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    padding: 8px;
    min-width: 44px;
    min-height: 44px;
    transition: background-color var(--closina-transition-fast);
}

.closina-action-overflow-trigger:hover {
    background-color: var(--closina-surface-hover);
}

/* Phase U28: Hybrid left sidebar drawer. Width comes from the layout token so
   U17/U18 can override without touching MainLayout.razor. */
.closina-shell-sidebar.mud-drawer {
    width: var(--closina-layout-sidebar-width);
}

.closina-shell-sidebar.mud-drawer--mini:not(.mud-drawer--open) {
    width: var(--closina-layout-sidebar-width-rail);
}

/* Rail compaction: when the sidebar is in the closed-mini state (icon rail),
   collapse every MudNavGroup's child container so only top-level icons show.
   Without this, groups that auto-expand because the current route lives inside
   them render their children as a stacked column of flat icons in the 64px
   rail — MudBlazor even ships padding rules up to 6 levels deep for that case
   (.mud-drawer--closed.mud-drawer-mini .mud-nav-group * .mud-navmenu .mud-nav-link),
   which only makes sense if you actually want the child icons visible. We
   don't — the user reaches children by hovering (OpenMiniOnHover flips the
   drawer to --open, dropping this rule) or by pinning the sidebar open.
   Scoped to .closina-shell-sidebar so other MudDrawers in the app are untouched. */
.closina-shell-sidebar.mud-drawer-mini.mud-drawer--closed .mud-nav-group .mud-collapse-container {
    display: none;
}

/* Phase U68 Pattern A — tree indent + guide rail for child items.
   Goal: each nested level shifts 12px right + grows a 1px left guide rail,
   so depth hierarchy is visible without relying on icon-glyph cues
   (Sub-Phase D stripped 66 nested leaves of their icons by design).

   The cascade works by applying margin-left:12px to EVERY group's collapse
   container — children of a depth-N group sit 12px right of the group itself.
   Combined with the universal `.mud-nav-link { padding-left: 24px }` rule
   (below), every nav-link at depth N ends up at column (24 + 12·N) from the
   drawer edge. Activators and leaves at the same depth share one column,
   so peer rows align without per-depth overrides.

   Mini-rail mode is short-circuited above (display:none on collapse-container),
   so the 12px margin/rail only show in expanded / pinned drawer modes.
   Mobile 44px touch-target floor is unaffected — padding adds to min-height.
   Dark mode swaps via the `--closina-border` token. */
.closina-shell-sidebar .mud-nav-group > .mud-collapse-container {
    margin-left: 12px;
    border-left: 1px solid var(--closina-border-strong);
}

/* iOS Safe-Area: Bottom padding on main content for home indicator bar.
   Prevents content from being hidden behind the iOS home indicator. */
.closina-main-content {
    padding-bottom: env(safe-area-inset-bottom);
}

/* X03 Batch-2 (UX-R03): at Xs the fixed MobileBottomNavBar (height
   var(--closina-layout-bottom-nav-height)) overlays the scroll region and
   covers the last content row/field/card. Reserve the nav height + safe-area so
   the final interactive element clears it. Breakpoint matches the nav's own
   display:flex breakpoint (max-width:599px) so the two stay in lockstep; Sm+
   (where the nav is display:none) keeps the safe-area-only rule above. */
@media (max-width: 599px) {
    .closina-main-content {
        padding-bottom: calc(var(--closina-layout-bottom-nav-height, 56px) + env(safe-area-inset-bottom, 0px));
    }
}

/* Phase U15: Scale down drawer navigation icons for a tighter sidebar.
   MudBlazor default nav icons are 24px (1.5rem) — reduce to 20px (1.25rem)
   for a more professional sidebar density. */
.mud-drawer .mud-nav-link-icon {
    font-size: 1rem !important;
    width: 1rem;
    height: 1rem;
    vertical-align: middle;
}

/* Center 1rem (16px) nav icons within the 64px mini-rail so the icon column
   centerline aligns with the topbar hamburger. Default MudBlazor padding-left
   is 16px (icon left-edge x=16, center x=24); we need center x=32 to match
   the rail's true center, so left-edge x=24 → padding-left 24px. Applies in
   both mini and expanded states for visual consistency — in expanded state the
   labels shift right by 8px but drawer width is unchanged so no truncation
   risk. Scoped to `.closina-shell-sidebar` so other MudDrawers in the app
   (settings rail, etc.) are untouched. */
.closina-shell-sidebar .mud-nav-link,
.closina-shell-sidebar .mud-nav-group .mud-nav-link {
    padding-left: 24px !important;
}

.mud-drawer .mud-nav-group .mud-icon-root {
    font-size: 1rem !important;
    vertical-align: middle;
}

/* Phase U27 (Sub-Phase C.2): Greyed/locked menu items.
   MenuBuilderService stamps `.menu-item-locked` on items where the member's
   subscription tier does not entitle the feature AND the definition declares
   GatingMode.GreyedWithUpsell. The item renders disabled with a lock badge
   and a tooltip directing the user to the billing/upgrade flow. */
.mud-nav-link.menu-item-locked,
.mud-nav-link.menu-item-upgrade-required,
.mud-nav-link.menu-item-coming-soon {
    color: var(--closina-text-secondary) !important;
    opacity: 0.65;
}

.mud-nav-link.menu-item-locked:hover,
.mud-nav-link.menu-item-upgrade-required:hover,
.mud-nav-link.menu-item-coming-soon:hover {
    opacity: 0.85;
    background-color: var(--closina-surface-hover);
}

.mud-nav-link.menu-item-locked.mud-nav-link-disabled,
.mud-nav-link.menu-item-locked[disabled] {
    cursor: not-allowed;
    pointer-events: auto; /* keep the wrapping MudTooltip responsive */
}

/* Phase U29: Keyboard-shortcut chip used in KeyboardShortcutsDialog (and any
   future surface that renders a key-cap style glyph). Tokens-only so dark
   mode flips automatically via [data-theme="dark"]. */
.closina-kbd {
    display: inline-block;
    padding: 2px 6px;
    font-family: var(--closina-font-mono);
    font-size: 0.85em;
    color: var(--closina-text-primary);
    background: var(--closina-surface-hover);
    border: 1px solid var(--closina-border-strong);
    border-radius: var(--closina-radius-sm);
    box-shadow: var(--closina-shadow-sm);
    line-height: 1.4;
}

/* Phase U37b: Microcopy text rendered inside RemoteAuthenticatorView slots
   (<LoggingIn>, <CompletingLoggingIn>) on /authentication/login and
   /authentication/login-callback. Replaces Microsoft's default plain text.

   Phase U37e (2026-04-27 a4b polish): vertically center via flex column +
   min-height: 60vh so the slot text lands at the same visual center as the
   pre-WASM splash (loading.html with logomark + "Turning interest into
   opportunity..." tagline). Without centering, the text snapped to the
   top of the viewport on WASM boot — UX-R07 / UX-R09 / UX-R10 (a4b
   2026-04-27T17:30:00Z, ux-auditor 3 WARN, ui-reviewer 1 WARN). */
.closina-auth-progress {
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
    text-align: center;
    color: var(--closina-text-secondary);
    font-family: var(--closina-font-sans);
    font-weight: var(--closina-font-weight-medium);
    line-height: var(--closina-leading-normal);
}

/* Phase U37c: Preconnect indicator chip rendered on the public landing page.
   Visible 50ms-500ms during the IdentityServer + Google Fonts preconnect
   handshake; fades on timer OR first user interaction. JS controller lives
   at wwwroot/js/preconnect-indicator.js. */
.closina-preconnect-indicator {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    padding: 0.375rem 0.75rem;
    font-family: var(--closina-font-sans);
    font-size: 0.75rem;
    color: var(--closina-text-secondary);
    background: var(--closina-surface);
    border: 1px solid var(--closina-border-faint);
    border-radius: var(--closina-radius-md);
    box-shadow: var(--closina-shadow-sm);
    opacity: 0;
    pointer-events: none;
    transition: opacity 300ms var(--closina-transition);
    z-index: var(--closina-z-sticky);
}

.closina-preconnect-indicator.visible {
    opacity: 1;
}

.closina-preconnect-indicator.fading {
    opacity: 0;
}

/* Page-title typography — Fraunces serif on every page H1.
   Body/UI/sidebar/buttons/section headers stay Inter sans.
   Scope: any <h1> rendered by AdminPageHeader / MemberPageHeader
   (MudText Typo="Typo.h4" HtmlTag="h1") plus any inline page H1.
   App.razor's <h1 class="sr-only"> SSR anchor is visually hidden
   so the rule applies but is invisible. */
h1 {
    font-family: var(--closina-font-display) !important;
    font-weight: 600;
    font-variation-settings: "opsz" 36, "SOFT" 30, "WONK" 0;
    letter-spacing: -0.01em;
}

/* ============================================================================
   13. WCAG 1.4.3 Contrast Hardening (Phase U69 final, 2026-05-03;
       extended Phase Z38 Sub-Phase B, 2026-07-25)

   AA contrast failures surfaced by accessibility-auditor that come from default
   MudBlazor / Syncfusion theme tokens:

   (a-1) DARK-mode filled CHIP text, all six BRIGHT semantic severities (Phase Z38
       Sub-Phase B). MudBlazor paints WHITE contrast text on the deliberately bright
       PaletteDark fills, measured at 1.67-2.77:1 — sub-AA on ~742 of 866 chips.
       Fixed by darkening the TEXT rather than the fill. See the rule for the full
       per-severity contrast table and the secondary carve-out.

   (a-2) MudButton with Color.Warning + Variant.Filled. Historically the MudBlazor
       default fill was #e65100 (white text → 3.79:1, sub-AA), so an override forced
       the background to var(--closina-warning-darker) (#c2410c). As of Phase Z34
       (2026-07-05) the palette Warning slot itself is #c2410c (Routes.razor
       PaletteLight), so the LIGHT-mode override became a no-op and was REMOVED; only
       the DARK-mode parity rule remains (PaletteDark.Warning = bright #fbbf24, forced
       down to #c2410c so dark buttons match light). Phase Z38 Sub-Phase B narrowed
       this rule to BUTTONS — the rule body below records why the chip half was dropped.
       Affects the "Create Contact (Admin Override)" button on the /a/m/contacts header.

   (b) Syncfusion grid pager links default to Bootstrap-derived #0d6efd on
       #e9ecef → 3.80:1. Override .e-pager .e-link / .e-numericitem to use
       var(--closina-primary-darker) (#0a4d8c) which gives ≥ 5:1 on the same
       background. Affects every paginated <SfGrid> consumer.
   ============================================================================ */

/* (a-1) DARK-mode filled CHIP text — WCAG 1.4.3 AA (Phase Z38 Sub-Phase B, 2026-07-25).

   `ClosinaChip` defaults to Variant.Filled and only 124 of its 866 call sites override the
   variant, so roughly 742 chips render filled. In dark mode MudBlazor paints its own WHITE
   contrast text (--mud-palette-{severity}-text) onto the deliberately BRIGHT PaletteDark
   fills ("Amber-400 — bright for dark bg"), which the F83-FU3 a4b accessibility auditor
   measured live at Primary 2.54:1 and Error 2.77:1 — i.e. an AA failure on essentially every
   filled chip in the app, re-verified by that auditor away from the dialog it was auditing.

   Strategy (user decision, 2026-07-25): DARKEN THE TEXT, KEEP THE BRIGHT FILLS. This
   preserves the palette's stated "bright accents on a dark surface" intent, and #000 clears
   AA on all six by a wide margin (computed WCAG relative luminance):

       primary  #10b981 →  8.28:1      success  #4ade80 → 12.05:1
       warning  #fbbf24 → 12.58:1      error    #f87171 →  7.59:1
       info     #38bdf8 →  9.80:1      tertiary #2dd4bf → 11.28:1

   Icons follow for free via `.mud-chip .mud-icon-root { color: inherit !important }`
   (section 3). Light mode is untouched — the light fills are already dark enough that
   MudBlazor's white contrast text passes.

   HOVER was measured, not assumed. A `.mud-clickable` chip swaps its background to
   --mud-palette-{severity}-darken, which MudBlazor computes via MudColor.ColorRgbDarken()
   since Closina does not override the *Darken slots. Probing the real 9.7.0 implementation
   gives #0d9668 / #28d768 / #f5b105 / #f75050 / #13b2f6 / #24b29f, on which #000 measures
   5.58 / 11.01 / 11.17 / 6.22 / 8.73 / 7.94 :1 — all still AA. (White on those same hover
   fills is 1.88-3.76:1, i.e. failing, so black is the better choice in BOTH states.) Only
   the background changes on hover, so the color declared here carries through.

   🚨 `secondary` is DELIBERATELY EXCLUDED and must stay excluded. PaletteDark.Secondary
   #475569 (Slate-600) is the one DARK fill in the set, so the numbers invert: white on it is
   7.58:1 (PASSES) and black is 2.77:1 (FAILS). Adding `.mud-chip-color-secondary` here to
   "complete the set" would turn a passing severity into a failing one. Guarded by
   SemanticPaletteContrastConvention_Tests.Filled_Chip_Text_Token_Meets_AA_On_Its_Dark_Palette_Fill,
   which resolves the effective text AND the effective fill out of this file and fails on a
   pinned secondary token.

   Token reuse (Z38 B3): --closina-alert-dark-text is the shared "black on a bright dark
   fill" value — its own definition already documents it as covering ALL filled severities in
   dark mode, and it is consumed by the dark filled-alert/snackbar rules in section 8. The
   "alert" in the name is historical. A second chip-specific token holding an identical #000
   would be two sources of truth for one decision, free to drift apart. */
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-primary,
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-success,
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-warning,
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-error,
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-info,
[data-theme="dark"] .mud-chip.mud-chip-filled.mud-chip-color-tertiary {
    color: var(--closina-alert-dark-text);
}

/* (a-2) Warning-tier filled BUTTON — DARK-mode fill parity. BUTTONS ONLY.
   The LIGHT-mode bg override and the OUTLINED/TEXT foreground override were REMOVED in Phase
   Z34 (2026-07-05) as no-ops: the palette Warning slot is now #c2410c (Routes.razor
   PaletteLight), so MudBlazor already fills filled-warning buttons with #c2410c (white text =
   5.18:1) and already paints outlined/text warning labels with --mud-palette-warning.
   The DARK rule below is NOT redundant and is retained: PaletteDark.Warning is the bright
   #fbbf24, so without this override a dark filled-warning button would render bright amber —
   force the darker #c2410c for sibling parity with light.

   Phase Z38 Sub-Phase B DROPPED the `.mud-chip.mud-chip-filled.mud-chip-color-warning`
   selector that used to share this rule (B2 reconciliation). Two reasons:
     1. It was the ONLY fill-darkening rule among the chips, so warning alone reached AA by a
        different mechanism than its five siblings — two strategies coexisting silently, which
        is precisely what a later reader "harmonises" in the wrong direction.
     2. It is not even a viable strategy for chips: #000 on the darkened #c2410c is 4.06:1,
        still sub-AA. Keeping the darkened fill AND applying (a-1)'s black text would have
        BROKEN warning. Dropping it lets warning use the bright #fbbf24 fill like every other
        severity, where #000 measures 12.58:1.
   Buttons keep the fill-darkening and are explicitly out of scope for Z38: a filled-warning
   button in dark mode still renders #c2410c with MudBlazor's white text (5.18:1, passes AA),
   byte-identical to its pre-Z38 behaviour. */
[data-theme="dark"] .mud-button-filled.mud-button-filled-warning {
    background-color: var(--closina-warning-darker) !important;
}

/* (b) Syncfusion pager link contrast — override Bootstrap blue */
.e-pager .e-link,
.e-pager .e-numericitem,
.e-pager .e-currentitem {
    color: var(--closina-primary-darker) !important;
}

[data-theme="dark"] .e-pager .e-link,
[data-theme="dark"] .e-pager .e-numericitem,
[data-theme="dark"] .e-pager .e-currentitem {
    color: var(--closina-primary-light) !important;
}

/* ============================================================================
   14. Empty-state primitives (Phase Z08 follow-up, 2026-05-07)

   Shared classes consumed by:
     - Components/Loading/ChatLoadingStates.razor (chat-UI inline empty state)
     - Components/SmartLoadingWrapper.razor (generic empty slot)

   Replaces the inline `Style="font-size: 6rem; opacity: 0.5;"` /
   `font-size: 1.25rem; font-weight: 500;` / `min-height: 400px;` triplet
   that was previously hand-rolled at every empty-state site.
   ============================================================================ */

.closina-empty-state-container {
    min-height: 400px;
}

.closina-empty-state-icon {
    font-size: 6rem;
    opacity: 0.5;
}

.closina-empty-state-title {
    font-size: 1.25rem;
    font-weight: var(--closina-font-weight-medium);
}

/* ============================================================================
   CHART-ROW EMPTY STATE (Phase F13 Sub-Phase E / F7)
   ----------------------------------------------------------------------------
   The dashboard charts row places a populated chart (Height="300px") and a
   possibly-empty chart card side-by-side in the same MudGrid row. When one
   card has data and the other does not, the empty card collapses to a single
   line of text, leaving a tall band of trailing whitespace beside the
   populated chart. This class pins the empty-state body to the same vertical
   footprint as a rendered 300px chart and centers the "no data" message,
   so both cards in the row keep a consistent height.
   ============================================================================ */

.closina-chart-empty-state {
    min-height: 300px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Bubble-row alignment classes for MessageBubbleSkeletons — mimic chat layout
   (alternating left/right bubble alignment) without per-row inline styles. */

.closina-bubble-row {
    display: flex;
    width: 100%;
}

.closina-bubble-row--start {
    justify-content: flex-start;
}

.closina-bubble-row--end {
    justify-content: flex-end;
}

/* Phase F123 — keep a two-word page-header action label on ONE line.

   A page-header action cluster is a flex row, so between roughly 960px and
   1400px it compresses each button by a few px. That is enough to wrap a
   two-word label onto a second line, which makes the button ~61px tall beside
   44px siblings: a UX-R09 row-height and row-top jitter defect, and ~+20px of
   page-header chrome against the Cat 67 budget. Measured on
   MemberOutreachDetailPage at 1024 and 1366; clean at 1440 and above, and not
   in the DOM at or below 959px where ActionOverflow collapses the cluster.

   Deliberately an opt-in class rather than a blanket rule on
   .closina-page-header-actions: the cluster only has an overflow-x scroll
   safety valve at or below 959px (U92 Sub-A), so forcing nowrap on every
   header button app-wide could push a busy cluster into horizontal overflow
   in exactly the band this fixes — trading a local defect for a UX-R04 one.
   Apply per button where the label is known to wrap. */

.closina-header-action-nowrap .mud-button-label {
    white-space: nowrap;
}
