/* ============================================================================
   Orcanex design tokens — single source of truth for the redesigned UI.
   Loaded once from Headcss.razor BEFORE every other stylesheet so scoped
   .razor.css files can reference var(--color-accent) etc.
   ============================================================================ */

:root {
    /* Surface */
    --color-bg:           #F7F8FA;
    --color-panel:        #FFFFFF;
    --color-border:       #E6E8EC;
    --color-border-soft:  #EFF1F4;

    /* Text */
    --color-text:         #0F1115;
    --color-text-muted:   #6B7280;
    --color-text-subtle:  #9AA0AA;

    /* Accent (single restrained brand colour). Slate is the system default —
       calm, corporate, "serious software". Other accents override these
       variables under [data-accent="…"] further down. */
    --color-accent:       #475569;
    --color-accent-soft:  #E2E8F0;
    --color-accent-hover: #334155;
    --color-accent-ring:  rgba(71, 85, 105, 0.20);   /* used for focus rings & "is-active" glows */

    /* Semantic tones */
    --color-success:      #0E8F5A;
    --color-success-soft: #E6F4ED;
    --color-warn:         #B6781F;
    --color-warn-soft:    #FBF1DF;
    --color-danger:       #C0322B;
    --color-danger-soft:  #FBE9E7;

    /* Icon-rail palette — rail-bg derives from the user's accent so the menu
       column visibly tints with their chosen palette. 22% accent over a
       mid-dark slate base produces a readable accent presence while keeping
       the rail clearly darker than the page panel. Falls back to flat #0F1115
       on browsers without color-mix support (Chrome <111, Firefox <113). */
    --color-rail-bg:      #0F1115;
    --color-rail-bg:      color-mix(in srgb, var(--color-accent) 22%, #1B1F28);
    --color-rail-fg:      #FFFFFF;
    --color-rail-fg-muted:#8B9099;
    --color-rail-active:  rgba(71, 85, 105, 0.18);
    --color-rail-active-fg:#94A3B8;

    /* Avatar palette (hashed by name) */
    --avatar-1: #E55C5C;
    --avatar-2: #E5904A;
    --avatar-3: #E5B83D;
    --avatar-4: #62B36A;
    --avatar-5: #3FAFA3;
    --avatar-6: #3F8FE5;
    --avatar-7: #7560E5;
    --avatar-8: #C455B0;

    /* Type */
    --font-family: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", monospace;

    /* Spacing scale */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 48px;

    /* Radius */
    --radius-sm: 6px;   /* chips */
    --radius-md: 8px;   /* fields, buttons */
    --radius-lg: 12px;  /* cards */
    --radius-pill: 999px;

    /* Shadow */
    --shadow-overlay: 0 8px 24px rgba(0, 0, 0, 0.12);
    --shadow-modal:   0 20px 60px rgba(0, 0, 0, 0.30);
    --shadow-toast:   0 8px 24px rgba(0, 0, 0, 0.18);

    /* Heights — field/button heights are calc() so they grow with the user's
       font-scale (the rem term reflects the root font-size). The px term
       is the density component; the rem term is the font-scale component.
       Net result: field text always has comfortable breathing room, even at
       xlarge. Row/topbar heights stay px because they don't contain text. */
    --h-topbar:    52px;
    --h-row:       64px;
    --h-row-md:    48px;
    --h-field:     calc(20px + 1.4rem);   /* ≈38 @ medium / ≈42 @ xlarge */
    --h-button:    calc(18px + 1.4rem);   /* ≈36 / ≈40 */
    --h-button-sm: calc(12px + 1.4rem);   /* ≈30 / ≈34 */

    /* Tight-form variants — used inside .orcanex-form-grid-tight (case form,
       specialist form, configuration pages). These scale with data-density
       so a user who picks comfortable/large still gets bigger fields on tight
       sections, but proportionally smaller than the standard form heights.
       Font tokens are in rem (relative to the 13px medium baseline) so the
       user's data-font-scale preference reaches them via html { font-size }. */
    --h-field-tight:        calc(12px + 1.4rem);   /* ≈30 @ medium / ≈34 @ xlarge */
    --font-tight-field:     0.96rem;
    --font-tight-label:     0.85rem;
    --h-textarea-tight-min: 64px;

    /* Vertical breathing room inside Field primitive: gap between the uppercase
       label and the input below it. Density-aware so larger densities get more
       air to read. */
    --field-label-gap:      6px;

    /* Widths */
    --w-icon-rail: 56px;
    --w-rail-expanded: 248px;   /* wide-rail mode (data-rail-expanded="1"): full logo + labels + sub-menu inline */
    --w-sub-rail:  224px;
    --w-drawer:    320px;

    /* Breakpoints — Bootstrap 5.3 aligned. CSS @media rules can't read custom
       properties, so these are reference constants for documentation and any
       JS that needs them (ViewportService.js mirrors the same numbers). The
       Orcanex viewports map: mobile <768, tablet 768–1199, desktop ≥1200. */
    --bp-mobile-l:    576px;
    --bp-tablet:      768px;
    --bp-tablet-l:    992px;
    --bp-desktop:    1200px;
    --bp-desktop-xl: 1400px;

    /* Mobile bottom-tab nav height (Phase 12). */
    --h-mobile-tabs: 60px;
    /* Mobile-only touch-target floor — Apple HIG / WCAG 2.5.5 AAA. Density
       and font-scale tokens normally drive --h-button etc.; the floor is
       applied via [data-viewport="mobile"] further down. */
    --touch-target: 44px;

    /* Z-index */
    --z-topbar: 30;
    --z-drawer: 40;
    --z-modal:  50;
    --z-toast:  60;

    /* Motion */
    --ease-hover: cubic-bezier(0.2, 0, 0, 1);
    --ease-enter: cubic-bezier(0.4, 0, 0.2, 1);
    --duration-hover: 120ms;
    --duration-enter: 160ms;
}

/* ============================================================================
   Dynamic Theming v1 — attribute-scoped overrides on <html>.

   Driven by user preferences stored on userProfiles and applied client-side
   via /js/user-settings.js applyUserPreferences(). The five axes are:

     data-theme         light (default) | dark
     data-density       compact (default) | comfortable | large
     data-font-scale    small | medium (default) | large | xlarge
     data-accent        blue (default) | teal | indigo | violet | magenta
                        | pink | crimson | amber | forest
     data-list-mode     card (default) | tabular        (consumed by Cases /
                                                         Specialists scoped CSS)

   Plus two boolean toggles:
     data-reduce-motion 0 (default) | 1
     data-high-contrast 0 (default) | 1

   See DOCS/Plans/dynamic-theming-and-user-customisation.md.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   data-theme="dark" — full palette inversion.
   Components stay token-driven; nothing else needs to change.
   ---------------------------------------------------------------------------- */
:root[data-theme="dark"] {
    /* Surface */
    --color-bg:           #0F1115;
    --color-panel:        #161A22;
    --color-border:       #252B36;
    --color-border-soft:  #1D222C;

    /* Text */
    --color-text:         #E5E7EB;
    --color-text-muted:   #9AA0AA;
    --color-text-subtle:  #6B7280;

    /* Accent — lifted to keep contrast on dark surfaces. Slate is the dark
       default; other accents override this under [data-theme="dark"][data-accent="…"]. */
    --color-accent:       #94A3B8;
    --color-accent-soft:  rgba(148, 163, 184, 0.16);
    --color-accent-hover: #B0BFD0;
    --color-accent-ring:  rgba(148, 163, 184, 0.30);

    /* Semantic tones */
    --color-success:      #2DB378;
    --color-success-soft: rgba(45, 179, 120, 0.16);
    --color-warn:         #D89A4A;
    --color-warn-soft:    rgba(216, 154, 74, 0.16);
    --color-danger:       #E5645D;
    --color-danger-soft:  rgba(229, 100, 93, 0.16);

    /* Icon-rail palette — tinted with the accent at 28% over a near-black base
       so the rail visibly picks up the user's chosen palette. */
    --color-rail-bg:      #0A0C10;
    --color-rail-bg:      color-mix(in srgb, var(--color-accent) 28%, #0E1118);
    --color-rail-fg:      #E5E7EB;
    --color-rail-fg-muted:#6B7280;
    --color-rail-active:  rgba(148, 163, 184, 0.22);
    --color-rail-active-fg:#B0BFD0;

    /* Avatar palette — slight desaturation for dark mode legibility */
    --avatar-1: #D44A4A;
    --avatar-2: #D17B33;
    --avatar-3: #D1A22B;
    --avatar-4: #4FA258;
    --avatar-5: #2F9C92;
    --avatar-6: #2F7BC5;
    --avatar-7: #6555C5;
    --avatar-8: #B045A0;

    /* Shadows — deeper to read against dark surfaces */
    --shadow-overlay: 0 8px 24px rgba(0, 0, 0, 0.50);
    --shadow-modal:   0 20px 60px rgba(0, 0, 0, 0.65);
    --shadow-toast:   0 8px 24px rgba(0, 0, 0, 0.55);
}

/* ----------------------------------------------------------------------------
   data-density — comfortable / large overrides.
   Compact is the :root baseline (--h-row 64, --h-field 36, etc.).
   ---------------------------------------------------------------------------- */
:root[data-density="comfortable"] {
    --h-row:        72px;
    --h-row-md:     56px;
    --h-field:      calc(24px + 1.4rem);   /* ≈42 @ medium / ≈46 @ xlarge */
    --h-button:     calc(22px + 1.4rem);
    --h-button-sm:  calc(16px + 1.4rem);
    --space-1: 5px;
    --space-2: 10px;
    --space-3: 14px;
    --space-4: 18px;
    --space-5: 22px;
    --space-6: 28px;
    --space-7: 36px;
    --space-8: 56px;
    --h-field-tight:        calc(20px + 1.4rem);   /* ≈38 @ medium / ≈42 @ xlarge */
    --font-tight-field:     1.04rem;
    --font-tight-label:     0.92rem;
    --h-textarea-tight-min: 80px;
    --field-label-gap:      10px;
}

:root[data-density="large"] {
    --h-row:        84px;
    --h-row-md:     64px;
    --h-field:      calc(32px + 1.4rem);   /* ≈50 @ medium / ≈54 @ xlarge */
    --h-button:     calc(28px + 1.4rem);
    --h-button-sm:  calc(20px + 1.4rem);
    --space-1: 6px;
    --space-2: 12px;
    --space-3: 16px;
    --space-4: 22px;
    --space-5: 28px;
    --space-6: 36px;
    --space-7: 48px;
    --space-8: 72px;
    --h-field-tight:        calc(28px + 1.4rem);   /* ≈46 @ medium / ≈50 @ xlarge */
    --font-tight-field:     1.12rem;
    --font-tight-label:     1rem;
    --h-textarea-tight-min: 96px;
    --field-label-gap:      14px;
}

/* ----------------------------------------------------------------------------
   data-font-scale — html { font-size } drives the rem-based type ramp below.
   Medium is the :root baseline (14px) so no override is needed for it.

   Ramp: 12 / 14 / 16 / 18 px — each step +2px. Medium picked at 14px because
   the previous 13px baseline (Hyper era) felt cramped at standard density.

   These MUST be in px (not rem) because they set the html element's
   font-size, which is the rem reference itself — using rem here would be a
   circular reference.
   ---------------------------------------------------------------------------- */
:root[data-font-scale="small"]  { font-size: 12px; }
:root[data-font-scale="large"]  { font-size: 16px; }
:root[data-font-scale="xlarge"] { font-size: 18px; }

/* ----------------------------------------------------------------------------
   data-accent — 16 curated palettes. Each overrides only the accent + ring;
   semantic tones (success/warn/danger) are unchanged. Dark-mode counterparts
   are scoped under [data-theme="dark"][data-accent="..."] further below.
   "slate" is the :root default and needs no light-mode block.
   ---------------------------------------------------------------------------- */
:root[data-accent="blue"] {
    --color-accent:       #2F62FF;
    --color-accent-soft:  #EAF0FF;
    --color-accent-hover: #1E51EE;
    --color-accent-ring:  rgba(47, 98, 255, 0.20);
    --color-rail-active:  rgba(47, 98, 255, 0.18);
    --color-rail-active-fg:#7B9CFF;
}
:root[data-accent="teal"] {
    --color-accent:       #0E8F8F;
    --color-accent-soft:  #DAF1F1;
    --color-accent-hover: #077676;
    --color-accent-ring:  rgba(14, 143, 143, 0.20);
    --color-rail-active:  rgba(14, 143, 143, 0.18);
    --color-rail-active-fg:#5BC4C4;
}
:root[data-accent="indigo"] {
    --color-accent:       #5C4DE0;
    --color-accent-soft:  #ECEAF9;
    --color-accent-hover: #4A3BCA;
    --color-accent-ring:  rgba(92, 77, 224, 0.20);
    --color-rail-active:  rgba(92, 77, 224, 0.18);
    --color-rail-active-fg:#9990F0;
}
:root[data-accent="violet"] {
    --color-accent:       #7C3AED;
    --color-accent-soft:  #F2EBFB;
    --color-accent-hover: #6A2DD6;
    --color-accent-ring:  rgba(124, 58, 237, 0.20);
    --color-rail-active:  rgba(124, 58, 237, 0.18);
    --color-rail-active-fg:#B791F4;
}
:root[data-accent="magenta"] {
    --color-accent:       #C8359E;
    --color-accent-soft:  #F9E5F0;
    --color-accent-hover: #B22A8B;
    --color-accent-ring:  rgba(200, 53, 158, 0.20);
    --color-rail-active:  rgba(200, 53, 158, 0.18);
    --color-rail-active-fg:#E08CC8;
}
:root[data-accent="pink"] {
    --color-accent:       #E14B89;
    --color-accent-soft:  #FCE6EE;
    --color-accent-hover: #C73B75;
    --color-accent-ring:  rgba(225, 75, 137, 0.20);
    --color-rail-active:  rgba(225, 75, 137, 0.18);
    --color-rail-active-fg:#F197B6;
}
:root[data-accent="crimson"] {
    --color-accent:       #C0322B;
    --color-accent-soft:  #FBE9E7;
    --color-accent-hover: #A52822;
    --color-accent-ring:  rgba(192, 50, 43, 0.20);
    --color-rail-active:  rgba(192, 50, 43, 0.18);
    --color-rail-active-fg:#E08881;
}
:root[data-accent="amber"] {
    --color-accent:       #B6781F;
    --color-accent-soft:  #FBF1DF;
    --color-accent-hover: #9C681A;
    --color-accent-ring:  rgba(182, 120, 31, 0.20);
    --color-rail-active:  rgba(182, 120, 31, 0.18);
    --color-rail-active-fg:#E0AC65;
}
:root[data-accent="forest"] {
    --color-accent:       #286A47;
    --color-accent-soft:  #DCEDE2;
    --color-accent-hover: #1F5739;
    --color-accent-ring:  rgba(40, 106, 71, 0.20);
    --color-rail-active:  rgba(40, 106, 71, 0.18);
    --color-rail-active-fg:#7FBE99;
}
/* Cyan — modern AI / medical-tech / dashboards. */
:root[data-accent="cyan"] {
    --color-accent:       #06B6D4;
    --color-accent-soft:  #CFFAFE;
    --color-accent-hover: #0891B2;
    --color-accent-ring:  rgba(6, 182, 212, 0.20);
    --color-rail-active:  rgba(6, 182, 212, 0.18);
    --color-rail-active-fg:#67E8F9;
}
/* Emerald — clean, healthy, success-focused — sits well on clinical pages. */
:root[data-accent="emerald"] {
    --color-accent:       #10B981;
    --color-accent-soft:  #D1FAE5;
    --color-accent-hover: #059669;
    --color-accent-ring:  rgba(16, 185, 129, 0.20);
    --color-rail-active:  rgba(16, 185, 129, 0.18);
    --color-rail-active-fg:#6EE7B7;
}
/* Rose — softer alternative to crimson; polished, modern, less aggressive. */
:root[data-accent="rose"] {
    --color-accent:       #F43F5E;
    --color-accent-soft:  #FFE4E6;
    --color-accent-hover: #E11D48;
    --color-accent-ring:  rgba(244, 63, 94, 0.20);
    --color-rail-active:  rgba(244, 63, 94, 0.18);
    --color-rail-active-fg:#FB7185;
}
/* Navy — premium corporate; pairs especially well with the dark sidebar. */
:root[data-accent="navy"] {
    --color-accent:       #1E3A8A;
    --color-accent-soft:  #DBE5F7;
    --color-accent-hover: #172E6E;
    --color-accent-ring:  rgba(30, 58, 138, 0.20);
    --color-rail-active:  rgba(30, 58, 138, 0.18);
    --color-rail-active-fg:#7FA0F0;
}
/* Graphite — minimalist mono; "Linear.app"-style understated chrome. */
:root[data-accent="graphite"] {
    --color-accent:       #3F3F46;
    --color-accent-soft:  #E4E4E7;
    --color-accent-hover: #27272A;
    --color-accent-ring:  rgba(63, 63, 70, 0.20);
    --color-rail-active:  rgba(63, 63, 70, 0.22);
    --color-rail-active-fg:#A1A1AA;
}
/* Copper — premium warm; sits naturally with Orca branding. */
:root[data-accent="copper"] {
    --color-accent:       #B45309;
    --color-accent-soft:  #FFEDD5;
    --color-accent-hover: #92400E;
    --color-accent-ring:  rgba(180, 83, 9, 0.20);
    --color-rail-active:  rgba(180, 83, 9, 0.18);
    --color-rail-active-fg:#E0A45F;
}

/* Dark-mode accent variants — boost lightness for contrast on dark surfaces. */
:root[data-theme="dark"][data-accent="teal"] {
    --color-accent:       #4FBDB5;
    --color-accent-soft:  rgba(79, 189, 181, 0.16);
    --color-accent-hover: #6CCFC8;
    --color-accent-ring:  rgba(79, 189, 181, 0.32);
    --color-rail-active:  rgba(79, 189, 181, 0.22);
    --color-rail-active-fg:#7FD4CC;
}
:root[data-theme="dark"][data-accent="indigo"] {
    --color-accent:       #8B7BFF;
    --color-accent-soft:  rgba(139, 123, 255, 0.16);
    --color-accent-hover: #A294FF;
    --color-accent-ring:  rgba(139, 123, 255, 0.32);
    --color-rail-active:  rgba(139, 123, 255, 0.22);
    --color-rail-active-fg:#A99CFF;
}
:root[data-theme="dark"][data-accent="violet"] {
    --color-accent:       #A77AFF;
    --color-accent-soft:  rgba(167, 122, 255, 0.16);
    --color-accent-hover: #B894FF;
    --color-accent-ring:  rgba(167, 122, 255, 0.32);
    --color-rail-active:  rgba(167, 122, 255, 0.22);
    --color-rail-active-fg:#C2A5FF;
}
:root[data-theme="dark"][data-accent="magenta"] {
    --color-accent:       #E27DC0;
    --color-accent-soft:  rgba(226, 125, 192, 0.16);
    --color-accent-hover: #EA98CD;
    --color-accent-ring:  rgba(226, 125, 192, 0.32);
    --color-rail-active:  rgba(226, 125, 192, 0.22);
    --color-rail-active-fg:#EBA5D2;
}
:root[data-theme="dark"][data-accent="pink"] {
    --color-accent:       #F285AD;
    --color-accent-soft:  rgba(242, 133, 173, 0.16);
    --color-accent-hover: #F69EBF;
    --color-accent-ring:  rgba(242, 133, 173, 0.32);
    --color-rail-active:  rgba(242, 133, 173, 0.22);
    --color-rail-active-fg:#F4A8C0;
}
:root[data-theme="dark"][data-accent="crimson"] {
    --color-accent:       #E5736C;
    --color-accent-soft:  rgba(229, 115, 108, 0.16);
    --color-accent-hover: #ED8E88;
    --color-accent-ring:  rgba(229, 115, 108, 0.32);
    --color-rail-active:  rgba(229, 115, 108, 0.22);
    --color-rail-active-fg:#EE9690;
}
:root[data-theme="dark"][data-accent="amber"] {
    --color-accent:       #E0A45F;
    --color-accent-soft:  rgba(224, 164, 95, 0.16);
    --color-accent-hover: #ECB97D;
    --color-accent-ring:  rgba(224, 164, 95, 0.32);
    --color-rail-active:  rgba(224, 164, 95, 0.22);
    --color-rail-active-fg:#ECBC85;
}
:root[data-theme="dark"][data-accent="forest"] {
    --color-accent:       #5DAE82;
    --color-accent-soft:  rgba(93, 174, 130, 0.16);
    --color-accent-hover: #76C09A;
    --color-accent-ring:  rgba(93, 174, 130, 0.32);
    --color-rail-active:  rgba(93, 174, 130, 0.22);
    --color-rail-active-fg:#85C8A4;
}
:root[data-theme="dark"][data-accent="blue"] {
    --color-accent:       #5C82FF;
    --color-accent-soft:  rgba(92, 130, 255, 0.16);
    --color-accent-hover: #7090FF;
    --color-accent-ring:  rgba(92, 130, 255, 0.32);
    --color-rail-active:  rgba(92, 130, 255, 0.22);
    --color-rail-active-fg:#7B9CFF;
}
:root[data-theme="dark"][data-accent="cyan"] {
    --color-accent:       #22D3EE;
    --color-accent-soft:  rgba(34, 211, 238, 0.16);
    --color-accent-hover: #67E8F9;
    --color-accent-ring:  rgba(34, 211, 238, 0.32);
    --color-rail-active:  rgba(34, 211, 238, 0.22);
    --color-rail-active-fg:#67E8F9;
}
:root[data-theme="dark"][data-accent="emerald"] {
    --color-accent:       #34D399;
    --color-accent-soft:  rgba(52, 211, 153, 0.16);
    --color-accent-hover: #6EE7B7;
    --color-accent-ring:  rgba(52, 211, 153, 0.32);
    --color-rail-active:  rgba(52, 211, 153, 0.22);
    --color-rail-active-fg:#6EE7B7;
}
:root[data-theme="dark"][data-accent="rose"] {
    --color-accent:       #FB7185;
    --color-accent-soft:  rgba(251, 113, 133, 0.16);
    --color-accent-hover: #FDA4AF;
    --color-accent-ring:  rgba(251, 113, 133, 0.32);
    --color-rail-active:  rgba(251, 113, 133, 0.22);
    --color-rail-active-fg:#FDA4AF;
}
:root[data-theme="dark"][data-accent="navy"] {
    --color-accent:       #6F8AE0;
    --color-accent-soft:  rgba(111, 138, 224, 0.16);
    --color-accent-hover: #8FA5E8;
    --color-accent-ring:  rgba(111, 138, 224, 0.32);
    --color-rail-active:  rgba(111, 138, 224, 0.22);
    --color-rail-active-fg:#8FA5E8;
}
:root[data-theme="dark"][data-accent="graphite"] {
    --color-accent:       #A1A1AA;
    --color-accent-soft:  rgba(161, 161, 170, 0.16);
    --color-accent-hover: #BCBCC4;
    --color-accent-ring:  rgba(161, 161, 170, 0.32);
    --color-rail-active:  rgba(161, 161, 170, 0.22);
    --color-rail-active-fg:#BCBCC4;
}
:root[data-theme="dark"][data-accent="copper"] {
    --color-accent:       #D97A28;
    --color-accent-soft:  rgba(217, 122, 40, 0.16);
    --color-accent-hover: #E59B5B;
    --color-accent-ring:  rgba(217, 122, 40, 0.32);
    --color-rail-active:  rgba(217, 122, 40, 0.22);
    --color-rail-active-fg:#E59B5B;
}
/* The dark+slate combination is already correct via the dark base palette,
   so no override is needed for [data-theme="dark"][data-accent="slate"]. */

/* ----------------------------------------------------------------------------
   data-reduce-motion — disable transitions and animations.
   Honours an OS-level prefers-reduced-motion if the user hasn't set it.
   ---------------------------------------------------------------------------- */
:root[data-reduce-motion="1"] {
    --duration-hover: 0ms;
    --duration-enter: 0ms;
}

:root[data-reduce-motion="1"] *,
:root[data-reduce-motion="1"] *::before,
:root[data-reduce-motion="1"] *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
}

@media (prefers-reduced-motion: reduce) {
    :root:not([data-reduce-motion="0"]) {
        --duration-hover: 0ms;
        --duration-enter: 0ms;
    }
}

/* ----------------------------------------------------------------------------
   data-viewport — sixth axis. Set on <html> by App.razor's inline boot script
   and re-asserted on debounced window.resize by user-settings.js. Drives the
   mobile/tablet/desktop touch-target floor below and is consumed by primitives
   and shell components. See DOCS/Architecture/responsive-design.md.
   Values: mobile, mobile-l, tablet, tablet-l, desktop, desktop-xl.
   ---------------------------------------------------------------------------- */
:root[data-viewport="mobile"],
:root[data-viewport="mobile-l"] {
    /* Touch-target floor — Apple HIG / WCAG 2.5.5 AAA. Field/Button heights
       always meet 44px regardless of density or font-scale. */
    --h-button:     max(var(--touch-target), calc(20px + 1.4rem));
    --h-button-sm:  max(var(--touch-target), calc(14px + 1.4rem));
    --h-field:      max(var(--touch-target), calc(22px + 1.4rem));
    --h-field-tight:max(var(--touch-target), calc(14px + 1.4rem));
    --h-row:        max(56px, var(--h-row));
}

/* Display utility classes — escape hatch for one-off cases primitives don't
   cover. Use sparingly; primitives should handle the common reflow. Mirrors
   Bootstrap d-* responsive utilities but avoids importing the whole utility
   layer.

   Show-only logic: rather than force the element hidden by default and use
   `display: revert` to reveal it (which forces `display: block` and beats
   any layout-critical `display: flex/grid` on the same element), we only
   apply `display: none !important` at the WRONG breakpoints. At the right
   breakpoint the element renders with its natural display value. */
@media (min-width: 768px) {
    .show-mobile-only { display: none !important; }
}
@media (max-width: 767.98px), (min-width: 1200px) {
    .show-tablet-only { display: none !important; }
}
@media (max-width: 1199.98px) {
    .show-desktop-only { display: none !important; }
}

@media (max-width: 767.98px)   { .hide-mobile { display: none !important; } }
@media (max-width: 1199.98px)  { .hide-tablet-down { display: none !important; } }
@media (min-width: 1200px)     { .hide-desktop-up { display: none !important; } }

/* ----------------------------------------------------------------------------
   Mobile bottom-tab clearance — global page-root padding.

   The mobile bottom-tab strip is `position: fixed` at the bottom of the
   viewport and renders OVER the bottom of the scrollable page. Every
   page wrapper that scrolls inside `.orcanex-frame-content` needs an
   internal padding-bottom equal to the strip's full rendered height
   (60px + safe-area-inset on iOS) plus visual breathing room — without
   it, the last form field / row gets hidden behind the strip.

   The padding MUST live on the page WRAPPER (a block element, not the
   flex scroll container) — Chromium has a long-standing bug where
   padding-bottom on a `display: flex; overflow: auto;` container is
   NOT included in the scrollable area
   (https://bugs.chromium.org/p/chromium/issues/detail?id=748518). The
   user reported "can't scroll past the last field" on SpecialistForm,
   UserDetails and friends — that's exactly this bug. Putting the
   padding on the block child makes the child taller; the flex parent
   then naturally extends its scroll area to fit. No bug, no spacer
   tricks needed.

   Pages with their OWN internal scroll (e.g. `.orcanex-cases-page`
   uses an inner virtualised list that handles its own bottom inset)
   don't need this — when the page root is itself flex-fill-height and
   doesn't bubble scroll up to `.orcanex-frame-content`, the padding
   here is harmless (it pads a non-scrolling box).

   Belt-and-braces approach because the previous single-rule fixes
   didn't stick visually for the user:
     1. `padding-bottom` on the last direct child of frame-content
        (block element, no Chromium flex/padding bug).
     2. `::after` flex spacer on frame-content itself as a fallback
        when the page wrapper has `min-height: 100%` and the browser
        keeps its scroll region at exactly the parent height.
     3. `scroll-padding-bottom` on frame-content so any scroll-into-
        view calls also respect the bottom inset. */
:root[data-viewport="mobile"]   .orcanex-frame-content > *:last-child,
:root[data-viewport="mobile-l"] .orcanex-frame-content > *:last-child {
    padding-bottom: calc(var(--h-mobile-tabs) + env(safe-area-inset-bottom, 0px) + var(--space-4)) !important;
}

/* CRITICAL: target the INNER content wrapper, not the page wrapper.
   The user's dev tools confirmed `.orcanex-user-details-page` is
   clamped to ~591 px by `min-height: 100%` interacting with flex,
   while its CHILD `.orcanex-user-details-body` is the element whose
   box actually grows with content (1245 px in the user's case). The
   form fields live inside the body, so the body's bottom edge is
   what ends up clipped behind the bottom-tab strip — adding padding
   to the page wrapper above is useless because the body overflows
   it anyway.

   Pattern: apply the bottom inset to the element whose box grows
   with the content. For UserDetails that's `.orcanex-user-details-body`;
   for SpecialistForm that's `.orcanex-specialist-tab-content`; for
   ClientDetails the equivalent inner content wrapper. */
:root[data-viewport="mobile"]   .orcanex-user-details-body,
:root[data-viewport="mobile-l"] .orcanex-user-details-body,
:root[data-viewport="mobile"]   .orcanex-specialist-tab-content,
:root[data-viewport="mobile-l"] .orcanex-specialist-tab-content,
:root[data-viewport="mobile"]   .orcanex-client-details-content,
:root[data-viewport="mobile-l"] .orcanex-client-details-content {
    padding-bottom: calc(var(--h-mobile-tabs) + env(safe-area-inset-bottom, 0px) + var(--space-4)) !important;
}

/* Keep the page-wrapper rule as a fallback for pages that DO grow
   their wrapper with content (rather than clamping at viewport
   height). Harmless on pages where the wrapper is clamped — the
   padding is inside the clamped box and ignored. */
:root[data-viewport="mobile"]   .orcanex-user-details-page,
:root[data-viewport="mobile-l"] .orcanex-user-details-page,
:root[data-viewport="mobile"]   .orcanex-specialist-form,
:root[data-viewport="mobile-l"] .orcanex-specialist-form,
:root[data-viewport="mobile"]   .orcanex-client-details-page,
:root[data-viewport="mobile-l"] .orcanex-client-details-page,
:root[data-viewport="mobile"]   .orcanex-external-user-details-page,
:root[data-viewport="mobile-l"] .orcanex-external-user-details-page {
    padding-bottom: calc(var(--h-mobile-tabs) + env(safe-area-inset-bottom, 0px) + var(--space-4)) !important;
}

:root[data-viewport="mobile"]   .orcanex-frame-content::after,
:root[data-viewport="mobile-l"] .orcanex-frame-content::after {
    content: "" !important;
    display: block !important;
    flex-shrink: 0 !important;
    height: calc(var(--h-mobile-tabs) + env(safe-area-inset-bottom, 0px) + var(--space-4)) !important;
    width: 100% !important;
}

:root[data-viewport="mobile"]   .orcanex-frame-content,
:root[data-viewport="mobile-l"] .orcanex-frame-content {
    scroll-padding-bottom: calc(var(--h-mobile-tabs) + env(safe-area-inset-bottom, 0px) + var(--space-4)) !important;
    /* CACHE-BUSTER MARKER 2026-05-11-A — if you can't see this property
       in dev tools when inspecting `<main class="orcanex-frame-content">`,
       your browser is serving a cached tokens.css. */
    --bottom-tab-clearance: 76px;
}

/* ----------------------------------------------------------------------------
   Bootstrap legacy modals — mobile full-screen.

   `<OrcanexModal>` already goes full-screen at mobile via its own scoped CSS.
   This block does the same for any raw Bootstrap `.modal-dialog` markup that
   hasn't been migrated yet. Apply globally so we don't have to copy these
   overrides into every page that hosts a legacy modal.

   The recipe (and the two common mistakes) is documented in
   DOCS/Architecture/responsive-design.md under "Modal full-screen at mobile
   (Bootstrap legacy)". Per-page overrides can still raise specificity for
   bespoke needs, but the default mobile experience is now sane.
   ---------------------------------------------------------------------------- */
:root[data-viewport="mobile"]   .modal-dialog,
:root[data-viewport="mobile-l"] .modal-dialog {
    max-width: 100% !important;
    width: 100%;
    margin: 0 !important;
    height: 100dvh;
    max-height: 100dvh;
}

/* Bootstrap's `.modal-dialog-centered` adds `align-items: center` which
   vertically centers a short modal-content within the full-height dialog.
   Override to `stretch` so content fills the dialog. */
:root[data-viewport="mobile"]   .modal-dialog-centered,
:root[data-viewport="mobile-l"] .modal-dialog-centered {
    align-items: stretch !important;
}

/* Modal-content fills the dialog; flex-column so body grows and footer
   shrinks. Body's `max-height: none` lifts any desktop-era `Nvh` cap that
   would otherwise prevent flex-grow (a common pattern in older modal CSS). */
:root[data-viewport="mobile"]   .modal-dialog .modal-content,
:root[data-viewport="mobile-l"] .modal-dialog .modal-content {
    height: 100%;
    border-radius: 0;
    border: none;
    display: flex;
    flex-direction: column;
}

/* Common pattern: `<EditForm>` (which Blazor renders as `<form>`) wraps
   both `.modal-body` and `.modal-footer` so the submit button can post the
   form. The form then becomes the direct child of `.modal-content`, and
   the body/footer aren't direct children of any flex container — so the
   `flex: 1 1 auto` on body and `flex-shrink: 0` on footer don't kick in,
   body collapses to content height, and the footer drifts mid-modal with
   form fields overflowing into the backdrop.

   Fix: any single wrapper element (`<form>`, `<EditForm>` → `<form>`,
   plain `<div>`) that sits as a direct child of `.modal-content` becomes
   a flex-column of its own, transparently passing the flex context down
   to the body/footer it wraps. Body still grows, footer still pins. */
:root[data-viewport="mobile"]   .modal-dialog .modal-content > form,
:root[data-viewport="mobile-l"] .modal-dialog .modal-content > form,
:root[data-viewport="mobile"]   .modal-dialog .modal-content > .modal-content-wrap,
:root[data-viewport="mobile-l"] .modal-dialog .modal-content > .modal-content-wrap {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

:root[data-viewport="mobile"]   .modal-dialog .modal-content .modal-body,
:root[data-viewport="mobile-l"] .modal-dialog .modal-content .modal-body {
    flex: 1 1 auto;
    max-height: none !important;
    overflow-y: auto;
    min-height: 0;
}

/* Footer flush at the bottom via flex (NOT `position: sticky` — sticky only
   activates on overflow, leaving the footer floating mid-modal on short
   forms). iOS safe-area-inset for the home bar. */
:root[data-viewport="mobile"]   .modal-dialog .modal-content .modal-footer,
:root[data-viewport="mobile-l"] .modal-dialog .modal-content .modal-footer {
    flex-shrink: 0;
    background: var(--color-panel);
    border-top: 1px solid var(--color-border);
    padding: var(--space-3) var(--space-4);
    padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
}

/* ----------------------------------------------------------------------------
   data-high-contrast — boost border darkness, deepen muted text, thicker focus.
   ---------------------------------------------------------------------------- */
:root[data-high-contrast="1"] {
    --color-border:       #B5BAC4;
    --color-border-soft:  #C8CCD3;
    --color-text-muted:   #4B5260;
    --color-text-subtle:  #6B7280;
}
:root[data-theme="dark"][data-high-contrast="1"] {
    --color-border:       #4D5666;
    --color-border-soft:  #3C4452;
    --color-text-muted:   #C8CCD3;
    --color-text-subtle:  #9AA0AA;
}

:root[data-high-contrast="1"] :focus-visible {
    outline-width: 3px !important;
    outline-offset: 2px;
}

/* ----------------------------------------------------------------------------
   App-wide font + reset.
   The Hyper theme's app-modern.css sets font-family on body — we override here
   so Inter wins until Hyper is removed in Phase 11.
   ---------------------------------------------------------------------------- */
/* Root font-size = 13px baseline. Overridden by data-font-scale (above) so
   `rem`-based type-ramp utilities (.t-h1, .t-body etc.) scale automatically.
   Body inherits from html so the cascade isn't broken by an explicit body
   font-size. */
html { font-size: 14px; }   /* rem baseline — overridden by [data-font-scale] above */

html,
body {
    margin: 0;
    padding: 0;
    font-family: var(--font-family);
    line-height: 1.5;
    color: var(--color-text);
    background: var(--color-bg);
}

/* Tabular numerics for any list/table cell */
.orcanex-num,
.orcanex-list td,
.orcanex-list th {
    font-variant-numeric: tabular-nums;
}

/* Type ramp utility classes — rem-based so they scale with data-font-scale
   (medium baseline = 13px; small=12, large=14, xlarge=16). */
.t-display-l   { font-size: 2.77rem; font-weight: 600; line-height: 1.15; letter-spacing: -0.6px; }   /* ≈36px */
.t-h1          { font-size: 1.69rem; font-weight: 600; line-height: 1.25; letter-spacing: -0.3px; }   /* ≈22px */
.t-h2          { font-size: 1.38rem; font-weight: 600; line-height: 1.3;  }                          /* ≈18px */
.t-h3          { font-size: 1.08rem; font-weight: 600; line-height: 1.4;  }                          /* ≈14px */
.t-body        { font-size: 1rem;    font-weight: 400; line-height: 1.5;  }                          /* =13px */
.t-body-strong { font-size: 1rem;    font-weight: 600; line-height: 1.5;  }
.t-label       { font-size: 0.92rem; font-weight: 500; line-height: 1.4;  }                          /* ≈12px */
.t-meta        { font-size: 0.85rem; font-weight: 500; line-height: 1.4;  color: var(--color-text-muted); }   /* ≈11px */
.t-kicker      { font-size: 0.85rem; font-weight: 600; line-height: 1.4;  letter-spacing: 1.2px; text-transform: uppercase; color: var(--color-text-muted); }
.t-mono        { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Focus ring — never remove default focus, just restyle */
.orcanex-focus:focus-visible,
.orcanex-focus:focus-within {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* Suppress focus rings for programmatic .focus() calls — keyboard users
   still see the ring via :focus-visible. */
:focus:not(:focus-visible) {
    outline: none;
}

/* Headings are never interactive, but Blazor's <FocusOnNavigate Selector="h1">
   in Routes.razor programmatically focuses the page heading after every
   navigation so screen readers announce the new page. Chrome treats focus on
   page-load as :focus-visible (no prior mouse interaction to disqualify it),
   so we have to suppress the outline explicitly on headings — including
   :focus-visible — to stop the black border appearing around the page title.
   Keyboard users tabbing the page never reach a non-interactive heading
   anyway because it's not in the tab order. */
h1:focus, h1:focus-visible,
h2:focus, h2:focus-visible,
h3:focus, h3:focus-visible,
h4:focus, h4:focus-visible,
h5:focus, h5:focus-visible,
h6:focus, h6:focus-visible {
    outline: none;
}

/* Hover lift — used on rows and cards */
.orcanex-hover:hover {
    background: var(--color-bg);
    transition: background var(--duration-hover) var(--ease-hover);
}

/* ============================================================================
   Bootstrap / Hyper retrofit overrides.
   The big-bang migration keeps Bootstrap markup on legacy pages but repaints
   the common utility classes with Orcanex tokens. Pages that already use
   Orcanex primitives (Btn, Card, Pill, Field) ignore these — primitives win
   via class specificity.
   ============================================================================ */

/* Surface */
body, .content-page, .wrapper {
    background: var(--color-bg) !important;
}

/* Cards */
.card {
    background: var(--color-panel);
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: none !important;
}
.card.shadow-sm {
    box-shadow: none !important;
}
.card-header {
    background: var(--color-panel) !important;
    border-bottom: 1px solid var(--color-border-soft) !important;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
    padding: 12px 16px !important;
    font-size: 1.08rem !important;
    font-weight: 600 !important;
    color: var(--color-text) !important;
}
.card-body { padding: 16px; }
.card-footer {
    background: var(--color-panel) !important;
    border-top: 1px solid var(--color-border-soft) !important;
}

/* Buttons */
.btn {
    border-radius: var(--radius-md) !important;
    font-weight: 500 !important;
    font-size: 1rem !important;
    padding: 0 12px !important;
    height: var(--h-button);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    line-height: 1;
    transition: background var(--duration-hover) var(--ease-hover),
                border-color var(--duration-hover) var(--ease-hover),
                color var(--duration-hover) var(--ease-hover);
}
.btn-sm, .btn-group-sm > .btn {
    height: var(--h-button-sm);
    padding: 0 10px !important;
    font-size: 0.92rem !important;
}
.btn-primary {
    background: var(--color-accent) !important;
    border-color: var(--color-accent) !important;
    color: #fff !important;
}
.btn-primary:hover, .btn-primary:focus {
    background: var(--color-accent-hover) !important;
    border-color: var(--color-accent-hover) !important;
    color: #fff !important;
}
.btn-outline-primary {
    color: var(--color-accent) !important;
    border-color: var(--color-border) !important;
    background: var(--color-panel) !important;
}
.btn-outline-primary:hover {
    background: var(--color-accent-soft) !important;
    color: var(--color-accent) !important;
    border-color: var(--color-accent) !important;
}
.btn-secondary, .btn-light, .btn-outline-secondary {
    background: var(--color-panel) !important;
    border-color: var(--color-border) !important;
    color: var(--color-text) !important;
}
.btn-secondary:hover, .btn-light:hover, .btn-outline-secondary:hover {
    background: var(--color-bg) !important;
    border-color: var(--color-border) !important;
    color: var(--color-text) !important;
}
.btn-success {
    background: var(--color-success) !important;
    border-color: var(--color-success) !important;
    color: #fff !important;
}
.btn-warning {
    background: var(--color-warn) !important;
    border-color: var(--color-warn) !important;
    color: #fff !important;
}
.btn-danger {
    background: var(--color-danger) !important;
    border-color: var(--color-danger) !important;
    color: #fff !important;
}
.btn-outline-danger {
    color: var(--color-danger) !important;
    border-color: var(--color-border) !important;
    background: var(--color-panel) !important;
}
.btn-outline-danger:hover {
    background: var(--color-danger-soft) !important;
    color: var(--color-danger) !important;
    border-color: var(--color-danger) !important;
}
.btn-link {
    color: var(--color-accent) !important;
    text-decoration: none !important;
}
.btn-link:hover { text-decoration: underline !important; }

/* Badges */
.badge {
    font-weight: 500 !important;
    font-size: 0.85rem !important;
    padding: 2px 8px !important;
    border-radius: var(--radius-pill) !important;
    line-height: 1.4;
    letter-spacing: 0.1px;
}
.badge.bg-primary, .bg-primary { background: var(--color-accent-soft) !important; color: var(--color-accent) !important; }
.badge.bg-success, .bg-success { background: var(--color-success-soft) !important; color: var(--color-success) !important; }
.badge.bg-warning, .bg-warning { background: var(--color-warn-soft) !important; color: var(--color-warn) !important; }
.badge.bg-danger, .bg-danger   { background: var(--color-danger-soft) !important; color: var(--color-danger) !important; }
.badge.bg-info,    .bg-info    { background: var(--color-accent-soft) !important; color: var(--color-accent) !important; }
.badge.bg-secondary, .bg-secondary { background: #F1F3F6 !important; color: #3B414B !important; }
.badge.bg-light    { background: var(--color-bg) !important; color: var(--color-text) !important; }

/* Form fields */
.form-control, .form-select {
    height: var(--h-field);
    padding: 0 12px !important;
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-md) !important;
    background: var(--color-panel) !important;
    color: var(--color-text) !important;
    font-size: 1rem !important;
    line-height: 1.4;
    box-shadow: none !important;
    transition: border-color var(--duration-hover) var(--ease-hover);
}
textarea.form-control { height: auto; min-height: 80px; padding: 8px 12px !important; }

/* Native file inputs need the button to fill the full input height — without
   this rule the "Choose file" button + filename hug the top of the box and
   leave dead space below. Bootstrap's vendor CSS sets a NEGATIVE margin on
   ::file-selector-button (margin: -.45rem -.9rem) so the button fills the
   parent's padding-box. Because our global .form-control has padding: 0 12px,
   the button's negative top-margin pulls it above the box. We override both:
   reset the parent padding/layout AND zero-out the button's negative margin. */
.form-control[type="file"] {
    padding: 0 !important;
    display: inline-flex !important;
    align-items: stretch !important;
    overflow: hidden;
    cursor: pointer;
    line-height: 1 !important;
}
.form-control[type="file"]::file-selector-button {
    margin: 0 12px 0 0 !important;
    margin-inline-end: 12px !important;
    padding: 0 14px !important;
    height: auto !important;
    align-self: stretch;
    border: 0 !important;
    border-right: 1px solid var(--color-border) !important;
    border-inline-end: 1px solid var(--color-border) !important;
    background-color: var(--color-bg) !important;
    color: var(--color-text) !important;
    font-family: var(--font-family) !important;
    font-size: 1rem !important;
    font-weight: 500 !important;
    line-height: var(--h-field) !important;
    cursor: pointer;
    transition: background-color var(--duration-hover) var(--ease-hover), color var(--duration-hover) var(--ease-hover);
}
.form-control[type="file"]::-webkit-file-upload-button {
    margin: 0 12px 0 0 !important;
    padding: 0 14px !important;
    height: auto !important;
    border: 0 !important;
    border-right: 1px solid var(--color-border) !important;
    background-color: var(--color-bg) !important;
    color: var(--color-text) !important;
    font-family: var(--font-family) !important;
    font-size: 1rem !important;
    font-weight: 500 !important;
    line-height: var(--h-field) !important;
    cursor: pointer;
}
.form-control[type="file"]::file-selector-button:hover {
    background-color: var(--color-accent-soft) !important;
    color: var(--color-accent) !important;
}
.form-control[type="file"]::-webkit-file-upload-button:hover {
    background-color: var(--color-accent-soft) !important;
    color: var(--color-accent) !important;
}
.form-control[type="file"]:disabled,
.form-control[type="file"][disabled] {
    cursor: not-allowed;
}
.form-control[type="file"]:disabled::file-selector-button {
    cursor: not-allowed;
    opacity: 0.6;
}
.form-control-sm, .form-select-sm {
    height: var(--h-button-sm);
    padding: 0 10px !important;
    font-size: 0.92rem !important;
}
.form-control:focus, .form-select:focus {
    outline: none !important;
    border-color: var(--color-accent) !important;
    box-shadow: 0 0 0 3px var(--color-accent-ring) !important;
}
.form-control::placeholder, .form-select::placeholder {
    color: var(--color-text-subtle);
}
.form-label {
    font-size: 0.92rem !important;
    font-weight: 500 !important;
    color: var(--color-text) !important;
    margin-bottom: 6px;
}
.input-group-text {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.92rem;
}

/* Tables */
.table {
    --bs-table-bg: var(--color-panel);
    --bs-table-color: var(--color-text);
    --bs-table-border-color: var(--color-border-soft);
    font-size: 1rem;
    color: var(--color-text);
}
.table > thead {
    background: var(--color-bg);
}
.table > thead th {
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border) !important;
    padding: 10px 12px;
}
.table tbody tr:hover {
    background: var(--color-bg);
}
.table tbody td {
    padding: 10px 12px;
    border-color: var(--color-border-soft);
    vertical-align: middle;
}

/* Alerts */
.alert {
    border-radius: var(--radius-md) !important;
    border: none !important;
    padding: 10px 12px !important;
    font-size: 1rem !important;
    line-height: 1.45;
}
.alert-success { background: var(--color-success-soft) !important; color: var(--color-success) !important; }
.alert-warning { background: var(--color-warn-soft) !important;    color: var(--color-warn) !important; }
.alert-danger  { background: var(--color-danger-soft) !important;  color: var(--color-danger) !important; }
.alert-info    { background: var(--color-accent-soft) !important;  color: var(--color-accent) !important; }

/* Modals — Bootstrap modal markup */
.modal-content {
    border-radius: var(--radius-lg) !important;
    border: 1px solid var(--color-border) !important;
    box-shadow: var(--shadow-modal) !important;
}
.modal-header {
    border-bottom: 1px solid var(--color-border) !important;
    padding: 14px 18px !important;
}
.modal-header .modal-title {
    font-size: 1.08rem !important;
    font-weight: 600 !important;
    color: var(--color-text) !important;
}
.modal-body { padding: 18px !important; font-size: 1rem; line-height: 1.55; }
.modal-footer { border-top: 1px solid var(--color-border) !important; padding: 12px 18px !important; gap: 8px; }

/* Pagination */
.page-link {
    border: 1px solid var(--color-border);
    color: var(--color-text);
    border-radius: var(--radius-sm) !important;
    margin: 0 2px;
    background: var(--color-panel);
}
.page-item.active .page-link {
    background: var(--color-accent);
    border-color: var(--color-accent);
}

/* Nav tabs / pills */
.nav-tabs {
    border-bottom: 1px solid var(--color-border-soft);
}
.nav-tabs .nav-link {
    border: none;
    color: var(--color-text-muted);
    font-size: 1rem;
    font-weight: 500;
    padding: 8px 14px;
    border-bottom: 2px solid transparent;
}
.nav-tabs .nav-link:hover {
    background: transparent;
    color: var(--color-text);
    border-bottom-color: var(--color-border);
}
.nav-tabs .nav-link.active {
    color: var(--color-accent);
    font-weight: 600;
    border-bottom-color: var(--color-accent);
    background: transparent;
}

.nav-pills .nav-link {
    border-radius: var(--radius-md);
    color: var(--color-text);
    font-size: 1rem;
    font-weight: 500;
    padding: 6px 12px;
}
.nav-pills .nav-link.active {
    background: var(--color-accent-soft);
    color: var(--color-accent);
}

/* Dropdowns */
.dropdown-menu {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-overlay);
    padding: 4px;
    font-size: 1rem;
}
.dropdown-item {
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    color: var(--color-text);
}
.dropdown-item:hover, .dropdown-item:focus {
    background: var(--color-bg);
    color: var(--color-text);
}
.dropdown-item.active, .dropdown-item:active {
    background: var(--color-accent-soft) !important;
    color: var(--color-accent) !important;
}

/* Page surface containers — pages typically wrap in container-fluid + content */
.content-page > .content {
    padding: 0;
}
.container-fluid { padding-left: 16px; padding-right: 16px; }

/* ----------------------------------------------------------------------------
   Master-data list pages — shared page-shell chrome that mirrors the
   Cases / Specialists list-page pattern.

   Master-data pages (Configuration/* and CRM/*) used to wrap their content
   in legacy Bootstrap `<div class="content"><div class="container-fluid">`,
   which produced an extra box + visible border around the inner Card that
   didn't match the Cases page (the theme default). `.orcanex-masterdata-page`
   replaces both legacy wrappers with a single flex-column shell, and a
   direct-child rule below gives the page's Card the same side / top /
   bottom margin the Cases content area uses — without affecting the
   page-header chrome above, which keeps its edge-to-edge panel bar. */
.orcanex-masterdata-page {
    display: flex;
    flex-direction: column;
    flex: 1;
}

/* The Card hosting the table sits flush against the page-header above;
   give it the same 14/24/24 inset that .orcanex-cases-content uses so
   master-data and Cases pages share a visual rhythm.

   Strip the Card's panel chrome (background / border / border-radius) on
   master-data pages — the table inside (.orcanex-mdtable) renders its
   own header band + per-row borders, so the outer Card frame produced a
   visible "extra box" double-border effect the user flagged. Keeping the
   .orcanex-card class on the markup but nulling its visible chrome means
   we don't have to refactor 28 pages to drop the primitive; the Cases
   page (the theme default) doesn't wrap its rows in a Card and now
   master-data renders the same way visually. */
.orcanex-masterdata-page > .orcanex-card {
    margin: 14px 24px 24px;
    background: transparent;
    border: 0;
    border-radius: 0;
}

/* Mobile: tighter side-margin so the table hugs the viewport edges, exactly
   like the Cases rows do at mobile. */
:root[data-viewport="mobile"]   .orcanex-masterdata-page > .orcanex-card,
:root[data-viewport="mobile-l"] .orcanex-masterdata-page > .orcanex-card {
    margin: var(--space-2);
}

/* Old leftbar / topbar — disable everything from Hyper that we no longer use */
.leftside-menu,
.navbar-custom,
.topbar,
.footer { display: none !important; }
.wrapper { display: block; padding: 0; margin: 0; }
.wrapper .content-page {
    margin: 0 !important;
    padding: 0 !important;
    min-height: auto;
}

/* ============================================================================
   Common page-internal class retrofits (custom classes we keep)
   ============================================================================ */

/* Welcome cards (Dashboard) */
.welcome-card {
    background: var(--color-panel) !important;
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-lg) !important;
    box-shadow: none !important;
    padding: 16px 20px !important;
    color: var(--color-text);
}
.welcome-card .welcome-title { font-size: 1.38rem; font-weight: 600; color: var(--color-text); margin: 0 0 4px; letter-spacing: -0.2px; }
.welcome-card .welcome-subtitle { font-size: 1rem; color: var(--color-text-muted); margin: 0; }

/* Stats cards (AdminDashboard / mini KPIs) */
.stats-card {
    background: var(--color-panel) !important;
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-lg) !important;
    padding: 14px 16px !important;
    display: flex;
    align-items: center;
    gap: 12px;
    box-shadow: none !important;
    transition: border-color var(--duration-hover) var(--ease-hover);
}
.stats-card:hover { border-color: var(--color-accent); }
.stats-card-warning { border-color: var(--color-warn) !important; }
.stats-card-danger { border-color: var(--color-danger) !important; }
.stats-card .stats-icon {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: var(--color-accent-soft);
    color: var(--color-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.38rem;
    flex-shrink: 0;
}
.stats-card .stats-content { min-width: 0; }
.stats-card .stats-value {
    font-size: 1.69rem;
    font-weight: 600;
    line-height: 1.1;
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.3px;
}
.stats-card .stats-label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin-top: 2px;
}

.mini-stat-card {
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 10px 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.mini-stat-card .mini-stat-label {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--color-text-muted);
}
.mini-stat-card .mini-stat-value { font-size: 1rem; font-weight: 600; color: var(--color-text); }

/* Search inputs in headers (cases/clients/users etc.) */
.cases-header-search,
.clients-header-search,
.users-header-search,
.specialists-header-search {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.cases-header-search-icon,
.clients-header-search-icon,
.users-header-search-icon,
.specialists-header-search-icon {
    position: absolute;
    left: 10px;
    color: var(--color-text-muted);
    font-size: 1.08rem;
    pointer-events: none;
}

.cases-header-search-input,
.clients-header-search-input,
.users-header-search-input,
.specialists-header-search-input {
    padding-left: 30px !important;
    width: 280px !important;
    background: var(--color-panel) !important;
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-md) !important;
    height: 30px !important;
    font-size: 1rem !important;
    transition: border-color var(--duration-hover) var(--ease-hover);
}

.cases-header-search-input:focus,
.clients-header-search-input:focus,
.users-header-search-input:focus,
.specialists-header-search-input:focus {
    border-color: var(--color-accent) !important;
    box-shadow: 0 0 0 3px var(--color-accent-ring) !important;
}

.cases-header-search-clear,
.clients-header-search-clear,
.users-header-search-clear,
.specialists-header-search-clear {
    position: absolute;
    right: 8px;
    background: transparent;
    border: none;
    color: var(--color-text-muted);
    cursor: pointer;
    padding: 0;
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
}

/* Status pipeline bar (Cases legacy — kept for cases not yet migrated) */
.status-pipeline-bar {
    display: flex !important;
    gap: 0 !important;
    background: var(--color-panel) !important;
    border: 1px solid var(--color-border) !important;
    border-radius: var(--radius-lg) !important;
    overflow: hidden !important;
    margin-bottom: 12px !important;
    box-shadow: none !important;
}
.pipeline-stat {
    flex: 1;
    padding: 10px 14px !important;
    border-right: 1px solid var(--color-border-soft) !important;
    background: transparent !important;
    cursor: pointer;
    position: relative;
}
.pipeline-stat:last-child { border-right: none; }
.pipeline-stat:hover { background: var(--color-bg) !important; }
.pipeline-stat.active::after {
    content: "";
    position: absolute;
    inset: auto 0 -1px;
    height: 2px;
    background: var(--pipeline-color, var(--color-accent));
}
.pipeline-stat .pipeline-label {
    font-size: 0.77rem !important;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 600;
    color: var(--pipeline-color, var(--color-text-muted)) !important;
}
.pipeline-stat .pipeline-value {
    font-size: 1.69rem !important;
    font-weight: 600 !important;
    color: var(--color-text) !important;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.3px;
}
.pipeline-stat .pipeline-progress {
    height: 4px !important;
    background: var(--color-border-soft) !important;
    border-radius: 2px;
    overflow: hidden;
    margin-top: 6px;
}
.pipeline-stat .pipeline-progress-fill {
    height: 100% !important;
    background: var(--pipeline-color, var(--color-accent)) !important;
}
.pipeline-total {
    flex: 1;
    padding: 10px 14px !important;
    background: var(--color-bg) !important;
}
.pipeline-total .pipeline-value-total {
    font-size: 1.69rem;
    font-weight: 600;
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
}

/* Status pills inside list rows (cases, etc.) */
.status-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px !important;
    border-radius: var(--radius-pill) !important;
    font-size: 0.85rem !important;
    font-weight: 500 !important;
    line-height: 1.4;
    letter-spacing: 0.1px;
    border: 1px solid var(--color-border) !important;
}

/* Loading spinner inline (Hyper's custom one) */
.loading-spinner-inline {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.spinner-ring-inline {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-accent);
    animation: orcanex-bounce 1.2s ease-in-out infinite;
}
.spinner-ring-inline:nth-child(2) { animation-delay: 0.15s; }
.spinner-ring-inline:nth-child(3) { animation-delay: 0.3s; }
@keyframes orcanex-bounce {
    0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
    40% { transform: translateY(-6px); opacity: 1; }
}

/* Avatar circles (legacy specialist-avatar, examinee-avatar etc.) */
.specialist-avatar,
.examinee-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    color: white;
    font-weight: 600;
    font-size: 0.77rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--color-panel);
    flex-shrink: 0;
}
.team-avatars { display: inline-flex; align-items: center; }
.team-avatars > * + * { margin-left: -8px; }
.specialist-more { background: var(--color-text-muted) !important; }

/* ============================================================================
   ORCANEX FORM PATTERN — the standard form-field layout used across the app.
   See CLAUDE.md / copilot-instructions.md "UI Design System" for the spec.

   Visual language:
     [icon-box]  4px gap  [field]
     - both have their own 1px border + 8px radius
     - icon-box is a square equal to the field height
     - field height: 32px (default) / 28px (tight) — controlled by .orcanex-form-grid
     - focus ring: var(--color-accent) border + 3px accent-soft glow on the field
     - select: a chevron carat appears on the right via background-image
   ============================================================================ */

/* Input group — icon-box prefix sits next to a flex input, both bordered. */
.orcanex-igroup {
    display: flex;
    align-items: stretch;
    gap: 4px;
    width: 100%;
    min-width: 0;
}

.orcanex-igroup-prefix,
.orcanex-igroup-suffix {
    height: var(--h-field);
    min-width: var(--h-field);
    padding: 0 8px;
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: 0.92rem;
    flex-shrink: 0;
    gap: 6px;
}

.orcanex-igroup-prefix-mono {
    font-family: var(--font-mono);
    font-weight: 600;
}

.orcanex-igroup-input {
    flex: 1;
    min-width: 0;
}

/* The input/select inside an igroup keeps its own border for the "two adjacent
   bordered boxes" look. */
.orcanex-igroup .form-control,
.orcanex-igroup .form-select,
.orcanex-igroup input[type="text"],
.orcanex-igroup input[type="email"],
.orcanex-igroup input[type="tel"],
.orcanex-igroup input[type="date"],
.orcanex-igroup input[type="number"],
.orcanex-igroup input[type="search"] {
    flex: 1;
    min-width: 0;
}

/* Form grid — N-column layout for fields inside a card body. Default
   gap is 10px vertical / 16px horizontal. The -tight modifier collapses
   field height + font for case-form density. */
.orcanex-form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px 16px;
    min-width: 0;
}
.orcanex-form-grid-1 { grid-template-columns: 1fr; }
.orcanex-form-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.orcanex-form-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.orcanex-form-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Span helpers for individual fields that need to break the grid (e.g. a
   full-width textarea inside a 3-col grid). */
.orcanex-form-grid > .span-2 { grid-column: span 2; }
.orcanex-form-grid > .span-3 { grid-column: span 3; }
.orcanex-form-grid > .span-4 { grid-column: span 4; }

/* Responsive collapse: 3+ cols → 2 on tablet, all → 1 on mobile.
   Span helpers also clamp so a `.span-2` inside a 1-col grid doesn't break.
   Bootstrap-aligned breakpoints — see DOCS/Architecture/responsive-design.md. */
@media (max-width: 1199.98px) {
    .orcanex-form-grid-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 991.98px) {
    .orcanex-form-grid-3,
    .orcanex-form-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .orcanex-form-grid > .span-3,
    .orcanex-form-grid > .span-4 { grid-column: span 2; }
}
@media (max-width: 575.98px) {
    .orcanex-form-grid-2,
    .orcanex-form-grid-3,
    .orcanex-form-grid-4 { grid-template-columns: 1fr; }
    .orcanex-form-grid > .span-2,
    .orcanex-form-grid > .span-3,
    .orcanex-form-grid > .span-4 { grid-column: span 1; }
}

/* Tight density variant — used inside .orcanex-form-grid-tight (case form,
   specialist form, configuration pages). At the default user density (compact)
   this collapses to 28px / 12.5px so sections fit more rows on screen. The
   --h-field-tight / --font-tight-* tokens scale with the user's density
   preference (data-density) so a user who picks comfortable/large still gets
   bigger fields on tight forms — proportionally smaller than the standard
   form, but never the original cramped 28px. */
.orcanex-form-grid-tight {
    --h-field: var(--h-field-tight);
}
.orcanex-form-grid-tight .orcanex-igroup-prefix,
.orcanex-form-grid-tight .orcanex-igroup-suffix {
    height: var(--h-field-tight);
    min-width: var(--h-field-tight);
}
.orcanex-form-grid-tight .form-control,
.orcanex-form-grid-tight .form-select,
.orcanex-form-grid-tight input,
.orcanex-form-grid-tight select,
.orcanex-form-grid-tight textarea {
    height: var(--h-field-tight) !important;
    font-size: var(--font-tight-field) !important;
}
.orcanex-form-grid-tight textarea {
    height: auto !important;
    min-height: var(--h-textarea-tight-min);
}
.orcanex-form-grid-tight .orcanex-field-label {
    font-size: var(--font-tight-label) !important;
    font-weight: 600 !important;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

/* Dropdown carat — every <select.form-select> gets a chevron-down icon on
   the right via SVG data-URI. This is the standard regardless of where the
   select renders. */
.form-select {
    appearance: none !important;
    -webkit-appearance: none !important;
    -moz-appearance: none !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: right 10px center !important;
    background-size: 14px !important;
    padding-right: 30px !important;
}

/* Read-only / display-mode appearance for form fields. When the page is in
   read-only mode, every input/select/textarea should flatten visually:
   muted background, muted text, no dropdown carat. This is the "display
   mode" look that signals the field is not editable. */
.form-control:disabled,
.form-select:disabled,
.form-control[readonly],
.form-select[readonly] {
    background-color: var(--color-bg) !important;
    color: var(--color-text-muted) !important;
    cursor: default !important;
    opacity: 1 !important;
}
.form-select:disabled {
    background-image: none !important;
    padding-right: 10px !important;
}

/* Field card titlebar — the standard "icon-box + label + optional action"
   row at the top of every card body. Replaces the heavy SectionCard header. */
.orcanex-card-titlebar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: var(--space-3);
    font-size: 1.04rem;
    font-weight: 600;
    color: var(--color-text);
}

.orcanex-card-titlebar-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.orcanex-card-titlebar > .orcanex-btn,
.orcanex-card-titlebar > .orcanex-card-titlebar-action {
    margin-left: auto;
}

/* Coloured icon-box that prefixes the card title. The variant determines the
   tint (default = accent, blue, amber, red, success). */
.orcanex-card-titlebar-icon {
    width: 22px;
    height: 22px;
    border-radius: var(--radius-sm);
    background: var(--color-accent-soft);
    color: var(--color-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.orcanex-card-titlebar-icon-blue    { background: var(--color-accent-soft);  color: var(--color-accent); }
.orcanex-card-titlebar-icon-amber   { background: var(--color-warn-soft);    color: var(--color-warn); }
.orcanex-card-titlebar-icon-red     { background: var(--color-danger-soft);  color: var(--color-danger); }
.orcanex-card-titlebar-icon-success { background: var(--color-success-soft); color: var(--color-success); }

/* Country picker prefix — used on phone fields. Renders a small flag + a
   native <select> for the dial code, all inside the standard prefix box.
   The select keeps its native chevron so the country picker is obviously
   interactive. */
.orcanex-igroup-prefix-country {
    padding: 0 !important;
    overflow: hidden;
    gap: 4px;
}
.orcanex-igroup-prefix-country .orcanex-country-flag {
    width: 18px;
    height: 13px;
    margin-left: 8px;
    object-fit: cover;
    border-radius: 2px;
    flex-shrink: 0;
    background: var(--color-bg);
}
.orcanex-igroup-prefix-country .orcanex-country-flag-fallback {
    width: 22px;
    height: 14px;
    margin-left: 6px;
    border-radius: 2px;
    background: var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.69rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    letter-spacing: 0.4px;
}
.orcanex-igroup-prefix-country select {
    border: none !important;
    background: transparent !important;
    background-image: none !important;
    appearance: auto !important;
    -webkit-appearance: menulist !important;
    -moz-appearance: menulist !important;
    font-family: var(--font-mono);
    font-size: 0.92rem;
    color: var(--color-text);
    cursor: pointer;
    padding: 0 4px !important;
    height: 100% !important;
    box-shadow: none !important;
    outline: none;
    width: auto !important;
}
.orcanex-igroup-prefix-country select:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

/* ============================================================================
   ORCANEX BUTTON — promoted from Btn.razor.css to global so raw <button>
   markup with .orcanex-btn classes (e.g. <button type="submit" form="…">
   that can't go through the Btn component) still picks up styling.
   ============================================================================ */
.orcanex-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    font-family: inherit;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    line-height: 1;
    transition: background var(--duration-hover) var(--ease-hover),
                color var(--duration-hover) var(--ease-hover),
                border-color var(--duration-hover) var(--ease-hover);
}

.orcanex-btn-md {
    height: var(--h-button);
    padding: 0 12px;
    font-size: 1rem;
}

.orcanex-btn-sm {
    height: var(--h-button-sm);
    padding: 0 10px;
    font-size: 0.92rem;
    gap: 5px;
}

.orcanex-btn-default {
    background: var(--color-panel);
    color: var(--color-text);
    border-color: var(--color-border);
}
.orcanex-btn-default:hover:not(:disabled) {
    background: var(--color-bg);
}

.orcanex-btn-ghost {
    background: transparent;
    color: var(--color-text-muted);
}
.orcanex-btn-ghost:hover:not(:disabled) {
    background: var(--color-bg);
    color: var(--color-text);
}

.orcanex-btn-primary {
    background: var(--color-accent);
    color: #fff;
    border-color: var(--color-accent);
}
.orcanex-btn-primary:hover:not(:disabled) {
    background: var(--color-accent-hover);
    border-color: var(--color-accent-hover);
}

.orcanex-btn-soft {
    background: var(--color-accent-soft);
    color: var(--color-accent);
}
.orcanex-btn-soft:hover:not(:disabled) {
    background: #DBE5FF;
}

.orcanex-btn-danger {
    background: var(--color-danger);
    color: #fff;
    border-color: var(--color-danger);
}
.orcanex-btn-danger:hover:not(:disabled) {
    background: #A12A24;
    border-color: #A12A24;
}

.orcanex-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ============================================================================
   Global page-header layout (used by Cases.razor + CompactPageHeader rewrite +
   any page that renders <div class="orcanex-page-header"> directly).
   These were originally scoped inside PageHeader.razor.css; promoting them
   here makes them apply wherever the markup appears.
   ============================================================================ */

.orcanex-page-header {
    padding: 16px 28px 14px;
    background: var(--color-panel);
    border-bottom: 1px solid var(--color-border);
}

.orcanex-page-header-crumbs {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.92rem;
    color: var(--color-text-muted);
    margin-bottom: 6px;
}

.orcanex-page-header-crumb {
    color: var(--color-text-muted);
    text-decoration: none;
}
.orcanex-page-header-crumb:hover { color: var(--color-text); }
.orcanex-page-header-crumb-active { color: var(--color-text); font-weight: 500; }
.orcanex-page-header-crumb-sep { color: var(--color-text-subtle); }

.orcanex-page-header-row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

/* When a Toolbar slot is rendered, the row vertically-centres so the
   search input / filter buttons line up with the title block, and the
   text shrinks instead of growing. */
.orcanex-page-header-row.has-toolbar {
    align-items: center;
}

.orcanex-page-header-row.has-toolbar .orcanex-page-header-text {
    flex: 0 0 auto;
}

.orcanex-page-header-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: wrap;
}

.orcanex-page-header-text {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
}

.orcanex-page-header-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    text-decoration: none;
    flex-shrink: 0;
}
.orcanex-page-header-back:hover {
    background: var(--color-bg);
    color: var(--color-text);
}

.orcanex-page-header-titles { min-width: 0; }
.orcanex-page-header-title { margin: 0; color: var(--color-text); }
.orcanex-page-header-subtitle {
    margin-top: 4px;
    font-size: 0.92rem;
    color: var(--color-text-muted);
}

.orcanex-page-header-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-shrink: 0;
    margin-left: auto;
}

.orcanex-page-header-below { margin-top: 12px; }

/* ============================================================================
   Global Orcanex card — covers card markup written directly in pages.
   The <Card> primitive still works via its scoped CSS; this just covers any
   direct `.orcanex-card` markup in page-level Razor files.
   ============================================================================ */

.orcanex-card {
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    color: var(--color-text);
}
.orcanex-card-padded { padding: var(--space-4); }
.orcanex-card-accent { border-left: 4px solid var(--color-accent); }
.orcanex-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.orcanex-card-head-text { min-width: 0; }
.orcanex-card-title { margin: 2px 0 0; font-size: 1.08rem; font-weight: 600; line-height: 1.4; }
.orcanex-card-actions { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }

/* Modal show — old SOS modal sometimes uses position absolute */
.modal.fade.show.d-block {
    background: rgba(15, 17, 21, 0.45) !important;
}
.modal.fade.show.d-block .modal-dialog { margin: 1.75rem auto; }
.modal.fade.show.d-block .modal-content {
    background: var(--color-panel);
    border-radius: var(--radius-lg) !important;
    border: 1px solid var(--color-border) !important;
    box-shadow: var(--shadow-modal) !important;
}

/* ============================================================================
   Segment cards (.orcanex-segments / .orcanex-segment)

   Reusable rich-data-card strip used at the top of list pages (Cases pipeline
   stages, Specialists workload buckets, etc.) to visualise category counts
   and the share of the total. Each card is also click-to-filter — pages bind
   their own onClick and toggle `.is-active` on the selected card.

   Per-card colour comes from inline `--seg-color` and `--seg-color-soft`
   custom properties (the soft tone is just the same hue at ~12% opacity for
   the icon-tile background). Pages should always set both inline.

   Visual rhythm — top to bottom:
     • orcanex-segment-head     icon-tile + uppercase label + share %
     • orcanex-segment-value-row  big bold count + optional unit word
     • orcanex-segment-bar      thin progress fill = share of total
     • orcanex-segment-meta     bottom muted line ("No active", "12 today", …)

   The TOTAL card is a dedicated dark variant via `.orcanex-segment-total`.
   ============================================================================ */
.orcanex-segments {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
    flex-shrink: 0;
}

/* Mobile: switch the segments strip from a wrapping grid to a horizontal
   scroll-snap rail so the user can swipe through stages without the page
   ballooning vertically. Each card snaps to the start. */
:root[data-viewport="mobile"] .orcanex-segments,
:root[data-viewport="mobile-l"] .orcanex-segments {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: var(--space-2);
    /* Allow the cards to overflow the scroll container's edge by extending
       the padding into the strip — looks like a normal page edge but the
       last card can scroll fully into view. */
    margin-inline: calc(-1 * var(--space-3));
    padding-inline: var(--space-3);
    /* Hide scrollbar visually but keep keyboard/screen-reader scrollability. */
    scrollbar-width: none;
}
:root[data-viewport="mobile"]   .orcanex-segments::-webkit-scrollbar,
:root[data-viewport="mobile-l"] .orcanex-segments::-webkit-scrollbar {
    display: none;
}
:root[data-viewport="mobile"]   .orcanex-segments > .orcanex-segment,
:root[data-viewport="mobile-l"] .orcanex-segments > .orcanex-segment {
    flex: 0 0 auto;
    min-width: 200px;
    scroll-snap-align: start;
}

.orcanex-segment {
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 12px 14px 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: var(--color-text);
    position: relative;
    overflow: hidden;
    transition: border-color var(--duration-hover) var(--ease-hover),
                background var(--duration-hover) var(--ease-hover),
                transform var(--duration-hover) var(--ease-hover);
}

.orcanex-segment:hover {
    border-color: var(--seg-color, var(--color-border));
}

.orcanex-segment.is-active {
    border-color: var(--seg-color, var(--color-accent));
    box-shadow: 0 0 0 3px var(--seg-color-soft, var(--color-accent-soft));
}

.orcanex-segment-head {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.orcanex-segment-icon {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--seg-color-soft, var(--color-bg));
    color: var(--seg-color, var(--color-text-muted));
    flex-shrink: 0;
}

.orcanex-segment-label {
    flex: 1;
    font-size: 0.77rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orcanex-segment-pct {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.orcanex-segment-value-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-height: 28px;
}

.orcanex-segment-value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--color-text);
    letter-spacing: -0.5px;
    font-variant-numeric: tabular-nums;
}

.orcanex-segment-value.is-zero {
    color: var(--color-text-subtle);
    font-weight: 600;
}

.orcanex-segment-unit {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: lowercase;
}

.orcanex-segment-bar {
    height: 3px;
    background: var(--color-border-soft);
    border-radius: 2px;
    overflow: hidden;
}

.orcanex-segment-bar-fill {
    height: 100%;
    background: var(--seg-color, var(--color-accent));
    border-radius: 2px;
    transition: width 250ms ease;
    min-width: 0;
}

.orcanex-segment-meta {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    display: flex;
    align-items: center;
    gap: 4px;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orcanex-segment-meta-success {
    color: var(--color-success);
    font-weight: 500;
}

.orcanex-segment-meta-warn {
    color: var(--color-warn);
    font-weight: 500;
}

.orcanex-segment-meta-danger {
    color: var(--color-danger);
    font-weight: 500;
}

/* TOTAL — dark gradient card. Use on the trailing position of the strip. */
.orcanex-segment-total {
    background: linear-gradient(135deg, #1A1F2A 0%, #0F1115 100%);
    border-color: #1A1F2A;
    cursor: default;
}

.orcanex-segment-total:hover {
    border-color: #1A1F2A;
}

.orcanex-segment-total .orcanex-segment-icon {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
}

.orcanex-segment-total .orcanex-segment-label {
    color: rgba(255, 255, 255, 0.7);
}

.orcanex-segment-total .orcanex-segment-value {
    color: #fff;
}

.orcanex-segment-total .orcanex-segment-pct,
.orcanex-segment-total .orcanex-segment-unit,
.orcanex-segment-total .orcanex-segment-meta {
    color: rgba(255, 255, 255, 0.55);
}

.orcanex-segment-total .orcanex-segment-bar {
    background: rgba(255, 255, 255, 0.12);
}

.orcanex-segment-total .orcanex-segment-bar-fill {
    background: linear-gradient(90deg, #2F62FF 0%, #C455B0 50%, #E5904A 100%);
    width: 100% !important;
}

/* Toggle button "pressed" state — used by buttons that open/close a panel
   (filter strip, advanced search, etc.). When the panel is open, pages add
   `.is-open` to the button so the user sees a visibly-active control rather
   than a flat ghost button that gives no hint it can be re-clicked to close. */
.orcanex-toggle-btn.is-open {
    background: var(--color-accent-soft) !important;
    color: var(--color-accent) !important;
    border-color: var(--color-accent) !important;
    box-shadow: 0 0 0 3px var(--color-accent-ring) !important;
}
.orcanex-toggle-btn.is-open:hover {
    background: var(--color-accent-soft) !important;
    color: var(--color-accent-hover) !important;
}

/* ============================================================================
   Toast notifications (jquery-toast-plugin) — Orcanex retrofit.

   Replaces the plugin's default coloured-block toasts with clean Orcanex
   cards: panel background, subtle border, semantic colour stripe down the
   left edge, circular icon tile, kicker-style heading, and a top loader bar
   tinted to match the variant.

   Variants:
     .jq-icon-success  — uses --color-success (green)
     .jq-icon-warning  — uses --color-warn    (amber)
     .jq-icon-error    — uses --color-danger  (red)
     .jq-icon-info     — uses --color-accent  (the user's chosen accent —
                                                follows pink/teal/etc.)

   Status semantics (success/warning/error) deliberately stay on the fixed
   semantic tones; only info follows the user's accent. That way an error
   never reads as "celebratory pink" because the user picked pink as their
   accent — danger is always danger.
   ============================================================================ */

.jq-toast-wrap {
    width: 320px !important;
    z-index: 9000 !important;
}

/* Single toast — Orcanex card. */
.jq-toast-single {
    position: relative;
    display: block;
    width: 100%;
    padding: 14px 40px 14px 56px !important;
    margin: 0 0 10px !important;
    background-color: var(--color-panel) !important;
    background-image: none !important;
    color: var(--color-text) !important;
    border: 1px solid var(--color-border) !important;
    border-left-width: 4px !important;
    border-radius: var(--radius-md) !important;
    box-shadow: var(--shadow-overlay) !important;
    font-family: var(--font-family) !important;
    font-size: 0.92rem !important;
    line-height: 1.45 !important;
    pointer-events: all;
}

.jq-toast-single h2 {
    font-family: var(--font-family) !important;
    font-size: 0.77rem !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.08em !important;
    color: var(--color-text-muted) !important;
    margin: 0 0 4px !important;
    line-height: 1.3 !important;
    background: none !important;
}

/* Icon tile — circular dot on the left containing a white SVG glyph. We
   override the plugin's background-image data URI with our own minimal
   inline SVG so the icon style matches the rest of the IconBox set. */
.jq-toast-single.jq-has-icon::before {
    content: "";
    position: absolute;
    left: 14px;
    top: 14px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: var(--color-text-muted);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 16px 16px;
}

/* Plugin paints its own embedded data URI on .jq-has-icon as a background-
   image on the SINGLE element. We've nulled that on the rule above and put
   the icon on ::before instead. */
.jq-has-icon {
    padding-left: 56px !important;
    background-image: none !important;
}

/* SUCCESS — green. */
.jq-icon-success {
    border-left-color: var(--color-success) !important;
    background-color: var(--color-panel) !important;
    background-image: none !important;
}
.jq-icon-success h2 { color: var(--color-success) !important; }
.jq-icon-success::before {
    background-color: var(--color-success);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}

/* INFO — uses the user's accent so it follows pink / teal / etc. */
.jq-icon-info {
    border-left-color: var(--color-accent) !important;
    background-color: var(--color-panel) !important;
    background-image: none !important;
}
.jq-icon-info h2 { color: var(--color-accent) !important; }
.jq-icon-info::before {
    background-color: var(--color-accent);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='16' x2='12' y2='12'/><line x1='12' y1='8' x2='12' y2='8'/></svg>");
}

/* WARNING — amber. */
.jq-icon-warning {
    border-left-color: var(--color-warn) !important;
    background-color: var(--color-panel) !important;
    background-image: none !important;
}
.jq-icon-warning h2 { color: var(--color-warn) !important; }
.jq-icon-warning::before {
    background-color: var(--color-warn);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/><line x1='12' y1='9' x2='12' y2='13'/><line x1='12' y1='17' x2='12' y2='17'/></svg>");
}

/* ERROR — red. */
.jq-icon-error {
    border-left-color: var(--color-danger) !important;
    background-color: var(--color-panel) !important;
    background-image: none !important;
}
.jq-icon-error h2 { color: var(--color-danger) !important; }
.jq-icon-error::before {
    background-color: var(--color-danger);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><line x1='18' y1='6' x2='6' y2='18'/><line x1='6' y1='6' x2='18' y2='18'/></svg>");
}

/* Close button — subtle, top-right corner. */
.close-jq-toast-single {
    position: absolute !important;
    top: 8px !important;
    right: 10px !important;
    width: 22px;
    height: 22px;
    background: transparent;
    color: var(--color-text-muted);
    font-size: 16px !important;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    transition: background var(--duration-hover) var(--ease-hover),
                color var(--duration-hover) var(--ease-hover);
}

.close-jq-toast-single:hover {
    background: var(--color-bg);
    color: var(--color-text);
}

/* Loader bar — sits along the top edge of the toast. Coloured per variant
   so the dwindling-time cue reads at a glance. */
.jq-toast-loader {
    height: 2px !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    border-radius: var(--radius-md) var(--radius-md) 0 0 !important;
    background: var(--color-text-muted) !important;
}

.jq-icon-success .jq-toast-loader { background: var(--color-success) !important; }
.jq-icon-info    .jq-toast-loader { background: var(--color-accent) !important; }
.jq-icon-warning .jq-toast-loader { background: var(--color-warn) !important; }
.jq-icon-error   .jq-toast-loader { background: var(--color-danger) !important; }

/* Reduce-motion: kill the loader animation so the bar just sits there. */
:root[data-reduce-motion="1"] .jq-toast-loaded {
    transition: none !important;
}

/* ============================================================================
   Master-data list-mode chrome (.orcanex-mdtable[data-list-mode])

   The .orcanex-mdtable primitive is used by every CRM and MasterData list
   page. Each page keeps its own grid-template-columns in scoped CSS, but the
   card-vs-tabular chrome is centralised here so the user's `data-list-mode`
   preference flows through every page automatically.

   These rules sit unscoped so they win against the per-page scoped row
   defaults: scoped `.orcanex-mdtable-row[b-xxx]` is specificity 0,2,0; the
   selectors below are 0,3,0 (.orcanex-mdtable + [data-list-mode] + .orcanex-mdtable-row).

   Card (default) — rows are individual panels with rounded chrome and a
                    breathing gap; the head sits transparently above them.
   Tabular        — rows pack inside a single panel with divider lines only.
   ============================================================================ */
.orcanex-mdtable[data-list-mode="card"] {
    gap: 8px;
}
.orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-head {
    background: transparent;
    border: none;
    padding-bottom: var(--space-1);
}
.orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-row {
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: 10px;
}

.orcanex-mdtable[data-list-mode="tabular"] {
    background: var(--color-panel);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.orcanex-mdtable[data-list-mode="tabular"] .orcanex-mdtable-row:last-child {
    border-bottom: none;
}

/* ============================================================================
   Mobile master-data card recipe.

   Compact 2-line card per row. The HEAD row hides (table is now a list of
   cards, not a grid with column headers). Each row becomes a compact card:

     ┌──────────────────────────────────┐
     │ CODE (mono, muted)               │ │
     │ Name / description (bold)        │ │ ← chevron
     │ status · flags · meta info       │ │
     └──────────────────────────────────┘

   Card height ~70-90 px (vs the previous ~130 px). The chevron is
   absolute-positioned right-of-content so it doesn't take a full row. All
   cell-* classes get reduced font sizes + muted secondary tones to make the
   primary "Name" cell stand out.

   Pages with a genuinely tabular display they want to preserve at mobile
   should wrap the table in `<div class="orcanex-mdtable-wide">` (the one
   exception documented in CLAUDE.md / responsive-design.md).
   ============================================================================ */
:root[data-viewport="mobile"]   .orcanex-mdtable .orcanex-mdtable-head,
:root[data-viewport="mobile-l"] .orcanex-mdtable .orcanex-mdtable-head {
    display: none;
}

:root[data-viewport="mobile"]   .orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-row,
:root[data-viewport="mobile-l"] .orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-row,
:root[data-viewport="mobile"]   .orcanex-mdtable[data-list-mode="tabular"] .orcanex-mdtable-row,
:root[data-viewport="mobile-l"] .orcanex-mdtable[data-list-mode="tabular"] .orcanex-mdtable-row {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 10px 36px 10px 12px;
    position: relative;
    grid-template-columns: none !important;
    min-height: 0;
}

:root[data-viewport="mobile"]   .orcanex-mdtable-row > [class*="orcanex-mdtable-cell-"],
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > [class*="orcanex-mdtable-cell-"] {
    width: 100%;
    min-width: 0;
}

/* Code cell — small muted uppercase identifier label above the name. */
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-code,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-code {
    font-size: 0.7rem;
    color: var(--color-text-muted);
    font-family: var(--font-mono);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.3;
}

/* Name / description cell — primary text, bold, slightly larger. */
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-name,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--color-text);
    line-height: 1.25;
}

/* Secondary cells — description / sequence / flags / status pill row. */
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-desc,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-desc,
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-flags,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-flags,
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-status,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-status {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    line-height: 1.3;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin-top: 2px;
}

/* Chevron — absolute-positioned at the right vertical centre of the card
   so it doesn't take a full row beneath the cells. */
:root[data-viewport="mobile"]   .orcanex-mdtable-row > .orcanex-mdtable-cell-actions,
:root[data-viewport="mobile-l"] .orcanex-mdtable-row > .orcanex-mdtable-cell-actions {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    color: var(--color-text-muted);
    width: auto;
    margin: 0;
    padding: 0;
}

/* Tighten the card list gap so cards sit closer together. */
:root[data-viewport="mobile"]   .orcanex-mdtable[data-list-mode="card"],
:root[data-viewport="mobile-l"] .orcanex-mdtable[data-list-mode="card"] {
    gap: 6px;
}

/* "Card mode" rounded corners are still useful at mobile (gives each row
   visual definition), but tighten the radius a touch. */
:root[data-viewport="mobile"]   .orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-row,
:root[data-viewport="mobile-l"] .orcanex-mdtable[data-list-mode="card"] .orcanex-mdtable-row {
    border-radius: 8px;
}

/* Wide-table escape hatch — keep the grid layout but allow horizontal scroll
   inside a wrapper so the page never side-scrolls. */
.orcanex-mdtable-wide {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* ============================================================================
   Bootstrap `.sticky-top` z-index clamp at mobile.

   Bootstrap's `.sticky-top` ships with `z-index: 1020`, which is fine for
   page-level chrome on desktop but bleeds above the mobile chrome (tab
   strips, MobileTabPicker triggers, etc.) on a phone — sticky table heads
   end up floating over the containing tab. The user reported this as
   "headers bleed through the tab menu".

   Clamp at mobile globally: any `thead.sticky-top` (the Bootstrap pattern)
   gets `z-index: 1` so it stays sticky within its own `.table-responsive`
   scroll wrap without escaping into the page stacking context. Desktop is
   untouched.

   Applies to every page in the app that uses `<thead class="sticky-top">`
   inside a tabbed surface — EnvSettings (9 tables), LogExplorer, LogViewer,
   and any ad-hoc admin table.
   ============================================================================ */
:root[data-viewport="mobile"]   thead.sticky-top,
:root[data-viewport="mobile-l"] thead.sticky-top {
    z-index: 1 !important;
}
