/* ==========================================================================
   HAVTO app alignment overlay -- APP-OWNED. Survives blueprint-migration-sync.

   Load AFTER havto-blueprint.css (see Components/App.razor). This file holds
   every app-side alignment delta so the sync-managed blueprint artifacts
   (wwwroot/css/havto-blueprint.css + Blueprint_Claude_Design/App/*) stay
   byte-identical to the Claude Design export and are NEVER hand-edited.
   The migration-sync skill -Force overwrites those files; it does not touch
   this one.

   Rules for this file:
   - Token-based only: var(--hav-*) / var(--mud-palette-*). No raw hex --
     light AND dark must both resolve. (Literal #ffffff / undefined
     var(--havto-*) previously fell back to white and broke dark mode.)
   - Every override notes the blueprint element it matches and why MudBlazor's
     DOM needs it, so a future blueprint drop can retire it.

   SECTION 1 restates blueprint utility values where the kit CSS disagrees with
   the visual source-of-truth HTML mockup -- raise these upstream so the kit CSS
   is corrected, then delete them here.
   SECTION 2 reconciles raw MudBlazor component DOM to the blueprint.
   ========================================================================== */

/* app root: own stacking context so app overlays/z-index behave predictably */
.hav-app { isolation: isolate; }

/* S11.69 boot splash theme gate -- app-owned delta on the kit failsafe. The kit
   rule `body:has([data-hav-layout]) .hav-boot { display: none }` lifts the splash
   at the first layout render, but that frame still carries the light default
   palette: ThemeStateService.LoadAsync can only read localStorage after the
   first render. Hold the plate until MudProviders emits [data-hav-theme-ready]
   so the reveal is the persisted theme, not a light flash. Wins over the kit
   failsafe on specificity and load order; once the marker lands the :not()
   drops out and the kit rule applies unchanged. */
body:has([data-hav-layout]):not(:has([data-hav-theme-ready])) .hav-boot { display: grid; }

/* ==========================================================================
   SECTION 1 -- Blueprint utility corrections (kit CSS != HTML mockup)
   Same selector as havto-blueprint.css; loaded later so it wins without
   !important. Restates only the changed properties.
   ========================================================================== */

/* KPI plate + section block -- RETIRED 2026-07-25: kit now uses var(--hav-line)
   for border and var(--hav-panel) for background natively. KPI value reverts to
   600/38px/6px 0 2px per kit. No overlay needed. */

/* Nav active tint must beat MudBlazor's own active background (needs !important). */
.hav-navlink a.active,
.hav-navlink a.mud-nav-link-active,
.hav-navlink .mud-nav-link.active,
.hav-navlink[aria-current="page"] a {
  background: rgba(59, 110, 165, 0.1) !important /* Chrome <111 fallback */;
  background: color-mix(in srgb, var(--hav-accent) 10%, transparent) !important;
}

/* Nav link sizing -- blueprint 13px label, 7px vertical padding. */
.hav-navlink a.mud-nav-link,
.hav-navlink .mud-nav-link {
  font-size: 13px;
  padding-top: 7px !important;
  padding-bottom: 7px !important;
}

/* Side menu tier tag: marks a nav item's minimum plan (e.g. Projects -> Project Pack).
   Mirrors the blueprint shell chip: 10px body text on a hairline strong-line border. */
.hav-nav-tier-tag {
  font-family: var(--hav-font-body);
  font-size: 10px;
  line-height: 1.5;
  padding: 1px 6px;
  border: 1px solid var(--hav-line-strong);
  border-radius: 2px;
  color: var(--hav-text-muted);
  white-space: nowrap;
  flex: none;
}

/* Tier tags right-align at row end, same layout treatment as count badges. */
.havto-side-menu .mud-navmenu .mud-nav-link:has(.hav-nav-tier-tag) .mud-nav-link-text {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  width: 100%;
  gap: 0.375rem;
  min-width: 0;
}

/* App bar -- flat (no elevation) with a hairline bottom border.
   The app bar sits on the panel surface so it reads as the same plane as the drawer. */
.hav-app .mud-appbar {
  background: var(--hav-panel) !important;
  border-bottom: 1px solid var(--hav-line);
}

/* Sidebar / drawer -- blueprint padding 12px 10px (MudBlazor defaults to 0).
   Target the nav menu inside the drawer, not the drawer itself (which is the
   fixed positioned container). The navmenu is the scrollable content area. */
.hav-app .mud-drawer .mud-navmenu {
  padding: 12px 10px !important;
}

/* Brand wordmark -- RETIRED 2026-07-25: kit now uses 18px natively. */

/* ==========================================================================
   SECTION 2 -- MudBlazor DOM reconciliation (raw components -> blueprint)
   Blueprint surfaces are square (0 radius), panel background, hairline border,
   no elevation. MudBlazor defaults to 8px radius, grey surface, elevation.
   Backgrounds use var(--hav-panel) (== --mud-palette-surface) so dark mode
   resolves to the dark surface instead of literal white.
   ========================================================================== */

/* Cards / outlined paper */
.hav-app .mud-card.mud-paper-outlined {
  border-radius: 0 !important;
  background: var(--hav-panel) !important;
  box-shadow: none !important;
}
.hav-app .mud-paper.mud-paper-outlined:not(.mud-popover) {
  border-radius: 0 !important;
  background: var(--hav-panel) !important;
  border: 1px solid rgba(31, 41, 55, 0.16) !important /* Chrome <111 fallback */;
  border: 1px solid color-mix(in srgb, var(--hav-text) 16%, transparent) !important;
}

/* Tables */
.hav-app .mud-table {
  background: var(--hav-panel) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
.hav-app .mud-table-cell {
  border-radius: 0 !important;
}

/* Outlined input borders -- square corners (MudBlazor defaults to 8px) */
.hav-app .mud-input-outlined-border {
  border-radius: 0 !important;
}

/* Non-outlined paper (filter bars) -- flat design, no elevation */
.hav-app .mud-paper:not(.mud-paper-outlined):not(.mud-popover):not(.mud-dialog) {
  border-radius: 0 !important;
  background: var(--hav-panel) !important;
  box-shadow: none !important;
}

/* Cards -- flat design, no elevation (covers MudCard without outlined class) */
.hav-app .mud-card {
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* HAV2115 -- MudBlazor's Elevation parameter injects a `mud-elevation-*` class that
   adds a diffuse shadow. The blueprint separates surfaces with 1px hairlines, not
   shadows, so we strip every elevation-derived shadow inside the app shell. */
.hav-app [class*="mud-elevation"] {
  box-shadow: none !important;
}

/* Filled buttons -- remove MudBlazor default elevation shadows */
.hav-app .mud-button-filled {
  box-shadow: none !important;
}

/* Switch thumb -- flat, no elevation; use the raised surface token for the fill
   so the knob re-themes in dark mode instead of MudBlazor's hardcoded #fafafa.
   The icon/text inside the knob uses the contrasting body text colour. */
.hav-app .mud-switch-button .mud-switch-thumb-small,
.hav-app .mud-switch-button .mud-switch-thumb-medium,
.hav-app .mud-switch-button .mud-switch-thumb-large {
  background-color: var(--hav-surface-raised) !important;
  color: var(--hav-text) !important;
  box-shadow: none !important;
}

/* Timeline dots -- flat, no elevation */
.hav-app .mud-timeline-item-dot {
  box-shadow: none !important;
}

/* FAB / scroll-to-top -- flat, no elevation (portaled outside .hav-app) */
.mud-fab {
  box-shadow: none !important;
}

/* Tabs -- flat design, no elevation on tab container */
.hav-app .mud-tabs {
  box-shadow: none !important;
}

/* Alerts -- square corners on all variants; info/warning get tint+border+padding */
.hav-app .mud-alert { border-radius: 0 !important; }
/* MudBlazor leaves the icon cell top-aligned, so on a one-line dense alert the
   glyph floats above the text baseline (shell billing/storage banners). */
.hav-app .mud-alert .mud-alert-icon { align-items: center !important; align-self: center !important; }
.hav-app .mud-alert.mud-alert-text-info,
.hav-app .mud-alert.mud-alert-outlined-info {
  background: rgba(0, 83, 135, 0.08) !important /* Chrome <111 fallback */;
  background: color-mix(in srgb, var(--hav-info) 8%, transparent) !important;
  border: 1px solid rgba(0, 83, 135, 0.3) !important /* Chrome <111 fallback */;
  border: 1px solid color-mix(in srgb, var(--hav-info) 30%, transparent) !important;
  border-radius: 0 !important;
  padding: 9px 13px !important;
}
.hav-app .mud-alert.mud-alert-text-warning,
.hav-app .mud-alert.mud-alert-outlined-warning,
.hav-app .mud-alert.mud-alert-text-error,
.hav-app .mud-alert.mud-alert-outlined-error {
  border: 1px solid rgba(245, 158, 11, 0.3) !important /* Chrome <111 fallback */;
  border: 1px solid color-mix(in srgb, var(--hav-warning, #f59e0b) 30%, transparent) !important;
  border-radius: 0 !important;
  padding: 9px 13px !important;
}
.hav-app .mud-alert.mud-alert-text-error,
.hav-app .mud-alert.mud-alert-outlined-error {
  border-color: rgba(220, 38, 38, 0.3) !important /* Chrome <111 fallback */;
  border-color: color-mix(in srgb, var(--hav-danger, #dc2626) 30%, transparent) !important;
}

/* Chips -- design system v1: 2px radius, 20px height, 2px 8px pad, nowrap, 16px icon.
   Applied to all size variants so components missing Size="Size.Small" or using
   Size.Medium/Large still conform. */
.hav-app .mud-chip {
  border-radius: 2px !important;
  height: 20px !important;
  min-height: 20px !important;
  padding: 2px 8px !important;
  font-size: 12px !important;
  white-space: nowrap !important;
}

.hav-app .mud-chip .mud-chip-icon,
.hav-app .mud-chip .mud-icon-root.mud-chip-icon {
  width: 16px !important;
  height: 16px !important;
  margin: 0 5px 0 0 !important;
  flex: none !important;
}

/* Nav links -- square corners (MudBlazor defaults to 8px) */
.hav-app .mud-nav-link { border-radius: 0 !important; }

/* Badges -- square corners (MudBlazor defaults to 10px) */
.hav-app .mud-badge { border-radius: 0 !important; }

/* Tab count badges are neutral quantities, not severity (HAV2141). Override any
   per-color MudBlazor classes to use the design-system .hav-count treatment. */
.hav-app .hav-tabs .mud-badge,
.hav-app .hav-tabs .mud-badge[class*="mud-badge-"] {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  min-width: 20px !important;
  padding: 1px 6px !important;
  font-family: var(--hav-font-mono) !important;
  font-size: 11px !important;
  line-height: 1.5 !important;
  color: var(--hav-text-label) !important;
  background: color-mix(in srgb, var(--hav-text) 8%, transparent) !important;
  border-radius: 2px !important;
  box-shadow: none !important;
}

/* Switch track -- design system v1 keeps the track and knob rounded as one of the
   three sanctioned radius exceptions. MudBlazor's default 9px pill shape is correct. */
.hav-app .mud-switch-track {
  border-radius: 9999px !important;
}

/* Switch track unchecked colour -- use a token-based muted grey instead of the
   theme text colour at 48% opacity, which renders near-black in light mode. */
.hav-app .mud-switch-track.mud-default {
  background-color: rgba(100, 116, 139, 0.55) !important /* Chrome <111 fallback */;
  background-color: color-mix(in srgb, var(--hav-text-muted) 55%, transparent) !important;
  opacity: 1 !important;
}

/* Buttons -- 14px, no uppercase, 34px height, square corners (all variants)
   MudBlazor generates per-color classes (success, error, warning, danger, info)
   so use attribute selectors to catch them all without enumerating. */
.hav-app .mud-button-filled-primary {
  font-size: 14px !important;
  text-transform: none !important;
  height: 34px !important;
}
.hav-app .mud-button-filled-default {
  font-size: 14px !important;
  text-transform: none !important;
}
.hav-app button[class*="mud-button-filled"],
.hav-app button[class*="mud-button-outlined"],
.hav-app button[class*="mud-button-text"],
.hav-app a[class*="mud-button-filled"],
.hav-app a[class*="mud-button-outlined"],
.hav-app a[class*="mud-button-text"] {
  border-radius: 0 !important;
  font-size: 14px !important;
  text-transform: none !important;
  height: 34px !important;
}

/* WCAG 2.1 AA color-contrast: MudBlazor 9.x sets outlined/text primary button
   text to --mud-palette-primary (#3b6ea5, ~5.8:1 on white). At 14px/600 the
   threshold is 4.5:1, which passes on pure white but fails on tinted and
   gray surfaces (e.g. expansion-panel bodies, page ground). PrimaryDarken
   (#2A5280, ~8:1 on white) passes comfortably on every app surface. */
.hav-app .mud-button-outlined.mud-button-outlined-primary,
.hav-app .mud-button-text.mud-button-text-primary {
  color: var(--hav-accent-strong) !important;
  --mud-ripple-color: var(--hav-accent-strong) !important;
}
.hav-app .mud-button-outlined.mud-button-outlined-primary {
  border-color: var(--hav-accent-strong) !important;
}

/* Tab panels -- square corners (MudBlazor defaults to 8px) */
.hav-app .mud-tabs-panels { border-radius: 0 !important; }

/* MudBlazor 9.x active tab panels use display: contents, so the blueprint
   .mud-tab-panel padding-top rule is ignored. Add the spacing to the panels
   container so the first tab content clears the tab strip. */
.hav-app .hav-tabs .mud-tabs-panels { padding-top: 18px !important; }

/* List page tab panels clip any overflow leaked by a MudDataGrid (e.g. its
   .mud-table-container scrollHeight) so the page scroll box is not inflated
   below the table. The table still scrolls internally because
   .hav-table .mud-table-container has overflow: auto. */
.hav-app .list-page-main-tabs .mud-tabs-panels,
.hav-app .list-page-main-content .list-page-main-tabs .mud-tabs-panels {
  overflow: hidden;
}

/* Embedded policy tabs (used inside ManageOrganization) -- hide the inner tab strip so the
   containing page tab strip is the only one visible. Match the specificity of the
   .hav-app .hav-tabs .mud-tabs-panels rule above so the padding override wins. */
.embedded-policy-tabs .mud-tabs-toolbar,
.embedded-policy-tabs .mud-tabs-header,
.embedded-policy-tabs .mud-tabs-tabbar { display: none !important; }
.hav-app .embedded-policy-tabs .hav-tabs .mud-tabs-panels { padding-top: 0 !important; }
.hav-app .embedded-policy-tabs .hav-tabs { margin-bottom: 0 !important; }

/* Rounded tabs variant -- square corners */
.hav-app .mud-tabs-rounded { border-radius: 0 !important; }

/* Tab bar -- square corners */
.hav-app .mud-tabs-tabbar { border-radius: 0 !important; }

/* HAV2140 (spec S11.15): the strip's bottom rule is the panel's top edge; the
   active tab is the 2px accent underline and nothing else -- a fill behind the
   strip is a second signal for one state. MudBlazor paints .mud-tabs-tabbar
   with --mud-palette-surface; the kit's .hav-tabs clears inner/content/wrapper
   but not the tabbar itself, so the fill leaked on list-page strips
   (list-page-main-tabs-header is a dead class; DetailContextTabsShell cleared
   it per-shell). Clear it once for every .hav-tabs strip and draw the bottom
   rule for horizontal strips so strip and panel read as one object. Vertical
   strips keep their own side rule (e.g. MyTimesheets day tabs). */
.hav-app .hav-tabs .mud-tabs-tabbar { background-color: transparent !important; }
.hav-app .hav-tabs .mud-tabs-tabbar:not(.mud-tabs-vertical) { border-bottom: 1px solid var(--hav-line); }

/* HAV2139 -- Disclosure surface: systemic override so ALL MudExpansionPanels
   within the app conform by default. Mirrors .hav-disclose from
   havto-blueprint.css. Opt-in .hav-disclose still works for the section
   variant (.hav-disclose--in-section). */
.hav-app .mud-expansion-panels {
  display: flex; flex-direction: column;
  background: transparent; box-shadow: none; border-radius: 0;
  border-top: 1px solid var(--hav-line);
  border-bottom: 1px solid var(--hav-line);
}
.hav-app .mud-expand-panel {
  background: transparent; box-shadow: none; border-radius: 0; margin: 0;
}
.hav-app .mud-expand-panel::before,
.hav-app .mud-expand-panel::after,
.hav-app .mud-expand-panel-border::before { display: none; }
.hav-app .mud-expand-panel.mud-panel-expanded { margin: 0; }
.hav-app .mud-expand-panel + .mud-expand-panel { border-top: 1px solid var(--hav-line); }
.hav-app .mud-expand-panel-header {
  min-height: 44px; padding: 11px 12px; gap: 12px;
  background: transparent; border-radius: 0;
  font-family: var(--hav-font-body); font-size: 14px; color: var(--hav-text);
}
.hav-app .mud-expand-panel-header:hover .mud-typography-body1,
.hav-app .mud-expand-panel-header:hover .mud-expand-panel-icon { color: var(--hav-accent); }/* removed hover fill: .hav-app .mud-expand-panel-header:hover */
.hav-app .mud-panel-expanded > .mud-expand-panel-header { background: transparent; }
.hav-app .mud-expand-panel-icon { color: var(--hav-text-label); transition: transform 160ms ease; }
/* MudBlazor uses .mud-expand-panel-gutters to inject 24px horizontal padding.
   Restore the blueprint intent: the panel body has no intrinsic padding.
   Disclosure panels are excluded -- the kit's .hav-disclose body rules in
   havto-blueprint.css own their spacing (v1.119.0 corrected selector). */
.hav-app .mud-expansion-panels:not(.hav-disclose):not(.hav-disclose--in-section) .mud-expand-panel .mud-expand-panel-content { background: transparent; padding: 0; }

/* Patterns bar (Archetypes 04): the recommendation disclosure is a flat bar --
   no wrapper hairlines, no 24px gutters, and the expanded body sits flush at
   the bar's left edge on the ground, rows separated by their own hairlines.
   The chevron stays, aligned with the tile edges to its right. */
.hav-app .advisory-row .mud-expansion-panels.hav-disclose:not(.hav-disclose--in-section) {
  border-top: 0;
  border-bottom: 0;
}
.hav-app .advisory-row .mud-expansion-panels.hav-disclose:not(.hav-disclose--in-section) .mud-expand-panel-header {
  padding-left: 0;
  padding-right: 0;
}
.hav-app .advisory-row .mud-expansion-panels.hav-disclose:not(.hav-disclose--in-section) .mud-expand-panel .mud-expand-panel-content {
  margin: 0 0 8px;
  padding: 0;
  border-left: 0;
}

/* In-section header sits on the section fill; only vertical padding is needed
   because the .hav-section padding provides the horizontal frame. */
.hav-app .hav-disclose--in-section .mud-expand-panel-header {
  padding: 6px 0;
}

/* Header title must use the full text token, not the 80% body1 opacity. */
.hav-app .hav-disclose .mud-expand-panel-header .mud-typography-body1 {
  color: var(--hav-text) !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 1.3 !important;
}

/* Repeated items inside a panel are rows separated by hairlines. */
.hav-app .hav-disclose .hav-list-row + .hav-list-row {
  border-top: 1px solid var(--hav-line);
}

/* Inside a sectioned disclosure the callout sits on the same left edge as the
   title and actions, so remove its left padding and let the body padding + the
   3px role border provide the small inset. */
.hav-app .hav-disclose--in-section .hav-list-row .hav-callout {
  padding-left: 0;
}

/* Button groups -- square corners */
.hav-app .mud-button-group-root { border-radius: 0 !important; }

/* Progress linear rounded variant -- design system v1 lists "progress/gauge caps"
   as a sanctioned radius exception. MudBlazor's Rounded="true" renders rounded
   caps, which is correct. Do NOT override to 0. */

/* Icon buttons -- square corners (MudBlazor defaults to 16px) */
.hav-app .mud-icon-button { border-radius: 0 !important; }

/* Breadcrumb rail -- MudBlazor 9.x pads .mud-breadcrumbs 16px 12px, insetting the
   trail ~12px from the content column edge on every detail/list page. The
   organization-pages.css rules (0.5rem 0) load BEFORE MudBlazor.min.css
   (App.razor) and lose the cascade; restated here where the overlay always wins.
   The list-page skeleton rail shares the selectors so the loading box matches
   the loaded rail instead of sitting tighter to the content above and below. */
.mud-breadcrumbs,
.list-page-breadcrumb-skeleton {
  padding: 8px 0 !important;
}
@media (max-width: 960px) {
  .mud-breadcrumbs,
  .list-page-breadcrumb-skeleton {
    padding: 4px 0 !important;
  }
}
@media (min-width: 1201px) {
  .mud-breadcrumbs,
  .list-page-breadcrumb-skeleton {
    padding: 12px 0 !important;
  }
}

/* Page title -- blueprint 30px/600 for h4.hav-h page headings.
   Unscoped: SuperAdminLayout has no .hav-app wrapper but still renders
   h4.hav-h page titles through the shared Base*PageLayout components. */
h4.hav-h {
  font-size: 30px !important;
  font-weight: 600 !important;
  line-height: 33.6px !important;
}

/* Section heading -- h6 at 16px */
.hav-app .mud-typography-h6 {
  font-size: 16px !important;
  line-height: 17.92px !important;
}

/* Card content padding -- 16px (blueprint panel padding) */
.hav-app .mud-card-content { padding: 16px !important; }

/* Body1 secondary/description text at 80% opacity */
.hav-app .mud-typography-body1 {
  color: rgba(31, 41, 55, 0.8) !important /* Chrome <111 fallback */;
  color: color-mix(in srgb, var(--hav-text) 80%, transparent) !important;
}

/* Caption -- 12.5px / 19.375px */
.hav-app .mud-typography-caption {
  font-size: 12.5px !important;
  line-height: 19.375px !important;
}

/* Calendar surface */
.hav-app .mud-calendar {
  background: var(--hav-panel) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  border: 1px solid rgba(31, 41, 55, 0.16) !important /* Chrome <111 fallback */;
  border: 1px solid color-mix(in srgb, var(--hav-text) 16%, transparent) !important;
}

/* Side panel / drawer -- unscoped: provider-hosted panels render under
   .hav-routes-scope, a sibling of the .hav-app MudLayout, so .hav-app rules
   never reach them. */
.mud-drawer-fixed {
  background: var(--hav-panel) !important;
  box-shadow: none !important;
  border-left: 1px solid rgba(31, 41, 55, 0.16) !important /* Chrome <111 fallback */;
  border-left: 1px solid color-mix(in srgb, var(--hav-text) 16%, transparent) !important;
}

/* Side panel body -- it is the scroll region, not a hairline section. */
.havto-side-panel-content.hav-section {
  background: transparent !important;
  border: none !important;
}

/* When no .hav-panel__footer commit bar follows, the body's reserved
   calc(20px + 64px) bottom padding has nothing to clear -- collapse it. */
.mud-drawer.hav-panel .hav-panel__body:last-child {
  padding-bottom: 20px;
}

/* Side panel header -- 56 header height (55 header content + 1px divider) with 20px side gutters. */
.hav-panel__header .mud-drawer-header {
  display: flex;
  align-items: center;
  min-height: 55px !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* ==========================================================================
   SECTION 3 -- App shell blueprint alignment (AppBar + SideNav)
   Maps MudBlazor app shell components to the authenticated-UI blueprint mockup.
   All token-based so dark mode resolves automatically.
   ========================================================================== */

/* AppBar toolbar -- blueprint padding 10px 16px, 14px gap.
   MudBlazor's default .mud-toolbar-appbar padding is 0 24px and icon Edge.Start adds
   a -12px pull; neutralise it so the hamburger and brand sit at the same gutter. */
.hav-app .mud-appbar .mud-toolbar-appbar {
  padding-top: 10px !important;
  padding-bottom: 10px !important;
  padding-left: 16px !important;
  padding-right: 16px !important;
  gap: 14px;
}

.hav-app .mud-appbar .mud-icon-button-edge-start {
  margin-inline-start: 0 !important;
}

/* AppBar action icons -- blueprint: 34x34 icon buttons. */
.hav-app .mud-appbar .mud-icon-button:not(.mud-icon-button-edge-start) {
  width: 34px !important;
  height: 34px !important;
  min-width: 34px !important;
  padding: 0 !important;
}

/* Brand wordmark -- blueprint: Barlow Condensed 18px / 600 weight.
   MudBlazor defaults to Barlow 14px / 400. */
.hav-app .hav-app-brand-wordmark {
  font-family: var(--hav-font-head) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  letter-spacing: 0.02em !important;
}

/* Profile avatar -- blueprint: circular user-initial avatar (34px).
   MudBlazor renders the account button as a 48px icon button. */
/* The image link carries no data-initial, so the circle geometry and the
   glyph-hiding rule need the has-avatar-image arm too. */
.hav-app .mud-appbar .mud-icon-button[data-initial],
.hav-app .mud-appbar .mud-icon-button.has-avatar-image {
  width: 34px !important;
  height: 34px !important;
  min-width: 34px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  /* HAV2196: tint is derived from the user id (MainLayout sets --hav-avatar-hue). */
  background-color: hsl(var(--hav-avatar-hue, 221) 48% 46%) !important;
  color: var(--hav-on-accent, var(--hav-text-inverted, #fff)) !important;
  overflow: hidden;
  position: relative;
}

/* Image link of the HAV2196 fallback chain: the photo fills the circle and the
   placeholder glyph stays hidden, exactly as it does for the initials link. */
.hav-app .mud-appbar .mud-icon-button.has-avatar-image .mud-icon-root {
  display: none !important;
}

.hav-app .mud-avatar.hav-avatar-tinted {
  background-color: hsl(var(--hav-avatar-hue, 221) 48% 46%);
  color: var(--hav-on-accent, var(--hav-text-inverted, #fff));
}

.hav-app .mud-avatar img.hav-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

/* MudIcon renders its SVG with class "mud-icon-root" (not "mud-icon" -- that class
   belongs to the wrapping <MudIcon> component, which MudIconButton doesn't render
   here). Without this the AccountCircle glyph never hides and shows through behind
   the initials in the corner of the avatar circle. */
.hav-app .mud-appbar .mud-icon-button[data-initial] .mud-icon-root {
  display: none !important;
}

.hav-app .mud-appbar .mud-icon-button.has-avatar-image img.hav-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

.hav-app .mud-appbar .mud-icon-button[data-initial]::before {
  content: attr(data-initial);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--hav-font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.3px;
}

/* Notification bell -- blueprint: silent when clean, a small error dot when not
   (Section 9.3). No count on the bell itself -- the count lives in the popover. */
.hav-app .mud-appbar .hav-notification-bell {
  position: relative;
  display: inline-flex;
}

.hav-app .mud-appbar .hav-notification-bell__dot {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--hav-error);
  pointer-events: none;
}

/* Notification stream rows stamp "HH:mm NZDT" (org compliance timezone on every
   front-facing time), wider than the kit's drawn clock-only grouped slot of 56px
   -- the stamp overflowed into the body column. The documented 88px slot
   ("dd MMM HH:mm") fits the format; the width follows the format (kit comment). */
.notification-panel-min .hav-feed--grouped,
.notification-panel-full .hav-feed--grouped { --hav-feed-time: 88px; }

/* Organization selector -- blueprint bordered pill */
.hav-app .organization-selector .current-org-display {
  display: inline-flex !important;
  align-items: center;
  gap: 7px;
  padding: 5px 10px !important;
  border: 1px solid var(--hav-line) !important;
  font-size: 13px !important;
  color: var(--hav-text) !important;
}

.hav-app .organization-selector .org-name {
  font-size: 13px !important;
  color: var(--hav-text) !important;
}

.hav-app .organization-selector .org-selector-locked-activator {
  border: 1px solid var(--hav-line) !important;
  padding: 5px 10px !important;
}

/* Organization selector -- narrow viewports: when the appbar crowds the pill,
   let the org name wrap to a second line (capped, then ellipsized) instead of
   being clipped mid-line by the toolbar. Keep the flex item's natural
   min-content floor -- min-width: 0 here collapses the pill to zero width.
   599px matches the breakpoint where havto-blueprint hides the brand wordmark. */
@media (max-width: 599px) {
  .hav-app .mud-appbar .organization-selector .org-name {
    max-width: 8.5rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* Compact appbar (<=479px): the rigid toolbar children already total ~477px, so
   below 480px the theme toggle and account menu clip off the right edge. Hide
   the AI help icon -- the nav drawer's Help & support section invokes the same
   panel -- and tighten the 14px gap so every remaining control stays reachable. */
@media (max-width: 479px) {
  .hav-app .mud-appbar .appbar-ai-help {
    display: none !important;
  }

  .hav-app .mud-appbar .mud-toolbar-appbar {
    gap: 8px;
    padding-left: 12px !important;
    padding-right: 12px !important;
  }
}

/* Ultra-narrow (~360px and below): the rigid appbar icons already claim most of
   the row, so let the pill degrade to a compact chip rather than pushing the
   account menu off the right edge. */
@media (max-width: 380px) {
  .hav-app .mud-appbar .organization-selector,
  .hav-app .mud-appbar .organization-selector .mud-menu,
  .hav-app .mud-appbar .organization-selector .mud-button-root,
  .hav-app .mud-appbar .organization-selector .current-org-display {
    min-width: 0;
  }

  .hav-app .mud-appbar .organization-selector .org-name {
    min-width: 0;
    max-width: 5.5rem;
  }
}

/* AppBar search visibility
   Both Bootstrap and MudBlazor ship d-* display utilities, so using those classes
   in MainLayout caused the search to stay hidden on 768-959px viewports (e.g. an
   iPad in portrait). Use app-owned classes and a 768px media query instead. */
.hav-app .mud-appbar .appbar-search-bar {
  display: none !important;
}

.hav-app .mud-appbar .appbar-search-trigger {
  display: inline-flex !important;
}

@media (min-width: 768px) {
  .hav-app .mud-appbar .appbar-search-bar {
    display: flex !important;
  }

  .hav-app .mud-appbar .appbar-search-trigger {
    display: none !important;
  }
}

/* Search bar -- blueprint: flex 1, max-width 420px, centered, compact, bordered */
.hav-app .custom-search-bar-wrapper {
  flex: 1 1 0% !important;
  max-width: 420px !important;
  margin-left: auto !important;
  margin-right: auto !important;
  border: 1px solid var(--hav-line) !important;
  background: var(--hav-ground) !important;
  border-radius: 0 !important;
  min-height: 34px !important;
  height: auto !important;
  padding: 6px 12px !important;
  align-items: center !important;
  box-sizing: border-box !important;
  justify-content: normal !important;
  gap: 8px !important;
}

.hav-app .custom-search-bar-wrapper .mud-input,
.hav-app .custom-search-bar-wrapper .mud-input-control,
.hav-app .custom-search-bar-wrapper .mud-input-control-input-container,
.hav-app .custom-search-bar-wrapper .mud-autocomplete {
  background: transparent !important;
  flex: 1 1 0% !important;
  width: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  height: auto !important;
  padding: 0 !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-control {
  width: 100% !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-adornment,
.hav-app .custom-search-bar-wrapper .mud-input-adornment-icon-button {
  color: var(--hav-text-muted) !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-adornment {
  height: 100% !important;
  align-items: center !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-adornment-icon-button {
  width: 20px !important;
  height: 20px !important;
  padding: 0 !important;
  margin: 0 !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-adornment-icon-button .mud-icon-root {
  width: 20px !important;
  height: 20px !important;
}

/* Remove the 320px max-width from the autocomplete root so it fills the 420px blueprint wrapper. */
.hav-app .custom-search-bar-wrapper .custom-search-bar {
  max-width: none !important;
}

.hav-app .custom-search-bar-wrapper .mud-input .mud-input-outlined-border,
.hav-app .custom-search-bar-wrapper .mud-input .mud-input-underline {
  border: none !important;
  display: none !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-root {
  padding: 0 !important;
  font-size: 13px !important;
  font-family: var(--hav-font-body) !important;
  font-weight: 400 !important;
  color: var(--hav-text) !important;
  line-height: 20.15px !important;
}

.hav-app .custom-search-bar-wrapper .mud-input-root::placeholder {
  color: var(--hav-text-muted) !important;
  font-family: var(--hav-font-body) !important;
  font-weight: 400 !important;
  opacity: 1 !important;
}

/* Drawer -- blueprint: 256px width, border-right, no elevation */
.hav-app .mud-drawer {
  border-right: 1px solid var(--hav-line) !important;
  box-shadow: none !important;
}

/* Side panels -- blueprint: 420px standard / 560px wide, full-width below 600px.
   Width is applied by MudDrawer as an inline style, so the mobile override uses !important. */
@media (max-width: 600px) {
  .havto-side-panel,
  .havto-side-panel-wide,
  .havto-side-panel-standard {
    width: 100% !important;
  }
}

@media (min-width: 960px) {
  .hav-app .mud-drawer-fixed.mud-drawer-pos-left {
    width: 256px !important;
    flex-basis: 256px !important;
  }
}

/* Workspace filter -- blueprint: bordered dropdown selector */
.hav-app .workspace-filter-select {
  display: flex !important;
  align-items: center;
  border: 1px solid var(--hav-line) !important;
  margin-bottom: 8px;
  font-size: 12.5px !important;
  line-height: 19.375px !important;
  color: var(--hav-text-muted) !important;
  cursor: pointer;
  padding: 0 !important;
}

.hav-app .workspace-filter-select .mud-input-control-input-container {
  background: transparent !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
  height: auto !important;
  width: 100% !important;
  padding: 0 !important;
}

.hav-app .workspace-filter-select .mud-input {
  background: transparent !important;
  width: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  height: auto !important;
  padding: 8px 24px 8px 10px !important;
  margin: 0 !important;
  border: none !important;
}

.hav-app .workspace-filter-select .mud-input-root {
  padding: 0 !important;
  font-family: var(--hav-font-body) !important;
  font-size: 12.5px !important;
  font-weight: 400 !important;
  color: var(--hav-text-muted) !important;
  line-height: 19.375px !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

/* Make the visible select slot fill the input so the popover sizes/anchors to the full box */
.hav-app .workspace-filter-select .mud-input .mud-input-slot:last-child {
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

.hav-app .workspace-filter-select .mud-input-adornment {
  height: auto !important;
  align-items: center !important;
}

.hav-app .workspace-filter-select .mud-input-adornment svg {
  width: 16px !important;
  height: 16px !important;
}

.hav-app .workspace-filter-select .mud-input-outlined-border {
  display: none !important;
}

.hav-app .workspace-filter-select:focus-within {
  border-color: var(--hav-accent) !important;
}

/* MudSelect dropdowns (workspace picker, etc.) -- neutral selected text, no left accent bar, subtle highlight */
.mud-list[id^="select-listbox"] .mud-list-item {
  color: var(--hav-text) !important;
  border-left: none !important;
}/* removed hover fill: .mud-list[id^="select-listbox"] .mud-list-item.mud-selected-item,
.mud-list[id^="select-listbox"] .mud-list-item:hover */

.mud-list[id^="select-listbox"] .mud-list-item.mud-selected-item .mud-text,
.mud-list[id^="select-listbox"] .mud-list-item:hover .mud-text {
  color: var(--hav-text) !important;
}

/* Search popover -- contained by the bar, blueprint command palette surface.
   Matches the appbar/ground color and stays within 60vh so the page itself
   never scrolls alongside the list. */
.hav-app .custom-search-popover,
.mud-popover.custom-search-popover {
  width: 420px !important;
  max-width: 420px !important;
  max-height: 60vh !important;
  overflow-y: auto !important;
  margin: 0 !important;
  border: 1px solid var(--hav-line) !important;
  border-top: none !important;
  border-radius: 0 !important;
  background: var(--hav-ground) !important;
  box-shadow: none !important;
  transform: translateX(-12px) !important;
}

.hav-app .custom-search-popover .mud-list,
.mud-popover.custom-search-popover .mud-list {
  padding: 0 !important;
  max-height: none !important;
  overflow-y: visible !important;
}

.hav-app .custom-search-popover .mud-list-item,
.mud-popover.custom-search-popover .mud-list-item {
  padding: 8px 16px !important;
  color: var(--hav-text) !important;
  border-left: none !important;
}

.hav-app .custom-search-popover .mud-list-item .mud-icon,
.hav-app .custom-search-popover .mud-list-item .mud-icon-root,
.mud-popover.custom-search-popover .mud-list-item .mud-icon,
.mud-popover.custom-search-popover .mud-list-item .mud-icon-root {
  color: var(--hav-text-muted) !important;
}.hav-app .custom-search-popover .mud-list-item-selected,
.hav-app .custom-search-popover .mud-selected-item,
.hav-app .custom-search-popover .mud-list-item:hover,
.hav-app .custom-search-popover .mud-list-item:focus-visible,
.hav-app .custom-search-popover .mud-list-item.focus-visible,
.mud-popover.custom-search-popover .mud-list-item-selected,
.mud-popover.custom-search-popover .mud-selected-item,
.mud-popover.custom-search-popover .mud-list-item:hover,
.mud-popover.custom-search-popover .mud-list-item:focus-visible,
.mud-popover.custom-search-popover .mud-list-item.focus-visible {
  border-left: none !important; color: var(--hav-text) !important;
}

.hav-app .custom-search-popover .mud-list-item-selected .mud-text,
.hav-app .custom-search-popover .mud-selected-item .mud-text,
.hav-app .custom-search-popover .mud-list-item:hover .mud-text,
.mud-popover.custom-search-popover .mud-list-item-selected .mud-text,
.mud-popover.custom-search-popover .mud-selected-item .mud-text,
.mud-popover.custom-search-popover .mud-list-item:hover .mud-text {
  color: var(--hav-text) !important;
}

/* Ctrl K badge in search bar */
.hav-app .custom-search-bar-wrapper .search-shortcut-badge {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex: 0 0 auto;
  font-family: ui-monospace, monospace;
  font-size: 10.5px;
  line-height: 1;
  color: var(--hav-text-muted);
  background: var(--hav-surface);
  border: 1px solid var(--hav-line);
  border-radius: 4px;
  padding: 2px 6px;
  margin-left: 8px;
  white-space: nowrap;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
  height: 22px;
  box-sizing: border-box;
}

/* MudNavGroup section icons -- blueprint group headers are text-only uppercase labels.
   Hide the first SVG (section icon) but keep the expand chevron (last SVG). */
.hav-app .mud-nav-group .hav-nav-group-label > svg:first-child {
  display: none !important;
}
.hav-app .mud-navmenu .mud-typography-caption,
.hav-app .mud-navmenu .hav-nav-group-label {
  font-family: var(--hav-font-head) !important;
  text-transform: uppercase !important;
  font-size: 11px !important;
  letter-spacing: 0.09em !important;
  color: var(--hav-text-muted) !important;
  padding: 9px 10px 5px !important;
}

/* Subsequent nav group labels -- blueprint adds extra top spacing (14px) after the first group.
   First group keeps the 9px top from the base rule above. */
.hav-app .mud-navmenu .mud-nav-group:not(:first-of-type) .hav-nav-group-label {
  padding-top: 14px !important;
}

/* Nav items -- blueprint: 13px body font, 7px 10px 7px 12px padding.
   Exclude .hav-nav-group-label so the 11px rule above wins for group headers. */
.hav-app .mud-nav-link:not(.hav-nav-group-label) {
  font-size: 13px !important;
  font-family: var(--hav-font-body) !important;
}

/* Nav link inner <a> padding -- blueprint: 7px 10px 7px 12px (MudBlazor defaults to 7px 16px) */
.hav-app .mud-nav-link:not(.hav-nav-group-label) {
  padding-left: 12px !important;
  padding-right: 10px !important;
}


/* MudDataGrid -- same surface/border treatment as MudTable (5b) */
.hav-app .mud-datagrid {
  background: var(--hav-panel) !important;
  border-radius: 0 !important;
}
.hav-app .mud-datagrid .mud-table-head {
  background: transparent !important;
}
.hav-app .mud-datagrid .mud-table-head .mud-table-cell {
  background: transparent !important;
}
.hav-app .hav-table .mud-table-head .mud-table-cell {
  background: var(--hav-surface-chrome) !important;
}
.hav-app .mud-datagrid .mud-table-cell {
  border-bottom: 1px solid rgba(31, 41, 55, 0.08) !important /* Chrome <111 fallback */;
  border-bottom: 1px solid color-mix(in srgb, var(--hav-text) 8%, transparent) !important;
}/* removed hover fill: .hav-app .mud-datagrid .mud-table-row:hover */

/* HAV2112 + HAV2189 -- List-page main content must not cause page-level horizontal scroll,
   and it must not become an independent vertical scroll region. Setting only overflow-x: hidden
   forces overflow-y to compute to auto (CSS 2.1), giving every long list page an inner scrollbar.
   min-width: 0 lets the flex item shrink; .hav-table .mud-table-container already owns the
   horizontal scroll for tables. */
.hav-app .list-page-main-content,
.hav-app .list-page-main-tabs {
  min-width: 0 !important;
}

/* HAV2112 -- Table chrome is one object: MudDataGrid toolbar = hav-table__header (56px bar),
   MudDataGrid pager = hav-table__footer (static, row count + pagination). */
.hav-app .hav-table .mud-datagrid-toolbar,
.hav-app .mud-datagrid .mud-datagrid-toolbar {
  display: flex !important;
  align-items: center !important;
  flex-wrap: wrap !important;
  gap: 12px !important;
  min-height: 56px !important;
  padding: 10px 16px !important;
  border: 1px solid var(--hav-line) !important;
  border-bottom: 0 !important;
  background: var(--hav-surface-chrome) !important;
}
.hav-app .hav-table .mud-datagrid-pager,
.hav-app .mud-datagrid .mud-datagrid-pager {
  position: static !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 12px !important;
  min-height: 48px !important;
  padding: 8px 16px !important;
  border: 1px solid var(--hav-line) !important;
  border-top: 0 !important;
  background: var(--hav-surface-chrome) !important;
  font-family: var(--hav-font-body) !important;
  font-size: 12px !important;
  color: var(--hav-text-label) !important;
}
.hav-app .hav-table .mud-datagrid-pager .mud-table-pagination,
.hav-app .mud-datagrid .mud-datagrid-pager .mud-table-pagination {
  font-family: var(--hav-font-head) !important;
  font-size: 11px !important;
  letter-spacing: .06em !important;
  text-transform: uppercase !important;
}

/* Table search field should use body type, not the subtitle/condensed stack (HAV2089) */
.hav-app .hav-table__search .mud-input-root {
  font-family: var(--hav-font-body) !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  color: var(--hav-text) !important;
}

.hav-app .hav-table__search .mud-input-root::placeholder {
  color: var(--hav-text-muted) !important;
  opacity: 1 !important;
}

.hav-app .hav-table__search .mud-input-adornment {
  color: var(--hav-text-muted) !important;
}

/* Blueprint filter-bar search has a 1px square border (Filter bar pattern) */
.hav-app .hav-table__search.mud-input-control-outlined .mud-input-outlined-border,
.hav-app .hav-table__search.mud-input-control-outlined .mud-input-outlined-border::before,
.hav-app .hav-table__search.mud-input-control-outlined .mud-input-outlined-border::after {
  border-radius: 0 !important;
}

/* Systemic: apply hav-table header typography to ALL tables within .hav-app
   so tables without explicit Class="hav-table" still get condensed uppercase
   headers per the blueprint spec (HAV2114). This cascades to side panels,
   shared sub-components, and platform admin pages. */
.hav-app .mud-table .mud-table-head th,
.hav-app .mud-table .mud-table-head .mud-table-cell,
.hav-app .mud-table thead th,
.hav-app .mud-datagrid .mud-table-head th,
.hav-app .mud-datagrid .mud-table-head .mud-table-cell,
.hav-app .mud-datagrid thead th {
  font-family: var(--hav-font-head) !important;
  text-transform: uppercase !important;
  letter-spacing: .07em !important;
  font-size: 11px !important;
  color: var(--hav-text-label) !important;
}
.hav-app .mud-table .mud-table-container { overflow: auto; }
.hav-app .mud-table .mud-table-head th,
.hav-app .mud-table .mud-table-head .mud-table-cell,
.hav-app .mud-table thead th {
  position: sticky; top: 0; z-index: 2;
}

/* HAV2065 -- Status chips: hav-status--* overrides MudBlazor's outlined chip colors
   with the blueprint tinted-fill + deep-text pattern. Applied via class on MudChip. */
.hav-app .mud-chip.hav-status--info { color: var(--hav-info-text)    !important; background: rgba(0, 83, 135, 0.14) !important; background: color-mix(in srgb, var(--hav-info) 14%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.hav-status--success { color: var(--hav-success-text) !important; background: rgba(35, 127, 82, 0.16) !important; background: color-mix(in srgb, var(--hav-success) 16%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.hav-status--warning { color: var(--hav-warning-text) !important; background: rgba(249, 169, 0, 0.16) !important; background: color-mix(in srgb, var(--hav-warning) 16%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.hav-status--error { color: var(--hav-error-text)   !important; background: rgba(192, 57, 43, 0.14) !important; background: color-mix(in srgb, var(--hav-error) 14%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.hav-status--neutral { color: var(--hav-text-label)   !important; background: rgba(100, 116, 139, 0.15) !important; background: color-mix(in srgb, var(--hav-text-muted) 15%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.hav-status--alert   { color: var(--hav-on-error)     !important; background: var(--hav-error) !important; border-color: transparent !important; }

/* HAV2326 -- outline form at the text role (e.g. a "Mandatory" marker on a template
   row): hairline border, no fill, no status colour. Pairs with hav-status--neutral. */
.hav-status.hav-status--outline { background: transparent !important; border: 1px solid var(--hav-line); }

/* Same tint pattern for chips that use the Color= prop directly (not the status class). */
.hav-app .mud-chip.mud-chip-color-info { color: var(--hav-info-text)    !important; background: rgba(0, 83, 135, 0.14) !important; background: color-mix(in srgb, var(--hav-info) 14%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.mud-chip-color-success { color: var(--hav-success-text) !important; background: rgba(35, 127, 82, 0.16) !important; background: color-mix(in srgb, var(--hav-success) 16%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.mud-chip-color-warning { color: var(--hav-warning-text) !important; background: rgba(249, 169, 0, 0.16) !important; background: color-mix(in srgb, var(--hav-warning) 16%, transparent) !important; border-color: transparent !important; }
.hav-app .mud-chip.mud-chip-color-error { color: var(--hav-error-text)   !important; background: rgba(192, 57, 43, 0.14) !important; background: color-mix(in srgb, var(--hav-error) 14%, transparent) !important; border-color: transparent !important; }

/* Dashboard header persona / provenance chips -- blueprint mockup uses muted text on
   a subtle outlined surface for the persona, and an inline info icon + text line
   (no chip chrome at all) for the guidance note. Overrides the tinted status
   pattern above. */
.hav-app .hav-status.dashboard-persona-chip {
  color: var(--hav-text-muted) !important;
  border: 1px solid var(--hav-line-strong) !important;
  background: transparent !important;
}
.hav-app .dashboard-guidance-note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--hav-font-body);
  font-size: 12px;
  color: var(--hav-info);
}
.hav-app .dashboard-guidance-note__icon {
  color: var(--hav-info) !important;
  font-size: 13px !important;
}

/* HAV2065 -- warning role used as typography / icon / text+outlined buttons must
   take the deep step. Amber (#F9A900) is a fill colour and fails AA on light
   grounds (1.96:1). --hav-warning-text is #8A5A00 in light, #F9A900 on dark. */
.hav-app .mud-typography-color-warning,
.hav-app .mud-icon-color-warning,
.hav-app .mud-button-text.mud-button-text-warning,
.hav-app .mud-button-text.mud-button-text-warning .mud-button-label,
.hav-app .mud-button-outlined.mud-button-outlined-warning,
.hav-app .mud-button-outlined.mud-button-outlined-warning .mud-button-label,
.hav-app .mud-button-outlined.mud-button-outlined-warning .mud-icon-root,
.hav-app .mud-button-text.mud-button-text-warning .mud-icon-root {
  color: var(--hav-warning-text) !important;
}

/* Side panel section cards -- hairline framed sections with 24px rhythm.
   Use with MudPaper elevation="0" and class="panel-section". */
.hav-app .mud-paper.panel-section,
.hav-app .hav-section.panel-section {
  border: 1px solid rgba(31, 41, 55, 0.16) !important /* Chrome <111 fallback */;
  border: 1px solid color-mix(in srgb, var(--hav-text) 16%, transparent) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  margin-bottom: 24px !important;
}

.hav-app .mud-paper.panel-section:last-child,
.hav-app .hav-section.panel-section:last-child {
  margin-bottom: 0 !important;
}

/*
  Avoid redundant nested borders inside side panels. If a panel-section (or any
  MudPaper inside a side panel body) exists only to wrap a single callout,
  alert, or another MudPaper, suppress its own border/padding so the grouped
  content provides the single surface. This kills the "box inside a box" noise
  without removing borders from panels that actually contain distinct sections.
*/
.havto-side-panel-content .mud-paper:has(> .hav-callout:only-child),
.havto-side-panel-content .mud-paper:has(> .mud-alert:only-child),
.havto-side-panel-content .mud-paper:has(> .mud-paper:only-child),
.havto-side-panel-content .mud-paper:has(> .mud-stack:only-child > .hav-callout:only-child),
.havto-side-panel-content .mud-paper:has(> .mud-stack:only-child > .mud-alert:only-child) {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

/* MudSelect dropdown panel -- square corners (5c) */
.hav-app .mud-popover .mud-list {
  border-radius: 0 !important;
}

/* MudPopover itself -- square corners (MudBlazor portals these outside .hav-app) */
.mud-popover {
  border-radius: 0 !important;
}

/* Bootstrap residual buttons -- square corners (connectivity overlay is outside .hav-app) */
.btn {
  border-radius: 0 !important;
}

/* Dialog surface -- blueprint specifies square corners (border-radius: 0).
   MudBlazor portals dialogs to body (outside .hav-app), so no .hav-app prefix.
   MudBlazor defaults to 8px; override to match the design system. */
.mud-dialog {
  border-radius: 0 !important;
}

/* Wizard dialog -- spec 11.50: a stepper of more than two steps leaves the
   drawer for a centred dialog at 720. MudBlazor portals dialogs to body
   (outside .hav-app), so no .hav-app prefix. Paired with HavtoDialogOptions.Wizard. */
.mud-dialog.havto-dialog-wizard {
  max-width: 720px;
}

/* Dialog input labels -- use app token so dark mode resolves (5d) */
.hav-app .mud-dialog .mud-input-label {
  color: var(--hav-text-muted) !important;
}

/* Command palette -- blueprint specifies a centered overlay surface at
   min(100%, 520px). The backdrop class is applied to the overlay, which is an
   adjacent sibling of the .mud-dialog inside .mud-dialog-container, so the
   adjacent-sibling selector is used to target the dialog surface. */
.command-palette-backdrop + .mud-dialog {
  width: min(100%, 520px);
  max-width: none;
}

@media (max-width: 600px) {
  /* Full-screen command palette on small screens */
  .command-palette-backdrop + .mud-dialog {
    width: 100%;
    max-width: 100%;
    min-height: 100vh;
    border-radius: 0;
  }

  .command-palette-backdrop + .mud-dialog .mud-dialog-content {
    min-height: 100vh;
  }
}

/* Print guidelines -- hide non-content chrome and let the page surface fill the sheet.
   Export/print is an app surface and should leave the building as a clean, light layout. */
@media print {
  .hav-app .mud-appbar,
  .hav-app .mud-drawer,
  .hav-app .custom-search-bar-wrapper,
  .hav-app .skip-to-main,
  .hav-app .mud-fab,
  .hav-app .ai-page-assistant-trigger,
  .hav-app .mud-speed-dial,
  .hav-app .theme-toggle,
  .hav-app .notification-button {
    display: none !important;
  }

  .hav-app .mud-main-content,
  .hav-app main,
  .hav-app #main-content {
    margin-left: 0 !important;
    margin-top: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
  }

  .hav-app {
    background: var(--hav-panel) !important;
  }

  .hav-app .mud-collapse-entered,
  .hav-app .mud-expand-panel-expanded {
    page-break-inside: avoid;
  }
}

/* ==========================================================================
   Filter bar composition -- blueprint (HAVTO Design System v1 S.21)
   One row, search grows, selects fixed 190px, 40px controls in a 56px bar.
   ========================================================================== */

.hav-app .register-filter-bar {
  gap: 0 !important;
}

.hav-app .register-filter-row {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  min-height: 56px !important;
}

.hav-app .register-filter-controls,
.hav-app .register-filter-controls.register-filter-secondary {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  flex: 1 1 auto !important;
  margin: 0 !important;
  /* One row, always: when the controls do not fit they scroll horizontally
     inside their flex lane instead of spilling over the trailing actions.
     Above 960 this was previously only overflow:visible, so a wide bar (e.g.
     visitor History: range + 3 selects + search + Export) painted its last
     controls on top of the Export button. */
  min-width: 0 !important;
  overflow-x: auto !important;
  scrollbar-width: none;
}

/* Two-column readout for analytics metrics: label muted, value in display face,
   tabular figures. Collapses to one column on narrow viewports. */
.hav-app .hav-row.hav-row--readout {
  grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 600px) {
  .hav-app .hav-row.hav-row--readout {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 960px) {
  /* Spec: the filter bar is one row -- never a stacked second toolbar. The <960
     contract is "search stays; the rest collapses behind Filters (n) in a side
     panel"; until the panel exists the row scrolls its controls horizontally
     instead of wrapping. */
  .hav-app .register-filter-row {
    flex-wrap: nowrap !important;
  }

  .hav-app .register-filter-controls,
  .hav-app .register-filter-controls.register-filter-secondary {
    flex-wrap: nowrap !important;
    min-width: 0 !important;
    overflow-x: auto !important;
    scrollbar-width: none;
  }

  /* Register intelligence panels collapse to a single column at tablet width;
     the left column's plates and figures wrap to their own floor. The layout is
     .hav-detail (8fr/4fr) since the 2026-09-13 switch - target it directly. */
  .hav-app .intelligence-layout,
  .hav-app .intelligence-layout > div {
    grid-template-columns: 1fr !important;
  }

  .hav-app .intelligence-layout .intelligence-right-sticky {
    position: static;
    top: auto;
    align-self: stretch;
  }
}

.hav-app .register-filter-search {
  flex: 1 1 280px !important;
  width: auto !important;
  max-width: none !important;
  min-width: 280px !important;
}

.hav-app .register-filter-search .mud-input-control,
.hav-app .register-filter-search .mud-input {
  width: auto !important;
  max-width: none !important;
}

.hav-app .register-filter-controls .mud-select {
  flex: 0 0 190px !important;
  width: 190px !important;
  min-width: 190px !important;
  max-width: 190px !important;
}

.hav-app .register-filter-controls .mud-select .mud-input-control {
  width: 190px !important;
  max-width: 190px !important;
}

/* MudDateRangePicker renders TWO date inputs plus separator + adornments side
   by side (~450px of intrinsic content). Sizing must land on the picker root
   only -- descendant rules hit both .mud-input-control wrappers AND the inner
   .mud-input-slot inputs, so each input inherited the cap and the pair painted
   outside its own outline and over the next control. The slots share the box
   via flex so the pair always fills (and stays inside) the outline. */
.hav-app .register-filter-controls .register-filter-date,
.hav-app .register-filter-controls .mud-date-range-picker {
  flex: 0 0 auto !important;
  width: auto !important;
  min-width: 460px !important;
  max-width: 520px !important;
}

.hav-app .register-filter-controls .register-filter-date .mud-input-slot,
.hav-app .register-filter-controls .mud-date-range-picker .mud-input-slot {
  flex: 1 1 0 !important;
  min-width: 0 !important;
}

.hav-app .register-filter-controls .register-filter-chip,
.hav-app .register-filter-controls .mud-chip-container {
  flex: 0 0 auto !important;
  width: auto !important;
}

.hav-app .register-filter-chips {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  gap: 8px !important;
  margin-top: 0 !important;
  padding-top: 12px !important;
}

/* Hide search field floating label inside filter bars -- placeholder + icon carry it. */
.hav-app .register-filter-search .mud-input-label {
  display: none !important;
}

/* Collapse the fieldset legend notch for filter-bar search fields: the label is
   hidden (placeholder + icon carry the cue), so the top border should stay solid. */
.hav-app .register-filter-search .mud-input-outlined-border legend {
  display: none !important;
}

/* Outlined filter-bar inputs keep their own hairline border; the bar is
   a row of controls, not a panel, so each control frames itself. */
.hav-app .register-filter-search .mud-input,
.hav-app .register-filter-controls .mud-select .mud-input {
  background: var(--hav-panel) !important;
}

.hav-app .register-filter-search .mud-input-outlined-border,
.hav-app .register-filter-controls .mud-select .mud-input-outlined-border {
  border-color: var(--hav-line) !important;
}

.hav-app .register-filter-search .mud-input:focus-within .mud-input-outlined-border,
.hav-app .register-filter-controls .mud-select .mud-input:focus-within .mud-input-outlined-border {
  border-color: var(--hav-accent) !important;
}

/* MudBlazor defaults .mud-input to Subtitle1 (Barlow Condensed / 1rem).
   Blueprint form controls use the body face so safety copy and placeholders read at pace. */
.hav-app .register-filter-search .mud-input,
.hav-app .register-filter-controls .mud-select .mud-input,
.hav-app .register-filter-search .mud-input .mud-input-slot,
.hav-app .register-filter-controls .mud-select .mud-input .mud-input-slot {
    font-family: var(--hav-font-body) !important;
    font-size: 0.875rem !important;
}

.hav-app .register-filter-search .mud-input .mud-input-slot::placeholder,
.hav-app .register-filter-controls .mud-select .mud-input .mud-input-slot::placeholder {
    color: var(--hav-text-muted) !important;
    opacity: 1 !important;
}

/* Dashboard stat cards -- blueprint: equal-height KPIs with a uniform semi-transparent colored border */
.hav-app .mud-paper.mud-paper-outlined.dashboard-stat {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 6px 2px;
  min-height: 58px;
  background: transparent !important;
  border-width: 1px !important;
  border-style: solid !important;
  border-color: rgba(203, 213, 225, 0.4) !important /* Chrome <111 fallback */;
  border-color: color-mix(in srgb, var(--hav-line) 40%, transparent) !important;
}


.hav-app .mud-paper.mud-paper-outlined.dashboard-stat-error {
  border-color: color-mix(in srgb, var(--hav-error) 40%, transparent) !important;
}

.hav-app .mud-paper.mud-paper-outlined.dashboard-stat-warning {
  border-color: color-mix(in srgb, var(--hav-warning) 45%, transparent) !important;
}

.hav-app .mud-paper.mud-paper-outlined.dashboard-stat-info {
  border-color: color-mix(in srgb, var(--hav-info) 40%, transparent) !important;
}

.hav-app .mud-paper.mud-paper-outlined.dashboard-stat-success {
  border-color: color-mix(in srgb, var(--hav-success) 40%, transparent) !important;
}

/* Compact recent-incident list rows inside the incidents tile */
.hav-app button.incident-list-button,
.hav-app .incident-list-button {
  min-height: 0 !important;
  height: auto !important;
  padding: 2px 0 !important;
  display: block !important;
  text-align: left !important;
  line-height: 1.25 !important;
}

.hav-app .incident-list-button .mud-button-label {
  display: block !important;
  width: 100% !important;
  padding: 0 !important;
}

.hav-app .incident-list-button .d-flex {
  align-items: center !important;
}

.hav-app .incident-list-button .mud-typography-body2 {
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

.hav-app .incident-list-button .mud-typography-caption {
  white-space: nowrap !important;
  flex: 0 0 auto !important;
}

/* Timeline: tighter spacing and smaller card padding to match blueprint density */
.hav-app .timeline-card .mud-card-content {
  padding: 8px 12px !important;
}

.hav-app .timeline-vertical .mud-timeline-item {
  padding-top: 4px !important;
  padding-bottom: 4px !important;
}

.hav-app .timeline-vertical .mud-timeline-item:last-child {
  padding-bottom: 0 !important;
}

/* Dashboard tile row -- keep it inside the container padding so it aligns with
   the surrounding callouts and sections. The top -8px offset is retained to
   preserve the vertical rhythm against the preceding MudStack gap. */
.hav-app .dashboard-tile-row {
  width: 100% !important;
  max-width: none !important;
  margin: -8px 0 0 0 !important;
}

/* Dashboard tile headers and section labels -- blueprint uses small tracked uppercase */
.hav-app .dashboard-tile-cell .mud-card-header .mud-typography-subtitle1,
.hav-app .dashboard-tile-cell .mud-typography-subtitle2 {
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  font-size: 13px !important;
  color: var(--hav-text) !important;
}

/* Dashboard tile footer actions, timeline load-more, and page-header primary action -- blueprint labels are uppercase */
.hav-app .dashboard-tile-cell .mud-card-actions button[class*="mud-button-"],
.hav-app .dashboard-tile-cell .timeline-content button[class*="mud-button-"],
.hav-app .dashboard-page-header-outer button.dashboard-header-action[class*="mud-button-"] {
  text-transform: uppercase !important;
}

/* H&S Activity tile title is already uppercased by the dashboard tile header rule above. */

/* ==========================================================================
   S.11.6 -- A row fills its width (HAV2130).
   Variable-count rows must not use fixed MudItem md= columns -- the count is
   a query, not a layout promise. Use flexbox so the last row grows to fill.
   ========================================================================== */
.cross-module-insights-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;                                  /* grid gutter token */
  justify-content: flex-start;                /* left-aligned and filled, never centred */
  align-items: stretch;                       /* equal-height cards in a row */
}

.cross-module-insights-grid > * {
  flex: 1 1 var(--cmi-row-min, 280px);
  min-width: min(100%, var(--cmi-row-min, 280px));
  box-sizing: border-box;
}

/* Track floors -- the item's minimum USABLE width, not a column count. */
.cross-module-insights-grid--alerts   { --cmi-row-min: 320px; }
.cross-module-insights-grid--insights { --cmi-row-min: 220px; }

/* Cards / alerts / callouts / insight paper fill the cell width and share a
   common row floor so cross-module insight rows remain the same height. */
.cross-module-insights-grid > .mud-card,
.cross-module-insights-grid > .mud-paper,
.cross-module-insights-grid > .mud-alert,
.cross-module-insights-grid > .hav-callout {
  width: 100%;
  min-height: 160px;
  display: flex;
  flex-direction: column;
}

/* 14px insight card content padding matches blueprint 04 density */
.cross-module-insights-grid .cross-module-insight-card-content {
  padding: 14px !important;
}

/* ==========================================================================
   Dashboard 04 -- patterns bar count badge: a filled accent pill, not the
   muted "(n)" disclose suffix. BaseRecommendationsPanel opt-in via AccentCount.
   ========================================================================== */
.hav-app .hav-count-pill {
  font-family: var(--hav-font-head);
  font-weight: 600;
  font-size: 12px;
  line-height: 1;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  display: inline-grid;
  place-items: center;
  background: var(--hav-accent);
  color: var(--hav-on-accent);
  border-radius: 10px;
}

/* ==========================================================================
   Dashboard 04 -- alert callouts stack full-width above the insight cards;
   they are strips, not tiles in a grid. Insight cards hug their content.
   ========================================================================== */
.cross-module-insights-grid--alerts {
  flex-direction: column;
}

.cross-module-insights-grid--alerts > * {
  flex: 0 0 auto;
  min-width: 0;
}

.cross-module-insights-grid > .mud-card,
.cross-module-insights-grid > .mud-paper,
.cross-module-insights-grid > .mud-alert,
.cross-module-insights-grid > .hav-callout {
  min-height: 0;
}

/* ==========================================================================
   SECTION 3 -- Journey detail bespoke overlay (S.06-A)
   Six classes and two tokens for the journey detail page. No new colour:
   marker colours are status roles the theme already ships. Promote into
   havto-blueprint.css once a second page needs them.
   ========================================================================== */

/* Tokens -- light block, then the dark override, beside the existing --hav-* set */
:root {
  --hav-map-route: var(--hav-accent);
  --hav-map-ground: var(--hav-panel);
  --hav-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --hav-space-2: 8px;
  --hav-space-3: 12px;
  --hav-space-4: 16px;
}
[data-theme="dark"], .mud-theme-dark {
  --hav-map-ground: var(--hav-panel);
}

/* Flush map surface inside a hairline card */
.hav-map {
  padding: 0;
  border-radius: 0;
  border-top: 1px solid var(--hav-line);
  min-height: 450px;
  background: var(--hav-map-ground);
}
.hav-map__failed {
  min-height: 450px;
  display: grid;
  place-items: center;
  padding: var(--hav-space-4);
  background: var(--hav-panel);
  color: var(--hav-text-muted);
  text-align: center;
}
.hav-map__caption {
  padding: var(--hav-space-2) var(--hav-space-4);
  font-family: var(--hav-font-body);
  font-size: 12px;
  color: var(--hav-text-muted);
}

/* Header strip on a padding-less card: icon + title + chip */
.hav-card__strip {
  display: flex;
  align-items: center;
  gap: var(--hav-space-3);
  min-height: 48px;
  padding: 0 var(--hav-space-4);
  border-bottom: 1px solid var(--hav-line);
}

/* Quick stats / Compliance: dense label-left, value-right read-out */
.hav-readout .mud-list-item {
  min-height: 36px;
  padding: var(--hav-space-2) 0;
  border-bottom: 1px solid var(--hav-line);
  background: none;
}
.hav-readout .mud-list-item:last-child { border-bottom: 0; }
.hav-readout .mud-list-item-text { color: var(--hav-text-muted); }
.hav-readout .hav-readout__value { margin-left: auto; font-weight: 600; color: var(--hav-text); }

/* Tabular numerals so coordinate columns align on the decimal */
.hav-num {
  font-family: var(--hav-font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ==========================================================================
   Empty-state plate overrides (HAV2113 + timeline rail slots)
   ListEmptyState wraps itself in a MudPaper. MudBlazor's .mud-paper carries a
   surface fill that overrides the transparent background in .hav-empty on some
   load orders, producing the gray block reported in record-timeline rails.
   Pin .mud-paper.hav-empty to transparent so the dashed plate renders on the
   parent surface, not as a filled box.
   ========================================================================== */
.mud-paper.hav-empty,
.hav-empty.mud-paper {
  background-color: transparent !important;
}

/* ==========================================================================
   Dashboard two-column layout (HAV dashboard shell)
   The main content + sidebar sit side-by-side only when each track is wide
   enough for the 2x2 KPI grid inside the primary column (2x280 + gap).
   This uses the actual container width so it adapts automatically when the
   side nav is open/closed, without a viewport breakpoint.
   ========================================================================== */
.hav-app .dashboard-layout-row {
  --hav-row-min: 576px;
}

/* Nested .hav-row (e.g., stat-card grids) should still use the default floor. */
.hav-app .dashboard-layout-row .hav-row { --hav-row-min: 280px; }
.hav-app .dashboard-layout-row .hav-row.hav-row--kpi { --hav-row-min: 240px; }
.hav-app .dashboard-layout-row .hav-row.hav-row--alert { --hav-row-min: 320px; }

/* ==========================================================================
   Outlined MudTextField / MudSelect floating labels
   MudBlazor renders the floating label with a transparent background and a
   zero-height hidden <legend>. The top border of the fieldset is drawn below
   the label, so a transparent label lets the border show through. Give the
   input and label an opaque surface background and lift the label above the
   fieldset border to stop the "clipped label" look.
   ========================================================================== */
.hav-app .mud-input.mud-input-outlined,
.hav-app .mud-select .mud-input.mud-input-outlined {
  background-color: var(--hav-panel);
}

.hav-app .mud-input-label-outlined {
  background-color: var(--hav-panel) !important;
  z-index: 1 !important;
}

/* ==========================================================================
   Accessibility contrast corrections
   The design-system spec treats warning as a fill only and secondary text as
   a deep step. MudBlazor maps Color.Warning and Color.Secondary to the same
   palette tokens, so text painted with those roles fails on light grounds.
   These overrides route warning-coloured text to its contrast foreground
   (black) and secondary-coloured text to the semantic text-secondary token.
   ========================================================================== */

/* Warning text: never use the amber fill as foreground; use its contrast text.
   These rules are intentionally not scoped to .hav-app so portals and alternate
   layouts (e.g. AuthLayout used by /rate-limit-exceeded) get the same accessible
   contrast. */
.mud-warning-text,
.mud-alert-text-warning,
.mud-alert-outlined-warning,
.mud-alert-text-warning .mud-alert-message,
.mud-alert-outlined-warning .mud-alert-message,
.mud-alert-text-warning .mud-typography,
.mud-alert-outlined-warning .mud-typography {
  color: var(--hav-warning-text) !important;
}

.mud-alert-text-warning .mud-alert-icon,
.mud-alert-outlined-warning .mud-alert-icon {
  color: var(--hav-warning-text) !important;
}

/* Info text/outlined alerts: MudBlazor's default icon can be too light; use the
   darkened variant so text and buttons inside remain WCAG AA on the tint. */
.mud-alert-text-info,
.mud-alert-outlined-info,
.mud-alert-text-info .mud-alert-message,
.mud-alert-outlined-info .mud-alert-message,
.mud-alert-text-info .mud-typography,
.mud-alert-outlined-info .mud-typography,
.mud-alert-text-info .mud-alert-icon,
.mud-alert-outlined-info .mud-alert-icon {
  color: color-mix(in srgb, var(--hav-info) 80%, black) !important;
}

/* Secondary text: use the semantic text-secondary token, which is deep enough
   for both panel and page grounds in light and dark mode. */
.hav-app .mud-secondary-text,
.hav-app .mud-button-text.mud-button-text-secondary .mud-button-label,
.hav-app .mud-button-outlined.mud-button-outlined-secondary .mud-button-label {
  color: var(--hav-text-muted) !important;
}

/* Text buttons inside tinted text/outlined alerts use the alert's readable
   darkened colour so a primary/warning/secondary button never disappears into
   the alert's tinted ground. */
.hav-app .mud-alert-text-info .mud-button-text .mud-button-label,
.hav-app .mud-alert-outlined-info .mud-button-text .mud-button-label {
  color: color-mix(in srgb, var(--hav-info) 80%, black) !important;
}

.hav-app .mud-alert-text-warning .mud-button-text .mud-button-label,
.hav-app .mud-alert-outlined-warning .mud-button-text .mud-button-label {
  color: var(--hav-warning-text) !important;
}

/* KPI captions must stay readable when a KPI is placed on a coloured ground.
   The colour is now carried by the HavKpiPlate CaptionColor/ValueColor
   parameters and the blueprint role tokens, so only force text-primary
   when the plate is genuinely on a tinted callout surface. */
.hav-app .hav-callout .hav-kpi__caption {
  color: var(--hav-text) !important;
}

/* Tinted callout grounds (info/warning/etc at 8-9% over the panel) drop the
   bare muted text below the 4.5:1 AA floor (~4.3:1). Small body text inside a
   callout uses the darker label token; elements carrying an explicit
   mud-*-text colour class keep it. */
.hav-app .hav-callout .mud-typography:not([class*="-text"]),
.hav-app .hav-callout__body {
  color: var(--hav-text-label);
}

/* Data-grid pager: MudBlazor's MudSelect label is used only for the accessible
   name (aria-labelledby); keep the visible "Rows per page" caption and hide the
   generated floating label from sighted users. */
.hav-app .mud-table-pagination-select .mud-input-label {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* HAV2177 -- stub definitions for component classes used by name but not yet spec'd. */
.hav-callout__content { display: block; }
.hav-callout__close { position: absolute; top: 10px; right: 10px; background: transparent; border: 0; cursor: pointer; }
/* Appendix A advisory loading stack: pairs with .hav-skeleton on the same
   element -- the contract object is three __lines at 16px, 8px apart, in a
   120px reserved body. Token overrides only; the kit class supplies display. */
.hav-skeleton-stack { --hav-skeleton-line: 16px; --hav-skeleton-gap: 8px; min-height: 120px; align-content: center; }
.hav-section__body { display: block; }
.hav-kpi__value--sm { font-size: 24px; line-height: 1.1; }

/* Feed timeline item body */
.hav-feed__content,
.hav-feed__text { display: block; min-width: 0; }

/* Accent feed mark -- used for positive/attention highlights */
.hav-feed__mark--accent { background: currentColor; color: var(--hav-accent); }
.hav-feed__mark--warning { background: currentColor; color: var(--hav-warning); }
.hav-feed__mark--error { background: currentColor; color: var(--hav-error); }
.hav-feed__mark--success { background: currentColor; color: var(--hav-success); }
.hav-feed__mark--info { background: currentColor; color: var(--hav-info); }
.hav-feed__mark--muted { background: currentColor; color: var(--hav-text-muted); }

/* Horizontal-scroll section wrapper -- keeps a table inside a clipped container */
.hav-scroll-x { overflow-x: auto; min-width: 0; }

/* Fixed-width icon-only table column (actions menu, row overflow) */
.hav-col-icon { width: 48px; }

/* Permission matrix toggle button and icon */
.hav-matrix__toggle { background: transparent; border: 0; padding: 0; color: var(--hav-text); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.hav-matrix__toggle-icon { display: inline-block; transition: transform 160ms ease; }
.hav-matrix__toggle-icon--collapsed { transform: rotate(-90deg); }
.hav-matrix__denied { font-size: 12px; color: var(--hav-text-muted); }
/* Capability caption note, always-on cell, footer row, and quiet-hours strip */
.hav-matrix__cap-note { display: block; font-size: 11.5px; color: var(--hav-text-muted); }
.hav-matrix__always { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--hav-text-muted); }
.hav-matrix__foot td { padding: 10px 12px; border-top: 1px solid var(--hav-line); }
.hav-matrix__quiet { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; }
.hav-matrix__quiet-title { font-family: var(--hav-font-head); font-weight: 600; font-size: 13px; color: var(--hav-text); }
.hav-matrix__quiet-note { font-size: 12px; color: var(--hav-text-muted); }
/* Correlation grid (S11.58): legend marks sit in text flow, so they need
   inline-block -- in a grid cell the mark is sized by place-items instead. */
.hav-matrix__help .hav-matrix__mark { display: inline-block; vertical-align: -1px; margin: 0 4px 0 14px; }
.hav-matrix__help .hav-matrix__mark:first-child { margin-left: 0; }
/* A correlation cell is read-only -- the kit's .hav-matrix__cell carries
   cursor:pointer for the permission matrix's radio-cell control. */
.hav-matrix__cell--static { cursor: default; }

/* Kiosk queue row (S11.59): the age column is a compared value, so it takes
   the mono face and a fixed width -- a column of times that shifts a pixel
   per row cannot be scanned. */
.hav-list-row--touch .hav-list-row__age {
  flex: 0 0 72px; text-align: end;
  font-family: var(--hav-font-mono); font-size: 14px;
  color: var(--hav-text-muted); white-space: nowrap;
}

/* Skeleton line modifiers beyond the kit pair (kit ships --sm/--md only).
   --lg fills the track; --title stands in for the page heading. */
.hav-skeleton__line--lg { width: 100%; }
.hav-skeleton__line--title { height: 28px; width: 40%; }

/* Table header icon cell */
.hav-th-icon { color: var(--hav-text-muted); }

/* Error text utility (used in place of inline style on QR scanner readouts) */
.text-error { color: var(--hav-error); }

/* AI metric detail colour tokens (HAV2206): colour decision belongs in the token
   layer, not in a C# Color enum. DetailColorClass carries one of these class
   suffixes so the detail line reads against both light and dark themes. */
.ai-metric-detail--success { color: var(--hav-success-text); }
.ai-metric-detail--warning { color: var(--hav-warning-text); }
.ai-metric-detail--error   { color: var(--hav-error-text); }
.ai-metric-detail--info    { color: var(--hav-info-text); }
.ai-metric-detail--neutral { color: var(--hav-text-muted); }

/* Navigation tile (Modules 07-L): the whole tile is the target -- the <a>
   wraps the MudPaper so there is one target, never a link inside a link
   (HAV2192). Title carries the arrow in accent ink (HAV2141); focus ring is
   the global .hav-app a:focus-visible rule. */
.hav-app a.hav-nav-tile { display: block; text-decoration: none; color: inherit; }
.hav-app a.hav-nav-tile .mud-paper { height: 100%; transition: border-color 140ms ease, background-color 140ms ease; }
.hav-app a.hav-nav-tile .hav-h { color: var(--hav-accent); }
.hav-app a.hav-nav-tile:hover .mud-paper {
  border-color: var(--hav-accent) !important;
  background: color-mix(in srgb, var(--hav-accent) 6%, transparent);
}

/* ==========================================================================
   HavFreshnessLine -- s.4 state matrix, Stale row.
   Panel-header meta line: "Updated n min ago" + manual refresh. Past the
   staleness threshold the copy gains "may be out of date"; the stamp itself
   stays muted - a stale value is real and merely old, not an error (HAV2301).
   ========================================================================== */
.hav-freshness {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--hav-font-body);
  font-size: 12px;
  color: var(--hav-text-muted);
}

.hav-freshness__refresh {
  appearance: none;
  border: none;
  background: none;
  padding: 2px 4px;
  font: inherit;
  color: var(--hav-accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.hav-freshness__refresh:disabled {
  color: var(--hav-text-muted);
  cursor: default;
  text-decoration: none;
}

/* The age stamp itself never wraps - the meta line stays one line. */
.hav-freshness__age {
  white-space: nowrap;
}

/* Stale copy gains the "may be out of date" qualifier; never error colour (HAV2301). */
.hav-freshness--stale .hav-freshness__age {
  color: var(--hav-text-muted);
}

/* Host row: right-aligned meta line at the panel/page header edge. */
.hav-freshness-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

/* Stale figures read as reference, not current: the metric region mutes. */
.hav-stale-figures .hav-kpi__value,
.hav-stale-figures .hav-kpi__label,
.hav-stale-figures .hav-stat__value,
.hav-stale-figures .mud-typography {
  color: var(--hav-text-muted) !important;
}

/* Conflict surface -- both versions shown; left rule marks the side, no row tint. */
.hav-conflict-field {
  border: 1px solid var(--hav-line);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.hav-conflict-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 50vh;
  overflow-y: auto;
}

.hav-conflict-field-label {
  color: var(--hav-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.hav-conflict-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.hav-conflict-value-row {
  display: flex;
  align-items: flex-start;
  gap: 4px;
}

.hav-conflict-value {
  border-left: 3px solid var(--hav-line);
  padding-left: 10px;
  min-width: 0;
  flex: 1;
}

.hav-conflict-mine {
  border-left-color: var(--hav-accent);
}

.hav-conflict-theirs {
  border-left-color: var(--hav-error);
}

.hav-conflict-side {
  color: var(--hav-text-muted);
}

.hav-conflict-same {
  color: var(--hav-text-muted);
}

.hav-conflict-merge-toggle {
  color: var(--hav-text-muted);
}

/* Merge mode: the radio group stacks the two pickable sides like the static pair. */
.hav-conflict-pick {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hav-conflict-pick .mud-input-control {
  margin: 0;
}

/* Radio aligns with the first line of its side's value block. */
.hav-conflict-radio {
  align-self: flex-start;
  margin-top: 2px;
}

@media (max-width: 380px) {
  .hav-conflict-pair {
    grid-template-columns: 1fr;
  }
}



/* ==========================================================================
   Repo delta: compact KPI row track
   Standard .hav-row--kpi tiles cap to the 240px floor which leaves sparse
   summary strips (3-4 small counters) stretched thin. The compact modifier
   lowers the auto-fit floor to 180px - the spec's plate minimum (HAV2210).
   ========================================================================== */
.hav-app .hav-row.hav-row--kpi-compact { --hav-row-min: 180px; }

/* Repo delta: a KPI strip inside an intelligence column declares its rungs.
   The left column is a size container so the strip answers to the width it
   actually has. A 4-plate strip that cannot fit 4 x 180px + gutters drops to
   two columns - never a 3+1 wrap (HAV2130) and never below the 180px plate
   floor (HAV2210). */
.hav-app .intelligence-layout > div { container-type: inline-size; }

@container (max-width: 767px) {
  .hav-app .intelligence-layout .hav-row.hav-row--kpi-compact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@container (max-width: 391px) {
  .hav-app .intelligence-layout .hav-row.hav-row--kpi-compact {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   Repo delta: uppercase code inputs
   Identifier fields (project numbers, site codes, WorkSafe refs) normalise to
   uppercase server-side; render them uppercase in the input so the user sees
   the stored shape before submit.
   ========================================================================== */
.hav-app .hav-input-uppercase input { text-transform: uppercase; }

/* ==========================================================================
   Repo delta: .hav-field-cap utility
   Applies the kit's --hav-field-cap token (640px) as a max-width on field
   grids / form columns that must not stretch full-bleed on wide surfaces.
   Replaces the inline style="max-width: var(--hav-field-cap)" pattern the
   inline-style gate rejects. Raise upstream as a kit utility; until the kit
   ships it, the class lives here.
   ========================================================================== */
.hav-app .hav-field-cap { max-width: var(--hav-field-cap); }

/* ==========================================================================
   Safe-area insets -- viewport-fit=cover (installed PWA / notched devices)
   env() resolves to 0 on desktops, iPads, and browsers without cutouts, so
   every rule below is inert there. The model: the app bar's own padding-top
   extends its background into the status band while the toolbar row keeps
   spec height, and every consumer of the --mud-appbar-height offset adds the
   same env() term so nothing renders under the taller bar.
   ========================================================================== */

/* App bar -- bleed the bar background into the status band and clear landscape
   side cutouts. The bar has no fixed height (the .mud-toolbar-appbar row
   carries --mud-appbar-height), so header padding grows it past spec exactly
   by the inset. Unscoped: every shell (.hav-app layouts, dense console bar,
   the non-fixed marketing bar) shares the contract. */
.mud-appbar {
  padding-top: env(safe-area-inset-top, 0px);
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

/* Main content -- MudBlazor derives padding-top from --mud-appbar-height in
   the same three variants the toolbar takes (56 narrow portrait / 48
   landscape / 64 spec). Each gets + the top inset so the scrollport starts
   below the taller bar. Side insets keep page content out of landscape
   cutouts. */
.mud-main-content {
  padding-top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/8 + env(safe-area-inset-top, 0px));
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

@media (min-width: 0px) and (orientation: landscape) {
  .mud-main-content {
    padding-top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/4 + env(safe-area-inset-top, 0px));
  }
}

@media (min-width: 600px) {
  .mud-main-content {
    padding-top: calc(var(--mud-appbar-height) + env(safe-area-inset-top, 0px));
  }
}

/* Dense app bar -- the dense toolbar is pinned to var-1/4 by MudBlazor's
   sibling rule; match it plus the inset. */
.mud-appbar-dense ~ .mud-main-content {
  padding-top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/4 + env(safe-area-inset-top, 0px));
}

/* Clipped drawers -- the nav drawer box top/height tracks the bar in
   MudBlazor's own breakpoints. :not(.hav-panel) excludes overlay side panels,
   which pin top:0/height:100dvh in the kit. */
.mud-drawer-fixed.mud-drawer-clipped-always:not(.hav-panel) {
  top: calc(var(--mud-appbar-height) + env(safe-area-inset-top, 0px));
  height: calc(100% - var(--mud-appbar-height) - env(safe-area-inset-top, 0px));
}

@media (max-width: 599px) and (orientation: landscape) {
  .mud-drawer-fixed.mud-drawer-clipped-always:not(.hav-panel) {
    top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/4 + env(safe-area-inset-top, 0px));
    height: calc(100% - (var(--mud-appbar-height) - var(--mud-appbar-height)/4) - env(safe-area-inset-top, 0px));
  }
}

@media (max-width: 599px) and (orientation: portrait) {
  .mud-drawer-fixed.mud-drawer-clipped-always:not(.hav-panel) {
    top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/8 + env(safe-area-inset-top, 0px));
    height: calc(100% - (var(--mud-appbar-height) - var(--mud-appbar-height)/8) - env(safe-area-inset-top, 0px));
  }
}

/* Dense app bar drawers -- MudBlazor's dense sibling rules carry higher
   specificity, so they need their own matching overrides. */
.mud-appbar-dense ~ .mud-drawer-fixed.mud-drawer-responsive.mud-drawer-clipped-always,
.mud-appbar-dense ~ .mud-drawer-fixed.mud-drawer-temporary.mud-drawer-clipped-always,
.mud-appbar-dense ~ .mud-drawer-fixed.mud-drawer-persistent:not(.mud-drawer-clipped-never) {
  top: calc(var(--mud-appbar-height) - var(--mud-appbar-height)/4 + env(safe-area-inset-top, 0px));
  height: calc(100% - var(--mud-appbar-height) + var(--mud-appbar-height)/4 - env(safe-area-inset-top, 0px));
}

/* Full-height overlays -- side panels (.hav-panel) and unclipped temporary
   drawers pin to the viewport top, so the box itself needs the inset as
   padding to clear the status band. Side + bottom insets apply to every
   fixed drawer so nav items and panel footers clear landscape cutouts and
   the gesture band. */
.mud-drawer-fixed:not(.mud-drawer-clipped-always),
.mud-drawer.hav-panel {
  padding-top: env(safe-area-inset-top, 0px);
}
.mud-drawer-fixed.mud-drawer-pos-left { padding-left: env(safe-area-inset-left, 0px); }
.mud-drawer-fixed.mud-drawer-pos-right { padding-right: env(safe-area-inset-right, 0px); }
.mud-drawer-fixed { padding-bottom: env(safe-area-inset-bottom, 0px); }

/* Commit bar + side-panel commit footer -- sticky at the bottom edge; pad
   the bar so its background bleeds into the gesture band while the buttons
   keep spec height. */
.hav-commit { padding-bottom: env(safe-area-inset-bottom, 0px); }
.hav-panel__footer { padding-bottom: env(safe-area-inset-bottom, 0px); }

/* Kiosk shell -- fixed inset:0 grid; pad the frame so head/body/commit stay
   out of the bands on a wall-mounted tablet or phone. */
.hav-kiosk {
  padding-top: env(safe-area-inset-top, 0px);
  padding-right: env(safe-area-inset-right, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-left: env(safe-area-inset-left, 0px);
}

/* Session-end overlay -- same fixed inset:0 contract as the kiosk. */
.hav-session-end {
  padding-top: env(safe-area-inset-top, 0px);
  padding-right: env(safe-area-inset-right, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-left: env(safe-area-inset-left, 0px);
}

/* Reconnect banner -- fixed top:0 above the app bar z-index; pad its content
   out of the status band and landscape cutouts. */
.hav-reconnect {
  padding-top: calc(8px + env(safe-area-inset-top, 0px));
  padding-left: calc(24px + env(safe-area-inset-left, 0px));
  padding-right: calc(24px + env(safe-area-inset-right, 0px));
}

/* Sticky settings rail -- keeps its 12px gap below the taller bar. */
.hav-settings__rail {
  top: calc(var(--mud-appbar-height, 64px) + 12px + env(safe-area-inset-top, 0px));
}

/* Skip link -- the focused position lands at the viewport corner; clear the
   status band + left cutout. */
.skip-to-main:focus {
  top: calc(0.5rem + env(safe-area-inset-top, 0px));
  left: calc(0.5rem + env(safe-area-inset-left, 0px));
}

/* Snackbars -- shift each location out of the bands via margin so MudBlazor's
   24px placement math is preserved. */
.mud-snackbar-location-top-left,
.mud-snackbar-location-top-center,
.mud-snackbar-location-top-right { margin-top: env(safe-area-inset-top, 0px); }

.mud-snackbar-location-bottom-left,
.mud-snackbar-location-bottom-center,
.mud-snackbar-location-bottom-right { margin-bottom: env(safe-area-inset-bottom, 0px); }

.mud-snackbar-location-top-left,
.mud-snackbar-location-bottom-left { margin-left: env(safe-area-inset-left, 0px); }

.mud-snackbar-location-top-right,
.mud-snackbar-location-bottom-right { margin-right: env(safe-area-inset-right, 0px); }

/* With a commit bar present the kit lifts bottom snackbars above it; add the
   gesture inset on top of that reservation. */
.hav-has-commit .mud-snackbar-location-bottom-left,
.hav-has-commit .mud-snackbar-location-bottom-center,
.hav-has-commit .mud-snackbar-location-bottom-right {
  margin-bottom: calc(var(--hav-commit-h, 64px) + 8px + env(safe-area-inset-bottom, 0px));
}

/* Blazor circuit error banner -- fixed bottom:0; extend its padding so the
   bar background fills the gesture band rather than floating above it. */
body #blazor-error-ui {
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  padding-left: calc(1.25rem + env(safe-area-inset-left, 0px));
  padding-right: calc(3rem + env(safe-area-inset-right, 0px));
}

/* AI help FAB -- fixed near the bottom-right corner; keep it above the
   gesture band and clear of the right cutout. */
.ai-help-fab {
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  right: calc(20px + env(safe-area-inset-right, 0px));
}
