﻿/* ===================================================================
   DESIGN TOKENS (single canonical :root -- do NOT duplicate)
   ===================================================================
   Two theme schemes: "longbow" (default) and "bootstrap".
   Scheme is set via data-scheme attribute on <html> by theme.js.
   Dark mode uses [data-theme="dark"] on <html>, set by theme.js.
   A @media fallback ensures tokens flip before JS runs (prevents FOUC).
   =================================================================== */

/* -------------------------------------------------------------------
   LONGBOW NAVY & COOL GRAY (default scheme -- no data-scheme needed)
   ------------------------------------------------------------------- */
:root {
    /* Brand / accent -- Amber. #D4890C is the Longbow gold; it must stay in step
       with --lb-brand-hover / --lb-brand-rgb / --lb-active below, which are all
       derived from it. #3353 flattened this one declaration to the Bootstrap
       scheme's #CC6C2C on the "one token, one value" misreading and turned the
       whole default scheme orange; #3553 restored the two Bootstrap blocks but
       left this line behind. */
    --lb-brand: #D4890C;
    --lb-brand-hover: #BE7A08;
    --lb-brand-light: #FDF6EC;
    --lb-brand-rgb: 212, 137, 12;

    /* Semantic colors */
    --lb-danger: #C94A3A;
    --lb-danger-bg: #FCEAE7;
    --lb-success: #2D8B55;
    --lb-success-bg: #E8F5EE;
    --lb-warning: #C05F1A;
    --lb-warning-bg: #FBF0E8;
    --lb-info: #3A6B9A;
    --lb-info-bg: #EBF3FA;

    /* AI Disclaimer Framework banner/dialog tokens (text + border companions
       to the semantic bg tokens above; keep every scheme block in sync). */
    --lb-info-text: #2E5A85;
    --lb-info-border: #B9D4EA;
    --lb-warning-text: #9A4A12;
    --lb-warning-border: #EAC9AE;

    /* Text -- main content area (light backgrounds) */
    --lb-text: #1C2536;
    --lb-text-muted: #6B7280;
    --lb-text-dim: #9CA3AF;
    --lb-text-bright: #0F1726;

    /* Text -- on dark sidebar backgrounds */
    --lb-text-on-dark: #C8D0DC;
    --lb-text-on-dark-muted: #7A8698;
    --lb-text-on-dark-dim: #5A6578;

    /* Surfaces -- Cool gray base */
    --lb-border: #C7CDD7;
    --lb-border-light: #DDE1E8;
    --lb-bg-surface: #E9ECF1;
    --lb-bg-white: #FFFFFF;
    --lb-surface-alt: #F5F7FA;
    --lb-card: #FFFFFF;
    --lb-elevated: #E5E8ED;

    /* Sidebar -- dark Navy */
    --lb-sidebar: #1C2536;
    --lb-sidebar-hover: #253040;
    --lb-sidebar-active-bg: rgba(204, 108, 44, 0.15);

    /* Top bar */
    --lb-bg-topbar: var(--lb-bg-white);
    --lb-bg-dropdown: var(--lb-bg-white);
    --lb-accent-tint: rgba(212, 137, 12, 0.08);
    --lb-timer-active: var(--lb-success);
    --lb-timer-active-bg: rgba(45, 139, 85, 0.08);

    /* Active state (nav indicators, role badge, selected items) */
    --lb-active: #D4890C;
    --lb-active-bg: rgba(212, 137, 12, 0.08);

    /* Supplementary palette */
    --lb-yellow: #B8860B;
    --lb-purple: #6B5CA0;
    --lb-purple-bg: #EFECF6;
    --lb-blue: #3A6B9A;
    --lb-blue-bg: #EBF3FA;

    /* Shadows */
    --lb-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 2px 6px rgba(0, 0, 0, 0.06);
    --lb-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.10);
    --lb-overlay-scrim: rgba(28, 37, 54, 0.35);

    /* Flat (secondary) button colors */
    --lb-btn-flat-bg: #E5E8ED;
    --lb-btn-flat-border: #D8DCE3;
    --lb-btn-flat-text: #1C2536;
    --lb-btn-flat-hover-bg: #D8DCE3;
    --lb-btn-flat-hover-border: #C8CDD6;
    --lb-btn-flat-hover-text: #0F1726;
    --lb-btn-flat-disabled-bg: #F0F2F5;
    --lb-btn-flat-disabled-border: #E5E8ED;
    --lb-btn-flat-disabled-text: #9CA3AF;

    /* Danger button colors */
    --lb-btn-danger-hover-bg: #FCEAE7;
    --lb-btn-danger-hover-border: #C94A3A;

    /* Nav pills inactive hover */
    --lb-nav-pill-hover-bg: #FDF6EC;
    --lb-nav-pill-hover-text: #BE7A08;

    /* Validation */
    --lb-validation-text: #C94A3A;

    /* Shape */
    --lb-radius-pill: 1.25rem;
    --lb-radius-card: 8px;

    /* Layout dimensions -- consumed by MainLayout, TopBar, and dialogs.
     * Breakpoint VALUES (768px phone/tablet line, 1200px tablet/desktop line)
     * cannot be CSS variables because @media queries do not expand custom
     * properties. Documented breakpoints used across the app:
     *   phone     <  768px   (drawer overlay UX)
     *   tablet    768-1199px (compact desktop, will get collapsed rail in chunk 6)
     *   desktop   >= 1200px  (full expanded rail, 6-col stat grids)
     */
    --lb-sidebar-width-collapsed: 56px;
    --lb-sidebar-width-expanded: 220px;
    --lb-topbar-height: 3.5rem;
    --lb-content-padding-x-phone: 0.75rem;
    --lb-dialog-max-width-phone: 95vw;
    --lb-dialog-max-height-phone: 90vh;

    /* Case-tab grid offset -- the chrome above a case-tab grid (case header,
     * tab strip, stat cards, filter/toolbar row). Consumed as
     * Height="calc(100vh - var(--lb-case-tab-grid-offset))" by every case-tab
     * SfGrid so the five tabs cannot drift apart one PR at a time (#2683 fixed
     * the calendar tab alone; #2731 is the residual on its siblings).
     *
     * Declared here on :root, NOT in a component's scoped .razor.css, because
     * CaseTimeBilling / CaseCalendarItemsPage / CaseContactsPage each carry
     * their own @page route as well as being embedded in CaseDataForm -- a
     * scoped declaration on the tab shell would not reach them when they render
     * standalone, leaving var() undefined, which invalidates the whole height
     * declaration (see below for why that is dangerous).
     *
     * KEEP THIS A FIXED LENGTH. Syncfusion infinite scroll needs a fixed grid
     * height to produce a scrollbar at all; a percentage/flex/auto height kills
     * loading outright (blank grid on filter change #1809; unreachable rows on
     * tall monitors, beta 2026-07-20). Each consumer also passes a 300px
     * fallback -- var(--lb-case-tab-grid-offset, 300px) -- so that if this token
     * is ever removed the height stays a fixed calc() instead of collapsing to
     * auto (which is that same infinite-scroll death).
     *
     * TWO CHROME STATES, so TWO VALUES (#3488). Focus mode (the default on case
     * routes) hides the top bar with display:none, which lifts everything below
     * it by --lb-topbar-height + its 1px border = 57px. A single fixed length
     * therefore cannot be right in both states, and the wrong direction is not
     * symmetric: too SMALL an offset makes the grid too tall, runs it past the
     * fold and puts the last rows behind an outer page scroll where they are
     * unreachable (#1809 / #2731 / #3203) -- while too LARGE only leaves a dead
     * strip, which is cosmetic.
     *
     * So the base value below is the focus-OFF (top bar visible) reserve = the
     * measured focus-ON value + 57px, and `main.lb-focus-active` further down
     * reclaims the bar's height. Base = the safe side, exactly as
     * CaseDataForm.razor.css:8-18 reasons about the case shell's own height.
     */
    --lb-case-tab-grid-offset: 357px;

    /* Same knob, for the one case tab whose grid sits under a StatCard row
     * instead of a toolbar row (Subpoenas). A stat row is taller chrome, so the
     * flat 300px would run the grid past the fold and put the last rows behind
     * an outer page scroll -- the opposite defect from the 430px literal this
     * replaces, which left a dead strip instead (#3203, split out of #3198).
     *
     * MEASURED, not derived: on Longbow_ATS case 1074 at a 855px viewport the
     * Subpoenas grid's top edge sits 284px down, and Syncfusion applies Height
     * to the grid's CONTENT area with the ~43px header row outside it, so the
     * grid reaches the fold at 284 + 43 = 327px. 340px keeps a ~13px gutter so
     * a slightly taller stat row cannot tip it into an overshoot. (For scale:
     * the toolbar-row tabs on the 300px token measure a 308px top edge.)
     *
     * Both measurements above were taken on a case route, i.e. in focus mode --
     * so they are the focus-ON figures, and the base values here carry the
     * +57px focus-OFF reserve (#3488). See the two-state note on the sibling
     * token above; the focus-ON originals are restored by the
     * `main.lb-focus-active` block below.
     *
     * MUST stay a `calc(100vh - var(--token, Npx))` at each consumer: Audit 14
     * (scripts/infinite-scroll-gate.py, RE_CALC_VH_VAR) requires the var() to
     * close the calc(), and a `calc(... var(...) - 130px)` form silently
     * degrades to "unresolvable height" and drops the grid out of coverage.
     */
    --lb-case-tab-grid-offset-stats: 397px;

    /* Focus ring */
    --lb-focus-ring: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;

    /* Phase 3 -- Timeline & Kanban */
    --lb-timeline-track: var(--lb-brand);
    --lb-timeline-track-bg: var(--lb-brand-light);
    --lb-timeline-sol: var(--lb-danger);
    --lb-timeline-waiting: var(--lb-warning);
    --lb-timeline-today: var(--lb-info);
    --lb-timeline-grid: #E5E8ED;
    --lb-kanban-unassigned: var(--lb-text-muted);
    --lb-ai-panel-bg: var(--lb-surface-alt);
    --lb-ai-accent: var(--lb-purple);

    /* Contact category badges -- light */
    --lb-text-on-brand: #FFFFFF;
    --lb-badge-client: #2563EB;
    --lb-badge-client-bg: #DBEAFE;
    --lb-badge-medical: #16A34A;
    --lb-badge-medical-bg: #DCFCE7;
    --lb-badge-adjuster: #C05F1A;
    --lb-badge-adjuster-bg: #FBF0E8;
    --lb-badge-defense: #C94A3A;
    --lb-badge-defense-bg: #FCEAE7;
    --lb-badge-expert: #7C3AED;
    --lb-badge-expert-bg: #EDE9FE;
    --lb-badge-staff: #0D9488;
    --lb-badge-staff-bg: #CCFBF1;
    --lb-badge-other: #6B7280;
    --lb-badge-other-bg: #F3F4F6;
}

/* -------------------------------------------------------------------
   FOCUS MODE -- case-tab grid offsets (#3488)
   -------------------------------------------------------------------
   MainLayout marks <main> with .lb-focus-active while focus mode is on
   (the default on all 11 case-tab routes), which hides the top bar and
   lifts everything below it by --lb-topbar-height + its 1px border.
   Redeclaring the tokens on that ancestor gives the case-tab grids the
   MEASURED focus-ON offsets; custom properties inherit, so every grid
   inside <main> picks these up with no change at the consumers -- they
   stay `calc(100vh - var(--token, Npx))`, which is what Audit 14
   (scripts/infinite-scroll-gate.py) requires.

   The :root values above are these plus 57px (the focus-OFF reserve).
   Keep the pair in step: the difference between the two blocks must
   stay exactly --lb-topbar-height + 1px, and both must stay fixed
   lengths. Same two-state shape as CaseDataForm.razor.css:28-30, which
   branches the case shell's own height on this class.
   ------------------------------------------------------------------- */
main.lb-focus-active {
    --lb-case-tab-grid-offset: 300px;
    --lb-case-tab-grid-offset-stats: 340px;
}

/* -------------------------------------------------------------------
   LONGBOW DARK MODE (data-attribute set by theme.js)
   -------------------------------------------------------------------
   theme.js sets data-theme="dark" on <html> synchronously in <head>.
   All dark-mode token overrides key off this attribute. The @media
   fallback below handles the brief window before JS executes.
   ------------------------------------------------------------------- */
[data-theme="dark"] {
    --lb-text: #C8CAD0;
    --lb-text-muted: #7A7E88;
    --lb-text-dim: #4A4E58;
    --lb-text-bright: #E8EAF0;
    --lb-text-on-dark: #C0C4CC;
    --lb-text-on-dark-muted: #6A7080;
    --lb-text-on-dark-dim: #7A7E88;
    --lb-border: #2E3038;
    --lb-border-light: #383A42;
    --lb-bg-surface: #101114;
    --lb-bg-white: #1A1B1F;
    --lb-surface-alt: #151618;
    --lb-card: #1E2024;
    --lb-elevated: #282A30;
    --lb-bg-topbar: #1E2024;
    --lb-bg-dropdown: #1E2024;
    --lb-brand-light: #2D2010;
    --lb-danger: #E05A4A;
    --lb-danger-bg: #2E1210;
    --lb-success: #38B068;
    --lb-success-bg: #0E2818;
    --lb-warning: #D06828;
    --lb-warning-bg: #2E1A0C;
    --lb-info: #5A8FC0;
    --lb-info-bg: #101E2E;
    --lb-info-text: #8FB8E0;
    --lb-info-border: #24425E;
    --lb-warning-text: #E8955A;
    --lb-warning-border: #4E2E14;
    --lb-accent-tint: rgba(212, 137, 12, 0.15);
    --lb-timer-active-bg: rgba(56, 176, 104, 0.15);
    --lb-sidebar: #16171C;
    --lb-sidebar-hover: #24262C;
    --lb-sidebar-active-bg: rgba(212, 137, 12, 0.12);
    --lb-active: #D4890C;
    --lb-active-bg: rgba(212, 137, 12, 0.10);
    --lb-yellow: #D4A020;
    --lb-purple: #8B7AC8;
    --lb-purple-bg: #1A1630;
    --lb-blue: #5A8FC0;
    --lb-blue-bg: #101E2E;
    --lb-shadow: 0 1px 3px rgba(0, 0, 0, 0.30);
    --lb-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.50);
    --lb-overlay-scrim: rgba(13, 14, 16, 0.45);

    /* Flat button tokens -- dark variants */
    --lb-btn-flat-bg: #282A30;
    --lb-btn-flat-border: #383A42;
    --lb-btn-flat-text: #C8CAD0;
    --lb-btn-flat-hover-bg: #34363E;
    --lb-btn-flat-hover-border: #484A54;
    --lb-btn-flat-hover-text: #E8EAF0;
    --lb-btn-flat-disabled-bg: #1A1B1F;
    --lb-btn-flat-disabled-border: #2E3038;
    --lb-btn-flat-disabled-text: #4A4E58;

    /* Danger hover -- dark */
    --lb-btn-danger-hover-bg: #2E1210;
    --lb-btn-danger-hover-border: #E05A4A;

    /* Nav pills hover -- dark */
    --lb-nav-pill-hover-bg: #2D2010;
    --lb-nav-pill-hover-text: var(--lb-brand);

    /* Validation -- dark */
    --lb-validation-text: #E05A4A;

    /* Focus ring inner glow -- dark surfaces need dark inner ring */
    --lb-focus-ring: 0 0 0 0.1rem #101114, 0 0 0 0.25rem #258cfb;

    /* Timeline gridlines -- dark */
    --lb-timeline-grid: #252730;

    /* Contact category badges -- dark */
    --lb-text-on-brand: #FFFFFF;
    --lb-badge-client: #93C5FD;
    --lb-badge-client-bg: #1E3A5F;
    --lb-badge-medical: #86EFAC;
    --lb-badge-medical-bg: #14332A;
    --lb-badge-adjuster: #FDBA74;
    --lb-badge-adjuster-bg: #3D2510;
    --lb-badge-defense: #FCA5A5;
    --lb-badge-defense-bg: #3B1414;
    --lb-badge-expert: #C4B5FD;
    --lb-badge-expert-bg: #2E1A5E;
    --lb-badge-staff: #5EEAD4;
    --lb-badge-staff-bg: #0D3331;
    --lb-badge-other: #9CA3AF;
    --lb-badge-other-bg: #2A2D33;
}

/* -- Dark mode: Bootstrap form-control inputs -- */
[data-theme="dark"] .form-control {
    background-color: var(--lb-bg-white);
    color: var(--lb-text);
    border-color: var(--lb-border);
}

[data-theme="dark"] .form-control::placeholder {
    color: var(--lb-text-muted);
}

[data-theme="dark"] .form-control:focus {
    background-color: var(--lb-elevated);
    color: var(--lb-text);
    border-color: var(--lb-brand);
    box-shadow: 0 0 0 0.2rem rgba(212, 137, 12, 0.15);
}

/* -------------------------------------------------------------------
   BOOTSTRAP DEFAULT SCHEME (opt-in via data-scheme="bootstrap")
   ------------------------------------------------------------------- */
[data-scheme="bootstrap"] {
    /* Bootstrap primary. This DELIBERATELY differs from the :root Longbow amber --
       re-valuing --lb-brand per scheme is the whole mechanism of the color-scheme
       picker, not token drift. #3353 flattened all three --lb-brand declarations to
       the Longbow amber on that misreading and broke the Bootstrap scheme; do not
       "normalize" these back together. */
    --lb-brand: #0d6efd;
    --lb-brand-hover: #0b5ed7;
    --lb-brand-light: #e7f1ff;
    --lb-brand-rgb: 13, 110, 253;
    --lb-danger: #dc3545;
    --lb-danger-bg: #f8d7da;
    --lb-success: #198754;
    --lb-success-bg: #d1e7dd;
    --lb-warning: #fd7e14;
    --lb-warning-bg: #fff3cd;
    --lb-info: #0dcaf0;
    --lb-info-bg: #cff4fc;
    --lb-info-text: #055160;
    --lb-info-border: #9eeaf9;
    --lb-warning-text: #664d03;
    --lb-warning-border: #ffe69c;
    --lb-text: #212529;
    --lb-text-muted: #6c757d;
    --lb-text-dim: #adb5bd;
    --lb-text-bright: #000;
    --lb-text-on-dark: #dee2e6;
    --lb-text-on-dark-muted: #adb5bd;
    --lb-text-on-dark-dim: #6c757d;
    --lb-border: #dee2e6;
    --lb-border-light: #e9ecef;
    --lb-bg-surface: #f8f9fa;
    --lb-bg-white: #fff;
    --lb-surface-alt: #f8f9fa;
    --lb-card: #fff;
    --lb-elevated: #e9ecef;
    --lb-sidebar: #212529;
    --lb-sidebar-hover: #343a40;
    --lb-sidebar-active-bg: rgba(13, 110, 253, 0.12);
    --lb-bg-topbar: #fff;
    --lb-bg-dropdown: #fff;
    --lb-accent-tint: rgba(13, 110, 253, 0.08);
    --lb-timer-active: #198754;
    --lb-timer-active-bg: rgba(25, 135, 84, 0.08);
    --lb-active: #0d6efd;
    --lb-active-bg: rgba(13, 110, 253, 0.08);
    --lb-yellow: #ffc107;
    --lb-purple: #6f42c1;
    --lb-purple-bg: #e2d9f3;
    --lb-blue: #0d6efd;
    --lb-blue-bg: #e7f1ff;
    --lb-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    --lb-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.10);
    --lb-overlay-scrim: rgba(33, 37, 41, 0.35);
    --lb-btn-flat-bg: #e9ecef;
    --lb-btn-flat-border: #dee2e6;
    --lb-btn-flat-text: #212529;
    --lb-btn-flat-hover-bg: #dee2e6;
    --lb-btn-flat-hover-border: #ced4da;
    --lb-btn-flat-hover-text: #000;
    --lb-btn-flat-disabled-bg: #f8f9fa;
    --lb-btn-flat-disabled-border: #e9ecef;
    --lb-btn-flat-disabled-text: #adb5bd;
    --lb-btn-danger-hover-bg: #f8d7da;
    --lb-btn-danger-hover-border: #dc3545;
    --lb-nav-pill-hover-bg: #e7f1ff;
    --lb-nav-pill-hover-text: #0b5ed7;
    --lb-validation-text: #dc3545;
    --lb-focus-ring: 0 0 0 0.1rem white, 0 0 0 0.25rem #0d6efd;

    /* Contact category badges -- bootstrap light */
    --lb-text-on-brand: #FFFFFF;
    --lb-badge-client: #0d6efd;
    --lb-badge-client-bg: #cfe2ff;
    --lb-badge-medical: #198754;
    --lb-badge-medical-bg: #d1e7dd;
    --lb-badge-adjuster: #fd7e14;
    --lb-badge-adjuster-bg: #fff3cd;
    --lb-badge-defense: #dc3545;
    --lb-badge-defense-bg: #f8d7da;
    --lb-badge-expert: #6f42c1;
    --lb-badge-expert-bg: #e2d9f3;
    --lb-badge-staff: #20c997;
    --lb-badge-staff-bg: #d2f4ea;
    --lb-badge-other: #6c757d;
    --lb-badge-other-bg: #e9ecef;
}

/* Bootstrap dark = both attributes present */
[data-theme="dark"][data-scheme="bootstrap"] {
    /* Bootstrap primary, dark variant -- see the note on the light block above. */
    --lb-brand: #6ea8fe;
    --lb-brand-hover: #8bb9fe;
    --lb-brand-light: #0a1628;
    --lb-brand-rgb: 110, 168, 254;
    --lb-danger: #ea868f;
    --lb-danger-bg: #2c0b0e;
    --lb-success: #75b798;
    --lb-success-bg: #0a1e13;
    --lb-warning: #ffb870;
    --lb-warning-bg: #332000;
    --lb-info: #6edff6;
    --lb-info-bg: #032830;
    --lb-info-text: #6edff6;
    --lb-info-border: #087990;
    --lb-warning-text: #ffda6a;
    --lb-warning-border: #997404;
    --lb-text: #dee2e6;
    --lb-text-muted: #adb5bd;
    --lb-text-dim: #6c757d;
    --lb-text-bright: #f8f9fa;
    --lb-text-on-dark: #dee2e6;
    --lb-text-on-dark-muted: #adb5bd;
    --lb-text-on-dark-dim: #6c757d;
    --lb-border: #495057;
    --lb-border-light: #343a40;
    --lb-bg-surface: #212529;
    --lb-bg-white: #2b3035;
    --lb-surface-alt: #272b30;
    --lb-card: #2b3035;
    --lb-elevated: #343a40;
    --lb-sidebar: #1a1d21;
    --lb-sidebar-hover: #2b3035;
    --lb-sidebar-active-bg: rgba(110, 168, 254, 0.12);
    --lb-bg-topbar: #2b3035;
    --lb-bg-dropdown: #2b3035;
    --lb-accent-tint: rgba(110, 168, 254, 0.12);
    --lb-timer-active: #75b798;
    --lb-timer-active-bg: rgba(117, 183, 152, 0.12);
    --lb-active: #6ea8fe;
    --lb-active-bg: rgba(110, 168, 254, 0.10);
    --lb-yellow: #ffda6a;
    --lb-purple: #a98eda;
    --lb-purple-bg: #1a1230;
    --lb-blue: #6ea8fe;
    --lb-blue-bg: #0a1628;
    --lb-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    --lb-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.55);
    --lb-btn-flat-bg: #343a40;
    --lb-btn-flat-border: #495057;
    --lb-btn-flat-text: #dee2e6;
    --lb-btn-flat-hover-bg: #495057;
    --lb-btn-flat-hover-border: #6c757d;
    --lb-btn-flat-hover-text: #f8f9fa;
    --lb-btn-flat-disabled-bg: #212529;
    --lb-btn-flat-disabled-border: #343a40;
    --lb-btn-flat-disabled-text: #6c757d;
    --lb-btn-danger-hover-bg: #2c0b0e;
    --lb-btn-danger-hover-border: #ea868f;
    --lb-nav-pill-hover-bg: #0a1628;
    --lb-nav-pill-hover-text: #6ea8fe;
    --lb-validation-text: #ea868f;
    --lb-focus-ring: 0 0 0 0.1rem #212529, 0 0 0 0.25rem #6ea8fe;

    /* Contact category badges -- bootstrap dark */
    --lb-text-on-brand: #FFFFFF;
    --lb-badge-client: #6ea8fe;
    --lb-badge-client-bg: #0a1628;
    --lb-badge-medical: #75b798;
    --lb-badge-medical-bg: #0a1e13;
    --lb-badge-adjuster: #ffb870;
    --lb-badge-adjuster-bg: #332000;
    --lb-badge-defense: #ea868f;
    --lb-badge-defense-bg: #2c0b0e;
    --lb-badge-expert: #a98eda;
    --lb-badge-expert-bg: #1a1230;
    --lb-badge-staff: #6edff6;
    --lb-badge-staff-bg: #032830;
    --lb-badge-other: #adb5bd;
    --lb-badge-other-bg: #343a40;
}

/* Compose dialog width cap (command-bar redesign): the dialog panel is 74vw
   but never wider than 1200px on ultrawides, and never crushed below 640px.
   Lives here (not ComposeEmailDialog.razor.css) because the CssClass lands on
   the reparented .e-dlg-container and the .e-dialog panel inside carries NO
   scope attribute — no scoped rule can reach it (probe-verified live).
   EnableResize still lets the user resize within these bounds. */
.compose-email-dialog .e-dialog {
    max-width: 1200px;
    min-width: 640px;
}

/* Native checkboxes (Email Inbox row-select: grid .lb-row-check, card
   .card-select) must follow the APP theme, not the OS: without color-scheme,
   an unchecked <input type="checkbox"> paints a glaring white box on the dark
   grid/cards. Lives here (not the scoped .razor.css) because a scoped rule
   cannot carry the :root[data-theme] prefix — the scope attribute would land
   on <html>, which never has it. Scoped to the inbox classes on purpose;
   auditing every raw checkbox app-wide is its own change. */
:root[data-theme="dark"] .lb-row-check,
:root[data-theme="dark"] .card-select {
    color-scheme: dark;
}

/* @media fallback: applies before theme.js runs to prevent FOUC.
   These are the LONGBOW dark values, so the selector must exclude the Bootstrap
   scheme. `:root:not([data-theme="light"])` is specificity (0,2,0) -- the SAME as
   `[data-theme="dark"][data-scheme="bootstrap"]` above -- and it is later in the
   file, so without the added :not() it wins the tie and repaints Bootstrap dark
   mode in Longbow colors on any OS-dark machine. Excluding bootstrap costs nothing:
   data-scheme is only ever set by theme.js, so a document carrying it has already
   run JS and the real scheme block applies. (The [data-theme="dark"] block above is
   (0,1,0) and is outranked by this rule either way -- harmless only because the two
   carry identical values. Keep them in sync.) */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]):not([data-scheme="bootstrap"]) {
        --lb-text: #C8CAD0;
        --lb-text-muted: #7A7E88;
        --lb-text-dim: #4A4E58;
        --lb-text-bright: #E8EAF0;
        --lb-text-on-dark: #C0C4CC;
        --lb-text-on-dark-muted: #6A7080;
        --lb-text-on-dark-dim: #7A7E88;
        --lb-border: #2E3038;
        --lb-border-light: #383A42;
        --lb-bg-surface: #101114;
        --lb-bg-white: #1A1B1F;
        --lb-surface-alt: #151618;
        --lb-card: #1E2024;
        --lb-elevated: #282A30;
        --lb-bg-topbar: #1E2024;
        --lb-bg-dropdown: #1E2024;
        --lb-brand-light: #2D2010;
        --lb-danger: #E05A4A;
        --lb-danger-bg: #2E1210;
        --lb-success: #38B068;
        --lb-success-bg: #0E2818;
        --lb-warning: #D06828;
        --lb-warning-bg: #2E1A0C;
        --lb-info: #5A8FC0;
        --lb-info-bg: #101E2E;
        --lb-info-text: #8FB8E0;
        --lb-info-border: #24425E;
        --lb-warning-text: #E8955A;
        --lb-warning-border: #4E2E14;
        --lb-accent-tint: rgba(212, 137, 12, 0.15);
        --lb-timer-active-bg: rgba(56, 176, 104, 0.15);
        --lb-sidebar: #16171C;
        --lb-sidebar-hover: #24262C;
        --lb-sidebar-active-bg: rgba(212, 137, 12, 0.12);
        --lb-active: #D4890C;
        --lb-active-bg: rgba(212, 137, 12, 0.10);
        --lb-yellow: #D4A020;
        --lb-purple: #8B7AC8;
        --lb-purple-bg: #1A1630;
        --lb-blue: #5A8FC0;
        --lb-blue-bg: #101E2E;
        --lb-shadow: 0 1px 3px rgba(0, 0, 0, 0.30);
        --lb-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.50);
        --lb-btn-flat-bg: #282A30;
        --lb-btn-flat-border: #383A42;
        --lb-btn-flat-text: #C8CAD0;
        --lb-btn-flat-hover-bg: #34363E;
        --lb-btn-flat-hover-border: #484A54;
        --lb-btn-flat-hover-text: #E8EAF0;
        --lb-btn-flat-disabled-bg: #1A1B1F;
        --lb-btn-flat-disabled-border: #2E3038;
        --lb-btn-flat-disabled-text: #4A4E58;
        --lb-btn-danger-hover-bg: #2E1210;
        --lb-btn-danger-hover-border: #E05A4A;
        --lb-nav-pill-hover-bg: #2D2010;
        --lb-nav-pill-hover-text: var(--lb-brand);
        --lb-validation-text: #E05A4A;
        --lb-focus-ring: 0 0 0 0.1rem #101114, 0 0 0 0.25rem #258cfb;

        /* Timeline gridlines -- dark fallback */
        --lb-timeline-grid: #252730;
    }
}

/* ===================================================================
   CANONICAL BREAKPOINTS (reference — CSS cannot use vars in @media)
   sm: 576px  |  md: 768px  |  lg: 992px  |  xl: 1400px
   =================================================================== */

html, body {
    font-family: 'Segoe UI', Helvetica, Arial, sans-serif;
    background-color: var(--lb-bg-surface);
    color: var(--lb-text);
}

/* -------------------------------------------------------------------
   SCROLLBAR STYLING
   -------------------------------------------------------------------
   Ensures scrollbars inside Syncfusion grids, panels, dialogs, and
   all overflow containers match the current theme in both light and
   dark modes. Uses --lb-* tokens so colors adapt automatically.
   scrollbar-color is the modern standard (Firefox); ::-webkit-*
   covers Chrome, Edge, and Safari.
   ------------------------------------------------------------------- */

/* Modern standard (Firefox) */
*,
*::before,
*::after {
    scrollbar-color: var(--lb-border) var(--lb-bg-surface);
    scrollbar-width: thin;
}

/* WebKit (Chrome, Edge, Safari) */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--lb-bg-surface);
}

::-webkit-scrollbar-thumb {
    background: var(--lb-border);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--lb-text-muted);
}

::-webkit-scrollbar-corner {
    background: var(--lb-bg-surface);
}

/* Left-nav rail override: the global rules above paint scrollbars with the
   light surface/border tokens, which show up pale against the always-dark
   navy sidebar in light mode. The sidebar tokens are dark in EVERY theme, so
   pinning the nav scrollbar to them keeps it dark-on-dark in all themes. */
.sidebar,
.lb-nav-body {
    scrollbar-color: var(--lb-sidebar-hover) var(--lb-sidebar);
}

.sidebar::-webkit-scrollbar-track,
.lb-nav-body::-webkit-scrollbar-track {
    background: var(--lb-sidebar);
}

.sidebar::-webkit-scrollbar-thumb,
.lb-nav-body::-webkit-scrollbar-thumb {
    background: var(--lb-sidebar-hover);
}

.sidebar::-webkit-scrollbar-thumb:hover,
.lb-nav-body::-webkit-scrollbar-thumb:hover {
    background: var(--lb-text-on-dark-dim, #55607a);
}

/* Links (non-nav) */
a:not(.nav-link), .btn-link {
    color: var(--lb-brand);
    text-decoration: none;
    transition: color 0.2s;
}

    a:not(.nav-link):hover, a:not(.nav-link):focus {
        color: var(--lb-brand-hover);
    }

    /* Focus visuals (Bootstrap-style) */
    .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
        box-shadow: var(--lb-focus-ring);
    }

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

/* Validation helpers */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid var(--lb-validation-text);
}

.validation-message {
    color: var(--lb-validation-text);
}

/* Blazor error boundary */
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0"idHJyYW5zbGF0ZSgteEZpZEdGTG93M1FIRWh3SldFeElpd3hNVEV4TkRJelkyRTBNakV5T0RrMk1UazBNRFFFUGdvZ1pqYzVRREV6WlhSMlJHRjVjRzl6TVRBd055MHlNekF6SUNJek1UYzNOREU1TVRJek5UZGhOalF6TVRBd0xqSmxZekE1SW4gIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred.";
    }

/* Checkbox tweak */
.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* === Bootstrap alert overrides -- use design tokens for dark/light === */
.alert-warning {
    background-color: var(--lb-warning-bg);
    color: var(--lb-warning);
    border-color: var(--lb-warning);
}

.alert-info {
    background-color: var(--lb-info-bg);
    color: var(--lb-info);
    border-color: var(--lb-info);
}

.alert-danger {
    background-color: var(--lb-danger-bg);
    color: var(--lb-danger);
    border-color: var(--lb-danger);
}

.alert-success {
    background-color: var(--lb-success-bg);
    color: var(--lb-success);
    border-color: var(--lb-success);
}

/* === Button scheme (Bootstrap and Syncfusion) === */
.btn-primary,
.e-btn.e-primary,
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--lb-brand) !important;
    border-color: var(--lb-brand) !important;
    color: #fff !important;
}

    .btn-primary:hover,
    .btn-primary:focus,
    .e-btn.e-primary:hover,
    .e-btn.e-primary:focus,
    .nav-pills .nav-link.active:hover,
    .nav-pills .nav-link.active:focus {
        background-color: var(--lb-brand-hover) !important;
        border-color: var(--lb-brand-hover) !important;
        color: #fff !important;
    }

    /* Base button sizing */
    .btn, .e-btn {
        border-radius: var(--lb-radius-pill);
        font-size: 0.95rem;
        padding: 0.4rem 0.9rem;
        line-height: 1.2;
    }
        /* Secondary (filled) -- token-driven, auto-flips in dark mode */
        .e-btn.e-flat {
            background-color: var(--lb-btn-flat-bg);
            border-color: var(--lb-btn-flat-border);
            color: var(--lb-btn-flat-text);
        }

            .e-btn.e-flat:hover, .e-btn.e-flat:focus {
                background-color: var(--lb-btn-flat-hover-bg);
                border-color: var(--lb-btn-flat-hover-border);
                color: var(--lb-btn-flat-hover-text);
            }
            /* Disabled secondary */
            .e-btn.e-flat:disabled,
            .e-btn.e-flat.e-disabled,
            .e-disabled .e-btn.e-flat {
                background-color: var(--lb-btn-flat-disabled-bg);
                border-color: var(--lb-btn-flat-disabled-border);
                color: var(--lb-btn-flat-disabled-text);
                opacity: 1;
            }
        /* Disabled buttons: keep shape */
        .e-btn:disabled,
        .e-btn.e-disabled,
        .e-disabled .e-btn {
            border-radius: 1.25rem;
            font-size: 0.95rem;
            padding: 0.4rem 0.9rem;
            line-height: 1.2;
        }

            .e-btn.e-primary:disabled,
            .e-btn.e-primary.e-disabled,
            .e-disabled .e-btn.e-primary {
                background-color: var(--lb-brand);
                border-color: var(--lb-brand);
                color: #fff;
                opacity: 0.65;
            }
        /* Destructive filled */
        .e-control.e-btn.e-danger {
            background-color: var(--lb-danger) !important;
            border-color: var(--lb-danger) !important;
            color: #fff !important;
        }

            .e-control.e-btn.e-danger:hover,
            .e-control.e-btn.e-danger:focus {
                background-color: var(--lb-btn-danger-hover-border) !important;
                border-color: var(--lb-btn-danger-hover-border) !important;
                color: #fff !important;
            }

/* === Nav pills (inactive) === */
.nav-pills .nav-link {
    color: var(--lb-brand);
    background-color: var(--lb-brand-light);
    border-radius: 1.25rem;
    font-size: 1.05rem;
    padding: 0.45rem 0.9rem;
    transition: background 0.2s, color 0.2s, box-shadow 0.2s;
}

    .nav-pills .nav-link:not(.active):hover,
    .nav-pills .nav-link:not(.active):focus {
        background-color: var(--lb-nav-pill-hover-bg);
        color: var(--lb-nav-pill-hover-text);
    }

    /* === Spinner overlay === */
.e-spinner-pane,
.e-spinner-pane.e-spin-show,
.e-spinner-pane.e-spin-overlay,
.e-spin-overlay .e-spinner-pane,
.e-spin-overlay.e-spinner-pane {
    background-color: color-mix(in srgb, var(--lb-bg-surface) 85%, transparent) !important;
}

/* === Dashboard layout tweaks === */

/* Let dashboard height be natural to content (prevents big empty space after last row) */
.dashboard-root {
    height: auto;
    min-height: 0;
    margin-top: 24px;
    margin-bottom: 24px;
    box-sizing: border-box;
    overflow: visible;
}

/* DO NOT force the dashboard to 100% height; allow it to size to content */
.e-dashboardlayout {
    height: auto;
}

    .e-dashboardlayout .e-dashboard-grid {
        height: auto;
    }
    /* Remove internal white space in panels */
    .e-dashboardlayout .e-panel {
        margin: 0;
    }

        .e-dashboardlayout .e-panel .e-panel-content {
            padding: 0;
        }
    /* Flex-fill panel content under header; tighten header */
    .e-dashboardlayout.e-control .e-panel .e-panel-container {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

        .e-dashboardlayout.e-control .e-panel .e-panel-container .e-panel-header {
            padding: 4px 8px;
            min-height: 28px;
            box-sizing: border-box;
            flex: 0 0 auto;
        }

        .e-dashboardlayout.e-control .e-panel .e-panel-container .e-panel-content,
        .panel-content {
            flex: 1 1 auto;
            min-height: 0;
            overflow: auto;
        }

    /* Trim grid chrome (if any grids are used elsewhere) */
.e-grid .e-headercontent {
    min-height: 40px;
}

.e-grid .e-pager {
    min-height: 40px;
}

/* Global alternating row colors -- use tokens so dark mode works. */
.e-grid .e-altrow {
    background-color: var(--lb-bg-surface);
}

.e-grid .e-row:not(.e-altrow) {
    background-color: var(--lb-bg-white);
}

/* Global: change the filter icon tooltip from "Filter Icon" to "Filter Rows".
   Syncfusion renders the tooltip via a title attribute on .e-filtermenudiv;
   CSS hides the native title and we inject the replacement text via
   the aria-label attribute set on the rendered button. */
.e-grid .e-icon-filter::after {
    content: '';
}

/* Grid filter/excel-filter dialog buttons: reset the global pill sizing so
   buttons inside the checkbox-filter popup stay compact and rectangular. */
.e-checkboxfilter .e-btn,
.e-flmenu-footer .e-btn,
.e-excelfilter .e-btn,
.e-filterdiv .e-btn,
.e-filter-popup .e-footer-content .e-btn {
    border-radius: 4px;
    font-size: 0.75rem;
    padding: 0.25rem 0.6rem;
    line-height: 1.3;
    min-height: 0;
}

.e-checkboxfilter .e-btn.e-primary,
.e-flmenu-footer .e-btn.e-primary,
.e-excelfilter .e-btn.e-primary,
.e-filterdiv .e-btn.e-primary,
.e-filter-popup .e-footer-content .e-btn.e-primary {
    border-radius: 4px;
}

/* Lay out the checkbox-filter footer as a clean flex row so the primary OK
   button sits beside Cancel at the trailing edge instead of being crammed
   into the corner and overlapping the search clear/reset icon (issue #335).
   Resizing the buttons alone (block above) did not fix the overlap; the
   footer needs an explicit flex layout. */
.e-checkboxfilter .e-footer-content,
.e-filter-popup .e-footer-content,
.e-flmenu-footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    padding: 8px;
    box-sizing: border-box;
    width: 100%;
}

.e-checkboxfilter .e-footer-content .e-btn,
.e-filter-popup .e-footer-content .e-btn,
.e-flmenu-footer .e-btn {
    margin: 0;
    float: none;
    min-height: 28px;
}

/* Grid filter search input: keep compact */
.e-checkboxfilter .e-input-group,
.e-flmenu .e-input-group {
    font-size: 0.8rem;
}

/* Constrain the filter-popup PARENT width (issue #990). The checkbox/menu/
   excel filter dialogs carry a min-width (250-260px) but no max-width, so on
   a wide grid the popup stretches toward the grid/column width; the
   width:100% footer above then pushes the OK button + funnel icon out to a
   clipped right edge. The prior fixes (#335 -- 06d451b3, c43cf33d) only laid
   the footer out as a flex row and never capped the parent, which is why the
   overlap came back as #990. Capping the dialog parents makes them size to
   their content (~column width). These classes are used only by grid filter
   popups, so the scope stays tight. :not(.e-checkbox-dialog-wrapper) leaves
   the adaptive (mobile, near-full-screen) checkbox filter untouched. The
   reset block below additionally exempts the adaptive (EnableAdaptiveUI)
   responsive-dialog variant -- see #990 regression note there. */
.e-checkboxfilter:not(.e-checkbox-dialog-wrapper),
.e-filter-popup,
.e-flmenu,
.e-excelfilter {
    max-width: 320px;
}

/* #990 regression fix. When a grid has EnableAdaptiveUI="true" (e.g. Quick
   Parts), the SAME checkbox/menu/excel filter content renders NESTED inside a
   slide-in .e-responsive-dialog, where Syncfusion sizes it to width:100% of the
   dialog (theme: .e-responsive-dialog .e-mainfilterdiv .e-dialog { width:100% }).
   The caps above still match that nested content -- the :not(.e-checkbox-dialog-
   wrapper) guard only excludes the *other* adaptive variant, not this one -- so
   the content was capped at 320px, collapsing the dialog to ~content width and
   clipping its header's OK + funnel/clear controls. Release the cap for filter
   content inside the responsive dialog so it fills the dialog as intended. The
   desktop, non-adaptive popups above stay capped. */
.e-responsive-dialog .e-checkboxfilter,
.e-responsive-dialog .e-filter-popup,
.e-responsive-dialog .e-flmenu,
.e-responsive-dialog .e-excelfilter {
    max-width: none;
}

/* The responsive dialog header carries the column name plus the confirm (OK)
   and funnel/clear controls in a flex row (theme: .e-res-custom-element). Let
   the column-name title shrink instead of pushing those controls past the edge,
   so OK + funnel stay fully visible at any width (#990). */
.e-responsive-dialog .e-dlg-header-content .e-res-custom-element {
    min-width: 0;
}
.e-responsive-dialog .e-dlg-header-content .e-dlg-custom-header {
    min-width: 0;
    flex: 1 1 auto;
}
.e-responsive-dialog .e-dlg-header-content .e-res-filter-clear-btn,
.e-responsive-dialog .e-dlg-header-content .e-res-apply-btn {
    flex: 0 0 auto;
}

/* Adaptive (phone) grid sort/filter renders as .e-responsive-dialog. Its footer
   (Clear / OK) inherits no spacing or width bound, so on a phone the right-
   aligned pair was cramped and clipped at the edge. Space the footer buttons and
   keep the dialog within the viewport. */
.e-responsive-dialog .e-footer-content {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    box-sizing: border-box;
    width: 100%;
}

@media (max-width: 767.98px) {
    .e-responsive-dialog {
        max-width: 100vw;
    }
}

/* The adaptive SORT responsive dialog (e.g. the calendar agenda grid, whose only
   sortable column is the hidden Date group) puts its Clear / OK buttons in the
   HEADER -- but, unlike the filter dialog handled above, they use the grid's
   default button classes, not the .e-res-apply-btn / .e-res-filter-clear-btn the
   #990 rules target. So they inherited no width, spacing, or radius cap and
   collapsed into cramped, overlapping pill/circle buttons at the top-right on a
   phone. Lay the header out as a spaced row and give its action buttons (not the
   close icon, not the filter funnel handled above) real text-button width and a
   normal radius so both labels read clearly and never overlap. */
.e-responsive-dialog .e-dlg-header-content {
    column-gap: 8px;
}

.e-responsive-dialog .e-dlg-header-content .e-btn:not(.e-dlg-closeicon-btn):not(.e-res-filter-clear-btn) {
    width: auto;
    min-width: 56px;
    height: auto;
    padding: 4px 14px;
    border-radius: 4px;
    white-space: nowrap;
    flex: 0 0 auto;
}

/* The Excel "custom filter" sub-dialog renders as its own body-level popup
   with two AND/OR condition rows (two ~141px radio groups), so it needs a
   little more room than the simple filters above -- cap it separately so it
   still cannot stretch to full grid width but its two rows are not cramped. */
.e-xlflmenu {
    max-width: 380px;
}

/* #988 — caption the DocumentEditorContainer's built-in properties-pane toggle.
   It is the far-right icon-only button (glyph e-de-ctnr-showhide) and is the
   ONLY reliable way to show/hide the right-hand Text formatting pane: it keeps
   working after the pane switches context for a header/footer/table/TOC, where
   Syncfusion auto-hides the Text pane. Syncfusion 33.2.12 exposes NO
   ShowPropertiesPaneChanged callback and NO runtime toggle method, so a custom
   Blazor toolbar item cannot drive the pane (that was the dead duplicate from
   51c73a37 that this fix removes) -- labeling the working built-in button is the
   reliable fix. Scoped .razor.css cannot reach the container's toolbar
   internals, so this must live in global app.css. The button is a flex item in
   .e-de-ctnr-toolbar (theme width:75px). #988 recurred: laid out inline, the
   caption sat to the RIGHT of the icon and clipped to "Text Pr…" inside the
   fixed-width item. Stack it BELOW the icon (flex column) and let the item size
   to content without clipping, so the full "Text Properties" label is readable. */
.e-de-ctnr-properties-pane-btn {
    width: max-content;
    flex-shrink: 0;
    overflow: visible;
}

.e-de-ctnr-properties-pane-btn .e-btn {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: max-content;
    padding-inline: 12px;
    height: auto;
    line-height: 1;
    /* removed: white-space: nowrap;  (was forcing icon+caption onto one line) */
}

.e-de-ctnr-properties-pane-btn .e-btn::after {
    content: "Text Properties";
    display: block;          /* own line, under the icon */
    width: 100%;
    text-align: center;
    white-space: nowrap;     /* keep the caption itself on one line */
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.1;
}

/* #988 (5th pass) — the caption rules above are necessary but were NOT enough.
   Verified in devtools on a running editor: the ::after already computes
   display:block and the 99px button already fits the ~75px label, so the label
   was never clipped by the BUTTON. The real clip is the toolbar's flex layout.
   .e-de-ctnr-toolbar is a flex row of two children: the scrollable button strip
   (.e-de-tlbr-wrapper) and this pinned properties-pane button (flex-shrink:0).
   The strip kept the flexbox default min-width:auto, which forbids shrinking
   below its own content width, so it stayed full-width and pushed the pinned
   button ~24px past the editor's right edge (.wp-editor, overflow:hidden) -- the
   label clipped to "Text Propert...". Letting the strip shrink lets the pinned
   button keep its full width; the strip's own e-hscroll arrows still handle the
   overflow, so no toolbar buttons are stranded. Measured: button right edge
   1113px -> 1090px (inside the 1090px toolbar edge); scroll arrows still present;
   holds at any toolbar width. This was the piece prior attempts (#1019/#1195/
   #1418/#1483) all missed -- they restyled the caption, never the strip. */
.e-de-ctnr-toolbar > .e-de-tlbr-wrapper {
    min-width: 0;
}

/* ===================================================================
   DOCUMENT TYPE ICON -- dark mode overrides (global scope required;
   Blazor CSS isolation would block :global() in the component CSS)
   =================================================================== */
[data-theme="dark"] .doc-type-icon {
    background: transparent !important;
    border: 1px solid currentColor;
    opacity: 0.75;
}

[data-theme="dark"] .doc-type-pdf    { color: #d97070; }
[data-theme="dark"] .doc-type-word   { color: #6898d8; }
[data-theme="dark"] .doc-type-excel  { color: #70b855; }
[data-theme="dark"] .doc-type-ppt    { color: #d8835a; }
[data-theme="dark"] .doc-type-image  { color: #c87898; }
[data-theme="dark"] .doc-type-video  { color: #9878d8; }
[data-theme="dark"] .doc-type-audio  { color: #58a8d8; }
[data-theme="dark"] .doc-type-text   { color: #909090; }
[data-theme="dark"] .doc-type-archive { color: #c8a85a; }
[data-theme="dark"] .doc-type-email  { color: #7898d8; }
[data-theme="dark"] .doc-type-default { color: #808080; }

/* ===================================================================
   STATUS PILL -- dark mode overrides (global scope required)
   =================================================================== */
[data-theme="dark"] .status-pill-green {
    background: transparent;
    color: #70b890;
    border-color: #3e6e50;
}

[data-theme="dark"] .status-pill-amber {
    background: transparent;
    color: #b88a40;
    border-color: #6e5020;
}

[data-theme="dark"] .status-pill-blue {
    background: transparent;
    color: #6888a8;
    border-color: #384e68;
}

[data-theme="dark"] .status-pill-gray {
    background: transparent;
    color: #686868;
    border-color: #404040;
}

/* ===================================================================
   SIGNATURE STATUS PILL -- e-signature lifecycle badges (global scope
   so they render correctly inside Syncfusion grid templates, which
   strip Blazor's scoped-CSS attribute).
   =================================================================== */
.sig-status-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    border: 1px solid transparent;
}

.sig-status-completed   { background: #d4edda; color: #155724; }
.sig-status-sent        { background: #cce5ff; color: #004085; }
.sig-status-sending     { background: #fff3cd; color: #856404; }
.sig-status-partial     { background: #d1ecf1; color: #0c5460; }
.sig-status-declined    { background: #f8d7da; color: #721c24; }
.sig-status-expired,
.sig-status-revoked,
.sig-status-dismissed,
.sig-status-draft       { background: #e2e3e5; color: #383d41; }

/* S3-12: Prepend text icons for WCAG — not color-only differentiation */
.sig-status-completed::before   { content: "\2713 "; /* ✓ */ }
.sig-status-sent::before        { content: "\2192 "; /* → */ }
.sig-status-sending::before     { content: "\2022 "; /* • */ }
.sig-status-partial::before     { content: "\00BD "; /* ½ */ }
.sig-status-declined::before    { content: "\2717 "; /* ✗ */ }
.sig-status-expired::before     { content: "\29D6 "; /* ⧖ */ }
.sig-status-revoked::before     { content: "\2298 "; /* ⊘ */ }
.sig-status-dismissed::before   { content: "\2014 "; /* — */ }
.sig-status-draft::before       { content: "\270E "; /* ✎ */ }

/* Dark mode: transparent backgrounds with colored text + subtle border,
   matching the look of the existing .status-pill-* convention above. */
[data-theme="dark"] .sig-status-completed {
    background: transparent; color: #70b890; border-color: #3e6e50;
}
[data-theme="dark"] .sig-status-sent {
    background: transparent; color: #6888a8; border-color: #384e68;
}
[data-theme="dark"] .sig-status-sending {
    background: transparent; color: #b88a40; border-color: #6e5020;
}
[data-theme="dark"] .sig-status-partial {
    background: transparent; color: #4a9aa8; border-color: #2d5e68;
}
[data-theme="dark"] .sig-status-declined {
    background: transparent; color: #c0625a; border-color: #6e3a35;
}
[data-theme="dark"] .sig-status-expired,
[data-theme="dark"] .sig-status-revoked,
[data-theme="dark"] .sig-status-dismissed,
[data-theme="dark"] .sig-status-draft {
    background: transparent; color: #888; border-color: #404040;
}

/* Global: grids using EnableAdaptiveUI handle mobile layout natively.
   Non-adaptive grids still get horizontal scroll as a fallback. */
@media (max-width: 768px) {
    .e-grid:not(.e-grid-min-height) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        /* Without containment, a sideways swipe here chains to the browser's edge
           swipe-back and exits the page (mobile bug class; see .docs-filter-chips).
           No touch-action -- Syncfusion owns gesture handling on these controls. */
        overscroll-behavior-x: contain;
    }
}

/* === Overview bar === */
.overview-bar {
    margin-bottom: 12px;
}

.kpi-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

.kpi-card {
    background: var(--lb-bg-surface);
    border: 1px solid var(--lb-border);
    border-radius: 8px;
    padding: 8px 10px;
}

.kpi-title {
    font-size: 0.85rem;
    color: var(--lb-text-muted);
}

.kpi-value {
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--lb-text);
}

/* === Compact lists and pager === */
.compact-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

    .compact-list li {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 3px 8px;
        border-bottom: 1px solid var(--lb-border);
    }

    .compact-list .list-title {
        font-weight: 600;
        margin-right: 6px;
    }

    .compact-list .list-sub {
        color: var(--lb-text-muted);
        font-size: 0.8rem;
    }

    /* Pager footer, minimal padding */
.panel-footer.pager {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
}

.panel-footer .pager-info {
    color: var(--lb-text-muted);
    font-size: 0.8rem;
}

.panel-footer .right-link {
    margin-left: auto;
}

/* Small buttons for compact UI */
.e-btn.e-small {
    font-size: 0.75rem;
    padding: 0.16rem 0.42rem;
    border-radius: 0.8rem;
}

/* Auto-height dashboard grid (replaces fixed-cell dashboard layout) */
.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}

/* Cards auto-size to their content */
.dash-card {
    background: var(--lb-bg-white);
    border: 1px solid var(--lb-border);
    border-radius: 8px;
    box-shadow: var(--lb-shadow);
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
}

/* Card section titles. #2883 made these real <h2>s so screen-reader heading
   navigation can reach them; inherit/0 cancel the heading's UA + Bootstrap
   font-size and margins so the card looks exactly as it did as a <header>. */
.dash-header {
    padding: 6px 10px;
    font-size: inherit;
    font-weight: 600;
    line-height: inherit;
    margin: 0;
    border-bottom: 1px solid var(--lb-border);
}

.dash-body {
    padding: 0; /* lists are already compact */
}

/* Make specific items span both columns when needed */
.span-2 {
    grid-column: 1 / -1;
}

/* Optional: responsive columns */
@media (max-width: 992px) {
    .dashboard-grid {
        grid-template-columns: 1fr;
    }
}

.dashboard-root .compact-list .list-title {
    font-weight: 400 !important;
    color: var(--lb-text) !important;
    font-size: 0.8rem !important;
}

.dashboard-root .compact-list .list-sub {
    color: var(--lb-text-muted) !important;
    font-size: 0.8rem !important;
}

/* Interactive rows for dashboard lists */
.dashboard-root .compact-list li {
    cursor: pointer; /* indicates interactivity */
    transition: background 0.15s;
}

    .dashboard-root .compact-list li:hover {
        background: var(--lb-bg-surface); /* subtle hover */
    }

    .dashboard-root .compact-list li:active {
        background: var(--lb-accent-tint); /* press feedback */
    }
    /* Keyboard accessibility: allow tabbing and focus ring */
    .dashboard-root .compact-list li:focus {
        outline: 2px solid #258cfb; /* matches global focus scheme */
        outline-offset: -2px;
    }

/* === Sidebar nav baseline indent for top-level items === */
.sidebar .nav.flex-column > .nav-item > .nav-link,
.sidebar .nav.flex-column > .nav-item > .settings-toggle {
    padding-left: 24px !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* Keep submenu indentation (these classes live inside NavMenu) */
.sidebar .submenu {
    padding-left: 24px; /* maintain relative indent to parents */
}

.sidebar .submenu-link {
    padding-left: 30px; /* keeps submenu deeper than parents */
    text-align: left;
}

/* Visual spacer so plain links align with submenu headers (if icons are used) */
.sidebar .nav.flex-column > .nav-item > .nav-link:not(.settings-toggle)::before {
    content: "";
    display: inline-block;
    width: 16px;
    height: 1px;
    margin-right: 6px;
}

/* === Sidebar nav: type scale (headers larger, submenu smaller) === */
.nav-scrollable > .flex-column > .nav-item > .nav-link,
.sidebar .nav.flex-column > .nav-item .settings-toggle {
    font-size: 1.30rem !important;
    line-height: 1.4 !important;
}

.submenu-link {
    font-size: 1.00rem !important; /* smaller submenu items */
    line-height: 1.35 !important;
}

/* Grid styling within dashboard cards */
.dashboard-root .dash-body .e-grid {
    border: none;
    border-radius: 0;
}

    .dashboard-root .dash-body .e-grid .e-gridheader {
        border-bottom: 1px solid var(--lb-border);
    }

    .dashboard-root .dash-body .e-grid .e-gridcontent {
        overflow-y: auto;
    }

    /* Dashboard grids: force desktop column visibility (override Syncfusion e-device/e-responsive) */
@media (min-width: 901px) {
    .dashboard-root .e-grid colgroup col {
        display: table-column !important;
    }

    .dashboard-root .e-grid .e-headercell.e-hide,
    .dashboard-root .e-grid .e-rowcell.e-hide {
        display: table-cell !important;
    }

    .dashboard-root .e-pager .e-mfirst,
    .dashboard-root .e-pager .e-mprev,
    .dashboard-root .e-pager .e-mnext,
    .dashboard-root .e-pager .e-mlast {
        display: none !important;
    }

    .dashboard-root .e-pager .e-pagercontainer {
        display: flex !important;
    }
}

/* Dashboard grids: hide columns on small viewports via pure CSS (bypasses Syncfusion HideAtMedia) */
@media (max-width: 900px) {
    .dash-col-md {
        display: none !important;
    }
}

@media (max-width: 768px) {
    .dash-col-sm {
        display: none !important;
    }
}

/* Keep consistent card spacing */
.dashboard-root .dash-card .dash-body {
    padding: 0;
    overflow: hidden;
}

/* Dashboard cards: fixed height on desktop, auto on mobile */
.dashboard-root .dash-card .dash-grid-body {
    height: 420px;
    overflow: hidden;
}

@media (max-width: 992px) {
    .dashboard-root .dash-card .dash-grid-body {
        height: auto;
        max-height: 500px;
        overflow-y: auto;
    }
}

/* ===================================================================
   RESPONSIVE / MOBILE SUPPORT
   =================================================================== */

/* --- Touch-friendly minimum sizing (applies everywhere) --- */
@media (pointer: coarse) {
    /* Minimum tap-target size per WCAG / Apple HIG (44px) */
    .nav-item ::deep .nav-link,
    .settings-toggle,
    .submenu-link,
    .e-toolbar .e-toolbar-item .e-btn,
    .e-btn,
    .btn {
        min-height: 44px;
    }

    /* Larger form controls on touch devices */
    .e-input-group,
    .e-ddl,
    .e-input,
    .e-numerictextbox,
    .e-datepicker {
        min-height: 44px;
        font-size: 1rem !important;
    }
}

/* --- Syncfusion grids: horizontal scroll only on non-dashboard grids --- */
.e-grid:not(.e-responsive) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* --- Syncfusion grids: soften the cell focus indicator --- */
/* Default theme draws a thick blue rectangle on the focused cell;
   replace with a subtle 1px gray border that works in both modes. */
.e-grid td.e-focused,
.e-grid th.e-focused {
    box-shadow: none;
    outline: none;
}

.e-grid td.e-focused::after {
    border: 1px solid var(--lb-border, rgba(128, 128, 128, 0.35));
}

/* --- Syncfusion Toolbar: allow wrapping instead of overflow --- */
@media (max-width: 767px) {
    .e-toolbar .e-toolbar-items {
        flex-wrap: wrap;
    }

    .e-toolbar .e-toolbar-item {
        flex-shrink: 1;
    }

    /* Reduce toolbar text size on small screens */
    .e-toolbar .e-tbar-btn-text {
        font-size: 0.8rem;
    }
}

/* --- Dashboard: single-column earlier on small screens --- */
@media (max-width: 767px) {
    .dashboard-grid {
        grid-template-columns: 1fr;
    }

    .kpi-row {
        grid-template-columns: 1fr;
    }

    .dashboard-root {
        margin-top: 12px;
        margin-bottom: 12px;
    }
}

/* === Dialog responsive caps =====================================
 * Constrain Syncfusion dialogs at narrower viewports so their inline
 * Width / Height attributes do not push beyond the viewport edges.
 *
 * Tokens defined in :root under "Layout dimensions" (chunk 3):
 *   --lb-dialog-max-width-phone  : 95vw
 *   --lb-dialog-max-height-phone : 90vh
 *
 * Specificity comes from `body .e-dialog` (0,1,1) -- higher than the
 * Syncfusion theme's `.e-dialog` (0,1,0) -- so we do not need
 * !important. The previous rules at this location used !important
 * which violates the project rule "Never use !important -- increase
 * specificity with extra selectors."
 *
 * Behavior by tier:
 *   Phone (<768px) :   force width AND max-width to the cap so even
 *                      small dialogs use the available reading area
 *                      (a 200px dialog on a 390px phone would look
 *                      lonely floating in the middle of the viewport).
 *   Tablet (768-1199): cap with max-width only -- small dialogs keep
 *                      their natural design width, oversized dialogs
 *                      are pulled in.
 *   Desktop (>=1200) : no cap; dialogs render at their declared size.
 *
 * The .e-dlg-content scroll rules ensure tall dialogs scroll inside
 * the capped height instead of overflowing the viewport.
 */
@media (max-width: 767.98px) {
    body .e-dialog {
        width: var(--lb-dialog-max-width-phone);
        max-width: var(--lb-dialog-max-width-phone);
        max-height: var(--lb-dialog-max-height-phone);
        min-width: 0;
    }

    body .e-dialog .e-dlg-content {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}

@media (min-width: 768px) and (max-width: 1199.98px) {
    body .e-dialog {
        max-width: var(--lb-dialog-max-width-phone);
        max-height: var(--lb-dialog-max-height-phone);
        min-width: 0;
    }

    body .e-dialog .e-dlg-content {
        overflow-y: auto;
    }
}

/* Re-skin the RTE "Background Color" tool as a Highlighter (#708, #991).
   The single glyph-bearing element is the split button's main face --
   `.e-rte-background-colorpicker .e-split-colorpicker.e-background-color::before`
   -- the exact element the bootstrap5 theme paints with the paint-bucket
   (\e783). The #708 regression used the bare `.e-background-color::before`,
   which ALSO matched the split-dropdown caret and the colour-picker sub-
   elements, spraying stray glyphs (reverted in 74b92072). Targeting the
   split-colorpicker face only -- mirroring the theme's own selector -- fixes
   that. \e739 is the e-icons "highlight-color" marker glyph (.e-icons
   .e-highlight-color), confirmed present in the shipped e-icons font. Scoped
   to .compose-email-dialog and given higher specificity than the theme rule so
   it wins without !important. */
body .e-dialog.compose-email-dialog .e-rte-toolbar .e-rte-background-colorpicker .e-split-colorpicker.e-background-color::before {
    content: "\e739";
}

/* The FontColor "A" and the Highlight tool sit adjacent with no separator
   between them and read as one blob (#991). Give the Highlight toolbar item
   breathing room from the FontColor item to its left. */
body .e-dialog.compose-email-dialog .e-rte-toolbar .e-rte-background-colorpicker {
    margin-inline-start: 6px;
}

/* Compose email goes edge-to-edge full-screen on phones (its inline
   Width/Height become 100vw/100% via tier), so the generic 95vw / 90vh caps
   above must be lifted for it. Higher specificity (.compose-email-dialog) wins
   without !important -- the body editor gets maximum room and the dialog cannot
   sit awkwardly off-center on a narrow screen. */
@media (max-width: 767.98px) {
    body .e-dialog.compose-email-dialog {
        max-width: 100vw;
        max-height: 100vh;
        border-radius: 0;
    }
}

/* === Phone bottom-sheet (lb-sheet-phone) -- opt-in dialog utility ====
 * Add CssClass="lb-sheet-phone" to an SfDialog so that on phones it docks
 * to the bottom edge as a full-width sheet with a rounded top, instead of
 * floating centered. Used by the heavier editor dialogs (NewCase, TaskEdit,
 * CalendarItem) where a thumb-reachable, full-width sheet reads as native.
 * Tablet/desktop are unaffected. CssClass lands on .e-dialog, so the bottom
 * docking reaches the modal's flex container (.e-dlg-container) via :has().
 * Specificity `body .e-dialog.lb-sheet-phone` (0,2,1) outranks the generic
 * `body .e-dialog` (0,1,1) phone cap above without !important. */
@media (max-width: 767.98px) {
    .e-dlg-container:has(.e-dialog.lb-sheet-phone) {
        align-items: flex-end;
    }

    body .e-dialog.lb-sheet-phone {
        width: 100vw;
        max-width: 100vw;
        max-height: 90vh;
        margin: 0;
        border-radius: 16px 16px 0 0;
        overflow: hidden;
    }

    body .e-dialog.lb-sheet-phone .e-dlg-content {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* --- Syncfusion Tab: scrollable headers on narrow screens --- */
@media (max-width: 767px) {
    .e-tab .e-tab-header {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }

    .e-tab .e-tab-header .e-toolbar-items {
        flex-wrap: nowrap;
    }
}

/* --- General content padding reduction on phones --- */
@media (max-width: 767px) {
    .content {
        padding-top: 0.5rem;
    }

    .px-4 {
        padding-left: 0.75rem !important;
        padding-right: 0.75rem !important;
    }
}

/* --- Global mobile/tablet compatibility hardening --- */
html,
body {
    max-width: 100%;
    /* overflow-x: clip (not hidden) -- both prevent horizontal scroll, but
       `hidden` forces the visible y-axis to compute as `auto`, turning <body>
       into a scroll container, which silently breaks `position: sticky` on
       descendants. That killed the desktop sidebar's sticky (it has
       sticky/top:0/100vh) so the nav would not follow the scroll on tall
       pages (issue #997). `clip` clips the same overflow WITHOUT establishing
       a scroll container, so sticky engages. Keep this as `clip`. */
    overflow-x: clip;
}

/* Rendered content (email bodies, chat, previews) can carry images/videos
   wider than a phone viewport, forcing whole-page horizontal scroll. Global
   guard per the mobile-readiness plan (2026-06-10 QA audit item). height:auto
   keeps the aspect ratio when max-width bites (a fixed height attribute would
   otherwise distort). */
img, video {
    max-width: 100%;
    height: auto;
}

@media (max-width: 992px) {
    /* Note: the .e-dialog and .e-dlg-content rules that used to live here
     * have been consolidated into the dedicated "Dialog responsive caps"
     * block above (using tokens, no !important, breakpoints aligned with
     * the chunk-6 tier model). The remaining rules below are tab and
     * kanban scroll-overflow handling, which are not in scope for the
     * dialog work and intentionally retain their 992px breakpoint. */

    .e-tab .e-tab-header {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }

    .e-tab .e-tab-header .e-toolbar-items {
        flex-wrap: nowrap;
    }

    .e-tab .e-tab-header .e-toolbar-item {
        flex: 0 0 auto;
    }

    .e-kanban .e-kanban-content {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }

    .e-kanban .e-card {
        min-height: 44px;
    }
}

@media (max-width: 768px) {
    body,
    .e-control,
    .e-input,
    .e-input-group input,
    .e-input-group textarea,
    .e-tab .e-tab-header .e-tab-text {
        font-size: 14px;
    }
}

@media (max-width: 576px) {
    .e-btn,
    .btn,
    button,
    a.e-btn,
    .e-tab .e-tab-header .e-toolbar-item {
        min-height: 44px;
        min-width: 44px;
    }
}

/* === Required field indicator === */
.required-indicator {
    color: var(--lb-danger);
    font-weight: 600;
    margin-left: 2px;
}

/* === Documents grid: name cell ===================================
   These rules style the Document Name cell template inside the SfGrid
   on CaseDocumentsPage. They live here in global CSS (not in the
   page's .razor.css) because Blazor scoped CSS adds a [b-xxxx] attribute
   to elements rendered directly in the component, but Syncfusion's grid
   re-renders cell template content during virtual row updates and the
   scope attribute is unreliable on those re-renders. Global rules apply
   unconditionally. */
.docs-name-cell {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    flex-wrap: wrap;
}

.docs-name-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    /* Explicit text color so the name reads on both light and dark themes;
       inheriting from the grid cell can pick up Syncfusion's dim cell color. */
    color: var(--lb-text) !important;
    /* Claim flex-grow so the name fills the leftover space between the icon
       and the meta spans -- without this, min-width:0 + flex-shrink:1 can
       collapse the element to zero width and hide the name entirely. */
    flex: 1 1 auto;
}

.docs-name-link {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    color: var(--lb-brand) !important;
    text-decoration: none;
    cursor: pointer;
    flex: 1 1 auto;
    display: inline-block;
    /* Syncfusion's grid theme sets line-height: 0 on cells in its modern
       SCSS, which vertically collapses anchor content to zero height so
       the text renders but is invisible. Force a real line-height. */
    line-height: 1.4 !important;
    visibility: visible !important;
    opacity: 1 !important;
    -webkit-text-fill-color: var(--lb-brand) !important;
}

.docs-name-link:hover {
    text-decoration: underline;
    color: var(--lb-brand-hover) !important;
    -webkit-text-fill-color: var(--lb-brand-hover) !important;
}

/* Same line-height fix for the non-link variant (used when the file type
   has no in-browser editor route). */
.docs-name-text {
    line-height: 1.4 !important;
}

/* Hyper-specific overrides scoped to Syncfusion's grid row cell so we win
   on cascade against any e-grid theme anchor / cell rule. */
.e-grid .e-rowcell .docs-name-link,
.e-grid .e-gridcontent .docs-name-link,
.e-grid td.e-rowcell .docs-name-cell .docs-name-link {
    color: var(--lb-brand) !important;
    -webkit-text-fill-color: var(--lb-brand) !important;
    text-decoration: none;
    cursor: pointer;
    visibility: visible !important;
    opacity: 1 !important;
    line-height: 1.4 !important;
}

.e-grid .e-rowcell .docs-name-link:hover,
.e-grid .e-gridcontent .docs-name-link:hover {
    color: var(--lb-brand-hover) !important;
    -webkit-text-fill-color: var(--lb-brand-hover) !important;
    text-decoration: underline;
}

/* The docs-name-cell container needs a real line-height too so the cell
   itself reserves vertical room for the text (the wrapper line-height
   propagates down to the icon and meta spans). */
.e-grid .e-rowcell .docs-name-cell {
    line-height: 1.4 !important;
}

/* Documents imported without a Name field fall back to a synthesized label
   (DocumentType + Subtype, or "Untitled #<id>"). Render those in muted /
   italic styling so users can tell at a glance that the document still
   needs a proper title. */
.docs-name-link--untitled,
.docs-name-text--untitled {
    font-style: italic;
    color: var(--lb-text-muted) !important;
    text-transform: capitalize;
}

.docs-name-meta {
    font-size: 11px;
    color: var(--lb-text-muted);
    white-space: nowrap;
    flex-shrink: 0;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    opacity: 0.7;
}

/* On phone, allow the doc-name-link/text to break across lines so long file
   names don't ellipsize the whole cell. */
@media (max-width: 768px) {
    .docs-name-link,
    .docs-name-text {
        white-space: normal;
        word-break: break-word;
        overflow-wrap: anywhere;
        flex-basis: 100%;
    }
}

/* ===================================================================
   SHARED COMPONENT CLASSES
   (Used across multiple .razor files — centralised here)
   =================================================================== */

/* --- Dropdown template items (contact picker pattern) --- */
.dd-template-item {
    margin: 5px;
}

.dd-template-company {
    font-style: italic;
    font-weight: 400;
}

/* --- ValueTemplate text inside SfDropDownList input box ---
   Syncfusion replaces normal input text with custom HTML when a
   ValueTemplate is used. Without explicit styling the content renders
   with the browser default font and collapses into the top-left corner.
   These rules match the standard Syncfusion e-input appearance. --- */
.e-ddl .dd-value-text {
    font-family: inherit;
    font-size: 14px;
    font-weight: 400;
    line-height: 36px;
    padding: 0 12px;
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--lb-text, #333);
}

/* --- Form labels inside SfDataForm custom templates --- */
.custom-label {
    font-weight: normal;
    color: var(--lb-text);
}

/* --- Syncfusion tab header overrides (used on many pages) --- */
.e-tab .e-tab-header .e-toolbar-item .e-tab-text {
    color: var(--lb-text-muted) !important;
    font-weight: bold !important;
}

.e-tab .e-tab-header .e-toolbar-item.e-active .e-tab-text {
    color: var(--lb-text) !important;
    font-weight: bold !important;
}

/* --- Toast error styling (used on calendar, case forms) --- */
.e-toast-container .e-toast .e-toast-message .e-toast-title {
    color: var(--lb-danger);
    font-size: 18px;
    font-weight: bold;
}

.e-toast-container .e-toast .e-toast-message .e-toast-content {
    color: var(--lb-danger);
    font-size: 13px;
    font-weight: normal;
}

/* --- Dialog flex layout (side-by-side content + button stack) --- */
.dialog-flex-container {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    width: 100%;
    gap: 32px;
}

.dialog-main-content {
    flex: 1 1 0;
    min-width: 0;
}

.dialog-button-stack {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    min-width: 160px;
    margin-top: 75px;
}

/* --- Search / action button (brand-colored) --- */
.search-action-btn {
    background-color: var(--lb-brand-hover) !important;
    color: #fff !important;
    width: 145px;
    min-width: 95px;
    max-width: 95px;
    border-radius: 4px;
    border: none;
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 2px;
}

/* --- Dialog footer actions row --- */
.dialog-footer-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    justify-content: flex-end;
}

/* The "Followup Task" action is wrapped in an SfTooltip container; without this
   it sits as a block and drops onto its own line, overlapping the row above.
   Keep every footer child shrink-to-content and vertically centered so they
   stay on one row (and wrap cleanly if the dialog is ever too narrow). */
.dialog-footer-actions > * {
    flex: 0 0 auto;
    /* The SfTooltip wrapper around "Followup Task" defaults to a full-width
       block; max-content caps it (and the plain buttons, already content-sized)
       at their natural width so all four share one row. */
    max-width: max-content;
    align-self: center;
}

/* --- Form group spacer (used in NewCaseDialog templates) --- */
.form-group-spaced {
    margin-bottom: 15px;
}

/* --- Bootstrap modal forced visible (replaces style="display:block") --- */
.modal-visible {
    display: block;
}

/* --- File input wrapper (used on document / email upload areas) --- */
.file-input-wrapper {
    width: 90%;
    margin-bottom: 12px;
}

/* --- Flex container for side-by-side grid+preview layouts --- */
.flex-row-layout {
    display: flex;
}

/* --- Contact dropdown formatting (shared by GlobalLogs, ReassignCases) --- */
.contact-display {
    /* No padding of its own: this only ever renders as a dropdown ItemTemplate,
       and the ".e-dropdownbase .e-list-item" block below now supplies the row's
       padding. Keeping both double-indented the text and made these rows 10px
       taller than every other dropdown's. */
    font-size: 14px;
    line-height: 1.4;
    color: var(--lb-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.contact-name {
    font-weight: 500;
    color: var(--lb-text);
}

.contact-company {
    font-weight: 400;
    color: var(--lb-text-muted);
    font-style: italic;
}

/* ===================================================================
   Syncfusion dropdown popups -- show the whole option text
   ===================================================================
   Syncfusion sizes an open popup to the INPUT, not to its contents:
   `popupWidth` defaults to "100%" and the JS writes the resulting pixel
   width as an INLINE style on the body-level popup element. Combined with
   the theme's `.e-dropdownbase .e-list-item { white-space: nowrap;
   text-overflow: ellipsis }`, any picker narrower than its longest option
   shows a clipped, unreadable list -- the Case Data Form's 160px Playbook
   picker being the one that got reported, with the same defect latent on
   every other narrow picker in the app.

   Fixing it per component (a `PopupWidth` on each of ~940 dropdown usages)
   both misses new ones and needs a magic number per screen, so the rules
   below fix the mechanism once, globally, for every SfDropDownList /
   SfComboBox / SfAutoComplete / SfMultiSelect at the same time.

   HOW it beats the inline width without `!important`: `min-width` and
   `max-width` are separate properties from `width`, and the used-width
   algorithm clamps to them AFTER the inline `width` is applied -- so a
   stylesheet can widen an inline-sized element. `min-width: max-content`
   grows the popup to its longest option; the item `max-width` caps how far
   that can go (and is what bounds the popup's own max-content, since an
   element's intrinsic contribution is clamped by its max-width); anything
   past the cap wraps instead of being cut off.

   Nothing changes for a picker already wide enough for its options -- a
   popup only grows past its inline width when an option would not have fit,
   which is exactly the broken case.

   js/dropdown-popup.js is the other half: Syncfusion positions the popup
   left-aligned to its input BEFORE these rules widen it and never re-fits,
   so a picker near the right edge of the window would open a popup that
   runs off-screen. Do not remove one without the other. */
.e-popup.e-ddl,
.e-popup.e-multi-select-list-wrapper {
    min-width: max-content;
    max-width: calc(100vw - 16px);
}

.e-dropdownbase .e-list-item,
.e-dropdownbase .e-list-group-item {
    /* Cap growth so one pathological option cannot produce a popup wider
       than the window; past this the text wraps. */
    max-width: min(520px, 88vw);
    /* Keep items full-bleed when the picker itself is wider than the cap. */
    min-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
    /* The theme indents the text with `text-indent`, which indents only the
       FIRST line -- wrapped lines would hang out to the left of it. Same
       12px, moved to padding so every line lines up. */
    text-indent: 0;
    padding-left: 12px;
    /* 20px line + 5px/5px == the theme's 30px single-line row height, so a
       one-line option is pixel-identical to before and only wrapped options
       get taller. */
    line-height: 20px;
    padding-top: 5px;
    padding-bottom: 5px;
}

/* Opt-out for virtualized pickers. Syncfusion's dropdown virtualization
   computes scroll offsets from a UNIFORM row height, so variable-height
   wrapped rows would desynchronize the scroll position from the data. These
   still get the wider popup -- they just keep the ellipsis past the cap.
   Applied via `CssClass="lb-ddl-nowrap"`, which Syncfusion copies onto the
   popup element. `.e-virtual-ddl` is Syncfusion's own marker for the same
   thing and is matched here as a backstop. */
.e-popup.lb-ddl-nowrap .e-list-item,
.e-popup.lb-ddl-nowrap .e-list-group-item,
.e-popup .e-virtual-ddl .e-list-item,
.e-popup .e-virtual-ddl .e-list-group-item {
    white-space: nowrap;
}

/* Override Syncfusion defaults for contact dropdowns */
.e-dropdownbase .e-list-item .contact-display {
    width: 100%;
    display: block;
}

.e-dropdownbase .e-list-item.e-active .contact-display {
    background-color: transparent;
}

/* --- Top-bar quick search (SearchBar.razor) dropdown items --- */
/* Global rules, not scoped CSS: the Syncfusion popup renders at body level
   and template content carries no isolation scope attribute, so these must
   live here (same pattern as .contact-display above). */
.e-dropdownbase .e-list-item .lb-search-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.e-dropdownbase .e-list-item .lb-search-item-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-dropdownbase .e-list-item .lb-search-item.is-open-case .lb-search-item-title {
    font-weight: 600;
}

.e-dropdownbase .e-list-item .lb-search-item.is-closed .lb-search-item-title {
    color: var(--lb-text-muted);
}

.e-dropdownbase .e-list-item .lb-search-closed-badge {
    flex-shrink: 0;
    padding: 0.1rem 0.45rem;
    border-radius: var(--lb-radius-pill);
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1.2;
    background: var(--lb-surface-alt);
    color: var(--lb-text-muted);
    border: 1px solid var(--lb-border);
}

/* --- Inline detail editor panel --- */
.detail-editor-panel {
    padding: 12px;
    border: 1px solid var(--lb-border);
    border-radius: 6px;
    margin-bottom: 12px;
}

.detail-section-pad {
    padding: 12px;
}

.detail-section-heading {
    margin-top: 0;
}

/* ===================================================================
   CODE DATA INLINE GEAR ICON
   ===================================================================
   Gear icon shown next to dropdown fields for admin users.
   Opens a CodeDataManagerDialog to manage the picklist inline. */

.field-with-gear {
    display: flex;
    align-items: flex-end;
    gap: 4px;
}

.field-with-gear > :first-child {
    flex: 1;
    min-width: 0;
}

.code-data-gear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--lb-text-muted, #999);
    cursor: pointer;
    flex-shrink: 0;
    transition: color 0.15s, background-color 0.15s;
}

.code-data-gear:hover {
    color: var(--lb-brand);
    background-color: var(--lb-surface-alt);
}

.code-data-gear .e-icons {
    font-size: 14px;
}

/* ================================================================
   Record Drawer -- Host page layout utilities
   Used by pages that adopt the side-drawer editing pattern.
   The RecordDrawer is position:absolute inside this container so
   it stays within the tab content area. position:relative makes
   this the positioning context; overflow:hidden clips the drawer
   during slide animation. flex:1 fills available tab height.
   ================================================================ */
.page-drawer-host {
    position: relative;
    width: 100%;
    max-width: 100%;
    flex: 1 1 auto;
    min-height: 300px;
    overflow: hidden;
}

.page-drawer-grid {
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
}



/* ================================================================
   Settlement Workup Forms (PI + WC)
   BEM-namespaced classes for the settlement workup forms.
   WC uses a centered SfDialog; PI uses a bottom RecordDrawer.
   Shared cosmetic/sizing styles live here; layout structure for
   the WC dialog body is in wc-workup-dialog classes below.
   ================================================================ */

/* -- Sections --------------------------------------------------- */
.workup-form__section {
    border-bottom: 1px solid var(--lb-border-light);
    padding-bottom: 0.4rem;
    margin-bottom: 0.4rem;
}

.workup-form__section:last-child {
    border-bottom: none;
    margin-bottom: 0;
}

.workup-form__section-header {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--lb-text-muted);
    margin-bottom: 0.35rem;
    padding-bottom: 0.15rem;
}

.workup-form__section-header--sub {
    margin-top: 0.6rem;
    padding-top: 0.4rem;
    border-top: 1px dashed var(--lb-border-light);
}

/* -- Rows ------------------------------------------------------- */
.workup-form__row {
    margin-bottom: 0.35rem;
}

.workup-form__row--full {
    display: flex;
    flex-direction: column;
}

.workup-form__row--pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}

/* -- Two-column form grid (WC dialog layout) -------------------- */
/* The divider sits on the grid row (single full-width rule) rather than on
   each section, so the line cannot terminate at two different heights when
   the left/right columns have unequal content. */
.workup-form__grid-2col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1.25rem;
    border-bottom: 1px solid var(--lb-border-light);
    padding-bottom: 0.4rem;
    margin-bottom: 0.4rem;
}

.workup-form__grid-2col > .workup-form__section {
    border-bottom: none;
    padding-bottom: 0;
    margin-bottom: 0;
}

/* -- Fields ----------------------------------------------------- */
.workup-form__field {
    display: flex;
    flex-direction: column;
}

.workup-form__field--checkbox {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding-bottom: 0.2rem;
}

.workup-form__field--action {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}

.workup-form__label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--lb-text);
    margin-bottom: 0.1rem;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    line-height: 1;
    white-space: nowrap;
}

.workup-form__read-only {
    font-size: 0.8rem;
    padding: 0.2rem 0.4rem;
    background: var(--lb-surface-alt);
    border: 1px solid var(--lb-border-light);
    border-radius: 3px;
    color: var(--lb-text);
    min-height: 1.6rem;
    display: flex;
    align-items: center;
}

.workup-form__computed {
    font-weight: 600;
}

.workup-form__info-icon {
    font-size: 0.7rem;
    color: var(--lb-text-muted);
    cursor: help;
    line-height: 1;
    vertical-align: middle;
}

/* SfTooltip wrapper inside labels must stay inline */
.workup-form__label .e-tooltip-wrap,
.workup-form__label > span {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

/* ================================================================
   WC Workup Dialog (.wc-workup-dialog)
   SfDialog portals to <body> -- scoped CSS cannot reach it.
   Centered modal replaces the old full-width bottom drawer.
   ================================================================ */

/* Constrain dialog content area height so the body scrolls */
.wc-workup-dialog .e-dlg-content {
    padding: 0;
    overflow: hidden;
    max-height: 70vh;
    display: flex;
    flex-direction: column;
}

.wc-workup-dialog .e-footer-content {
    padding: 0;
}

/* -- PI Workup Dialog (CaseSettlementPage) ---------------------- */
.pi-workup-dialog .e-dlg-content {
    padding: 0;
    overflow: hidden;
    max-height: 70vh;
    display: flex;
    flex-direction: column;
}

/* The drawer forms wrap their content in <fieldset class="drawer-fieldset"> (for the
   read-only disabled= gate). A fieldset's anonymous content box breaks the flex height
   chain from .e-dlg-content down to .workup-dialog-body, so take its box out of layout
   entirely. display:contents does not affect the disabled= semantics (those are DOM,
   not layout). Scoped to the two workup dialogs so other drawer fieldsets are untouched. */
.wc-workup-dialog .e-dlg-content > .drawer-fieldset,
.pi-workup-dialog .e-dlg-content > .drawer-fieldset {
    display: contents;
}

.pi-workup-dialog .e-footer-content {
    padding: 0;
}

.pi-workup-dialog__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 0.75rem 1.25rem;
}

.pi-workup-dialog__footer-left,
.pi-workup-dialog__footer-right {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

/* On a phone the settlement-workup footer (Cancel + Follow-up on the left, Set
   as Active / Delete / Save Workup on the right) is wider than the viewport, so
   the space-between row overflowed and the Save button was clipped off the right
   edge. Let the footer and each button group wrap to additional rows. */
@media (max-width: 767.98px) {
    .pi-workup-dialog__footer {
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 8px;
    }

    .pi-workup-dialog__footer-left,
    .pi-workup-dialog__footer-right {
        flex-wrap: wrap;
    }

    /* Safety net for any other dialog whose buttons sit in Syncfusion's standard
       footer (DialogButtons): let them wrap instead of clipping at the edge.
       flex-wrap only changes layout when the row actually overflows. */
    .e-dialog .e-footer-content {
        flex-wrap: wrap;
    }
}

/* Loading placeholder inside dialog content */
.wc-workup-dialog__loading {
    position: relative;
    min-height: 300px;
}

/* -- Dialog body: fields left, summary sidebar right ------------ */
.workup-dialog-body {
    display: flex;
    flex-direction: row;
    flex: 1 1 auto;
    min-height: 0;
}

.workup-dialog-body__fields {
    flex: 1 1 0;
    overflow-y: auto;
    padding: 1rem 1.25rem;
    min-width: 0;
}

/* -- Summary sidebar (pinned right) ----------------------------- */
.workup-dialog-body__summary {
    flex: 0 0 240px;
    border-left: 1px solid var(--lb-border-light);
    background: var(--lb-surface-alt);
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    overflow-y: auto;
}

.workup-form__summary-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--lb-text-muted);
}

/* -- Summary sidebar hero rows (scoped to sidebar to avoid
      cascading over the PI bottom-drawer hero styles) ----------- */
.workup-dialog-body__summary .workup-form__hero-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 0.8rem;
    color: var(--lb-text);
    padding: 0;
}

.workup-dialog-body__summary .workup-form__hero-value {
    font-weight: 600;
}

.workup-dialog-body__summary .workup-form__hero-row--deduction {
    color: var(--lb-text-muted);
    font-size: 0.78rem;
}

.workup-dialog-body__summary .workup-form__hero-divider {
    border-top: 1px solid var(--lb-border-light);
    margin: 0.15rem 0;
}

.workup-dialog-body__summary .workup-form__hero-divider--total {
    border-top-width: 2px;
    border-top-color: var(--lb-border);
    margin: 0.25rem 0;
}

.workup-dialog-body__summary .workup-form__hero-row--total {
    font-weight: 600;
    font-size: 0.85rem;
}

.workup-dialog-body__summary .workup-form__hero-row--total span:last-child {
    font-size: 1.1rem;
}

.workup-dialog-body__summary .workup-form__hero-row--positive span:last-child {
    color: var(--lb-success);
}

.workup-dialog-body__summary .workup-form__hero-row--negative span:last-child {
    color: var(--lb-danger);
}

/* MSA advisory pushed to the bottom of the summary sidebar */
.workup-form__msa-advisory {
    margin-top: auto;
}

/* -- Dialog footer layout --------------------------------------- */
.wc-workup-dialog__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    gap: 0.5rem;
    width: 100%;
}

.wc-workup-dialog__footer-left,
.wc-workup-dialog__footer-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* -- Responsive: stack dialog layout on narrow viewports -------- */
@media (max-width: 768px) {
    .workup-form__grid-2col {
        grid-template-columns: 1fr;
    }

    /* Stacked column layout. The body grows with content and the dialog's
       own content area scrolls -- the internal overflow:auto on the fields
       panel collapsed it to zero on phone because flex: 1 1 0 in a column
       parent without an enforced height has no room to grow. */
    .workup-dialog-body {
        flex-direction: column;
        flex: 0 0 auto;
        height: auto;
    }

    .workup-dialog-body__fields {
        flex: 1 1 auto;
        overflow-y: visible;
        padding: 0.75rem;
    }

    .workup-dialog-body__summary {
        flex: 0 0 auto;
        border-left: none;
        border-top: 1px solid var(--lb-border-light);
        overflow-y: visible;
    }

    /* Settlement workup dialogs (PI and WC) must scroll on phone so all form
       fields are reachable. The default Syncfusion dialog content allows
       scroll, but these dialogs need an explicit max-height so it actually
       engages. */
    .e-dialog.wc-workup-dialog .e-dlg-content,
    .e-dialog.pi-workup-dialog .e-dlg-content {
        overflow-y: auto;
        max-height: calc(var(--lb-dialog-max-height-phone, 90vh) - 7rem);
    }

    .wc-workup-dialog__footer {
        flex-direction: column;
        align-items: stretch;
    }

    .wc-workup-dialog__footer-right {
        justify-content: flex-end;
    }
}

/* ===================================================================
   Case Contact Dialog (.case-contact-dialog)
   SfDialog portals to <body> -- scoped CSS cannot reach it.
   =================================================================== */

/* -- Avatar header bar -- */
.case-contact-dialog .dialog-header-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 4px 10px;
    border-bottom: 1px solid var(--lb-border, #dee2e6);
    margin-bottom: 4px;
    flex-shrink: 0;
}

.case-contact-dialog .dialog-avatar {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 15px;
    color: #fff;
    flex-shrink: 0;
}

.case-contact-dialog .dialog-avatar.avatar--info   { background: var(--lb-info, #0dcaf0); }
.case-contact-dialog .dialog-avatar.avatar--purple { background: #7c4dff; }
.case-contact-dialog .dialog-avatar.avatar--coral  { background: #ff6b6b; }
.case-contact-dialog .dialog-avatar.avatar--teal   { background: #20c997; }
.case-contact-dialog .dialog-avatar.avatar--gray   { background: #adb5bd; }

.case-contact-dialog .dialog-header-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.case-contact-dialog .dialog-header-name {
    font-weight: 600;
    font-size: 16px;
    color: var(--lb-text, #212529);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.case-contact-dialog .dialog-header-role {
    font-size: 13px;
    color: var(--lb-text-muted, #6c757d);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* -- Split footer -- */
.case-contact-dialog .e-footer-content {
    display: flex !important;
    flex-direction: row !important;
    align-items: center;
    width: 100%;
    padding: 8px 16px;
}

.case-contact-dialog .dialog-footer-split {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    gap: 12px;
    flex-wrap: nowrap;
}

.case-contact-dialog .dialog-footer-left,
.case-contact-dialog .dialog-footer-right {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    flex-shrink: 0;
}

/* -- Dialog content flex layout -- */
.case-contact-dialog .e-dlg-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.case-contact-dialog .e-dlg-content > .dialog-header-bar + .e-tab,
.case-contact-dialog .e-dlg-content > .e-tab {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.case-contact-dialog .e-tab .e-content {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.case-contact-dialog .e-tab .e-content .e-item {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* -- General Info layout -- */
.case-contact-dialog .gi-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.case-contact-dialog .gi-two-col {
    display: flex;
    gap: 16px;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
}

.case-contact-dialog .gi-left {
    flex: 1 1 0;
    min-width: 0;
    overflow: auto;
}

.case-contact-dialog .gi-right {
    flex: 1 1 0;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    display: grid;
    grid-template-rows: minmax(160px, 1fr) auto auto;
    gap: 12px;
}

.case-contact-dialog .addr-scroll {
    overflow: auto;
    min-height: 0;
}

.case-contact-dialog .gi-section-gap {
    margin-top: 12px;
}

.case-contact-dialog .gi-right .gi-section-gap {
    margin-top: 0;
}

.case-contact-dialog .gi-bottom {
    margin-top: 16px;
}

/* -- Address toolbar -- */
.case-contact-dialog .addr-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0 10px;
    flex-wrap: wrap;
}

.case-contact-dialog .addr-toolbar-label {
    font-weight: 600;
    font-size: 14px;
    color: var(--lb-text, #212529);
}

.case-contact-dialog .addr-type-dropdown {
    min-width: 120px;
    max-width: 160px;
}

.case-contact-dialog .addr-nav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--lb-border, #dee2e6);
    border-radius: 4px;
    background: var(--lb-bg-white, #fff);
    cursor: pointer;
    color: var(--lb-text-muted, #6c757d);
    padding: 0;
    transition: border-color 0.15s ease;
}

.case-contact-dialog .addr-nav-btn:hover {
    border-color: var(--lb-brand);
    color: var(--lb-text);
}

.case-contact-dialog .addr-counter {
    font-size: 12px;
    color: var(--lb-text-muted, #6c757d);
    min-width: 42px;
    text-align: center;
    white-space: nowrap;
}

/* -- Detail tab -- */
.case-contact-dialog .detail-tab-body {
    padding: 12px 0;
}

/* -- Form grid layouts (inside dialog) -- */
.case-contact-dialog .form-section-title {
    margin: 12px 0 8px;
    font-weight: 600;
    color: var(--lb-text, #212529);
    border-bottom: 1px solid var(--lb-border, #dee2e6);
    padding-bottom: 4px;
}

.case-contact-dialog .form-grid {
    display: grid;
    gap: 10px 12px;
}

.case-contact-dialog .form-grid-2 {
    grid-template-columns: repeat(2, 1fr);
}

.case-contact-dialog .form-grid-4 {
    grid-template-columns: repeat(4, 1fr);
}

.case-contact-dialog .form-grid-11 {
    grid-template-columns: repeat(11, 1fr);
}

.case-contact-dialog .span-1  { grid-column: span 1; }
.case-contact-dialog .span-2  { grid-column: span 2; }
.case-contact-dialog .span-3  { grid-column: span 3; }
.case-contact-dialog .span-4  { grid-column: span 4; }
.case-contact-dialog .span-5  { grid-column: span 5; }
.case-contact-dialog .span-6  { grid-column: span 6; }
.case-contact-dialog .span-7  { grid-column: span 7; }
.case-contact-dialog .span-9  { grid-column: span 9; }
.case-contact-dialog .span-11 { grid-column: span 11; }
.case-contact-dialog .span-full { grid-column: 1 / -1; }

.case-contact-dialog .gender-radios {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: center;
    padding-top: 4px;
}

.case-contact-dialog .checkbox-row {
    display: flex;
    gap: 16px;
    align-items: center;
    padding-top: 22px; /* align with fields that have labels above */
    flex-wrap: wrap;
}

/* -- Responsive -- */
@media (max-width: 768px) {
    .case-contact-dialog .form-grid-11,
    .case-contact-dialog .form-grid-4 {
        grid-template-columns: 1fr;
    }

    .case-contact-dialog .span-1,
    .case-contact-dialog .span-2,
    .case-contact-dialog .span-3,
    .case-contact-dialog .span-4,
    .case-contact-dialog .span-5,
    .case-contact-dialog .span-6,
    .case-contact-dialog .span-7,
    .case-contact-dialog .span-9,
    .case-contact-dialog .span-11 {
        grid-column: span 1;
    }

    .case-contact-dialog .gi-two-col {
        flex-direction: column;
    }
}

/* -- User Fields / Relations tab -- */
.case-contact-dialog .udf-two-col {
    display: flex;
    gap: 16px;
    margin-top: 12px;
}

.case-contact-dialog .udf-col {
    flex: 1 1 0;
    min-width: 0;
}

/* Disabled relationship strikethrough */
.case-contact-dialog .disabled-item {
    text-decoration: line-through;
    display: inline-block;
    width: 100%;
}

/* -- Grid edit cells: adapt background/text to current theme -- */
/* Prevents the hard-coded white fill that breaks dark mode          */
.case-contact-dialog .e-grid .e-editedrow td.e-rowcell {
    background-color: var(--lb-bg-white) !important;
    color: var(--lb-text) !important;
}
.case-contact-dialog .e-grid .e-editedrow .e-input-group,
.case-contact-dialog .e-grid .e-editedrow input.e-input,
.case-contact-dialog .e-grid .e-editedrow .e-ddl.e-input-group {
    background-color: transparent !important;
    color: var(--lb-text) !important;
}
/* Ensure inline Save (✓) / Cancel (✗) command buttons are visible in dark mode */
.case-contact-dialog .e-grid .e-editedrow .e-btn-icon {
    color: var(--lb-text) !important;
}

/* -- Tab badge (used on Calendar, Documents, Cases tabs) -- */
.case-contact-dialog .tab-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    margin-left: 6px;
    line-height: 1;
}

.case-contact-dialog .tab-badge--neutral {
    background: var(--lb-bg-surface);
    color: var(--lb-text-muted);
}

/* ===================================================================
   Contact Search Dialog (.lb-contact-search-dialog)
   SfDialog portals to <body> -- scoped CSS cannot reach it.
   =================================================================== */

.lb-contact-search-dialog .search-fields {
    display: flex;
    gap: 12px;
    align-items: flex-end;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.lb-contact-search-dialog .search-field {
    flex: 1 1 180px;
    min-width: 150px;
}

.lb-contact-search-dialog .search-field input.e-input {
    width: 100%;
    box-sizing: border-box;
}

.lb-contact-search-dialog .search-field--btn {
    flex: 0 0 auto;
    padding-bottom: 1px;
}

.lb-contact-search-dialog .search-validation {
    color: var(--lb-danger, #dc3545);
    font-size: 13px;
    margin-bottom: 8px;
}

.lb-contact-search-dialog .search-results {
    margin-bottom: 12px;
}

.lb-contact-search-dialog .result-name {
    font-weight: 500;
}

.lb-contact-search-dialog .result-address {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.lb-contact-search-dialog .result-address-line1 {
    font-size: 12px;
}

.lb-contact-search-dialog .result-address-line2 {
    font-size: 11px;
    color: var(--lb-text-muted);
}

.lb-contact-search-dialog .result-address-na {
    font-size: 12px;
    color: var(--lb-text-muted, #6c757d);
}

.lb-contact-search-dialog .case-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 22px;
    padding: 0 6px;
    border-radius: 11px;
    font-size: 12px;
    font-weight: 600;
    background: var(--lb-bg-surface);
    color: var(--lb-text-muted);
}

.lb-contact-search-dialog .result-actions {
    display: flex;
    gap: 6px;
    align-items: center;
}

.lb-contact-search-dialog .already-on-case {
    color: var(--lb-text-muted, #6c757d);
    font-size: 13px;
}

.lb-contact-search-dialog .search-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--lb-text-muted, #6c757d);
}

.lb-contact-search-dialog .search-bottom-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0 4px;
    border-top: 1px solid var(--lb-border, #dee2e6);
    margin-top: 8px;
}

.lb-contact-search-dialog .search-bottom-text {
    font-size: 14px;
    color: var(--lb-text-muted, #6c757d);
}

/* ===================================================================
   Contact Link Dialog (.lb-contact-link-dialog)
   SfDialog portals to <body> -- scoped CSS cannot reach it.
   =================================================================== */

.lb-contact-link-dialog .link-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 0 12px;
    border-bottom: 1px solid var(--lb-border, #dee2e6);
    margin-bottom: 12px;
}

.lb-contact-link-dialog .link-avatar {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 15px;
    color: #fff;
    background: var(--lb-info, #0dcaf0);
    flex-shrink: 0;
}

.lb-contact-link-dialog .link-header-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.lb-contact-link-dialog .link-name {
    font-weight: 600;
    font-size: 16px;
    color: var(--lb-text, #212529);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lb-contact-link-dialog .link-subtitle {
    font-size: 13px;
    color: var(--lb-text-muted, #6c757d);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lb-contact-link-dialog .link-section-title {
    margin: 0 0 10px;
    font-weight: 600;
    color: var(--lb-text, #212529);
    font-size: 14px;
}

.lb-contact-link-dialog .link-form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.lb-contact-link-dialog .link-field--full {
    grid-column: 1 / -1;
}

.lb-contact-link-dialog .link-checks {
    display: flex;
    align-items: center;
    gap: 16px;
    padding-top: 22px;
}

.lb-contact-link-dialog .link-validation {
    color: var(--lb-danger, #dc3545);
    font-size: 13px;
    margin-top: 8px;
}

/* -- Link dialog footer -- */
.lb-contact-link-dialog .e-footer-content {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 8px 16px;
}

.workup-form__char-count {
    font-size: 0.65rem;
    color: var(--lb-text-muted);
    text-align: right;
    margin-top: 0.1rem;
}

/* -- Post to Ledger button and badge -- */
.workup-form__post-btn {
    color: var(--lb-info);
}

.workup-form__posted-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: var(--lb-success);
    font-weight: 600;
}

.workup-form__posted-note {
    font-size: 0.7rem;
    color: var(--lb-text-muted);
    margin-top: 0.25rem;
}

/* -- Pro-rate button and label (PI only) -- */
.workup-form__prorate-btn {
    color: var(--lb-success);
}

.workup-form__prorate-label {
    font-size: 0.7rem;
    color: var(--lb-text-muted);
    margin-top: 0.25rem;
    font-style: italic;
}

.workup-form__prorate-hint {
    font-size: 0.7rem;
    color: var(--lb-text-muted);
    margin-top: 0.25rem;
}

/* -- Settlement Amount accent border -- */
.workup-form__settlement-input .e-input-group {
    border-left: 3px solid var(--lb-brand, rgb(204, 108, 44));
}

/* -- PPD Award computed result (WC only) -- tinted read-only box -- */
.workup-form__ppd-result {
    background: var(--lb-info-bg);
    border-color: var(--lb-info);
    color: var(--lb-info);
}

/* -- Advisory notes (WC: amber for MSA, info for statutory cap) -- */
.workup-form__advisory {
    display: flex;
    align-items: flex-start;
    gap: 0.3rem;
    font-size: 0.65rem;
    line-height: 1.3;
    padding: 0.25rem 0.5rem;
    border-radius: 3px;
    margin-top: 0.15rem;
}

.workup-form__advisory--amber {
    background: var(--lb-warning-bg);
    border: 1px solid var(--lb-warning);
    color: var(--lb-warning);
}

.workup-form__advisory--info {
    background: var(--lb-info-bg);
    border: 1px solid var(--lb-info);
    color: var(--lb-info);
}

/* -- Fee cap warning (WC only) -- red inline alert -- */
.workup-form__fee-cap-warning {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--lb-danger);
    padding: 0.35rem 0.6rem;
    background: var(--lb-danger-bg);
    border: 1px solid var(--lb-danger);
    border-radius: 4px;
    margin-top: 0.2rem;
    margin-bottom: 0.2rem;
}

/* -- Net to Client hero box -- */
.workup-form__hero {
    border: 2px solid var(--lb-border-light);
    border-radius: 8px;
    padding: 0.75rem 1rem;
}

.workup-form__hero--positive {
    border-color: var(--lb-success);
    background: var(--lb-success-bg);
}

.workup-form__hero--negative {
    border-color: var(--lb-danger);
    background: var(--lb-danger-bg);
}

.workup-form__hero-row {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    padding: 0.12rem 0;
    color: var(--lb-text);
}

.workup-form__hero-row--deduction {
    color: var(--lb-text-muted);
}

.workup-form__hero-divider {
    border-top: 1px solid var(--lb-border-light);
    margin: 0.3rem 0;
}

.workup-form__hero-row--total {
    font-size: 1.05rem;
    font-weight: 700;
}

.workup-form__hero--positive .workup-form__hero-row--total {
    color: var(--lb-success);
}

.workup-form__hero--negative .workup-form__hero-row--total {
    color: var(--lb-danger);
}

/* -- Validation errors -- */
.workup-form__errors {
    grid-column: 1 / -1;
    background: var(--lb-danger-bg);
    border: 1px solid var(--lb-danger);
    border-radius: 4px;
    padding: 0.4rem 0.75rem;
}

.workup-form__errors ul {
    margin: 0;
    padding-left: 1.2rem;
    font-size: 0.75rem;
    color: var(--lb-danger);
}

/* -- Compact Syncfusion inputs inside the drawer -- */
.workup-form--bottom .e-input-group:not(.e-multi-line-input),
.workup-form--bottom .e-input-group:not(.e-multi-line-input) input,
.workup-form--bottom .e-input-group:not(.e-multi-line-input) .e-input {
    font-size: 0.8rem;
    height: 28px;
    min-height: 28px;
}

.workup-form--bottom .e-ddl.e-input-group {
    height: 28px;
    min-height: 28px;
}

.workup-form--bottom .e-date-wrapper {
    height: 28px;
    min-height: 28px;
}

.workup-form--bottom .e-multi-line-input {
    height: auto;
    min-height: auto;
}

.workup-form--bottom textarea.e-input {
    font-size: 0.8rem;
    height: auto;
    min-height: 60px;
    resize: vertical;
}

/* -- Mobile: stack vertically -- */
@media (max-width: 768px) {
    .workup-form--bottom {
        flex-direction: column;
        overflow: auto;
    }

    .workup-form__fields {
        grid-template-columns: 1fr;
        padding-right: 0;
    }

    .workup-form__hero-column {
        flex: 0 0 auto;
    }

    .workup-form__row--pair {
        grid-template-columns: 1fr;
    }
}

/* ===================================================================
   CHAT MESSAGE HIGHLIGHT (search "Go to message" scroll target)
   ===================================================================
   Applied by chat.js scrollToAndHighlightMessage(). The class is added
   via JS after scrolling into view, then removed after the animation
   completes. Uses --lb-warning-bg for the flash color.
   =================================================================== */

.chat-msg-highlight {
    animation: chat-highlight-fade 2.5s ease-out;
}

@keyframes chat-highlight-fade {
    0%   { background-color: var(--lb-warning-bg); }
    100% { background-color: transparent; }
}
/* =====================================================================
   PRINT STYLES
   =====================================================================
   Global print rules live here (not in scoped .razor.css files) because
   Blazor CSS isolation adds unique scope attributes that prevent
   scoped rules from reaching Syncfusion component internals.
   =================================================================== */

@media print {
    /* --- Hide application chrome --- */
    .sidebar,
    .top-row {
        display: none !important;
    }

    .page {
        display: block !important;
    }

    main {
        width: 100% !important;
    }

    article {
        padding: 0 !important;
    }

    /* --- Calendar page: hide toolbar, legend, status --- */
    .calendar-page-wrapper .e-toolbar,
    .calendar-sync-status,
    .activity-legend {
        display: none !important;
    }

    /* --- Calendar page: remove fixed height so content flows --- */
    .calendar-page-wrapper {
        height: auto !important;
        overflow: visible !important;
    }

    .calendar-main-layout {
        overflow: visible !important;
        height: auto !important;
    }

    /* --- Agenda grid: auto-height so all rows print --- */
    .agenda-grid-container,
    .agenda-grid-container .e-grid,
    .agenda-grid-container .e-gridcontent,
    .agenda-grid-container .e-gridcontent .e-content {
        height: auto !important;
        overflow: visible !important;
    }

    /* --- Scheduler: let Syncfusion PrintAsync handle it --- */
    .scheduler-container .e-schedule {
        height: auto !important;
        overflow: visible !important;
    }
}

/* =====================================================================
 * Custom icon: e-lb-dollar
 * US dollar sign rendered as a font glyph within the e-icons font stack.
 * Used for the Ledger case tab in place of the generic e-money icon.
 * ===================================================================== */
.e-icons.e-lb-dollar::before {
    content: '\0024'; /* Unicode dollar sign $ */
    font-family: inherit;
    font-style: normal;
    font-weight: 600;
    font-size: 0.95em;
    speak: none;
}

/* =====================================================================
 * Custom icon: e-lb-scales
 * Balance scales U+2696 for the Litigation case section. The phone case
 * overview used "e-balance-scale", which is NOT in the Syncfusion icon font
 * (nor is "e-handshake" it used for Settlement), so both rows rendered blank.
 * Settlement now reuses e-lb-dollar; Litigation uses this glyph, following the
 * same fall-back pattern as e-lb-envelope / e-lb-bell above.
 * ===================================================================== */
.e-icons.e-lb-scales::before {
    content: '\2696\FE0E'; /* ⚖ U+2696 SCALES + VS15 for monochrome text style */
    font-family: "Segoe UI Symbol", "Segoe UI Emoji", "Apple Color Emoji",
                 "Noto Sans Symbols2", sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 1.05em;
    speak: none;
}

/* =====================================================================
 * Custom icon: e-lb-envelope
 * Unicode envelope U+2709 rendered through the e-icons font stack.
 * Syncfusion's e-mail and e-inbox glyphs are not present in this build
 * (the curated icon list in CaseTypeTabAdmin.razor pointedly omits any
 * email glyph), so we add one. Used by the topbar Email Inbox button.
 * ===================================================================== */
.e-icons.e-lb-envelope::before {
    content: '\2709\FE0E'; /* ✉ U+2709 ENVELOPE + VS15 for monochrome text style */
    /* The Syncfusion icon font does not include this glyph, so we let the
       browser fall back to a system font that does. The variation selector
       (U+FE0E) requests the monochrome text presentation so it matches the
       surrounding line-icon aesthetic instead of a colored emoji. */
    font-family: "Segoe UI Symbol", "Segoe UI Emoji", "Apple Color Emoji",
                 "Noto Sans Symbols2", sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 1.05em;
    speak: none;
}

/* =====================================================================
 * Custom icon: e-lb-bell
 * Unicode bell U+1F514 (monochrome text presentation) for the topbar
 * Notifications button. Syncfusion has no verified bell glyph in this
 * build, and the button was previously using e-send (a paper airplane),
 * which is the wrong affordance for notifications.
 * ===================================================================== */
.e-icons.e-lb-bell::before {
    content: '\1F514\FE0E'; /* 🔔 U+1F514 BELL + VS15 for monochrome text style */
    font-family: "Segoe UI Symbol", "Segoe UI Emoji", "Apple Color Emoji",
                 "Noto Sans Symbols2", sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 1.05em;
    speak: none;
}

/* =====================================================================
 * Investigation Page – Accordion brand color overrides
 * Prevents Syncfusion's default blue on chevron hover and text flash.
 * ===================================================================== */
.investigation-layout .e-accordion .e-acrdn-item .e-toggle-icon .e-tgl-collapse-icon {
    color: var(--lb-text) !important;
    transition: color 0.15s ease;
}

.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:hover .e-toggle-icon .e-tgl-collapse-icon,
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:focus .e-toggle-icon .e-tgl-collapse-icon {
    color: var(--lb-brand) !important;
}

/* Force header text and all children to never be blue */
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header,
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header *,
.investigation-layout .e-accordion .e-acrdn-item.e-select > .e-acrdn-header,
.investigation-layout .e-accordion .e-acrdn-item.e-select > .e-acrdn-header *,
.investigation-layout .e-accordion .e-acrdn-item.e-active > .e-acrdn-header,
.investigation-layout .e-accordion .e-acrdn-item.e-active > .e-acrdn-header *,
.investigation-layout .e-accordion .e-acrdn-item.e-item-focus > .e-acrdn-header,
.investigation-layout .e-accordion .e-acrdn-item.e-item-focus > .e-acrdn-header * {
    color: var(--lb-text) !important;
    background-color: transparent !important;
    outline: none !important;
    box-shadow: none !important;
    transition: color 0.3s ease;
}

/* On click/focus flash yellow then fade back */
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:active,
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:active *,
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:focus,
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:focus * {
    color: var(--lb-brand) !important;
    background-color: transparent !important;
    outline: none !important;
    box-shadow: none !important;
}

/* Chevron hover stays yellow */
.investigation-layout .e-accordion .e-acrdn-item .e-acrdn-header:hover .e-tgl-collapse-icon {
    color: var(--lb-brand) !important;
}

/* ===================================================================
   BLAZOR CIRCUIT RECONNECT MODAL
   -------------------------------------------------------------------
   Custom UI for Blazor's reconnect lifecycle. Markup lives in App.razor;
   retry policy and auto-reload logic live in js/blazor-reconnect.js.
   Blazor toggles the components-reconnect-{show,hide,failed,rejected}
   classes on #components-reconnect-modal; we drive visibility + the
   per-state message from those classes.
   =================================================================== */
#components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10050;
    background: var(--lb-overlay-scrim);
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
}

#components-reconnect-modal .lb-reconnect-card {
    background: var(--lb-card);
    color: var(--lb-text);
    border-radius: 12px;
    box-shadow: var(--lb-shadow-lg);
    padding: 1.75rem 2rem;
    max-width: 420px;
    width: 100%;
    text-align: center;
}

#components-reconnect-modal .lb-reconnect-title {
    margin: 0 0 0.75rem 0;
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--lb-text-bright);
}

#components-reconnect-modal .lb-reconnect-message {
    margin: 0 0 1rem 0;
    color: var(--lb-text-muted);
    font-size: 0.9375rem;
    line-height: 1.45;
    display: none;
}

#components-reconnect-modal.components-reconnect-show .lb-reconnect-message-retrying {
    display: block;
}

#components-reconnect-modal.components-reconnect-failed .lb-reconnect-message-failed {
    display: block;
}

#components-reconnect-modal.components-reconnect-rejected .lb-reconnect-message-rejected {
    display: block;
}

/* Spinner is only meaningful while retrying. */
#components-reconnect-modal .lb-reconnect-spinner {
    width: 36px;
    height: 36px;
    margin: 0 auto 1rem;
    border: 3px solid var(--lb-border-light);
    border-top-color: var(--lb-brand);
    border-radius: 50%;
    animation: lb-reconnect-spin 0.9s linear infinite;
    display: none;
}

#components-reconnect-modal.components-reconnect-show .lb-reconnect-spinner {
    display: block;
}

/* Reload button only matters once retry has failed or been rejected. */
#components-reconnect-modal .lb-reconnect-reload {
    display: none;
    min-width: 140px;
}

#components-reconnect-modal.components-reconnect-failed .lb-reconnect-reload,
#components-reconnect-modal.components-reconnect-rejected .lb-reconnect-reload {
    display: inline-block;
}

@keyframes lb-reconnect-spin {
    to { transform: rotate(360deg); }
}

/* -------------------------------------------------------------------
   BoldSign embedded-send dialog
   SfDialog renders at <body>, outside component-scoped CSS, so the
   ::deep rules in EmbeddedSendDialog.razor.css never reach its content
   area and the iframe collapses to the browser default (~150px). These
   global rules give the content area a concrete height so the iframe
   (height:100%) fills the dialog and BoldSign's field-placement UI is
   usable. Keyed on the dialog's CssClass="embed-send-dialog".
   ------------------------------------------------------------------- */
.embed-send-dialog .e-dlg-content {
    height: calc(90vh - 110px);
    overflow: hidden;
    padding: 10px 14px;
}

.embed-send-dialog .embed-send-iframe-container {
    width: 100%;
    height: calc(90vh - 160px);
    overflow: hidden;
}

.embed-send-dialog .embed-send-iframe {
    width: 100%;
    height: 100%;
    border: none;
}

/* =====================================================================
 * Global empty-state utility (.lb-empty-state)
 * Use these classes for all "no results" / "nothing here yet" blocks.
 * ===================================================================== */

.lb-empty-state {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--lb-text-muted);
}

.lb-empty-icon {
    font-size: 2.5rem;
    opacity: 0.35;
    display: block;
    margin-bottom: 0.75rem;
}

.lb-empty-title {
    font-weight: 600;
    color: var(--lb-text);
    margin-bottom: 0.25rem;
}

.lb-empty-sub {
    font-size: 0.875rem;
    margin: 0;
}

.lb-back-link {
    display: inline-block;
    margin-top: 1rem;
    font-size: 0.875rem;
    color: var(--lb-brand);
    text-decoration: none;
}

.lb-back-link:hover {
    text-decoration: underline;
}

/* Settings sub-page "← Settings" back bar.
   Global so standalone Settings sub-pages can reuse the AdminSetting hub's
   back-bar look without each one duplicating scoped CSS. */
.settings-back-bar {
    padding: 12px 0;
    margin-bottom: 8px;
}

.settings-back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    color: var(--lb-brand);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    font-family: inherit;
    text-decoration: none;
    transition: background-color 200ms ease;
}

.settings-back-link:hover {
    background: var(--lb-brand-light);
    text-decoration: none;
}

.settings-back-link:focus-visible {
    outline: none;
    box-shadow: var(--lb-focus-ring);
}

.settings-back-link .e-icons {
    font-size: 14px;
}

/* ===================================================================
   AI Document Drafting dialog (NewAiDraftDialog)
   SfDialog teleports its content to <body>, so these rules live in global
   app.css (scoped .razor.css is unreliable for teleported popup content).
   The editor needs an explicit height or SfDocumentEditorContainer (Height=100%)
   collapses to 0 and the draft is invisible.
   =================================================================== */
.ai-draft-dialog .ai-draft-body {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    height: 100%;
    min-height: 0;
}

.ai-draft-dialog .ai-draft-controls {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ai-draft-dialog .ai-draft-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.ai-draft-dialog .ai-draft-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--lb-text-muted);
}

.ai-draft-dialog .ai-draft-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.ai-draft-dialog .ai-draft-hint {
    font-size: 0.82rem;
    color: var(--lb-text-muted);
    font-style: italic;
}

.ai-draft-dialog .ai-draft-status,
.ai-draft-dialog .ai-draft-placeholder {
    padding: 1.5rem 0.5rem;
    color: var(--lb-text-muted);
    text-align: center;
}

/* Incomplete-context banner (#3285). Sits above the editor and stays for as long as the
   draft is on screen -- a draft written from a partial case file must not read as complete.
   Colours come from the .alert-warning / .alert-danger token overrides. */
.ai-draft-dialog .ai-draft-gap-banner {
    flex: 0 0 auto;
    margin: 0;
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
    line-height: 1.35;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.ai-draft-dialog .ai-draft-editor {
    flex: 1 1 auto;
    min-height: 360px;
    border: 1px solid var(--lb-border);
    border-radius: 6px;
    overflow: hidden;
}

/* Discard / replace / save-incomplete confirm (#3288). */
.ai-draft-confirm .ai-draft-confirm-text {
    margin: 0;
    color: var(--lb-text);
}

.ai-draft-dialog .ai-draft-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    width: 100%;
}

/* =====================================================================
 * Calendar event hover tooltip -- Week / Month "at a glance" (/calendar)
 * SfSchedule renders its tooltip popup at <body>, so scoped .razor.css can
 * never reach it -- these styles must be global. Everything is scoped to the
 * scheduler event tooltip via :has(.cal-tip) so other SfTooltips (search box,
 * workup labels, etc.) are left untouched. Colors use --lb-* vars, so the
 * bubble themes itself for light/dark automatically.
 * ===================================================================== */
.e-tooltip-wrap.e-popup:has(.cal-tip) {
    background: var(--lb-card);
    border: 1px solid var(--lb-border);
    border-radius: 8px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
    max-width: 340px;
    opacity: 1;
}

/* Strip Syncfusion's default tip padding -- the card sets its own. */
.e-tooltip-wrap:has(.cal-tip) .e-tip-content {
    padding: 0;
    line-height: normal;
}

/* Match the little arrow to the card surface + border. The outer triangle is the
   border edge, the inner triangle the fill; set both border-color and color on the
   inner so it works whichever the active Syncfusion theme keys off. */
.e-tooltip-wrap.e-popup:has(.cal-tip) .e-arrow-tip-outer.e-tip-top { border-bottom-color: var(--lb-border); }
.e-tooltip-wrap.e-popup:has(.cal-tip) .e-arrow-tip-outer.e-tip-bottom { border-top-color: var(--lb-border); }
.e-tooltip-wrap.e-popup:has(.cal-tip) .e-arrow-tip-inner.e-tip-top { border-bottom-color: var(--lb-card); color: var(--lb-card); }
.e-tooltip-wrap.e-popup:has(.cal-tip) .e-arrow-tip-inner.e-tip-bottom { border-top-color: var(--lb-card); color: var(--lb-card); }

.cal-tip {
    text-align: left;
    padding: 10px 12px 10px 14px;
    border-left: 4px solid var(--lb-brand);
    border-radius: 6px;
    color: var(--lb-text);
    font-size: 0.8rem;
    line-height: 1.45;
}

.cal-tip-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
}

.cal-tip-title {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--lb-text-bright);
    word-break: break-word;
}

.cal-tip-badge {
    flex: 0 0 auto;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--lb-text-muted);
    background: var(--lb-surface-alt);
    border: 1px solid var(--lb-border-light);
    border-radius: 10px;
    padding: 1px 7px;
    white-space: nowrap;
}

.cal-tip-when {
    color: var(--lb-text-muted);
    margin-bottom: 6px;
}

.cal-tip-row {
    display: flex;
    gap: 8px;
    margin-top: 2px;
}

.cal-tip-label {
    flex: 0 0 46px;
    color: var(--lb-text-muted);
    font-weight: 600;
}

.cal-tip-val {
    flex: 1 1 auto;
    color: var(--lb-text);
    word-break: break-word;
}

.cal-tip-note {
    margin-top: 7px;
    padding-top: 7px;
    border-top: 1px dashed var(--lb-border);
    color: var(--lb-text);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 6.5em;
    overflow: hidden;
}

/* Activity-color accent bar -- mirrors the event-tile palette (OnEventRendered,
   ActivityCode % 8) so the hover bubble is color-coded like the tile it describes. */
.cal-tip.cal-tip-c0 { border-left-color: #dc2626; }
.cal-tip.cal-tip-c1 { border-left-color: #2563eb; }
.cal-tip.cal-tip-c2 { border-left-color: #16a34a; }
.cal-tip.cal-tip-c3 { border-left-color: #7c3aed; }
.cal-tip.cal-tip-c4 { border-left-color: #0891b2; }
.cal-tip.cal-tip-c5 { border-left-color: #d97706; }
.cal-tip.cal-tip-c6 { border-left-color: #be185d; }
.cal-tip.cal-tip-c7 { border-left-color: #6b7280; }
.cal-tip.cal-tip-cnone { border-left-color: var(--lb-brand); }

/* =====================================================================
 * Month view "+N more" day popup (PopupType.EventContainer) -- /calendar
 * The shared multi-line appointment <Template> overflowed the fixed-height
 * slots Syncfusion lays out in this popup, so events piled on top of each
 * other into an unreadable jumble. Render a clean, compact, scannable day
 * list instead: each event is one color-coded chip showing its title; the
 * full detail is one hover away (the .cal-tip tooltip) and one click away
 * (the preview panel). Global because the popup is portaled outside the
 * component's scoped DOM. The overlap fix is keyed on .e-more-event-popup
 * (the inner content list) so it holds regardless of the wrapper class.
 * ===================================================================== */
.e-more-popup-wrapper.e-popup {
    background: var(--lb-card);
    border: 1px solid var(--lb-border);
    border-radius: 8px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
    max-width: 320px;
}

.e-more-popup-wrapper .e-more-event-popup {
    padding: 6px 8px 10px;
}

/* Stop the overlap: let each event take its natural height in normal flow
   with spacing, instead of being absolutely placed in a too-short slot. The
   inline height/top/left/width Syncfusion sets require !important to override. */
.e-more-event-popup .e-appointment {
    position: relative !important;
    height: auto !important;
    min-height: 0 !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    width: auto !important;
    margin: 0 0 5px 0 !important;
    border-radius: 4px;
    overflow: hidden;
}

.e-more-event-popup .e-appointment:last-child {
    margin-bottom: 0 !important;
}

.e-more-event-popup .e-appointment .e-appointment-details {
    height: auto !important;
    padding: 4px 8px;
}

/* Compact chip: show the title line only. The bulky lines (location, ends,
   attendee list, note) are what overflowed; they're available on hover. */
.e-more-event-popup .appt-detail,
.e-more-event-popup .appt-attendee,
.e-more-event-popup .appt-note {
    display: none !important;
}

.e-more-event-popup .appt-title {
    white-space: normal;
    margin-bottom: 0;
    font-size: 0.8rem;
    line-height: 1.3;
}

/* ===================================================================
   GRID CONTEXT MENU -- open fully, never scroll
   Global scope required: Syncfusion teleports the menu out of the
   component, so Blazor CSS isolation cannot reach it.

   Since Syncfusion 23.2.6 a grid's context menu scrolls itself when it
   does not fit the space it measures, replacing the missing items with
   up/down chevrons. On the case Email tab the grid lives in a splitter
   pane, so the measured space is the PANE, not the window -- a ten-item
   menu turned into a stub with two arrows. There is no component switch
   to turn this off (Syncfusion tracks it as an open feature request), so
   the vertical-scroll wrapper is neutralised here instead.

   !important throughout: Syncfusion's VScroll writes height and the
   translateY offset as INLINE styles from JS, which no selector outrank.
   =================================================================== */
.e-contextmenu-wrapper .e-menu-vscroll,
.e-contextmenu-wrapper.e-menu-vscroll,
.e-contextmenu-container .e-menu-vscroll,
.e-contextmenu-container.e-menu-vscroll {
    height: auto !important;
    /* No viewport cap. A vh clamp here would be one bad measurement away from
       collapsing the menu to nothing, and Longbow's longest context menu is ten
       items (~350px) -- shorter than any real screen. Syncfusion still flips the
       menu upward near the bottom edge, so it stays on screen without scrolling. */
    max-height: none !important;
    overflow: visible !important;
}

/* The chevrons themselves. */
.e-contextmenu-wrapper .e-menu-vscroll > .e-scroll-nav,
.e-contextmenu-container .e-menu-vscroll > .e-scroll-nav {
    display: none !important;
}

/* The clipping viewport VScroll wraps around the item list. */
.e-contextmenu-wrapper .e-menu-vscroll > .e-vscroll-bar,
.e-contextmenu-container .e-menu-vscroll > .e-vscroll-bar {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
}

/* VScroll pages the list by translating this element; reset it so the
   first item is not left scrolled out of view. */
.e-contextmenu-wrapper .e-menu-vscroll .e-vscroll-content,
.e-contextmenu-container .e-menu-vscroll .e-vscroll-content {
    height: auto !important;
    transform: none !important;
}

.e-contextmenu-wrapper ul.e-contextmenu,
.e-contextmenu-container ul.e-contextmenu {
    max-height: none !important;
    overflow: visible !important;
}

/* ── HIPAA authorization badges (Records Requests tab) ─────────────────
   GLOBAL by necessity: Syncfusion grid templates strip the Blazor scoped-CSS
   attribute, so component-scoped styles never reach these spans.
   Thresholds are data-driven (firm HipaaAuthWarningDays) — the classes only
   style the three states from the hipaa-auth-expiration-alerts spec. */
.lb-auth-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
}

.lb-auth-badge-expired {
    background-color: #fde8e8;
    color: #b42318;
    border: 1px solid #f3b6b0;
}

.lb-auth-badge-warning {
    background-color: #fff6e6;
    color: #935f00;
    border: 1px solid #f2d59b;
}

.lb-auth-badge-none {
    background-color: #f1f3f5;
    color: #5f6b7a;
    border: 1px solid #d8dee6;
}
/* ============================================================
   AI Disclaimer Framework (ai-disclaimer-framework spec).
   Dialog rules MUST live here, not scoped CSS: SfDialog reparents
   its container to <body>, out of scoped-CSS reach. Tokens live
   in the scheme blocks above (one set per scheme — keep in sync).
   ============================================================ */

.ai-terms-dialog.e-dialog {
    /* The fixed 560px inline width overflows phone viewports. */
    max-width: 92vw;
}

.ai-terms-dialog .ai-terms-content {
    /* The disclaimer is stored as plain text; pre-line honors its line breaks
       and bullet dashes without any markup/sanitizer surface. */
    white-space: pre-line;
    font-size: 0.9rem;
    line-height: 1.55;
    max-height: 55vh;
    overflow-y: auto;
}

.ai-terms-dialog .ai-terms-error,
.ai-disclaimer-settings .ai-terms-error {
    margin-top: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 6px;
    background: var(--lb-warning-bg, #FBF0E8);
    color: var(--lb-warning-text, #9A4A12);
    border: 1px solid var(--lb-warning-border, #EAC9AE);
    font-size: 0.85rem;
}

.ai-terms-dialog .ai-terms-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* AI Disclaimers settings section (AiDisclaimerSettings.razor) */
.ai-disclaimer-settings .ai-ds-title { margin-bottom: 0.25rem; }
.ai-disclaimer-settings .ai-ds-subtitle { color: var(--lb-text-muted, #6B7280); font-size: 0.88rem; }
.ai-disclaimer-settings .ai-ds-field { margin-bottom: 1rem; max-width: 720px; }
.ai-disclaimer-settings .ai-ds-actions { margin-bottom: 1.5rem; }
.ai-disclaimer-settings .ai-ds-divider { margin: 1.5rem 0; }
.ai-disclaimer-settings .ai-ds-grid-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.25rem;
}
.ai-disclaimer-settings .ai-ds-grid-title { margin: 0; }
