/* ============================================================================ */
/* Palette — CONSOLIDATED per SUB-GAP-004 / 005 / 006 (23 Apr 2026).            */
/*                                                                              */
/* Every Nova design token (palette, severity, surface, panel typography) now   */
/* lives in ONE canonical runtime file:                                         */
/*   src/Nova.Web/wwwroot/css/nova.tokens.css                                   */
/*                                                                              */
/* Retired in this file: raw palette (v2.3), Stitch MD3 surface ladder (v2.4),  */
/* occ-sev / occ-insight severity aliases (v2.5), panel-title / caption / header*/
/* typography vars (v2.5 — components now use .nova-panel-title / -subtitle /   */
/* -meta utility classes promoted to tokens.css per SUB-GAP-005 §4.A).          */
/*                                                                              */
/* This file now contains only MudBlazor overrides, component-specific CSS      */
/* classes, and the legacy Stitch MD3 semantic aliases (--nova-surface,         */
/* --nova-error, --nova-warning, etc.) that still have active consumers.        */
/* Do not re-add raw hex or Nova design tokens here — they belong in            */
/* nova.tokens.css.                                                             */
/* ============================================================================ */

/* ===== Nova Design Tokens ===== */
:root {
    --nova-spacing-xs: 4px;
    --nova-spacing-sm: 8px;
    --nova-spacing-md: 16px;
    --nova-spacing-lg: 24px;
    --nova-spacing-xl: 32px;
    --nova-spacing-2xl: 48px;

    /* Radii — tightened per v2 trust rule: 16px reads too soft for this domain */
    --nova-radius-sm: 4px;
    --nova-radius-md: 8px;
    --nova-radius-lg: 8px;
    --nova-radius-pill: 9999px;

    /* Canonical panel header typography — every panel (pyramid, heatmap, trend, waterfall,
       risk-stack, hotspot context, section-panel) MUST use these so title↔caption and
       header↔content spacing stays identical across pages. Never override per-page. */

    --nova-shadow-sm:      0 1px 3px rgba(0, 0, 0, 0.07);
    --nova-shadow-md:      0 2px 8px rgba(0, 0, 0, 0.06);
    /* --nova-shadow-lg migrated to nova.tokens.css per v2.13b roadmap B2 */
    --nova-shadow-xl:      0 24px 48px rgba(25, 28, 30, 0.12), 0 4px 12px rgba(25, 28, 30, 0.06);
    --nova-shadow-ambient: 0 4px 20px rgba(25, 28, 30, 0.06);
    --nova-shadow-primary: none; /* DEPRECATED — colored drop-shadows violate v2 trust rule */

    --nova-transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);

    /* Layout */
    --nova-content-max-width: 1400px;
    --nova-sidebar-width:     260px;
    --nova-appbar-height:     64px;

    /* Font stack — IBM Plex is the single voice of the system. Plex Sans max weight is 700. */
    --nova-font-sans: 'IBM Plex Sans', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    --nova-font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Type scale (rem, 16px base) */
    --nova-text-page-title:   1.875rem; /* 30px */
    --nova-text-section:      1rem;
    --nova-text-kpi-value:    2.25rem;  /* 36px */
    --nova-text-kpi-value-lg: 3rem;     /* 48px hero */
    --nova-text-body:         0.875rem;
    --nova-text-label:        0.625rem; /* 10px uppercase */
    --nova-text-caption:      0.6875rem;
    --nova-text-badge:        0.625rem;

    /* Weights — IBM Plex Sans caps at 700; never synthesize bolder. */
    --nova-weight-regular: 400;
    --nova-weight-medium:  500;
    --nova-weight-semi:    600;
    --nova-weight-bold:    700;
    --nova-weight-black:   700;

    /* Tracking */
    --nova-track-tight:   -0.02em;
    --nova-track-normal:  0;
    --nova-track-wide:    0.02em;
    --nova-track-wider:   0.08em;
    --nova-track-widest:  0.15em;

    /* ===== Stitch MD3 Color Tokens ===== */
    --nova-surface: #f7f9fc;
    --nova-surface-card: #ffffff;

    --nova-text: #191c1e;
    /* --nova-text-secondary, --nova-text-muted, --nova-primary now canonical in nova.tokens.css (SUB-GAP-033). */
    /* --nova-primary-dark dropped: zero consumers; --nova-tertiary dropped: 4 consumers swept to --nova-primary. */
    --nova-error: #ba1a1a;
    --nova-error-container: #ffdad6;
    --nova-warning: #a23b00;
    --nova-border: #c2c6d7;
    --nova-border-light: rgba(0, 0, 0, 0.06);
    --nova-border-subtle: rgba(0, 0, 0, 0.06);

    /* Insight / severity tokens (shared across Overview + Activity + future pages).
       --nova-severity-success itself is defined in nova.tokens.css. App.css owns
       the -bg / -text / -severe / -info variants. */
    /* --nova-severity-critical, --nova-severity-severe now canonical in nova.tokens.css (SUB-GAP-033). */
    --nova-severity-warning: #f59e0b;
    --nova-severity-info: #146EF4;
    --nova-severity-success-bg: rgba(34, 197, 94, 0.08);
    --nova-severity-success-text: #15803d;
    --nova-severity-warning-bg: rgba(245, 158, 11, 0.08);
    --nova-severity-warning-text: #a16207;
    --nova-severity-critical-bg: rgba(239, 68, 68, 0.08);
    --nova-severity-critical-text: #b91c1c;
    --nova-severity-info-bg: rgba(20, 110, 244, 0.06);
    --nova-severity-info-text: var(--nova-text);

    /* v2.11 SUB-GAP-021/022 — signal-canvas focal surface (inverted dark surface
       used by NovaSignalCard + NovaPredictorCard only). One-per-page discipline. */
    --nova-signal-canvas:          #0e1016;
    --nova-signal-canvas-alt:      #1a1d25;
    --nova-signal-hairline:        rgba(255, 255, 255, 0.08);

    /* v2.11 SUB-GAP-026 — 5th aging-tier severity (preserves the 5-band palette). */
    --nova-severity-critical-deep: #991b1b;

    /* v2.11 SUB-GAP-022 — NovaPredictorCard LIVE-pulse cadence (slower than spinner). */
    --nova-motion-predictor-pulse-duration: 1800ms;

    /* ============================================================================ */
    /* Semantic tokens - light mode defaults. Components reference these.         */
    /* ============================================================================ */

    /* Chrome (sidebar + appbar — always slightly darker than canvas to form L-shape rail) */
    --nova-chrome-surface:       var(--nova-neutral-50);
    --nova-chrome-surface-hover: rgba(0, 0, 0, 0.03);
    --nova-chrome-divider:       rgba(0, 0, 0, 0.06);
    --nova-chrome-text:          var(--nova-ink-900);
    --nova-chrome-text-muted:    var(--nova-neutral-500);
    --nova-chrome-accent:        var(--nova-blue-500);
    --nova-chrome-elevation:     0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.03);

    /* Canvas (content area - flips with theme) */
    --nova-canvas-surface:       var(--nova-neutral-0);
    --nova-canvas-panel:         var(--nova-neutral-0);
    --nova-canvas-panel-alt:     var(--nova-neutral-100);
    --nova-canvas-border:        var(--nova-neutral-300);

    /* Text — canonical values in nova.tokens.css; no local override. */

    /* Severity tokens live in nova.tokens.css (canonical DS source).
       A prior block here redeclared --nova-severity-* as aliases of
       --nova-sev-*; --nova-sev-info was never defined, which resolved
       to empty and crashed ThemeInitializer. Do not re-introduce. */

    /* Signal tokens — contrast-dark callout (inverted against current canvas) */
    --nova-signal-surface: var(--nova-ink-900);
    --nova-signal-ink:     #FFFFFF;
    --nova-signal-cta-bg:  #FFFFFF;
    --nova-signal-cta-ink: var(--nova-ink-900);

    /* Canvas inset shadow (seam between chrome and canvas) */
    --nova-canvas-inset-shadow:
        inset 2px 0 4px -2px rgba(0, 0, 0, 0.08),
        inset 0 2px 4px -2px rgba(0, 0, 0, 0.08);
}

/* ============================================================================ */
/* Dark mode overrides - chrome + canvas + text + accent all flip             */
/* Multi-selector so dark tokens fire whether MainLayout has set [data-theme]  */
/* or only MudThemeProvider has applied .mud-theme-dark yet.                   */
/* ============================================================================ */
[data-theme="dark"],
.mud-theme-dark {
  /* Chrome flips to dark */
  --nova-chrome-surface:       var(--nova-neutral-900);
  --nova-chrome-surface-hover: rgba(255, 255, 255, 0.04);
  --nova-chrome-divider:       rgba(255, 255, 255, 0.07);
  --nova-chrome-text:          var(--nova-text-primary);
  --nova-chrome-text-muted:    var(--nova-text-muted);
  --nova-chrome-accent:        var(--nova-blue-300);
  --nova-chrome-elevation:     0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);

  /* Canvas flips — canonical values in nova.tokens.css; only the legacy
     --nova-canvas-surface alias (still consumed inside app.css) is kept. */
  --nova-canvas-surface: var(--nova-neutral-900);

  --nova-accent:         var(--nova-blue-300);

  /* Severity dark-mode values live in nova.tokens.css under [data-theme="dark"].
     Do not override here — a prior block referenced --nova-sev-*-dark custom
     properties that were never defined, which resolved to empty and crashed
     ThemeInitializer at first render. */

  /* Signal tokens invert in dark mode: LIGHT surface on dark canvas */
  --nova-signal-surface: #FFFFFF;
  --nova-signal-ink:     var(--nova-ink-900);
  --nova-signal-cta-bg:  var(--nova-ink-900);
  --nova-signal-cta-ink: #FFFFFF;

  --nova-border-subtle: rgba(255, 255, 255, 0.05);

  /* v2.11 SUB-GAP-021/022 — signal-canvas dark-mode variants. Hairline stays mode-invariant. */
  --nova-signal-canvas:          #050608;
  --nova-signal-canvas-alt:      #101217;

  /* v2.11 SUB-GAP-026 — aging 5th tier, dark mode. */
  --nova-severity-critical-deep: #fca5a5;

  --nova-canvas-inset-shadow:
      inset 2px 0 6px -2px rgba(0, 0, 0, 0.35),
      inset 0 2px 6px -2px rgba(0, 0, 0, 0.35);
}

[data-theme="dark"],
.mud-theme-dark {
    --nova-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.2);
    --nova-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.3);
    /* --nova-shadow-lg dark override migrated to nova.tokens.css per v2.13b roadmap B2 */
}

[data-theme="dark"],
.mud-theme-dark {
    --nova-surface: #131316;
    --nova-surface-card: #19191d;

    --nova-text: #e8eaed;
    /* --nova-text-secondary, --nova-text-muted, --nova-primary now canonical in nova.tokens.css dark block (SUB-GAP-033). */
    /* --nova-primary-dark + --nova-tertiary dropped: see :root for retirement notes. */
    --nova-error: #f28b82;
    --nova-error-container: rgba(242, 139, 130, 0.15);
    --nova-warning: #fbbf24;
    --nova-border: #48474b;
    --nova-border-light: rgba(255, 255, 255, 0.05);

    /* Insight / severity tokens — dark mode. -success itself flips via nova.tokens.css. */
    /* --nova-severity-critical, --nova-severity-severe now canonical in nova.tokens.css dark block (SUB-GAP-033). */
    --nova-severity-warning: #fbbf24;
    --nova-severity-info: #7dafff;
    --nova-severity-success-bg: rgba(74, 222, 128, 0.1);
    --nova-severity-success-text: #4ade80;
    --nova-severity-warning-bg: rgba(251, 191, 36, 0.1);
    --nova-severity-warning-text: #fbbf24;
    --nova-severity-critical-bg: rgba(255, 113, 108, 0.1);
    --nova-severity-critical-text: #ff716c;
    --nova-severity-info-bg: rgba(125, 175, 255, 0.1);
    --nova-severity-info-text: var(--nova-text);
}

/* Dark mode: slightly desaturated status chips */
[data-theme="dark"] .mud-chip,
.mud-theme-dark .mud-chip {
    opacity: 0.88;
}

/* Dark mode: soften table header borders */
[data-theme="dark"] .mud-table .mud-table-head th,
.mud-theme-dark .mud-table .mud-table-head th {
    border-bottom-color: rgba(255, 255, 255, 0.07) !important;
}

/* Dark mode: drawer border */
[data-theme="dark"] .mud-drawer,
.mud-theme-dark .mud-drawer {
    border-right-color: rgba(255, 255, 255, 0.07) !important;
}

/* Dark mode: appbar border */
[data-theme="dark"] .mud-appbar,
.mud-theme-dark .mud-appbar {
    border-bottom-color: rgba(255, 255, 255, 0.07) !important;
}

/* Dark mode: validation colors */
[data-theme="dark"] .valid.modified:not([type=checkbox]),
.mud-theme-dark .valid.modified:not([type=checkbox]) {
    outline-color: #5cb87a;
}

[data-theme="dark"] .invalid,
.mud-theme-dark .invalid {
    outline-color: #e07070;
}

[data-theme="dark"] .validation-message,
.mud-theme-dark .validation-message {
    color: var(--nova-error-text);
}

/* ===== MOBILE-FIRST BASE ===== */
html {
    font-size: 16px;
}

body {
    font-size: var(--nova-text-body);
    -webkit-text-size-adjust: 100%; /* prevent iOS auto-zoom */
}

/* FocusOnNavigate (Routes.razor) moves focus to the first <h1> on every
   navigation so screen-reader users hear the new page title. FocusOnNavigate
   makes the heading focusable only programmatically (tabindex=-1 — never a Tab
   stop), so the browser's default focus ring is pure visual noise that reads as
   "the title is selected". Suppress it; there is no keyboard-focus path to lose. */
h1:focus {
    outline: none;
}

/* Touch-target utility — apply to interactive elements ≤md */
.nova-touch {
    min-height: var(--nova-touch-min);
    min-width: var(--nova-touch-min);
}

@media (min-width: 768px) {
    .nova-touch {
        min-height: auto;
        min-width: auto;
    }
}

/* Body scroll lock when drawer is open */
body[data-drawer-open="true"] {
    overflow: hidden;
}

/* ===== Global Component Overrides ===== */

/* Typography */
html, body {
    height: 100%;
    margin: 0;
    overflow: hidden;
}

body {
    font-family: 'IBM Plex Sans', sans-serif;
    font-size: 14px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* App-shell stretch — unscoped so it applies regardless of Blazor scoped-CSS
   bundle state. height (not min-height) locks the shell to viewport; the
   grid row must be explicit (1fr) or the auto-row sizes to content; main
   column scrolls internally when content is taller than viewport. */
.nova-shell {
    height: 100vh;
    grid-template-rows: 1fr;
}

.nova-shell__main {
    min-height: 0;
    overflow: hidden;
}

.nova-shell__content {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}

/* Stitch utility classes */
.tabular-nums { font-variant-numeric: tabular-nums; }
.primary-gradient { background: var(--nova-primary); }
[data-theme="dark"] .primary-gradient,
.mud-theme-dark .primary-gradient { background: var(--nova-primary); }
.ambient-shadow { box-shadow: 0px 4px 20px rgba(25, 28, 30, 0.06); }
[data-theme="dark"] .ambient-shadow,
.mud-theme-dark .ambient-shadow { box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.3); }

/* Buttons — consistent radius and weight */
.mud-button-root {
    border-radius: var(--nova-radius-sm) !important;
    text-transform: none !important;
    font-weight: 600 !important;
    letter-spacing: 0.01em;
}

/* Filled inputs — compact, no underline */
.mud-input-filled {
    border-radius: var(--nova-radius-sm) !important;
}

.mud-input-filled::before,
.mud-input-filled::after {
    border-bottom: none !important;
}

[data-theme="dark"] .mud-input-filled,
.mud-theme-dark .mud-input-filled {
    background: var(--nova-input-filled-bg) !important;
}

[data-theme="dark"] .mud-input-filled:hover,
.mud-theme-dark .mud-input-filled:hover {
    background: var(--nova-input-filled-bg-hover) !important;
}

/* Select dropdowns — compact height */
.mud-select .mud-input-slot {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
}

/* Tabs — global style */
.mud-tab {
    font-weight: 600 !important;
    text-transform: none !important;
    letter-spacing: 0.01em;
}

/* Tabs — Stitch clean underline: muted inactive, primary active, thin indicator */
.mud-tabs .mud-tab {
    color: var(--nova-text-muted) !important;
    transition: color 150ms ease;
}

.mud-tabs .mud-tab:hover {
    color: var(--nova-text) !important;
}

.mud-tabs .mud-tab.mud-tab-active {
    color: var(--nova-primary) !important;
    font-weight: 600 !important;
}

.mud-tabs .mud-tabs-toolbar {
    border-bottom: 1px solid var(--nova-border-light);
}

.mud-tab-slider {
    background: var(--nova-primary) !important;
}

/* Paper — Stitch tonal depth: flat surface + subtle border, no MudBlazor elevation shadow */
.mud-paper {
    background: var(--nova-surface-card) !important;
    border: 1px solid var(--nova-border-light);
    box-shadow: none !important;
}

.mud-paper.mud-elevation-0 {
    border: none;
}

/* Table headers — global uppercase labels */
.mud-table .mud-table-head th {
    font-size: 0.6875rem !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.08em !important;
}

[data-theme="dark"] .mud-table .mud-table-head th,
.mud-theme-dark .mud-table .mud-table-head th {
    background: var(--nova-input-filled-bg) !important;
    color: var(--nova-text-muted) !important;
}

/* Table rows — subtle hover */
[data-theme="dark"] .mud-table-row:hover,
.mud-theme-dark .mud-table-row:hover {
    background: rgba(255, 255, 255, 0.02) !important;
}

/* Tables — Stitch: zebra rows, no dividers, compact */
.mud-table .mud-table-body tr:nth-child(even) {
    background: var(--nova-canvas);
}

.mud-table .mud-table-body tr:hover {
    background: var(--nova-canvas-panel) !important;
}

.mud-table .mud-table-body td {
    border-bottom: none !important;
}

/* DataGrid — Stitch: clean header, no footer border */
.mud-data-grid .mud-table-head th {
    background: transparent !important;
    border-bottom: 2px solid var(--nova-border-light) !important;
}

.mud-data-grid .mud-table-footer td {
    border-top: 1px solid var(--nova-border-light) !important;
}

/* Nav link icons — default to secondary color, NOT primary */
.mud-nav-link .mud-nav-link-icon {
    color: var(--mud-palette-text-secondary) !important;
}

/* Only active nav link gets primary icon */
.mud-nav-link.active .mud-nav-link-icon {
    color: var(--mud-palette-primary) !important;
}

[data-theme="dark"] .mud-nav-link.active .mud-nav-link-icon {
    color: var(--nova-chrome-accent) !important;
}

/* ------------------------------------------------------------------ */
/* Shell chrome - sidebar + appbar share --nova-chrome-surface        */
/* ------------------------------------------------------------------ */
/* App bar — matches chrome-appbar.html: 64px white, border, menu + breadcrumb + user chip */
.nova-appbar.mud-appbar {
    background: var(--nova-canvas-surface) !important;
    color: var(--nova-chrome-text) !important;
    border-bottom: 1px solid var(--nova-canvas-border);
    border-top: 2px solid transparent;
    box-shadow: none;
    backdrop-filter: none;
    padding-inline: 20px;
    gap: 14px;
    height: var(--nova-appbar-height);
    font-family: var(--nova-font-sans);
    z-index: 10;
}

.nova-appbar--impersonating.mud-appbar {
    border-top-color: var(--nova-severity-warning);
}

.nova-appbar .mud-icon-button {
    color: var(--nova-chrome-text) !important;
}

.nova-appbar .mud-icon-button:hover {
    color: var(--nova-chrome-accent) !important;
    background: var(--nova-chrome-surface-hover);
}

/* Impersonation chip — amber bordered rectangle, never tint the fill heavily */
.nova-appbar-impersonation-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid var(--nova-severity-warning);
    background: rgba(245, 158, 11, 0.08);
    color: var(--nova-severity-warning-text);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-family: var(--nova-font-sans);
    margin-right: 10px;
}

.nova-appbar-impersonation-chip svg {
    stroke: currentColor;
}

.nova-drawer.mud-drawer {
    background: var(--nova-chrome-surface) !important;
    color: var(--nova-chrome-text) !important;
    border-right: 1px solid var(--nova-chrome-divider);
    box-shadow: 1px 0 2px rgba(0, 0, 0, 0.04), 1px 0 3px rgba(0, 0, 0, 0.03);
}

[data-theme="dark"] .nova-drawer.mud-drawer {
    box-shadow: 1px 0 2px rgba(0, 0, 0, 0.35), 1px 0 3px rgba(0, 0, 0, 0.25);
}

.nova-canvas {
    background: var(--nova-canvas-surface);
    min-height: 100vh;
    padding-top: calc(var(--mud-appbar-height, 56px) + var(--nova-spacing-lg));
}

.nova-canvas-inner {
    max-width: var(--nova-content-max-width);
    margin: 0 auto;
    padding: 0 var(--nova-spacing-lg) var(--nova-spacing-lg);
}

/* ===== User Chip ===== */
/* User chip — matches chrome-appbar.html: bordered rectangle with avatar + stacked name/subtitle + chevron */
.nova-user-chip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 10px 4px 4px;
    border: 1px solid var(--nova-canvas-border);
    background: transparent;
    color: var(--nova-chrome-text);
    cursor: pointer;
    transition: background var(--nova-transition), border-color var(--nova-transition);
    font-family: var(--nova-font-sans);
}

.nova-user-chip:hover {
    background: var(--nova-chrome-surface-hover);
    border-color: var(--nova-chrome-accent);
}

/* Impersonating: warning ring on the chip — visible at every viewport, including
   phone where the standalone severity pill is hidden to save appbar real estate. */
.nova-user-chip--impersonating {
    border-color: var(--nova-severity-warning);
    box-shadow: 0 0 0 1px var(--nova-severity-warning);
}

.nova-user-chip--impersonating:hover {
    border-color: var(--nova-severity-warning);
}

/* Impersonation banner inside the menu — shown when impersonating, sits above
   the regular header. Carries the company being impersonated as the primary surface. */
.nova-user-menu-impersonation {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 4px;
    background: color-mix(in srgb, var(--nova-severity-warning) 12%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--nova-severity-warning) 25%, transparent);
    color: var(--nova-severity-warning);
}

.nova-user-menu-impersonation-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.nova-user-menu-impersonation-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--nova-severity-warning);
}

.nova-user-menu-impersonation-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--nova-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nova-user-chip-avatar {
    width: 28px !important;
    height: 28px !important;
    font-size: 11px !important;
    font-weight: 700 !important;
}

.nova-user-chip-info {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
}

.nova-user-chip-name {
    font-size: 12px;
    font-weight: 700;
    color: var(--nova-chrome-text);
    white-space: nowrap;
}

.nova-user-chip-subtitle {
    font-size: 10px;
    font-weight: 500;
    color: var(--nova-chrome-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 140px;
}

/* The `.mud-icon-root` half of this selector was left behind when the chevron became a NovaIcon.
   NovaIcon emits no Mud class, so the compound never matched and the chevron has been unstyled ever
   since - the same silent-and-flattering failure as the dead utility classes: a rule that reads as
   if it works. `font-size` went with it, because NovaIcon's own Size parameter owns the glyph now. */
.nova-user-chip-chevron {
    color: var(--nova-chrome-text-muted);
}

/* ===== Drawer (token-driven - old -light/-dark variants removed) ===== */

/* Dark mode: main content area */
[data-theme="dark"] .mud-main-content,
.mud-theme-dark .mud-main-content {
    background: var(--nova-canvas) !important;
}

/* Dark mode: tab bar */
[data-theme="dark"] .mud-tabs-header,
.mud-theme-dark .mud-tabs-header {
    background: transparent !important;
}

/* ============================================================================
   Sidebar chrome — nav is composed from DS components (NovaBrand, NovaNavSection,
   NovaNavItem) and NovaAppShell slots (LogoSlot / SearchSlot / SidebarFooter),
   so the brand lockup, nav wrapper, search-slot wrapper, section labels, nav
   items, footer container, and all collapsed-rail behavior now ship with the
   package. Only the MudBlazor search-input internals and the status-widget
   content (both rendered into DS slots) are tuned here.
   ============================================================================ */

.nova-nav-search-input .mud-input-outlined {
    border-radius: 0;
    font-size: 16px; /* >=16px prevents iOS focus-zoom; the only sub-16px input in the chrome */
    min-height: 32px;
}

.nova-nav-search-input .mud-input-adornment-start .mud-icon-root {
    font-size: 14px;
    color: var(--nova-text-muted);
}

/* ===== Sidebar status footer content (rendered into NovaAppShell's SidebarFooter) =====
   The footer container (padding / border-top / margin-top:auto / collapsed hiding)
   is the DS shell's .nova-shell__sidebar-footer; only the status widget is styled here. */
.nova-nav-status {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--nova-font-sans);
}

.nova-nav-status-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.10em;
    color: var(--nova-chrome-text);
}

.nova-status-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--nova-radius-pill);
    background: var(--nova-severity-success);
    box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18);
    display: inline-block;
    flex-shrink: 0;
    animation: novaStatusPulse 2.4s ease-in-out infinite;
}

[data-theme="dark"] .nova-status-dot {
    box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.22);
}

@keyframes novaStatusPulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.55; }
}

.nova-nav-version-text {
    margin-left: auto;
    font-size: 10px;
    color: var(--nova-chrome-text-muted);
}

[data-theme="dark"] .nova-status-dot {
    box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.12);
}

/* Phone-only appbar curation. Slot children (NovaFreshnessChip, NovaSeverityPill,
   NovaUserMenu in MainLayout's <AppbarRight>) have their own Blazor scope, so they
   can't be reached from NovaAppShell.razor.css. Rule lives unscoped here.
   Uses max-width to confine to phone only — `display: revert` at md+ doesn't
   restore the chip/pill's own display:inline-flex (revert rolls back to UA default,
   not author origin). app.css is exempt from the canonical-breakpoint validator
   (which only scans Components/DesignSystem/**), so 767px is fine here. */
@media (max-width: 767px) {
    .nova-shell__appbar-right > *:not(:last-child) {
        display: none !important;
    }
}

/* Collapsed-rail (data-collapsed) behavior — hiding the wordmark + glyph-clipping
   the brand, hiding nav-item labels/badges/tags and section labels, hiding the
   menu-search and the sidebar footer, centering icons — now ships with the DS
   components/shell themselves (NovaBrand GAP-056, NovaNavItem/NovaNavSection
   GAP-023, NovaAppShell), each self-managing it via its own scoped CSS. The
   consumer-side rules that previously lived here were retired with the migration
   to the DS nav primitives. */

/* =========================================================================
   Trend chart wrapper (v2.13b · §M-8 NovaTrendChart consumer migration).
   The new NovaTrendChart has a Title param but no Caption. Pages that need
   a Title + Caption header above the SVG plot use this block to render
   them externally and keep the consumer markup co-located + scannable.
   ========================================================================= */
.nova-trend-block {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.nova-trend-block__head {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.nova-trend-block__head .nova-panel-title {
    margin: 0;
}

.nova-trend-block__head .nova-panel-subtitle {
    margin: 0;
}

/* ===== Dashboard Components ===== */

.nova-filter-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.nova-filter-group {
    display: flex;
    align-items: flex-end;
    gap: 16px;
    flex: 1;
    flex-wrap: wrap;
}

.nova-filter-item {
    flex: 1;
    min-width: 140px;
}

.nova-filter-label {
    display: block;
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--nova-text-secondary);
    margin-bottom: 6px;
}

.nova-filter-input .mud-input-filled {
    border-radius: var(--nova-radius-sm) !important;
}

[data-theme="dark"] .nova-filter-input .mud-input-filled,
.mud-theme-dark .nova-filter-input .mud-input-filled {
    background: var(--nova-input-filled-bg) !important;
}

.nova-apply-btn {
    font-weight: 700 !important;
    letter-spacing: 0.02em;
    height: 42px;
    padding-left: 32px !important;
    padding-right: 32px !important;
    white-space: nowrap;
    flex-shrink: 0;
}

/* Dashboard Tabs */
.nova-dashboard-tabs .mud-tabs-header {
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

[data-theme="dark"] .nova-dashboard-tabs .mud-tabs-header,
.mud-theme-dark .nova-dashboard-tabs .mud-tabs-header {
    border-bottom-color: rgba(255, 255, 255, 0.05);
}

.nova-dashboard-tabs .mud-tabs-panels {
    padding-top: 24px;
}

/* Section panel — visual container for left/right halves.
   Surface tokens align to NovaCard (canvas-panel + canonical hairline + flat).
   No explicit height — flex/grid parents stretch children via align-items:
   stretch by default, and standalone usage (block-level siblings) sizes to
   content instead of forcing every panel to fill the viewport. */
.nova-section-panel {
    background: var(--nova-canvas-panel);
    border: 1px solid var(--nova-canvas-border);
    border-radius: var(--nova-radius-md);
    padding: 24px;
}

/* Section panel header — title row inside a panel card */
.nova-section-panel-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
}
.nova-section-panel-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--nova-text);
}

.nova-section-panel-titleblock {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin-bottom: 16px;
}

.nova-section-panel-titleblock > .nova-section-panel-title {
    margin: 0;
}

.nova-section-panel-subtitle {
    font-size: 13px;
    font-weight: 400;
    color: var(--nova-text-muted);
    line-height: 1.4;
}

/* Show more link at bottom of truncated tables */
.nova-show-more {
    display: flex;
    justify-content: center;
    padding: 12px 0 4px 0;
    border-top: 1px solid var(--nova-border-light);
}

/* Section Heading with colored bar */
.nova-section-heading {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 24px;
    margin-bottom: 12px;
}
.nova-section-panel > .nova-section-heading:first-child {
    margin-top: 0;
}

.nova-section-bar {
    width: 4px;
    height: 24px;
    border-radius: 9999px;
    flex-shrink: 0;
}

/* KPI Container */
.nova-kpi-container {
    border: 1px solid rgba(0, 0, 0, 0.06);
}

[data-theme="dark"] .nova-kpi-container,
.mud-theme-dark .nova-kpi-container {
    border-color: rgba(255, 255, 255, 0.05);
}

/* ============================================================================
   User Menu Popover — fixed 280px width so the panel (and the VIEWING AS strip)
   stays bounded. Chrome (bg/border/shadow) comes from the DS NovaMenu popover;
   padding:0 lets the edge-to-edge sections (header, impersonation banner, items)
   own their own spacing; overflow:hidden clips those flush sections to the
   popover's rounded corners (else the banner's square top corners poke out).
   Selector targets .nova-menu__popover (the div-based NovaMenu), not the
   retired MudMenu .mud-paper.
   ============================================================================ */
.nova-user-menu-popover .nova-menu__popover {
    width: 280px;
    padding: 0;
    overflow: hidden;
}

.nova-user-menu-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--nova-chrome-divider);
}

.nova-user-menu-header-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.nova-user-menu-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--nova-text-primary);
    line-height: 1.2;
}

.nova-user-menu-company {
    font-size: 11px;
    color: var(--nova-chrome-text-muted);
    line-height: 1.3;
    margin-top: 2px;
}

.nova-user-menu-role {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.10em;
    color: var(--nova-chrome-accent);
    margin-top: 3px;
}

.nova-user-menu-section {
    padding: 6px 0;
}

.nova-user-menu-section--danger {
    border-top: 1px solid var(--nova-chrome-divider);
}

.nova-user-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 18px;
    background: transparent;
    border: none;
    color: var(--nova-text-primary);
    font-family: var(--nova-font-sans);
    font-size: 13px;
    font-weight: 400;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--nova-transition);
}

.nova-user-menu-item:hover {
    background: var(--nova-chrome-surface-hover);
}

.nova-user-menu-item--danger {
    color: var(--nova-severity-critical-text);
    font-weight: 600;
    padding: 10px 18px;
}

.nova-user-menu-item--danger:hover {
    background: rgba(220, 38, 38, 0.06);
}

/* KPI Card */
.nova-kpi-card {
    display: flex;
    flex-direction: column;
    padding: 12px 16px;
}

.nova-kpi-label {
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 4px;
}

.nova-kpi-value {
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1;
    color: var(--mud-palette-text-primary);
}

.nova-kpi-warning {
    color: var(--nova-severity-warning-text) !important;
}

/* Ranking Table — surface aligned to NovaCard (canvas-border auto-flips light↔dark). */
.nova-ranking-table {
    border: 1px solid var(--nova-canvas-border);
    border-radius: var(--nova-radius-md);
    overflow: hidden;
}

.nova-team-table th {
    font-size: 0.625rem !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.1em !important;
    color: var(--mud-palette-text-secondary) !important;
    padding: 12px 16px !important;
    text-align: left !important;
}

[data-theme="dark"] .nova-team-table th,
.mud-theme-dark .nova-team-table th {
    background: rgba(255, 255, 255, 0.03) !important;
}

.nova-team-table td {
    padding: 12px 16px !important;
    font-size: 0.875rem;
    font-weight: 500;
}

.nova-team-table tbody tr {
    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}

[data-theme="dark"] .nova-team-table tbody tr,
.mud-theme-dark .nova-team-table tbody tr {
    border-bottom-color: rgba(255, 255, 255, 0.05);
}

.nova-team-table tbody tr:hover {
    background: rgba(0, 0, 0, 0.02);
}

[data-theme="dark"] .nova-team-table tbody tr:hover,
.mud-theme-dark .nova-team-table tbody tr:hover {
    background: rgba(255, 255, 255, 0.03);
}

.nova-rank-cell {
    color: var(--mud-palette-text-secondary) !important;
    font-weight: 500 !important;
}

.nova-name-cell {
    font-weight: 700 !important;
}

/* Progress bar behind Total cell */
.nova-total-cell {
    position: relative;
}

.nova-bar-bg {
    position: absolute;
    top: 4px;
    left: 0;
    bottom: 4px;
    border-radius: 0;
    z-index: 0;
}

.nova-bar-value {
    position: relative;
    z-index: 1;
    font-weight: 700;
}

/* ===== Hero selector — pill-shaped inline context switcher (e.g. employee picker) ===== */
.nova-hero-selector {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: 9999px;
    background: var(--nova-canvas-panel);
    color: var(--nova-text);
    font-size: 0.9375rem;
    font-weight: 700;
    border: 1px solid transparent;
    cursor: pointer;
    transition: background 150ms ease, border-color 150ms ease;
    max-width: 100%;
}

.nova-hero-selector:hover {
    border-color: var(--nova-primary);
    background: var(--nova-canvas);
}

.nova-hero-selector-chevron {
    font-size: 18px !important;
    color: var(--nova-text-muted);
    flex-shrink: 0;
}

[data-theme="dark"] .nova-hero-selector,
.mud-theme-dark .nova-hero-selector {
    background: rgba(255, 255, 255, 0.05);
}

[data-theme="dark"] .nova-hero-selector:hover,
.mud-theme-dark .nova-hero-selector:hover {
    background: rgba(255, 255, 255, 0.08);
}

/* ===== Status legend — shared key for stacked status bars ===== */
.nova-status-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 12px;
}

.nova-status-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.nova-status-legend-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: var(--nova-radius-sm);
}

.nova-status-legend-in-progress { background: var(--nova-severity-info); }
.nova-status-legend-pending { background: var(--nova-severity-warning); }
.nova-status-legend-overdue { background: var(--nova-severity-critical); }
.nova-status-legend-completed { background: var(--nova-severity-success); }

/* Placement variant: legend below a table, left-aligned (trailing key) */
.nova-status-legend-bottom {
    margin-top: 12px;
    margin-bottom: 0;
}

/* ===== VsTeam comparison — single bar + team-avg tick + delta chip ===== */
.nova-vsteam-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.nova-vsteam-row {
    display: grid;
    grid-template-columns: 120px 1fr 70px 90px;
    align-items: center;
    gap: 16px;
}

.nova-vsteam-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.nova-vsteam-bar-track {
    position: relative;
    height: 10px;
    background: var(--nova-canvas-border);
    border-radius: 0;
}

.nova-vsteam-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    background: var(--nova-primary);
    border-radius: 0;
    transition: width 0.3s ease;
}

.nova-vsteam-bar-tick {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 2px;
    background: var(--nova-text-primary);
    opacity: 0.65;
    transform: translateX(-1px);
    border-radius: 0;
}

.nova-vsteam-value {
    font-weight: 700;
    font-size: 0.9375rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.nova-vsteam-delta-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px 8px;
    border-radius: var(--nova-radius-pill);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
}

.nova-vsteam-delta-up {
    background: rgba(16, 185, 129, 0.12);
    color: var(--nova-severity-success-text);
}

.nova-vsteam-delta-down {
    background: rgba(239, 68, 68, 0.12);
    color: var(--nova-severity-critical-text);
}

.nova-vsteam-delta-neutral {
    background: rgba(148, 163, 184, 0.15);
    color: var(--mud-palette-text-secondary);
}

.nova-vsteam-legend {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

.nova-vsteam-legend-tick {
    display: inline-block;
    width: 2px;
    height: 14px;
    background: var(--mud-palette-text-primary);
    opacity: 0.65;
    border-radius: 0;
}

@media (max-width: 640px) {
    .nova-vsteam-row {
        grid-template-columns: 1fr;
        gap: 6px;
    }
}

/* Unified Employee Performance Table — grouped column headers for Inspections vs Standalone */
.nova-team-table-unified .nova-team-group-row th {
    padding: 8px 16px !important;
    font-size: 0.625rem !important;
    letter-spacing: 0.14em !important;
    text-align: center !important;
    border-bottom: none !important;
}

.nova-team-table-unified .nova-team-group-inspections {
    color: var(--nova-primary) !important;
    border-bottom: 2px solid var(--nova-primary) !important;
}

.nova-team-table-unified .nova-team-group-standalone {
    color: var(--nova-primary) !important;
    border-bottom: 2px solid var(--nova-primary) !important;
}

/* ===== Delta Indicators ===== */
.nova-kpi-delta {
    font-size: 0.6875rem;
    font-weight: 600;
    margin-top: 4px;
}

.nova-delta-good {
    color: var(--nova-severity-success-text);
}

.nova-delta-bad {
    color: var(--nova-severity-critical-text);
}

.nova-delta-neutral {
    color: var(--mud-palette-text-secondary);
}

/* ===== Breakdown Rows ===== */
.nova-breakdown-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.nova-breakdown-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nova-breakdown-name {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 70%;
}

.nova-breakdown-count {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--mud-palette-text-secondary);
}

.nova-breakdown-bar.mud-progress-linear {
    height: 6px !important;
    border-radius: 0 !important;
}

/* ===== Empty State ===== */
/* ===== Voyage Grid ===== */
.nova-voyage-grid .mud-table .mud-table-head th {
    background: transparent;
}

.nova-type-chip.mud-chip {
    height: 20px;
    font-size: 0.6875rem;
    font-weight: 600;
    padding: 0 6px;
    margin: 1px 2px;
}

/* ===== Filter Toggle ===== */
.nova-filter-toggle.mud-toggle-group {
    flex-wrap: wrap;
}

/* ===== Responsive ===== */
@media (max-width: 960px) {
    .nova-user-chip-info {
        display: none;
    }
}

/* ===== Damage Analysis — Stitch Design Tokens ===== */
.nova-damage-page { background: var(--nova-canvas-panel-alt); }

/* Filter bar — Stitch: bg-surface-container-low, flex, rounded-xl */
.nova-damage-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    background: var(--nova-canvas);
    padding: 16px;
    border-radius: var(--nova-radius-md);
}

/* Period toggle group — Stitch: white bg, rounded-xl, ghost border, shadow-sm */
.nova-damage-period-group {
    display: inline-flex;
    background: var(--nova-surface-card);
    padding: 4px;
    border-radius: var(--nova-radius-md);
    flex-shrink: 0;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(194, 198, 215, 0.2);
}

.nova-damage-period-btn {
    border: none;
    background: transparent;
    padding: 0 20px;
    height: 32px;
    font-family: 'IBM Plex Sans', sans-serif;
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--nova-text-muted);
    cursor: pointer;
    transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
    line-height: 32px;
    border-radius: 8px;
}

.nova-damage-period-btn:hover {
    color: var(--nova-text);
}

.nova-damage-period-btn.active {
    background: var(--nova-primary);
    color: var(--nova-on-accent);
    box-shadow: 0 2px 8px rgba(20, 110, 244, 0.25);
}

[data-theme="dark"] .nova-damage-period-btn.active,
.mud-theme-dark .nova-damage-period-btn.active {
    background: var(--nova-primary);
    color: var(--nova-signal-ink-dark);
}

/* Apply button — flat primary per trust rule (no gradients) */
.nova-damage-apply-btn {
    background: var(--nova-primary);
    color: var(--nova-on-accent);
    border: none;
    padding: 0 32px;
    height: 36px;
    line-height: 36px;
    border-radius: 8px;
    font-family: 'IBM Plex Sans', sans-serif;
    font-size: 0.875rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(20, 110, 244, 0.25);
    transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
    flex-shrink: 0;
}

.nova-damage-apply-btn:hover {
    box-shadow: 0 4px 16px rgba(20, 110, 244, 0.35);
}

.nova-damage-apply-btn:active {
    transform: scale(0.95);
}

[data-theme="dark"] .nova-damage-apply-btn,
.mud-theme-dark .nova-damage-apply-btn {
    /* background flips via --nova-primary in :root [data-theme=dark]/.mud-theme-dark */
    color: var(--nova-signal-ink-dark);
    box-shadow: 0 4px 12px rgba(138, 180, 248, 0.20);
}

/* ===== Stitch KPI Cards ===== */
.nova-kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
    margin-bottom: 24px;
    margin-top: 16px;
}

@media (max-width: 1280px) {
    .nova-kpi-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
    .nova-kpi-grid { grid-template-columns: 1fr; }
}

.nova-stitch-kpi-card {
    background: var(--nova-canvas-panel);
    border: 1px solid var(--nova-canvas-border);
    padding: 24px;
    border-radius: var(--nova-radius-md);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    transition: background-color 150ms ease;
    box-shadow: 0 4px 20px 0 rgba(20, 110, 244, 0.05);
}

[data-theme="dark"] .nova-stitch-kpi-card,
.mud-theme-dark .nova-stitch-kpi-card {
    box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.3);
}

.nova-stitch-kpi-card:hover {
    background: var(--nova-canvas);
}

.nova-stitch-kpi-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--nova-text-muted);
}

.nova-stitch-kpi-value {
    font-size: 1.875rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--nova-text);
    line-height: 1.1;
}

.nova-stitch-delta-good {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 700;
    background: var(--nova-delta-good-bg);
    color: var(--nova-delta-good-text);
}

.nova-stitch-delta-bad {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 700;
    background: var(--nova-delta-bad-bg);
    color: var(--nova-delta-bad-text);
}

.nova-stitch-delta-neutral {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 700;
    background: var(--nova-delta-neutral-bg);
    color: var(--nova-delta-neutral-text);
}

.nova-stitch-kpi-bar {
    margin-top: 16px;
    height: 4px;
    width: 100%;
    background: var(--nova-canvas-panel);
    border-radius: 0;
    overflow: hidden;
}

/* ===== Stitch Severity Donut ===== */
.nova-donut-container {
    position: relative;
    display: flex;
    justify-content: center;
    padding: 24px 0;
}

.nova-donut {
    width: 192px;
    height: 192px;
    border-radius: var(--nova-radius-pill);
    position: relative;
}

.nova-donut-ring {
    position: absolute;
    inset: 0;
    border-radius: var(--nova-radius-pill);
    mask: radial-gradient(circle, transparent 60%, black 61%);
    -webkit-mask: radial-gradient(circle, transparent 60%, black 61%);
}

.nova-donut-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.nova-donut-center-value {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--nova-text);
}

.nova-donut-center-label {
    font-size: 10px;
    text-transform: uppercase;
    font-weight: 700;
    letter-spacing: 0.15em;
    color: var(--nova-text-muted);
}

.nova-donut-legend {
    margin-top: 32px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.nova-donut-legend-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.nova-donut-legend-label {
    display: flex;
    align-items: center;
    gap: 12px;
}

.nova-donut-legend-dot {
    width: 12px;
    height: 12px;
    border-radius: var(--nova-radius-pill);
    flex-shrink: 0;
}

.nova-donut-legend-name {
    font-size: 0.875rem;
    color: var(--nova-text-secondary);
}

.nova-donut-legend-value {
    font-size: 0.875rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--nova-text);
}

.nova-stitch-kpi-bar-fill {
    height: 100%;
    border-radius: 9999px;
    transition: width 0.3s ease;
}

/* ===== Stitch OEM/Park Comparison Cards ===== */
.nova-comparison-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-top: 16px;
}

@media (max-width: 600px) {
    .nova-comparison-grid {
        grid-template-columns: 1fr;
    }
}

.nova-comparison-card {
    padding: 16px;
    background: var(--nova-surface);
    border-radius: 8px;
}

.nova-comparison-name {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--nova-text-muted);
    margin-bottom: 4px;
}

.nova-comparison-rate {
    font-size: 1.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.nova-comparison-bar {
    margin-top: 8px;
    height: 4px;
    width: 100%;
    border-radius: 9999px;
    overflow: hidden;
}

.nova-comparison-bar-fill {
    height: 100%;
    border-radius: 9999px;
}

/* ===== Stitch Heatmap ===== */
.nova-heatmap-table {
    width: 100%;
    text-align: center;
    font-variant-numeric: tabular-nums;
    border-collapse: separate;
    border-spacing: 0;
}

.nova-heatmap-table thead th {
    font-size: 10px !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    color: var(--nova-text-muted) !important;
    padding: 0 4px 16px 4px !important;
    background: transparent !important;
    border: none !important;
}

.nova-heatmap-table thead th:first-child {
    text-align: left;
    min-width: 140px;
}

.nova-heatmap-table tbody td {
    padding: 4px !important;
    border: none !important;
    background: transparent !important;
}

.nova-heatmap-table tbody td:first-child {
    text-align: left;
    font-weight: 700;
    color: var(--nova-text);
    padding: 12px 8px !important;
}

.nova-heatmap-cell-zero {
    background: var(--nova-canvas);
    color: var(--nova-text-muted);
}

/* ===== Stitch Vertical Breakdown Bar ===== */
.nova-stitch-breakdown {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 16px;
}

.nova-stitch-breakdown-item {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.nova-stitch-breakdown-header {
    display: flex;
    justify-content: space-between;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--nova-text-secondary);
}

.nova-stitch-breakdown-count {
    font-variant-numeric: tabular-nums;
}

.nova-stitch-breakdown-pct {
    font-weight: 400;
    color: var(--nova-text-muted);
    margin-left: 4px;
}

.nova-stitch-bar-track {
    height: 8px;
    width: 100%;
    background: var(--nova-canvas-panel);
    border-radius: 9999px;
    overflow: hidden;
}

.nova-stitch-bar-fill {
    height: 100%;
    border-radius: 9999px;
    background: var(--nova-primary);
    transition: width 0.3s ease;
}

/* ===== Overview Grid (shared: Yard Overview + Yard Analytics Team Performance) ===== */
.nova-overview-grid {
    display: grid;
    grid-template-columns: 5fr 7fr;
    gap: 24px;
}

@media (max-width: 1024px) {
    .nova-overview-grid {
        grid-template-columns: 1fr;
    }
}

/* ===== Equal 2-column grid (shared: Occupancy signals 2x2, generic side-by-side cards) ===== */
.nova-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    align-items: stretch;
}

@media (max-width: 1024px) {
    .nova-grid-2 {
        grid-template-columns: 1fr;
    }
}

.nova-overview-hero {
    background: var(--nova-canvas-panel);
    border: 1px solid var(--nova-canvas-border);
    border-radius: var(--nova-radius-md);
    padding: 32px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

@media (max-width: 600px) {
    .nova-overview-hero {
        padding: 20px 16px;
    }
}

.nova-overview-status-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

@media (max-width: 600px) {
    .nova-overview-status-strip {
        grid-template-columns: 1fr;
    }
}

.nova-overview-section-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--nova-text);
    margin-bottom: 16px;
}

.nova-overview-insights {
    display: flex;
    flex-direction: column;
    gap: 16px;
    flex: 1;
    align-self: stretch;
    width: 100%;
}

/* Sibling-anchored sizing is driven from JS (see js/app.js: novaInsightAnchor).
   The JS sets max-height on the inner .nova-insight-list (NOT this wrapper) so
   non-list siblings inside the wrapper (like a hero-number block) keep their
   natural height, and only the row area is bounded by the sibling's height.
   Phone is untouched — single-column stack at <md, insights take natural height. */

.nova-overview-units-hero {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 8px;
}

.nova-overview-units-value {
    font-size: 2.5rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    color: var(--nova-text);
}

.nova-overview-units-label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
}

/* The legacy overview-insight list/item pastel block was retired in v2.11
   per SUB-GAP-024 §5. Use the insight-list + insight-row design-system
   components — they own layout, spacing, and the no-row-tinting trust rule. */

.nova-insight-icon {
    font-size: 18px;
    flex-shrink: 0;
    margin-top: 1px;
}

.nova-insight-text {
    flex: 1;
}

.nova-insight-good {
    background: var(--nova-severity-success-bg);
    color: var(--nova-severity-success-text);
}
.nova-insight-good .nova-insight-icon { color: var(--nova-severity-success); }

.nova-insight-warning {
    background: var(--nova-severity-warning-bg);
    color: var(--nova-severity-warning-text);
}
.nova-insight-warning .nova-insight-icon { color: var(--nova-severity-warning); }

.nova-insight-critical {
    background: var(--nova-severity-critical-bg);
    color: var(--nova-severity-critical-text);
}
.nova-insight-critical .nova-insight-icon { color: var(--nova-severity-critical); }

.nova-insight-info {
    background: var(--nova-severity-info-bg);
    color: var(--nova-severity-info-text);
}
.nova-insight-info .nova-insight-icon { color: var(--nova-severity-info); }

.nova-overview-stat-card {
    background: var(--nova-canvas-panel);
    border: 1px solid var(--nova-canvas-border);
    border-radius: var(--nova-radius-md);
    padding: 24px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

/* Clickable drill-down variant: stat card opens a unit-level popup on click.
   Shared modifier so every dashboard using .nova-overview-stat-card gets the
   same affordance (cursor, accent border + lift on hover, keyboard focus ring). */
.nova-overview-stat-card--clickable {
    cursor: pointer;
    text-align: left;
    width: 100%;
    font: inherit;
    color: inherit;
    transition: border-color 120ms ease, background 120ms ease;
}

.nova-overview-stat-card--clickable:hover {
    border-color: var(--nova-primary);
    background: var(--nova-canvas-panel-alt);
}

.nova-overview-stat-card--clickable:focus-visible {
    outline: 2px solid var(--nova-primary);
    outline-offset: 2px;
}

.nova-overview-stat-card--clickable .nova-overview-stat-drill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--nova-primary);
    font-weight: 600;
}

.nova-overview-stat-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--nova-text-muted);
}

.nova-overview-stat-value {
    font-size: 1.875rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    color: var(--nova-text);
    margin-top: 4px;
}

.nova-overview-stat-sub {
    display: block;
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--nova-text-secondary);
    margin-top: 6px;
}

/* ===== Nova Tab Grid Layout =====
   Grid cells auto-stretch by default (align-items: stretch), but we also make each zone a
   flex-column with the child flex:1 so the inner panel/card FILLS its zone height — any pair
   of side-by-side zones is therefore always visually equal-height regardless of content length. */
.nova-tab-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--nova-spacing-lg); }
.nova-zone-full,
.nova-zone-half,
.nova-zone-two-thirds,
.nova-zone-one-third { display: flex; flex-direction: column; min-width: 0; }
.nova-zone-full > *,
.nova-zone-half > *,
.nova-zone-two-thirds > *,
.nova-zone-one-third > * { flex: 1 1 auto; min-height: 0; }
.nova-zone-full { grid-column: span 12; }
.nova-zone-half { grid-column: span 12; }
.nova-zone-two-thirds { grid-column: span 12; }
.nova-zone-one-third { grid-column: span 12; }
@media (min-width: 1024px) {
    .nova-zone-half { grid-column: span 6; }
    .nova-zone-two-thirds { grid-column: span 8; }
    .nova-zone-one-third { grid-column: span 4; }
}
.nova-zone-ring { display: flex; align-items: center; justify-content: center; background: var(--nova-canvas-panel); border: 1px solid var(--nova-canvas-border); border-radius: var(--nova-radius-md); padding: var(--nova-spacing-xl); }
.nova-loading { display: flex; align-items: center; justify-content: center; padding: var(--nova-spacing-2xl); }
.nova-loading-skeleton { display: flex; flex-direction: column; gap: var(--nova-spacing-md); }
.nova-loading-rows { display: flex; flex-direction: column; gap: var(--nova-spacing-sm); }

.nova-cell-critical { color: var(--nova-severity-critical); font-weight: 700; }
.nova-cell-stack { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nova-cell-stack__sub { font-size: 11px; font-weight: 400; color: var(--nova-text-muted); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nova-section-panel-title-mb { margin-bottom: var(--nova-spacing-sm); }

/* ===== Nova Hotspot Panel =====
   Spotlight card for when a single entity dominates a metric (e.g. one park holds 100% of overdue).
   Heatmap gradient background keyed to severity. Hero metric centered, meta chips below.
   Reusable: Damage hotspot, Occupancy saturation, Charging bottleneck. */
.nova-hotspot-panel {
    position: relative;
    background: var(--nova-canvas-panel);
    border: 1px solid var(--nova-canvas-border);
    border-radius: var(--nova-radius-md);
    padding: var(--nova-spacing-md) var(--nova-spacing-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-height: 160px;
}
/* v2 FLAT contract — severity carried by:
     (1) 3px left border (severity-keyed),
     (2) HOTSPOT eyebrow in --nova-severity-*-text (set at call site),
     (3) 10x10 top-right corner mark via ::after, consumes --nova-hotspot-corner.
   Consumer API unchanged: .nova-hotspot-severity-{good,warning,critical}.
   Dark-mode severity tokens auto-flip via nova.tokens.css — no per-theme overrides here.
   --nova-hotspot-glow and --nova-hotspot-dot are retired; any page reading them
   directly is a call-site bug to fix in pass 2. */
.nova-hotspot-panel::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 10px;
    height: 10px;
    background: var(--nova-hotspot-corner, var(--nova-text-muted));
    pointer-events: none;
}
.nova-hotspot-panel.nova-hotspot-severity-good     { --nova-hotspot-corner: var(--nova-severity-success);  border-left: 3px solid var(--nova-severity-success); }
.nova-hotspot-panel.nova-hotspot-severity-warning  { --nova-hotspot-corner: var(--nova-severity-warning);  border-left: 3px solid var(--nova-severity-warning); }
.nova-hotspot-panel.nova-hotspot-severity-critical { --nova-hotspot-corner: var(--nova-severity-critical); border-left: 3px solid var(--nova-severity-critical); }
.nova-hotspot-header { position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: flex-start; gap: var(--nova-spacing-md); }
.nova-hotspot-context { font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; color: var(--nova-text-muted); }
.nova-hotspot-tag { font-size: 0.625rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; padding: 4px 10px; border-radius: var(--nova-radius-pill); background: var(--nova-canvas-panel-alt); color: var(--nova-text-secondary); }
.nova-hotspot-body { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 4px; }
.nova-hotspot-title { margin: 0; font-size: 1rem; font-weight: 700; color: var(--nova-text); }
.nova-hotspot-value { font-size: 2.75rem; font-weight: 700; line-height: 1; color: var(--nova-text); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.nova-hotspot-caption { font-size: 0.8125rem; color: var(--nova-text-secondary); line-height: 1.4; max-width: 60ch; }
.nova-hotspot-meta { position: relative; z-index: 1; display: flex; flex-wrap: wrap; gap: var(--nova-spacing-sm); padding-top: var(--nova-spacing-sm); border-top: 1px solid var(--nova-border-light); }
.nova-hotspot-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 0.75rem; padding: 4px 10px; border-radius: var(--nova-radius-pill); background: var(--nova-canvas-panel); color: var(--nova-text-secondary); }
.nova-hotspot-chip-value { font-weight: 700; color: var(--nova-text); font-variant-numeric: tabular-nums; }

.nova-hotspot-title--clickable,
.nova-hotspot-chip--clickable
{
    cursor: pointer;
}

/* Chip drill target renders as a <button>; strip UA chrome so it matches the span chip exactly. */
.nova-hotspot-chip--clickable
{
    border: none;
    margin: 0;
    font-family: inherit;
    font-size: 0.75rem;
    line-height: inherit;
    text-align: left;
    appearance: none;
    -webkit-appearance: none;
}

.nova-hotspot-title--clickable:hover,
.nova-hotspot-title--clickable:focus-visible
{
    text-decoration: underline;
    outline: none;
}

.nova-hotspot-chip--clickable:hover,
.nova-hotspot-chip--clickable:focus-visible
{
    background: color-mix(in srgb, var(--nova-primary) 10%, var(--nova-canvas-panel));
    outline: none;
}

/* ===== Nova View-All Footer =====
   Standard footer button for tables/lists that cap visible rows. Click opens a dialog with the full list. */
.nova-view-all-footer { display: flex; justify-content: center; padding: var(--nova-spacing-md) 0 0; }
.nova-view-all-btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: var(--nova-radius-pill); background: transparent; color: var(--nova-primary); border: 1px solid var(--nova-border-light); font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; cursor: pointer; transition: background var(--nova-transition), border-color var(--nova-transition); }
.nova-view-all-btn:hover { background: var(--nova-canvas-panel); border-color: var(--nova-primary); }

/* ── Command Center Home ── */

.nova-welcome-bar {
    padding: 0;
}

.nova-welcome-name {
    color: var(--mud-palette-primary);
}

.nova-text-secondary {
    color: var(--mud-palette-text-secondary);
}

.nova-widget-card {
    border: 1px solid rgba(var(--mud-palette-text-primary-rgb), 0.05);
    border-radius: var(--nova-radius-md);
    height: 100%;
}

.nova-widget-card:hover {
    border-color: rgba(var(--mud-palette-primary-rgb), 0.2);
    transition: border-color 0.2s ease;
}

.nova-widget-title {
    font-weight: 700;
}

.nova-nav-card {
    border: 1px solid rgba(var(--mud-palette-text-primary-rgb), 0.05);
    border-radius: var(--nova-radius-md);
    text-align: center;
    transition: border-color 0.2s ease;
}

.nova-nav-card:hover {
    border-color: rgba(var(--mud-palette-primary-rgb), 0.2);
}

.nova-attention-link {
    white-space: nowrap;
}

/* Severity / rate accent classes used by breakdown bars and comparison cards.
   Tokens resolve to light and dark palettes via existing --nova-severity-* vars. */

.nova-sev-ok { color: var(--nova-severity-success); }
.nova-sev-warn { color: var(--nova-severity-warning, #f59e0b); }
.nova-sev-crit { color: var(--nova-severity-critical, #ef4444); }
.nova-sev-neutral { color: var(--nova-primary); }

.nova-stitch-bar-track.nova-sev-ok .nova-stitch-bar-fill,
.nova-stitch-bar-fill.nova-sev-ok { background: var(--nova-severity-success); }
.nova-stitch-bar-track.nova-sev-warn .nova-stitch-bar-fill,
.nova-stitch-bar-fill.nova-sev-warn { background: var(--nova-severity-warning, #f59e0b); }
.nova-stitch-bar-track.nova-sev-crit .nova-stitch-bar-fill,
.nova-stitch-bar-fill.nova-sev-crit { background: var(--nova-severity-critical, #ef4444); }
.nova-stitch-bar-track.nova-sev-neutral .nova-stitch-bar-fill,
.nova-stitch-bar-fill.nova-sev-neutral { background: var(--nova-primary); }

.nova-comparison-bar.nova-sev-ok .nova-comparison-bar-fill { background: var(--nova-severity-success); }
.nova-comparison-bar.nova-sev-warn .nova-comparison-bar-fill { background: var(--nova-severity-warning, #f59e0b); }
.nova-comparison-bar.nova-sev-crit .nova-comparison-bar-fill { background: var(--nova-severity-critical, #ef4444); }
.nova-comparison-bar.nova-sev-neutral .nova-comparison-bar-fill { background: var(--nova-primary); }

/* The .nova-damage-focal / -body / -title / -sub / -cta rules retired in v2.11.
   DamageAnalytics now uses <NovaSignalCard> as the focal surface, driven by
   Kind-tagged Critical insights from DamageAnalyticsService.GenerateInsights. */

/* Ranked list used by OEM / Yard comparison. Scans as a leaderboard. */

.nova-rank-list {
    display: flex;
    flex-direction: column;
}

.nova-rank-row {
    display: flex;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--nova-border-light, rgba(194, 198, 215, 0.22));
}

/* Clickable drill-down variant: a ranked row opens a unit-level popup on click.
   Shared modifier so any ranked list can opt a row into drill-down without page CSS. */
.nova-rank-row--clickable {
    width: 100%;
    cursor: pointer;
    background: none;
    border-top: none;
    border-left: none;
    border-right: none;
    text-align: inherit;
    font: inherit;
    color: inherit;
    transition: background 120ms ease;
}

.nova-rank-row--clickable:hover {
    background: var(--nova-canvas-panel-alt);
}

.nova-rank-row--clickable:focus-visible {
    outline: 2px solid var(--nova-primary);
    outline-offset: -2px;
}

.nova-rank-row:first-child {
    padding-top: 0;
}

.nova-rank-row:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.nova-rank-num {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--nova-text-muted);
    min-width: 18px;
    padding-top: 4px;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.nova-rank-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.nova-rank-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
}

.nova-rank-name {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--nova-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.nova-rank-value {
    font-size: 1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.nova-rank-bar-track {
    height: 4px;
    background: var(--nova-canvas-panel, rgba(194, 198, 215, 0.2));
    border-radius: 9999px;
    overflow: hidden;
}

.nova-rank-bar-fill {
    height: 100%;
    border-radius: 9999px;
    transition: width 0.3s ease;
}

.nova-rank-meta {
    font-size: 0.75rem;
    color: var(--nova-text-muted);
    font-variant-numeric: tabular-nums;
}

/* ── Breadcrumb ─────────────────────────────────────────── */
.nova-breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.875rem;
    color: var(--nova-chrome-text-muted);
    padding-left: 8px;
}

.nova-breadcrumb-link,
.nova-breadcrumb-parent {
    color: var(--nova-chrome-text-muted);
    text-decoration: none;
}

.nova-breadcrumb-link:hover {
    color: var(--nova-chrome-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.nova-breadcrumb-current {
    color: var(--nova-chrome-text);
    font-weight: 600;
    font-size: 0.9375rem;
}

.nova-breadcrumb-sep {
    color: var(--nova-chrome-text-muted);
    opacity: 0.4;
}

.nova-appbar-breadcrumb {
    padding-left: 8px;
}

/* ============================================================================ */
/* NovaStateView - empty / 404 / error / loading states                        */
/* ============================================================================ */

.nova-state-view {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    min-height: 400px;
    padding: 48px 24px;
    text-align: center;
    color: var(--nova-text-primary);
}

.nova-state-illustration {
    width: 320px;
    max-width: 80%;
    height: auto;
    color: var(--nova-text-muted);
    opacity: 0.8;
}

.nova-state-headline {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0;
}

.nova-state-subtext {
    font-size: 0.9375rem;
    color: var(--nova-text-secondary);
    max-width: 440px;
    line-height: 1.5;
    margin: 0;
}

.nova-state-cta {
    margin-top: 8px;
    display: flex;
    gap: 12px;
}

.nova-state-error .nova-state-headline {
    color: var(--nova-severity-critical);
}

/* ============================================================================ */
/* Login split layout                                                            */
/* ============================================================================ */

.nova-login-split {
    display: grid;
    grid-template-columns: minmax(360px, 40vw) 1fr;
    min-height: 100vh;
    background: var(--nova-canvas-surface);
    color: var(--nova-text-primary);
}

@media (max-width: 900px) {
    .nova-login-split {
        grid-template-columns: 1fr;
    }
    .nova-login-hero {
        display: none;
    }
}

.nova-login-form {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 64px;
    gap: 20px;
    max-width: 480px;
    width: 100%;
    justify-self: center;
}

.nova-login-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 24px;
}

.nova-login-brand-logo { height: 28px; }

.nova-login-brand-logo-dark { display: none; }

[data-theme="dark"] .nova-login-brand-logo-light { display: none; }

[data-theme="dark"] .nova-login-brand-logo-dark { display: inline-block; }

.nova-login-brand-name {
    font-size: 1rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--nova-text-secondary);
    text-transform: uppercase;
}

.nova-login-title {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0 0 8px 0;
}

/* Reserve a fixed slot for the inline form error so the layout does not
   shift when the error appears/disappears. Compact one-line text — heavy
   card-style state views are reserved for full-page error states. */
.nova-login-error-slot {
    min-height: 1.25rem;
    display: flex;
    align-items: center;
}

.nova-login-error {
    color: var(--nova-severity-critical);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.25rem;
}

.nova-login-forgot {
    color: var(--nova-text-muted) !important;
}

.nova-login-footer {
    display: flex;
    justify-content: space-between;
    margin-top: auto;
    padding-top: 32px;
    font-size: 0.75rem;
    color: var(--nova-text-muted);
}

.nova-login-hero {
    position: relative;
    /* Poster image is the first-paint + video-disabled fallback (reduced motion, load failure). */
    background: url('/images/login/customers-bg-poster.webp') center / cover no-repeat, var(--nova-brand-login-hero-fallback);
    overflow: hidden;
}

.nova-login-hero-video {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    z-index: 0;
}

.nova-login-hero-overlay {
    position: absolute; inset: 0;
    z-index: 1;
    /* Flat scrim for text legibility over hero footage (no gradients per trust rule). */
    background: rgba(14, 14, 17, 0.45);
    pointer-events: none;
}

/* Respect reduced-motion: drop the video, fall back to the static poster background. */
@media (prefers-reduced-motion: reduce) {
    .nova-login-hero-video {
        display: none;
    }
}

[data-theme="dark"] .nova-login-hero-overlay {
    background: rgba(14, 14, 17, 0.60);
}

.nova-login-hero-stats {
    position: absolute;
    z-index: 2;
    left: 32px; bottom: 32px;
    display: flex; gap: 32px;
    color: var(--nova-signal-ink);
    padding: 16px 20px;
    background: rgba(14, 14, 17, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--nova-radius-md);
    backdrop-filter: blur(6px);
}

[data-theme="dark"] .nova-login-hero-stats {
    background: rgba(14, 14, 17, 0.65);
}

.nova-login-hero-stats > div {
    display: flex; flex-direction: column; gap: 4px;
}

.nova-login-hero-stat-label {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
}

.nova-login-hero-stat-value {
    font-size: 1.25rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Clickable insight rows inside the Needs-attention card */
.nova-attention-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.nova-attention-link:hover .nova-insight-row {
    background: var(--nova-chrome-surface-hover);
}

/* Home widget — heading row with Nova sprite icon + title */
.nova-widget-heading {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
}

.nova-widget-title {
    margin: 0;
    font-family: var(--nova-font-sans);
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--nova-text-primary);
}

.nova-widget-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

/* Activity Pipeline — ink metrics row, severity only on Overdue>0 (violation #5) */
.nova-pipeline-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
    font-family: var(--nova-font-sans);
}

.nova-pipeline-metric {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.nova-pipeline-value {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--nova-text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.nova-pipeline-value--critical {
    color: var(--nova-severity-critical);
}

.nova-pipeline-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--nova-text-muted);
}

.nova-pipeline-label--critical {
    color: var(--nova-severity-critical-text);
}


/* ============================================================================
   Semantic typography utilities — aligned with Logisoft Nova Design System
   Use these on real UI elements instead of inline font-size / font-weight.
   ============================================================================ */
.nova-body {
    font-family: var(--nova-font-sans);
    font-size: var(--nova-text-body);
    line-height: 1.6;
    color: var(--nova-text);
}

.nova-h1,
.nova-page-title {
    font-size: var(--nova-text-page-title);
    font-weight: var(--nova-weight-black);
    letter-spacing: var(--nova-track-tight);
    color: var(--nova-text);
    line-height: 1.1;
}

.nova-h2,
.nova-section-title {
    font-size: var(--nova-text-section);
    font-weight: var(--nova-weight-bold);
    color: var(--nova-text);
}

.nova-kpi-value-lg {
    font-size: var(--nova-text-kpi-value-lg);
    font-weight: var(--nova-weight-black);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--nova-track-tight);
    line-height: 1;
    color: var(--nova-text);
}

.nova-table-header {
    font-size: var(--nova-text-label);
    font-weight: var(--nova-weight-bold);
    text-transform: uppercase;
    letter-spacing: var(--nova-track-widest);
    color: var(--nova-text-muted);
}

.nova-caption {
    font-size: var(--nova-text-caption);
    font-weight: var(--nova-weight-medium);
    color: var(--nova-text-secondary);
}

.nova-badge {
    font-size: var(--nova-text-badge);
    font-weight: var(--nova-weight-bold);
    text-transform: uppercase;
    letter-spacing: var(--nova-track-wider);
}

.nova-code,
.nova-mono {
    font-family: var(--nova-font-mono);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

/* DEPRECATED — v2 trust rule: no gradients. Aliased to flat solid primary. */
.nova-primary-gradient {
    background: var(--nova-primary);
}
[data-theme="dark"] .nova-primary-gradient {
    background: var(--nova-primary);
}

/* ============================================================================ */
/* NovaDialog scrim layout — global because the class is applied to a NovaOverlay
   element (a different scoped-CSS host than NovaDialog), so scoped rules in
   NovaDialog.razor.css never matched. Centers the dialog inside the overlay. */
/* ============================================================================ */
.nova-dialog__scrim {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 0;
}

@media (min-width: 768px) {
    .nova-dialog__scrim {
        align-items: center;
        justify-content: center;
        padding: var(--nova-space-lg);
    }
}

/* ===== Global ink utilities — severity-keyed text color =====
   Use on numeric values, captions, table cells where ONLY the ink
   should change with severity (rainbow-row rule: don't tint the row,
   tint the value). Backgrounds stay neutral. */
.nova-ink-success  { color: var(--nova-severity-success); }
.nova-ink-warning  { color: var(--nova-severity-warning); }
.nova-ink-critical { color: var(--nova-severity-critical); }
.nova-ink-muted    { color: var(--nova-text-muted); }

/* ===== Empty data row inside a table — small muted centered line =====
   For <td colspan="N">No results</td> patterns. Distinct from
   NovaEmptyState (which is a full-card chrome with icon + title). */
.nova-table-empty-row {
    font-size: 12px;
    color: var(--nova-text-secondary);
    padding: 12px 0;
    text-align: center;
}

/* ===== Dialog title row — icon + bold title flex line =====
   For NovaDialog TitleContent slots that combine an icon and a heading.
   Distinct from the NovaCard header — this is for modal headers. */
.nova-dialog-title-row {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 700;
}

/* ===== DRAWER (overlay sidebar ≤md) ===== */
.nova-drawer-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 998;
}

.nova-drawer-backdrop[data-open] {
    display: block;
}

@media (min-width: 768px) {
    .nova-drawer-backdrop {
        display: none !important; /* never overlay above md */
    }
}

.nova-drawer {
    position: fixed;
    inset: 0 auto 0 0;
    width: 280px;
    max-width: 85vw;
    background: var(--nova-surface-1);
    z-index: 999;
    transform: translateX(-100%);
    transition: transform 200ms ease-out;
    overflow-y: auto;
}

.nova-drawer[data-open] {
    transform: translateX(0);
}

@media (min-width: 768px) {
    .nova-drawer {
        /* Above md, drawer logic is replaced by inline sidebar. Reset.
           width: auto lets the grid track determine width — important so the
           collapsed-state grid override (64px) actually shrinks the sidebar.
           If we set width to a fixed token here, the element overflows its
           track when the track shrinks. */
        position: static;
        transform: none;
        width: auto;
        max-width: none;
        transition: none;
        z-index: auto;
    }
    .nova-drawer[data-open] {
        transform: none;
    }
}

/* Shared definition-list pattern for detail drawers (stock/booking/invoice detail).
   Two-column label/value rows with token-driven divider; light + dark via tokens. */
.nova-detail-list {
    display: grid;
    grid-template-columns: minmax(140px, 38%) 1fr;
    margin: 0;
}
.nova-detail-list dt,
.nova-detail-list dd {
    padding: 8px 0;
    margin: 0;
    font-size: 0.8125rem;
    border-bottom: 1px solid color-mix(in srgb, var(--nova-text-primary) 8%, transparent);
}
.nova-detail-list dt {
    color: var(--nova-text-muted);
}
.nova-detail-list dd {
    color: var(--nova-text-primary);
}

/* Inline country flag (emoji) next to a port/location code. NOT the DS NovaFlag component, which
   owns .nova-flag: this one styles a bare emoji glyph and must not shadow it. */
.nova-emoji-flag {
    font-size: 1.05em;
    line-height: 1;
    margin-right: 2px;
    vertical-align: -0.05em;
}

/* Vertical form layout (booking editor and future forms). */
.nova-form-stack {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 560px;
}
.nova-unit-row {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    flex-wrap: wrap;
}

/* Two-column form grid for editor tabs/wizard steps (fits without scrolling). */
.nova-form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    max-width: 820px;
}
@media (max-width: 768px) {
    .nova-form-grid {
        grid-template-columns: 1fr;
    }
}
.nova-form-grid--full {
    grid-column: 1 / -1;
}
.nova-unit-card {
    grid-column: 1 / -1;
    border: 1px solid color-mix(in srgb, var(--nova-text-primary) 10%, transparent);
    border-radius: var(--nova-radius-md, 8px);
    padding: 16px;
}
.nova-unit-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    color: var(--nova-text-muted);
    font-size: 0.8125rem;
}

/* ===== Test hooks badge — visible only when ASPNETCORE_ENVIRONMENT=E2E ===== */
.nova-testhooks-badge {
    position: fixed;
    right: var(--nova-space-3, 12px);
    bottom: var(--nova-space-3, 12px);
    z-index: 2000;
    padding: 4px 10px;
    border-radius: var(--nova-radius-sm, 4px);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    background: var(--nova-severity-warning);
    color: var(--nova-on-severity-warning);
    pointer-events: none;
}

/* Print: the SPA shell pins html/body to the viewport with overflow:hidden (for the
   fixed app chrome), which clips printable document pages to a single page. Release it
   for print so document pages (e.g. the Transport Profit report) paginate fully. */
@media print {
    html, body {
        height: auto !important;
        overflow: visible !important;
    }
}

/* ── Print document (shared by every printable report page: Transport Profit, Vessel Operations) ──
   Generic document chrome + structured-body primitives. Pages compose these; never re-roll per page. */
.nova-print-toolbar {
    display: flex;
    justify-content: flex-end;
    padding: 16px 24px;
    background: var(--nova-canvas-panel, #f5f6f8);
    border-bottom: 1px solid var(--nova-canvas-border, rgba(0, 0, 0, 0.08));
}

.nova-print-btn {
    padding: 8px 16px;
    border: 1px solid var(--nova-primary, #146EF4);
    border-radius: 8px;
    background: transparent;
    color: var(--nova-primary, #146EF4);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
}

.nova-print-doc {
    max-width: 1180px;
    margin: 0 auto;
    padding: 28px 40px 64px;
    color: var(--nova-text, #111111);
    font-size: 12px;
}

.nova-print-loading {
    padding: 48px;
    text-align: center;
    color: var(--nova-text-muted, #666);
}

.nova-print-letterhead {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding-bottom: 16px;
}

.nova-print-brand {
    font-size: 26px;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--nova-primary, #146EF4);
}

.nova-print-brand span {
    color: var(--nova-text-muted, #888);
    font-weight: 600;
    margin-left: 4px;
}

.nova-print-company {
    text-align: right;
    font-size: 16px;
    font-weight: 700;
    color: var(--nova-text, #111);
    max-width: 50%;
}

.nova-print-title {
    margin: 16px 0 18px;
    font-size: 20px;
    font-weight: 800;
    color: var(--nova-primary, #146EF4);
    text-align: center;
}

.nova-print-meta {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 2px 0;
    margin-bottom: 24px;
    font-size: 12px;
}

.nova-print-meta > div {
    display: contents;
}

.nova-print-meta-k {
    font-weight: 700;
    color: var(--nova-primary, #146EF4);
    padding-right: 24px;
}

/* Structured report body: titled sections, KPI tiles, and tabular data. */
.nova-print-section {
    margin-bottom: 22px;
    break-inside: avoid;
}

.nova-print-section-title {
    margin: 0 0 8px;
    font-size: 13px;
    font-weight: 700;
    color: var(--nova-text, #111);
    border-bottom: 1px solid var(--nova-canvas-border, rgba(0, 0, 0, 0.12));
    padding-bottom: 4px;
}

.nova-print-kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}

.nova-print-kpi {
    display: flex;
    flex-direction: column;
    gap: 2px;
    border: 1px solid var(--nova-canvas-border, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
    padding: 8px 10px;
}

.nova-print-kpi-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--nova-text-muted, #666);
}

.nova-print-kpi-value {
    font-size: 18px;
    font-weight: 800;
    color: var(--nova-text, #111);
}

.nova-print-kpi-sub {
    font-size: 10px;
    color: var(--nova-text-muted, #666);
}

.nova-print-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11px;
}

.nova-print-table th,
.nova-print-table td {
    text-align: left;
    padding: 4px 8px;
    border-bottom: 1px solid var(--nova-canvas-border, rgba(0, 0, 0, 0.10));
}

.nova-print-table th {
    font-weight: 700;
    color: var(--nova-text, #111);
}

.nova-print-table th.num,
.nova-print-table td.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.nova-print-mono {
    font-family: var(--nova-font-mono, ui-monospace, monospace);
}

.nova-print-empty {
    color: var(--nova-text-muted, #666);
    font-style: italic;
    padding: 8px 0;
}

/* Print pages use EmptyLayout, which renders straight into the SPA's overflow:hidden body
   (app.css pins html/body to the viewport). With no shell scroll container the document is
   clipped on screen. Promote it to a full-viewport scroll layer for on-screen preview; print
   reverts to normal block flow so the browser paginates the whole document. */
@media screen {
    .nova-print-screen {
        position: fixed;
        inset: 0;
        overflow-y: auto;
        background: var(--nova-canvas, #ffffff);
    }
}

@media print {
    .nova-print-screen { position: static; overflow: visible; background: none; }
    .nova-print-noprint { display: none !important; }
    .nova-print-doc { max-width: none; padding: 0 8px; }
    @page { size: landscape; margin: 12mm; }
}
