/* ==========================================================================
   Neurobashi WMS 0.6.1 -- shared V2 design system (astra_design_v2/06_claude_handoff).

   CASCADE, in load order, for every portal:
     1. shared/css/base.css            tokens with their 0.6.0 values + the established components
     2. shared/css/design-system.css   THIS FILE: display-mode presentation tokens, shell (sidebar, header,
                                       account menu, mode switch), shared V2 component treatments
     3. portal sheet(s)                employee: /css/employee.css (UX-2G) then /css/workspace.css;
                                       vendor: /vendor/css/vendor.css
   Runtime: shared/js/branding.js writes the Web Studio colours inline on <html>; they beat every rule here.
   Nothing in this file sets a brand colour -- it only consumes --primary, --sidebar, --surface ... .

   DISPLAY MODES: <html data-display-mode="operations|visual"> (shared/js/theme-boot.js sets Operations before
   first paint; shared/js/shell-ui.js applies the account's saved choice). Light/dark is the independent
   data-theme axis, so all four combinations come from the tokens below.
   ========================================================================== */

/* ---- 1. Presentation tokens: Operations (default) ----------------------- */
:root {
  --shell-header-h: 56px;
  --page-pad-top: 16px;
  --page-pad-x: 20px;
  --page-pad-bottom: 40px;
  --grid-gap: 12px;
  --panel-pad: 16px;
  --card-pad: 14px;
  --radius-card: 10px;
  --radius-control: 8px;
  --title-size: 1.75rem;           /* 28px */
  --kpi-min-h: 76px;
  --kpi-value: 1.6rem;
  --nav-row: 40px;
  --shadow: 0 1px 2px #1021370f, 0 2px 8px #1021370d;
  --focus-ring: var(--primary);
}
/* ---- Visual (optional per-account preference) ---------------------------- */
:root[data-display-mode="visual"] {
  --shell-header-h: 64px;
  --page-pad-top: 24px;
  --page-pad-x: 24px;
  --grid-gap: 16px;
  --panel-pad: 20px;
  --card-pad: 18px;
  --radius-card: 12px;
  --title-size: 2rem;              /* 32px */
  --kpi-min-h: 104px;
  --kpi-value: 2.1rem;
  --nav-row: 44px;
  --shadow: 0 1px 2px #1021370d, 0 6px 20px #10213714;
}
:root[data-theme="dark"] { --shadow: 0 1px 2px #00000040, 0 2px 8px #00000038; }
:root[data-theme="dark"][data-display-mode="visual"] { --shadow: 0 1px 2px #00000040, 0 8px 24px #00000052; }
@media (max-width: 1366px) { :root[data-display-mode="visual"] { --page-pad-x: 20px; --page-pad-top: 20px; } }

/* Decoration exists only in Visual. Functional content is never hidden by mode. */
:root:not([data-display-mode="visual"]) .decor { display: none !important; }

/* ---- 2. No-flash start-up: the gate rule lives at the end of base.css, so the sign-in page (which loads
   only base.css) is gated by the same one rule. ---------------------------------------------------- */

/* The app moves focus to <main tabindex="-1"> after each navigation (for screen readers). It is never reachable by
   Tab, so the browser's default ring around the whole workspace is noise, not a focus indicator. */
#mainContent:focus { outline: none; }

/* ---- 3. Icons ------------------------------------------------------------- */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- 4. Application frame and sidebar ------------------------------------ */
.app { --sidebar-width: 224px; }
@media (max-width: 1500px) { .app { --sidebar-width: 216px; } }
@media (max-width: 1400px) { .app { --sidebar-width: 208px; } }
@media (min-width: 801px) { .app[data-sidebar-collapsed="true"] { --sidebar-width: 72px; } }
.work { padding: var(--page-pad-top) var(--page-pad-x) var(--page-pad-bottom); }

.side {
  padding: 18px 12px 12px;
  gap: 16px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--sidebar) 88%, #ffffff 12%) 0%, var(--sidebar) 38%, var(--sidebar) 100%);
}
.side .brand { gap: 10px; padding: 0 6px; }
.mark:not(.has-logo) { background: transparent; box-shadow: none; width: 38px; height: 38px; }
.mark .brand-cube { width: 36px; height: 36px; fill: none; stroke: color-mix(in srgb, var(--accent) 55%, var(--on-sidebar)); stroke-width: 2; stroke-linejoin: round; }   /* follows Studio: readable on any sidebar */
.side .brand h1 { font-size: 1.12rem; font-weight: 800; letter-spacing: -.01em; }
.side .brand .eyebrow { opacity: .7; }
.side-scroll { gap: 14px; }
.nav-group + .nav-group { margin-top: 10px; padding-top: 10px; border-top: 1px solid color-mix(in srgb, var(--on-sidebar) 10%, transparent); }
.nav-group-title { padding-inline: 12px; margin-bottom: 4px; font-size: .68rem; letter-spacing: .09em; opacity: .62; }
.side .nav button {
  min-height: var(--nav-row);
  gap: 12px;
  padding: 8px 12px;
  border-radius: 8px;
  color: color-mix(in srgb, var(--on-sidebar) 88%, transparent);
  font-size: .9rem;
  font-weight: 600;
}
.side .nav button .nav-icon svg { width: 20px; height: 20px; }
.side .nav button:hover { background: color-mix(in srgb, var(--on-sidebar) 9%, transparent); color: var(--on-sidebar); }
.side .nav button.active {
  background: var(--primary);
  color: var(--on-primary);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--primary) 32%, transparent);
}
.side .nav button.active::before { display: none; }
.side .nav button:focus-visible { outline: 2px solid var(--on-sidebar); outline-offset: 2px; }
.side-footer:empty { display: none; }
/* Expanded desktop sidebar: a label that does not fit wraps to a second line instead of losing its end
   ("Inbound shipments" was "Inbound ship..." at 1366 px on every platform, and at 1440 px with Linux fonts). */
@media (min-width: 801px) {
  .app:not([data-sidebar-collapsed="true"]) .side .nav .nav-label { white-space: normal; text-overflow: clip; line-height: 1.2; }
}
.idle-controls { padding-top: 10px; border-top-color: color-mix(in srgb, var(--on-sidebar) 12%, transparent); }
.sidebar-collapse-toggle { width: 100%; justify-content: flex-start; gap: 10px; min-height: 40px; padding: 8px 12px; color: var(--on-sidebar); }
@media (min-width: 801px) {
  .app[data-sidebar-collapsed="true"] .sidebar-collapse-toggle { justify-content: center; padding: 8px; }
  .app[data-sidebar-collapsed="true"] .sidebar-collapse-label { display: none; }
}

/* ---- Collapsed rail (desktop): icons only, one centred column -------------------------------------------
   Both portals. The column is the rail's own width, so no label, heading or fixed size can widen it (the
   vendor's Account heading did: 85 px buttons in a 52 px column, a sideways scrollbar, icons 17 px off centre).
   Rows are a compact 34 px in both display modes (44 px on a touch screen), so a warehouse manager's 15 fit a
   768 px laptop. An account with more destinations than the viewport holds (a system owner has 24) scrolls the icon column by wheel, touch or keyboard focus, with no visible bar and
   faded ends; every destination stays reachable. The collapse control is not in that column (sidebar.js puts
   it in .idle-controls, a sibling below), so it never moves. Each icon keeps its title tooltip and aria-label
   (sidebar.js). Group headings: employee in workspace.css, vendor in vendor.css. */
@media (min-width: 801px) {
  .app[data-sidebar-collapsed="true"] .side { padding: 14px 10px 10px; gap: 10px; }
  .app[data-sidebar-collapsed="true"] .side-scroll { gap: 0; overflow: hidden; }
  .app[data-sidebar-collapsed="true"] .nav {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
    padding: 12px 4px;   /* room for the focus ring inside the clipping column */
    overflow-x: hidden;
    scrollbar-width: none;
    scroll-padding-block: 12px;
    -webkit-mask-image: linear-gradient(transparent, #000 12px, #000 calc(100% - 12px), transparent);
    mask-image: linear-gradient(transparent, #000 12px, #000 calc(100% - 12px), transparent);
  }
  .app[data-sidebar-collapsed="true"] .nav::-webkit-scrollbar { display: none; }
  .app[data-sidebar-collapsed="true"] .side .nav button { height: 34px; min-height: 34px; padding: 0; gap: 0; justify-content: center; }
  .app[data-sidebar-collapsed="true"] .nav-group-title { display: none; }
  .app[data-sidebar-collapsed="true"] .idle-controls { justify-content: center; padding-top: 8px; }
  .app[data-sidebar-collapsed="true"] .sidebar-collapse-toggle { width: 44px; min-height: 40px; border-color: transparent; background: transparent; }
  .app[data-sidebar-collapsed="true"] .sidebar-collapse-toggle:hover,
  .app[data-sidebar-collapsed="true"] .sidebar-collapse-toggle:focus-visible { background: color-mix(in srgb, var(--on-sidebar) 9%, transparent); }
}
@media (min-width: 801px) and (pointer: coarse) {
  .app[data-sidebar-collapsed="true"] .side .nav button { height: 44px; min-height: 44px; }
}

/* ---- 5. Header: breadcrumb + session controls ----------------------------- */
.top {
  position: sticky;
  top: 0;
  z-index: 30;
  min-height: var(--shell-header-h);   /* 56 / 64: the 46px account trigger + 2 x 4px + the 1px rule fits both */
  margin: calc(-1 * var(--page-pad-top)) calc(-1 * var(--page-pad-x)) 0;
  padding: 4px var(--page-pad-x);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  backdrop-filter: none;
}
:root[data-display-mode="visual"] .top { border-bottom-color: transparent; box-shadow: 0 1px 2px #1021370a, 0 4px 14px #1021370f; }
:root[data-theme="dark"][data-display-mode="visual"] .top { box-shadow: 0 1px 0 var(--border); }
.breadcrumb { gap: 8px; font-size: .84rem; color: var(--primary-dark); }
.breadcrumb strong { font-weight: 700; }
.page-title { margin: 20px 0 6px; font-size: var(--title-size); line-height: 1.15; font-weight: 800; letter-spacing: -.025em; }

.shell-actions { display: flex; align-items: center; gap: 4px; min-width: 0; }
.shell-actions > .btn {
  min-height: 40px;
  padding: 8px 10px;
  border-color: transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
}
.shell-actions > .btn:hover { background: var(--surface-soft); border-color: transparent; }
.shell-actions .side-action-icon svg { width: 20px; height: 20px; }
.shell-icon { width: 44px; height: 44px; min-width: 44px; min-height: 44px; padding: 0; display: inline-grid; place-items: center; font-size: 1.15rem; }
.shell-icon[aria-pressed="true"] { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-dark); }
.mode-toggle { position: relative; }
.mode-toggle[aria-pressed="true"]::after {   /* the non-colour "selected" mark (specimen 22) */
  content: "\2713";
  position: absolute;
  top: -5px;
  right: -5px;
  width: 17px;
  height: 17px;
  display: grid;
  place-items: center;
  border: 2px solid var(--surface);
  border-radius: 50%;
  background: var(--primary);
  color: var(--on-primary);
  font-size: 10px;
  font-weight: 900;
  line-height: 1;
}
.shell-divider { width: 1px; height: 26px; margin: 0 6px; background: var(--border); }
.top .idle-timer { margin: 0 4px; color: var(--muted); font-size: .84rem; font-weight: 600; white-space: nowrap; }
.top .idle-timer::before { content: "Session "; font-weight: 500; }
.top .idle-timer.idle-timer-warning { color: var(--danger); }

.account-trigger {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 4px 10px 4px 4px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
}
.account-trigger:hover { background: var(--surface-soft); }
.account-trigger .avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--sidebar);
  color: var(--on-sidebar);
  font-size: .76rem;
  font-weight: 800;
}
.account-trigger .avatar img { width: 100%; height: 100%; object-fit: cover; }
.account-text { display: grid; min-width: 0; max-width: 190px; text-align: left; line-height: 1.2; }
.account-text strong, .account-text span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-text strong { font-size: .86rem; }
.account-text span { color: var(--muted); font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; }
/* Mid widths (801-1099 px): beside the sidebar the header row has about 550-850 px, too little for every label --
   the account button was pushed off-screen at 801-960 px (both portals). Refresh and Unlock layout show their icon
   only (their aria-label and title still name them), the account shows its avatar, the timer drops its word, and a
   long breadcrumb may wrap instead of pushing the row wider. */
@media (min-width: 801px) and (max-width: 1099px) {
  .shell-actions > .shell-text .side-action-label { display: none; }
  .shell-actions > .shell-text { padding-inline: 10px; }
  .account-trigger { gap: 4px; }
  .account-trigger .account-text { display: none; }
  .top .idle-timer::before { content: none; }
  .breadcrumb { min-width: 0; flex-wrap: wrap; }
}
/* Touch: every sidebar/menu row and header action is at least 44 px in both modes (Operations rows are 40 px for a
   mouse; the phone menu had no touch floor, and these header buttons out-specified the coarse .btn rule). */
@media (pointer: coarse) {
  :root { --nav-row: 44px; }
  .shell-actions > .btn { min-height: 44px; }
}
.account-chevron { width: 16px; height: 16px; color: var(--muted); }

.account-menu-panel {
  position: fixed;
  inset: auto;
  top: calc(var(--shell-header-h) + 6px);
  right: 12px;
  margin: 0;
  min-width: 240px;
  max-width: min(320px, calc(100vw - 24px));
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 16px 40px #0d182533;
}
.account-menu-panel .menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  text-align: left;
  text-decoration: none;   /* My profile is a link */
  cursor: pointer;
}
.account-menu-panel .menu-item:hover, .account-menu-panel .menu-item:focus-visible { background: var(--surface-soft); }
.account-menu-panel .menu-item .side-action-icon svg, .account-menu-panel .menu-item .ico { width: 18px; height: 18px; }
.account-menu-panel .menu-item + .menu-item#logout { margin-top: 4px; border-top: 1px solid var(--border); border-radius: 0 0 8px 8px; }

.mode-status.mode-status-warning {   /* storage failed: say so once, without blocking anything */
  position: fixed;
  z-index: 50;
  top: calc(var(--shell-header-h) + 8px);
  right: 16px;
  width: auto;
  height: auto;
  max-width: min(360px, calc(100vw - 32px));
  margin: 0;
  padding: 10px 14px;
  overflow: visible;
  clip: auto;
  white-space: normal;
  border: 1px solid var(--warning);
  border-radius: 10px;
  background: var(--warning-soft);
  color: var(--warning);
  font-weight: 600;
}

/* ---- 6. Shared component treatments (V2) --------------------------------- */
.panel, .card { border-color: var(--border); }
.btn { border-radius: var(--radius-control); }
.btn .ico { width: 18px; height: 18px; }
.btn.primary { box-shadow: 0 1px 2px color-mix(in srgb, var(--primary) 30%, transparent); }
:root[data-display-mode="visual"] .btn.primary { box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 30%, transparent); }
.empty-state.error { color: var(--danger); }
:where(.btn, .nav button, input, select, textarea, [role="button"], tr[tabindex], a, .table[tabindex], .sort-button,
  .account-trigger, .menu-item, .home-task, .queue-tile):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---- 7. Narrow shell (<= 800px): menu + brand on the navy bar, theme / mode / account fixed beside them -- */
@media (max-width: 800px) {
  :root, :root[data-display-mode="visual"] { --page-pad-x: 16px; --page-pad-top: 14px; }
  .side { min-height: 64px; padding: 10px 172px 10px 12px; }   /* the right padding reserves the fixed header icons' row */
  .side-scroll { flex-basis: calc(100% + 160px); margin-right: -160px; }   /* ...which the opened menu, on its own row, gets back (172 - 12) */
  .btn.nav-toggle { order: 0; margin-left: 0; width: 44px; min-width: 44px; min-height: 44px; padding: 0; justify-content: center; }
  .btn.nav-toggle > span:not([aria-hidden]) { display: none; }
  /* The brand takes what is left of the bar's one row (basis 0), so a classic 15px scrollbar or a narrow window
     shrinks the logo instead of pushing it onto a second row. */
  .side .brand,
  .side .brand.system-logo-only:not(.company-logo-only),
  .side .brand[data-company-brand].company-logo-only { order: 1; flex: 1 1 0; min-width: 0; max-width: 100%; }
  .side .brand.system-logo-only:not(.company-logo-only),
  .side .brand[data-company-brand].company-logo-only { max-width: 132px; }
  .side .brand.system-logo-only:not(.company-logo-only) .mark,
  .side .brand[data-company-brand].company-logo-only [data-company-logo] { width: 100%; max-width: 132px; height: 44px; }
  .side .brand > div { min-width: 0; }
  .side .brand h1, .side .brand .eyebrow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .top {
    position: static;
    margin: 0 calc(-1 * var(--page-pad-x));
    min-height: 0;
    padding: 6px var(--page-pad-x);
    justify-content: flex-end;
  }
  .shell-actions { width: 100%; justify-content: flex-start; flex-wrap: wrap; }
  .shell-divider { display: none; }
  #themeToggle, #displayModeToggle, #accountMenuButton {
    position: fixed;
    z-index: 45;
    top: 10px;
    color: var(--on-sidebar);
    border-color: color-mix(in srgb, var(--on-sidebar) 28%, transparent);
    background: transparent;
  }
  #accountMenuButton { right: 12px; width: 44px; padding: 3px; justify-content: center; }
  #displayModeToggle { right: 64px; }
  #themeToggle { right: 116px; }
  #displayModeToggle[aria-pressed="true"] { border-color: var(--on-sidebar); background: color-mix(in srgb, var(--on-sidebar) 14%, transparent); color: var(--on-sidebar); }
  #displayModeToggle[aria-pressed="true"]::after { border-color: var(--sidebar); }
  .account-trigger .account-text, .account-chevron { display: none; }
  .account-trigger .avatar { width: 36px; height: 36px; background: color-mix(in srgb, var(--on-sidebar) 16%, transparent); }
  .account-menu-panel { top: 62px; right: 8px; }
  .top .idle-timer:not([hidden]) { display: block; order: 3; flex: 0 0 auto; margin: 0 0 0 auto; }
  .page-title { margin-top: 14px; font-size: clamp(1.5rem, 6vw, 1.75rem); }
}
@media (max-width: 360px) {
  .side .brand > div { display: none; }   /* logo-only brand before any target shrinks */
}

@media (prefers-reduced-motion: reduce) {
  .side .nav button, .account-trigger, .shell-actions > .btn { transition: none; }
}
@media (forced-colors: active) {
  .mode-toggle[aria-pressed="true"] { outline: 2px solid CanvasText; }
  .mode-toggle[aria-pressed="true"]::after { forced-color-adjust: none; background: Highlight; color: HighlightText; }
}

/* ==========================================================================================================
   7. Shared V2 components (Phase 3) -- every screen of both portals
   One treatment per component, from astra_design_v2/06_claude_handoff/COMPONENT_SPECIFICATIONS.md. Density and
   elevation come from the mode tokens, so Operations and Visual are the same markup, ids and listeners; only
   presentation differs. Portal sheets add portal-specific layout only. Text casing and labels are unchanged.
   ========================================================================================================== */
:root {
  --control-height: 40px;          /* buttons */
  --field-height: 40px;            /* inputs, selects */
  --cell-pad-y: 9px;               /* table rows: 40 px pointer rows */
  --cell-pad-x: 12px;
  --tab-h: 40px;
  --label-color: var(--text);
}
:root[data-display-mode="visual"] {
  --control-height: 44px;
  --field-height: 44px;
  --cell-pad-y: 12px;              /* 44 px rows */
  --cell-pad-x: 14px;
  --tab-h: 44px;
}
@media (pointer: coarse) { :root { --control-height: 44px; --field-height: 44px; --cell-pad-y: 12px; --tab-h: 44px; } }

/* Page heading: eyebrow, subtitle, page actions on the right. Visual gives the subtitle the brand voice. */
.page-heading, .head { align-items: center; gap: 16px; margin-bottom: var(--grid-gap); }
.page-heading p, .head p { font-size: .94rem; }
:root[data-display-mode="visual"] .page-heading p { color: var(--primary-dark); font-size: 1.02rem; }
.page-heading .btn.primary, .head .btn.primary { min-height: var(--control-height); padding-inline: 18px; }

/* Buttons */
.btn { border-radius: var(--radius-control); padding-inline: 14px; font-weight: 650; transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease; }
.btn.primary { box-shadow: 0 1px 2px color-mix(in srgb, var(--primary) 28%, transparent); }
:root[data-display-mode="visual"] .btn.primary { box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 26%, transparent); }
.btn.danger { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.btn.small { border-radius: calc(var(--radius-control) - 2px); }

/* Panels and cards: a fine border in Operations; Visual lifts them on a soft shadow */
.panel, .card { border-radius: var(--radius-card); }
:root[data-display-mode="visual"] .panel, :root[data-display-mode="visual"] .page:not(#dashboard) .card { border-color: color-mix(in srgb, var(--border) 55%, transparent); }
.panel-heading h4 { font-size: 1.02rem; font-weight: 750; }

/* Page-level status cards (Orders, Inbound ...): one divided strip in Operations, separate cards in Visual */
.page:not(#dashboard) .cards.status-cards { gap: 0; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--surface); box-shadow: var(--shadow); }
.page:not(#dashboard) .cards.status-cards > .card { border: 0; border-radius: 0; box-shadow: none; }
.page:not(#dashboard) .cards.status-cards > .card + .card { border-left: 1px solid var(--border); }
:root[data-display-mode="visual"] .page:not(#dashboard) .cards.status-cards { gap: var(--grid-gap); overflow: visible; border: 0; background: transparent; box-shadow: none; }
:root[data-display-mode="visual"] .page:not(#dashboard) .cards.status-cards > .card { border: 1px solid color-mix(in srgb, var(--border) 55%, transparent); border-radius: var(--radius-card); box-shadow: var(--shadow); }
:root[data-display-mode="visual"] .page:not(#dashboard) .cards.status-cards > .card + .card { border-left-width: 1px; }

/* Tabs: an underline strip on the panel surface */
.queue-tabs { gap: 2px; padding: 0 6px; border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--surface); box-shadow: var(--shadow); }
.queue-tabs button { min-height: var(--tab-h); border-radius: 0; }
.queue-tabs button[aria-selected="true"] { box-shadow: inset 0 -3px var(--primary); }

/* Filters: labelled fields on the panel; labels read as labels, not captions */
.filter-toolbar { gap: var(--grid-gap); }
.field > span, .check-field > span { color: var(--label-color); font-size: .8rem; font-weight: 650; }
input, select, textarea { border-color: var(--border-strong); transition: border-color .12s ease, box-shadow .12s ease; }
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) { border-color: color-mix(in srgb, var(--primary) 35%, var(--border-strong)); }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--primary); outline: 2px solid color-mix(in srgb, var(--primary) 45%, transparent); outline-offset: 1px; }
.filter-disclosure > summary { border-radius: var(--radius-control); }

/* Tables: soft header, mode row height, clear hover */
.table { border-radius: var(--radius-card); box-shadow: var(--shadow); }
:root[data-display-mode="visual"] .table { border-color: color-mix(in srgb, var(--border) 55%, transparent); }
th, td { padding: var(--cell-pad-y) var(--cell-pad-x); }
th { color: color-mix(in srgb, var(--text) 70%, var(--muted)); font-size: .7rem; }
.grid-table th, .grid-table td { padding: 6px; }   /* editing grids keep their own density */
tbody tr:hover td { background: color-mix(in srgb, var(--surface-soft) 70%, transparent); }
.selectable-table tbody tr.selected td { background: var(--primary-soft); }

/* Badges: compact pill with a subtle tone border (never colour alone: the label is the state) */
.badge { border: 1px solid color-mix(in srgb, currentColor 18%, transparent); }

/* Dialogs and drawers: native, same ids; padding by mode */
.dialog-header, .dialog-footer { padding: var(--panel-pad) calc(var(--panel-pad) + 2px); }
.dialog-body { padding: calc(var(--panel-pad) + 2px); }
.dialog-header h3 { font-size: 1.2rem; font-weight: 750; letter-spacing: -.01em; }
:root[data-display-mode="visual"] .dialog-header h3 { font-size: 1.32rem; }

/* States: empty / loading / message */
.empty-state { border-radius: var(--radius-card); }
:root[data-display-mode="visual"] .panel .empty-state:not(:has(> .table)) { background: color-mix(in srgb, var(--surface-soft) 60%, transparent); }
.toast { border-radius: var(--radius-card); box-shadow: var(--shadow-dialog); }


/* Record lists fit their panel (owner issue A: Orders scrolled sideways at 1440 px). Headers and text cells may
   wrap at word boundaries, so the browser fits the columns to the width; identifiers never break mid-code
   (overflow-wrap stays normal), states and actions stay on one line, nothing is hidden, and a list that still
   cannot fit keeps the named horizontal scroll. Column order saved by TableTools is unaffected (no nth-child). */
.selectable-table th, .selectable-table td { white-space: normal; padding-inline: calc(var(--cell-pad-x) - 4px); }
.selectable-table th { min-width: 4.5em; }
.selectable-table th .sort-button { white-space: normal; text-align: left; }
.selectable-table td.primary-cell, .selectable-table td .badge, .selectable-table td .btn, .selectable-table td time { white-space: nowrap; }
.selectable-table td.primary-cell .secondary-cell { white-space: nowrap; }
/* A field whose label is nested one level deeper (searchable pickers) reads like every other label */
.field > label > span { display: block; margin-bottom: 6px; color: var(--label-color); font-size: .8rem; font-weight: 650; }

/* Native check controls keep their native size: the generic field rule (width 100%, field height) must not
   stretch a radio or checkbox. :where() keeps this below every component's own checkbox rule. */
:where(input)[type="radio"], :where(input)[type="checkbox"] { width: 18px; height: 18px; min-height: 0; padding: 0; flex: 0 0 auto; accent-color: var(--primary); }
/* Touch: keep 0.6.0's floor (base.css `input { min-height: 44px }` under a coarse pointer), which the min-height: 0
   above overrode -- the Exceptions row checkboxes measured 18 px on a phone (ux2g_b touch-target test). Components
   that size their own checkbox and give the label the 44 px (`.field.checkbox`, `.check-field`, `.nr-events`) win. */
@media (pointer: coarse) {
  :where(input)[type="radio"], :where(input)[type="checkbox"] { min-height: 44px; }
}

/* ---- 8. Sign-in and first-run setup ---------------------------------------------------------------------
   Sign-in takes the installation's branding (branding.js) exactly as before; these pages now share the
   component layer above. First-run setup runs before any configuration exists, so it shows the palette a
   fresh installation is created with (services/setup.FRESH_INSTALL_BRANDING_COLORS, as branding.js derives
   it), never another customer's colours. */
body.setup-page {
  --primary: #1764F6; --primary-dark: #1764F6; --primary-soft: #1764F618; --on-primary: #ffffff;
  --sidebar: #102137; --on-sidebar: #ffffff; --accent: #0F8DA8; --accent-text: #0d7c94; --focus: #1764F6;
  background: var(--background);
}
/* light surfaces as a fresh install derives them; dark keeps the existing dark surface tokens */
:root:not([data-theme="dark"]) body.setup-page { --background: #F3F7FD; --surface: #FFFFFF; --surface-soft: #f8fbfe; --border: #e3e4e6; --border-strong: #ccced0; }
.setup-page .brand { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.setup-page .brand .mark { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: var(--sidebar); box-shadow: none; }
.setup-page .brand .brand-cube { width: 30px; height: 30px; }
.setup-page #serialSetupChoice { display: grid; gap: 10px; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-card); }
.setup-page #serialSetupChoice legend { padding: 0 6px; color: var(--text); font-size: .9rem; font-weight: 700; }
.setup-page #serialSetupChoice label { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius-control); cursor: pointer; }
.setup-page #serialSetupChoice label:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); }
.setup-page .btn.primary { min-height: 44px; }
.auth .field > span { font-size: .84rem; }

/* ---- Phase 3 review fixes (evidence/phase3/REVIEW_C1.md) ------------------------------------------------ */
/* D01: a primary button that is also destructive is a filled danger button (red text on blue was unreadable) */
.btn.primary.danger { background: var(--danger); border-color: var(--danger); color: #ffffff; box-shadow: none; }
.btn.primary.danger:hover { background: color-mix(in srgb, var(--danger) 86%, #000000); border-color: color-mix(in srgb, var(--danger) 86%, #000000); }
/* Dark theme: --danger is a light red (readable as text on dark surfaces), too light under white text (3.1:1);
   the filled button darkens it to 6.8:1. Notes/warnings: base.css fixes light-theme text colours that the dark
   soft backgrounds made unreadable (1.4:1 and 1.9:1); a media preview stays white, so its caption stays dark. */
:root[data-theme="dark"] .btn.primary.danger { background: color-mix(in srgb, var(--danger) 62%, #000000); border-color: color-mix(in srgb, var(--danger) 62%, #000000); }
:root[data-theme="dark"] .btn.primary.danger:hover { background: color-mix(in srgb, var(--danger) 52%, #000000); border-color: color-mix(in srgb, var(--danger) 52%, #000000); }
:root[data-theme="dark"] .info-banner { border-color: color-mix(in srgb, var(--primary) 45%, transparent); color: var(--text); }
:root[data-theme="dark"] .warning-box { border-color: color-mix(in srgb, #f0c78c 40%, transparent); color: #f0c78c; }
:root[data-theme="dark"] .media-preview:not(.landscape) .muted { color: #5f6b76; }
/* D04/D06/D07/D13: a button placed directly in a form grid keeps its natural size, aligned with the fields */
.form-grid > .btn, .form-grid > button.btn { align-self: end; justify-self: start; }
/* D09/D10: single-line fields share one height (date inputs were 42-46 px next to 40 px selects); filter
   fields get room for their own values */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]), select { height: var(--field-height); }
.grid-table input, .grid-table select { height: auto; }   /* editing grids keep their own compact rows */
.filter-toolbar .field { min-width: 11rem; }
/* D14 + test_58: on a phone the page status strip scrolls sideways again instead of clipping its cards (DEF-PEO-03: in Visual too) */
@media (max-width: 800px) { .page:not(#dashboard) .cards.status-cards, :root[data-display-mode] .page:not(#dashboard) .cards.status-cards { overflow-x: auto; overscroll-behavior-inline: contain; } }
/* D11: a list wider than its panel shows a scroll edge where more columns are (CSS-only cue; the table itself
   is transparent so the cue paints behind the rows) */
.table {
  background:
    linear-gradient(to right, var(--surface) 30%, transparent) left / 28px 100% no-repeat local,
    linear-gradient(to left, var(--surface) 30%, transparent) right / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--text) 18%, transparent), transparent) left / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--text) 18%, transparent), transparent) right / 12px 100% no-repeat scroll,
    var(--surface);
}
.table > table { background: transparent; }
/* D16: the Visual subtitle keeps the brand voice without reading as a link */
:root[data-display-mode="visual"] .page-heading p { color: color-mix(in srgb, var(--primary-dark) 62%, var(--text)); }
/* D05: lists and the paragraphs/cards around them get breathing room */
.panel > p + .table, .panel > .table + .panel, .page > .table + .panel, .page > p + .table { margin-top: var(--grid-gap); }
/* D08: action clusters inside cards wrap instead of overflowing the card */
.panel .actions, .card .actions { flex-wrap: wrap; min-width: 0; }
/* D22: a disclosure always shows its affordance */
details > summary { cursor: pointer; }
/* D23: the sticky Studio save bar never covers the last fields */
.settings-savebar { z-index: 5; }
/* D24: on a phone a page's own action (New order, Create account ...) is a full-width control under the intro,
   not a centred orphan */
@media (max-width: 800px) {
  .page-heading { align-items: stretch; }
  .page-heading > .btn, .page-heading > .actions { width: 100%; }
  .page-heading > .btn { justify-content: center; }
}
