/* ui_v2.css — design system for the rebuilt UI.
   Single rulebook: every page rebuilt under the new design extends app_base_v2
   and reads from this file. Tokens, primitives, and shell components only —
   page-specific styles live with the page. */

:root {
  /* Greens */
  --green-900: oklch(36% 0.10 150);
  --green-700: oklch(48% 0.13 148);
  --green-600: oklch(55% 0.13 148);
  --green-500: oklch(62% 0.14 148);
  --green-100: oklch(96% 0.03 148);
  --green-050: oklch(98.5% 0.015 148);

  /* Warm neutrals (ink) */
  --ink-900: oklch(22% 0.01 110);
  --ink-700: oklch(40% 0.01 110);
  --ink-500: oklch(58% 0.008 110);
  --ink-400: oklch(70% 0.006 110);
  --ink-200: oklch(90% 0.005 110);
  --ink-150: oklch(93% 0.005 110);
  --ink-100: oklch(96% 0.004 110);
  --ink-050: oklch(98.5% 0.004 110);
  --paper:   oklch(99.2% 0.003 110);

  /* Status accents */
  --amber: oklch(72% 0.16 75);
  --amber-ink: oklch(35% 0.10 60);
  --rose:  oklch(62% 0.18 25);
  --plum:  oklch(48% 0.16 305);
  --sky:   oklch(60% 0.13 240);

  --shadow-sm: 0 1px 2px rgba(20,15,10,.04), 0 1px 1px rgba(20,15,10,.03);
  --shadow-md: 0 1px 2px rgba(20,15,10,.04), 0 4px 12px rgba(20,15,10,.05), 0 12px 32px -16px rgba(20,15,10,.10);
  --shadow-lg: 0 2px 4px rgba(20,15,10,.04), 0 12px 28px -8px rgba(20,15,10,.10), 0 24px 56px -24px rgba(20,15,10,.15);

  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 14px;

  /* Spreadsheet sticky-header alignment. The page-title head
     (.uiv2-workboard__head) is pinned to this exact height and the
     sticky column-header row (.uiv2-table__header) locks at this same
     `top`, so the two stack flush with no overlap (column labels never
     clip behind the title) and no gap (rows can't bleed between them).
     One value drives both — they can't drift. */
  --uiv2-workboard-head-h: 76px;
}

/* Reset for the v2 shell only — does not affect old templates. */
.uiv2, .uiv2 * { box-sizing: border-box; }
.uiv2 {
  margin: 0;
  font-family: "Inter Tight", system-ui, sans-serif;
  color: var(--ink-900);
  background: var(--ink-050);
  min-height: 100vh;
}
/* Anchors inside the .uiv2 shell get a baseline reset (inherit color
   from parent + no underline). `:where()` keeps the selector matching
   the same elements but contributes ZERO specificity, so any per-
   component `color:` rule (.uiv2-btn--primary white-on-green, .uiv2-link
   green text, .uiv2-rail__pill--active green-900, .uiv2-card__link, etc.)
   wins on its own without needing !important or per-class overrides.
   Without :where(), the (0,1,1) specificity of `.uiv2 a` was beating
   every (0,1,0) component-level color rule on anchor elements — the
   bug Reid caught in G5 visual review where Record Fulfillment buttons
   rendered with dark inherited text instead of the white from
   .uiv2-btn--primary. */
:where(.uiv2 a) { color: inherit; text-decoration: none; }
.uiv2 button { font: inherit; }

/* Mono utility */
.uiv2 .mono {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-variant-ligatures: none;
}

/* ────────── Shell layout ────────── */
/* The shell locks to exactly viewport height (NOT min-height) so the
   inner `.uiv2-body` can become the actual scroll container via its
   `overflow: auto`. Without `height: 100vh` here, the shell grew with
   content, the body never had a constrained height, and `overflow:
   auto` was inert — so the document scrolled instead of the body, and
   any `position: sticky` inside `.uiv2-body` (the right rail's
   Quick Actions / state-filter pills / Saved Views) couldn't engage
   with the document scroll because `.uiv2-body`'s `overflow: auto`
   declared it the scroll ancestor for its descendants. The combination
   of `height: 100vh` on the shell + `min-height: 0` on the flex
   children is the standard nested-flex-with-internal-scroll recipe;
   it matches the studio mockup's `OrdersShell` pattern. */
.uiv2-shell {
  display: flex;
  height: 100vh;
}
.uiv2-main {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ────────── Sidebar ────────── */
.uiv2-sidebar {
  width: 220px;
  flex: 0 0 220px;
  background: #fff;
  border-right: 1px solid var(--ink-150);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}
.uiv2-sidebar__brand {
  padding: 18px 18px 14px;
  display: flex;
  align-items: center;
  gap: 9px;
}
.uiv2-sidebar__logo {
  width: 44px; height: 44px;
  object-fit: contain;
  flex-shrink: 0;
  /* O-only mark: shown in the COLLAPSED rail. Expanded shows the full wordmark
     (which includes the O), so the standalone icon is hidden by default to
     avoid a double-O. */
  display: none;
}
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__logo { display: block; }
.uiv2-sidebar__wordmark {
  height: 52px;
  width: auto;
  display: block;
}
.uiv2-sidebar__brand-name {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.2px;
  white-space: nowrap;
}
.uiv2-sidebar__brand-sub {
  font-size: 12px;
  color: var(--ink-500);
  margin-top: -1px;
}
.uiv2-sidebar__nav {
  overflow: auto;
  flex: 1;
}
.uiv2-sidebar__group {
  padding: 6px 10px;
}
.uiv2-sidebar__group-head {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-500);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  padding: 12px 10px 6px;
}
.uiv2-sidebar__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  font-size: 14.5px;
  color: var(--ink-700);
  border-radius: 7px;
  cursor: pointer;
  font-weight: 500;
  transition: background .12s, color .12s;
}
.uiv2-sidebar__item:hover {
  background: var(--ink-100);
  color: var(--ink-900);
}
.uiv2-sidebar__item.active {
  background: var(--green-050);
  color: var(--green-900);
}
.uiv2-sidebar__item-icon {
  width: 15px; height: 15px;
  flex: 0 0 15px;
  opacity: .65;
  display: flex;
  align-items: center;
  justify-content: center;
}
.uiv2-sidebar__item.active .uiv2-sidebar__item-icon { opacity: 1; }
.uiv2-sidebar__item-label { flex: 1; }

/* Sidebar sub-menu (Phase 20.1 H3 — Orders module sub-nav under Orders Hub).
   Container indents + bordered guideline; sub-items mirror parent item
   structure but smaller. Active variant: green-050 background + green-900 ink
   + bold. Disabled variant: muted ink + no pointer events + not-allowed cursor.
   Admin-tag: small uppercase label for admin-gated sub-items. */
.uiv2-sidebar__submenu {
  margin: 2px 0 4px 17px;
  padding-left: 18px;
  border-left: 1px solid var(--ink-150);
}
.uiv2-sidebar__subitem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-700);
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
}
.uiv2-sidebar__subitem:hover {
  background: var(--ink-050);
}
.uiv2-sidebar__subitem--active {
  color: var(--green-900);
  background: var(--green-050);
  font-weight: 600;
}
.uiv2-sidebar__subitem--active:hover {
  background: var(--green-050);
}
.uiv2-sidebar__subitem-admin-tag {
  font-size: 10px;
  color: var(--ink-400);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  font-weight: 700;
}

.uiv2-sidebar__user {
  border-top: 1px solid var(--ink-150);
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 9px;
}
.uiv2-sidebar__avatar {
  width: 28px; height: 28px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--green-500), var(--green-700));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}
.uiv2-sidebar__user-info { flex: 1; min-width: 0; }
.uiv2-sidebar__user-email {
  font-size: 13.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.uiv2-sidebar__user-tenant {
  font-size: 12px;
  color: var(--ink-500);
}
.uiv2-sidebar__logout-form {
  margin: 0;
  flex: 0 0 auto;
}
.uiv2-sidebar__logout {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 7px;
  color: var(--ink-500);
  cursor: pointer;
  padding: 0;
  transition: background .12s, color .12s, border-color .12s;
}
.uiv2-sidebar__logout:hover {
  background: var(--ink-100);
  color: var(--ink-900);
}
.uiv2-sidebar__logout:focus-visible {
  outline: none;
  border-color: var(--green-700);
  box-shadow: 0 0 0 2px var(--green-050);
  color: var(--ink-900);
}

/* ────────── Topbar ────────── */
.uiv2-topbar {
  height: 52px;
  background: #fff;
  border-bottom: 1px solid var(--ink-150);
  display: flex;
  align-items: center;
  padding: 0 24px;
  gap: 12px;
}
.uiv2-topbar__crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.uiv2-topbar__crumb { color: var(--ink-500); }
.uiv2-topbar__crumb--current { color: var(--ink-900); font-weight: 600; }
.uiv2-topbar__sep { color: var(--ink-400); }
.uiv2-topbar__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
}

/* ────────── Body container ────────── */
/* `min-height: 0` is required for nested-flex internal scroll: a flex
   item's default `min-height: auto` would expand to fit content,
   defeating `overflow: auto`. With `min-height: 0`, this body shrinks
   to its flex-allotted space and the scrollbar engages. See the
   `.uiv2-shell` height-100vh comment for the full chain. */
.uiv2-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  /* padding-top: 0 — sticky descendants (e.g., .uiv2-workboard__head)
     lock at `top: 0` which maps to the scroll port's CONTENT-box top.
     If padding-top > 0, there's a visible gap between the topbar and
     the locked sticky head where row content bleeds through during
     scroll (caught in Phase 20.1 cutover smoke on /orders/?state=shipped).
     Horizontal + bottom padding preserved; per-page wrappers
     (.uiv2-card, .uiv2-workboard__main, etc.) carry their own
     top-edge breathing via internal padding. */
  padding: 0 32px 24px;
}

/* ────────── Buttons ────────── */
.uiv2-btn {
  all: unset;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 7px;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid var(--ink-150);
  background: #fff;
  color: var(--ink-700);
  transition: background .12s, border-color .12s;
}
.uiv2-btn:hover { background: var(--ink-050); }
.uiv2-btn--primary {
  background: var(--green-700);
  border-color: var(--green-700);
  color: #fff;
  font-weight: 600;
}
.uiv2-btn--primary:hover { background: var(--green-900); border-color: var(--green-900); }

/* ────────── Pills ────────── */
.uiv2-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: 0.1px;
  line-height: 1;
  white-space: nowrap;
  padding: 2px 9px;
  font-size: 12px;
  height: 20px;
}
.uiv2-pill--amber { background: var(--amber); color: var(--amber-ink); }
.uiv2-pill--sky   { background: var(--sky);   color: #fff; }
.uiv2-pill--rose  { background: var(--rose);  color: #fff; }
.uiv2-pill--green { background: var(--green-600); color: #fff; }
.uiv2-pill--ink   { background: var(--ink-200); color: var(--ink-900); }

/* ────────── Stat tile ────────── */
.uiv2-stat {
  background: #fff;
  border: 1px solid var(--ink-150);
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: transform .15s, box-shadow .15s;
  text-decoration: none;
  color: inherit;
}
.uiv2-stat:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}
.uiv2-stat__label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.uiv2-stat__value {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -1px;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.uiv2-stat__value--amber { color: var(--amber-ink); }
.uiv2-stat__value--rose  { color: var(--rose); }
.uiv2-stat__dot {
  width: 6px; height: 6px;
  border-radius: 999px;
}
.uiv2-stat__dot--amber { background: var(--amber); }
.uiv2-stat__dot--rose  { background: var(--rose); }

/* ────────── Card ────────── */
.uiv2-card {
  background: #fff;
  border: 1px solid var(--ink-150);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  /* `overflow: clip` (not `hidden`) so sticky descendants engage with
     the outer scroll container (`.uiv2-body`) instead of getting
     bound to this card. `clip` keeps visual clipping for the rounded
     corners + box-shadow without creating a scroll context. */
  overflow: clip;
}
.uiv2-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0 0 10px;
}
.uiv2-card__title {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
}
.uiv2-card__title-count {
  font-weight: 500;
  color: var(--ink-500);
  margin-left: 6px;
}
.uiv2-card__link {
  font-size: 13.5px;
  color: var(--green-700);
  font-weight: 500;
  cursor: pointer;
}
.uiv2-card__link:hover { color: var(--green-900); }

/* ────────── Page header (non-card) ────────── */
.uiv2-h1 {
  margin: 0;
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.5px;
}
.uiv2-h1-sub {
  font-size: 14.5px;
  color: var(--ink-500);
  margin-top: 4px;
}

/* ────────── Flash messages ────────── */
.uiv2-flashes { margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }
.uiv2-flash {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 14.5px;
  line-height: 1.45;
  border: 1px solid var(--ink-150);
  background: #fff;
  color: var(--ink-900);
}
.uiv2-flash--success { border-color: var(--green-600); background: var(--green-050); color: var(--green-900); }
.uiv2-flash--info    { border-color: var(--sky); background: oklch(96% 0.03 240); color: oklch(35% 0.10 240); }
.uiv2-flash--warning { border-color: var(--amber); background: oklch(96% 0.06 75); color: var(--amber-ink); }
.uiv2-flash--error,
.uiv2-flash--danger  { border-color: var(--rose); background: oklch(96% 0.04 25); color: var(--rose); }

/* ────────── Workboard (Phase 20.1 G1, layout corrected G5) ────────── */

/* Layout: main content on the LEFT (taking the operator's primary
   read direction), page-context rail on the RIGHT (Quick Actions +
   state filter pills + Saved Views). Matches the studio mockup's
   OrdersShell pattern (orders-shared.jsx:649) — global app sidebar
   stays on the left edge of the page; the per-page sub-nav rail sits
   on the right. G1 shipped with the rail on the LEFT by mistake; G5
   flips both the grid columns AND the template's DOM order so the
   rendered HTML matches the visual layout (screen-reader linearity
   follows the same reading path as a sighted user). */
/* .uiv2-workboard — main column wrapper. The Actions panel (formerly
   the right column of this grid) was lifted to the shell level
   2026-05-13; this is now a single-column wrapper. Keeping the class
   for backward-compat with `data-workboard-root` JS selectors. */
.uiv2-workboard {
  display: block;
}

/* ─── Topbar freshness indicator ─── */
.uiv2-freshness {
  font-size: 13px;
  color: var(--ink-500);
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--ink-050);
  border: 1px solid var(--ink-150);
}
.uiv2-freshness--stale { color: var(--amber-ink); border-color: var(--amber); background: oklch(96% 0.06 75); }
.uiv2-freshness--never { color: var(--rose); border-color: var(--rose); background: oklch(96% 0.04 25); }

/* ─── Right "Actions panel" — full-height sticky sibling of <main>
   (2026-05-13 refinement; replaces the in-workboard grid cell). Mirrors
   .uiv2-sidebar's anatomy: fixed width, full viewport height, sticky
   top:0, border on the inside edge (left here vs right on the sidebar).
   Width transitions for the collapse animation. */
.uiv2-rail {
  width: 280px;
  flex: 0 0 280px;
  background: #fff;
  border-left: 1px solid var(--ink-150);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  transition: width 200ms ease, flex-basis 200ms ease;
}
/* Chevron toggle — mirror of .uiv2-sidebar__toggle but on the LEFT edge
   of the panel (the edge facing main content). Sits half-inside/half-
   outside the panel border like the sidebar's chevron does. */
.uiv2-rail__toggle {
  position: absolute;
  top: 22px;
  left: -11px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--ink-150);
  color: var(--ink-500);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 6;
  padding: 0;
  box-shadow: var(--shadow-sm);
  transition: color 0.12s, border-color 0.12s;
}
.uiv2-rail__toggle:hover {
  color: var(--ink-900);
  border-color: var(--ink-400);
}
/* Scrollable content container inside the panel — gives the panel its
   internal scroll while keeping the chevron in a fixed position. */
.uiv2-rail__content {
  flex: 1;
  overflow-y: auto;
  padding: 12px 8px;
}
.uiv2-rail__header {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--ink-500);
  padding: 4px 10px 8px;
}
.uiv2-rail__pill {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  margin: 1px 0;
  border-radius: 7px;
  font-size: 14px;
  color: var(--ink-700);
  text-decoration: none;
  cursor: pointer;
}
.uiv2-rail__pill:hover { background: var(--ink-050); }
.uiv2-rail__pill--active {
  background: var(--green-050);
  color: var(--green-900);
  font-weight: 600;
}
.uiv2-rail__dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  flex: 0 0 7px;
  background: var(--ink-400);
}
.uiv2-rail__dot--amber { background: var(--amber); }
.uiv2-rail__dot--sky   { background: var(--sky); }
.uiv2-rail__dot--rose  { background: var(--rose); }
.uiv2-rail__dot--plum  { background: var(--plum); }
.uiv2-rail__dot--green { background: var(--green-600); }
.uiv2-rail__dot--ink   { background: var(--ink-400); }
.uiv2-rail__label { flex: 1; }
.uiv2-rail__count {
  font-size: 12.5px;
  color: var(--ink-500);
  font-variant-numeric: tabular-nums;
}

/* ─── Center main column ─── */
.uiv2-workboard__main {
  background: #fff;
  border: 1px solid var(--ink-150);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

/* Table-host wrapper — applied as a modifier class on .uiv2-card or
   .uiv2-workboard__main when the card contains a table that might
   exceed the work-surface width. Per UI_Layout.md § 11 / 2026-05-13
   sticky-preserving refinement:
     min-width: 100%    -> fills parent when content fits within parent
     width: max-content -> grows to content width when content is wider
   When the wrapper grows past .uiv2-body's content area, .uiv2-body's
   own `overflow: auto` engages horizontal scroll. The card decoration
   (border + box-shadow) visually wraps the full table at all widths.

   IMPORTANT: no `overflow` override — both .uiv2-card and
   .uiv2-workboard__main have a clip/visible overflow that does NOT
   create a scroll container, so the sticky chain (.uiv2-table__header
   -> .uiv2-body) stays intact. Applying this modifier is safe on any
   element that doesn't itself create a scroll container.

   Apply this class on the three table-hosting wrappers (Workboard +
   the two Orders surfaces wrapped in .uiv2-card). Without it, wide
   tables get clipped silently by .uiv2-card's `overflow: clip` —
   reverting to the truncation bug 2026-05-13 was meant to fix. */
.uiv2-table-host {
  min-width: 100%;
  width: max-content;
}
/* Fill variant — for surfaces whose column count comfortably fits a desktop
   viewport (e.g. Reservations Admin v2, 8 columns). The base `max-content`
   sizing is for many-column scroll tables (Workboard) and collapses fr tracks
   to their minimums, leaving a right-side white band on wide screens. `width:
   100%` lets the fr columns distribute the full width; horizontal scroll on
   genuinely narrow viewports is still handled by `.uiv2-body`'s overflow.
   Declared after the base rule so it wins at equal specificity. */
.uiv2-table-host--fill {
  width: 100%;
}

/* ─── Tab strip (uiv2) ─── */
/* In-card tab navigation (e.g. Reservations: Line Items | Orders). Sits
   directly under the workboard head; the active tab carries the brand
   underline + a volume badge. */
.uiv2-tabs {
  display: flex;
  gap: 4px;
  padding: 0 18px;
  border-bottom: 1px solid var(--ink-150);
}
.uiv2-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-500);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.uiv2-tab:hover { color: var(--ink-900); }
.uiv2-tab--active {
  color: var(--green-700);
  border-bottom-color: var(--green-700);
  font-weight: 600;
}
.uiv2-tab__badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-500);
  background: var(--ink-050);
  border-radius: 10px;
  padding: 1px 7px;
}
.uiv2-tab--active .uiv2-tab__badge {
  color: var(--green-900);
  background: var(--green-050);
}
.uiv2-workboard__head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--ink-150);
  /* Sticky page-level title row — stays visible while the operator
     scrolls down the table. White background prevents row content
     bleed-through. z-index above the table__header so the rail title
     wins on visual stack when they touch. Pinned across all Phase
     20.1 spreadsheet surfaces via shared class (Workboard, Items to
     Pick, Reservations Admin v2).

     Fixed height (border-box) so the sticky column header below can
     lock at exactly this height — see --uiv2-workboard-head-h. Excess
     content is clipped rather than allowed to grow the head and
     reintroduce the overlap/gap mismatch. */
  height: var(--uiv2-workboard-head-h);
  overflow: hidden;
  position: sticky;
  top: 0;
  z-index: 3;
  background: #fff;
}
.uiv2-workboard__title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--ink-900);
  /* Deterministic line box: title + inline count share line 1, the
     subtitle takes line 2, so the head reliably fits the 2-line
     --uiv2-workboard-head-h (no 3-line clip). */
  line-height: 1.2;
  display: inline-block;
  /* Zero the UA <h1> margin (margin-block ~0.67em). Without this the
     phantom top/bottom margins push the head content past the fixed
     --uiv2-workboard-head-h, and overflow:hidden slices the subtitle in
     half — the deterministic 2-line box math above only holds with the
     UA margins neutralized. Fixed 2026-05-20. */
  margin: 0;
}
.uiv2-workboard__count {
  font-weight: 500;
  color: var(--ink-500);
  margin-left: 6px;
  font-size: 15px;
}
.uiv2-workboard__sub {
  font-size: 13.5px;
  color: var(--ink-500);
  /* margin: 0 base resets the UA <p> margin-block (~1em bottom) that
     would otherwise overflow the fixed-height head; margin-top: 2px is
     the only intended spacing. See .uiv2-workboard__title note. */
  margin: 0;
  margin-top: 2px;
  /* Single line so the head height stays deterministic (fixed at
     --uiv2-workboard-head-h); long subtitles ellipsize rather than wrap
     and push the column header out of alignment. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.uiv2-workboard__filter-strip {
  /* Sits below .uiv2-workboard__head as its own in-flow strip (NOT inside
     the fixed-height head — see orders_hub.html comment). Horizontal inset
     + vertical spacing match the sibling toolbar / active-filters strips so
     all card-level strips align to the head's 18px content edge. */
  margin: 12px 18px;
  font-size: 13px;
  color: var(--ink-700);
  background: var(--green-050);
  border: 1px solid var(--green-600);
  border-radius: 6px;
  padding: 6px 10px;
}

/* ─── Rows table ─── */
/* IMPORTANT: no `overflow-x: auto` on this wrapper. An overflow value
   here would create a scroll container, which would bind sticky
   descendants (`.uiv2-table__header` at `top: 56px`) to THIS element
   instead of to `.uiv2-body` — breaking the sticky column header
   during vertical page scroll. Horizontal scroll for wide tables is
   handled by `.uiv2-body`'s existing `overflow: auto` + the wrapping
   card growing to `max-content` (see .uiv2-workboard__main and
   .uiv2-card-table-host below). Per UI_Layout.md § 11 / 2026-05-13
   sticky-preserving refinement. */
.uiv2-table {
  border-top: 1px solid var(--ink-100);
}
/* Shared anatomy only — no grid-template-columns here. Each surface
   declares its own template via a `.uiv2-table--<surface>` modifier
   class (see "Per-surface table column templates" further down).
   Why per-surface: Workboard has 9 columns with distinct semantics;
   Items to Pick has 4; Reservations Admin v2 has 8. A shared template
   on this class would impose Workboard's column widths on the other
   two surfaces (the original bug the 2026-05-13 fix addresses). */
.uiv2-table__header,
.uiv2-table__row {
  display: grid;
  gap: 8px;
  align-items: center;
  padding: 11px 16px;
}
.uiv2-table__header {
  background: var(--ink-050);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--ink-500);
  border-bottom: 1px solid var(--ink-150);
  /* Sticky column-header row — locks flush BELOW the
     .uiv2-workboard__head. Both use --uiv2-workboard-head-h: the head is
     pinned to that height and this row locks at that same `top`, so they
     stack with no overlap (labels never clip behind the title) and no
     gap (rows can't bleed between them). Previously a hardcoded 56px
     that was smaller than the real head height, so the column labels
     slid up behind the title — fixed 2026-05-20. z-index 3 on head > 2
     here; background opaque (var(--ink-050)). */
  position: sticky;
  top: var(--uiv2-workboard-head-h);
  z-index: 2;
}
.uiv2-table__row {
  border-top: 1px solid var(--ink-100);
  font-size: 14px;
  color: var(--ink-900);
}
.uiv2-table__row:first-child { border-top: none; }
/* Cells render their natural content. No ellipsis truncation — the
   per-surface column templates use fixed widths + minmax(MIN, fr)
   so columns can't shrink below readability. When the table's
   natural width exceeds the container, the wrapping card grows to
   `max-content` (see `.uiv2-workboard__main`) and `.uiv2-body`'s
   `overflow: auto` handles horizontal scroll — no scroll context
   between this cell and the body, which preserves sticky header
   binding. Per UI_Layout.md § 11 refinement pass 2026-05-13:
   operators must never see "abc..." for identifier columns;
   horizontal scroll is the correct fallback. `white-space: nowrap`
   retained so cell content stays single-line (multi-line wrapping
   inside a fixed-height row would clip vertically anyway). */
.uiv2-table__cell {
  white-space: nowrap;
}
.uiv2-table__cell--right { text-align: right; }
.uiv2-table__cell--checkbox { display: flex; align-items: center; justify-content: center; }
.uiv2-table__cell--order {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.uiv2-table__sub {
  font-size: 12px;
  color: var(--ink-500);
}
.uiv2-table__cell--action .uiv2-action-form { display: inline-block; margin: 0; }

/* ─── Per-surface table column templates (2026-05-13 refinement) ───
   Each surface's table declares its column widths here. Tracks use
   only fixed `Npx` widths or `minmax(MIN, FR)` with fr units —
   NEVER `auto`. Why: each .uiv2-table__row is its own grid, and
   `auto` in `minmax(MIN, auto)` resolves from each grid's OWN
   content (max-content), so the header would compute different
   track widths from each row, causing visually jagged columns
   across rows. Fixed px values + fr units resolve identically
   across all grids (assuming identical container width, which
   they have since both header + rows are block-level children of
   the same `.uiv2-table` parent). */

/* Workboard / Fulfillment — 6 columns (2026-05-13 simplification):
   checkbox · Order · Buyer · Total · Age · State.
   Lines + Destination + Action columns were removed:
     - Lines / Destination: low-attention-density data; operator gets
       these on Order Detail drill-in (via Order# link).
     - Action: per-row primary CTA (Record Fulfillment) moved to the
       bulk action toolbar (single-order only — disabled when ≠1
       selected). Other state-specific primary actions (Open Group,
       View Activity, Print, Release Hold) are reached via Order#
       drill-in to Order Detail.
   Order + Buyer remain fr-flexible identifier columns. */
.uiv2-table--workboard .uiv2-table__header,
.uiv2-table--workboard .uiv2-table__row {
  grid-template-columns:
    32px                  /* checkbox */
    minmax(140px, 1.3fr)  /* Order (primary id, fr-flexible) */
    minmax(100px, 1fr)    /* Buyer (primary id, fr-flexible) */
    90px                  /* Total */
    60px                  /* Age */
    100px;                /* State pill */
}

/* All Orders rail — same 6-column shape as Workboard but two tweaks:
   - col 5 widens from 60px (fits "23d" age token) to 90px (fits
     "05/14/2026" date + "Order date ▼" sort header)
   - Order column is fixed 140px instead of Workboard's minmax(140px,
     1.3fr). Why: with width:max-content on .uiv2-table-host + nowrap
     on cells, long buyer emails on Shopify-only views (avg 21 chars,
     max 28) force the Buyer track to expand beyond 1fr. Order's
     1.3fr then greedily claims 1.3/2.3 of the resulting extra space,
     adding ~150px of whitespace after short "S####" order IDs and
     pushing the State column off the right edge in narrow viewports.
     Fixing Order at 140px (sufficient for eBay's 14-char "##-#####-
     #####" format at ~112px and Shopify's 5-char "S####" at ~50px)
     eliminates the bloat. Buyer's 1fr now absorbs all flexible
     space. Workboard's grid above is unchanged.
   Single-state rails keep the compact age column. */
.uiv2-table--workboard.uiv2-table--all-orders .uiv2-table__header,
.uiv2-table--workboard.uiv2-table--all-orders .uiv2-table__row {
  grid-template-columns:
    32px                  /* checkbox */
    140px                 /* Order (fixed; see note above) */
    minmax(100px, 1fr)    /* Buyer */
    90px                  /* Total */
    90px                  /* Order date */
    100px;                /* State pill */
}

/* History (Phase 20.1 standalone surface) — read-only audit list. Marketplace
   is its own column here (not the order# subline) since History has the width
   for it; the host carries the `--fill` modifier so the Buyer fr track
   distributes the full width instead of collapsing (see .uiv2-table-host--fill).
   Columns: Order date · Order · Marketplace · Buyer · Total · Status (date
   first — History is chronological; default sort is `created`). */
.uiv2-table--history .uiv2-table__header,
.uiv2-table--history .uiv2-table__row {
  grid-template-columns:
    110px                 /* Order date */
    140px                 /* Order (fixed; see all-orders note) */
    110px                 /* Marketplace */
    minmax(140px, 1fr)    /* Buyer */
    100px                 /* Total (right-aligned) */
    110px;                /* Status pill */
}

/* Phase 20.3 Activity / Movement ledger (reskin of inventory/activity.html).
   Columns: Date · Action · SKU · Location · Qty · User · Reference (date
   first — the ledger is chronological). Named `--activity-ledger` to avoid
   colliding with the existing 6-col `.uiv2-table--activity` card grid below. */
.uiv2-table--activity-ledger .uiv2-table__header,
.uiv2-table--activity-ledger .uiv2-table__row {
  grid-template-columns:
    150px                 /* Date (timestamp) */
    100px                 /* Action chip */
    minmax(90px, 0.8fr)   /* SKU */
    100px                 /* Location */
    70px                  /* Qty (right-aligned) */
    minmax(140px, 1fr)    /* User */
    minmax(120px, 1.2fr); /* Reference */
}

/* Phase 20.3 Stock-by-location (reskin of inventory/stock_list.html).
   Columns: SKU · Title · Total Qty · Locations · Last Activity · History */
.uiv2-table--stock .uiv2-table__header,
.uiv2-table--stock .uiv2-table__row {
  grid-template-columns:
    minmax(100px, 0.8fr)  /* SKU */
    minmax(160px, 1.4fr)  /* Title */
    90px                  /* Total Qty (right-aligned) */
    90px                  /* Locations (right-aligned) */
    150px                 /* Last Activity */
    90px;                 /* History link */
}

/* Phase 20.4 Locations list (Warehouse). Occupancy-enriched after the
   Stock-by-location merge (2026-06-17).
   Columns: select · Code · Name · Status · SKUs (right) · Units (right). */
.uiv2-table--locations .uiv2-table__header,
.uiv2-table--locations .uiv2-table__row {
  grid-template-columns:
    40px                  /* select checkbox */
    minmax(120px, 1fr)    /* Code */
    minmax(160px, 1.4fr)  /* Name */
    110px                 /* Status chip */
    90px                  /* SKUs */
    90px;                 /* Units */
}

/* Phase 20.4 Stock-by-location (Warehouse, Q-3). Location-lensed occupancy —
   distinct from the item-lensed .uiv2-table--stock above.
   Columns: Code · Name · SKUs (right) · Units (right) · Status. */
.uiv2-table--location-stock .uiv2-table__header,
.uiv2-table--location-stock .uiv2-table__row {
  grid-template-columns:
    minmax(120px, 1fr)    /* Code */
    minmax(160px, 1.4fr)  /* Name */
    90px                  /* SKUs (right-aligned) */
    90px                  /* Units (right-aligned) */
    110px;                /* Status chip */
}

/* Phase 20.3 report-launcher pages (Audit Report / Cycle Count reskins) —
   a centered single-column doc of v2 cards, a green-accented primary action
   card (generate / reset), and a small comparison table. */
.uiv2-report-page {
  max-width: 820px;
  margin: 0 auto;
  padding: 18px 0 36px;
}
.uiv2-report-page__lede {
  margin: 4px 0 20px;
  font-size: 14.5px;
}
.uiv2-report-page .uiv2-card {
  margin-bottom: 16px;
}
.uiv2-report-page .uiv2-card__title {
  margin-bottom: 10px;
}
.uiv2-report-page .uiv2-card__body p {
  margin: 0 0 10px;
}
.uiv2-report-page .uiv2-card__body p:last-child {
  margin-bottom: 0;
}
.uiv2-report-page .uiv2-card__body ul,
.uiv2-report-page .uiv2-card__body ol {
  margin: 0 0 0 18px;
  padding: 0;
}
.uiv2-report-page .uiv2-card__body li {
  margin: 3px 0;
}

/* Accent card — green left border marks the primary action card. */
.uiv2-card--accent {
  border-left: 3px solid var(--green-700, #297a45);
}

/* Comparison table on the report pages (High-Turn vs Cycle Count). */
.uiv2-report-page__compare {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  margin-top: 4px;
}
.uiv2-report-page__compare th,
.uiv2-report-page__compare td {
  text-align: left;
  padding: 6px 10px;
  border-bottom: 1px solid var(--ink-100);
  vertical-align: top;
}
.uiv2-report-page__compare thead th {
  color: var(--ink-500);
  font-weight: 600;
  border-bottom: 2px solid var(--ink-200);
}

/* Phase 20.2 Items List — column template per Items List Page MIC § 1.4.
   7 columns (no kebab/Actions column per Reid 2026-05-19 directive — SKU
   anchor is the View action; secondary actions live on Item Detail).
   Fixed/minmax widths only (NEVER `auto`, NEVER `display:none` at narrow
   viewports — both are anti-patterns per Entry 322). */
.uiv2-table--workboard.uiv2-table--items-list .uiv2-table__header,
.uiv2-table--workboard.uiv2-table--items-list .uiv2-table__row {
  grid-template-columns:
    32px                   /* checkbox */
    minmax(110px, 0.8fr)   /* SKU (primary id, mono, fr-flexible) */
    minmax(180px, 2fr)     /* Title (largest fr — text content) */
    minmax(100px, 0.8fr)   /* Category */
    minmax(100px, 0.8fr)   /* Condition */
    minmax(120px, 0.9fr)   /* Status chips */
    80px;                  /* On hand (right-aligned mono) */
}

/* Phase 20.6 surface 4 — Models List explorer (no checkbox column;
   drill via the model_code cell). Model / Display name / Brand / Category /
   Status / Parts / Created / Last edit. */
.uiv2-table--workboard.uiv2-table--models-list .uiv2-table__header,
.uiv2-table--workboard.uiv2-table--models-list .uiv2-table__row {
  grid-template-columns:
    minmax(120px, 0.9fr)   /* Model (primary id, mono, fr-flexible) */
    minmax(150px, 1.6fr)   /* Display name (largest fr — text content) */
    minmax(80px, 0.6fr)    /* Brand */
    minmax(80px, 0.6fr)    /* Category */
    minmax(80px, 0.6fr)    /* Status chip */
    64px                   /* Parts (right-aligned mono) */
    100px                  /* Created (right-aligned) */
    100px;                 /* Last edit (right-aligned) */
}

/* Phase 20.6 surface 2 — Model Detail parts table (Items card). Checkbox /
   SKU / Title / Role / Notes / Added / Remove. */
.uiv2-table--workboard.uiv2-table--model-parts .uiv2-table__header,
.uiv2-table--workboard.uiv2-table--model-parts .uiv2-table__row {
  grid-template-columns:
    32px                   /* checkbox */
    minmax(100px, 0.8fr)   /* SKU (mono link) */
    minmax(140px, 1.6fr)   /* Title */
    minmax(80px, 0.6fr)    /* Role */
    minmax(110px, 1fr)     /* Notes */
    92px                   /* Added (created_at) */
    64px;                  /* Remove (right) */
}

/* Phase 20.6 surface 5 — Bulk-Add Parts picker table. Rows are appended
   client-side (infinite scroll), so each row is its own grid; the template
   below applies identically to the static header and every JS-built row.
   Checkbox / SKU / Title / Brand / Category / Qty / Status. */
.uiv2-table--bulk-add-parts .uiv2-table__header,
.uiv2-table--bulk-add-parts .uiv2-table__row {
  grid-template-columns:
    36px                   /* checkbox / select-all */
    minmax(90px, 0.7fr)    /* SKU (mono link) */
    minmax(160px, 2.4fr)   /* Title (largest fr — text content) */
    minmax(90px, 0.7fr)    /* Brand */
    minmax(90px, 0.7fr)    /* Category */
    64px                   /* Qty (right-aligned mono) */
    110px;                 /* Status pill */
}
/* Already-attached rows are dimmed and non-interactive (checkbox disabled
   in JS); selectable rows render at full strength. */
.uiv2-table--bulk-add-parts .uiv2-table__row--assigned { opacity: 0.55; }

/* Phase 20.6 surface 7 — Field Definitions admin list. Field key / Label /
   Section / Pinned / Filterable / Values / Status / Actions. */
.uiv2-table--field-definitions .uiv2-table__header,
.uiv2-table--field-definitions .uiv2-table__row {
  grid-template-columns:
    minmax(110px, 1fr)    /* Field key (mono) */
    minmax(120px, 1.4fr)  /* Label (link) */
    minmax(80px, 0.8fr)   /* Section */
    72px                  /* Pinned */
    80px                  /* Filterable */
    70px                  /* Values (right) */
    90px                  /* Status */
    196px;                /* Actions (Edit + Archive/Restore + Delete) */
}
.uiv2-table--field-definitions .uiv2-table__row--archived { opacity: 0.6; }

/* Phase 20.6 surface 2 — Model Detail edit-mode stacked form + inline
   filters + documents list. Composed from existing tokens; no new colors. */
.uiv2-stack-form { display: flex; flex-direction: column; gap: 6px; }
.uiv2-stack-form .uiv2-input,
.uiv2-stack-form .uiv2-textarea,
.uiv2-stack-form .uiv2-select { margin-bottom: 6px; }
.uiv2-field-label { font-size: 12.5px; font-weight: 600; color: var(--ink-700); margin-top: 4px; }
.uiv2-stack-form__actions { display: flex; gap: 10px; margin-top: 12px; }

.uiv2-inline-filters { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 12px 0; }
.uiv2-inline-filters .uiv2-input { max-width: 240px; }

.uiv2-doc-list { display: flex; flex-direction: column; }
.uiv2-doc-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 12px; font-size: 13.5px; text-align: left;
  background: none; border: none; border-bottom: 1px solid var(--ink-100);
  cursor: pointer; color: var(--ink-900); width: 100%;
}
.uiv2-doc-row:last-child { border-bottom: none; }
.uiv2-doc-row:hover { background: var(--ink-050); }
.uiv2-doc-row__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uiv2-doc-row__hint { color: var(--green-700); font-size: 12.5px; font-weight: 600; flex-shrink: 0; margin-left: 10px; }

.uiv2-danger-inline { margin-top: 12px; }

/* Phase 20.2 surface 5 — Listing Health diagnostics explorer (no
   checkbox column; read-only triage surface). SKU / Title / On hand /
   Severity / Issues. */
.uiv2-table--workboard.uiv2-table--listing-health .uiv2-table__header,
.uiv2-table--workboard.uiv2-table--listing-health .uiv2-table__row {
  /* SKU + Severity size to their content (no trailing whitespace);
     Title + Issues absorb all slack via fr so the gaps close up. */
  grid-template-columns:
    minmax(90px, max-content)   /* SKU (mono link) — content width */
    minmax(180px, 3fr)          /* Title — absorbs slack */
    70px                        /* On hand (right-aligned mono) */
    110px                       /* Severity chip — fixed, no trailing gap */
    minmax(160px, 2fr);         /* Issues badges — absorbs slack */
}
.uiv2-listing-health__issues {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
/* Muted awareness-only metric strip (zero-stock active listings) — subtle,
   sits above the workboard, links to the on-demand filtered view. */
.uiv2-lh-muted {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  margin-bottom: 12px;
  background: var(--ink-050);
  border: 1px solid var(--ink-100);
  border-radius: var(--radius-md, 8px);
  font-size: 13px;
  color: var(--ink-500);
}
.uiv2-lh-muted__count {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink-900);
}
.uiv2-lh-muted__label { flex: 1; }
.uiv2-lh-muted__link { white-space: nowrap; }
/* Compact rows — Listing Health is a dense triage list; tighten the
   shared workboard row padding + font so more diagnostics fit on screen.
   Scoped to this surface so Workboard / Items List are untouched. */
.uiv2-table--listing-health .uiv2-table__header,
.uiv2-table--listing-health .uiv2-table__row {
  padding-top: 5px;
  padding-bottom: 5px;
}
.uiv2-table--listing-health .uiv2-table__row {
  font-size: 13px;
}

/* Phase 20.2 surface 6 — Field Options per-field admin table.
   Value · Items using · Source · Status · Actions. Rows are client-
   rendered (field_options_admin.js) into a [data-options-body] wrapper
   inside .uiv2-table; the wrapper is a plain block child while the header
   is a direct child — both span the table's full width and each row is its
   own grid, so the fixed/fr tracks line up. NEVER `auto`/`max-content`
   here (those resolve per-row from content and jag the columns across
   rows — see the per-surface-template note above). */
.uiv2-table--field-options .uiv2-table__header,
.uiv2-table--field-options .uiv2-table__row {
  grid-template-columns:
    minmax(160px, 2fr)   /* Value (fr-flexible) */
    90px                 /* Items using (right-aligned mono) */
    110px                /* Source pill */
    100px                /* Status chip */
    230px;               /* Actions (Rename / Hide / Delete) */
}
/* This table sits in a normal page-flow card, NOT a .uiv2-workboard
   scroll-host. The global .uiv2-table__header sticky rule pins
   top: var(--uiv2-workboard-head-h) (~76px), so without a workboard head
   above it the header detaches and floats ~76px down the viewport,
   sliding over rows as the page scrolls. Reset to static so it scrolls
   with the table like an ordinary card header. */
.uiv2-table--field-options .uiv2-table__header {
  position: static;
}

/* Full-width "Download CSV" action at the top of the Listing Health
   filter rail. */
.uiv2-rail__export {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

/* Phase 20.1 All Orders Page MIC § 6.3 — Filters form in the rail's
   middle section (Actions panel) when display_state == "All". Mirrors
   the existing slide-out filter panel's field stack but inline in the
   rail, with a multi-select State chip group. */
.uiv2-rail-filters {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.uiv2-rail-filters__label {
  font-size: 11px;
  font-weight: 500;
  color: var(--uiv2-color-text-muted, #5c6470);
  margin-top: 4px;
}

.uiv2-rail-filters__checkbox {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  margin-top: 4px;
}

.uiv2-rail-filters__actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}

.uiv2-rail-filters__actions .uiv2-btn {
  flex: 1;
}

/* Order# emphasis (2026-05-13 refinement): the Order# link is the
   primary drill-in affordance from the table (the per-row Action
   column was removed). Bump font-size one scale step (14 -> 15) and
   weight (500 -> 600) so the link reads clearly as the clickable
   identifier without being shouty. */
.uiv2-table__cell--order .uiv2-link {
  font-size: 15px;
  font-weight: 600;
}

/* Items to Pick — 4 columns: SKU · Title · To Pick · On Hand. SKU +
   Title are primary identifiers (fr-flexible); numeric columns fixed. */
.uiv2-table--items-to-pick .uiv2-table__header,
.uiv2-table--items-to-pick .uiv2-table__row {
  grid-template-columns:
    minmax(120px, 1fr)   /* SKU */
    minmax(160px, 2fr)   /* Title */
    80px            /* To Pick */
    80px;           /* On Hand */
}

/* Reservations — Line Items tab, 6 columns (Phase 20.1 Surface 4): checkbox ·
   Date · SKU · Order · Buyer · Reservation Status. Date leads (matches History);
   SKU follows Date because the SKU is the line item's identity at this grain.
   Order# is a green link (drill to Order Detail); the sole bulk action is
   Release (the Exception column / Clear-Exception action were removed — the
   reservation-exception path is unreachable + never used in prod; pick problems
   become PICK_SKIP blockers that release the hold). Order, Buyer and Reservation
   Status are fr-flexible; Date is the sortable order-placed date. */
.uiv2-table--reservations-admin .uiv2-table__header,
.uiv2-table--reservations-admin .uiv2-table__row {
  grid-template-columns:
    32px                  /* checkbox */
    100px                 /* Date (order placed) */
    minmax(90px, 0.6fr)   /* SKU (line-item identity — follows Date) */
    minmax(130px, 1.2fr)  /* Order (mono order#, drill link) */
    minmax(110px, 1fr)    /* Buyer */
    minmax(110px, 1fr);   /* Reservation Status (hold lifecycle) */
}

/* Reservations — Orders tab, 7 columns: checkbox · Date · Order · Buyer · Market
   Status · Internal Status · Reservations (active count). Column order aligns
   with the History surface (Date first, Order and Buyer as their own columns).
   Order-grained (no SKU); bulk Close / Cancel Orders release the holds. Pick
   Status dropped — picking belongs to the Queue; the clearing / stale-cleanup
   function reads the Market-vs-Internal status mismatch (shipped outside PMP).
   Pick status is still filterable. */
.uiv2-table--reservations-orders .uiv2-table__header,
.uiv2-table--reservations-orders .uiv2-table__row {
  grid-template-columns:
    32px                  /* checkbox */
    100px                 /* Date (order placed) */
    minmax(130px, 1.2fr)  /* Order (mono order#, drill link) */
    minmax(120px, 1fr)    /* Buyer */
    minmax(120px, 1fr)    /* Market Status */
    120px                 /* Internal Status */
    96px;                 /* Reservations (active count) */
}

/* Reservations cells truncate instead of overflowing into the next column.
   The base .uiv2-table__cell sets `white-space: nowrap` but no overflow/min-
   width, so long content (e.g. a buyer email at the narrow line-item grain)
   spilled across the grid line. `min-width: 0` lets the fr tracks shrink;
   overflow + ellipsis clips cleanly. Scoped to the two reservations tables. */
.uiv2-table--reservations-admin .uiv2-table__cell,
.uiv2-table--reservations-orders .uiv2-table__cell {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ─── Sortable column headers ─── */
.uiv2-sort-header {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  text-decoration: none;
  color: var(--ink-500);
}
.uiv2-sort-header:hover { color: var(--ink-900); }
.uiv2-sort-header--active { color: var(--ink-900); }
.uiv2-sort-chevron {
  font-size: 9.5px;
  display: inline-flex;
  flex-direction: column;
  line-height: 0.85;
  opacity: 0.7;
}

/* ─── State chip (per-row state cell) ─── */
.uiv2-state-chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  background: var(--ink-100);
  color: var(--ink-700);
}
.uiv2-state-chip--amber { background: oklch(96% 0.06 75); color: var(--amber-ink); }
.uiv2-state-chip--sky   { background: oklch(96% 0.05 240); color: oklch(35% 0.10 240); }
.uiv2-state-chip--rose  { background: oklch(96% 0.04 25); color: var(--rose); }
.uiv2-state-chip--plum  { background: oklch(96% 0.05 305); color: var(--plum); }
.uiv2-state-chip--green { background: var(--green-050); color: var(--green-900); }
.uiv2-state-chip--ink   { background: var(--ink-100); color: var(--ink-700); }

/* ─── Pagination + per-page ─── */
.uiv2-pagination {
  padding: 12px 18px;
  border-top: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 13px;
  color: var(--ink-500);
}
.uiv2-pagination__info { flex: 0 0 auto; }
.uiv2-pagination__per-page {
  flex: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.uiv2-pagination__per-page .uiv2-link { padding: 0 4px; }
.uiv2-pagination__nav {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.uiv2-pagination__page {
  font-weight: 600;
  color: var(--ink-700);
}

/* ─── Generic link primitive ─── */
.uiv2-link {
  color: var(--green-700);
  text-decoration: none;
  font-weight: 500;
}
.uiv2-link:hover { text-decoration: underline; }
.uiv2-link--active { color: var(--ink-900); font-weight: 600; }

/* ─── Mono utility (tabular numerals + fixed-width) ─── */
.uiv2-mono {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
}

/* ─── Empty state ─── */
.uiv2-empty {
  padding: 60px 24px;
  text-align: center;
  color: var(--ink-500);
}
.uiv2-empty__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-empty__body {
  font-size: 13.5px;
  margin-top: 4px;
}
.uiv2-empty__cta {
  margin-top: 12px;
  display: inline-block;
}
/* Filtered-zero: same shape as no-data but signals "your filters narrowed
   to nothing" rather than "the rail itself is empty" (bedrock § 14.1
   State 3 + MIC § 1.8). */
.uiv2-empty--filtered-zero .uiv2-empty__body { color: var(--ink-500); }
.uiv2-empty--filtered-zero .uiv2-empty__summary {
  font-size: 13px;
  margin-top: 6px;
  color: var(--ink-400);
  font-style: italic;
}
/* Sync-not-run: distinguishing variant on Ready/Picked rails when
   no successful sync has ever completed for the tenant
   (MIC § 1.8 + Workflow Matrix Job 22). Points to Sync Console. */
.uiv2-empty--sync-not-run .uiv2-empty__title { color: var(--amber-ink); }

/* ─── Page-state banners (Phase 20.1 G4) ─── */
/* Amber-tone alert blocks for Provider-disconnected (per-connection,
   in the rail-counts region) and Sync-blocked (system-wide, above the
   table). Both are bedrock § 14.1 State 5/6 — amber, never rose, since
   the operator did not cause these (upstream-blocked or external). */
.uiv2-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.45;
  border: 1px solid var(--ink-150);
  background: #fff;
  color: var(--ink-900);
  margin-bottom: 12px;
}
.uiv2-banner--warning {
  border-color: var(--amber);
  background: oklch(96% 0.06 75);
  color: var(--amber-ink);
}
.uiv2-banner__body { flex: 1 1 auto; }
.uiv2-banner__action { flex: 0 0 auto; margin-left: 8px; }
.uiv2-banner--provider-disconnected { margin: 8px 6px; padding: 8px 10px; font-size: 13.5px; }
.uiv2-banner--sync-blocked { margin: 0 0 12px 0; }

/* ─── Row overlays + Picking-rail metadata (Phase 20.1 G5) ─── */
/* Risk-flag overlay dot — 7px rose circle, rendered before the order ID
   in `.uiv2-table__cell--order` when `risk_badges` is non-empty AND the
   rail isn't filtered to Review. Color is never the sole signal — the
   markup carries `title` + `aria-label` so the cue is keyboard- and
   screen-reader-discoverable (bedrock § 7.1 + Coverage Map line 317). */
.uiv2-table__order-line {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.uiv2-risk-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--rose);
  flex: 0 0 7px;
  display: inline-block;
}

/* Picking-rail metadata sub-line — read-only handheld pick-session info
   per MIC § 1.2 + Module MIC § 6.1 Q-B. Renders below the channel sub-
   line on Picking-rail rows only. Quiet by default; stale variant
   (>30 min session) gets an amber tint per bedrock § 14.1 State 7
   "stale-data indicators are quiet by default" — no banner styling. */
.uiv2-pick-meta {
  font-size: 12px;
  color: var(--ink-500);
  margin-top: 2px;
  line-height: 1.4;
}
.uiv2-pick-meta--stale {
  color: var(--amber-ink);
}

/* ─── Action button variants (extend existing .uiv2-btn) ─── */
.uiv2-btn--default {
  background: #fff;
  color: var(--ink-700);
  border: 1px solid var(--ink-200);
}
.uiv2-btn--default:hover { background: var(--ink-050); }
.uiv2-btn--danger {
  background: var(--rose);
  color: #fff;
  border-color: var(--rose);
}
.uiv2-btn--danger:hover { filter: brightness(0.92); }
/* Outline filter-action buttons — green "Filter" (apply) + red "Clear" (reset),
   used as a pair on the Reservations tabs and the History filter form. */
.uiv2-btn--outline-green {
  background: #fff;
  color: var(--green-700);
  border-color: var(--green-600);
}
.uiv2-btn--outline-green:hover { background: var(--green-050); }
.uiv2-btn--outline-red {
  background: #fff;
  color: var(--rose);
  border-color: var(--rose);
}
.uiv2-btn--outline-red:hover { background: var(--rose-050, #fff1f2); }
/* Button bar — keeps a set of buttons together as one unit (e.g. the Filter +
   Clear pair) so a flex-wrap parent can never split them across rows: the whole
   group wraps together. FileMaker "button bar" equivalent. */
.uiv2-btn-group {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* ─── Responsive (2026-05-13 refinement): table column drop REMOVED ───
   The legacy @media (max-width: 768px) rule that hid table columns by
   nth-child (display: none on cols 4, 6, 7) was Workboard-specific but
   inherited by every .uiv2-table — hiding the wrong columns on Items
   to Pick + Reservations Admin v2 where the column order differs.
   Replaced by per-surface column templates with minmax() + horizontal
   scroll on .uiv2-table. Operators never silently lose data columns.
   See UI_Layout.md § 11 + the per-surface templates above. */

/* ────────── Workboard selection toolbar (Phase 20.1 G2) ────────── */

.uiv2-bulk-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  margin: 0 18px 12px;
  background: var(--green-050);
  border: 1px solid var(--green-600);
  border-radius: var(--radius);
  font-size: 14px;
  color: var(--green-900);
}
.uiv2-bulk-toolbar[hidden] { display: none; }
.uiv2-bulk-toolbar__count {
  font-weight: 600;
  flex: 0 0 auto;
}

/* Danger Zone strip (Phase 20.2 Items List) — dedicated L4 bulk
   toolbar visually separated from the L2/L3 selection toolbar so
   the operator can't fat-finger a destructive bulk op. Per Items
   Module MIC § 9 Q-2 + bedrock § 13.3. */
.uiv2-bulk-toolbar--danger-zone {
  background: var(--rose-050, #fff1f2);
  border-color: var(--rose-600, #e11d48);
  color: var(--rose-900, #881337);
}
.uiv2-bulk-toolbar__actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.uiv2-bulk-toolbar__clear {
  margin-left: auto;
  background: transparent;
  border: none;
  color: var(--green-700);
  cursor: pointer;
  font-size: 13.5px;
  padding: 6px 4px;
}
.uiv2-bulk-toolbar__clear:hover { text-decoration: underline; }

/* ────────── Modal overlay + box ────────── */

.uiv2-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 18, 22, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
.uiv2-modal-overlay[hidden] { display: none; }
.uiv2-modal {
  width: 520px;
  max-width: calc(100vw - 32px);
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 64px -12px rgba(15, 18, 22, 0.4);
  overflow: hidden;
}
.uiv2-modal--reason {
  /* L3 reason-required modal — neutral chrome */
}
.uiv2-modal--destructive {
  /* L4 destructive — danger chrome accent */
  border-top: 3px solid var(--rose);
}
.uiv2-modal--bulk-confirm {
  /* L2 bulk-confirm — same chrome as reason, no field */
}
.uiv2-modal__head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  gap: 10px;
}
.uiv2-modal__title {
  flex: 1;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.2px;
  color: var(--ink-900);
  margin: 0;
}
.uiv2-modal__close {
  background: transparent;
  border: none;
  color: var(--ink-500);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.uiv2-modal__close:hover { color: var(--ink-900); }
.uiv2-modal__body {
  padding: 16px 18px;
}
.uiv2-modal__consequence {
  font-size: 14px;
  color: var(--ink-700);
  line-height: 1.5;
  margin: 0 0 14px;
}
.uiv2-modal__field-label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink-500);
  margin-bottom: 6px;
}
.uiv2-modal__field-label--phrase {
  margin-top: 14px;
}
.uiv2-modal__required {
  color: var(--rose);
  font-weight: 700;
}
.uiv2-modal__phrase-token {
  display: inline-block;
  background: var(--ink-100);
  color: var(--rose);
  padding: 1px 6px;
  border-radius: 3px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px;
}
.uiv2-modal__foot {
  padding: 12px 18px;
  background: var(--ink-050);
  border-top: 1px solid var(--ink-100);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* ────────── Modal form fields ────────── */

.uiv2-textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid var(--ink-200);
  border-radius: 7px;
  min-height: 64px;
  resize: vertical;
  color: var(--ink-900);
  background: #fff;
}
.uiv2-textarea:focus {
  outline: 2px solid var(--green-600);
  outline-offset: -1px;
  border-color: var(--green-600);
}
.uiv2-input--phrase {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  font-size: 14px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  border: 1px solid var(--ink-200);
  border-radius: 7px;
  color: var(--ink-900);
  background: #fff;
}
.uiv2-input--phrase:focus {
  outline: 2px solid var(--rose);
  outline-offset: -1px;
  border-color: var(--rose);
}

/* ────────── Pill — danger variant for L4 modal header ────────── */
.uiv2-pill--danger {
  background: var(--rose);
  color: #fff;
}

/* ────────── Submit-disabled state ────────── */
.uiv2-btn[disabled],
.uiv2-btn[disabled]:hover {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
}

/* ────────── Workboard rail sections (G3) ────────── */

.uiv2-rail__section {
  padding: 6px 4px;
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-rail__section:last-child { border-bottom: none; }

.uiv2-quick-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.uiv2-quick-actions form { margin: 0; }
.uiv2-quick-actions__btn {
  width: 100%;
  text-align: left;
  font-size: 13.5px;
  padding: 6px 10px;
}

.uiv2-saved-views {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.uiv2-saved-views__link {
  font-size: 14px;
  color: var(--ink-700);
}

/* ────────── Active-filters strip (G3) ────────── */

.uiv2-active-filters {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  margin: 0 18px 12px;
  background: var(--ink-050);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius);
  font-size: 13.5px;
  color: var(--ink-700);
}
.uiv2-active-filters__label {
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 12px;
}
.uiv2-active-filters__summary { flex: 1; }
.uiv2-active-filters__clear {
  font-size: 13.5px;
}

/* ────────── Filter slide-out panel (G3) ────────── */

.uiv2-filter-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  max-width: calc(100vw - 32px);
  background: #fff;
  border-left: 1px solid var(--ink-150);
  box-shadow: -12px 0 32px -16px rgba(15, 18, 22, 0.16);
  display: flex;
  flex-direction: column;
  z-index: 40;
  transform: translateX(100%);
  transition: transform 0.18s ease;
}
.uiv2-filter-panel--open { transform: translateX(0); }
.uiv2-filter-panel[hidden] { display: none; }

.uiv2-filter-panel__form {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.uiv2-filter-panel__head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  gap: 10px;
}
.uiv2-filter-panel__title {
  flex: 1;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-900);
  margin: 0;
}
.uiv2-filter-panel__body {
  flex: 1;
  overflow: auto;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.uiv2-filter-panel__date-range {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.uiv2-filter-panel__checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-700);
}
.uiv2-filter-panel__foot {
  padding: 12px 18px;
  border-top: 1px solid var(--ink-100);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Filter form-field primitives */
.uiv2-input,
.uiv2-select {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 10px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid var(--ink-200);
  border-radius: 7px;
  background: #fff;
  color: var(--ink-900);
}
.uiv2-input:focus,
.uiv2-select:focus {
  outline: 2px solid var(--green-600);
  outline-offset: -1px;
  border-color: var(--green-600);
}

/* ────────── Structured-flash banner (.uiv2-flash--bulk) ────────── */

.uiv2-flash--bulk {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 16px;
  margin: 0 18px 16px;
}
.uiv2-flash--bulk__heading {
  font-weight: 600;
}
.uiv2-flash--bulk__skipped,
.uiv2-flash--bulk__errors {
  font-size: 13.5px;
  color: var(--ink-700);
}
.uiv2-flash--bulk__error-list {
  margin: 4px 0 0;
  padding-left: 18px;
}
.uiv2-flash--bulk__error-list li {
  font-size: 13px;
  color: var(--ink-700);
}
.uiv2-flash--bulk__view-affected {
  align-self: flex-start;
  font-size: 13.5px;
  font-weight: 600;
  margin-top: 4px;
}

/* ──────────────────────────────────────────────────────────────────────
   Order Detail (L3 — Build Phase 20.1 Order Detail MIC § 5.4 Commit F).
   Header strip + status strip + 2-column body shell (main work area
   + context rail) + right column cards (Buyer / Totals / Fulfillment)
   + PICKING-state lock variant. Body left-column primitives (blockers,
   group strip, line items, dev tools, fulfill-flow) land in G/H/I.
   ────────────────────────────────────────────────────────────────────── */

.uiv2-detail-header {
  padding: 18px 28px 6px;
}
.uiv2-detail-header__title {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.uiv2-detail-header__order-id {
  color: var(--green-700);
  font-size: 24px;
  font-weight: 700;
}
.uiv2-detail-header__sub {
  margin-top: 4px;
  font-size: 13.5px;
  color: var(--ink-500);
}
.uiv2-detail-header__primary-form {
  display: inline-block;
}

.uiv2-status-strip {
  margin: 0 28px;
  padding: 10px 16px;
  background: var(--ink-050);
  border: 1px solid var(--ink-100);
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: 13px;
}
.uiv2-status-strip__field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.uiv2-status-strip__label {
  color: var(--ink-500);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 11px;
}
.uiv2-status-strip__value {
  font-size: 12.5px;
}
/* Status-strip override tones — applied via Jinja macro in templates.
   CANCELED is terminal-destructive (rose); CANCEL REQUESTED + REFUNDED
   are amber (action-pending or revenue-loss). Same modifier classes
   fire on any of the three pills (EXTERNAL / INTERNAL / PHYSICAL) when
   the rendered value matches — semantic coloring, not pill-specific.
   Tinted background + bold dark text renders as small pill badges
   that read at a glance against the plain mono text on neutral
   values (CLOSED / SHIPPED / FULFILLED). Foreground-only coloring
   was tried first and proved invisible at 11.5px — the tinted-bg
   pattern matches the existing "Printed" chip elsewhere on the page. */
.uiv2-status-strip__value--canceled {
  color: var(--rose);
  background: oklch(96% 0.04 25);
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 4px;
}
.uiv2-status-strip__value--cancel-requested,
.uiv2-status-strip__value--refunded {
  color: var(--amber-ink);
  background: oklch(95% 0.06 75);
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 4px;
}
.uiv2-status-strip__synced {
  margin-left: auto;
  color: var(--ink-500);
}

/* Outer detail-shell wrapper. As of 2026-05-13 rail harmonization the
   context rail moved out of body_content into {% block right_panel %}
   (sibling of <main>); this wrapper is now a passthrough preserving the
   class for backward-compat with route-level test assertions. The inner
   2-column grid (main + KV cards) lives on .uiv2-detail-shell__main. */
.uiv2-detail-shell {
  margin-top: 16px;
  flex: 1;
  min-width: 0;
}
/* As of 2026-05-13 layout pass: col-cards aside removed; the inner
   2-col grid collapses to a single-column passthrough hosting only
   col-main. The KV cards (Buyer / Totals / Fulfillment) + Dev Tools
   now live inline in col-main as 2-card .uiv2-detail-cards-row
   groups (Row A above line items, Row B below). */
.uiv2-detail-shell__main {
  padding: 4px 28px 28px;
  min-width: 0;
}
.uiv2-detail-shell__col-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.uiv2-detail-shell__group-link {
  font-weight: 600;
  color: var(--plum);
}

/* 2-card-per-row primitive used by Order Detail's Row A (Buyer +
   Totals) and Row B (Fulfillment + Dev Tools). Auto-fit grid: stays
   2-col while the container is wide enough for 2 × 260px minimums +
   gap (≈ 536px); collapses to 1-col below that. Parent col-main's
   flex `gap: 16px` handles vertical spacing between consecutive
   children — no margin-bottom on the row itself. */
.uiv2-detail-cards-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  align-items: start;
}

/* Card head + body — new sub-classes for inside-card title bars and
   body padding. Distinct from home.html's existing `.uiv2-card__head`
   usage (which floats title above the card, no border). */
.uiv2-card__head--titled {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid var(--ink-100);
  font-size: 14px;
  font-weight: 700;
}
.uiv2-card__body {
  padding: 14px 16px;
}
.uiv2-card__body--kv {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.uiv2-kv {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.uiv2-kv__label {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink-500);
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.uiv2-kv__value {
  font-size: 14px;
  color: var(--ink-900);
}
.uiv2-kv__value--multiline {
  line-height: 1.45;
}
.uiv2-kv__value--mono {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 500;
}
.uiv2-kv__hint {
  font-size: 12.5px;
  color: var(--ink-500);
  margin-left: 8px;
}

.uiv2-totals-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;
  color: var(--ink-700);
}
.uiv2-totals-row--total {
  border-top: 1px solid var(--ink-100);
  padding-top: 10px;
  margin-top: 4px;
}
.uiv2-totals-row--total span:first-child {
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-totals-row__value {
  font-weight: 700;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}

/* Context rail (Order Detail). As of 2026-05-13 rail harmonization the
   outer chrome (border-left, full-height sticky, width, scroll) is
   provided by the dual-classed .uiv2-rail rule; .uiv2-detail-rail
   scopes only the detail-specific internals below (section, heading,
   btn, locked-body, hint, level pills). */
.uiv2-detail-rail__section {
  padding: 12px 14px 14px;
  border-bottom: 1px solid var(--ink-100);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.uiv2-detail-rail__section:last-child {
  border-bottom: none;
}
.uiv2-detail-rail__section--locked {
  background: oklch(98% 0.02 25);
}
.uiv2-detail-rail__heading {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-500);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.uiv2-detail-rail__heading--rose {
  color: var(--rose);
}
.uiv2-detail-rail__btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: 100%;
}
.uiv2-detail-rail__btn-icon {
  flex: 0 0 15px;
}
.uiv2-detail-rail__btn-label {
  flex: 1;
  text-align: left;
}
.uiv2-detail-rail__locked-body {
  font-size: 13.5px;
  color: var(--ink-700);
  margin-bottom: 6px;
}
.uiv2-detail-rail__hint {
  font-size: 13px;
  color: var(--ink-500);
  font-style: italic;
}
.uiv2-detail-rail__level {
  display: inline-block;
  font-size: 10px;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
}
.uiv2-detail-rail__level--ink {
  background: var(--ink-100);
  color: var(--ink-500);
}
.uiv2-detail-rail__level--rose {
  background: oklch(96% 0.04 25);
  color: var(--rose);
  border: 1px solid var(--rose);
}

/* Skeleton placeholder — used in F for the body left column until
   Commits G/H/I fill in blockers / group / line items / activity /
   dev tools / fulfill-flow. */
.uiv2-placeholder {
  padding: 24px;
  background: var(--ink-050);
  border: 1px dashed var(--ink-200);
  border-radius: 10px;
  color: var(--ink-500);
  font-size: 14px;
  line-height: 1.5;
}

/* Responsive — the outer rail is now governed by the global chrome
   state machine in COLLAPSIBLE RAILS; the inner KV cards reflow via
   .uiv2-detail-cards-row's auto-fit (260px minimum). No media query
   needed on this surface — auto-fit handles 2-col ↔ 1-col fluidly
   from the rail collapse points down to narrow viewports. */

/* ──────────────────────────────────────────────────────────────────────
   Order Detail body left-column primitives — Build Phase 20.1 Order
   Detail MIC § 1.4–§ 1.6 Commit G. Blockers strip + Group context
   card + Line items card.
   ────────────────────────────────────────────────────────────────────── */

.uiv2-blockers-strip {
  background: oklch(98% 0.02 25);
  border: 1px solid var(--rose);
  border-left: 3px solid var(--rose);
  border-radius: 10px;
  padding: 12px 14px;
}
.uiv2-blockers-strip__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.uiv2-blockers-strip__icon {
  color: var(--rose);
  font-size: 15px;
}
.uiv2-blockers-strip__label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--rose);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.uiv2-blockers-strip__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.uiv2-blockers-strip__item {
  /* 4-column grid: pill | reason | time | resolve.
     Phase 8.3 adds two optional rows under the top row — "Flagged
     line(s)" and "Context" — that span columns 2-4 so they indent
     under the reason and skip the pill column. align-items: center
     keeps the top row vertically centered; the new rows are
     single-cell spans so center-alignment is a no-op for them. */
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  column-gap: 10px;
  row-gap: 4px;
  align-items: center;
  font-size: 13.5px;
  color: var(--ink-900);
}
.uiv2-blockers-strip__type {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11.5px;
}
.uiv2-blockers-strip__reason {
  min-width: 0;
}
.uiv2-blockers-strip__time {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px;
  color: var(--ink-500);
}
.uiv2-blockers-strip__resolve {
  /* Right-anchored in the top row — sits to the right of the
     timestamp. Sized small so it doesn't dominate the strip's red
     alert affordance; the strip is information-first, action-second. */
  padding: 4px 10px;
  font-size: 12.5px;
}
.uiv2-blockers-strip__triggers,
.uiv2-blockers-strip__snapshot {
  /* Phase 8.3 — span from the reason column to the right edge so the
     line content indents under the reason text, not under the pill.
     Smaller and dimmer than the top row so the operator's eye still
     lands on the reason first. */
  grid-column: 2 / -1;
  font-size: 12.5px;
  color: var(--ink-700);
  line-height: 1.4;
}
.uiv2-blockers-strip__trigger-line {
  /* Inline-block keeps each SKU + title pair atomic when the trigger
     list wraps on a narrow viewport — prevents break mid-pair. */
  display: inline-block;
}

.uiv2-group-strip {
  background: #fff;
  border: 1px solid var(--ink-150);
  border-left: 3px solid var(--plum);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.uiv2-group-strip__head {
  flex: 1;
  min-width: 0;
}
.uiv2-group-strip__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-group-strip__id {
  color: var(--plum);
  font-weight: 700;
}
.uiv2-group-strip__sub {
  font-size: 13px;
  color: var(--ink-500);
  margin-top: 2px;
}
.uiv2-group-strip__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.uiv2-line-items {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.uiv2-line-items__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.uiv2-line-items__head-meta {
  font-size: 13px;
  color: var(--ink-500);
  font-weight: 500;
}
.uiv2-line-items__th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 10px 16px;
  background: var(--ink-050);
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-line-items__th--center { text-align: center; }
.uiv2-line-items__th--right { text-align: right; }
.uiv2-line-items__row {
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-line-items__row:last-child {
  border-bottom: none;
}
.uiv2-line-items__row--exception {
  background: oklch(98% 0.02 25);
}
.uiv2-line-items__td {
  padding: 12px 16px;
  vertical-align: middle;
}
.uiv2-line-items__td--center { text-align: center; }
.uiv2-line-items__td--right { text-align: right; }
.uiv2-line-items__td--num {
  font-variant-numeric: tabular-nums;
}
.uiv2-line-items__td--item {
  min-width: 0;
  max-width: 280px;
}
/* Item title wraps to at most 2 lines; longer titles ellipsize. Full
   title remains accessible via the `title=` attribute on the span
   (hover tooltip) and via the SKU link (which opens the inventory
   item where the full title is the page header). 2026-05-13: replaces
   the Location column with title-row breathing room — operators use
   the Record Fulfillment flow for actual pick locations. */
.uiv2-line-items__title-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.uiv2-line-items__sku {
  color: var(--green-700);
  font-weight: 600;
  font-size: 13.5px;
  text-decoration: none;
}
.uiv2-line-items__sku:hover {
  text-decoration: underline;
}
.uiv2-line-items__sku-missing {
  color: var(--ink-500);
}
.uiv2-line-items__title {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-weight: 500;
}
.uiv2-line-items__exc-pill {
  font-size: 11.5px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
}
.uiv2-line-items__res-pill {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.uiv2-line-items__blocks-available {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--amber-ink);
  text-align: right;
}
.uiv2-line-items__exception-row {
  background: oklch(98% 0.02 25);
}
.uiv2-line-items__exception-detail {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 0;
}
.uiv2-line-items__exception-msg {
  font-size: 13px;
  color: var(--rose);
  flex: 1;
  min-width: 0;
}
.uiv2-line-items__exception-link {
  font-size: 13px;
  font-weight: 500;
  flex: 0 0 auto;
}
.uiv2-line-items__impact-summary {
  padding: 10px 16px;
  background: oklch(98% 0.04 75);
  border-top: 1px solid var(--ink-100);
  font-size: 13px;
  color: var(--ink-700);
}

/* ──────────────────────────────────────────────────────────────────────
   Order History card — append-only lifecycle timeline rendered on
   Order Detail under the Line items table. Mirrors the line-items
   table primitives (th/td padding, header row tone, row borders)
   but in a `uiv2-history` namespace so the two surfaces can diverge
   independently. See order_detail.html for the inline event-label /
   event-tone maps that drive the row pills.
   ────────────────────────────────────────────────────────────────── */
.uiv2-history {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.uiv2-history__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.uiv2-history__head-meta {
  font-size: 13px;
  color: var(--ink-500);
  font-weight: 500;
}
.uiv2-history__th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 10px 16px;
  background: var(--ink-050);
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-history__th--time { width: 140px; }
.uiv2-history__th--actor { width: 220px; }
.uiv2-history__row {
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-history__row:last-child {
  border-bottom: none;
}
.uiv2-history__td {
  padding: 12px 16px;
  vertical-align: top;
}
.uiv2-history__td--time {
  white-space: nowrap;
  font-size: 13px;
  color: var(--ink-700);
}
.uiv2-history__td--details {
  min-width: 0;
  color: var(--ink-900);
  line-height: 1.45;
}
.uiv2-history__td--actor {
  font-size: 13px;
  color: var(--ink-700);
  word-break: break-word;
}
.uiv2-history__type {
  font-size: 12px;
  white-space: nowrap;
}
.uiv2-history__detail-line {
  margin-top: 2px;
  line-height: 1.4;
}
.uiv2-history__detail-line:first-child {
  margin-top: 0;
}
.uiv2-history__detail-muted {
  font-size: 12.5px;
  color: var(--ink-500);
  margin-top: 2px;
}
.uiv2-history__empty {
  padding: 16px;
  font-size: 13px;
  color: var(--ink-500);
  text-align: center;
}

/* ──────────────────────────────────────────────────────────────────────
   Record Fulfillment — Order Detail MIC § 1.12 Commit H. Inline flow
   that renders above the body left column when the resolver returns
   record_fulfillment as the primary action AND blocked_actions does
   not gate it. Plus the resolver-blocked panel for when it does.
   Modal chrome reuses the .uiv2-modal-overlay + .uiv2-modal family
   (workboard.js pattern).
   ────────────────────────────────────────────────────────────────────── */

.uiv2-rf-blocked {
  background: oklch(98% 0.04 75);
  border: 1px solid oklch(80% 0.10 75);
  border-left: 3px solid var(--amber);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.uiv2-rf-blocked__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.uiv2-rf-blocked__icon {
  color: var(--amber-ink);
  font-size: 15px;
}
.uiv2-rf-blocked__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-900);
}
.uiv2-rf-blocked__body {
  flex: 1 1 100%;
  font-size: 13.5px;
  color: var(--ink-700);
  line-height: 1.45;
}
.uiv2-rf-blocked__actions {
  display: flex;
  gap: 8px;
}

.uiv2-fulfill-flow {
  background: #fff;
  border: 1px solid var(--ink-200);
  border-top: 3px solid var(--green-700);
  border-radius: 12px;
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}
.uiv2-fulfill-flow__head {
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--ink-100);
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.uiv2-fulfill-flow__icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--green-050);
  color: var(--green-700);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 32px;
  font-size: 17px;
}
.uiv2-fulfill-flow__title-block {
  flex: 1;
  min-width: 0;
}
.uiv2-fulfill-flow__title {
  font-size: 15.5px;
  font-weight: 700;
  color: var(--ink-900);
  display: flex;
  align-items: center;
  gap: 8px;
}
.uiv2-fulfill-flow__subtitle {
  font-size: 13.5px;
  color: var(--ink-500);
  margin-top: 3px;
  line-height: 1.5;
}
.uiv2-fulfill-flow__close-link {
  text-decoration: none;
  font-size: 20px;
  line-height: 1;
}
.uiv2-fulfill-flow__progress {
  padding: 10px 18px;
  background: var(--ink-050);
  border-bottom: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-700);
}
.uiv2-fulfill-flow__progress-bar {
  flex: 1;
  height: 4px;
  background: var(--ink-100);
  border-radius: 2px;
  overflow: hidden;
}
.uiv2-fulfill-flow__progress-bar > div {
  height: 100%;
  width: 0;
  background: var(--green-700);
  transition: width 0.2s ease;
}
.uiv2-fulfill-flow__blocker-banner {
  margin: 12px 18px 0;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--rose);
  border-left: 3px solid var(--rose);
  border-radius: 8px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.uiv2-fulfill-flow__blocker-banner[hidden] { display: none; }
.uiv2-fulfill-flow__blocker-icon {
  color: var(--rose);
  font-size: 15px;
}
.uiv2-fulfill-flow__blocker-text {
  flex: 1;
  font-size: 13.5px;
}
.uiv2-fulfill-flow__blocker-text strong {
  display: block;
  color: var(--rose);
}
.uiv2-fulfill-flow__lines {
  padding: 6px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.uiv2-fulfill-line {
  border: 1px solid var(--ink-100);
  border-radius: 8px;
  padding: 10px 12px;
}
.uiv2-fulfill-line[data-empty="1"] {
  background: oklch(98% 0.02 25);
  border-color: var(--rose);
}
.uiv2-fulfill-line__head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}
.uiv2-fulfill-line__status {
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--ink-500);
}
.uiv2-fulfill-line__status[data-status-kind="ready"] { color: var(--green-700); }
.uiv2-fulfill-line__status[data-status-kind="partial"] { color: var(--amber-ink); }
.uiv2-fulfill-line__status[data-status-kind="empty"] { color: var(--rose); }
.uiv2-fulfill-line__status[data-status-kind="over"] { color: var(--rose); }
.uiv2-fulfill-line__sku {
  color: var(--green-700);
  font-weight: 600;
  font-size: 13.5px;
}
.uiv2-fulfill-line__title {
  flex: 1;
  min-width: 0;
}
.uiv2-fulfill-line__progress {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13px;
  color: var(--ink-500);
}
.uiv2-fulfill-line__alloc-rows {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.uiv2-fulfill-line__alloc-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.uiv2-fulfill-line__alloc-loc {
  flex: 1;
  min-width: 0;
}
.uiv2-fulfill-line__alloc-qty {
  width: 70px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.uiv2-fulfill-line__add-split {
  margin-top: 8px;
}
.uiv2-fulfill-line__empty {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--rose);
  font-style: italic;
}
.uiv2-fulfill-flow__footer {
  padding: 12px 18px;
  background: var(--ink-050);
  border-top: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  gap: 10px;
}
.uiv2-fulfill-flow__summary {
  flex: 1;
  font-size: 13.5px;
  color: var(--ink-700);
}
.uiv2-fulfill-flow__effects {
  margin: 10px 0 0;
  padding-left: 20px;
  font-size: 13.5px;
  color: var(--ink-700);
  line-height: 1.6;
}
.uiv2-fulfill-flow__confirm-summary {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--ink-050);
  border-radius: 6px;
  font-size: 13.5px;
  color: var(--ink-700);
}
.uiv2-fulfill-flow__confirm-summary div {
  margin-bottom: 4px;
}
.uiv2-fulfill-flow__confirm-summary div:last-child {
  margin-bottom: 0;
}

/* ──────────────────────────────────────────────────────────────────────
   Developer / admin recovery — Order Detail MIC § 1.8 Commit I.
   Native <details>/<summary> collapsible. Admin-gated; non-admin
   sees the header + "Admin only" placeholder. PICKING-lock variant
   per § 1.13: only Reset to Pickable + Scanner Test render inside.
   Modals reuse .uiv2-modal-overlay + .uiv2-modal--destructive family
   from Workboard's bulk-action modals — no new modal primitives.
   ────────────────────────────────────────────────────────────────────── */

.uiv2-dev-tools {
  background: #fff;
  border: 1px solid var(--ink-150);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.uiv2-dev-tools[open] .uiv2-dev-tools__head {
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-dev-tools__head {
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  list-style: none;
}
.uiv2-dev-tools__head::-webkit-details-marker {
  display: none;
}
.uiv2-dev-tools__icon {
  color: var(--ink-500);
  font-size: 15px;
}
.uiv2-dev-tools__title {
  flex: 1;
}
.uiv2-dev-tools__level {
  margin-right: 4px;
}
.uiv2-dev-tools__chev {
  color: var(--ink-500);
  font-size: 12px;
  transition: transform 0.15s ease;
}
.uiv2-dev-tools[open] .uiv2-dev-tools__chev {
  transform: rotate(180deg);
}
.uiv2-dev-tools__body {
  padding: 14px 16px;
  background: var(--ink-050);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.uiv2-dev-tools__body--gated {
  align-items: center;
  justify-content: center;
  padding: 18px 16px;
}
.uiv2-dev-tools__gated-text {
  font-size: 13.5px;
  color: var(--ink-500);
  font-style: italic;
}
.uiv2-dev-tools__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.uiv2-dev-tools__btn {
  width: 100%;
}
.uiv2-dev-tools__field {
  background: #fff;
  border: 1px solid var(--ink-200);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.uiv2-dev-tools__field-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink-500);
}
.uiv2-dev-tools__field-level {
  display: inline-block;
  margin-left: 6px;
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 4px;
  background: oklch(96% 0.04 25);
  color: var(--rose);
  border: 1px solid var(--rose);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.uiv2-dev-tools__field-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.uiv2-dev-tools__select {
  flex: 1;
}
.uiv2-dev-tools__scanner-input {
  flex: 1;
  font-size: 13.5px;
  background: var(--ink-050);
  border: 1px solid var(--ink-150);
  border-radius: 5px;
  padding: 6px 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.uiv2-dev-tools__field-hint {
  font-size: 11.5px;
  color: var(--ink-500);
}
.uiv2-dev-tools__reason {
  width: 100%;
  font-size: 13px;
  padding: 6px 8px;
  resize: vertical;
}
.uiv2-dev-tools__footer-text {
  font-size: 12.5px;
  color: var(--ink-500);
  line-height: 1.55;
  margin-top: 4px;
}

/* Modal warn-tone consequence — used by Reset to Pickable modal's
   restocking warning per § 8 Q2 verbatim copy. */
.uiv2-modal__consequence--warn {
  color: var(--amber-ink);
  font-weight: 500;
}

/* ──────────────────────────────────────────────────────────────────
   COLLAPSIBLE RAILS — responsive primitive (2026-05-13 refinement)

   Body classes drive layout state:
     .uiv2-sidebar-state-{expanded|collapsed|hidden}
     .uiv2-rail-state-{expanded|hidden}

   Inline boot script in app_base_v2.html applies one of each class
   to <body> before paint, reading localStorage first then falling
   back to viewport-width defaults:
     ≥1280px : sidebar=expanded, rail=expanded
     1024–1279 : sidebar=collapsed, rail=expanded
     <1024px : sidebar=hidden,   rail=hidden
   User toggles override and persist to localStorage; the body class
   is always authoritative once boot has run.
   ────────────────────────────────────────────────────────────────── */

/* Width transitions for sidebar collapse. Keep existing `position: sticky`
   from the base .uiv2-sidebar rule — `sticky` already creates a positioning
   context for the absolutely-positioned toggle button, no override needed. */
.uiv2-sidebar {
  transition: width 200ms ease, flex-basis 200ms ease;
}

/* Sidebar collapsed: 64px icon rail. Hidden: removed from flow. */
body.uiv2-sidebar-state-collapsed .uiv2-sidebar { width: 64px; flex-basis: 64px; }
body.uiv2-sidebar-state-hidden    .uiv2-sidebar { display: none; }

/* Collapsed-state: hide labels, brand text, group heads, submenu,
   user info, search text, pills/badges */
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__brand-name,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__brand > div:not(.uiv2-sidebar__logo),
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__item-label,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__group-head,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__submenu,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__user-info,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__logout-form,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__item .uiv2-pill {
  display: none;
}
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__brand,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__item,
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__user {
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
}
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__group {
  padding-left: 8px;
  padding-right: 8px;
}
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__nav { overflow-x: hidden; }

/* Sidebar toggle button — small chevron floating on the outside edge */
.uiv2-sidebar__toggle {
  position: absolute;
  top: 22px;
  right: -11px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--ink-150);
  color: var(--ink-500);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 6;
  padding: 0;
  box-shadow: var(--shadow-sm);
  transition: color 0.12s, border-color 0.12s;
}
.uiv2-sidebar__toggle:hover {
  color: var(--ink-900);
  border-color: var(--ink-400);
}
.uiv2-sidebar__toggle svg { transition: transform 200ms ease; }
body.uiv2-sidebar-state-collapsed .uiv2-sidebar__toggle svg { transform: rotate(180deg); }
body.uiv2-sidebar-state-hidden    .uiv2-sidebar__toggle { display: none; }

/* Hamburger button in topbar — only when sidebar is fully hidden */
.uiv2-topbar__hamburger {
  width: 32px;
  height: 32px;
  display: none;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--ink-150);
  border-radius: 7px;
  color: var(--ink-700);
  cursor: pointer;
  margin-right: 12px;
}
.uiv2-topbar__hamburger:hover { background: var(--ink-050); color: var(--ink-900); }
body.uiv2-sidebar-state-hidden .uiv2-topbar__hamburger { display: inline-flex; }

/* Actions panel — three states (mirror of sidebar):
     expanded  (~280px) -> full content, labels visible
     collapsed (~64px)  -> icon-only rail; labels, headers, saved views
                            suppressed; filter pills become just colored
                            dots (state name implicit via hover tooltip)
     hidden    (0px)    -> panel removed from flex layout
   Chevron on panel's left edge cycles expanded <-> collapsed.
   Topbar 'Show actions' button (data-rail-show) restores from hidden. */

body.uiv2-rail-state-collapsed .uiv2-rail { width: 64px; flex-basis: 64px; }
body.uiv2-rail-state-hidden    .uiv2-rail { display: none; }

/* Collapsed state — hide text content; the chevron stays so the
   operator can expand back. Section headers + saved views hidden.
   Quick Actions buttons collapse to icon-only via .uiv2-quick-actions__label
   suppression. Filter pills lose label + count, keep just the colored dot. */
body.uiv2-rail-state-collapsed .uiv2-rail__header,
body.uiv2-rail-state-collapsed .uiv2-quick-actions__label,
body.uiv2-rail-state-collapsed .uiv2-rail__label,
body.uiv2-rail-state-collapsed .uiv2-rail__count,
body.uiv2-rail-state-collapsed .uiv2-saved-views,
body.uiv2-rail-state-collapsed .uiv2-banner--provider-disconnected {
  display: none;
}
/* Saved views section header alone — hide the whole section since
   the views need labels to be useful. Identified by the section that
   contains a .uiv2-saved-views child (third section in the rail). */
body.uiv2-rail-state-collapsed .uiv2-rail__section:has(.uiv2-saved-views) {
  display: none;
}
body.uiv2-rail-state-collapsed .uiv2-rail__content {
  padding: 12px 8px;
}
body.uiv2-rail-state-collapsed .uiv2-quick-actions__btn {
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
}
body.uiv2-rail-state-collapsed .uiv2-rail__pill {
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
}
body.uiv2-rail-state-collapsed .uiv2-rail__dot {
  width: 10px;
  height: 10px;
  flex-basis: 10px;
}

/* Chevron rotation when collapsed — points outward (right) instead of
   inward (left), signaling "click to expand back". Mirror of sidebar. */
.uiv2-rail__toggle svg { transition: transform 200ms ease; }
body.uiv2-rail-state-collapsed .uiv2-rail__toggle svg { transform: rotate(180deg); }

/* Topbar reveal button: visible only when panel is fully hidden. The
   panel chevron handles expanded <-> collapsed; the topbar button is
   the escape hatch from the fully-hidden state. */
.uiv2-rail-show { display: none; }
body.uiv2-rail-state-hidden .uiv2-rail-show { display: inline-flex; }

/* ─── Order Detail rail — collapsed-state internals (2026-05-13).
   The shared .uiv2-rail collapsed selectors target Workboard-specific
   primitives (__header, __label, __count, __pill). Detail-rail uses
   its own internals (__heading, __btn-label, __locked-body, __hint,
   __level), so the hide rules below are scoped explicitly. Icon SVGs
   inside .uiv2-detail-rail__btn stay visible at 64px width; text
   labels suppress; tooltips (title=) carry the action names. */
body.uiv2-rail-state-collapsed .uiv2-detail-rail__heading,
body.uiv2-rail-state-collapsed .uiv2-detail-rail__btn-label,
body.uiv2-rail-state-collapsed .uiv2-detail-rail__locked-body,
body.uiv2-rail-state-collapsed .uiv2-detail-rail__hint,
body.uiv2-rail-state-collapsed .uiv2-detail-rail__level {
  display: none;
}
body.uiv2-rail-state-collapsed .uiv2-detail-rail__btn {
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
  gap: 0;
}
body.uiv2-rail-state-collapsed .uiv2-detail-rail__section {
  padding: 8px;
}

/* ─── Locked-state force-expand. The locked rail variant (PICKING-state
   structural lock per Order Detail MIC § 8 Q2) explains WHY the order
   is uncontrollable. Two of three render branches have no button to
   carry a tooltip (admin-with-active-session and non-admin both show
   hint text only), so collapsing the rail strips operator context the
   page can't recover. Force-expand whenever the locked section renders,
   regardless of body class. :has() supported on the Chrome-target
   operator viewport. */
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) {
  width: 280px;
  flex: 0 0 280px;
}
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__heading,
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__btn-label,
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__locked-body,
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__hint {
  display: revert;
}
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__btn {
  justify-content: flex-start;
  padding-left: 14px;
  padding-right: 14px;
  gap: 8px;
}
body.uiv2-rail-state-collapsed .uiv2-detail-rail:has(.uiv2-detail-rail__section--locked) .uiv2-detail-rail__section {
  padding: 12px 14px 14px;
}

/* ────────── Item Detail v2 (Phase 20.2, surface 3 of 6) ──────────
   Read-mode primitives that extend the canonical detail-page shell.
   .uiv2-detail-header + .uiv2-detail-shell family (reused from Order
   Detail). Adds: prose helpers + per-card table column templates. */

/* Prose — paragraph text inside cards (Danger Zone consequence copy,
   Review note, Photos placeholder). */
.uiv2-prose {
  margin: 0 0 12px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-900);
}
.uiv2-prose:last-child { margin-bottom: 0; }
.uiv2-prose--muted { color: var(--ink-500); }

/* Inventory card — 2 columns: Location · On hand (right) */
.uiv2-table--inventory .uiv2-table__header,
.uiv2-table--inventory .uiv2-table__row {
  grid-template-columns: 1fr 110px;
}

/* Compatibility card — 5 columns: Model · Display name · Role · Notes · Action */
.uiv2-table--compatibility .uiv2-table__header,
.uiv2-table--compatibility .uiv2-table__row {
  grid-template-columns: minmax(120px, 0.7fr) minmax(180px, 1.4fr) minmax(80px, 0.5fr) minmax(140px, 1fr) 90px;
}

/* Listings card — 5 columns: Channel · Title · State · Qty · Last seen */
.uiv2-table--listings .uiv2-table__header,
.uiv2-table--listings .uiv2-table__row {
  grid-template-columns: minmax(80px, 0.5fr) minmax(200px, 1.6fr) minmax(90px, 0.5fr) 110px 120px;
}

/* Reservations card — 6 columns: Order · Channel · Status · Reserved · Picked · When */
.uiv2-table--reservations .uiv2-table__header,
.uiv2-table--reservations .uiv2-table__row {
  grid-template-columns: minmax(120px, 0.8fr) minmax(80px, 0.5fr) minmax(90px, 0.6fr) 90px 80px 110px;
}

/* Activity card — 6 columns: When · Action · Location · Delta · Reason · By */
.uiv2-table--activity .uiv2-table__header,
.uiv2-table--activity .uiv2-table__row {
  grid-template-columns: 140px minmax(100px, 0.6fr) 100px 80px minmax(140px, 1fr) minmax(140px, 0.9fr);
}
/* Detail-page in-card tables (Inventory, Listings, Reservations, Compatibility,
   Recent activity, …) are short lists on a normally-scrolling detail page — NOT
   workboard scroll-hosts. The global sticky `.uiv2-table__header` otherwise pins
   at the workboard-head offset and strands itself mid-list as the page scrolls.
   Kill sticky for EVERY table inside a `.uiv2-detail-shell` (item / model / order
   detail + create) regardless of table modifier; work surfaces
   (.uiv2-table-host / workboard) keep their sticky headers. Fixed 2026-06-16;
   broadened 2026-06-17 from activity-only after Listings/Inventory still floated. */
.uiv2-detail-shell .uiv2-table__header {
  position: static;
}

/* Danger-zone card wrapper — rose tint on the section card itself
   (parallel to .uiv2-bulk-toolbar--danger-zone on selection toolbars).
   Bedrock § 13 L4 lives inside this wrapper on detail surfaces. */
.uiv2-section--danger-zone {
  border-color: var(--rose-600, #e11d48);
  background: var(--rose-050, #fff1f2);
}
.uiv2-section--danger-zone .uiv2-card__head--titled {
  border-bottom-color: var(--rose-600, #e11d48);
}
.uiv2-section--danger-zone .uiv2-card__title {
  color: var(--rose-900, #881337);
}

/* Edit-mode lock/unlock switch — used by Item Detail v2 + Items
   Sections v2 (Phase 20.2 surfaces 3+4). Admin-only pill that
   toggles between read-mode (locked) and edit-mode (unlocked). Maps
   to ?mode=edit query param. Locked state = neutral ink; unlocked
   state = amber to signal "fields editable, autosave armed". */
.uiv2-edit-switch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--ink-200, var(--ink-150));
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900);
  background: #fff;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.uiv2-edit-switch:hover {
  border-color: var(--ink-500);
  background: var(--ink-050);
}
.uiv2-edit-switch__icon {
  font-size: 14px;
  line-height: 1;
}
.uiv2-edit-switch__label {
  letter-spacing: 0.2px;
}
.uiv2-edit-switch--locked {
  color: var(--ink-700);
  background: #fff;
}
.uiv2-edit-switch--unlocked {
  color: var(--amber-ink, var(--ink-900));
  background: oklch(96% 0.06 75);
  border-color: var(--amber, var(--ink-500));
}
.uiv2-edit-switch--unlocked:hover {
  background: oklch(94% 0.07 75);
  border-color: var(--amber-ink, var(--ink-700));
}

/* Small + link button variants — used by Item Detail's per-field Save
   buttons (Title, Review), Stock Adjust submit, and inline detach links. */
.uiv2-btn--sm {
  padding: 4px 10px;
  font-size: 13px;
}
.uiv2-btn--link {
  background: transparent;
  border: none;
  color: var(--rose);
  padding: 0;
  cursor: pointer;
  font-size: 13px;
  text-decoration: underline;
}
.uiv2-btn--link:hover { color: var(--rose-900, #881337); }

/* Stock Adjust inline form — Inventory card body. Operator-OK per
   Module MIC Q-9 exception. Horizontal flex row at desktop, stacked
   on small screens. */
.uiv2-stock-adjust {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--ink-150);
}
.uiv2-stock-adjust__row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.uiv2-stock-adjust__label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-right: 4px;
}
.uiv2-stock-adjust__location { flex: 1 1 200px; }
.uiv2-stock-adjust__qty { flex: 0 0 90px; }
.uiv2-stock-adjust__reason { flex: 1 1 200px; }

/* Compatibility attach typeahead — Compatibility card body. Result
   list renders as a stack of clickable buttons below the search input. */
.uiv2-compat-attach {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--ink-150);
}

/* Recent-model chips — sticky one-click attach for the last 5 models
   this user touched. Restored from legacy items_view_page.html. */
.uiv2-compat-attach__recent {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}
.uiv2-chip {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--ink-150);
  background: #fff;
  font-size: 12.5px;
  font-weight: 500;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  color: var(--ink-900);
  cursor: pointer;
}
.uiv2-chip:hover {
  border-color: var(--green-600);
  background: var(--green-050);
}
.uiv2-chip--recent { /* semantic anchor; baseline pill styling above */ }
.uiv2-compat-attach__results {
  margin-top: 6px;
  border: 1px solid var(--ink-150);
  border-radius: 6px;
  background: #fff;
  max-height: 240px;
  overflow-y: auto;
}
.uiv2-compat-attach__result {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--ink-100);
  cursor: pointer;
  font-size: 13.5px;
  color: var(--ink-900);
}
.uiv2-compat-attach__result:last-child { border-bottom: none; }
.uiv2-compat-attach__result:hover {
  background: var(--green-050);
}

/* Photo thumbnail grid — read-only display, click → lightbox. */
.uiv2-photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}
.uiv2-photo-thumb {
  background: transparent;
  border: 1px solid var(--ink-150);
  border-radius: 6px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  display: block;
}
.uiv2-photo-thumb:hover {
  border-color: var(--green-600);
}
.uiv2-photo-thumb--primary {
  border-color: var(--green-600);
  border-width: 2px;
}
.uiv2-photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Interactive assignment-gallery variant (Phase 20.9 Inline Model Media).
   The thumb is a clickable div (so the bulk checkbox + ★ can nest); selection
   drives the footer action bar, the checkbox drives the bulk bar. No slots. */
.uiv2-photo-thumb--interactive { position: relative; }
.uiv2-photo-thumb--selected { outline: 2px solid var(--sky); outline-offset: 1px; }
.uiv2-photo-thumb--checked { outline: 2px solid var(--green-600); outline-offset: 1px; }
.uiv2-photo-thumb__star {
  position: absolute;
  top: 3px;
  right: 3px;
  font-size: 12px;
  color: var(--green-700);
  text-shadow: 0 0 2px #fff;
}
.uiv2-photo-thumb__check {
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  margin: 0;
  cursor: pointer;
  opacity: 0;
  z-index: 2;
}
.uiv2-photo-thumb--interactive:hover .uiv2-photo-thumb__check,
.uiv2-photo-thumb__check:checked { opacity: 1; }
.uiv2-photo-thumb__info {
  position: absolute;
  right: 4px;
  bottom: 4px;
  width: 19px;
  height: 19px;
  border-radius: 999px;
  border: 1px solid var(--ink-150);
  background: rgba(255, 255, 255, .92);
  color: var(--ink-700);
  font-size: 11px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 3;
  /* Hidden via opacity (not display:none) so the button stays in the tab order
     and the :focus reveal actually fires for keyboard users — the `?` shortcut
     opens the drawer for the focused thumb (P2 a11y review fix). */
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s;
}
.uiv2-photo-thumb--interactive:hover .uiv2-photo-thumb__info,
.uiv2-photo-thumb__info:focus { opacity: 1; pointer-events: auto; }

/* Lightbox modifier on .uiv2-modal-overlay — full-screen photo viewer.
   Item Detail Page MIC § 8.1 Q-B locked: extend canonical modal,
   adopt vanilla-JS handler pattern from items_view_page.html. */
.uiv2-modal-overlay--lightbox {
  display: flex !important;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.92);
  padding: 24px;
}
.uiv2-modal-overlay--lightbox[hidden] {
  display: none !important;
}
.uiv2-lightbox__close {
  position: absolute;
  top: 20px;
  right: 20px;
  background: #fff;
  color: var(--ink-900);
  border: none;
  border-radius: 999px;
  width: 36px;
  height: 36px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.uiv2-lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.85);
  color: var(--ink-900);
  border: none;
  border-radius: 999px;
  width: 44px;
  height: 44px;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.uiv2-lightbox__nav--prev { left: 24px; }
.uiv2-lightbox__nav--next { right: 24px; }
.uiv2-lightbox__nav:hover {
  background: #fff;
}
.uiv2-lightbox__image {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: 8px;
  background: #000;
}

/* ────────── Inline media CRUD (Phase 20.9 Inline Item Media) ──────────
 * Promotes the read-only photo grid / doc list to interactive management.
 * Shared in *shape* by inline model media (20.9 surface 2); the JS wiring
 * and backing diverge (slot vs assignment) per 20.9 § 9.5. Second-occurrence
 * earns a Patterns.md reference on model-media ship. */

/* Slot grid — 24-slot capacity view (filled + empty "+ Add"), ported from the
 * mockup's .pmp-slot-* (Build_Phase_20_9_Media_Design/inline-media.jsx). Slot 1
 * is primary; click selects → footer action bar acts on the selection. */
.uiv2-slot-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 6px;
}
.uiv2-slot {
  position: relative;
  aspect-ratio: 1;
  background: var(--ink-100);
  border: 1px solid var(--ink-150);
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10.5px;
  color: var(--ink-500);
  cursor: pointer;
  padding: 0;
}
.uiv2-slot--filled { border: 1px solid var(--ink-200); background: #fff; }
.uiv2-slot--primary { border: 2px solid var(--green-600); box-shadow: 0 0 0 2px var(--green-050); }
.uiv2-slot--empty { border: 1px dashed var(--ink-200); color: var(--ink-400); background: var(--ink-050); }
.uiv2-slot--selected { outline: 2px solid var(--sky); outline-offset: 1px; }
.uiv2-slot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.uiv2-slot__num {
  position: absolute;
  bottom: 3px;
  left: 4px;
  background: rgba(255, 255, 255, .85);
  color: var(--ink-700);
  font-size: 9px;
  font-weight: 700;
  padding: 0 4px;
  border-radius: 3px;
  line-height: 14px;
  font-family: "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace;
}
.uiv2-slot--primary .uiv2-slot__num { background: var(--green-700); color: #fff; }
.uiv2-slot__star { position: absolute; top: 3px; right: 3px; font-size: 11px; color: var(--green-700); }
/* Bulk-select checkbox (top-left). Visible when checked or on cell hover so it
   doesn't clutter the grid; click toggles bulk selection without selecting the slot. */
.uiv2-slot__check {
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  margin: 0;
  cursor: pointer;
  opacity: 0;
  z-index: 2;
}
.uiv2-slot--filled:hover .uiv2-slot__check,
.uiv2-slot__check:checked { opacity: 1; }
.uiv2-slot--checked { outline: 2px solid var(--green-600); outline-offset: 1px; }
.uiv2-slot__info {
  position: absolute;
  bottom: 3px;
  right: 3px;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .9);
  border: 1px solid var(--ink-150);
  font-size: 10px;
  line-height: 1;
  color: var(--ink-700);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* Opacity-hide (not display:none) so the button is tabbable and the :focus
     reveal fires for keyboard users — enables the `?` shortcut (P2 a11y fix). */
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s;
}
.uiv2-slot--filled:hover .uiv2-slot__info,
.uiv2-slot__info:focus { opacity: 1; pointer-events: auto; }

/* Selected-slot footer action bar. */
.uiv2-media-actionbar {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 8px 14px;
  border-top: 1px solid var(--ink-100);
  background: var(--ink-050);
  font-size: 12px;
}
.uiv2-media-actionbar__readout { flex: 1; color: var(--ink-500); min-width: 0; }
.uiv2-media-actionbar[hidden] { display: none; }

/* Media uploader — dashed dropzone + hidden input + progress line. */
.uiv2-media-uploader {
  border: 1.5px dashed var(--ink-200);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  text-align: center;
  background: var(--ink-050);
  transition: border-color .12s ease, background .12s ease;
}
.uiv2-media-uploader--dragover {
  border-color: var(--green-600);
  background: var(--green-050);
}
.uiv2-media-uploader[hidden] { display: none; }
.uiv2-media-uploader__hint { color: var(--ink-500); font-size: 12.5px; margin-top: 6px; }
.uiv2-media-uploader__input { display: none; }
.uiv2-media-progress {
  font-size: 12.5px;
  color: var(--green-700);
  font-weight: 600;
  margin-top: 8px;
  min-height: 1em;
}
.uiv2-media-progress--error { color: var(--rose); }
.uiv2-media-full-note {
  font-size: 12.5px;
  color: var(--amber-ink);
  font-weight: 600;
}
.uiv2-doc-row__remove {
  background: transparent;
  border: none;
  color: var(--ink-500);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
  margin-left: 8px;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}
.uiv2-doc-row__remove:hover { color: var(--rose); background: var(--ink-050); }

/* Global Asset Detail drawer (Phase 20.9 Media Hub G-9). */
.uiv2-asset-drawer {
  position: fixed;
  inset: 0;
  z-index: 2100;
  pointer-events: none;
}
.uiv2-asset-drawer__scrim {
  position: absolute;
  inset: 0;
  background: rgba(17, 24, 39, .36);
  opacity: 0;
  transition: opacity .16s ease;
}
.uiv2-asset-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  width: min(440px, 100vw);
  height: 100%;
  background: #fff;
  border-left: 1px solid var(--ink-150);
  box-shadow: -18px 0 42px rgba(15, 23, 42, .14);
  transform: translateX(100%);
  transition: transform .18s ease;
  display: flex;
  flex-direction: column;
}
.uiv2-asset-drawer--open { pointer-events: auto; }
.uiv2-asset-drawer--open .uiv2-asset-drawer__scrim { opacity: 1; }
.uiv2-asset-drawer--open .uiv2-asset-drawer__panel { transform: translateX(0); }
.uiv2-asset-drawer__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-asset-drawer__eyebrow {
  color: var(--ink-500);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.uiv2-asset-drawer__title { margin: 2px 0 0; font-size: 20px; line-height: 1.2; }
.uiv2-asset-drawer__close {
  width: 32px;
  height: 32px;
  border: 1px solid var(--ink-150);
  border-radius: 999px;
  background: #fff;
  color: var(--ink-700);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.uiv2-asset-drawer__body { padding: 16px 18px 22px; overflow-y: auto; }
.uiv2-asset-drawer__preview {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--ink-150);
  border-radius: 8px;
  background: var(--ink-050);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  margin-bottom: 14px;
}
.uiv2-asset-drawer__preview-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.uiv2-asset-drawer__preview-empty,
.uiv2-asset-drawer__state,
.uiv2-asset-drawer__empty {
  color: var(--ink-500);
  font-size: 13px;
}
.uiv2-asset-drawer__state { padding: 16px 0; }
.uiv2-asset-drawer__state--error { color: var(--rose); }
.uiv2-asset-drawer__section {
  border-top: 1px solid var(--ink-100);
  padding-top: 12px;
  margin-top: 12px;
}
.uiv2-asset-drawer__section h3 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 800;
}
.uiv2-asset-drawer__count { color: var(--ink-500); font-weight: 600; }
.uiv2-asset-drawer__row {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  gap: 10px;
  padding: 6px 0;
  font-size: 12.5px;
}
.uiv2-asset-drawer__row span { color: var(--ink-500); }
.uiv2-asset-drawer__row strong {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-asset-drawer__timeline-row {
  display: grid;
  gap: 2px;
  padding: 9px 0;
  border-top: 1px solid var(--ink-100);
  font-size: 12.5px;
}
.uiv2-asset-drawer__timeline-row:first-of-type { border-top: none; }
.uiv2-asset-drawer__timeline-row strong { color: var(--ink-900); }
.uiv2-asset-drawer__timeline-row span { color: var(--ink-700); }
.uiv2-asset-drawer__timeline-row small { color: var(--ink-500); }
/* Per-assignment Detach button (sits on the assignment timeline row). */
.uiv2-asset-drawer__detach {
  justify-self: start;
  margin-top: 4px;
  padding: 2px 8px;
  font-size: 11.5px;
  border: 1px solid var(--ink-150);
  border-radius: 5px;
  background: #fff;
  color: var(--rose);
  cursor: pointer;
}
.uiv2-asset-drawer__detach:hover { background: var(--ink-050); }
.uiv2-asset-drawer__detach:disabled { opacity: .5; cursor: default; }
/* Footer action row (Archive / Triage link). */
.uiv2-asset-drawer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 14px;
  margin-top: 6px;
  border-top: 1px solid var(--ink-100);
}

/* External-import picker grid (Phase 20.9 Q-3 modal). */
.uiv2-import-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0;
}
.uiv2-import-grid[hidden] { display: none; }
.uiv2-import-thumb {
  position: relative;
  width: 84px;
  height: 84px;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  padding: 2px;
  cursor: pointer;
  background: var(--ink-050);
}
.uiv2-import-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
}
.uiv2-import-thumb:hover:not(.is-disabled) { border-color: var(--green-600); }
.uiv2-import-thumb.is-selected { border-color: var(--green-600); background: var(--green-050); }
.uiv2-import-thumb.is-disabled { opacity: .4; cursor: not-allowed; }
.uiv2-import-thumb__mark {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--green-600);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.uiv2-import-thumb:not(.is-selected) .uiv2-import-thumb__mark { display: none; }


/* ────────── Items Sections (Phase 20.2, surface 4 of 6) ──────────
 * Shell-generic primitives per Items Sections Page MIC § 5.5 + Q-11
 * — Phase 20.6 Models Sections reuses the same shell. No items-
 * specific class names; tab content is what varies between domains. */

/* Main pane wrapper inside body_content. No grid container here —
 * the rail lives in the canonical {% block right_panel %} slot at
 * the layout level (sibling of <main>) per the Orders Workboard
 * pattern. The shared boot script + click handler in app_base_v2.html
 * own the rail collapse machinery; no Sections-specific scripts. */
.uiv2-sections-main {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

/* Sections rail modifier — widens the rail to fit ~85 chars of
 * product title on the bottom row of each double-height list row,
 * and pins filter form + list head at the top of the rail with the
 * batch toolbar at the bottom; only the item list scrolls.
 *
 * Width math: 36px checkbox column + ~14px content padding-right +
 * 85 chars × ~6.5px (Inter Tight 13px mixed-case avg) ≈ 600px
 * minimum. 620px gives breathing room. Operator-locked 2026-05-19.
 *
 * Canonical .uiv2-rail__content has overflow-y: auto (Workboard
 * pattern — whole rail scrolls as one unit). Sections needs filter
 * controls + column-label row pinned so operator sees what's
 * applied while scrolling the list. Achieved by overriding the
 * content container to a non-scrolling flex column; the item list
 * inside is the only scroll context. Drop padding too so the inner
 * blocks span the full rail width. */
.uiv2-rail--sections {
  width: 400px;
  flex: 0 0 400px;
}
@media (max-width: 1279px) {
  .uiv2-rail--sections {
    width: 360px;
    flex: 0 0 360px;
  }
}
.uiv2-rail--sections .uiv2-rail__content {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* Collapsed state: canonical rail shrinks to 64px width and hides
 * Workboard-specific internals (__header, __label, __pill, etc. per
 * ui_v2.css:2640). Sections content (filter form + list + toolbar)
 * isn't on that hide list — the 64px sliver would squeeze the full
 * filter form, overflowing + occluding. Reviewer-caught 2026-05-19.
 * Sections-scoped fix: hide the entire content block when collapsed.
 * The chevron toggle stays visible (lives outside __content) so the
 * operator can expand back. */
body.uiv2-rail-state-collapsed .uiv2-rail--sections .uiv2-rail__content {
  display: none;
}

/* Filter form — Operator-locked 2026-05-19. No "Filter Items"
 * header (saves vertical space); 4 fields stacked one per row, each
 * field is a flex row with a fixed-width label on the left + flex:1
 * input on the right (labels align vertically into a clean column
 * edge). */
.uiv2-sections-filters {
  padding: 0.875rem 0.875rem 0.5rem;
}
.uiv2-sections-filters__rows {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.uiv2-sections-filters__field {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}
.uiv2-sections-filters__field label {
  flex: 0 0 80px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-700);
}
.uiv2-sections-filters__field .uiv2-input,
.uiv2-sections-filters__field .uiv2-select {
  flex: 1;
  min-width: 0;
}

/* Actions row — Filter / Clear on the left, Hide-OOS pushed to the
 * right via margin-left: auto on the Hide-OOS form. Lives outside
 * the filter <form> so the Hide-OOS form (separate GET that flips
 * just hide_out_of_stock) can be a sibling at the same visual level.
 * Border-bottom seals the filter section away from the list head. */
.uiv2-sections-filters__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.875rem 0.875rem;
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-sections-filters__hide-oos {
  margin: 0 0 0 auto;
}
.uiv2-sections-filters__toggle {
  font-size: 0.75rem;
  padding: 0.3125rem 0.75rem;
  border: 1px solid var(--ink-200);
  background: #fff;
  color: var(--ink-700);
  border-radius: 999px;
  cursor: pointer;
}
.uiv2-sections-filters__toggle--on {
  background: var(--amber, #f5b800);
  border-color: var(--amber, #f5b800);
  color: var(--amber-ink, #5a4400);
}

/* Item list head — Select-all + N items row. Pinned by the flex
 * column on the parent rail; no position: sticky needed because the
 * outer .uiv2-rail__content no longer scrolls. */
.uiv2-sections-list__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.875rem;
  background: #fff;
  border-bottom: 1px solid var(--ink-100);
  flex-shrink: 0;
}
.uiv2-sections-list__head-select {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--ink-700);
  cursor: pointer;
}
.uiv2-sections-list__head-count {
  font-size: 0.75rem;
}
.uiv2-sections-list {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
/* Double-height row per Operator design 2026-05-19 (revised
 * later same day):
 *   top row:    [chk] SKU                            QTY
 *   bottom row: Title text (flush with chk left edge)
 *
 * Checkbox is inline on the top row (was in a 36px left column).
 * The bottom anchor's left padding matches the top row's left
 * padding so title's left edge sits flush with the checkbox's
 * left edge — visually the top + bottom rows align on the left
 * margin. Two anchors (one per row) instead of nesting the
 * checkbox inside the anchor (browsers may navigate when an
 * embedded form control fires). */
.uiv2-sections-list__row {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--ink-100);
  transition: background-color 80ms ease;
}
.uiv2-sections-list__row:hover {
  background: var(--ink-050, #f7f7f9);
}
.uiv2-sections-list__row--selected {
  background: oklch(96% 0.04 170);
}
.uiv2-sections-list__row-top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.875rem 0;
  min-width: 0;
}
.uiv2-sections-list__checkbox-cell {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  cursor: pointer;
}
.uiv2-sections-list__checkbox-cell input[type="checkbox"] {
  margin: 0;
}
.uiv2-sections-list__row-link-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.uiv2-sections-list__row-link-bottom {
  display: block;
  padding: 0.1875rem 0.875rem 0.5rem;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}
.uiv2-sections-list__sku {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--green-700, #297a45);
  flex: 0 0 auto;
}
.uiv2-sections-list__title {
  display: block;
  font-size: 0.8125rem;
  color: var(--ink-700);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Amber QTY chip — Operator directive 2026-05-19. Was a gray pill;
 * now uses the amber state-chip color palette + bold + 16px so the
 * stock count pops at-a-glance during triage scanning. Color is the
 * canonical --amber background + --amber-ink text (matches
 * .uiv2-pill--amber + .uiv2-state-chip--amber siblings). */
/* QTY chip pinned to the row's right edge — `margin-left: auto`
 * pushes it explicitly even if other elements get added to row-top
 * later (more robust than depending solely on
 * justify-content: space-between on the parent). The chip's right
 * edge aligns with the right edge of the row-link container, which
 * is the same right edge the title (in row-bottom) uses — so QTY
 * and the title's end are visually stacked. */
.uiv2-sections-list__qty {
  font-size: 1rem;
  font-weight: 700;
  color: var(--amber-ink, #5a4400);
  background: var(--amber, #f5b800);
  text-align: center;
  padding: 0.1875rem 0.625rem;
  border-radius: 999px;
  flex: 0 0 auto;
  line-height: 1.1;
  margin-left: auto;
  min-width: 2.5rem;
}

/* Two-column stacked row variant — Items Sections (Operator design
 * 2026-06-09). The base rules above keep the single-column layout
 * (top row "[chk] SKU … QTY" + bottom-row title) still used by the
 * shared Models Sections surface. The `--stacked` modifier on the
 * Items list container restructures each row into a 2-column grid: a
 * left identity column ([chk] SKU stacked over the amber QTY chip) and
 * a right title column that wraps to up to 2 lines with NO truncation,
 * reclaiming the horizontal void the old layout left between SKU and a
 * right-pinned QTY. Scoped to Items so the merged Models Sections
 * surface is unaffected. */
.uiv2-sections-list--stacked .uiv2-sections-list__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  column-gap: 0.625rem;
  padding: 0.5rem 0.875rem;
}
.uiv2-sections-list--stacked .uiv2-sections-list__row-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  min-width: 0;
}
.uiv2-sections-list--stacked .uiv2-sections-list__row-top {
  padding: 0;
}
.uiv2-sections-list--stacked .uiv2-sections-list__row-link-top {
  flex: 0 0 auto;
  justify-content: flex-start;
}
.uiv2-sections-list--stacked .uiv2-sections-list__qty {
  margin-left: 0;
  align-self: flex-start;
}
.uiv2-sections-list--stacked .uiv2-sections-list__row-link-bottom {
  padding: 0.0625rem 0 0;
  align-self: start;
}
.uiv2-sections-list--stacked .uiv2-sections-list__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  overflow: hidden;
  line-height: 1.3;
}

/* Bulk toolbar — pinned to the bottom of the rail by virtue of being
 * the last flex item in the .uiv2-rail--sections .uiv2-rail__content
 * flex column. No sticky needed because the outer container no longer
 * scrolls (only the item list above does). */
.uiv2-bulk-toolbar--sections {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.625rem 0.875rem;
  background: var(--ink-050, #f7f7f9);
  border-top: 1px solid var(--ink-200);
  gap: 0.5rem;
  flex-shrink: 0;
}
.uiv2-bulk-toolbar--sections .uiv2-bulk-toolbar__count {
  font-size: 0.8125rem;
  color: var(--ink-900);
  font-weight: 600;
}
.uiv2-bulk-toolbar--sections .uiv2-bulk-toolbar__actions {
  display: flex;
  gap: 0.375rem;
}

/* Center pane — selected-item compact header. */
.uiv2-sections-header {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--ink-100);
}
.uiv2-sections-header__sku {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--green-700, #297a45);
  letter-spacing: -0.01em;
}
.uiv2-sections-header__title {
  font-size: 0.9375rem;
  color: var(--ink-900);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.uiv2-sections-header__chips {
  display: inline-flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}
.uiv2-sections-header__manage {
  font-size: 0.8125rem;
  white-space: nowrap;
  flex: 0 0 auto;
}

/* Photo carousel — center pane top region. */
.uiv2-sections-carousel {
  position: relative;
  background: var(--ink-050, #f7f7f9);
  border: 1px solid var(--ink-100);
  border-radius: 8px;
  padding: 0.375rem;
  min-height: 360px;
}
.uiv2-sections-carousel__viewport {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 380px;
}
.uiv2-sections-carousel__image {
  display: none;
  max-width: 100%;
  max-height: 460px;
  object-fit: contain;
  cursor: zoom-in;
  border-radius: 4px;
}
.uiv2-sections-carousel__image--active {
  display: block;
}
.uiv2-sections-carousel__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid var(--ink-200);
  color: var(--ink-700);
  border-radius: 999px;
  width: 32px;
  height: 32px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  z-index: 1;
}
.uiv2-sections-carousel__nav--prev { left: 8px; }
.uiv2-sections-carousel__nav--next { right: 8px; }

/* 6-tab bar with count badges. */
.uiv2-sections-tabs {
  background: #fff;
  border: 1px solid var(--ink-100);
  border-radius: 8px;
  overflow: hidden;
}
.uiv2-sections-tabs__bar {
  display: flex;
  border-bottom: 1px solid var(--ink-100);
  overflow-x: auto;
}
.uiv2-sections-tabs__tab {
  flex: 0 0 auto;
  padding: 0.625rem 1rem;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-500);
  cursor: pointer;
  white-space: nowrap;
}
.uiv2-sections-tabs__tab:hover {
  color: var(--ink-900);
  background: var(--ink-050, #f7f7f9);
}
.uiv2-sections-tabs__tab--active {
  color: var(--ink-900);
  border-bottom-color: var(--green-700, #297a45);
  background: #fff;
}
.uiv2-sections-tabs__count {
  display: inline-block;
  margin-left: 0.375rem;
  padding: 0.0625rem 0.4375rem;
  font-size: 0.6875rem;
  background: var(--ink-100);
  color: var(--ink-700);
  border-radius: 999px;
  font-weight: 600;
}
/* Per-function tab-count colors — give each section a consistent
   visual cue so operators recognize the data type across screens
   (Operator 2026-05-20). Inventory=amber (matches the QTY chip + the
   Inventory nav), Models=sky, Reservations=plum, Listings=green. The
   badge keeps its function color whether or not its tab is active, so
   the cue is always present. Tones mirror the .uiv2-state-chip palette. */
.uiv2-sections-tabs__count--amber { background: oklch(96% 0.06 75); color: var(--amber-ink); }
.uiv2-sections-tabs__count--sky   { background: oklch(96% 0.05 240); color: oklch(35% 0.10 240); }
.uiv2-sections-tabs__count--plum  { background: oklch(96% 0.05 305); color: var(--plum); }
.uiv2-sections-tabs__count--green { background: var(--green-050, #e8f5ed); color: var(--green-900, #1a4f2c); }
.uiv2-sections-tabs__panel {
  padding: 1rem;
  min-height: 200px;
}

/* Details tab content — read-only dl two-column grid. */
.uiv2-sections-details {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem 1.25rem;
  margin: 0;
}
.uiv2-sections-details__row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 0.75rem;
  padding: 0.375rem 0;
  border-bottom: 1px solid var(--ink-050, #f0f0f3);
  align-items: baseline;
}
.uiv2-sections-details__row--wide {
  grid-column: 1 / -1;
}
.uiv2-sections-details__row dt {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-500);
  text-transform: uppercase;
  letter-spacing: 0.025em;
}
.uiv2-sections-details__row dd {
  margin: 0;
  font-size: 0.875rem;
  color: var(--ink-900);
  word-break: break-word;
}

/* Review edit block — Module MIC Q-9 explicit-Save contract. Renders
 * below the Details dl when edit_mode is active. Mirrors the Surface
 * 3 review card pattern (flag checkbox + note textarea + Save Review
 * button + status span) inside the Sections Details-tab panel. */
.uiv2-sections-review-edit {
  margin-top: 1.25rem;
  padding: 0.875rem;
  background: var(--ink-050, #f7f7f9);
  border: 1px solid var(--ink-100);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.uiv2-sections-review-edit__title {
  margin: 0 0 0.25rem 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-sections-review-edit__flag {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--ink-700);
}

/* Responsive — three breakpoints per MIC § 5.4. The canonical
 * .uiv2-rail (in app_base_v2.html) handles its own width transitions
 * and viewport-state collapse; Sections only needs to adjust the
 * inner Details dl on narrow viewports. */
@media (max-width: 899px) {
  .uiv2-sections-details { grid-template-columns: 1fr; }
  .uiv2-sections-details__row { grid-template-columns: 120px 1fr; }
}
@media (max-width: 599px) {
  .uiv2-sections-tabs__bar {
    /* Horizontal scroll on small viewports — collapse to dropdown
       is deferred to D4 (requires JS). */
    -webkit-overflow-scrolling: touch;
  }
}

/* ── D4 (item_sections.js) rendered content ──────────────────────────
 * Lightweight list/grid primitives for the JS-rendered lazy tabs
 * (Inventory / Reservations / Listings) + the Models tab + Sales tab.
 * Deliberately NOT the heavyweight .uiv2-table per-surface grid system —
 * these panels show a handful of fields per row, so a simple two-column
 * flex row reads cleaner and needs no per-surface column template. */
.uiv2-sections-list__row--checked {
  background: var(--green-050, #e8f5ed);
}

.uiv2-sections-invtotal {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0 0.625rem 0;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--ink-100);
  font-weight: 600;
  color: var(--ink-900);
}
.uiv2-sections-invtotal__num {
  font-variant-numeric: tabular-nums;
  background: var(--ink-100);
  color: var(--ink-700);
  border-radius: 999px;
  padding: 0.125rem 0.625rem;
  font-size: 0.8125rem;
}

.uiv2-sections-adjust {
  margin-top: 0.875rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--ink-100);
}
.uiv2-sections-adjust__label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  color: var(--ink-500);
  margin-bottom: 0.375rem;
}
.uiv2-sections-adjust__row {
  display: flex;
  gap: 0.375rem;
  margin-bottom: 0.375rem;
}
.uiv2-sections-adjust__row > .uiv2-input:not(.uiv2-sections-adjust__qty),
.uiv2-sections-adjust__row > .uiv2-select {
  flex: 1;
}
.uiv2-sections-adjust__qty {
  width: 80px;
  flex: 0 0 80px;
}

.uiv2-sections-tablist {
  list-style: none;
  margin: 0;
  padding: 0;
}
.uiv2-sections-tablist__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--ink-050, #f0f0f3);
  font-size: 0.875rem;
}
.uiv2-sections-tablist__row:last-child { border-bottom: none; }
.uiv2-sections-tablist__num {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink-900);
  white-space: nowrap;
}

.uiv2-sections-models {
  list-style: none;
  margin: 0 0 0.875rem 0;
  padding: 0;
}
.uiv2-sections-models__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--ink-050, #f0f0f3);
  font-size: 0.875rem;
}
.uiv2-sections-models__row:last-child { border-bottom: none; }
.uiv2-sections-models__attach {
  margin-top: 0.5rem;
}
.uiv2-sections-models__recent {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.5rem;
}

.uiv2-sections-sales {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.625rem;
  margin: 0;
}
.uiv2-sections-sales__cell {
  padding: 0.625rem 0.75rem;
  background: var(--ink-050, #f7f7f9);
  border: 1px solid var(--ink-100);
  border-radius: 6px;
}
.uiv2-sections-sales__cell dt {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  color: var(--ink-500);
}
.uiv2-sections-sales__cell dd {
  margin: 0.25rem 0 0 0;
  font-size: 0.9375rem;
  color: var(--ink-900);
}
