/*
  ALPHA-06 bartender ticket UI component styles.

  Built entirely on design/tokens.css and the active design/themes/*.css
  file (see index.html's <link> order and design/README.md's "How
  engineers consume this in ALPHA-06"). Every color, spacing, radius,
  shadow, and touch-target value below is a var(--token-name); nothing
  here is a literal hex, pixel, or millisecond copied out of a mockup, per
  design/README.md's instruction. Class names follow
  design/mockups/ring.html and design/mockups/liquor-sheet.html where a
  screen has an authoritative mockup, so this file reads as an
  implementation of those mockups rather than a new layout language.

  Touch-first per design/principles.md: nothing tappable is smaller than
  --touch-target-min (44px); Prepared and Pay use the larger tiers. No
  hover-only affordance carries meaning; :hover rules below are a bonus
  for a mouse-driven review pass, never required to operate the screen.
*/

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
  -webkit-font-smoothing: antialiased;
}

/* UX82 (docs/build-briefs/UX82-ss-theme-fonts.md): typeface ROLES a theme
   may swap (design/tokens.css: --font-family-display, --font-family-accent,
   --font-style-accent). Family and italic style only; no size, weight,
   spacing or color is set here, so a theme that overrides nothing renders
   exactly as before. Display: headings, screen titles and the big totals.
   Accent: subtitles and hint lines. Everything else stays on the base
   family through body. Info callout boxes are state messages and stay on
   the base face. */
h1,
h2,
h3,
h4,
.login-title,
.pin-entry-title,
.tabs-page-title,
.section-title,
.admin-subsection-title,
.confirm-title,
.ss-title,
.stock86-title,
.totals-row-grand,
.pay-confirm-amount-value,
.price-preview-value,
.figure-card-value {
  font-family: var(--font-family-display);
}
.login-subtitle,
.pin-entry-subtitle,
.sheet-subtitle,
.admin-page-subtitle,
.ss-lede {
  font-family: var(--font-family-accent);
  font-style: var(--font-style-accent);
}
/* Already italic hint lines: take the accent family only. */
.admin-onhand-value--unavailable,
.purchasing-cart-proposal-unit-hint {
  font-family: var(--font-family-accent);
}

/* UX90 (docs/build-briefs/UX90-theme-contrast-and-brand-separation.md): the
   Scissors & Scotch theme reads as the shop's brand. Fonts and colors only:
   no size, spacing or layout property is set here, every selector is scoped to
   [data-theme="brass"], and no other theme changes.
   1. Headlines in Proxima Nova ExtraBold (800, UX82-F2), the shop's heaviest
      licensed face.
   2. Bitter Italic on section descriptions and hints (.admin-field-help),
      except the modifier variants that carry a status message, which stay on
      the base face like every other state message (UX82).
   3. The top bar is Whiskey Brown with cream text and a thin S&S Red rule
      drawn as an inset shadow (no border, so nothing moves). Controls inside
      the location keep their own light fills. Red is an accent rule, never a field. */
[data-theme="brass"]
  :is(
    h1,
    h2,
    h3,
    h4,
    .login-title,
    .pin-entry-title,
    .tabs-page-title,
    .section-title,
    .profile-section-title,
    .admin-subsection-title,
    .confirm-title,
    .ss-title,
    .stock86-title
  ) {
  font-weight: 800;
}
[data-theme="brass"] .admin-field-help:not([class*="--"]) {
  font-family: var(--font-family-accent);
  font-style: var(--font-style-accent);
}
[data-theme="brass"] .topbar {
  background: var(--color-brand-brown);
  border-bottom-color: var(--color-brand-brown);
  box-shadow: inset 0 -3px 0 var(--color-brand-red);
  color: var(--color-brand-cream);
}
[data-theme="brass"] .topbar .topbar-left .location {
  color: var(--color-brand-cream);
}
[data-theme="brass"]
  .topbar
  :is(
    .location,
    .topbar-connectivity,
    .topbar-pricing-model,
    .topbar-terminal-ok,
    .theme-switcher-label
  ) {
  color: var(--color-brand-cream-muted);
}

/* UX83 (docs/build-briefs/UX83-snipsip-themes.md): money figures and counts
   under the two SnipSip themes use the numeric role with tabular, lining
   figures so columns of prices align. Instrument Sans (the body face) carries
   tnum; IBM Plex Mono is deliberately NOT used because it is too wide at the
   floor tablet size. Family and font-variant only: no size, weight, spacing
   or color is set here, and the selector is scoped to the two new themes so
   every other theme is unchanged. */
[data-theme="snipsip-ink"]
  :is(
    .tile-price,
    .line-price,
    .line-price-was,
    .line-special-amount,
    .liquor-price,
    .liquor-price-final,
    .liquor-price-diff,
    .modifier-chip-price,
    .totals-row,
    .totals-row-grand > span:last-child,
    .totals-compact,
    .pay-confirm-amount-value,
    .pay-confirm-totals,
    .price-preview-value,
    .figure-value,
    .figure-card-value,
    .discount-line-amount,
    .manager-exception-amount,
    .refund-total-row,
    .tab-figures,
    .review-figure-value,
    .review-total-value,
    .unresolved-amount-value,
    .lpc-count,
    .cpc-history-count,
    .ph-sum,
    .ph-tl,
    .line-edit-price-history small
  ),
[data-theme="snipsip-site"]
  :is(
    .tile-price,
    .line-price,
    .line-price-was,
    .line-special-amount,
    .liquor-price,
    .liquor-price-final,
    .liquor-price-diff,
    .modifier-chip-price,
    .totals-row,
    .totals-row-grand > span:last-child,
    .totals-compact,
    .pay-confirm-amount-value,
    .pay-confirm-totals,
    .price-preview-value,
    .figure-value,
    .figure-card-value,
    .discount-line-amount,
    .manager-exception-amount,
    .refund-total-row,
    .tab-figures,
    .review-figure-value,
    .review-total-value,
    .unresolved-amount-value,
    .lpc-count,
    .cpc-history-count,
    .ph-sum,
    .ph-tl,
    .line-edit-price-history small
  ) {
  font-family: var(--font-family-numeric);
  font-variant-numeric: tabular-nums lining-nums;
}

button,
input,
select {
  font-family: inherit;
  font-size: inherit;
  /* Contrast defect fix, owner review 2026-08-22 (Amendment 2026-08-22,
     item 1): form controls do not inherit `color` from their ancestors
     by default in the UA stylesheet the way a <div> or <span> does; a
     <button> in particular renders with the platform's `buttontext`
     system color unless told otherwise. .tile already carried its own
     `color: inherit;` (ALPHA-06) for exactly this reason, but that fix
     was never generalized, so every OTHER button built afterward
     (.tab-card in ALPHA-07, .liquor-row in ALPHA-06/10, admin rows, and
     every <input>/<select>) silently fell back to that near-black
     system default. On every light theme this happened to look correct
     by accident (near-black text on a light surface reads fine), which
     is exactly why the theme verification pass never caught it: nothing
     LOOKED broken until Charcoal, the one dark theme, rendered the same
     near-black default against a near-black background. Setting
     `color: inherit` here once, at the element level, makes every
     current and future form control resolve to the active theme's
     `--color-text-primary` the same way ordinary text already does,
     instead of depending on each new component remembering to repeat
     `.tile`'s fix by hand. */
  color: inherit;
}

[hidden] {
  display: none !important;
}

/* ---------- Buttons, shared ---------- */

.btn-primary,
.btn-secondary,
.btn-pay,
.btn-add {
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-semibold);
  border: 1px solid transparent;
  cursor: pointer;
}

.btn-primary {
  height: var(--touch-target-comfortable);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-base);
  box-shadow: var(--shadow-2);
  border: none;
}
/* Design principle 3, "blocked is a state you see before you touch it":
   the same visually-blocked treatment .btn-pay:disabled already
   establishes, extended to every plain .btn-primary a screen can disable
   (e.g. the Counts review's Close count button with nothing counted
   yet), so a disabled primary action never LOOKS fully live. */
.btn-primary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
}

.btn-secondary {
  height: var(--touch-target-comfortable);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  padding: 0 var(--space-4);
}

.btn-secondary:disabled {
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
}

.btn-compact {
  padding: 0 var(--space-4);
}

.btn-full {
  width: 100%;
}

.btn-icon {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-full);
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  cursor: pointer;
}
.btn-icon:hover {
  background: var(--color-surface-sunken);
}

button:disabled {
  cursor: not-allowed;
}

button:focus-visible,
input:focus-visible,
select:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* ---------- UIFIX1 (SF-7): one base style for every native control ----------
   A control with no class of its own used to fall back to the browser's white chrome while its text inherited the
   theme's light ink, so on a dark theme it showed light text on a white box (Settings Inventory items, Network and billing,
   the Schedule email dialog). Every rule here sits in :where(), so it has no specificity: any component class still wins
   on the property it sets, and a control nobody styled reads from the theme tokens. A new control can no longer ship
   unstyled. Dark themes tell the browser so, which darkens date pickers, select lists and scrollbars. */
[data-theme="snipsip-ink"],
[data-theme="charcoal"] {
  color-scheme: dark;
}
:where(button) {
  background-color: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
/* A button with no class at all is an unstyled new control: it gets a touch-sized face. */
:where(button:not([class])) {
  min-height: var(--touch-target-min);
  padding: var(--space-1) var(--space-4);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
:where(button:disabled) {
  color: var(--color-text-tertiary);
}
:where(
  input:not(
    [type="checkbox"],
    [type="radio"],
    [type="range"],
    [type="file"],
    [type="color"],
    [type="hidden"],
    [type="button"],
    [type="submit"]
  )
),
:where(select),
:where(textarea) {
  background-color: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2);
}
:where(textarea) {
  padding: var(--space-2) var(--space-3);
}
:where(input::placeholder, textarea::placeholder) {
  color: var(--color-text-tertiary);
}
:where(input[type="checkbox"], input[type="radio"]) {
  width: 28px;
  height: 28px;
  accent-color: var(--color-accent-strong);
  cursor: pointer;
}
:where(dialog) {
  background-color: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-3);
}
:where(dialog)::backdrop {
  background: rgb(0 0 0 / 0.5);
}

/* ---------- Centered-card screens (auth track, track/auth Slice 1) ----
   Five screens share this one centered-card layout: terminal setup (the
   one-time server/tenant connection step), the user-tile picker, the PIN
   pad, the manager-approval approver picker, and the payment-terminal
   picker. index.html's own header comment has the full walk order; this
   replaced the old single #login-screen the pre-auth stub used.

   Gate finding 6, 2026-08-27: #approval-picker-screen and
   #terminal-picker-screen were both built on the same .login-card markup
   as the three original screens but were never added to this selector,
   so each rendered as a bare card jammed into the top-left of an
   otherwise empty page (measured at 1280x800: getBoundingClientRect()
   height 355 against a full-viewport page, no centering, no padding).
   Anything added here must be added to this list; e2e/
   manager-approval.spec.ts asserts the resulting geometry rather than
   only toBeVisible(), which cannot see the difference. */

#terminal-setup-screen,
#user-picker-screen,
#pin-entry-screen,
#approval-picker-screen,
#terminal-picker-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}
/* UX100: the sign-in and reader picker cards start below the toast slot, so "PIN changed." or an
   error lies over the page, not the card's logo or first control. (The approval picker keeps its own spacing.) */
#user-picker-screen,
#terminal-picker-screen {
  padding-top: calc(var(--toast-slot-band) + var(--space-2));
}

.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-8);
}

.login-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-1);
}

.login-subtitle {
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-6);
}

.field-label {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  margin: var(--space-4) 0 var(--space-1);
}

.field-input {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  padding: 0 var(--space-4);
  color: var(--color-text-primary);
}

.login-submit {
  width: 100%;
  margin-top: var(--space-6);
}

.login-note {
  margin-top: var(--space-5);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  line-height: var(--line-height-relaxed);
}

/* ---------- User-tile picker ----------
   One large touch tile per active employee (CLAUDE.md touch-only rule:
   this is the only "typing" a shared terminal ever needs, and it is
   none). Widens .login-card slightly over the plain 420px login-card
   default so 2-3 tiles per row is comfortable on a landscape tablet. */
.user-picker-card {
  max-width: 640px;
}
/* UX117: on the sign-in card the one vertical gap (logo, location name, tile grid, divider, device name) is
   also the gap between tile rows and columns. The reader and approver cards keep their own spacing. */
#user-picker-screen .user-picker-card {
  --user-picker-gap: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--user-picker-gap);
}
#user-picker-screen .user-picker-card > .login-title {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--user-picker-gap);
  margin: 0;
}
#user-picker-screen .brand-logo-card,
#user-picker-screen .brand-location {
  margin: 0;
}
#user-picker-screen .user-picker-card > .login-note {
  margin: 0;
}
#user-picker-screen .user-tile-list {
  margin: 0;
}
.user-tile-list {
  /* UX117: equal columns and equal rows, so every tile has one width and one height (three across, two on a
     phone). A lone last tile, or the last two, sit centered under the full rows. */
  --user-tile-cols: 3;
  display: grid;
  grid-template-columns: repeat(calc(var(--user-tile-cols) * 2), minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--user-picker-gap, var(--space-3));
  margin: var(--space-2) 0 var(--space-5);
}
@media (max-width: 520px) {
  .user-tile-list {
    --user-tile-cols: 2;
  }
}
/* UX100: an empty list (the reader picker with no readers) takes no height, so no dead gap sits above the line
   that follows it. */
.user-tile-list:empty {
  display: none;
}
.user-tile-list > .user-tile {
  grid-column: span 2;
}
@media (min-width: 521px) {
  .user-tile-list > .user-tile:last-child:nth-child(3n + 1) {
    grid-column: 3 / span 2;
  }
  .user-tile-list > .user-tile:nth-last-child(2):nth-child(3n + 1) {
    grid-column: 2 / span 2;
  }
  .user-tile-list > .user-tile:last-child:nth-child(3n + 2) {
    grid-column: 4 / span 2;
  }
}
@media (max-width: 520px) {
  .user-tile-list > .user-tile:last-child:nth-child(2n + 1) {
    grid-column: 2 / span 2;
  }
}
.user-tile-list > .tabs-loading {
  grid-column: 1 / -1;
  padding: var(--space-4) 0;
}
#terminal-picker-empty {
  padding: var(--space-2) var(--space-5) var(--space-4);
}
.user-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-target-primary);
  padding: var(--space-5) var(--space-3);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  cursor: pointer;
  text-align: center;
}
.user-tile:hover {
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
}
.user-tile:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.user-tile-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.user-tile-role-badge {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.user-picker-change-terminal {
  margin-top: var(--space-5);
  width: 100%;
}

/* ---------- PIN pad ----------
   One reusable pad (main.ts's openPinEntry) driving both login and the
   three-step change-PIN flow. Every digit is --touch-target-primary
   (64px), the largest of the three touch-target tiers: this is the
   highest-frequency touch target in the whole app, entered many times a
   shift on a shared terminal with no keyboard fallback (CLAUDE.md
   touch-only rule). 3 columns, matching the DOM order already in
   index.html (1-2-3 / 4-5-6 / 7-8-9 / clear-0-backspace). */
.pin-pad-card {
  width: 100%;
  max-width: 420px;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-8);
  text-align: center;
}
.pin-entry-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-1);
}
.pin-entry-subtitle {
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-5);
}
/* Dots, never digits (this is a shared terminal); large and legible from
   arm's length, per the work item's own "not a phone" instruction. */
.pin-entry-display {
  min-height: var(--touch-target-comfortable);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-2xl);
  letter-spacing: var(--space-3);
  color: var(--color-text-primary);
  margin-bottom: var(--space-4);
}
.pin-entry-error {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  margin: 0 0 var(--space-4);
  text-align: left;
}
.pin-pad-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--touch-target-gap-min);
  margin-bottom: var(--space-5);
}
.pin-pad-digit {
  min-height: var(--touch-target-primary);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.pin-pad-digit:hover:not(:disabled),
.pin-pad-digit:active:not(:disabled) {
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  /* Owner finding 2026-08-23: the light accent-subtle fill kept the
     digit's normal text color, which on Charcoal is light-on-light and
     unreadable mid-tap. Pair with accent-strong, the trio every theme
     already contrast-verifies (see .tile-kind-badge). */
  color: var(--color-accent-strong);
}
.pin-pad-digit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.pin-pad-clear,
.pin-pad-backspace {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.pin-pad-actions {
  display: flex;
  gap: var(--space-3);
}
.pin-pad-actions .btn-secondary,
.pin-pad-actions .btn-primary {
  flex: 1;
}

/* ---------- My Profile ---------- */
.profile-section {
  margin: 0 0 var(--space-6);
}
.profile-section-title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-1);
}
/* USR4 (docs/build-briefs/USR4-my-profile-details.md): the "Your
   details" section's two-up field pairing (First/Last, Email/Phone),
   the same house pattern the Add User admin popup already uses. */
.admin-field-row {
  display: flex;
  gap: var(--space-4);
}
.admin-field-row > div {
  flex: 1;
  min-width: 0;
}
.field-label-tight {
  margin-top: var(--space-2);
}
/* Reserved height so an error appearing or clearing never shifts Save
   up or down -- the brief's own "inline errors with reserved height." */
.field-error {
  min-height: 1.2em;
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-strong);
}
.field-input.field-input-invalid {
  border-color: var(--color-danger-strong);
  background: var(--color-surface);
}
.profile-save-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-2);
}
.profile-save-row .btn-primary {
  min-width: 160px;
}

/* ---------- Shared centered confirm dialog ----------
   Distinct from the bottom-sheet .scrim/.sheet family above: a small,
   centered dialog for a single short message plus 1-2 actions (the
   one-time temporary-PIN reveal, index.html's #pin-reveal-scrim; any
   future caller with the same "one message, no form" shape). Built on
   the same tokens as .admin-confirm-sheet/.admin-confirm-body/
   .admin-confirm-actions one screen over, just centered instead of
   docked to the bottom edge. */
.confirm-scrim {
  position: fixed;
  inset: 0;
  background: var(--color-scrim);
  z-index: var(--z-scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}
.confirm-dialog {
  width: 100%;
  max-width: 420px;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-6);
}
.confirm-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-3);
}
.confirm-message {
  margin: 0 0 var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
}
.confirm-actions {
  display: flex;
  gap: var(--space-3);
}
.confirm-actions .btn-primary,
.confirm-actions .btn-secondary {
  flex: 1;
}
.pin-reveal-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--space-2);
  text-align: center;
  color: var(--color-text-primary);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: 0 0 var(--space-5);
}

/* ---------- Open Tabs (ALPHA-07 landing screen) ----------
   .topbar and its children are shared with the ring screen below (see
   "App shell / top bar"); this section only adds what is unique to Open
   Tabs. Modeled on design/mockups/tabs.html: single flowing column,
   max-width container, no fixed-height app shell, so it uses ordinary
   page scroll at every supported width (1280x800, 1024x768, and phone)
   with no bespoke breakpoint of its own. */

#open-tabs-screen {
  min-height: 100vh;
  background: var(--color-bg);
}

/* Live-verification finding, ALPHA-08, at 1024x768, ORIGINALLY: Open
   Tabs' own then-per-screen topbar-right grew from one theme control at
   ALPHA-07 to six items (theme label, selector, employee badge, Closeout
   Summary, Manager Settings, Log out) as ALPHA-08 and ALPHA-10 each added
   a button here without re-checking this screen's own fit at the
   narrower supported tablet width, leaving topbar-left (flex-shrink: 1,
   no floor) crushed to near zero width so the brand name and location
   visually overlapped the theme selector instead of being pushed aside
   or wrapped.

   UX17/UX18 (docs/build-briefs/UX17-persistent-navigation.md,
   UX18-manager-surfaces-to-admin.md) collapsed nine per-screen topbars
   into the ONE shared #app-topbar and moved Closeout Summary/Manager
   Exceptions off it entirely, so topbar-right carried at most two
   direct children (the one screen-specific secondary-action button,
   #topbar-secondary-action, plus the account-menu trigger) on EVERY
   screen, never six, until UX29 (docs/build-briefs/UX29-terminal-and-
   connectivity-status-on-the-ring-screen.md) added a third,
   non-interactive, always-present badge (#topbar-connectivity-badge) as
   the lane's first child; three is still far short of six, and the badge
   is short, fixed-width text, never a wrapping label. That real narrowing is what makes generalizing this
   guard from "Open Tabs only" to every screen the shared location now serves
   safe rather than reckless: the ORIGINAL reason ring was excluded (its
   own fixed-height ticket rail had no spare row to give up if the topbar
   wrapped, see .app's own comment above) no longer competes with a row
   this location is now unlikely to ever need. Kept as a width-keyed
   breakpoint rather than an unconditional wrap for the same
   content-driven reasoning as before: flex-wrap's own one-line-fits test
   measures the FULL, un-truncated content, so an unconditional wrap
   would still wrap at 1280x800 where nowrap-plus-shrink already fits.
   1150px sits comfortably between the two supported tablet widths. */
@media (max-width: 1150px) {
  #app-topbar,
  #app-topbar .topbar-right {
    flex-wrap: wrap;
    row-gap: var(--space-2);
  }
}

.tabs-page {
  max-width: 880px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-20);
}
/* INV26 S1 list-fit fix (design/mockups/inv26-list-fit.html; live stage0
   defect, ADMIN_WORKSTATION 1280x800, 2026-09-28). Scoped to the Settings
   screen alone by id, so #open-tabs-screen's own .tabs-page (and every
   other screen sharing the class: My Profile, Closeout Summary, Void
   History) is untouched at 880px; only Settings, whose five-column
   inv-table needs the room, gets the wider column. At the 1280px floor
   viewport this still leaves ~40px of side margin, never edge-to-edge. */
#admin-screen .tabs-page {
  /* UX79: no cap; Settings uses the width the screen has (owner, 2026-10-05).
     Forms and text blocks are held to a readable line length at the end of
     this file. */
  max-width: none;
}

.tabs-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.tabs-page-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  margin: 0;
}

.new-ticket-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.new-ticket-name-input {
  flex: 1;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  font-size: var(--font-size-md);
}
/* TABSLAYOUT1: one control height (56) for every field and button in the page body. */
.btn-new-ticket {
  height: var(--touch-target-comfortable);
  min-width: 184px;
  padding: 0 var(--space-8);
  border-radius: var(--radius-md);
  border: none;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-2);
  flex-shrink: 0;
  cursor: pointer;
}

.tab-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.tabs-empty {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--color-text-secondary);
}
.tabs-loading {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--color-text-tertiary);
}

.tab-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
  min-height: var(--touch-target-primary);
  text-align: left;
  cursor: pointer;
}
.tab-card:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.tab-main {
  flex: 1;
  min-width: 0;
}
.tab-name-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.tab-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
/* TABSLAYOUT1 (lead decision): every Open Tabs card is the same height, so a long name is cut to one line. The
   full name is on the title and in the text the screen reader reads. */
#open-tabs-list .tab-name {
  display: block;
  font-weight: var(--font-weight-bold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* TABSLAYOUT1: one row of badges under the server line, all one size. */
.tab-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  margin-top: var(--space-2);
}
.tab-badges [hidden] {
  display: none;
}
.badge-age,
.badge-aging,
.badge-paid,
.badge-awaiting {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  height: 26px;
  padding: 0 var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
/* Under 1 hr: neutral. */
.badge-age {
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
}
/* 1 hr and up: warning. */
.badge-aging {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
/* 24 hr and up: danger (lead decision, provisional). */
.badge-aging.badge-stale {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
}
/* Sixteenth amendment item 2: a Paid badge on a fully-paid open tab, the existing green success tokens. */
.badge-paid {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
/* RCPT1-S3: an Open Tabs card waiting for the tip written on its receipt, in the warning pair. */
.badge-awaiting {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
.tab-meta {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
/* TABSLAYOUT1: the server line holds its space when empty, so cards stay the same height. */
.tab-server {
  min-height: 1.4em;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tab-figures {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-shrink: 0;
}
.figure {
  text-align: right;
}
.figure-value {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-primary);
}
.figure-label {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.chevron {
  flex-shrink: 0;
  width: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-lg);
}

.recently-closed-section {
  margin-top: var(--space-8);
}
.recently-closed-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-1);
}
.recently-closed-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: 0 0 var(--space-4);
}
.btn-reopen {
  height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
  cursor: pointer;
}

/* TM1 (docs/backlog.md; DEC-230, owner ruling "merge only"). Merge mode's
   own chrome: the banner that replaces ordinary browsing instructions
   while merge-selection is active, the marked/dimmed tab-card states, and
   the bottom action bar that appears once a source and a target are both
   picked. Same token vocabulary .badge-aging/.badge-paid already use, no
   new colors. */
.tab-merge-mode-banner {
  flex-basis: 100%;
  box-sizing: border-box;
  min-height: var(--touch-target-comfortable);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
.tab-merge-mode-cancel {
  background: none;
  border: none;
  color: var(--color-info);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  cursor: pointer;
}
.tab-card.tab-merge-dimmed {
  opacity: 0.55;
}
.tab-card.tab-merge-marked {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle);
  outline: 2px solid var(--color-accent);
}
.tab-merge-mark-badge {
  position: absolute;
  top: -10px;
  left: -10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: #fff;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  flex-shrink: 0;
}
.tab-merge-role-label {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  margin-top: var(--space-1);
}
.tab-merge-action-bar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: var(--shadow-2);
  padding: var(--space-4) var(--space-5);
  margin-top: var(--space-4);
  border-radius: var(--radius-lg);
}
.tab-merge-move-list {
  list-style: none;
  margin: var(--space-4) 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
}
.tab-merge-move-list li {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
}
.tab-merge-move-list .tab-merge-move-label {
  font-weight: var(--font-weight-semibold);
  min-width: 70px;
}
.tab-merge-move-list .tab-merge-move-detail {
  color: var(--color-text-secondary);
}
.tab-merge-hold-note {
  display: block;
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin: 0 0 var(--space-4);
}
/* TM1: the two-line "Merged from" trail on a tab that absorbed another
   one (design/mockups/po-merge-invoice-tm1-result.html), the same
   success-token pairing .badge-paid already uses. */
.tab-merge-trail {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-success-text);
}

/* TAB1 (DEC-270; design/mockups/core-tab-search-notes.md). The sticky find
   row. The real scroll root on Open Tabs is #app-shell (overflow-y: auto,
   see its own rule below); the topbar is inside it and scrolls away, so
   top: 0 pins this row to the top of the visible area. Its parent
   (.tabs-page) spans the whole list, so the row stays stuck all the way
   down. */
.tab-find {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) 0;
  margin-bottom: var(--space-2);
  background: var(--color-bg);
}
.tab-find[hidden] {
  display: none;
}
/* TAB3: the chip row wraps under the toggle and search field. */
.tab-find {
  flex-wrap: wrap;
  row-gap: var(--space-2);
}
.tab-find-chips {
  flex-basis: 100%;
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-top: var(--space-1);
}
.tab-find-chip-divider {
  flex: none;
  width: 1px;
  height: 24px;
  margin: 0 var(--space-1);
  background: var(--color-border-strong);
}
.tab-find-chip[hidden] {
  display: none;
}
.tab-find-chip {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.tab-find-chip b {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
}
/* A chip with nothing behind it is quiet but still tappable. */
.tab-find-chip.is-zero {
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
}
.tab-find-chip[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}
.tab-find-chip[aria-pressed="true"] b {
  color: var(--color-accent-strong);
}
.tab-find-toggle {
  display: flex;
  box-sizing: border-box;
  height: var(--touch-target-comfortable);
  flex-shrink: 0;
  padding: 4px;
  gap: 4px;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
}
.tab-find-toggle-button {
  height: 48px;
  min-width: 108px;
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.tab-find-toggle-button b {
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
.tab-find-toggle-button[aria-pressed="true"] {
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
}
.tab-find-toggle-button[aria-pressed="true"] b {
  color: var(--color-accent-strong);
}
.tab-find-field {
  flex: 1;
  min-width: 0;
  height: var(--touch-target-comfortable);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-left: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-tertiary);
}
.tab-find-field:focus-within {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
  color: var(--color-text-primary);
}
.tab-find-icon {
  flex-shrink: 0;
}
.tab-find-input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: none;
  background: transparent;
  outline: none;
  font-size: var(--font-size-md);
  color: var(--color-text-primary);
}
.tab-find-clear {
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-lg);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.tab-find-clear[hidden] {
  display: none;
}
.tab-card[hidden] {
  display: none;
}
/* TABSLAYOUT1: Merge tabs is an outlined 56px control at the end of the find row; pressed is the accent pair. */
.tab-merge-toggle {
  height: var(--touch-target-comfortable);
  flex-shrink: 0;
  padding: 0 var(--space-6);
  border-radius: var(--radius-md);
  font-size: var(--font-size-md);
}
.tab-merge-toggle[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}
.tab-name mark,
.tab-meta mark,
.tab-why mark {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  border-radius: 3px;
  padding: 0 1px;
  font-weight: var(--font-weight-bold);
}
.tab-why {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.tab-find-empty {
  text-align: center;
  padding: var(--space-10) var(--space-5);
}
.tab-find-empty[hidden] {
  display: none;
}
.tab-find-empty h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-lg);
}
.tab-find-empty p {
  margin: 0 0 var(--space-5);
  color: var(--color-text-secondary);
}
.tab-find-empty-actions[hidden] {
  display: none;
}
.tab-find-empty-actions {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
}
.tab-find-empty-actions button {
  height: 56px;
  padding: 0 var(--space-6);
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-bold);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  cursor: pointer;
}
.tab-find-empty-actions button.is-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}

@media (max-width: 480px) {
  .tab-card {
    flex-wrap: wrap;
  }
  .tab-figures {
    width: 100%;
    justify-content: space-between;
  }
  .new-ticket-row {
    flex-direction: column;
  }
  .btn-new-ticket {
    width: 100%;
  }
}

/* TABSLAYOUT1 (docs/build-briefs/TABSLAYOUT1-open-tickets.md; supersedes the UX14 density block): no "Open
   Tabs" heading (the section keeps aria-label="Open Tabs"); a 1280px page; 56px controls on two aligned rows;
   cards in a grid of equal 112px minimum height, 3 columns on an iPad in landscape and 2 in portrait. Scoped to
   #open-tabs-screen because .tabs-page and .tab-list are shared with other screens. */
#open-tabs-screen .tabs-page {
  max-width: 1280px;
  padding: var(--space-5) var(--space-6) var(--space-12);
}
#open-tabs-screen .tabs-page-header {
  display: none;
}
#open-tabs-screen .tab-find {
  padding: var(--space-2) 0 var(--space-3);
  margin-bottom: 0;
}
#open-tabs-screen .tab-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--space-3);
}
#open-tabs-list .tab-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 20px;
  align-items: center;
  column-gap: var(--space-3);
  min-height: 112px;
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-5);
}
#open-tabs-list .tab-card:active {
  background: var(--color-surface-sunken);
}
#open-tabs-list .tab-figures {
  gap: var(--space-3);
  justify-content: flex-end;
}
#open-tabs-list .chevron {
  justify-content: flex-end;
}
/* UX100: the empty, loading and error lines span every column, so they center under the controls instead of
   sitting in the left column. */
#open-tabs-screen .tab-list > :is(.tabs-empty, .tabs-loading) {
  grid-column: 1 / -1;
}

/* ---------- App shell / top bar ---------- */

/* UX17 (docs/build-briefs/UX17-persistent-navigation.md): the persistent
   topbar (#app-topbar) moved OUTSIDE every screen `<section>`, including
   #ring-screen's own `.app` wrapper it used to sit inside as `.app`'s
   first flex child. `.app` used to be `height: 100vh` for exactly that
   reason (see the removed comment this replaces): with the topbar gone
   from inside it, height:100vh here would double-count the topbar's own
   height against the viewport. #app-shell (new, wraps the topbar and
   every screen section as siblings, directly under <body>) is now the
   ONE viewport-height flex column; `.app` fills whatever height
   #ring-screen's own flex-item allocation leaves it (height: 100%),
   preserving exactly the same "a definite, bounded height for .body's
   flex:1 to fill" property the old height:100vh gave it, just measured
   one level up. */
#app-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
  /* Matches html/body's own height:100% above; min-height keeps the app
     usable on a viewport shorter than 720px without ever collapsing
     below it (moved here from .app's own former rule, unchanged). */
  min-height: 720px;
  overflow-y: auto;
}
/* Every screen section is a plain, naturally-sized flex item by default
   (flex-shrink: 0 so none of them is ever squeezed below its own content
   -- #app-shell's own overflow-y: auto is what turns a taller-than-
   viewport screen into a scrollable region, exactly matching the plain
   page-scroll behavior every screen already had before #app-shell
   existed). #ring-screen overrides this below: it is the one screen with
   its own bounded-height, internally-scrolling layout (.app/.body). */
#app-shell > section {
  flex: 0 0 auto;
}
#ring-screen:not([hidden]) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.app {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.topbar {
  /* UX15-F1: the header is the account dropdown's containing block, so
     the menu can sit outside .topbar-right's overflow lane below and
     still hang from the header's bottom edge. */
  position: relative;
  /* UX96 (DEC-356): three columns, the two sides equal (minmax(0, 1fr) each) and the lockup in the middle
     (auto), so the lockup is centered in the header whatever the widths of the left and right groups. Both
     sides can shrink to zero, so the columns can never overlap one another. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  /* UX14 (DEC-314): 56px (--topbar-height) instead of 71px. The 44px
     controls are untouched; only the 13px above and below shrink. The
     height is a floor (min-height), not a fixed value, so the wrapped
     portrait layout below can still grow. */
  box-sizing: border-box;
  min-height: var(--topbar-height);
  padding: 0 var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
  /* Design gate finding, ALPHA-06: at 1024x768 this used to wrap to two
     rows, eating ~40-56px the ticket rail needed. The real trigger is
     unbounded content (a long tenant id or employee id can outgrow the
     row on its own), not the viewport width, so the fix is nowrap plus
     truncating the two open-ended text fields (.location, .employee-name
     below) rather than a width-keyed breakpoint hack. Restored to wrap at
     phone/tablet-portrait width in the existing max-width:900px block
     below, where .body already stacks into a single column and a second
     topbar row is not competing with the ticket rail for height. */
  flex-wrap: nowrap;
}
.topbar-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex-shrink: 1;
  /* UX15: a defensive floor, not the load-bearing fix (that is
     .topbar-right's own shrink/scroll change above). If this side is
     ever squeezed below its own children's combined size in some future
     layout this file has not anticipated, clip the excess here rather
     than let it render outside this box and under .topbar-right's own
     controls, matching the reasoning `.topbar-right`'s own comment
     states in full. */
  overflow: hidden;
}
/* UX93: the Snip & Sip logo (design/brand/). The black parts draw in currentColor, so the logo takes
   the ink of whatever surface it sits on (dark in SnipSip Light, light in SnipSip Ink and night, cream
   on the Scissors & Scotch location); the ochre is the brand ochre in every theme. Size is set here once
   and no theme changes it. */
.brand-mark {
  display: block;
  flex: none;
  height: 28px;
  width: auto;
  aspect-ratio: 266 / 346;
}
.brand-mark-card {
  height: 44px;
  margin: 0 auto var(--space-2);
}
.brand-logo {
  display: block;
  flex: none;
  height: 36px;
  width: auto;
  aspect-ratio: 1263 / 346;
}
/* DEC-348 (UX94): the lockup as the heading of a card. Centered, wide enough to read, never cramped. */
.brand-logo-card {
  height: 48px;
  margin: 0 auto var(--space-2);
}
.so-wordmark:has(.brand-logo) {
  display: inline-flex;
  align-items: center;
}
.location {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* UX96 (DEC-356): the location name is the one name in the header, right beside the home button: it reads as
   the title it is, and truncates with an ellipsis before it can reach the lockup. */
.topbar-left .location {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}
/* UX96 (DEC-356): the centered lockup. The wordmark and the mark are two images of the same logo; main.ts's
   fitTopbarBrand sets data-brand-fit on the header: "full" (the lockup) or "mark" (the mark alone, when no
   compaction of the right group leaves room for the lockup). The logo is centered either way. */
.topbar-right {
  /* In its grid column the group hugs the right edge of the header, as it did when the header was a flex row.
     fitTopbarBrand only leaves it in this column when it fits (or the reader label can shrink to fit), so
     right-aligning cannot push content out of reach to the left. */
  justify-content: flex-end;
}
.topbar-center {
  display: flex;
  align-items: center;
  justify-content: center;
}
.topbar-logo {
  --topbar-logo-height: 32px;
  height: var(--topbar-logo-height);
}
.topbar-mark {
  display: none;
  height: 32px;
}
.topbar[data-brand-fit="mark"] .topbar-logo {
  display: none;
}
.topbar[data-brand-fit="mark"] .topbar-mark {
  display: block;
}
/* Compaction of the right group, so the centered logo has room (main.ts fitTopbarBrand sets these, one level
   at a time, in this order). The full text stays in each element, so a screen reader still reads it; only the
   drawing changes. */
#app-topbar.topbar .topbar-right {
  flex-wrap: nowrap;
}
.topbar[data-c-gap] .topbar-right {
  /* UX100: never tighter than 8px, so two pills (Online and the pricing chip) never touch in portrait. */
  gap: var(--space-2);
}
.topbar[data-c-reader] .topbar-terminal-ok,
.topbar[data-c-reader] .topbar-terminal-warning,
.topbar[data-c-pricing] .topbar-pricing-model {
  font-size: 0;
}
.topbar[data-c-reader] .topbar-terminal-ok::after,
.topbar[data-c-reader] .topbar-terminal-warning::after,
.topbar[data-c-pricing] .topbar-pricing-model::after {
  content: attr(data-short);
  font-size: var(--font-size-sm);
}
/* The reader's short chip carries its state colour: the warning button is already amber; the working reader is
   green. */
.topbar[data-c-reader] .topbar-terminal-ok {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.topbar[data-c-reader] .topbar-terminal-warning {
  padding: 0 var(--space-2);
}
.topbar[data-c-user] .employee-name {
  display: none;
}
.topbar[data-c-tight] {
  padding-left: var(--space-3);
  padding-right: var(--space-3);
  column-gap: var(--space-2);
}
/* UX100: the last level also draws the status pills flat (no rim, little padding; the 44px height stays), so
   Online, the reader and the pricing chip still read with their dots in a
   portrait header. The words stay in the page (aria-label, the element text). */
.topbar[data-c-tight] :is(.topbar-connectivity, .topbar-pricing-model, .topbar-terminal-ok) {
  padding: 0 var(--space-1);
  gap: var(--space-1);
  border-color: transparent;
}
.topbar[data-c-tight] .topbar-terminal-warning {
  padding: 0 var(--space-1);
}
.topbar[data-c-tight] .topbar-right {
  gap: var(--space-1);
}
.topbar[data-c-tight] .topbar-connectivity,
.topbar[data-c-tight] .topbar-terminal-ok::after,
.topbar[data-c-tight] .topbar-terminal-warning::after,
.topbar[data-c-tight] .topbar-pricing-model::after {
  font-size: var(--font-size-xs);
}
.topbar[data-c-tight] .account-trigger {
  padding: 0 var(--space-1);
  gap: var(--space-1);
}
/* UX30 (docs/build-briefs/UX30-pricing-model-visible-on-the-ring-screen.md):
   the ring screen's own pricing-model badge, styled at the same visual
   weight as .location above (same tokens, reused rather than a second
   visual language for one line of text) since both are inert, muted
   status text rather than a control. */
.topbar-pricing-model {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.topbar-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: nowrap;
  /* UX15 (docs/build-briefs/UX15-floor-topbar-overflow.md): this used to
     be `flex-shrink: 0`, which refuses to give up any of its own width no
     matter how many buttons it holds. With .topbar-left's own
     `flex-shrink: 1; min-width: 0` (kept, still needed so .location's
     ellipsis can absorb a long tenant id per the ALPHA-06 comment above),
     a stubborn flex-shrink:0 here forced the ENTIRE deficit onto
     .topbar-left, past the point its own content (the home icon, the
     brand name) could still fit, and that content then rendered outside
     .topbar-left's own shrunk box and under .topbar-right's buttons,
     which is exactly the click-interception defect this item fixes.
     Allowing this side to shrink too lets the flex algorithm split the
     deficit by each side's own size (mostly landing here, since this side
     is normally the larger of the two), and overflow-x below turns
     whatever still does not fit into a horizontal pan inside this row's
     own lane instead of spilling onto .topbar-left. This is what makes
     the row incapable of overlapping regardless of how many buttons a
     later change adds here: the two sides can only ever sum to the
     container's own width, never more. */
  flex-shrink: 1;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
/* UX15: every direct child (each button, and the account-menu trigger)
   keeps its own natural, single-line size no matter how small this row's
   own box gets squeezed to above. Without this, a plain flex child's
   default `flex-shrink: 1` lets its TEXT wrap to two or three lines
   before the row above finishes giving up its own width, and the wrapped
   lines then get clipped by this row's `overflow-y: hidden` (observed
   directly while building this fix: "Record Outside Order" wrapped to
   three lines and its bottom line was cut off). Reserving each child's
   own size and letting the row's `overflow-x: auto` above carry whatever
   does not fit keeps every label on one line and every button fully
   readable, at the cost of a horizontal pan for the buttons furthest
   right when many are visible at once (rare after this item's own
   consolidation of the three purchasing entry points into one). */
.topbar-right > * {
  flex-shrink: 0;
}
/* Same visible-scrollbar treatment .ticket-lines already uses (that
   rule's own comment: overflow:auto alone renders no reliably visible
   scrollbar on every platform), oriented horizontally for this row. */
.topbar-right::-webkit-scrollbar {
  height: 6px;
}
.topbar-right::-webkit-scrollbar-track {
  background: transparent;
}
.topbar-right::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
}
/* PAY5-F1 (docs/backlog.md; docs/build-briefs/PAY5-F1-terminal-notice-in-
   topbar.md; design/mockups/ux39-pay5-ticket-header.html, review Section
   4.1; DEC-196). A small, non-shrinking wrapper (.topbar-right > * already
   sets flex-shrink: 0 above) around whichever of #topbar-terminal-status
   or #topbar-terminal-warning is currently visible, so main.ts can read
   its own real bounding box and anchor .topbar-terminal-detail's right
   edge to it. */
.topbar-terminal-warning-wrap {
  display: inline-flex;
  align-items: center;
}
/* Plain text naming the registered terminal, same visual weight as
   .topbar-connectivity beside it (not a control). */
.topbar-terminal-ok {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
/* A real 44px warning-colored button, replacing the PAY7 ticket-header
   chip (it measured 19x22px against e2e/usability.spec.ts's 44px floor,
   `padding: 2px var(--space-2)` with no min-height). Same warning tokens
   .badge-aging/.ticket-hold-badge already use elsewhere in this file,
   never a new color. aria-expanded reflects whether
   #topbar-terminal-detail is currently open. */
.topbar-terminal-warning {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
.topbar-terminal-warning:active {
  opacity: 0.7;
}
/* The full plain-language message, shown only once
   #topbar-terminal-warning is tapped (never automatically). Positioned
   here by main.ts (JavaScript, not CSS) against
   #topbar-terminal-warning-wrap's own real bounding box: this element is
   NOT nested inside that wrapper (see its own markup comment in
   index.html) because .topbar-right's own overflow-y: hidden (UX15)
   clips an absolutely positioned descendant nested inside it to a
   one-row-high box, the exact defect UX15-F1 already found and fixed
   once for the account-dropdown menu (styles.css's own .account-dropdown
   rule), reused here rather than rediscovered. z-index matches
   .account-dropdown's own --z-ticket-rail: both are small anchored
   popovers, never a full sheet or scrim. */
.topbar-terminal-detail {
  position: fixed;
  z-index: var(--z-ticket-rail);
  width: 340px;
  max-width: calc(100vw - 2 * var(--space-4));
  background: var(--color-surface);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.topbar-terminal-detail-text {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-warning-strong);
}
/* UX29: text not colour alone (CLAUDE.md's floor rule), non-interactive
   (no hover/focus states, no cursor change), so this is plain inline
   text rather than a pill or dot. */
.topbar-connectivity {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
/* UX100 (UX96 review): Online, the reader and the pricing chip are pills at the 44px floor, each with a state dot,
   not bare grey text. The dot is a second signal beside the words (the words stay; colour is never the only
   cue). Non-interactive: no hover, no cursor. */
.topbar-connectivity,
.topbar-pricing-model,
.topbar-terminal-ok {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  box-sizing: border-box;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: transparent;
}
.topbar-connectivity:empty {
  display: none;
}
.topbar {
  --topbar-dot-ok: var(--color-success);
  --topbar-dot-warn: var(--color-warning-strong);
}
/* The fixed success green is dark; on the dark themes the dots take a lighter green and amber so they clear 3:1
   against the header. */
[data-theme="snipsip-ink"] .topbar,
[data-theme="charcoal"] .topbar {
  --topbar-dot-ok: #5fcf8a;
  --topbar-dot-warn: #e8ad5a;
}
.topbar-connectivity,
.topbar-pricing-model,
.topbar-terminal-ok {
  line-height: 1;
}
.topbar-connectivity::before,
.topbar-terminal-ok::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--topbar-dot-ok);
}
.topbar-connectivity[data-state="offline"]::before {
  background: var(--color-danger);
}
.topbar-connectivity[data-state="issue"]::before {
  background: var(--topbar-dot-warn);
}
.topbar-pricing-model::before {
  background: var(--color-accent-strong);
}
/* CL8: an unhealthy reader (Offline, Not seen) draws in the warning tint, the word always in the text. */
.topbar-terminal-ok[data-health="unhealthy"]::before {
  background: var(--topbar-dot-warn);
}
.topbar-terminal-ok[data-health="unhealthy"] {
  color: var(--color-warning-strong);
  border-color: var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
}
.topbar[data-c-reader] .topbar-terminal-ok[data-health="unhealthy"] {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
[data-theme="brass"] .topbar :is(.topbar-connectivity, .topbar-pricing-model, .topbar-terminal-ok) {
  border-color: var(--color-brand-cream-muted);
}
.theme-switcher-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.theme-switcher {
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  padding: 0 var(--space-3);
}
.employee {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  min-width: 0;
}
.employee-name {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.employee-badge {
  min-width: 32px;
  height: 32px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-xs);
}

/* ---------- Sixteenth amendment item 1: topbar redesign ----------
   A Home icon button sits immediately right of the company name
   (.topbar-left), and the logged-in user's own name chip is always
   pinned to the top-right corner (.topbar-right), tapping it opens a
   touch-friendly dropdown containing, in order, Theme, Settings
   (rights-holders only), and Log out. Replaces the old standalone Theme
   <select> and Settings/Log out buttons that used to sit loose in the
   location. One consistent shape, duplicated per screen in index.html (this
   codebase has no shared-component layer), so one set of classes here
   styles all five instances identically across every screen and theme. */
.btn-home-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  flex-shrink: 0;
  align-self: center;
}
.btn-home-icon:active {
  background: var(--color-surface-sunken);
}
.account-menu {
  position: relative;
  flex-shrink: 0;
}
/* The tappable name chip itself: same visual weight as the old .employee
   span it replaces (reuses .employee/.employee-badge/.employee-name
   inside it unchanged), just now a real <button> that opens the
   dropdown, with a caret marking it as interactive. */
.account-trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
/* TABSLAYOUT1: the badge sits snug inside the pill. */
.account-trigger .employee-badge {
  width: 28px;
  min-width: 28px;
  height: 28px;
  margin-left: calc(var(--space-2) * -1);
}
.account-trigger[aria-expanded="true"] {
  border-color: var(--color-accent-strong);
}
.account-trigger-caret {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
/* Absolutely positioned under the trigger rather than a full scrim
   sheet: this is a small menu, not a form, and the touch-only rule only
   requires it be dismissible by tapping outside (main.ts's outside-tap
   and Escape handling), never that it block the rest of the screen. */
.account-dropdown {
  position: absolute;
  top: calc(100% + var(--space-2));
  /* UX15-F1: positioned against .topbar (position: relative above), not
     .account-menu, because .topbar-right's overflow-y: hidden (UX15)
     clipped a menu positioned inside it to a one-row-high box. Aligned
     with the header's own right padding. */
  right: var(--space-5);
  z-index: var(--z-ticket-rail);
  /* UX115: the menu sits inside the header, so unstyled text inherited the header's text color (cream on brass). */
  color: var(--color-text-primary);
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.account-dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2);
  min-height: var(--touch-target-min);
}
.account-dropdown-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.account-dropdown-theme .theme-switcher {
  flex: 1;
  min-width: 0;
}
.account-dropdown-button {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-sm);
  border: none;
  background: transparent;
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  text-align: left;
}
.account-dropdown-button:active {
  background: var(--color-surface-sunken);
}

/* ---------- Body: menu + ticket rail ---------- */

.body {
  display: flex;
  flex: 1;
  min-height: 0;
}

.menu-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* ALPHA-10 item 1, corrected during the design/QA gate re-review
   (2026-08-20): a fixed 27-entry strip (A-Z plus "#") does not fit one
   row at either supported tablet width (a 44px target per letter needs
   ~1341px; only 880px is available at 1280x800 and 624px at 1024x768,
   both measured live against #alphabet-strip.clientWidth), and the
   original fix left the overflow as a horizontal scroll with zero
   affordance, so roughly half the alphabet was reachable only by a
   bartender who happened to guess to swipe sideways on what reads as a
   static row of buttons.

   Fixed by wrapping to two rows (flex-wrap) instead of scrolling one.
   44px stays the real touch-target floor (tokens.css: "nothing tappable
   is smaller than 44px") and is never shrunk to force a fit. What gives
   instead is this strip's own horizontal padding and inter-letter gap,
   both dropped to 0: at 1024x768, 14 letters at 44px with any gap or
   padding at all no longer fits inside 624px (14 * 44px = 616px alone,
   leaving 8px total to split across 13 gaps and 2 sides), so both had to
   go to zero to reach exactly two rows rather than three. Adjacent
   letters keep a visible 1px seam from each button's own border (below)
   colliding with its neighbor's, which reads as a grid divider rather
   than a gap; row-to-row spacing is a separate, small var(--space-1) row
   gap, kept deliberately minimal so the extra row costs as little
   vertical space as possible against the menu grid's own dominant share
   of the screen. Verified live (Chromium) at both supported widths: two
   full rows, no horizontal scrollbar, every letter including "Z" and "#"
   fully visible with no scrolling. */
.alphabet-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) 0;
  /* 2px sides, not the space-5 every other row in this pane uses: the
     narrowest supported width has essentially zero slack left once 14
     letters at the 44px floor are laid out with no inter-letter gap (see
     this rule's own header comment), so this strip alone gives up its
     edge inset rather than the letters giving up their touch-target
     size. */
  padding: var(--space-3) 2px var(--space-2);
  flex-shrink: 0;
  background: var(--color-bg);
}
.alphabet-letter {
  flex-shrink: 0;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  cursor: pointer;
}
/* A letter with no drinks stays in the strip, muted and unclickable
   (:disabled), rather than the strip reflowing around only letters
   currently in use; see main.ts's renderAlphabetStrip. */
.alphabet-letter:disabled,
.alphabet-letter.inactive {
  opacity: 0.35;
  cursor: not-allowed;
  color: var(--color-text-tertiary);
}

.menu-scroll {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-2) var(--space-5) var(--space-8);
}

.menu-empty {
  color: var(--color-text-secondary);
  padding: var(--space-6) 0;
}

.menu-section {
  margin-bottom: var(--space-8);
  scroll-margin-top: var(--space-4);
}
.menu-section-title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  margin: 0 0 var(--space-3);
}

.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--space-3);
}

/* VOC1-F8 (docs/build-briefs/VOC1-F8-view-recipe-on-the-floor.md, Section
   2.1). A cocktail tile is now a wrapper holding two independently
   tappable siblings (the unchanged add-to-ticket .tile button, plus
   .tile-recipe-button below) rather than one overloaded surface; a
   non-cocktail tile keeps rendering a bare .tile as the grid's direct
   child, unwrapped, since CSS Grid treats any direct child as a grid
   item regardless of its own class. position: relative anchors the
   recipe button's own absolute corner placement.
   UX40 (docs/build-briefs/UX40-recipe-button-beside-price.md, Section
   1.2 Part A): align-self: start stops Grid's own default
   `align-items: stretch` from stretching this wrapper to the row's own
   tallest member. .tile itself is a plain block child and never
   stretches, so without this rule a short tile's wrapper sat taller
   than its own visible card, invisibly, and a bottom-anchored child
   (the Recipe button) measured its offset against that stretched
   wrapper box rather than the actual card, rendering partly or fully
   below it on a short tile next to a taller row-mate. With this rule
   the wrapper's own box always equals .tile's real rendered height. */
.tile-wrapper {
  position: relative;
  align-self: start;
}

/* UX40 (docs/build-briefs/UX40-recipe-button-beside-price.md, Section
   1.2 Part B): reserved only on a tile that is actually rendering the
   Recipe button (the wrapper carries this modifier class exactly where
   recipeButton.hidden is set in renderMenuGrid), so a tile with no
   button -- no admin.menu_drink.view permission, or a non-cocktail item
   that is never wrapped at all -- keeps its price at full width like
   every other tile, never paying for a control it does not render. */
.tile-wrapper--recipe-visible .tile-price {
  padding-right: 72px;
}

.tile {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4);
  min-height: 96px;
  display: flex;
  flex-direction: column;
  /* UX45 Section 2a (docs/build-briefs/UX45-liquor-tile-badge-grouping.md,
     real-app redesign): was justify-content: space-between, which
     distributed a tile's leftover vertical space evenly across every gap
     (badge-to-badge, badge-to-name, name-to-price alike), so nothing
     visually bound the POUR/OUT badges to the product name beneath them
     any more tightly than to empty space. flex-start removes that
     even-distribution; .tile-price's own margin-top: auto (below) takes
     back 100% of the leftover height so price still anchors the card's
     own bottom edge exactly as before. gap stays at its ORIGINAL,
     unchanged production value (var(--space-3)) for every tile alike --
     the first build instead tightened this shared gap directly, which
     also shrank a bare two-child cocktail tile's own name-to-price gap
     and moved UX40's fixed-inset Recipe button over the wrapped drink
     name. The badge-to-badge/badge-to-name tightening is scoped to the
     two badge elements themselves (their own margin-bottom, below)
     rather than to this shared token. */
  justify-content: flex-start;
  gap: var(--space-3);
  text-align: left;
  cursor: pointer;
  color: inherit;
  width: 100%;
}
.tile:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.tile-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.tile-price {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  /* UX45: reproduces .tile's old justify-content: space-between effect
     for price specifically (absorbs all leftover height in the flex
     column so price still sits at the card's own bottom edge), now that
     .tile itself no longer distributes leftover space evenly. */
  margin-top: auto;
}
/* VOC1-F8, Section 2.1: touch-target-comfortable, matching
   .stock-state-badge's own corner-marker convention (a plain-language
   word, never color alone) but absolutely positioned rather than
   flowed, since it must be independently tappable rather than
   decorative. No title attribute (check:touch-only): the visible
   "Recipe" label plus aria-label is the recovery.
   UX40 (docs/build-briefs/UX40-recipe-button-beside-price.md, Section
   1.2 Part B, DEC-192): moved from top-right (where it covered the
   drink name) to bottom-right, sharing the price's row. The right
   inset matches --space-4 (16px), the same value as .tile's own
   padding and therefore the price text's own left edge, so the button
   respects the same inner-padding boundary the price does. The bottom
   inset is --space-1 (4px), tuned against the mockup's own real
   single-line price geometry so the button's vertical center lands
   within about 1px of the price line's own center; --space-2 or
   --space-4 both overshoot by several px either way. */
.tile-recipe-button {
  position: absolute;
  bottom: var(--space-1);
  right: var(--space-4);
  min-width: var(--touch-target-min);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-1);
  /* UX129: the element paints its own pill. The 44px box is the hit area; the transparent borders make up the
     difference and background-clip keeps the fill to the padding box, a 24px pill. A rendered-text contrast audit
     reads the button's own background, which a ::before layer hid (it saw dark text on the dark tile, 1.03:1). */
  box-sizing: border-box;
  border: 10px solid transparent;
  border-left-width: var(--space-1);
  border-right-width: var(--space-1);
  border-radius: var(--radius-md);
  background-color: var(--color-accent-strong);
  background-clip: padding-box;
  color: var(--color-text-on-accent);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tile-recipe-button:hover {
  filter: brightness(0.92);
}

.tile-price.variable {
  /* Amendment 2026-08-22 (item 2): --color-accent-strong is now the
     DEEP fill/pill-text color (paired with a light --color-accent-subtle
     background or with --color-text-on-accent on a solid fill; see
     design/README.md "Distinctness from the fixed semantic hues,
     Charcoal's inverted pairing"). This is the one spot that colors text
     directly on the plain tile surface with no subtle-background pill
     underneath it, so it reads the lighter --color-accent (base) instead,
     the variant every theme keeps legible as bare text on its own
     surface. */
  color: var(--color-accent);
  font-weight: var(--font-weight-medium);
}

/* Inventory track (track/inventory) Slice 3, Amendment 2026-08-22
   (twelfth): "type-appropriate tiles" for a pour/draft-beer/packaged menu
   tile, alongside a cocktail tile's unchanged plain look. Reuses
   .line-badge-substitution's exact accent-subtle/accent-strong/accent-
   subtle-border trio (design/tokens.css, verified-contrast in every
   theme) rather than inventing a second accent pairing: this is the same
   "an intended, ordinary distinction, not a problem" case that badge's
   own comment already argues for. */
.tile-kind-badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: var(--line-height-tight);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  /* UX45 Section 2a (docs/build-briefs/UX45-liquor-tile-badge-grouping.md,
     real-app redesign): pulls tight to whatever follows (the stock-state
     badge, or the name when there is no stock-state badge) with a
     negative margin that nets out against .tile's own unchanged
     var(--space-3) (12px) gap: 12px - 8px = 4px (var(--space-1)), the
     same tight figure the original design measured, without touching the
     shared gap token itself (see .tile's own comment for why). */
  margin-bottom: calc(var(--space-1) - var(--space-3));
}

/* ---------- Resizable ticket rail (Amendment 2026-08-22, sixth, item 1) ----------
   The drag handle sits as a DOM sibling BETWEEN .menu-pane and
   .ticket-rail (index.html), not inside either, so it can own the visual
   boundary line between them (moved here from .ticket-rail's own former
   border-left, now removed below to avoid a doubled seam) while its own
   width stays fixed regardless of how wide the rail itself is dragged. */
.rail-resize-handle {
  flex-shrink: 0;
  /* Comfortable touch target, not the 1px seam a plain border would give:
     the item's own words are "a comfortable touch target (a visible
     handle, not a 1-pixel edge)." 24px is this product's own documented
     hit-area floor for a narrow drag affordance (see the grip location below
     for the actually-visible part); still short of touch-target-min
     (44px) because a full 44px-wide vertical strip would eat meaningfully
     into the menu grid's own tight width budget at 1024x768 for a control
     that is dragged, not tapped, and drag targets tolerate a narrower hit
     area than a tap target does (there is no adjacent-target misfire risk
     the way a 44px tap-target floor exists to prevent). */
  width: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: col-resize;
  /* Stops the browser's own touch-scroll/pan gesture from competing with
     a touch drag that starts on this element - without this, a touch drag
     on a touch device scrolls the page instead of resizing the rail. */
  touch-action: none;
  border-left: 1px solid var(--color-border);
  background: var(--color-surface);
}
/* The actual visible grip: a short rounded location centered in the handle's
   own full-column-height hit area, distinguishing "there is something to
   drag here" from a plain divider line. Runs the full column height via
   the handle's own flex-stretch (a sibling flex item of .menu-pane and
   .ticket-rail inside .body, which does not override the default
   align-items: stretch), never just a corner or edge. */
.rail-resize-handle::before {
  content: "";
  width: 4px;
  height: 48px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
}
.rail-resize-handle:hover::before,
.rail-resize-handle.dragging::before {
  background: var(--color-accent);
}
/* Below the tablet-landscape primary target, .body stacks the rail under
   the menu instead of beside it (see the @media (max-width: 900px) rule
   further down); a horizontal drag handle has no meaning once the two
   panes are no longer side by side, so it is hidden rather than left
   present and inert. */
@media (max-width: 900px) {
  .rail-resize-handle {
    display: none;
  }
}

/* ---------- Ticket rail ---------- */

.ticket-rail {
  /* Default width; src/railResize.ts overwrites this with an inline
     style on load (the device's stored width, or this same 400px default
     when nothing is stored yet - see RAIL_WIDTH_DEFAULT_PX). Kept in sync
     with that constant deliberately, as the pre-JS-paint fallback. */
  width: 440px;
  flex-shrink: 0;
  background: var(--color-surface);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* PAYTOTAL1-F1: the drink list yields space to the authoritative totals and actions.
     The rail fallback keeps every control reachable if an unusually long set of reductions exceeds its height. */
  overflow-y: auto;
  scrollbar-gutter: stable;
}
.ticket-rail::-webkit-scrollbar {
  width: 8px;
}
.ticket-rail::-webkit-scrollbar-track {
  background: transparent;
}
.ticket-rail::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
}
/* UX13 (design/ux13-ticket-rail-rationale.md, DEC-053's "DENSITY: compact
   chrome" scale, design/tokens.css). The header used to be a title row,
   then a "N drinks" subtitle row, then a separate guest-actions row:
   three rows of vertical budget for information that fits on one. This
   is now one --chrome-row-height row, costing nothing beyond what a
   header chip already needs at that height. */
.ticket-header {
  padding: 0 var(--space-4);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.ticket-header-row {
  height: var(--chrome-row-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--chrome-gap-tight);
}
/* The ticket's own name and status, sharing one truncating line
   (mirroring design/mockups/ticket-rail-redesign-blocked.html's own
   .ticket-id). #ticket-sub carries the name (or "Ticket" for an unnamed
   walk-in); #order-status/.ticket-age carries status, unchanged text
   logic either way. */
.ticket-id {
  min-width: 0;
  flex-shrink: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-size-chrome);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
.ticket-age {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
/* Payments-track Slice 4 (DEC-002). Mirrors .badge-aging's own
   inline-pill shape (border, subtle background, small bold text), the
   warning palette rather than accent: a hold is money set aside on a
   guest's card, worth calling out visually the same way an aging tab
   already is, not a neutral status line. */
.ticket-hold-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  width: fit-content;
}
/* PAY14 (docs/build-briefs/PAY14-order-hold-provider-recheck.md, Section
   8.1, D2 required change 1, approved by the ui-ux-designer in
   design/reviews/pay14-order-hold-provider-recheck-2026-09-25.md): "Hold
   needs a manager" uses the danger trio, not the warning palette an
   ordinary healthy hold already uses. */
.ticket-hold-badge--needs-manager {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
}
/* PAY14 (Section 8.1, the Q3 note): "Test hold cleared. Take a card at
   Pay." in the badge's own slot, in the info palette (the .badge-simulated
   trio). */
.ticket-hold-badge--test-cleared {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
}

.no-order-panel {
  padding: var(--space-6) var(--space-5);
  text-align: center;
  color: var(--color-text-secondary);
}
.no-order-panel p {
  margin: 0 0 var(--space-4);
}

/* UX13 (design/ux13-ticket-rail-rationale.md). The old min-height calc
   here (git history) modeled a "two lines plus a peek" FLOOR, tuned
   against the six-action chrome stack this item removes and against a
   second, tighter tablet height DEC-051/VP1-F1 has since retired (the
   floor is designed and tested at FLOOR_DEVICE.viewport alone). That
   floor is gone outright, not raised: with every sibling chrome element
   compressed to its own real minimum (the header row, the totals block,
   the action row), flex: 1 alone gives this region whatever is left,
   which is what harness/e2e/ux13-ticket-rail.spec.ts measures directly
   against the real rendered rail rather than a hand-tuned pixel formula. */
.ticket-lines {
  min-height: 0;
  flex: 1;
  overflow-y: auto;
  /* UX14 (designer polish R1/R2): space-4 not space-5 and no reserved
     scrollbar gutter, as in the approved mockup, so a drink name keeps about
     16px more of row one. The thin visible scrollbar below still shows when
     the list overflows. */
  padding: 0 var(--space-4);
}
/* Visible scroll affordance: overflow-y:auto alone renders no reliably
   visible scrollbar on every platform (macOS Chromium's default is a
   thin overlay that only appears while actively scrolling, easy to miss
   under location lighting). This keeps a thin permanent track+thumb instead,
   Chromium/WebKit only per the browser support this product targets
   (browser-only, touch tablet; no Firefox requirement in
   docs/solution-architecture.md). */
.ticket-lines::-webkit-scrollbar {
  width: 8px;
}
.ticket-lines::-webkit-scrollbar-track {
  background: transparent;
}
.ticket-lines::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
}

.line {
  /* Compact two-row line, design gate fix (2026-08-20): was a single
     flex row with name/liquor/price stacked three-deep in .line-info
     beside the Prepared pill, which let a real long liquor name (up to
     ~57 characters, fixtures/inventory-snapshot.json) wrap onto two or
     three lines on its own and push measured line height to 121-166px,
     leaving barely more than one line visible in the rail at either
     1280x800 or 1024x768. Name and price now share a row (.line-top)
     and the liquor detail is a single truncated row below it, so a real
     line measures well under 96px; see .ticket-lines's min-height
     comment for the retuned figure this was measured against live.
     UX44 (docs/build-briefs/UX44-ticket-line-name-whole-price-below.md,
     the Hybrid variant, DEC-198): gap tightened from --space-2 to
     --space-1, reclaiming 4px of chrome for .line-name-text, layered
     under .line-top's own flex-wrap (below) so a name that needs a
     second row for its price costs zero added row height. */
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}
.line:last-child {
  border-bottom: none;
}
.line-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.line-top {
  /* UX44 Section 2a (docs/build-briefs/UX44-ticket-line-name-whole-price-
     below.md, real-app redesign, DEC-198): the base state is exactly the
     pre-UX44 shipped layout (nowrap, a single var(--space-2) gap). A pure
     CSS flex-wrap trigger wraps against each child's own PREFERRED
     (max-content) width, not its truncated rendered width, so an
     unconditional flex-wrap: wrap here wrapped every long real drink name
     too (not only a name that would render whole), costing height for
     nothing and clipping row 8 of the rail. The wrap decision is instead
     made per row in script, refreshLineNameStacking() (main.ts), which
     toggles .line-top-stacked below only when the whole name actually
     fits once the price is out of the way. */
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: var(--space-2);
  min-width: 0;
}
.line-top.line-top-stacked {
  /* Applied only by refreshLineNameStacking() for a row where wrapping
     actually shows the whole name. The row-axis (vertical) gap is
     tightened to 2px once wrapped, since a wrapped two-line stack needs
     far less separation than the horizontal name-to-price gap does on one
     line; the column-axis (horizontal) gap stays var(--space-2)
     unchanged. */
  flex-wrap: wrap;
  gap: 2px var(--space-2);
}
.line-name {
  /* UI-batch gate fix (drink-name touch recovery): now a flex wrapper,
     the same shape .line-detail below already has, holding one
     truncating child (.line-name-text) instead of being the truncating
     element itself. main.ts's attachTruncatedTextTapToggle needs a
     wrapper to toggle the shared .line-detail-expanded class on,
     independently of the text span it measures for overflow - the same
     reason .line-detail split from its own text during the ALPHA-10
     re-review. Still .line-top's flex item; sizing is unchanged, only
     moved onto this rule from the old single-element version. */
  flex-shrink: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 2px;
}
/* Expanded state, same shared class and reasoning as
   .line-detail.line-detail-expanded below: align-items relaxes from
   center to flex-start once the name wraps onto multiple lines, so a
   long drink name never gets vertically centered against .line-top's
   own price/paid-badge siblings while wrapped. */
.line-name.line-detail-expanded {
  align-items: flex-start;
}
.line-name-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  overflow: hidden;
  /* UX49 (docs/build-briefs/UX49-ticket-rail-name-word-truncation.md):
     was text-overflow: ellipsis, the browser's own CHARACTER-boundary
     clip. main.ts's refreshLineNameWordTruncation now computes the
     truncated text in JS, appending its own ellipsis character, so the
     browser must never ALSO re-clip it: with "ellipsis" still set here,
     a JS-truncated candidate that still slightly overshot the box (the
     rare case where not even the first whole word fits,
     truncateToWholeWord's own documented fallback) was found being
     re-clipped by the browser down to a character fragment again
     ("Cucumber..." -> "Cucu..."), reproducing the exact defect this item
     fixes. "clip" leaves the JS-computed text as the single source of
     truth for what is shown. */
  /* UX114 (docs/build-briefs/UX114-ticket-line-names-wrap.md), owner: "Two
     lines, then cut." The name wraps to at most two lines and the browser
     ends the second with an ellipsis; a longer name opens on tap below. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  text-overflow: ellipsis;
  white-space: normal;
  word-break: normal;
  overflow-wrap: anywhere;
  /* Touch-only audit fix, same reasoning as .line-detail-text below:
     tapping this text is the real, touch-first recovery path for a
     truncated drink name now (the title attribute is a non-touch
     fallback only). cursor: pointer is cosmetic (this product is
     touch-only); :active is the real, always-on tap feedback. */
  cursor: pointer;
}
.line-name-text:active {
  opacity: 0.65;
}
.line-name.line-detail-expanded .line-name-text {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  /* UX75-F1: words break only at spaces; a single unbroken token wider
     than the box is the one case allowed to split. */
  word-break: normal;
  overflow-wrap: anywhere;
}
/* UX75-F1 (docs/build-briefs/UX75-F1-open-name-width.md): while a name is
   open, its price drops under it, the same wrap .line-top-stacked gives a
   row at the narrower rail, so the open name gets the row width beside the
   state button instead of a ~65px column (one word per line, its own state
   button pushed below the rail fold). Keyed on the expanded state, not on
   viewport; a collapsed row never matches. */
.line-top:has(.line-name.line-detail-expanded) {
  flex-wrap: wrap;
  gap: 2px var(--space-2);
}
.line-detail {
  /* Design gate fix, ALPHA-10 re-review (2026-08-20): this row now holds
     up to two children, a truncating text span (the liquor name) and, for
     a substituted line, a non-shrinking badge (see .line-badge below). It
     used to be a single block element whose own overflow/ellipsis rules
     applied to ALL of its text content, including an appended
     "· Substituted" suffix, which is exactly what let a long liquor name
     truncate the marker away; see main.ts's renderTicketLines for the
     full history. The overflow/ellipsis behavior itself moved onto
     .line-detail-text so it applies only to the liquor name now, never to
     the badge. */
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.line-detail-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Touch-only audit fix (ALPHA-09 release evidence, category 2,
     main.ts:1790 and main.ts:1814): a truncated title-only tooltip is
     never touch-reachable, and live inspection found the title
     attribute empty regardless. main.ts's attachTruncatedTextTapToggle
     makes this row itself the recovery path: tapping it wraps to the
     full text (see .line-detail-expanded below), tapping again
     collapses it back. cursor: pointer is cosmetic (this product is
     touch-only), :active below is the real, always-on tap feedback. */
  cursor: pointer;
}
.line-detail-text:active {
  opacity: 0.65;
}
/* Expanded state, toggled on the row wrapper (.line-detail, shared by
   both the normal liquor-detail row and .line-warning) rather than on
   .line-detail-text itself, so align-items can relax from center to
   flex-start: once the text wraps onto multiple lines, centering would
   vertically split a non-shrinking sibling badge (.line-badge) or notch
   it off-center against the now-taller text block. Untouched
   (untruncated) lines never gain this class (attachTruncatedTextTapToggle
   is a no-op when textEl.scrollWidth <= textEl.clientWidth), so the
   compact two-row layout and Review 5's line-height fixes are unchanged
   for every line that was never truncated in the first place. */
.line-detail.line-detail-expanded {
  align-items: flex-start;
}
.line-detail.line-detail-expanded .line-detail-text {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  word-break: break-word;
}
/* UX13 (design/ux13-ticket-rail-rationale.md "Problem 2"): the tap-to-
   expand path above (attachTruncatedTextTapToggle) had no VISIBLE sign it
   exists (cursor: pointer alone, invisible with no hover on a
   touchscreen). This chevron (main.ts's appendTruncationChevron) is
   always in the DOM but hidden by default, shown only once
   refreshLineTruncationChevrons marks its own row genuinely truncated
   (scrollWidth > clientWidth), and rotated while the row is expanded, the
   same shape design/mockups/ticket-rail-redesign-blocked.html's own
   .trunc-chevron establishes. Purely visual: the tap target stays the
   text span itself, unchanged. */
.trunc-chevron {
  display: none;
  flex-shrink: 0;
  font-size: 12px;
  font-weight: var(--font-weight-bold);
  line-height: 1;
  color: var(--color-accent-strong);
  transform: translateY(1px);
  transition: transform var(--motion-fast) var(--motion-easing-standard);
}
.line-name.is-truncated .trunc-chevron,
.line-detail.is-truncated .trunc-chevron {
  display: inline-block;
}
.line-name.line-detail-expanded .trunc-chevron,
.line-detail.line-detail-expanded .trunc-chevron {
  transform: rotate(180deg) translateY(-1px);
}
.line-price {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  white-space: nowrap;
}
/* ALPHA-07: a resumed line whose liquor selection could not be
   reconstructed (see main.ts's TicketLineState.priceable comment). Rare;
   warning-colored so it reads as "needs attention", not as a normal
   price. */
/* DSC35-S7 (design/mockups/dsc35-ticket-rail.html): the price after a
   scheduled special, in the success colour and bold, with the green Auto
   strip full width under the line. A line wraps ONLY when it carries a
   strip, so every other line lays out exactly as before. */
.line.line-has-special {
  flex-wrap: wrap;
  padding: var(--space-1) 0;
}
.line-price.line-price-now {
  color: var(--color-success-text);
  font-weight: var(--font-weight-bold);
}
.line-special {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  line-height: 1.2;
  border-radius: var(--radius-sm);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.tag-auto {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.line-special-name {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-strong);
  overflow-wrap: anywhere;
}
.line-special-amount {
  flex-shrink: 0;
  text-align: right;
  white-space: nowrap;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-success-strong);
}
/* DSC35-S7b: the plain muted line under a drink whose special a manager removed. */
.line-special-removed {
  flex: 1 1 100%;
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.line-price.unavailable {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}

/* ---------- UX14 (docs/build-briefs/UX14-floor-density.md, DEC-314): ring screen ----------
   A to Z strip: ONE swipeable row of 44px letters (--index-strip-height),
   only letters that have a drink, the right edge fading while there is more
   to swipe to. It was two wrapped rows (114px). */
.alphabet-strip {
  flex-wrap: nowrap;
  gap: 0;
  align-items: center;
  box-sizing: border-box;
  height: var(--index-strip-height);
  padding: 0 var(--space-2);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.alphabet-strip::-webkit-scrollbar {
  display: none;
}
.alphabet-strip.has-more {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
}
/* POUR and OUT side by side above the name (they were stacked, 22px each). */
.tile-badges {
  display: flex;
  align-items: center;
  align-self: flex-start;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-bottom: calc(var(--space-1) - var(--space-3));
}
.tile-badges .tile-kind-badge,
.tile-badges .stock-state-badge {
  margin-bottom: 0;
}
/* A ticket line is two rows, always: the name gets the whole first row, then
   the price and the liquor share row two (a pour drink was three rows, 92px,
   against 62px for a plain one; a name used to share row one with its price
   and truncate to "Al..."). Designer polish R1/R2 on UX14. .line-top is
   display: contents so its name and price join the info column's grid. */
.line-info {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: center;
  gap: var(--space-1) var(--space-2);
}
.line-info > * {
  grid-column: 1 / -1;
  min-width: 0;
}
.line-info > .line-top {
  display: contents;
}
.line-info .line-price,
.line-info .line-detail-text {
  line-height: var(--line-height-tight);
}
.line-info .line-top .line-name {
  grid-column: 1 / -1;
}
.line-info .line-top .line-price {
  grid-column: 1;
  align-self: center;
}
.line-info .line-top + .line-detail:not(.line-modifiers):not(.line-warning) {
  grid-column: 2;
}
/* Design gate fix (2026-08-20): the persistent "needs a manager" note
   that replaces .line-detail on an unpriceable line (renderTicketLines).
   Shares .line-detail's layout (one truncated row) but reads as a warning
   rather than incidental detail text, so the state is visible on the line
   itself for as long as the line is on screen, not only in a toast.
   Targets .line-detail-text (the child span), not .line-detail itself,
   now that .line-detail is a flex wrapper rather than the text element. */
.line-warning .line-detail-text {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
/* ALPHA-10 item 2, corrected during the design gate re-review
   (2026-08-20): "Substituted lines show it plainly on the ticket rail"
   (work item instruction), now a standalone badge rather than text
   appended to the truncating liquor-name row (main.ts's renderTicketLines
   carries the full history of why). flex-shrink: 0 keeps the badge's
   full width guaranteed regardless of how much the liquor name beside it
   has to truncate; .line-detail-text is the only thing that ever gives up
   width. Distinguished by shape (a bordered, filled pill) and its own
   literal text ("Substituted"), not by color alone, so it reads
   correctly in every theme including colorblind and high-contrast, where
   .line-badge-substitution's accent-subtle/accent-strong/accent-subtle-
   border trio (design/tokens.css) is still a verified-contrast pair (see
   each theme file's own contrast-ratio comment) even though the hue
   itself differs theme to theme. Accent-colored rather than
   warning-colored: a substitution is an intended bartender action, not a
   problem needing attention the way an unpriceable line is. */
.line-badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.line-badge-substitution {
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
}
/* VOC1-F7 Slice 2 (DEC-171): a pour modifier gets its own plainly-labeled
   badge, the same non-truncating shape .line-badge-substitution already
   established, so a manager reading the ticket rail never infers pour size
   from price alone. Info-toned rather than accent-toned: distinct from a
   substitution (a different fact about the same line), verified-contrast
   pair per design/tokens.css's own --color-info* comment. */
.line-badge-pour {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
}
/* .line-badge-paid (the separate "Paid" pill this file used to define
   here, ALPHA-08) is gone as of Amendment 2026-08-22 (sixth), item 2: the
   signal it carried now lives on the line's own .state-btn instead (see
   .state-btn.paid below), one control per line rather than two stacked
   side by side. */
/* Amendment 2026-08-22 (item 3): the per-line guest badge (.line-badge-
   guest, info-toned) is gone. A guest's drinks are now grouped under
   their own .line-section-header (below) instead, so which guest a line
   belongs to is conveyed by the section it sits in rather than a badge
   competing with the drink name for the line's own limited width. */
.line-section-header {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
  padding: var(--space-2) 0 var(--space-1);
  margin-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}
.line-section-header:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
/* Amendment 2026-08-22 (fifth), item 3: a section whose every line is
   already covered sinks to the bottom of the rail and is "visibly marked
   paid" (the item's own wording). Text-suffixed by main.ts's
   buildLineSectionHeader (", paid"), never color alone, matching this
   file's own touch-only/colorblind rule; the color here reuses the same
   fixed success pairing .line-badge-paid above already established for
   "this is a positive, paid state." Font-size/weight/padding are
   untouched from the plain .line-section-header above, so this adds no
   height of its own. */
.line-section-header-paid {
  color: var(--color-success-text);
}

.state-btn {
  /* Design gate fix (2026-08-20): dropped from touch-target-comfortable
     (56px) to touch-target-min (44px, still >= the 44px hard floor) and
     from a fixed 148px to a content-sized min-width, to give the
     compacted .line-info more of the ticket rail's 400px width for real
     drink/liquor names instead of forcing them to wrap.
     UX44 (docs/build-briefs/UX44-ticket-line-name-whole-price-below.md,
     the Hybrid variant, DEC-198): padding and icon-to-text gap tightened
     further (var(--space-3) to var(--space-2), var(--space-2) to
     var(--space-1)) to reclaim more chrome for .line-name-text; still
     comfortably above the 112px DEC-053 floor and the 44px height floor
     (both unchanged below). */
  flex-shrink: 0;
  height: var(--touch-target-min);
  min-width: 112px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  border: 1px solid transparent;
  cursor: pointer;
}
.state-btn .dot-icon {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.state-btn.not-prepared {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border-color: var(--color-warning-subtle-border);
}
.state-btn.not-prepared .dot-icon {
  border: 2px solid var(--color-warning-strong);
}
.state-btn.prepared {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border-color: var(--color-success-subtle-border);
  cursor: default;
}
.state-btn.prepared .dot-icon {
  background: var(--color-success-strong);
  /* text-on-dark, not text-on-accent: this background is the FIXED
     semantic success-strong color (design/tokens.css), always dark, not
     this theme's own accent-strong. text-on-accent is tuned per-theme to
     pair with THAT theme's accent-strong specifically (see
     design/README.md) and on Charcoal is a dark color, since Charcoal's
     own accent-strong is light; paired with the fixed dark success-strong
     it renders near-invisible dark-on-dark. text-on-dark is defined on
     every theme to be safely light against a dark, saturated background,
     which is what this fixed chip icon always is. Design/QA gate finding,
     2026-08-21: found while verifying the new Charcoal accent red does
     not read as an error state; this bug predates that change (same root
     cause affected the danger/success toast and the warning/info icons
     below, fixed alongside it). */
  color: var(--color-text-on-dark);
  font-size: 12px;
  font-weight: var(--font-weight-bold);
}
/* Amendment 2026-08-22 (sixth), item 2: the terminal Paid state, replacing
   the separate .line-badge-paid pill that used to render beside this
   button (see that class's own now-historical comment above). Deliberately
   a SOLID success fill rather than reusing .state-btn.prepared's subtle
   tint: the two are adjacent states a bartender scans past quickly, and a
   light-green-on-light-green pair (subtle Prepared next to a
   hypothetically subtle Paid) would read as one state twice rather than a
   clear progression. color-success-strong/text-on-dark is the same
   verified-contrast fixed pair .toast.toast-success and this same rule's
   own .dot-icon above already use for "a solid, always-dark, saturated
   background," so this stays legible in every theme including Charcoal
   without a new pairing to verify. */
.state-btn.paid {
  background: var(--color-success-strong);
  color: var(--color-text-on-dark);
  border-color: var(--color-success-strong);
  cursor: default;
}
.state-btn.paid .dot-icon {
  background: var(--color-text-on-dark);
  color: var(--color-success-strong);
  font-size: 12px;
  font-weight: var(--font-weight-bold);
}

/* The whole money/action block stays together above the rail edge while drinks scroll.
   Native rail overflow remains a safety fallback for an exceptionally tall set of actual reductions. */
.ticket-money-footer {
  position: sticky;
  bottom: 0;
  flex-shrink: 0;
  background: var(--color-surface);
}
.ticket-totals {
  padding: var(--chrome-gap-hairline) var(--space-4) 0;
  border-top: 1px solid var(--color-border);
  flex-shrink: 0;
}
.totals-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  padding: var(--space-1) 0;
}
/* PAYTOTAL1: ticket breakdown is always visible; Total has no collapse action. */
.totals-row-grand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-xl);
  line-height: var(--line-height-chrome);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
.totals-label-row {
  display: flex;
  align-items: center;
  gap: 2px;
}
.totals-compact {
  display: flex;
}

/* UX62 (docs/build-briefs/UX62-paid-ticket-totals.md): the persistent
   "Paid" row, directly under Total. Copied from the owner-approved mockup
   (design/mockups/ux62-paid-ticket-totals.html's "NEW in the proposed
   panel only" block). Same row shape as .totals-row-grand (Total), one
   size down; fixed success tokens plus a check glyph and the word "Paid"
   carry the state together, never color alone (design/principles.md rule
   1). */
.totals-row-paid {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--chrome-gap-hairline);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-text);
}
.totals-row-paid .paid-label {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.totals-row-paid .paid-check {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--color-success-strong);
  color: var(--color-text-on-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: var(--font-weight-bold);
}
.totals-row-paid .paid-count {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-chrome);
}

/* UX62 tip correction (owner ruling, 2026-09-28): a plain detail row,
   directly under Paid, matching Subtotal/Tax's own weight rather than
   Paid's own success-check treatment -- Tips is a breakdown figure, not a
   completion state, so it carries no icon and no color signal of its own
   (design/principles.md rule 1 governs STATE; this is an amount). Shown
   only when the summed tip is above zero (renderPaidRow). */
.totals-row-tips {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--chrome-gap-hairline);
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
  color: var(--color-text-secondary);
}

/* UX62-F1 (docs/build-briefs/UX62-F1-refunded-line.md), owner ruling
   2026-09-28, "Separate Refunded line": same secondary treatment as
   .totals-row-tips directly above, not Paid's success-check treatment --
   a refund is an amount breakdown on this ticket, not itself a completion
   state (design/principles.md rule 1). Shown only when a completed refund
   exists (renderPaidRow). */
.totals-row-refunded {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--chrome-gap-hairline);
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
  color: var(--color-text-secondary);
}

/* Sixteenth amendment item 2: the "All paid. Close this ticket?" one-tap
   prompt. Success tokens (this is a good-news state), touch-first row
   with both controls at the >=44px hard floor (CLAUDE.md's touch-only
   rule), matching .zero-due-prompt-actions below. */
/* ALPHA-12 vertical-space-budget class of bug (see .ticket-lines' own
   comment above for the full history): design-gate finding, this rule's
   own first version used justify-content:space-between with flex-wrap,
   which wraps to two full rows the moment the text and both buttons
   cannot share one line, roughly DOUBLING this element's height
   (measured 127px on a 400px-wide rail at 1024x768 vs. an intended ~55px)
   and pushing #ticket-actions/#close-ticket down far enough to overlap
   #debug-panel below the ticket rail - the exact `#debug-panel
   intercepts pointer events` failure mode this codebase has hit before.
   UX63/UX52 (docs/backlog.md): the ORIGINAL one-row-plus-ellipsis fix for
   that bug traded one defect for another. "All paid. Ticket closed." and
   "Nothing left to pay. Close this ticket?" both truncated to "All
   pai..." beside their own button at FLOOR_DEVICE's 400px rail width
   (design/reviews/pay14-screens/built-18-walkout-on-stranded-tab-*.png),
   unreadable by touch with no title-tooltip recovery allowed on a floor
   surface (CLAUDE.md). Fixed by a DELIBERATE two-row stack instead: the
   text is its own full-width row (wraps onto a second line if it must,
   never truncates), and the actions sit on their own row below it,
   right-aligned. This is not the old uncontrolled wrap: the two rows are
   fixed roles (text always on top, actions always on the bottom), so the
   height is bounded and predictable rather than depending on where a
   button happens to force a break mid-row. Neither button shrinks or
   loses its 44px floor (--touch-target-min, CLAUDE.md's touch-only
   rule); the small height this adds comes out of #ticket-lines' own
   flex-grow budget, never out of a touch target. */
.zero-due-prompt {
  margin: 0 var(--space-5) var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
}
.zero-due-prompt-text {
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  white-space: normal;
  overflow-wrap: break-word;
}
.zero-due-prompt-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-shrink: 0;
}
.zero-due-prompt-actions button {
  height: var(--touch-target-min);
  padding: 0 var(--space-3);
}

.ticket-actions {
  position: sticky;
  bottom: 0;
  z-index: 1;
  background: var(--color-surface);
  /* UX13: Prepare All and Pay now share ONE row (.action-row-primary
     below) instead of Pay owning a full-width row under a separate
     Prepare-All/Close-Ticket pair. Close Ticket is gone outright (see
     index.html's own comment on this block). No gap here: the real
     production topbar (unlike the isolated mockup's own simplified one)
     leaves this rail less room than the mockup could assume, and
     harness/e2e/ux13-ticket-rail.spec.ts measures every pixel of it, so a
     conditional child (#pay-block-reason, #no-tip-button, #pay-status)
     sits directly against whatever is above it; each already carries its
     own background/border-left so the boundary stays readable without a
     gap spending height this rail does not have.
     UX46 (docs/build-briefs/UX46-pay-divider-clearance.md): a single,
     one-time var(--space-1) (4px) top padding was added so Pay (the
     taller of the two primary-row buttons, its own top edge sitting
     flush at the row's own top edge under align-items: center) gets a
     visible gap from the divider above, matching Prepare All's own
     existing clearance. This does NOT reopen the "no gap" rule above:
     every conditional child below the primary row still stacks against
     its own neighbour with zero gap between THEM, unchanged. */
  padding: var(--space-1) var(--space-4) 0;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  border-top: 1px solid var(--color-border);
}
/* Sharing one row instead of two stacked rows is a LAYOUT change, not a
   touch-target change: neither button's own height moved (Prepare All is
   --touch-target-min, Pay is --touch-target-primary, both unchanged
   below). Stacked, the pair costs 44 + --chrome-gap-target + 64 = 116px;
   side by side they cost max(44, 64) = 64px, since --chrome-gap-target
   (8px) is spent horizontally between them instead of vertically between
   rows -- design/ux13-ticket-rail-rationale.md's own single largest
   density saving. This is the one place this rail departs from
   design/principles.md rule 2 ("Pay is a single full-width location... nothing
   else competes with it for size, color, or position"): Pay still
   dominates by size (64px vs 44px) and by color (solid accent fill vs
   Prepare All's outline below), so the hierarchy rule 2 asks for is still
   visible at a glance; only "alone on its own row" is given up. */
.action-row-primary {
  display: flex;
  align-items: center;
  gap: var(--chrome-gap-target);
}
.btn-prepare-all {
  flex: 1;
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.btn-prepare-all:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
  cursor: default;
}
/* .action-row-primary's own two-thirds share; .btn-pay's base rule below
   (height, color, shape) is shared with every other Pay-styled button in
   this file (#zero-due-close, the pay-confirm sheet's own confirm
   button), so the flex ratio stays scoped to this row rather than
   applied to .btn-pay generally. */
.action-row-primary .btn-pay {
  flex: 2;
}

.btn-pay {
  height: var(--touch-target-primary);
  border-radius: var(--radius-md);
  border: none;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  box-shadow: var(--shadow-2);
}
.btn-pay:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
}
/* UX74: the bare word "Pay" while the payment preview is out of date.
   One weight step lighter than the amount label so a lone word does not
   shout. Box, height and disabled colors are unchanged. */
.btn-pay.is-stale {
  font-weight: var(--font-weight-semibold);
}
/* Found by this task's own live Charcoal sweep (Amendment 2026-08-22),
   not by the owner's report: this read the FIXED --color-warning-strong
   as bare text with no background at all, the inverse of design/README.md's
   own rule ("never pair a semantic color with a component's own surface
   or text tokens") from the other direction, a fixed color against a
   THEME surface rather than a theme color against a fixed surface. On
   every light theme this happened to stay legible by accident
   (warning-strong is dark, light surfaces are light); measured at 2.58:1
   against Charcoal's own dark surface, well under the 4.5:1 floor. Given
   its own self-contained warning-subtle background, the same pairing
   every other warning chip in this file already uses
   (design/README.md's checked 5.4:1 ratio), so it now reads correctly
   regardless of theme surface, not just by accident on light ones. */
/* UX13: compressed from a padded, bordered banner to a left-accented
   line (design/mockups/ticket-rail-redesign-blocked.html's own
   .pay-block-reason), roughly a quarter of the previous box's height.
   Still color + shape together (design/README.md's own "never color
   alone" rule: a colored left bar, not color alone) and still its own
   row; not a tappable control, so it is not held to the 44px/8px rules
   the buttons above it are. */
.pay-block-reason {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-left: 3px solid var(--color-warning-strong);
  padding: var(--chrome-gap-hairline) var(--space-2) var(--chrome-gap-hairline) var(--space-3);
}
/* UX74-F1 (DEC-286, design/mockups/ux74-f1-preview-failed.html): the
   failed reading of the Pay block. Same left-bar shape as
   .pay-block-reason in the danger pair, text on the left and one 48px
   Try again button on the right. Words carry it, colour helps. Touch
   only: no hover rule, no animation. */
.pay-fail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  background: var(--color-danger-subtle);
  border-left: 3px solid var(--color-danger-strong);
  color: var(--color-danger-strong);
}
.pay-fail[hidden] {
  display: none;
}
.pay-fail-text {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-semibold);
}
.btn-retry {
  flex: none;
  min-width: 120px;
  height: 48px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-danger-strong);
  color: var(--color-danger-strong);
  font-family: inherit;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
}
.pay-status {
  text-align: center;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  padding: var(--space-2);
  border-radius: var(--radius-md);
}
.pay-status.success {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.pay-status.error {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  /* CL6-F1-F3 design review: the three-line live-money message must never clip. */
  padding-bottom: var(--space-3);
}
/* TERM2: Pending is a caution, not an error. Same tokens .badge-aging uses. */
.pay-status.warning {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
/* TERM2: a card payment waiting on a reader. Larger than the other status
   lines and a fixed minimum height, so the rail does not jump when the line
   appears or is replaced by the result. */
.pay-status.waiting {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 72px;
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-size: var(--font-size-base);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  color: var(--color-text-primary);
}
.pay-status.waiting .pay-status-lines {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pay-status.waiting .pay-status-title {
  font-weight: var(--font-weight-bold);
}
.pay-status.waiting .pay-status-hint {
  font-weight: var(--font-weight-medium);
}
.pay-status-spinner {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  border: 3px solid var(--color-accent-subtle-border);
  border-top-color: var(--color-accent-strong);
  animation: pay-status-spin 1s linear infinite;
}
@keyframes pay-status-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .pay-status-spinner {
    animation: none;
    border-top-color: var(--color-accent-strong);
    border-right-color: var(--color-accent-strong);
  }
}
#pay-reader-cancel-button {
  min-height: var(--touch-target-min);
}

/* Design/QA gate finding F: per-maker tip split, shown right after a
   payment with a tip actually captures. Plain theme-native surface (not a
   fixed semantic background), since this is informational, not a state
   signal - ordinary --color-text-primary/--color-surface is correct here,
   unlike the warn-/status- banners' fixed-background pairs above. */
.pay-tip-split {
  margin-top: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.pay-tip-split-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: var(--space-2);
}
.pay-tip-split-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  padding: var(--space-1) 0;
}

/* ---------- Debug / session panel (staff/admin only, never shown to a
   customer). Carries the provisional-tax label per
   docs/decision-proposals/provisional-pricing-config.md wherever a rate
   (not just a dollar amount) is displayed. ---------- */

.debug-panel {
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  padding: var(--space-2) var(--space-5);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  flex-shrink: 0;
}
.debug-panel summary {
  cursor: pointer;
  padding: var(--space-2) 0;
}
.debug-panel dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0 0 var(--space-3);
}
.debug-panel dt {
  color: var(--color-text-tertiary);
}
.debug-panel dd {
  margin: 0;
  font-family: ui-monospace, monospace;
}

/* ---------- Liquor sheet ---------- */

.scrim {
  position: fixed;
  inset: 0;
  background: var(--color-scrim);
  z-index: var(--z-scrim);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}
.sheet {
  background: var(--color-surface);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--shadow-3);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 640px;
  max-height: min(720px, 92vh);
  z-index: var(--z-sheet);
}
.sheet-header {
  padding: var(--space-5) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.sheet-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}
.sheet-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}

/* INV26 Slice 2 (DEC-206 item 3): Backbar-style item-detail tabs, ported
   from design/mockups/inv26-inventory-backbar.html's own <style> block
   (the owner-approved mockup, DEC-207: "Good mockup design. Approved."),
   built on this file's own tokens rather than the mockup's hardcoded
   values. Scoped to #admin-bottle-form-sheet's own tab bar and its three
   panels; no other sheet in this file uses these classes. */
.item-tabs {
  display: flex;
  gap: var(--space-8);
  margin-top: var(--space-4);
}
.item-tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: none;
  border: none;
  padding: 0 0 var(--space-3);
  font-size: var(--font-size-base);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  min-height: var(--touch-target-min);
}
.item-tab.active {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-bold);
  border-bottom-color: var(--color-accent-strong);
}
/* INV27 (docs/build-briefs/INV27-item-editor-redesign.md; DEC-227 item
   1), ported from design/mockups/inv27-item-editor.html's own <style>
   block: the numbered-tab badge ("1", "2", "3") each tab label now
   carries, per the owner's approved "manager's own setup order" design. */
.item-tab .tab-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.item-tab.active .tab-num {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
/* INV27 (DEC-227 item 1): the add-another-vendor-offer mini-form's own
   separated, headed card (Stock & vendor tab), so its blank Vendor SKU
   input reads as a new entry rather than as a broken echo of the SKU
   already shown in the existing-offer list above it. INV27 coordinator
   review, 2026-09-29: a genuinely separate, bordered card (matching
   .pricing-current-card's own visual language just below), not a
   dashed divider line -- the mockup's own dashed-top-border treatment
   (this rule's original ported form) read as too weak a separation once
   built, so its blank Vendor SKU input still risked reading as
   continuous with the existing offer row above it rather than as its
   own distinct "add a new one" section. */
.add-offer-card {
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-top: var(--space-5);
}
.add-offer-heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-1);
}
.add-offer-plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}
/* INV27 (DEC-227 item 1): "What we charge today" card, Pricing tab, sell
   price and pour options at the top directly above the calculator that
   explains them. Ported from the same mockup's own <style> block. */
.pricing-current-card {
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
}

/* Price calculator tab panel (INV26 Slice 3), ported from
   design/mockups/inv26-inventory-backbar.html's own <style> block (the
   owner-approved mockup, DEC-207: "Good mockup design. Approved."),
   built on this file's own tokens rather than the mockup's hardcoded
   values, the identical porting convention the Inventory information
   tab panel's own comment below already states. */
.calc-grid {
  display: grid;
  grid-template-columns: 160px 1fr 1fr;
  column-gap: var(--space-8);
  row-gap: var(--space-2);
  max-width: 640px;
}
.calc-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  padding-bottom: var(--space-2);
}
.calc-head-unit {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
/* INV27 (DEC-227 item 1): "Saves here" badge, marking whichever
   calculator column (per fl oz or per bottle) Save actually writes on
   this item's own sale mechanism. Only one column ever carries it at a
   time; the other renders no badge at all (hidden), rather than a dimmed
   or negated one, matching this file's own "state you can see before you
   touch it" convention. */
.calc-saves-badge {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-2);
}
/* INV27 coordinator review, 2026-09-29: the column that does not save
   (e.g. per bottle for a per-ounce item) reads as reference-only, never
   as a real price. Ported from the mockup's own <style> block. */
.calc-head-nosave {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.calc-cell.dimmed {
  opacity: 0.55;
}
.calc-row-label {
  display: flex;
  align-items: center;
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
  height: var(--touch-target-comfortable);
}
.calc-cell {
  display: flex;
  align-items: center;
}
.calc-value-readonly {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  padding: 0 var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}
.calc-value-editable {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  display: flex;
  align-items: center;
  padding: 0 var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}
.calc-value-editable:focus-within {
  box-shadow: var(--shadow-focus);
  border-color: var(--color-accent-strong);
}
.calc-value-editable input {
  border: none;
  background: none;
  padding: 0;
  width: 100%;
  font: inherit;
  color: inherit;
  /* The parent .calc-value-editable already shows the focus ring via its
     own box-shadow on :focus-within, so the input's native focus outline
     is suppressed here rather than left to stack on top of it (found in
     the ui-ux-designer's built-screen review, doubled ring on the
     per-bottle target markup % field). */
  outline: none;
  /* type="number" spinner arrows, suppressed consistently for both
     columns (found in the ui-ux-designer's built-screen review: the
     per-bottle field showed spinners while the per-ounce field did not,
     an inconsistency rather than an intended difference -- neither
     calculator input needs a spinner, since both take a percent typed on
     the numeric keypad). */
  -moz-appearance: textfield;
}
.calc-value-editable input::-webkit-outer-spin-button,
.calc-value-editable input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.calc-value-derived {
  width: 100%;
  height: var(--touch-target-comfortable);
  display: flex;
  align-items: center;
  padding: 0 var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  border-bottom: 1px solid var(--color-border);
}
.calc-help {
  margin: var(--space-5) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  max-width: 640px;
}
/* Save is its own primary action inside this tab, sized like every other
   .btn-primary, not full-width like the sheet-wide "Save item" footer
   button: this is a secondary, tab-scoped save, not the primary action
   for the whole sheet. .btn-primary:disabled already gives it the
   "visibly blocked" treatment design principle 3 requires; the reason it
   is blocked renders in .calc-save-reason immediately below it. */
.calc-save-btn {
  margin-top: var(--space-5);
  padding: 0 var(--space-6);
}
.calc-save-reason {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  max-width: 640px;
}
.calc-save-reason:empty {
  display: none;
}

/* Inventory information tab panel */
.inv-info-grid {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
}
.inv-info-media {
  flex: 1 1 100%;
}
.inv-photo-placeholder {
  width: 220px;
  height: 220px;
  border-radius: var(--radius-lg);
  border: 1px dashed var(--color-border-strong);
  background: var(--color-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  padding: var(--space-4);
}
.inv-onhand-block {
  margin-top: var(--space-4);
  /* DOCSBUG4 (design/mockups/docsbug4-reverse-movement-list.html): On hand on
     the left, Record movement on the right, the Recent movements list
     beneath. The sheet is never wide enough to seat the field column beside
     this one, so the column spans the row. */
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: var(--space-4);
  align-items: center;
}
.inv-onhand-block > .inv-onhand-label,
.inv-onhand-block > .inv-onhand-value {
  grid-column: 1;
}
.inv-onhand-block > .admin-onhand-warning {
  grid-column: 1 / -1;
}
.inv-onhand-block > .admin-record-movement-button {
  grid-column: 2;
  grid-row: 1 / span 2;
  width: auto;
  min-width: 160px;
}
.inv-onhand-block > [hidden] {
  display: none;
}
.inv-onhand-label {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-1);
}
.inv-onhand-value {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
  margin: 0;
}
.inv-info-fields {
  flex: 1 1 420px;
  min-width: 320px;
}

/* DOCSBUG4 (docs/build-briefs/DOCSBUG4-reverse-a-movement.md; DEC-274;
   design/mockups/docsbug4-reverse-movement-*): the Recent movements list on
   the Stock & vendor tab and the reverse dialogs. Tokens only, the same ones
   the mockups were built on. Every row carries a tag plus words for its
   state, never color alone. No hover rule anywhere: touch only. */
.inv-movements {
  flex: 1 1 100%;
  min-width: 0;
}
.admin-movements-status {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-success-subtle-border);
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.inv-movements-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}
.inv-movements-head .section-title {
  margin: 0;
}
.inv-movements-count {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.inv-movements-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}
.inv-movements-list:empty {
  display: none;
}
.inv-movement {
  display: grid;
  grid-template-columns: 1fr auto 132px;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-2) var(--space-4);
  min-height: 68px;
}
.inv-movement + .inv-movement {
  border-top: 1px solid var(--color-border);
}
.inv-movement[data-fresh="true"] {
  background: var(--color-accent-subtle);
}
.inv-movement-top {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.inv-movement-when {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.inv-movement-detail {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.inv-movement-qty {
  text-align: right;
  white-space: nowrap;
}
.inv-movement-qty b {
  display: block;
  font-size: var(--font-size-md);
  font-variant-numeric: tabular-nums;
}
.inv-movement-qty span {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.inv-movement--reversed .inv-movement-qty b {
  text-decoration: line-through;
  color: var(--color-text-tertiary);
}
.inv-movement-act {
  display: flex;
  justify-content: flex-end;
}
.inv-movement-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.inv-movement-act .inv-movement-tag {
  width: 100%;
  min-height: 32px;
}
.inv-movement-tag--ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.inv-movement-tag--info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
  color: var(--color-info);
}
.inv-movement-reverse {
  width: 100%;
  min-height: var(--touch-target-min);
  color: var(--color-accent-strong);
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
}
.inv-movements-older {
  width: 100%;
  min-height: var(--touch-target-min);
  margin: var(--space-3) 0;
}
@media (max-width: 640px) {
  .inv-movement {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "main qty"
      "act act";
  }
  .inv-movement-main {
    grid-area: main;
  }
  .inv-movement-qty {
    grid-area: qty;
  }
  .inv-movement-act {
    grid-area: act;
    justify-content: flex-start;
  }
  .inv-movement-reverse {
    width: auto;
    min-width: 160px;
  }
  .inv-movement-act .inv-movement-tag {
    width: auto;
    padding: 0 14px;
  }
}
.admin-reverse-ba {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-3);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.admin-reverse-ba-label {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.admin-reverse-ba-value {
  display: block;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.admin-reverse-ba-arrow {
  font-size: var(--font-size-xl);
  color: var(--color-text-tertiary);
}
.admin-reverse-orig {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-5);
  font-size: var(--font-size-sm);
  margin: 0 0 var(--space-4);
}
.admin-reverse-orig dt {
  color: var(--color-text-tertiary);
}
.admin-reverse-orig dd {
  margin: 0;
  font-weight: var(--font-weight-medium);
}
.admin-reverse-orig [hidden] {
  display: none;
}
/* AU14-F14: the required reason on the reverse confirm. Chips wrap rather than
   shrink below the touch floor; the amber line and the Pick one state reuse the
   approved reason sheet's own look (.po-required, .admin-onhand-warning). */
.admin-reverse-reason {
  margin: 0 0 var(--space-4);
}
.admin-reverse-reason-heading {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.admin-reverse-reason-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* While the reason is still to be picked, the two plain notes below the picker
   stay out of the way: with the amber line showing they ran partly under the
   footer. They read in full the moment a reason is picked, before the button wakes. */
.admin-reverse-reason:has([data-testid="admin-reverse-reason-blocked"]:not([hidden]))
  ~ .admin-reverse-note {
  display: none;
}
.admin-reverse-reason .admin-onhand-warning {
  margin-top: var(--space-3);
}
.admin-reverse-reason [hidden] {
  display: none;
}
/* DOCSBUG4: the reverse confirm rides on the shared confirm sheet. Its lead
   sentence reads larger than an ordinary confirm message, and its accent
   primary takes the room the danger button takes in the other callers. */
.admin-confirm-body .admin-confirm-message--lead {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: 1.35;
  margin: 0 0 var(--space-4);
}
.admin-confirm-body .admin-confirm-message--refusal {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.admin-confirm-actions #admin-confirm-confirm.btn-primary {
  flex: 1;
}
#admin-confirm-extra .admin-reverse-note:last-child {
  margin-bottom: 0;
}
.admin-confirm-body .admin-reverse-note {
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-3);
}
.field-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--space-6);
}
.vendor-manage-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-2);
  background: none;
  border: none;
  padding: 0;
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  min-height: var(--touch-target-min);
}
.provenance-note {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.sheet-subtitle {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.required-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-3);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
}

.search-row {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.search-input {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  padding: 0 var(--space-4);
  color: var(--color-text-primary);
}
.search-input::placeholder {
  color: var(--color-text-tertiary);
}

.liquor-list {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-2) var(--space-3) var(--space-4);
}
.liquor-empty {
  padding: var(--space-6) var(--space-3);
  color: var(--color-text-secondary);
  text-align: center;
}
/* VOC1-F3: the Recent strip above the liquor list. Five equal chips, 64px tall. */
.liquor-recent {
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.liquor-recent[hidden] {
  display: none;
}
.liquor-recent-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  padding-bottom: var(--space-1);
}
.liquor-recent-chips {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-2);
}
.liquor-recent-chip {
  min-height: 64px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  text-align: left;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2px;
  cursor: pointer;
}
.liquor-recent-chip.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
}
.liquor-recent-chip-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.liquor-recent-chip-price {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-bold);
}
.liquor-group-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  padding: var(--space-3) var(--space-2) var(--space-2);
}
.liquor-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  text-align: left;
}
.liquor-row + .liquor-row {
  margin-top: 2px;
}
.liquor-row.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
/* Amendment 2026-08-22 (item 2) fallout, caught in this task's own live
   Charcoal sweep, not by the owner's report: .liquor-name/.liquor-price/
   .liquor-type normally read the ambient --color-text-primary/secondary/
   tertiary tokens, which is correct against the row's usual transparent
   background. Once selected, the row's OWN background switches to
   --color-accent-subtle, and every theme's accent-subtle is now light
   (this item made Charcoal's light too, matching the other three), while
   Charcoal's own text-primary/secondary/tertiary stay light-on-dark
   colors. Before this item, Charcoal's accent-subtle was dark, so the
   ambient light text colors happened to still read correctly against it;
   flipping it light for the badge/pill fix elsewhere in this same item
   silently broke this specific spot the same way the item's own Finding 1
   broke text-on-button, just newly introduced rather than inherited. On
   every light theme this was already accidentally fine (text-primary is
   already dark there), which is exactly why nothing else in this sweep
   caught it. Fixed the same way every other accent-subtle pairing in this
   file already is: explicit, self-contained accent-strong text, dark and
   readable on the now-uniformly-light accent-subtle on every theme,
   never left to inherit whatever the ambient (theme-relative) text color
   happens to be. */
.liquor-row.selected .liquor-name,
.liquor-row.selected .liquor-price,
.liquor-row.selected .liquor-type,
.liquor-row.selected .liquor-spirit-type,
.liquor-row.selected .liquor-price-final,
.liquor-row.selected .liquor-price-diff {
  color: var(--color-accent-strong);
}
.liquor-check {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--color-border-strong);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: transparent;
}
.liquor-row.selected .liquor-check {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.liquor-name-block {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.liquor-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  color: var(--color-text-primary);
}
.liquor-type {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
/* VOC1-F2 (docs/build-briefs/VOC1-F2-liquor-sheet-shows-each-options-
   final-price.md, Section 2.1). DEC-162's own "spirit type... shows per
   row under it": the same categoryLabel text the group heading above
   already shows, repeated per row since a bartender scanning a mixed
   or browsed list reads a row's own type, not only the group it sits
   under. Text-only (never a title tooltip, check:touch-only). */
.liquor-spirit-type {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
/* VOC1-F2. The right-aligned price column now stacks two lines: the
   final drink price this row would produce, and (beneath it) the
   difference from the cheapest option in the list, blank for the
   cheapest row itself -- never a $0.00 label (Section 2.1). */
.liquor-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
  gap: 1px;
}
.liquor-price-final {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
/* Section 2.4's second fallback: a row this load's batch could not price.
   Warning-colored so it reads as "needs attention" rather than a normal
   price, matching .line-price.unavailable's own established pairing;
   never color alone, since the words "Price unavailable" are the text
   content itself. */
.liquor-price-final.unavailable {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
.liquor-price-diff {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  white-space: nowrap;
}

/* VOC1-F5 Slice 1/2 (docs/build-briefs/VOC1-F5-stock-states-on-the-floor-
   and-86-blocks-selection.md, Section 2). Shared between the liquor-sheet
   row and the non-cocktail menu tile, text-only (never color alone, per
   this item's own false-greens list): the badge's own word ("Low",
   "Out", "86'd") is always present in the DOM's text content, the color
   pairing below is a reinforcement, never the sole signal. Reuses
   .tile-kind-badge's/.pay-block-reason's own accent-pair shape rather
   than inventing a third. */
.stock-state-badge {
  flex-shrink: 0;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: var(--line-height-tight);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
/* UX45 Section 2a (docs/build-briefs/UX45-liquor-tile-badge-grouping.md,
   real-app redesign): same tight-pull margin as .tile-kind-badge above,
   scoped to .tile > deliberately -- .stock-state-badge also renders
   inside .liquor-row (a ROW-direction flex layout in the liquor-picker
   sheet, unrelated to this defect, sharing only the class name), and an
   unscoped edit to the shared base rule above would reach that context
   too, for no reason connected to this item. */
.tile > .stock-state-badge {
  margin-bottom: calc(var(--space-1) - var(--space-3));
}
.stock-state-badge--low {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
/* UX110: a liquor pour card's bottom row has the shelf name bottom left and the price bottom right (the price
   alone sits bottom right when no shelf is assigned). Cocktail cards keep the price left, clear of the Recipe button. */
.tile-price-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
  margin-top: auto;
}
.tile-price-row > .tile-price {
  margin-top: 0;
}
.tile-price-row--pour > .tile-price {
  margin-left: auto;
  flex-shrink: 0;
  text-align: right;
  white-space: nowrap;
}
.tile-shelf {
  min-width: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stock-state-badge--out,
.stock-state-badge--flagged {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
}
/* Slice 2: the real `disabled` attribute on a flagged .liquor-row/.tile,
   not a class; this is purely the visual companion to that attribute. */
.liquor-row:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ALPHA-10 item 2, 2026-08-20 amendment: the explicit "More spirits"
   expansion into every active liquor. Deliberately plainer than
   .btn-add/.btn-primary (secondary-styled, full-width, sits inside the
   scrollable sheet body rather than the footer) so tapping it reads as
   "look further," not as the drink's own default confirm action. */
.btn-more-spirits {
  width: 100%;
  min-height: var(--touch-target-comfortable);
  margin-top: var(--space-2);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px dashed var(--color-border-strong);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
/* Replaces .btn-more-spirits once tapped (main.ts's handleMoreSpiritsClick
   hides one and shows the other): a persistent, plain-language reminder
   that the sheet is now showing every active liquor, not just this
   drink's usual categories, for as long as the sheet stays open. */
.substitution-note {
  margin: var(--space-2) var(--space-3) 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}

/* ---------- MyTime track (track/mytime) Slice 2: Add Guest client
   search (index.html's #add-guest-sheet), amendment 2026-08-23
   (nineteenth). Result rows mirror .liquor-row's own shape (same
   min-height, same selected/tap styling family) so the search-and-tap
   feel is consistent with the liquor picker's already-shipped, already
   touch-tested pattern rather than inventing a second one. ---------- */
.add-guest-freshness {
  margin-top: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.add-guest-freshness.stale {
  color: var(--color-warning-text);
}
.add-guest-results {
  max-height: 320px;
  overflow-y: auto;
  padding: var(--space-2) var(--space-3) 0;
}
.add-guest-result-row {
  display: flex;
  /* UX42 (docs/build-briefs/UX42-add-guest-long-name.md): flex-start, not
     center, so a two-line wrapped name does not vertically center against
     its shorter siblings (the phone tail, the badge column). */
  align-items: flex-start;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  text-align: left;
}
.add-guest-result-row + .add-guest-result-row {
  margin-top: 2px;
}
.add-guest-result-row:active {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
.add-guest-result-name-block {
  flex: 1;
  min-width: 0;
}
.add-guest-result-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  color: var(--color-text-primary);
  /* UX42: was a single-line text-overflow: ellipsis clip, which cut two
     similar long guest names to the identical string before either could
     be told apart, and tapping a row adds that guest immediately (no
     preview step). Wraps to up to two lines instead; a name still too
     long for two lines ends in an ellipsis at the end of line 2, the
     standard multi-line-clamp technique, so nothing is silently cut with
     no sign more text exists. */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.add-guest-result-phone {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.add-guest-result-badges {
  /* UX42: stacked under the name instead of beside it, so badges (which
     never shrink, flex-shrink: 0 below) never take width away from the
     name. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  flex-shrink: 0;
  margin-top: 2px;
}
.add-guest-badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: var(--line-height-tight);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.add-guest-badge-member {
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
}
.add-guest-badge-provisional {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
.add-guest-results-empty {
  padding: var(--space-4) var(--space-3);
  color: var(--color-text-secondary);
  text-align: center;
  font-size: var(--font-size-sm);
}
.add-guest-results-hint {
  padding: var(--space-4) var(--space-3);
  color: var(--color-text-tertiary);
  text-align: center;
  font-size: var(--font-size-sm);
}
/* Mirrors .btn-more-spirits's own "plainer, dashed, full-width, lives in
   the scrollable body" shape, for the identical reason: this is a
   secondary path (offered only once search has already come up empty),
   not the sheet's default confirm action. */
.btn-new-client {
  width: 100%;
  min-height: var(--touch-target-comfortable);
  margin: var(--space-2) var(--space-3) 0;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px dashed var(--color-border-strong);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.add-guest-new-client-help {
  margin: var(--space-4) var(--space-5) var(--space-2);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.add-guest-divider {
  margin: var(--space-4) var(--space-5) 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  text-align: center;
}

/* UX51: character counter under the free-text guest label. Quiet by
   default (tertiary text, chrome type scale per DEC-053); switches to
   the fixed warning pair once the input is within 5 characters of
   maxlength=40, so the limit is visible before it is hit rather than
   only discovered when typing silently stops. */
.add-guest-label-counter {
  margin: var(--space-1) var(--space-5) 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
  text-align: right;
}
.add-guest-label-counter.add-guest-label-counter-near-limit {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-medium);
}

.sheet-footer {
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: 1px solid var(--color-border);
  flex-shrink: 0;
  background: var(--color-surface);
}
.price-preview {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}
.price-preview-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.price-preview-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
}
.price-preview-value.placeholder {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.price-breakdown {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-3);
  min-height: 1em;
}
/* VOC1-F7 Slice 2 (docs/build-briefs/VOC1-F7-cocktail-pour-modifier.md,
   Section 2.5): plain-button chips, each a real >=44px touch target
   (--touch-target-min), matching .admin-chip-option's own comment on why a
   chip needs a real target rather than a compressed label. Wraps onto a
   second row rather than shrinking below that floor when a product carries
   several configured sizes. */
.pour-size-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.pour-size-chip {
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
/* Selected-chip pairing mirrors .liquor-row.selected's own accent-subtle/
   accent-strong pair exactly (this file's own established selected-state
   convention), never color alone: the recipe-default chip's "(standard)"
   text and the selected chip's own border are both still legible without
   relying on the accent hue. */
.pour-size-chip.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
/* VOC1-F4 (docs/build-briefs/VOC1-F4-drink-modifier-catalog.md, Section
   2.5): mirrors .pour-size-row/.pour-size-chip exactly -- the identical
   plain-button chip shape, each a real >=44px touch target
   (--touch-target-min), wrapping onto a second row rather than shrinking
   below that floor when a drink carries several attached modifiers. */
.modifier-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.modifier-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.modifier-chip-label {
  font-weight: var(--font-weight-medium);
}
.modifier-chip-price {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
/* Selected-chip pairing mirrors .pour-size-chip.selected's own
   accent-subtle/accent-strong pair exactly, never color alone: a
   required-but-unpicked chip is still distinguished by its own "(Required)"
   text, not only by the absence of this selected styling. */
.modifier-chip.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.modifier-chip.selected .modifier-chip-price {
  color: var(--color-accent-strong);
}
/* VOC1-F4 (Section 2.5): the ticket line's own applied-modifier badges,
   mirroring .line-badge-pour's info-toned, non-truncating shape exactly,
   so a manager reading the ticket rail never infers which modifiers were
   applied from price alone. */
.line-modifiers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}
.line-badge-modifier {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
}
.btn-add {
  width: 100%;
  height: var(--touch-target-primary);
  border-radius: var(--radius-md);
  border: none;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.btn-add.enabled {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
}
.btn-add.disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
}

/* ---------- UX14 (docs/build-briefs/UX14-floor-density.md, DEC-314) ----------
   The top-anchored sheet shell. A sheet that opens the on-screen keyboard is
   anchored to the TOP of the screen, --sheet-edge-gap down, never to the
   bottom: the keyboard rises from the bottom, so the field and the confirm
   button have to live in the top --keyboard-safe-height (design/tokens.css,
   PROVISIONAL 420px). Opt in with .scrim-top on the scrim. */
.scrim.scrim-top {
  align-items: flex-start;
  padding-top: var(--sheet-edge-gap);
}
.scrim.scrim-top .sheet {
  border-radius: var(--radius-xl);
  max-height: calc(100vh - var(--sheet-edge-gap));
}
/* UX102 (click-through review, Floor top-anchored sheets): the sheet stays 24px from the top, because a sheet that
   opens the keyboard has to fit the top 420px (--keyboard-safe-height), but the header band under the scrim is
   covered, so no half-clipped brand or title text peeks out above the sheet. The band is the page colour under the
   same dim as the rest of the scrim, so it reads as dimmed page, with nothing drawn on it. */
.scrim.scrim-top::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--topbar-height);
  background: linear-gradient(var(--color-scrim), var(--color-scrim)), var(--color-bg);
}

/* Liquor sheet. Title row 56px; the pour line and status flag share one
   row; search and More spirits share one row; rows are one 48px line (the
   spirit type is the group heading, kept on a search result); one footer
   that never changes height on a pick (price, breakdown and pour chips on
   one row, Add to Ticket under them). */
#liquor-sheet {
  max-width: 960px;
}
#liquor-sheet .sheet-header {
  min-height: var(--sheet-header-height);
  display: flex;
  align-items: center;
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-4);
}
#liquor-sheet .sheet-title-row {
  width: 100%;
  align-items: center;
}
#liquor-sheet .sheet-title {
  min-width: 0;
}
.liquor-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-4) var(--space-2);
  flex-shrink: 0;
}
.liquor-sub .sheet-subtitle {
  margin-top: 0;
  min-width: 0;
}
.liquor-sub .required-flag {
  margin-top: 0;
  /* A long liquor name wraps inside the flag rather than pushing the pour line
     out (designer polish L5). */
  flex-shrink: 1;
  max-width: 62%;
  white-space: normal;
}
.required-flag.chosen {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}
.liquor-search-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.liquor-search-line .search-row {
  flex: 1;
  min-width: 0;
  padding: 0;
  border-bottom: none;
}
.liquor-search-line .search-input {
  height: 48px;
}
.liquor-search-line .btn-more-spirits {
  width: auto;
  margin-top: 0;
  min-height: 48px;
  flex-shrink: 0;
  border-style: solid;
  padding: 0 var(--space-4);
}
#liquor-sheet .substitution-note {
  margin: var(--space-1) var(--space-4) 0;
  padding: var(--space-1) var(--space-3);
  flex-shrink: 0;
}
#liquor-sheet .liquor-list {
  padding: 0 var(--space-2);
  min-height: 0;
}
#liquor-sheet .liquor-group-title {
  padding: var(--space-2) var(--space-3) var(--space-1);
}
#liquor-sheet .liquor-row {
  min-height: 48px;
  padding: 0 var(--space-3);
}
#liquor-sheet .liquor-name-block {
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-2);
}
#liquor-sheet .liquor-name {
  font-size: var(--font-size-md);
}
#liquor-sheet .liquor-price {
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-3);
}
#liquor-sheet .liquor-price-final {
  min-width: 64px;
  text-align: right;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
#liquor-sheet .liquor-price-diff {
  /* Fixed width, right aligned (designer polish L3/L4): the final price's
     right edge is then the same on every row whatever the difference reads. */
  flex: 0 0 72px;
  width: 72px;
  text-align: right;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#liquor-sheet .liquor-row .stock-state-badge {
  align-self: center;
}
#liquor-sheet .sheet-footer {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: var(--space-3);
  row-gap: var(--space-2);
  padding: var(--space-2) var(--space-4) var(--space-3);
}
#liquor-sheet .price-preview {
  grid-column: 1;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  height: var(--touch-target-comfortable);
  margin-bottom: 0;
}
#liquor-sheet .price-preview-label {
  font-size: var(--font-size-xs);
  line-height: 1.2;
}
#liquor-sheet .price-preview-value {
  line-height: 1;
}
#liquor-sheet .price-breakdown {
  grid-column: 2;
  margin-bottom: 0;
  min-height: 0;
  /* Designer polish L3/L4: --font-size-sm (15px), up from --font-size-xs
     (13px) in tertiary grey, so the arithmetic behind the price reads. */
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#liquor-sheet .pour-size-row {
  grid-column: 3;
  flex-wrap: nowrap;
  margin-bottom: 0;
}
#liquor-sheet .modifier-row {
  grid-column: 1 / -1;
  margin-bottom: 0;
}
#liquor-sheet .btn-add {
  grid-column: 1 / -1;
}
/* Keyboard up (height-keyed, a margin above --keyboard-safe-height): keep
   the field, a few rows and Add to Ticket on screen by dropping the
   breakdown sentence and trimming the chrome. The price and the pour chips
   stay. */
@media (max-height: 520px) {
  #liquor-sheet .price-breakdown {
    display: none;
  }
  #liquor-sheet .price-preview {
    height: var(--touch-target-comfortable);
  }
  #liquor-sheet .sheet-footer {
    padding-top: var(--space-1);
    padding-bottom: var(--space-2);
    row-gap: var(--space-1);
  }
  /* One footer row: price, pour chips and Add to Ticket side by side. */
  #liquor-sheet .sheet-footer {
    grid-template-columns: auto auto 1fr;
  }
  #liquor-sheet .price-preview,
  #liquor-sheet .pour-size-row,
  #liquor-sheet .btn-add {
    grid-row: 1;
  }
  #liquor-sheet .pour-size-row {
    grid-column: 2;
  }
  #liquor-sheet .modifier-row {
    grid-row: 2;
  }
  #liquor-sheet .btn-add {
    grid-column: 3;
    height: var(--touch-target-comfortable);
  }
  .liquor-sub {
    padding-top: 0;
    padding-bottom: var(--space-1);
  }
}

/* ---------- UX14 (DEC-314): the counting sheet ----------
   Counting follows the floor rule (it is done walking the shelves with the
   device). A 56px title row holding the title, the progress text and Review
   and close, a 4px progress line, the product name beside its quantity
   field, one footer row, anchored to the top (.scrim-top) so the quantity
   field stays above the keyboard. */
#admin-count-session-sheet {
  max-width: 960px;
}
#admin-count-session-sheet .sheet-header {
  padding: var(--space-1) var(--space-3) var(--space-2) var(--space-4);
}
#admin-count-session-sheet .sheet-title-row {
  align-items: center;
  min-height: calc(var(--sheet-header-height) - var(--space-3));
}
#admin-count-session-sheet .admin-count-progress {
  margin: 0;
  white-space: nowrap;
}
#admin-count-session-sheet .admin-count-review-link {
  width: auto;
  margin: 0 0 0 auto;
  min-height: var(--touch-target-min);
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  white-space: nowrap;
}
#admin-count-session-sheet .admin-count-progress-track {
  height: 4px;
  margin-top: 0;
}
#admin-count-session-sheet .admin-count-governance-row {
  margin-top: var(--space-2);
}
#admin-count-session-sheet .admin-count-governance-row .btn-secondary {
  height: var(--touch-target-min);
  min-height: var(--touch-target-min);
}
#admin-count-session-body {
  padding: var(--space-2) var(--space-4);
}
#admin-count-walk-content {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--space-3);
}
#admin-count-walk-content > .field-label {
  margin: 0;
}
#admin-count-section-picker {
  flex: 1 1 0;
  min-width: 0;
  margin-bottom: 0;
}
#admin-count-session-sheet .admin-count-product-card {
  flex: 1 1 100%;
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 40%);
  column-gap: var(--space-4);
  align-items: center;
}
#admin-count-session-sheet .admin-count-product-name {
  grid-column: 1;
  grid-row: 1;
  align-self: end;
  font-size: var(--font-size-lg);
}
#admin-count-session-sheet .admin-count-product-status {
  grid-column: 1;
  grid-row: 2;
  align-self: start;
  margin: 0;
}
#admin-count-quantity-label {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
}
#admin-count-session-sheet .admin-count-quantity-input {
  grid-column: 2;
  grid-row: 2 / span 2;
  align-self: start;
  margin: 0;
}
#admin-count-session-sheet #admin-count-unit-picker {
  grid-column: 1;
  grid-row: 3;
  margin: var(--space-2) 0 0;
}
#admin-count-session-sheet .sheet-footer {
  padding: var(--space-2) var(--space-4) var(--space-3);
}

/* ---------- UX14 (DEC-314): the Count stock page ----------
   The "COUNT" heading and the "Counting mode" label only repeat what the
   controls say (the mode choice keeps its aria-label), so they go; the mode
   choice and Start a count share one row; Past counts move up. */
#admin-screen[data-ops-view="counts"] .ops-view-header {
  margin-bottom: var(--space-2);
}
#admin-screen[data-ops-view="counts"] .ops-view-heading .admin-page-subtitle {
  margin: 0;
}
#admin-counts-panel > .section-title:first-child,
#admin-counts-start-mode-label {
  display: none;
}
#admin-counts-start-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
#admin-counts-start-row .admin-chip-select {
  margin-bottom: 0;
}
#admin-counts-start-button {
  width: auto;
  flex: 1 1 0;
}
#admin-counts-start-empty {
  flex: 1 1 100%;
  margin: 0;
}
#admin-counts-panel .section-title {
  margin: var(--space-3) 0 var(--space-2);
}

/* ---------- UX14 (DEC-314): Edit Line and the void reasons ----------
   Secondary actions share rows instead of each taking a full-width row
   (DEC-053's third shape), and the drink name joins the title's own row.
   Same words, same order, same notices. */
#line-edit-sheet {
  max-width: 760px;
}
#line-edit-sheet .sheet-header,
.choice-sheet-two-col .sheet-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: var(--space-3);
  min-height: var(--sheet-header-height);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-4);
}
#line-edit-sheet .sheet-title-row,
.choice-sheet-two-col .sheet-title-row {
  display: contents;
}
#line-edit-sheet .sheet-title,
.choice-sheet-two-col .sheet-title {
  grid-column: 1;
  grid-row: 1;
}
#line-edit-sheet .sheet-subtitle,
.choice-sheet-two-col .sheet-subtitle {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  min-width: 0;
}
#line-edit-sheet .sheet-header .btn-icon,
.choice-sheet-two-col .sheet-header .btn-icon {
  grid-column: 3;
  grid-row: 1;
}
#line-edit-sheet .pay-info-banner {
  margin: var(--space-2) var(--space-4) 0;
}
#line-edit-sheet .line-edit-actions {
  display: grid;
  /* CORE5 and CORE6 added Add another and Move to tab; four columns keep the common sheet at two
     rows and its UX14 height. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-4);
}
.choice-sheet-two-col {
  max-width: 760px;
}
.choice-sheet-two-col .choice-note {
  margin: var(--space-2) var(--space-4);
  padding: var(--space-2) var(--space-3);
}
.choice-sheet-two-col .choice-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  padding: 0 var(--space-4) var(--space-2);
}
.choice-sheet-two-col .sheet-footer {
  padding: var(--space-2) var(--space-4) var(--space-3);
}

/* ---------- UX14 (DEC-314): Add guest ----------
   A 56px title row, the search field, a one-line label, the name or seat
   field with its 0/40 counter inside it, one footer row, anchored to the top
   (.scrim-top) so the field and Add guest stay above the keyboard. */
#add-guest-sheet {
  max-width: 960px;
}
#add-guest-sheet .sheet-header {
  min-height: var(--sheet-header-height);
  display: flex;
  align-items: center;
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-4);
}
#add-guest-sheet .sheet-title-row {
  width: 100%;
  align-items: center;
}
#add-guest-sheet .search-row {
  padding: var(--space-2) var(--space-4);
  border-bottom: none;
}
#add-guest-sheet .add-guest-freshness {
  margin: var(--space-2) var(--space-4) 0;
}
#add-guest-sheet .add-guest-freshness:empty {
  display: none;
}
#add-guest-sheet .add-guest-results {
  /* The list shrinks with the screen so the footer stays reachable with the
     keyboard up: a cap of 320px, down to two rows. */
  max-height: clamp(96px, calc(100vh - 360px), 320px);
  padding: 0 var(--space-4);
}
#add-guest-sheet .add-guest-results:empty {
  padding: 0;
}
#add-guest-sheet .add-guest-divider {
  margin: 0 var(--space-4);
  padding-top: var(--space-1);
  border-top: none;
  text-align: left;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#add-guest-sheet .field-row {
  position: relative;
  padding: var(--space-1) var(--space-4) var(--space-2);
}
#add-guest-sheet #add-guest-label-input {
  padding-right: 72px;
}
#add-guest-sheet .add-guest-label-counter {
  position: absolute;
  right: calc(var(--space-4) + var(--space-3));
  top: 50%;
  transform: translateY(-65%);
  margin: 0;
  pointer-events: none;
}
#add-guest-sheet .sheet-footer {
  padding: var(--space-2) var(--space-4) var(--space-3);
}

/* ---------- Pay confirm sheet (ALPHA-07) ----------
   Shares .scrim/.sheet/.sheet-header/.sheet-title-row/.sheet-title/
   .sheet-footer with the liquor sheet above; only what is unique to this
   sheet is defined here. */

/* UX81: the test-payment badge sits on the title line, and the pay sheet's
   header and footer use tighter vertical padding, to leave the Charging now
   box its floor. Scoped to the pay sheet; other sheets keep the shared rules. */
.pay-confirm-sheet .sheet-header {
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.pay-confirm-sheet .sheet-title-row {
  align-items: center;
  /* Never let a wrapping badge run into the close button. */
  flex-wrap: wrap;
}
.pay-confirm-sheet .sheet-title {
  min-width: 0;
}
.pay-confirm-sheet .simulated-badge {
  margin-top: 0;
  margin-right: auto;
}
.pay-confirm-sheet .sheet-footer {
  padding: var(--space-3) var(--space-5) var(--space-4);
}

.simulated-badge {
  /* Design gate fix (2026-08-20, finding 4): bumped from font-size-xs/
     font-weight-semibold and 3px/space-2 padding, which read as a quiet
     footnote easy to miss under location lighting. "No card charged" is also
     now duplicated onto .pay-confirm-note below the Confirm button, so a
     bartender does not depend on noticing this badge alone. */
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
}

.pay-confirm-amount {
  text-align: center;
  padding: var(--space-2) var(--space-5) var(--space-1);
}
.pay-confirm-amount-label {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.pay-confirm-amount-value {
  display: block;
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  margin-top: var(--space-1);
}

.pay-confirm-totals {
  padding: 0 var(--space-5) var(--space-2);
  border-top: none;
}

/* Design/QA gate finding D: what Pay is about to charge, listed by name,
   distinct from the totals block below it. Theme-native surface, not a
   fixed semantic background: this is informational, not a state signal. */
.pay-confirm-charging-now {
  margin: 0 var(--space-5) var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}
.pay-confirm-charging-now-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: var(--space-1);
}
.pay-confirm-charging-now-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  padding: var(--space-1) 0;
}
/* Touch-only product rule: no title-attribute-only recovery for hidden
   text (there is no hover on a touchscreen to reveal a tooltip). Wraps
   instead of truncating; this list is short (a handful of rows at most)
   and each row has room to grow, unlike the ticket rail's own tightly
   height-budgeted line layout. */
.pay-confirm-charging-now-row span:first-child {
  word-break: break-word;
}

.pay-confirm-actions {
  display: flex;
  gap: var(--space-3);
}
.pay-confirm-actions .btn-secondary {
  flex: 1;
}
.pay-confirm-actions .btn-pay {
  flex: 2;
}

/* UX14 (DEC-314): the Confirm Payment sheet in two columns on a top-anchored
   shell. Left: the amount owed, one Subtotal / Tax / Tip line and UX81's
   Charging now box (still listing the drinks, owner ruling). Right: the tip
   choices. Split moves into the title row; the footer sentence is gone. */
#pay-confirm-sheet {
  max-width: 960px;
}
.pay-confirm-sheet .sheet-header {
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-4);
  min-height: var(--sheet-header-height);
  display: flex;
  align-items: center;
}
.pay-confirm-sheet .sheet-title-row {
  width: 100%;
}
.pay-confirm-sheet .pay-confirm-split-link {
  /* A 44px hit area (designer polish P2): the box, not just its text, is
     tall and wide enough to tap. */
  width: auto;
  min-width: var(--touch-target-min);
  height: var(--touch-target-min);
  margin: 0 var(--space-2) 0 0;
  padding: 0 var(--space-4);
  white-space: nowrap;
}
.pay-confirm-sheet .pay-confirm-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: var(--space-5);
  align-content: start;
  padding: var(--space-2) var(--space-4) var(--space-2);
}
.pay-confirm-sheet .pay-confirm-body > * {
  grid-column: 1;
  min-width: 0;
}
.pay-confirm-sheet .pay-confirm-body > .tip-section {
  grid-column: 2;
  grid-row: 1 / span 8;
}
.pay-confirm-sheet .pay-confirm-body > .warn-banner,
.pay-confirm-sheet .pay-confirm-body > .ack-row,
.pay-confirm-sheet .pay-confirm-body > .pay-info-banner {
  grid-column: 1 / -1;
}
.pay-confirm-sheet .pay-confirm-amount {
  text-align: left;
  padding: 0;
}
.pay-confirm-sheet .pay-confirm-charging-now {
  margin: 0 0 var(--space-2);
}
/* Charging now keeps listing the drinks (owner ruling, DEC-314) and, at the
   full floor screen, grows to use the height the sheet has (designer polish
   P1/P2): up to what is left after the amount, the totals line, the header and
   the footer, never below UX81's cap. UX81's own cap, about two and a half
   rows so a long ticket shows a partly visible third row as the cue that the
   list scrolls, now applies only with the keyboard up, where the sheet is
   short. */
.pay-confirm-sheet .pay-confirm-body > .pay-confirm-charging-now {
  max-height: max(7.25rem, calc(100vh - 24rem));
}
/* Keyboard up (height-keyed, as the liquor sheet's rule). */
@media (max-height: 520px) {
  .pay-confirm-sheet .pay-confirm-body > .pay-confirm-charging-now {
    max-height: 7.25rem;
  }
}
.pay-confirm-sheet .pay-confirm-totals {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  padding: 0 0 var(--space-2);
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.pay-confirm-sheet .pay-confirm-totals .totals-row {
  display: flex;
  gap: var(--space-1);
  padding: 0;
  margin: 0;
}
.pay-confirm-sheet .pay-confirm-totals .totals-row + .totals-row::before {
  content: "\00b7";
  margin-right: var(--space-1);
}
.pay-confirm-sheet .tip-section {
  margin: 0;
}
@media (max-width: 899px) {
  .pay-confirm-sheet .pay-confirm-body {
    grid-template-columns: minmax(0, 1fr);
  }
  .pay-confirm-sheet .pay-confirm-body > .tip-section {
    grid-column: 1;
    grid-row: auto;
  }
}

/* ---------- Toast ----------
   Design gate fix (2026-08-20, finding 2 non-blocking correction): .toast
   used to be unconditionally styled danger-red, so a plainly good outcome
   ("Ticket closed.") read as an error. Base positioning/shape lives here;
   color comes from one of the three variant classes below, which main.ts's
   showToast always applies explicitly (see its own comment). */

/* UX47 (docs/build-briefs/UX47-toast-placement-rule.md): was bottom:
   var(--space-6), centered over the whole viewport above every sheet
   (--z-toast > --z-sheet), so a toast firing while a sheet is open could
   sit directly on top of that sheet's own bottom row, and could cover the
   ticket rail's own bottom-anchored status line when no sheet was open.
   Anchored to the top instead, clear of the topbar: every sheet in this
   product slides up from the bottom (.sheet) and the ticket rail's own
   status/action block also lives at the bottom of its surface
   (.ticket-actions, #pay-status), so a top-anchored toast can never
   overlap either one, on this screen or any other. The offset is derived,
   not a bare literal: the top bar is --topbar-height tall (56px since UX14,
   it was 68px plus a border), and var(--space-2) leaves an 8px gap below it. */
/* UX100 (UX96 review): ONE toast slot, used by the floor and by Settings. It is a fixed band directly under the
   header band (--toast-slot-top is the header's own height plus a gap), centered, and it never takes a tap: the
   slot and the toast let every pointer through to the control underneath, so a toast cannot block an input or a
   button. It adds no height to any screen, so nothing moves when a toast comes or goes (a toast that took its
   own row moved the PIN pad under the bartender's finger). With a panel open on the right (86 list, My Tips) the
   slot keeps to the dimmed menu on the left. */
:root {
  --toast-slot-top: calc(var(--topbar-height) + var(--space-2));
}
/* Where the slot's toast ends (a one line toast is about 44px tall). The sign-in cards start their content below
   it, so a toast raised there lies over nothing but the page. Open Tabs does not reserve it: UX14's density rule
   (all 12 tabs visible at once, list near the top) leaves no spare 48px. */
:root {
  --toast-slot-band: calc(var(--toast-slot-top) + 52px);
}
.toast-slot {
  position: fixed;
  top: var(--toast-slot-top);
  left: 0;
  right: 0;
  z-index: var(--z-toast);
  display: flex;
  justify-content: center;
  padding: 0 var(--space-4);
  pointer-events: none;
}
#app-shell:has(.stock86-backdrop:not([hidden])) .toast-slot {
  right: min(640px, 100vw);
}
.toast {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  max-width: 90vw;
  pointer-events: none;
}
/* text-on-dark, not text-on-accent, on both variants below: the
   background is a FIXED semantic *-strong color (design/tokens.css),
   always dark, never this theme's own accent-strong. Design/QA gate
   finding, 2026-08-21, found while verifying the new Charcoal accent red
   against toasts (Amendment 2026-08-21, eighth/ninth): on Charcoal,
   text-on-accent is dark (tuned for Charcoal's own light accent-strong),
   which against the fixed dark danger-strong/success-strong background
   rendered functionally invisible text, roughly 1.9:1. text-on-dark is
   defined on every theme to be safely light against a dark, saturated
   background, which is what a fixed *-strong color always is; swapping
   to it fixes Charcoal (now ~8:1) with no change on any other theme
   (text-on-accent was already near-white there, so the two tokens were
   already equal in value, just not in meaning). */
.toast.toast-danger {
  background: var(--color-danger-fill);
  color: var(--color-text-on-dark);
}
/* TERM3: a caution, same pair as .badge-aging. */
.toast.toast-warning {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
.toast.toast-success {
  background: var(--color-success-strong);
  color: var(--color-text-on-dark);
}
/* Neutral: --color-text-primary/--color-surface are always a verified
   high-contrast pair in every theme (design/tokens.css), so swapping them
   (dark-on-light in a light theme, light-on-dark in a dark theme) gives a
   readable neutral chip without a fourth theme-independent color pair to
   maintain. Used for a heads-up that degrades gracefully rather than an
   error (see loadCheapestLiquorPrices's toast call). */
.toast.toast-neutral {
  background: var(--color-text-primary);
  color: var(--color-surface);
}

/* ---------- Responsive: tablet portrait and phone width ----------
   Tablet landscape (1280x800, 1024x768) is the primary supported class
   and uses the two-column layout above unchanged. Below 900px the ticket
   rail stacks under the menu instead of beside it, per the ALPHA-06
   instruction to stay usable at phone width even though phone is not a
   primary target (design/README.md: "Breakpoints below tablet width" are
   an explicit gap in the design mockups; this is a functional fallback,
   not a designed phone experience). */
@media (max-width: 900px) {
  .body {
    flex-direction: column;
  }
  .ticket-rail {
    /* !important, deliberately: src/railResize.ts applies the resized/
       persisted rail width as an INLINE style (railEl.style.width), which
       normally beats any stylesheet rule regardless of media query or
       selector specificity - only an !important stylesheet declaration
       out-ranks a plain inline one. Below this breakpoint .body is a
       single stacked column (above) and .rail-resize-handle is hidden
       (its own rule below), so a leftover wide inline width from a
       previous, wider viewport must not force this narrow layout back
       into a fixed-width side column. */
    width: auto !important;
    border-top: 1px solid var(--color-border);
  }
  .menu-pane {
    min-height: 45vh;
  }
  /* Below the tablet-landscape primary target, .body is already a single
     stacked column (above), so a second topbar row is not competing with
     the ticket rail for height the way it was at 1024x768; wrapping is
     an acceptable fallback here, same as pre-fix behavior. */
  .topbar {
    flex-wrap: wrap;
  }
  .topbar-right {
    flex-wrap: wrap;
  }
}

/* ---------- ALPHA-10 item 3: manager settings screen ---------- */

.admin-page-subtitle {
  margin: 0 0 var(--space-5);
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
}

.admin-drink-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.admin-drink-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}

.admin-drink-info {
  min-width: 0;
  flex: 1;
}
.admin-drink-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.admin-drink-category {
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}

/* Amendment 2026-08-22 (tenth): bulk drink operations. */

.admin-panel-header-actions {
  display: flex;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* The per-row selection checkbox, multiselect mode only. Sized to the
   same --touch-target-min floor .ack-checkbox already establishes for a
   plain (non-toggle-switch) checkbox in this codebase. */
.admin-drink-select-checkbox {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
}

.admin-select-all-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-1);
  margin-bottom: var(--space-3);
  cursor: pointer;
}
.admin-select-all-checkbox {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
}

/* Sticky footer location, the same visual weight as the pay-confirm sheet's
   own footer: stays reachable without scrolling back up to find it after
   selecting drinks lower in a long list. */
.admin-bulk-action-bar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
}
.admin-bulk-action-buttons {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
#admin-drink-bulk-count {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

/* Plain-language progress and per-drink failure summary, persistent (not
   a toast) so a manager can review what happened after a bulk apply. */
.admin-bulk-result {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.admin-bulk-failure-list {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
}
.admin-bulk-failure-list li {
  margin-bottom: var(--space-1);
}

/* Plain toggle switch: a real checkbox input (screen-reader and keyboard
   accessible, aria-label set per row in main.ts) visually hidden behind a
   track/status pair, the whole label a single >=44px touch target. Never
   a bare unlabeled checkbox, per this screen's plain-language, 8th-grade
   staff-facing wording standard applied to a manager surface. */
.admin-toggle-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  min-height: var(--touch-target-min);
  cursor: pointer;
  /* DSC35-F2: anchors the visually hidden checkbox inside its own switch. Without a positioned ancestor its
     containing block is the page, not the scrolling #app-shell, so tapping the switch scrolled the DOCUMENT to
     reach it and the whole app slid out of view (a blank screen). Same fix UX113 made for .admin-chip-option. */
  position: relative;
}
.admin-toggle-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.admin-toggle-track {
  position: relative;
  width: 48px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  transition: background-color 0.15s ease;
  flex-shrink: 0;
}
.admin-toggle-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  transition: transform 0.15s ease;
}
.admin-toggle-input:checked ~ .admin-toggle-track {
  background: var(--color-success-strong);
}
.admin-toggle-input:checked ~ .admin-toggle-track::after {
  transform: translateX(20px);
}
.admin-toggle-input:focus-visible ~ .admin-toggle-track {
  /* Amendment 2026-08-22 (item 2) fallout, same class of bug as the
     .liquor-row.selected fix above: this was the one focus outline in
     the file built on --color-accent-strong directly instead of the
     shared --color-focus-ring convention every other :focus-visible rule
     here already uses (see the button/input/select rule near the top of
     this file and the two other :focus-visible rules below). That was
     already an inconsistency before this item; it stayed invisible only
     because the old Charcoal accent-strong happened to be light. Now
     that accent-strong is dark on every theme, this outline needs the
     token actually meant to survive landing on any surface. Switched to
     match the established convention rather than special-cased. */
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.admin-toggle-input:disabled ~ .admin-toggle-track {
  opacity: 0.7;
}
.admin-toggle-status {
  min-width: 56px;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

/* ================================================================   ALPHA-11: manager console expansion (Drinks/Bottles/Location settings
   sections, add/edit forms). Every rule below is tokens-only, same
   discipline as every rule above; touch targets never drop below
   --touch-target-min.
   ======================================================================= */

.admin-panel-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.admin-panel-header .admin-page-subtitle {
  margin: 0;
  flex: 1;
}

/* UX26 (docs/build-briefs/UX26-set-up-this-location-checklist.md): an
   additive card above the existing rail, adapted from the mockup's own
   .setup-card shape (design/mockups/settings-setup-checklist.html) to
   this file's real tokens. Admin surface, keyboard and pointer assumed. */
.admin-setup-checklist {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
}
.admin-setup-checklist-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.admin-setup-checklist-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.admin-setup-checklist-progress {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
}
#admin-setup-open {
  min-height: var(--touch-target-min);
}
#admin-setup-checklist-toggle {
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.admin-setup-checklist-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-setup-checklist-list[hidden] {
  display: none;
}
.admin-setup-checklist-step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
}
.admin-setup-checklist-step[data-state="done"] {
  opacity: 0.6;
}
.admin-setup-checklist-step-body {
  flex: 1;
  min-width: 0;
}
.admin-setup-checklist-step-title {
  font-weight: var(--font-weight-semibold);
}
.admin-setup-checklist-step-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
/* ONB2 S3: the one-line "Set up this location" banner on Open Tabs at an admin's first sign-in. */
.first-day-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.first-day-banner[hidden] {
  display: none;
}
.first-day-banner-text {
  flex: 1;
  min-width: 200px;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-setup-checklist-step-link {
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: none;
  background: none;
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

/* Settings rebuild (docs/backlog.md SET1/SET2/SET3), replacing the old
   five-tab .admin-section-nav row: a left rail of ten grouped areas plus
   a search box, so the operator sees only the group they picked instead
   of scrolling one long flat panel. Admin surface, so a keyboard and
   pointer are assumed (CLAUDE.md's scoped touch-only rule); the rail
   collapses to a horizontal scrolling strip below 900px only so it still
   works on a narrower laptop window, not for touch. */
.settings-shell {
  display: flex;
  align-items: flex-start;
  gap: var(--space-6);
}
.settings-rail {
  flex: 0 0 240px;
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.settings-search-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.settings-search-input {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
}
.settings-search-input:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.settings-search-count {
  margin: 0;
  padding: 0 var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  min-height: 1em;
}
.settings-rail-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.settings-rail-item {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.settings-rail-item[aria-selected="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.settings-groups {
  flex: 1;
  min-width: 0;
}

/* UX12 (DEC-052 ruling (2)): a jump control at the top of any settings
   group panel long enough to need it, built by admin.ts's
   ensureSettingsSectionJump from that panel's own subsection headings.
   Sticky the same way .settings-rail beside it already is (that sibling
   proves the technique holds against this page's own document-level
   scroll, so this reuses it rather than inventing a floating widget).
   UX36 (DEC-186, option A of design/mockups/settings-section-jump-
   redesign.html): always exactly one row, scrolling sideways instead of
   wrapping, so it never grows past the scroll-margin-top budget below
   and never covers the heading it lands on. */
.admin-section-jump {
  position: sticky;
  top: var(--space-4);
  z-index: var(--z-sticky);
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.admin-section-jump-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  flex-shrink: 0;
}
/* UX36: the scrolling strip itself. min-width: 0 is required for a flex
   child to shrink below its content's own natural width, which is what
   lets overflow-x ever activate inside this flex row at all. The
   mask-image fade signals "there is more to scroll" without a visible
   scrollbar; a sideways swipe or drag is the gesture a tablet user
   already has. overflow-y: hidden is deliberate (this strip is one row
   tall, never more), which is why the focus-visible treatment below is
   an inset box-shadow rather than an outset outline: an outset outline
   would be clipped by this same overflow-y.
   UX36 design-review fix: the mask-image's own gradient is fixed to this
   element's border box, never to the scrolled content, so its fade
   zones sit at the SAME two edges regardless of scroll position. Without
   padding, the first button's own text starts flush at the left edge, so
   at rest (scrollLeft 0, nothing further left) that fade clipped real
   content ("Item kinds" read "em kinds") and read as a false "more to
   scroll" cue. The inset is one hairline token wider than the fade, so the
   added smallest token absorbs fractional maximum-scroll rounding across
   engines while keeping chip border boxes outside the unchanged fade.
   scroll-padding-inline keeps scroll-snap's own "start" alignment landing
   a button just past that inset rather than snapping it half into the
   faded area. */
.admin-section-jump-list {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-2);
  overflow-x: auto;
  overflow-y: hidden;
  min-width: 0;
  padding-inline: calc(var(--space-4) + var(--space-hairline));
  scroll-padding-inline: calc(var(--space-4) + var(--space-hairline));
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--space-4),
    #000 calc(100% - var(--space-4)),
    transparent 100%
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--space-4),
    #000 calc(100% - var(--space-4)),
    transparent 100%
  );
}
.admin-section-jump-list::-webkit-scrollbar {
  display: none;
}
.admin-section-jump-button {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
  scroll-snap-align: start;
}
.admin-section-jump-more {
  flex-shrink: 0;
  min-width: var(--touch-target-comfortable);
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-strong);
  background: var(--color-surface);
  color: var(--color-accent-strong);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.admin-section-jump-more[hidden] {
  display: none;
}
.admin-section-jump-button:hover,
.admin-section-jump-button:focus-visible {
  border-color: var(--color-accent-strong);
}
/* UX36, corrected per the designer's independent review: an outset
   outline here would be clipped by .admin-section-jump-list's own
   overflow-y: hidden. An inset box-shadow paints entirely inside this
   button's own border box, so it cannot be clipped by any ancestor's
   overflow regardless of that ancestor's own box, and it leaves the
   row's own rendered height (and the scroll-margin-top budget above)
   untouched. */
.admin-section-jump-button:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--color-focus-ring);
}
.admin-section-jump-button[aria-current="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}

/* SET2: the live search-results overlay, shown in place of the active
   group panel whenever the search box is non-empty. */
.settings-search-results {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* SET2: while a search is active, every group panel underneath the
   results overlay is hidden (the overlay's own [hidden] toggle handles
   showing/hiding itself; this class only ever hides its SIBLINGS). */
.settings-groups.settings-search-active > *:not(.settings-search-results) {
  display: none !important;
}
.settings-search-result {
  display: block;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  text-align: left;
  cursor: pointer;
}
.settings-search-result:hover,
.settings-search-result:focus-visible {
  border-color: var(--color-accent-strong);
}
.settings-search-result-group {
  display: inline-block;
  margin-bottom: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.settings-search-result-label {
  display: block;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.settings-search-result-description {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.settings-search-empty {
  margin: 0;
  padding: var(--space-4);
  color: var(--color-text-tertiary);
}
/* A field flashed into view from a search result, briefly highlighted so
   the operator's eye finds it against the rest of the group panel. */
.settings-search-target-flash {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* DEC-203 tablet-overflow fix (UX72): .settings-shell's own base rule
   sets align-items: flex-start so the sticky rail and the content column
   (each a plain auto-width block box) do not stretch to match each
   other's HEIGHT in the two-column row layout above 900px. That same
   align-items value carries into this column layout unless overridden:
   in a column flex container align-items governs the CROSS axis, which
   here is WIDTH, so "flex-start" left every child (.settings-rail,
   #admin-settings-groups) sized to its own content's shrink-to-fit width
   instead of the column's own available width. #admin-settings-groups
   contains the Jump-to nav's horizontally scrolling pill row
   (.admin-section-jump-list, overflow-x: auto), and a shrink-to-fit box
   that contains an internal scroll container is sized against that
   scroll container's own max-content (unclamped) width rather than the
   space actually available, so the whole content column rendered near
   1100px wide regardless of viewport, clipped with no scrollbar by
   #app-shell's own overflow-x: auto sitting above it. Restoring stretch
   here, scoped to this breakpoint only, makes both children fill the
   column's own width, so #admin-settings-groups is bounded and every
   input inside it fits, and the Jump-to row's own overflow-x: auto then
   does what it was built for: it scrolls sideways within its own bounds
   instead of forcing its ancestor wide. */
@media (max-width: 900px) {
  .settings-shell {
    flex-direction: column;
    align-items: stretch;
  }
  .settings-rail {
    flex: 1 1 auto;
    position: static;
    width: 100%;
  }
  .settings-rail-groups {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .settings-rail-item {
    flex: 1 1 auto;
  }
}

.admin-search-row {
  padding: 0;
  border-bottom: none;
  margin-bottom: var(--space-4);
}

/* Owner alpha-review feedback (Amendment 2026-08-21, fourth): shelf-tier
   and liquor-category filter chips above the Bottles list. Each group is
   its own single-select radio row (native radio inputs sharing one
   `name`, same visually-hidden-input-plus-label shape as
   .admin-chip-select's checkbox pickers above; :checked styling is
   identical since it keys off the sibling selector, not the input type),
   so tapping a chip in one group never disturbs the other group's
   selection, and "All" is always one tap away rather than a picker to
   reopen. */
.admin-bottle-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.admin-filter-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.admin-filter-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.admin-filter-chip-select {
  margin-bottom: 0;
}

/* DSC22 (DEC-097): the Discounts panel's own Sort/Type/State chip groups,
   the same column-of-groups layout as .admin-bottle-filters above, given
   its own class rather than sharing that one so a future change to either
   list's own filter row does not silently move the other. */
.admin-discount-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.admin-bottle-list {
  display: block;
}

/* INV26 Slice 1 (docs/build-briefs/INV26-backbar-inventory.md; DEC-206
   item 2, DEC-207), matching design/mockups/inv26-inventory-backbar.html's
   own Artboard 1 (owner-approved, DEC-207: "Good mockup design.
   Approved."), lifted near-verbatim from that mockup's own <style>. This
   REPLACES the old flex-row-button list styling below it used to carry
   (.admin-bottle-row was a card-shaped button; .admin-bottle-info/-name/
   -detail/-shelf-row/-shelf-chip and the old .admin-bottle-status/
   .inactive pill are all retired along with it, per this brief's own "no
   type or subtype column" -- the category/price detail line and the
   item-kind/shelf-tier chips those rules styled no longer render). The
   TF2 group-heading rule (.admin-bottle-group-heading) survives, now
   styling a colspanning <td> inside the table instead of a flex-list <h3>,
   since TF2's own owner ruling ("move it to the bottom, ... a new section
   of disabled inventory") is unchanged by this brief. */
table.inv-table {
  width: 100%;
  border-collapse: collapse;
  /* INV26 S1 list-fit fix: fixed layout so the five column widths
     admin.ts's INVENTORY_LIST_COLUMNS sets on each <th> (46/16/16/8/14%)
     are load-bearing rather than advisory. Auto layout let Package/On
     hand/Par/Status grow past their declared share to fit content,
     pushing Par and Status off the right edge of the real, narrower
     Settings column (design/mockups/inv26-list-fit.html's own header
     comment). */
  table-layout: fixed;
}
.inv-table thead th {
  padding: 0;
  border-bottom: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  text-align: left;
}
.inv-sort-btn {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  width: 100%;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  background: none;
  border: none;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.inv-sort-btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.inv-sort-btn .caret {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
th[aria-sort="ascending"] .inv-sort-btn,
th[aria-sort="descending"] .inv-sort-btn {
  color: var(--color-accent-strong);
}
th[aria-sort="ascending"] .inv-sort-btn .caret,
th[aria-sort="descending"] .inv-sort-btn .caret {
  color: var(--color-accent-strong);
}
.inv-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-base);
  vertical-align: middle;
}
.inv-table tbody tr:last-child td {
  border-bottom: none;
}
.inv-table tbody tr.inv-row:hover {
  background: var(--color-surface-sunken);
  cursor: pointer;
}
.inv-item-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
/* Owner alpha-review feedback (pre-existing, still true of this column):
   a real location's bottle names run long (a seeded real name is up to
   ~67 characters); clipped to one line with an ellipsis rather than
   wrapping the row tall. This is NOT a title-attribute-only recovery
   (CLAUDE.md's touch-only rule forbids that): activating the row (its
   existing, already keyboard- and touch-reachable action) opens the edit
   sheet, whose title ("Edit {full name}") and pre-filled name field both
   show the complete, untruncated name, so the real recovery path is a
   normal tap or Enter, not a hidden hover/title affordance. */
.admin-bottle-name-text {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.inv-col-package {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  /* INV26 S1 list-fit fix: with table-layout: fixed, a long value would
     otherwise wrap to two lines and grow the row rather than the
     column. Shortened Package text ("750 ml", "1/2 barrel") rarely needs
     this, but On hand's own unit word can still be long enough to wrap
     at the fixed 16% share, so all three narrow numeric-ish columns get
     the same guard. */
  white-space: nowrap;
}
.inv-col-onhand {
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.inv-col-onhand.negative {
  color: var(--color-warning-text);
}
.inv-col-par {
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.inv-size-assumed {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
}
.admin-bottle-size-confirm {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.inv-status-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  border: 1px solid var(--color-border);
}
/* INVLOC1 Slice 2 (DEC-326; design/mockups/invloc1-s2-*). The item editor's table of locations, the Stock levels list's location
   header and switch, and the two notes. Built on the existing tokens only. Every control is at least 44px, and nothing
   scrolls sideways: the table rows stack under 640px exactly as the mockup's own media query does. */
.admin-stock-intro {
  margin-top: 0;
}
.inv-locations {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: var(--space-3);
}
.inv-locations-head,
.inv-locations-row {
  display: grid;
  grid-template-columns: minmax(150px, 1.1fr) 1fr 1.3fr;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-4);
}
.inv-locations-head {
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border-strong);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}
/* INVLOC1 Slice 5: the same table with two columns (a location, and one picker or one number). */
.inv-locations--two .inv-locations-head,
.inv-locations--two .inv-locations-row {
  grid-template-columns: minmax(150px, 1fr) 2fr;
}
/* INVLOC1 Slice 5, designer pass: the two headings use the Slice 2 section-label look, a placeholder reads clearly yet stays
   lighter than a typed value, a read-only table is quiet, and the details summary shows a chevron and a Show or Hide cue. */
.inv-locations-section-label {
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.inv-locations .field-input::placeholder {
  color: var(--color-text-secondary);
  opacity: 1;
}
.inv-locations-note-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
}
.inv-locations-lock {
  flex: none;
  color: var(--color-text-tertiary);
}
.inv-locations--readonly .field-input {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-secondary);
  cursor: default;
}
/* TESTDEBT8-F1: a disabled input reads as blocked before it is touched, the same quiet treatment the
   read-only locations list uses, on the flat surface with the quiet border, since the live field is already sunken. */
.field-input:disabled {
  opacity: 1;
  background: var(--color-surface);
  border-color: var(--color-border);
  -webkit-text-fill-color: var(--color-text-secondary);
  cursor: not-allowed;
}
/* A disabled control must stay legible: quiet, not faded out. */
.inv-locations--readonly .field-input:disabled {
  opacity: 1;
  -webkit-text-fill-color: var(--color-text-secondary);
}
.inv-locations--readonly .inv-locations-row--here {
  background: transparent;
}
.admin-vendor-location-accounts > summary {
  list-style: none;
  gap: var(--space-2);
}
.admin-vendor-location-accounts > summary::-webkit-details-marker {
  display: none;
}
.admin-vendor-location-accounts > summary::before {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 120ms ease;
  margin-right: var(--space-1);
}
.admin-vendor-location-accounts[open] > summary::before {
  transform: rotate(45deg);
}
.admin-vendor-location-accounts > summary::after {
  content: "Show";
  margin-left: auto;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.admin-vendor-location-accounts[open] > summary::after {
  content: "Hide";
}
.admin-vendor-location-accounts {
  margin: var(--space-3) 0;
}
.admin-vendor-location-accounts > summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-weight: var(--font-weight-semibold);
}
.inv-locations-row {
  border-bottom: 1px solid var(--color-border);
}
.inv-locations-row:last-child {
  border-bottom: 0;
}
.inv-locations-row--here {
  background: var(--color-accent-subtle);
}
.inv-locations-location-name {
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.inv-locations-tag {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-strong);
}
.inv-locations-row .field-input {
  height: 52px;
}
.inv-locations-note {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
}
.inv-locations-note p {
  margin: 0;
  flex: 1;
  min-width: 200px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.inv-locations-note-action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.inv-locations-later {
  margin-top: 4px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-tertiary);
}
@media (max-width: 640px) {
  .inv-locations-head {
    display: none;
  }
  .inv-locations-row,
  .inv-locations--two .inv-locations-row {
    grid-template-columns: 1fr 1fr;
  }
  .inv-locations-row > :first-child {
    grid-column: 1 / -1;
  }
}
.inv-location-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.inv-location-header .admin-page-subtitle {
  margin: 0;
}
/* The active Stock filter chip is solid, as in the mockup (design/mockups/invloc1-s2-4a). */
#admin-stock-filter .admin-chip-option-input:checked ~ .admin-chip-option-label {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.inv-location-switch {
  display: inline-flex;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 3px;
  gap: 3px;
  max-width: 100%;
  flex-wrap: wrap;
}
.inv-location-switch button {
  min-height: var(--touch-target-min);
  min-width: 110px;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.inv-location-switch button[aria-checked="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.inv-no-par-note {
  display: block;
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.inv-no-par-note strong {
  display: block;
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
}
.inv-col-par--none {
  color: var(--color-text-tertiary);
  white-space: normal;
}
.inv-item-bin {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
.inv-status-ok {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border-color: var(--color-success-subtle-border);
}
.inv-status-low {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border-color: var(--color-warning-subtle-border);
}
.inv-status-out {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  border-color: var(--color-danger-subtle-border);
}
.inv-status-negative {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border-color: var(--color-warning-subtle-border);
}
/* TF2, owner testing feedback 2026-08-28: "on the inventory for all
   stock, if we were to disable inventory, that inventory items should
   move to the bottom into a new section of disabled inventory". Rendered
   only when BOTH groups have something in them (admin.ts's
   renderBottleList), so a location with nothing disabled sees the flat
   list exactly as before. Deliberately quiet: a heading row, not a
   banner. */
.admin-bottle-group-heading {
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
}

/* Activating a Drinks/Bottles row opens the edit sheet; the row itself is
   already >=44px tall (.inv-table td padding), so no extra affordance
   element is required for the touch target, matching the ring screen's
   own tappable-row precedent (.liquor-row). admin.ts's buildInventory
   ListRow also makes the <tr> keyboard-focusable (tabIndex + Enter/Space),
   since Settings is an admin surface where CLAUDE.md requires both
   keyboard and pointer, unlike the floor's touch-only rule. */
.admin-drink-row {
  cursor: pointer;
}
.admin-drink-row:focus-visible,
.admin-bottle-row:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* A field's own toggle switch that is a form field, not a list-row
   action: same visual language as .admin-toggle-* above, spaced like a
   field. */
.admin-field-toggle {
  margin: var(--space-4) 0 var(--space-1);
}

.admin-field-help {
  margin: var(--space-1) 0 var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  line-height: var(--line-height-normal);
}

/* VEN7-F1 (docs/build-briefs/VEN7-F1-vendor-status-persistence.md;
   design/mockups/ven7-f1-vendor-save-error-persistence.html, option a).
   #admin-settings-vendor-status carries this class only while it is
   showing a sticky, not-yet-dismissed failure; a settled success that is
   safe to show clears the class along with the text (clearVendorStatus,
   admin.ts). */
.admin-field-help.admin-vendor-status--error {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  color: var(--color-danger-strong);
}
.admin-vendor-status-dismiss {
  flex-shrink: 0;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-danger-strong);
  font-size: var(--font-size-base);
  cursor: pointer;
}

/* UX64/UX59 (DEC-209): .admin-field never carried a rule at all, so a
   `<label class="admin-field"><span>...</span><input></label>` pair (the
   Add user sheet's PIN-choice fields) fell back to a bare <label>'s
   default inline flow and wrapped mid-row the moment the row was too
   narrow for both. This stacks the label above its input, matching every
   other labelled field in this file. */
.admin-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.admin-field > span {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}

/* UX64/UX59: #admin-add-user-pin-error (and .admin-error generally) had
   no rule either, so it reserved no height; the mismatch message
   appearing shoved the buttons below it down a line. Reserving the
   height up front means showing the message moves nothing. */
#admin-add-user-pin-error,
.admin-error {
  min-height: 1.2em;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  margin: var(--space-2) 0;
}

/* UX64 (DEC-209): the Add role / Add user buttons now sit at the top of
   their own sections, above the list, instead of a row beneath it. */
.admin-section-add-row {
  margin: 0 0 var(--space-4);
}

/* UX64: pairs First/Last name and Email/Phone on the Add user popup's
   details step so it fits at 1280x800 with no internal scroll. Each
   field keeps its own label and input; only the row is shared. */
.admin-field-row {
  display: flex;
  gap: var(--space-4);
}
.admin-field-row > div {
  flex: 1;
  min-width: 0;
}

/* UX24: a <button type="button"> styled to read as an inline text link,
   for an in-page cross-link inside a .admin-field-help paragraph (never
   an <a href="#">, matching this file's own established preference for a
   real button over a fragment link, e.g. .settings-search-result above).
   Reset to plain inline text, then styled like a link. */
.admin-inline-link {
  display: inline;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--font-size-sm);
  color: var(--color-accent-strong);
  text-decoration: underline;
  cursor: pointer;
}

.admin-inline-link:hover,
.admin-inline-link:focus-visible {
  color: var(--color-accent);
}

/* Amendment 2026-08-22 (second), settings input formatting: the visible
   unit affordance ("%" for a percent field, "$" for a dollars field) so
   the human-readable unit is evident without relying on the label alone.
   A plain wrapper + absolutely positioned mark, matching this file's
   other affix-free inputs' own precedent of using padding rather than a
   bespoke input component; the input keeps using .field-input's real
   styling untouched, this only reserves room for the mark and positions
   it. aria-hidden on the mark: the field's own <label> ("Tax rate, in
   percent" / the shelf-tier row's "price in dollars" aria-label) already
   carries the unit for assistive tech, so the visual mark would be
   redundant noise read twice. Originally settings-only; a UI-batch gate
   fix (exactness rule extension) carried the same "$" affix onto the
   drink build-charge and bottle sell-price catalog fields
   (index.html/admin.ts), whose own labels already say "in dollars" too,
   so the aria-hidden reasoning above still holds there. */
.field-input-affix {
  position: relative;
  display: block;
}
.field-input-affix-mark {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-base);
  pointer-events: none;
}
.field-input-affix--suffix .field-input {
  padding-right: calc(var(--space-4) + 1.5ch);
}
.field-input-affix--suffix .field-input-affix-mark {
  right: var(--space-4);
}
.field-input-affix--prefix .field-input {
  padding-left: calc(var(--space-4) + 1ch);
}
.field-input-affix--prefix .field-input-affix-mark {
  left: var(--space-4);
}

.provisional-flag {
  display: inline-flex;
  align-items: center;
  margin-left: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  vertical-align: middle;
}

/* Multi-select "chip" pickers (liquor-slot categories, pour ounce
   options): each chip is its own >=44px touch target, a real checkbox
   under the hood (screen-reader and keyboard accessible) rather than a
   div with a click handler, mirroring .admin-toggle-input's
   visually-hidden-input pattern. */
/* VER57-F1: the "Loading pour sizes..." line inside the pour chip
   container. Same text style as .admin-field-help; the 44px min-height
   reserves one chip row so the area is not blank while vocabularies load.
   Not interactive. */
.admin-pour-loading-hint {
  min-height: 44px;
  margin: 0;
}
.admin-chip-select {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.admin-chip-option {
  display: inline-flex;
  /* UX113: anchors the visually hidden radio inside its own chip, so focusing it on tap does not scroll the screen. */
  position: relative;
}
.admin-chip-option-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.admin-chip-option-label {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.admin-chip-option-input:checked ~ .admin-chip-option-label {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.admin-chip-option-input:focus-visible ~ .admin-chip-option-label {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* UX34 (Section 2.3, DEC-188): a chip standing in for a stored value that
   is not actually a member of the picker's own real option set (today,
   only the Standard pour picker's orphaned-value chip). Same --color-
   warning-* tokens .admin-bottle-shelf-chip.unassigned already uses for
   the identical "real but not currently a normal option" meaning, kept
   distinct from the plain, unchecked .admin-chip-option-label above and
   from the accent :checked style below, in both states, so the chip reads
   as a warning whether or not it is currently selected. */
.admin-chip-option--unassigned .admin-chip-option-label {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.admin-chip-option--unassigned .admin-chip-option-input:checked ~ .admin-chip-option-label {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-strong);
  color: var(--color-warning-strong);
}

/* Read-only chip row (configured tip presets, shown with a remove
   action): visually similar to the picker chips above but each carries
   its own X touch target rather than being itself a toggle. */
.admin-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.admin-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2) 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.admin-chip-remove {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: 50%;
  border: none;
  background: transparent;
  color: inherit;
  font-size: var(--font-size-base);
  cursor: pointer;
  flex-shrink: 0;
}
.admin-add-chip-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-4);
}
.admin-add-chip-row .field-input {
  flex: 1;
}

/* Payments-track Slice 3: Settings > Payments > Terminals. Same visual
   language as .admin-drink-row/.admin-toggle-* (a plain list), a list
   rather than a div so screen readers announce "N terminals". Amendment
   2026-08-22 (ninth) added the per-row rename affordance below; the row
   itself is still not a single tap target the way a drink/bottle row is
   (the toggle and the rename button are each their own explicit control,
   since a bare row tap here would be ambiguous between "edit" and
   "toggle active" the way it never is for a drink/bottle row, which has
   only one edit destination). */
.admin-terminal-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  list-style: none;
  padding: 0;
}
.admin-terminal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
.admin-terminal-info {
  min-width: 0;
  flex: 1;
}
.admin-terminal-name-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.admin-terminal-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  min-width: 0;
  /* TERM2: a long reader name wraps instead of shrinking the Active toggle. */
  white-space: normal;
  overflow-wrap: anywhere;
}
.admin-terminal-row .admin-toggle-label {
  flex-shrink: 0;
}
.admin-terminal-provider-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: 2px;
}
.admin-terminal-provider-line .admin-terminal-provider {
  margin-top: 0;
}
.reader-chip {
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.reader-chip.reader-chip-success {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.reader-chip.reader-chip-danger {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}
.reader-recheck-button {
  min-height: var(--touch-target-min);
}
/* TERM2: the registration form. Two columns for the fields, the button on its
   own full-width row at 820px and below. */
.admin-terminal-register {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: var(--space-2) var(--space-4);
  align-items: start;
  margin-bottom: var(--space-4);
}
.admin-terminal-register-field .field-label {
  margin-top: 0;
}
.admin-terminal-register-button {
  align-self: start;
  margin-top: calc(var(--font-size-sm) * 1.5 + var(--space-1));
  min-height: var(--touch-target-min);
}
.admin-terminal-code-help {
  margin: var(--space-1) 0 0;
}
@media (max-width: 820px) {
  .admin-terminal-register {
    grid-template-columns: 1fr 1fr;
  }
  .admin-terminal-register-button {
    grid-column: 1 / -1;
    width: 100%;
    margin-top: 0;
  }
}
/* Amendment 2026-08-22 (ninth): the rename pencil. Sized by .btn-icon's
   own --touch-target-min floor; margin-left: auto is deliberately NOT
   used here (the button sits directly after the name, not pinned to the
   row's far edge, since .admin-terminal-provider below already occupies
   the same visual column the Active toggle uses on the row's far side). */
.admin-terminal-rename-button {
  flex-shrink: 0;
  font-size: var(--font-size-md);
}
.admin-terminal-rename-button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.admin-terminal-provider {
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}

/* M0: Settings > Void reasons. Same row language as
   .admin-terminal-list above (a plain list of rows, each with an editable
   name and an Active toggle on the far side); a separate class rather
   than a reuse of the terminal one because the two lists are unrelated
   and a shared name would make either one risky to restyle. */
.admin-void-reason-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  list-style: none;
  padding: 0;
}
.admin-void-reason-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
/* ITEM2 Slice 2: item_kind rows carry an extra block (the sale-mechanism
   picker) a bare label-plus-switch row was never built to hold. The
   stacked modifier turns the row into a column so that extra block sits
   below the label/switch top line instead of crowding into the same
   space-between row every other vocabulary list still uses unmodified. */
.admin-void-reason-row--stacked {
  flex-direction: column;
  align-items: stretch;
}
/* UX43 designer finding 1: a flex child's default min-width is its own
   content width, so an unusually long, unbroken vocabulary label (up to
   MAX_VOCABULARY_LABEL_LENGTH, 80 characters, harness/src/domain/
   settingsBounds.ts) refused to shrink and pushed the row's own On/Off
   switch off the visible card. min-width: 0 lets the label actually
   shrink to the row's real width, and overflow-wrap: anywhere lets a
   label with no spaces wrap onto a second line instead of overflowing.
   The switch itself (.admin-toggle-label, flex-shrink: 0)
   is unchanged, so it always stays visible at its own fixed size. */
.admin-vocab-row-label {
  min-width: 0;
  overflow-wrap: anywhere;
}
.admin-item-kind-mechanism-top-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
}
.admin-item-kind-mechanism-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
  width: 100%;
}
/* INV27 (docs/build-briefs/INV27-item-editor-redesign.md; DEC-227 item 3;
   mockup Artboard D). Settings > Inventory's own "Default target markup %,
   by item kind" card (moved here from Menu, coordinator correction
   2026-09-29): one bordered row per active item_kind vocabulary entry, the
   same bordered-card row shape .admin-shelf-tier-row already uses
   elsewhere on this screen, grouped under a single card rather than each
   row's own separate border.

   A fixed label column (coordinator correction 2026-09-29: "the % inputs
   are ragged... give labels a fixed column so all inputs line up in one
   column"). CSS GRID, not flex: the original flex row put the label, the
   input, and the (empty but still flex-participating) status paragraph as
   three siblings under `justify-content: space-between`, which anchors
   the FIRST and LAST items to the row's own edges and leaves the MIDDLE
   item (the input) positioned by the remaining space on either side --
   different for every row once label text length varies ("Liquor" vs.
   "Packaged"), which is exactly the raggedness reported. Grid's two fixed
   columns put the input in the same horizontal position on every row
   regardless of label length; the status paragraph spans both columns on
   its own row beneath, so a save-error message never fights the input for
   column 2's width. */
.admin-target-markups-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}
.admin-target-markup-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  align-items: center;
  column-gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.admin-target-markup-row:last-child {
  border-bottom: none;
}
.admin-target-markup-row-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-target-markup-row-input {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.admin-target-markup-row-input .field-input {
  width: 90px;
  text-align: right;
}
.admin-target-markup-row-status {
  grid-column: 1 / -1;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-target-markup-row-status:empty {
  display: none;
}
.admin-item-kind-initial-policy {
  min-width: 0;
  margin: 0 0 var(--space-3);
  padding: 0;
  border: 0;
}
.admin-policy-radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0 var(--space-3);
}
.admin-policy-radio-option {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  color: var(--color-text-secondary);
  background: var(--color-surface);
  cursor: pointer;
}
.admin-policy-radio-option:has(input:checked) {
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  font-weight: var(--font-weight-semibold);
}
.admin-policy-radio-option input {
  position: absolute;
  inset: -1px;
  width: auto;
  height: auto;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.admin-policy-radio-option input:focus-visible {
  outline: none;
}
.admin-policy-radio-option:has(input:focus-visible) {
  outline: 3px solid var(--color-focus-ring, var(--color-accent-strong));
  outline-offset: 2px;
}
.admin-item-kind-policy-error {
  overflow-wrap: anywhere;
  white-space: normal;
}
.admin-void-reason-fields {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 1;
}
.admin-void-reason-name {
  flex: 1;
  min-width: 0;
}
.admin-void-reason-shipped {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  white-space: nowrap;
}

/* Discounts, slice A: Settings > Discounts. Same row language as
   .admin-void-reason-row above, with more columns because a discount
   carries more than a label. An ADMIN surface, so a dense row with a
   select and typed value boxes is legitimate here (product-owner ruling
   2026-08-27); the floor never sees this layout. Wraps rather than
   overflowing, so a narrower laptop window stacks the columns instead of
   scrolling the page sideways. */
.admin-discount-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  list-style: none;
  padding: 0;
}
.admin-discount-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
/* DSC35-S6: schedule summary plus status chip, under the row's name. Breaks
   onto its own line (flex-basis) so a long summary never squeezes the
   editable fields. Colours are tokens only; Off and Ended use the tertiary
   text token, not opacity (dsc35-notes item 12). */
.admin-discount-schedule {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}
.admin-discount-schedule-summary {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-discount-schedule-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.admin-discount-schedule-status-running {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.admin-discount-schedule-status-off,
.admin-discount-schedule-status-ended,
.admin-discount-schedule-status-manual {
  /* Surface, not sunken: the colorblind theme's tertiary text is 4.22:1 on
     sunken and clears 4.5:1 on surface. */
  background: var(--color-surface);
  color: var(--color-text-tertiary);
}
.admin-discount-name {
  flex: 1 1 12rem;
  min-width: 8rem;
}
.admin-discount-type {
  flex: 0 1 12rem;
}
.admin-discount-value-wrap {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.admin-discount-value-unit {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  min-width: 1ch;
}
.admin-discount-value {
  width: 6rem;
}
.admin-discount-flags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.admin-discount-check {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  /* UX100: a 44px tap row with a 24px box, the whole row the target (Tickets, Items, Needs approval, Needs a
     reason, on the Add form and on a discount's row). */
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  cursor: pointer;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.admin-discount-check > input[type="checkbox"] {
  flex: none;
  width: 24px;
  height: 24px;
  margin: 0;
}
/* Adversarial-gate fix, 2026-08-29 (docs/backlog.md CL5): the visible
   consequence text for closes_ticket, ALWAYS on screen and never a hover
   tooltip -- this console runs on a tablet, which has no hover. Forces
   onto its own line under the checkbox via flex-basis while the
   checkbox's own label text stays on one line (the parent's nowrap). */
.admin-discount-check-hint {
  flex-basis: 100%;
  width: 100%;
  white-space: normal;
  font-size: var(--font-size-xs);
  color: var(--color-warning-text);
}
/* Settings rebuild SET1 hard requirement 2: member_daily_comp is given a
   home but stays READ ONLY (src/domain/discounts.ts's own comment on
   why); plain text in a pill, never a checkbox, so nobody mistakes it
   for editable. closes_ticket moved to an editable checkbox above,
   2026-08-29 (docs/backlog.md CL5): no CHECK constraint ever referenced
   it, unlike member_daily_comp. */
.admin-discount-readonly-flag {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  white-space: nowrap;
}
/* UX92: the Add Discount button heads the list, beside the Sort, Type and State
   chips, and the add form is a popout (#admin-discount-add-scrim). */
.admin-discount-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.admin-discount-head .admin-discount-filters {
  flex: 1 1 24rem;
  margin-bottom: 0;
}
.admin-discount-open {
  flex: 0 0 auto;
  white-space: nowrap;
}
/* The form is long enough that the generic 720px sheet cap would scroll it at a laptop height;
   the body still scrolls (the .sheet-body default) on a shorter window. */
.admin-discount-add-sheet {
  max-height: min(860px, 94vh);
}
.admin-discount-add-error {
  margin: 0;
  padding: var(--space-2) var(--space-5) 0;
}
.admin-discount-add-group {
  margin-top: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  border: 0;
  padding: 0;
  min-width: 0;
}
.admin-discount-add-group .field-label {
  flex-basis: 100%;
  padding: 0;
  margin-bottom: 0;
}

/* Discounts, slice A: the ONE summed Discount row in the ticket's totals
   block (owner ruling 2026-08-28, "the total discount should be a line
   item at the bottom of the ticket").

   TF1, owner testing feedback the same day: this used to be a <button>,
   because tapping it was the floor's only route back to a mis-applied
   discount. Nothing on screen said it was tappable and the owner did not
   find it ("there is no way to remove a discount if you apply the wrong
   one"), so removal moved onto an explicit Remove control on each
   discount's own row (.discount-line below) and this reverted to a plain
   total.

   UX13: the touch-target-min height is gone. It dated from when this row
   was still a <button>, TF1 already removed that, and DEC-053's density
   scale gives a non-interactive chrome row (nothing here is tappable) no
   44px floor to hold onto; docs/build-briefs/UX13-ticket-rail.md records
   why this row stays always-visible rather than folding behind the Total
   tap the way Subtotal/Tax do (ten already-passing e2e assertions depend
   on its visibility the instant a discount is applied). */
.totals-row-discount {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--space-1) 0;
  font-size: var(--font-size-sm);
  color: var(--color-success-text);
}

/* PAYTOTAL1-F1: named reductions belong to the fixed totals block, not a separate scrolling list. */
/* QAWALK1-F4: with many specials the named lines would fill the rail and push every drink row out of
   view at the floor viewport. The block keeps a capped height (about one and a half rows, so a cut-off
   row signals more) and scrolls inside itself; the drink rows keep their space. Money is unchanged. */
.ticket-totals .discount-lines {
  display: block;
  min-height: 0;
  max-height: 7.5rem;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.ticket-totals .discount-line {
  padding: var(--space-1) 0;
}
.ticket-totals .discount-line-amount,
.ticket-totals .totals-row > :last-child,
.ticket-totals .totals-row-grand > :last-child {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.discount-lines .discount-line-name,
.discount-lines .discount-line-detail {
  white-space: normal;
  overflow-wrap: anywhere;
  overflow: visible;
  text-overflow: clip;
}
.discount-specials-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 32px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--font-size-sm);
  color: var(--color-success-text);
  font-variant-numeric: tabular-nums;
}
.discount-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}
.discount-line:last-child {
  border-bottom: none;
}
.discount-line-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.discount-line-name {
  font-size: var(--font-size-md);
  line-height: var(--line-height-tight);
  color: var(--color-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.discount-line-detail {
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.discount-line-amount {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-text);
  white-space: nowrap;
}
/* The removal affordance the owner could not find, made explicit and
   per-row. A real touch target (the 44px hard floor, CLAUDE.md's
   touch-only rule) and a word rather than an icon, because "Remove" is
   the thing that was missing and an icon would be one more glyph to
   decode mid-service. */
.btn-discount-remove {
  flex-shrink: 0;
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.btn-discount-remove:active {
  background: var(--color-surface-sunken);
}
.btn-discount-remove:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
/* DSC2: a derived member benefit has no application behind it, so it
   carries this word where a removable discount carries its Remove button.
   Deliberately NOT a disabled-looking button: a control that cannot act
   reads as a broken control, and the bartender needs to know this row is
   automatic rather than that it is stuck. Sized to the same 44px row
   rhythm so the two kinds of row line up. */
.discount-line-badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}

/* Auth track (track/auth) Slice 1: Settings > Users. Same visual
   language as .admin-terminal-list/.admin-drink-row above (a plain list
   of rows, each with its own info block and action buttons); the role
   picker in the Add User row reuses .admin-chip-select/.admin-chip-
   option-* as-is (admin.ts's renderChipRadioGroup), no new chip CSS
   needed. */
.admin-add-user-row {
  flex-wrap: wrap;
}
.admin-add-user-row .field-input {
  min-width: 200px;
}
.admin-user-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.admin-user-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
.admin-user-info {
  min-width: 0;
  flex: 1;
}
.admin-user-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.admin-user-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.admin-user-badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.admin-user-badge-active {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}
.admin-user-badge-inactive {
  color: var(--color-text-tertiary);
}
.admin-user-badge-locked {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
}
.admin-user-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  flex-shrink: 0;
}

.admin-component-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.admin-component-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.admin-component-row .field-input {
  height: var(--touch-target-min);
}
.admin-component-name-input {
  flex: 2 1 160px;
  min-width: 120px;
}
.admin-component-quantity-input {
  flex: 1 1 80px;
  min-width: 70px;
}
.admin-component-unit-input {
  flex: 1 1 80px;
  min-width: 70px;
}
/* CORE14: the ingredient item picker. A search box with a short result list under it; a result is a full-height button. */
.admin-component-item {
  flex: 2 1 220px;
  min-width: 160px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-component-item .admin-component-name-input {
  flex: 0 0 auto;
  width: 100%;
  min-width: 0;
}
.admin-component-item-results {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  max-height: 240px;
  overflow-y: auto;
}
.admin-component-item-results .admin-field-help {
  margin: 0;
  padding: var(--space-3);
}
.admin-component-item-option {
  flex-shrink: 0;
  overflow-wrap: anywhere;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: none;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.admin-component-item-option:last-child {
  border-bottom: none;
}
.admin-component-needs-product {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.admin-component-needs-product-badge {
  padding: 2px var(--space-2);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
  font-weight: 600;
}
.admin-component-pour-name {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-min);
  font-weight: 600;
  color: var(--color-text-primary);
}
.admin-component-liquor-slot-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.admin-component-remove {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--color-danger);
  font-size: var(--font-size-lg);
  cursor: pointer;
  flex-shrink: 0;
  margin-left: auto;
}

/* Generic scrollable sheet body: the liquor sheet's own middle region is
   named .liquor-list because it is ONLY ever a liquor list; the add/edit
   forms below need the identical layout role (flex:1, internal scroll,
   capped by the shared .sheet's own max-height) for an ordinary form, so
   this is the general-purpose name that role should have had. Capped
   height plus internal scroll, never bottom-pinned inputs, is this
   codebase's own established answer to the on-screen keyboard appearing
   (design/README.md; ALPHA-08 checkpoint notes). */
.sheet-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
}
/* Design/QA gate CRITICAL correction, 2026-08-21: .pay-confirm-body reuses
   .sheet-body's flex:1/overflow-y:auto scrolling behavior (index.html's own
   comment on the wrapper has the full reproduction) but overrides its
   default padding to zero, the same way .admin-confirm-body below
   overrides it too: every child inside already carries its own left/
   right/top/bottom spacing (var(--space-5) throughout), sized on the
   assumption of being a direct child of .sheet, not of an already-padded
   .sheet-body. Without this override every child would get DOUBLED
   horizontal padding. Declared HERE, after .sheet-body's own rule (not
   grouped with the rest of the pay-confirm-sheet's styles earlier in this
   file): both are single-class selectors of equal specificity, so CSS
   resolves the conflicting `padding` declaration by source order, and an
   override placed BEFORE the rule it means to override loses the cascade
   silently, with no error - a real mistake this correction's own first
   draft made and caught only by a negative control that unexpectedly
   still passed (see docs/review-record.md's Review 10 for the full
   story). .admin-confirm-body's own identical override, immediately
   below, has always been correctly placed after .sheet-body for the same
   reason. */
.pay-confirm-body {
  padding: 0;
}
/* UX23 (docs/build-briefs/UX23-tip-line-below-the-fold.md): the sheet-body
   scroll above used to be the ONLY scroll region in this sheet, so the
   "Charging now" itemization (one row per uncovered drink, unbounded) grew
   downward and pushed Total due, Subtotal, Tax and Tip, the last row in
   that block, below the fold on any realistic ticket. Fixed by giving
   .pay-confirm-charging-now its own bounded, independently scrolling
   region and stopping the whole body from scrolling as one unit: this
   turns .pay-confirm-body into the flex column that actually lays its
   children out (the .sheet-body ancestor rule above only makes it a flex
   ITEM of .sheet, not a flex container for its own children), pins every
   child to its natural height with flex-shrink:0 by default, and then
   overrides Charging now specifically, immediately below, to be the one
   region that shrinks and scrolls first; min-height:0 is required for a
   flex item to be allowed to shrink to fit .sheet's own fixed max-height
   cap instead of forcing the cap open.
   overflow-y stays auto (VER19, following the pre-existing "unreachable
   Confirm" CRITICAL correction two rules up, whose own ack-row/warn-
   banner reachability this must not regress) rather than becoming hidden,
   as a LAST-RESORT fallback, not the normal path: with Charging now the
   only flex-shrink:1 child, the flexbox algorithm gives it first claim on
   any deficit regardless of this ancestor's overflow value (overflow does
   not affect flex sizing, only what happens to content that still does
   not fit after sizing), so in every case UX23 was written for, Charging
   now alone absorbs the deficit, this ancestor's content fits its own
   resolved height exactly, no scrollbar appears, and Tip stays visible
   with no scroll of any kind, unchanged from the flex-shrink:0/hidden
   version. auto only ever engages when even a fully collapsed (min-
   height:0) Charging now still leaves the OTHER, pinned children (the
   warn banner, the ack row, ...) taller than the available space, e.g. a
   long ticket reopened with a prior captured payment: there, scrolling
   the ack row into reach is strictly better than clipping it
   unreachable, which is the exact regression the CRITICAL correction
   above exists to prevent. Proven both ways in
   harness/e2e/ui.spec.ts's own "VER19" test: the ordinary UX23 case
   still shows no scrollbar on this ancestor, and the combined long-
   ticket-plus-warning-banner case is reachable only because of this
   fallback (observed failing with `hidden` first). */
.pay-confirm-body {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  min-height: 0;
}
.pay-confirm-body > * {
  flex-shrink: 0;
}
/* The one exception: Charging now is the only region whose content length
   is unbounded (docs/build-briefs/UX23-tip-line-below-the-fold.md's own
   "constraint that rules out the easy wrong fix" - this must hold on a
   twelve-drink ticket exactly as it does on a six-drink one, never by
   fitting everything inside a fixed height that happens to work for
   today's ticket). No pixel literal is used to bound it: flex-grow stays
   at its default 0, so on a SHORT list this element takes only its own
   content height, same as before this change, rather than stretching to
   fill whatever room is left. flex-shrink:1 plus min-height:0 is what
   does the bounding, self-adjusting to whatever .pay-confirm-body's own
   resolved height (set by .sheet-body's flex:1 above, itself capped by
   .sheet's max-height: min(720px, 92vh)) actually leaves over once every
   flex-shrink:0 sibling above has taken its natural size: on a LONG list,
   the deficit lands entirely on this element (the only shrinkable child),
   and overflow-y:auto exposes whatever does not fit through a scrollbar
   confined to this region. In the ticket sizes UX23 was written for, this
   alone is enough and the ancestor's own overflow-y:auto (immediately
   above) never engages: Total due, the totals block, and the tip presets
   stay visible with no scroll at all. Only in the rarer case this
   element's own comment above documents (that combination taller than
   the sheet even with Charging now fully collapsed) does the ancestor's
   fallback scroll engage too. This tracks any sheet size
   automatically, including a future change to the floor viewport
   (FLOOR_DEVICE, harness/e2e/floorDevice.ts) or the .sheet max-height
   token, with no second number to keep in sync by hand.
   Selector specificity: `.pay-confirm-body > *` above is one class plus
   the universal selector, which contributes zero specificity, so that
   rule is (0,1,0); this rule is two classes, (0,2,0), and wins outright.
   Source order plays no part, so this override cannot silently lose the
   cascade the way the padding override two rules up once did by relying
   on order (see that rule's own comment). */
.pay-confirm-body > .pay-confirm-charging-now {
  flex-shrink: 1;
  /* UX81: never below the title plus one full row (measured 84px scrollHeight
     for one line, so 5rem at the 17px root), and never above about two and a
     half rows, so a long ticket shows a partly visible third row as the cue
     that the list scrolls. The space this floor needs is reclaimed from the
     sheet header (badge inline with the title), the Total due padding and the
     spacing around the footer, never from this box. If the sheet is still
     short, the body's own auto-overflow fallback above scrolls first. */
  min-height: 5rem;
  max-height: 7.75rem;
  overflow-y: auto;
  /* Dragging the list must not chain into the sheet body. */
  overscroll-behavior: contain;
}
/* UX81: a short fade at the bottom edge, only while the list overflows and is
   not at its end (class toggled by updatePayChargingNowOverflow in main.ts).
   Sticky to the scrollport's bottom, with a negative margin the same height so
   it adds nothing to scrollHeight; it takes no touches. */
.pay-confirm-charging-now.has-more-below::after {
  content: "";
  display: block;
  position: sticky;
  bottom: 0;
  height: var(--space-6);
  margin-top: calc(-1 * var(--space-6));
  background: linear-gradient(to bottom, transparent, var(--color-surface-sunken) 85%);
  pointer-events: none;
}
/* Deliberately NOT display:flex. An earlier draft made this a flex
   column (to zero out the first field-label's own top margin below);
   that turned every direct child, including buttons like #admin-drink-
   add-component, into a flex item whose default flex-shrink:1 let the
   browser shrink it below its own explicit height (measured live at
   1024x768: the Add component button collapsed to ~24px, well under
   --touch-target-min) whenever the sheet's already-scrollable content
   exceeded the available height, since a shrinkable flex item is
   resized before an overflow:auto container actually scrolls. Plain
   block flow has no such failure mode: every child keeps its own CSS
   height, and .sheet-body's own overflow-y:auto (a sibling class on the
   same element) scrolls the overflow exactly as intended. */
.admin-form-body .field-label:first-child {
  margin-top: 0;
}

.admin-form-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-form-error {
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  min-height: 1.2em;
}
/* CORE10: one line per message, so every error from one Save reads together. */
.admin-form-error-line {
  display: block;
}
/* CORE10: a tab that has an error carries a bold "!" (shape, never colour alone) and its hidden words. */
.item-tab-error-mark {
  margin-inline-start: var(--space-1);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold);
}
.item-tab-error-mark .item-tab-error-words {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Destructive-deactivation confirm sheet (Review 9 correction,
   both gates, Medium) ----------
   Shared by the drinks list toggle and the bottle form's Active toggle.
   Built entirely on the same .scrim/.sheet/.sheet-header/.sheet-title
   tokens every other admin sheet already uses, per design/README.md; the
   only new classes are the body/actions layout below. */
.admin-confirm-sheet {
  max-width: 480px;
}
.admin-confirm-body {
  padding: var(--space-2) var(--space-5) var(--space-4);
}
.admin-confirm-body p {
  margin: 0;
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
}
.admin-confirm-actions {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: 1px solid var(--color-border);
}
.admin-confirm-actions .btn-secondary,
.admin-confirm-actions .btn-danger {
  flex: 1;
}

.admin-settings-save-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.admin-settings-save-status {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-medium);
}

.admin-shelf-tier-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
  background: var(--color-surface);
}
.admin-shelf-tier-key {
  min-width: 64px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.admin-shelf-tier-row .field-input {
  height: var(--touch-target-min);
}
.admin-shelf-tier-name-input {
  flex: 2 1 160px;
  min-width: 120px;
}
/* The price input's own flex sizing moves to its .field-input-affix
   wrapper (the actual flex child of .admin-shelf-tier-row now that the
   "$" mark sits alongside it, Amendment 2026-08-22 second); the input
   itself stays width:100% of that wrapper via .field-input's own rule. */
.admin-shelf-tier-row .field-input-affix--prefix {
  flex: 1 1 120px;
  min-width: 100px;
}

/* INV19 Slice 1 (docs/build-briefs/INV19-pour-size-price-override.md).
   Same bordered-card row shape as .admin-shelf-tier-row above; one row
   per pour size already configured on the item being edited. */
.admin-pour-price-override-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
  background: var(--color-surface);
}
.admin-pour-price-override-size {
  min-width: 56px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.admin-pour-price-override-sign {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.admin-pour-price-override-row .field-input-affix--prefix {
  flex: 1 1 120px;
  min-width: 100px;
}
.admin-pour-price-override-status {
  flex: 1 1 220px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-pour-price-override-status--danger {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2);
}

/* Inventory track Slice 3: the item editor's "Size" field pair (a plain
   quantity plus its free-text unit, e.g. 750 + "ml"), same two-input flex
   row shape as .admin-shelf-tier-row above without that row's bordered
   card chrome, since this pair is a single field's own two parts rather
   than a repeating list. */
.admin-size-row {
  display: flex;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.admin-size-row .field-input {
  height: var(--touch-target-min);
}
.admin-size-row #admin-bottle-size-value {
  flex: 1 1 120px;
  min-width: 100px;
}
.admin-size-row #admin-bottle-size-unit {
  flex: 1 1 100px;
  min-width: 80px;
}

/* TF3 (docs/backlog.md, owner ruling 2026-08-28): Par level and the
   read-only on-hand figure sit side by side, so the stock target and the
   current count read at a glance. INV20 (DEC-190, DEC-206) removed the
   separate reorder-threshold column: par level is the one stock target. */
.admin-par-onhand-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.admin-par-onhand-col {
  flex: 1 1 0;
  min-width: 220px;
}
/* INV20 (DEC-190, DEC-206), owner-approved 2026-09-28: plain read-only
   text, not styled like a field-input. The first pass styled this like a
   sunken, bordered box, which reads as editable when it is not; the
   owner's one accepted change was to make it plain text instead. Still a
   <p>, never an <input>: see index.html's own comment on this element
   for why that is load-bearing, not cosmetic. Height and vertical
   centering match the Par level input beside it so the two baselines
   align. */
.admin-onhand-value {
  display: flex;
  align-items: center;
  margin: 0;
  height: var(--touch-target-comfortable);
  padding: 0;
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.admin-onhand-value--unavailable {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
  font-style: italic;
}
/* UX16-F2 (docs/build-briefs/UX16-F2-negative-on-hand-shown-not-hidden.md;
   DEC-178): a plain warning beside a negative on-hand figure, never hidden
   or refused. Same left-bar-plus-color shape .pay-block-reason already
   uses, so the warning is not conveyed by color alone. */
.admin-onhand-warning {
  display: flex;
  align-items: center;
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-left: 3px solid var(--color-warning-strong);
  padding: var(--chrome-gap-hairline) var(--space-2) var(--chrome-gap-hairline) var(--space-3);
}

/* ================================================================   ALPHA-08: line-edit control, tip section, pay-warning banner, closeout
   summary. Tokens-only throughout, same as every rule above.
   ======================================================================= */

/* Small icon-only button, sibling of .state-btn in a rendered ticket
   line's row (renderTicketLines). Same touch-target-min floor as
   .btn-icon; kept icon-only (not a text button) specifically to protect
   the compact two-row line's tight width budget (.line's own comment
   above documents how sensitive that budget already is). Hidden entirely
   once the order has a captured payment this session (state.orderPaid),
   matching src/domain/lineEditing.ts's own "blocked after any captured
   payment" gate: an edit control a tap could not act on would be worse
   than no control at all. */
.btn-line-edit {
  flex-shrink: 0;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-line-edit:hover {
  background: var(--color-surface-sunken);
}

/* VOC1-F8 build-time amendment, dated 2026-09-22. An UNCOVERED cocktail
   line's recipe control does not live here as a fourth row button
   (removed once; it collapsed .line-name-text on a long drink name,
   e2e/ui.spec.ts's own truncation-recovery test) -- it renders inside the
   line-edit-sheet's #line-edit-view-recipe button instead, reached
   through the unchanged .btn-line-edit trigger. A COVERED cocktail line
   has no edit button at all (buildTicketLineRow's own `if (!covered)`),
   so THIS class fills that same now-empty slot instead, mutually
   exclusive with .btn-line-edit and never a third control. Text, since
   it never has to compress into .btn-line-edit's own icon-only width. */
.btn-line-recipe {
  flex-shrink: 0;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-line-recipe:hover {
  background: var(--color-surface-sunken);
}

/* Amendment 2026-08-22 (fifth), item 2: the prominent, always-visible
   quick action on an unassigned line (main.ts's buildTicketLineRow,
   promptAssignGuest), distinct from the "..." edit-sheet control above
   which every line (assigned or not) already offers. A real touch
   target of its own (touch-target-min floor, same as every other
   tappable control in this file), rendered as its own row in the line's
   info column rather than squeezed into .line-top, so it never competes
   with the drink name/price for that row's own tight width budget
   (.line's own comment documents how sensitive that budget already is).
   Accent-colored (an intended, available action, not a warning), never
   color alone since the text itself says exactly what it does. */
.line-assign-guest-button {
  align-self: flex-start;
  height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
.line-assign-guest-button:active {
  opacity: 0.8;
}

.line-edit-actions {
  padding: var(--space-4) var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.btn-danger {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.btn-danger:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
  cursor: default;
}

/* ---------- Tips (ALPHA-08) ----------
   Sits inside the pay-confirm sheet, between totals and the pay-warning
   banner. Presets are rendered from config (main.ts's loadTipOptions),
   never hardcoded percentages; see docs/decision-proposals/provisional-
   tips-config.md rule 3. */
.tip-section {
  padding: 0 var(--space-5) var(--space-3);
}
.tip-section-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
}
.tip-preset-row {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.btn-tip-preset {
  flex: 1;
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: var(--line-height-tight);
}
.btn-tip-preset .tip-preset-amount {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.btn-tip-preset.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.btn-tip-preset.selected .tip-preset-amount {
  color: var(--color-accent-strong);
}
.tip-custom-row {
  display: flex;
  gap: var(--space-2);
}
.tip-custom-input {
  flex: 1;
  min-width: 0;
}
#tip-none-button.selected,
#tip-custom-apply.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}

/* ---------- Pay warning (ALPHA-08, product owner ruling 2026-08-20) ----------
   Mirrors design/mockups/pay-warning.html: amber, never danger red (a
   guest may legitimately be starting a new round); the banner stays on
   screen through both the unacknowledged and acknowledged states, never
   disappearing once shown. */
.warn-banner {
  margin: 0 var(--space-5) var(--space-4);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.warn-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.warn-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-warning-strong);
  /* text-on-dark, not text-on-accent: see .toast.toast-danger's comment
     above; same fixed-strong-color-as-background bug, same fix. */
  color: var(--color-text-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  flex-shrink: 0;
}
.warn-title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-warning-strong);
}
/* Design/QA gate finding E, CRITICAL: both of these used to read
   --color-text-primary, a THEME-layer token, against
   --color-warning-subtle, a FIXED semantic background. On Charcoal (the
   one dark theme) --color-text-primary is a LIGHT color, landing at
   1.0:1 contrast against this light amber background: functionally
   invisible. design/README.md's own rule ("never pair a semantic color
   with a component's own surface or text tokens") says exactly why this
   was wrong: a fixed semantic background must pair only with its own
   fixed semantic text color. --color-warning-strong already IS that
   partner (.warn-title, just below the CSS that reads this comment, has
   always used it) and is already verified at 5.4:1 against
   --color-warning-subtle in design/README.md's own checked-pairs table,
   independent of which theme surface happens to be behind the banner. */
.warn-prior {
  margin-top: var(--space-2);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-warning-strong);
}
.warn-body {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
}

/* Design/QA gate finding C: a distinct DANGER-colored variant (never the
   amber above, which is deliberately non-alarming for "you might be
   double-charging a guest on purpose") for "we could not even check
   whether this tab was already paid." This is a hard block, not a
   caution: the fixed danger semantic pair, same rule as .warn-prior/
   .warn-body above (a fixed subtle background pairs only with its own
   fixed strong text token, never a theme token). */
.warn-banner-danger {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
}
.warn-icon-danger {
  background: var(--color-danger-fill);
}
.warn-title-danger {
  color: var(--color-danger-strong);
}
.warn-body-danger {
  color: var(--color-danger-strong);
}

/* Acknowledge control: unchecked by default, never pre-checked (design/
   principles.md rule 4, "no soft default"). Confirm stays disabled until
   this is explicitly checked (main.ts's updatePayConfirmButtonState).
   Design/QA gate finding I: now a <label> (index.html), so the whole row
   is the click target, not just the checkbox square; `cursor: pointer`
   makes that discoverable. */
.ack-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-3) var(--space-4);
  margin: 0 var(--space-5) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  cursor: pointer;
}
/* Design/QA gate finding I: was 24x24px, below the 44px touch-target
   floor this codebase holds everywhere else (--touch-target-min). Bumped
   to the floor itself; the row's own 56px --touch-target-comfortable
   min-height already had headroom for it. */
.ack-checkbox {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
}
.ack-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
}

/* Amendment 2026-08-22 (fifth), item 1: the neutral, non-alarming
   counterpart to .warn-banner above (index.html's #pay-warning-note),
   shown instead of it for a captured payment that is NOT a reopened-tab
   surprise (an ordinary sequential multi-guest payment). Info-colored, no
   checkbox: this states a fact, it does not ask for a decision. Same
   fixed-semantic-token pairing (own strong/subtle text-and-background
   pair, never a theme token) every other banner in this file uses; see
   .warn-prior/.warn-body's own comment for why. */
.pay-info-banner {
  margin: 0 var(--space-5) var(--space-4);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-info);
}

/* ---------- Closeout summary (ALPHA-08) ----------
   Mirrors design/mockups/closeout-summary.html: an info-colored "not
   finalized" banner (never success, never a lock), figure cards, and two
   named warning-colored unresolved lists rather than one vague exceptions
   count. */
.closeout-page {
  max-width: 1024px;
}
.status-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
}
.status-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-info);
  /* text-on-dark, not text-on-accent: see .toast.toast-danger's comment
     above; same fixed-strong-color-as-background bug, same fix. */
  color: var(--color-text-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  flex-shrink: 0;
}
.status-title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  color: var(--color-info);
}
/* Design/QA gate finding E: same fixed-background/theme-text mismatch as
   .warn-prior/.warn-body above, on the closeout "not finalized" banner's
   fixed --color-info-subtle background. --color-info is already this
   banner's own verified text partner (.status-title and .status-icon,
   just above, already use it) at 6.0:1 against --color-info-subtle per
   design/README.md's checked-pairs table. */
.status-body {
  font-size: var(--font-size-sm);
  color: var(--color-info);
  margin-top: var(--space-1);
  max-width: 62ch;
}

/* CL6: the finalized banner reuses the .status-banner layout with the
   fixed success pair (own strong text on own subtle background), the
   same rule every other success surface follows. */
.status-banner-success {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}
.status-banner-success .status-icon {
  background: var(--color-success-strong);
}
.status-banner-success .status-title,
.status-banner-success .status-body {
  color: var(--color-success-strong);
}

/* CL6: day navigation arrows and the finalize affordances. */
.closeout-day-nav {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
#closeout-finalize-button {
  margin-top: var(--space-3);
}
.closeout-view-note {
  margin-bottom: var(--space-3);
}
.closeout-hold-at-risk {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold);
}

/* Design/QA gate finding H: freshness row (as-of timestamp + manual
   refresh) and the stale-figures note, both on the live closeout summary.
   .closeout-stale-note uses the fixed warning pair (own strong text on
   own subtle background, per the same finding-E rule the pay-warning
   banner follows), since "this number may be old" is a real caution, not
   decoration. */
.closeout-freshness {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.closeout-last-updated {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.closeout-stale-note {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
}
.section-title,
.admin-subsection-title {
  /* UX12: admin.ts's ensureSettingsSectionJump scrolls a settings
     subsection's own heading to the TOP of the viewport (block: "start"),
     and the sticky jump control it built sits at that same top edge.
     Without this, the heading would land partly behind that control
     instead of below it.
     UX36 correction (DEC-186's own owner ruling: "never covers the
     heading a jump lands on"): the previous formula (space-4 + touch-
     target-comfortable + space-4 = 88px) approximated the nav's own
     rendered height as touch-target-comfortable ALONE, omitting its own
     top/bottom padding entirely, then compared that against a budget
     meant to represent full distance from the viewport's own top. Those
     are two different reference frames, and UX36's own build-time
     measurement (harness/e2e/ux36-settings-section-jump-one-row.spec.ts)
     caught the result: on the real Menu panel, the nav's own live bottom
     edge measured 100.5px from the viewport top (sticky top:16px, plus
     padding-top ~12.75px, plus the 56px button, plus padding-bottom
     ~12.75px, plus a 2px border), while this formula only ever reserved
     88px, landing a jumped-to heading roughly 10px BEHIND the nav's own
     bottom edge, a real, measured, reproducible violation of DEC-186's
     own requirement, not merely the "8px of air" the previous version of
     this comment (and the UX36 brief's own design section) believed.
     Rebuilt to name every real term instead of approximating one of
     them: the nav's own sticky top offset (space-4), its own top padding
     (space-3), the button's own height (touch-target-comfortable), its
     own bottom padding (space-3), and a real buffer for "a little air"
     (space-4) -- 16 + 12 + 56 + 12 + 16 = 112px, which clears the
     measured 100.5px real edge with about 11px to spare, restoring the
     air this formula always intended rather than merely claimed. */
  scroll-margin-top: calc(
    var(--space-4) + var(--space-3) + var(--touch-target-comfortable) + var(--space-3) +
      var(--space-4)
  );
}
/* SET11 (DEC-130 ruling (e)): the Menu panel's own five group headings
   (General, Liquor, Beer, Wine, Cider). Deliberately its own class, never
   .section-title or .admin-subsection-title: ensureSettingsSectionJump's
   own SETTINGS_SECTION_JUMP_HEADING_SELECTOR reads exactly those two
   classes, so a group heading sharing either one would be picked up as an
   extra jump-list entry alongside the editor heading directly beneath it. */
.admin-menu-group-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-2);
  margin: var(--space-8) 0 var(--space-4);
}
.admin-menu-group:first-of-type .admin-menu-group-title {
  margin-top: 0;
}
.section-title {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  margin: var(--space-8) 0 var(--space-3);
}
.section-title:first-of-type {
  margin-top: 0;
}
.closeout-subsection-title {
  margin-top: 0;
}
.closeout-open-tabs-by-bartender {
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.section-count {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  text-transform: none;
  letter-spacing: normal;
}
.figure-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-3);
}
.figure-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4);
}
.figure-card-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.figure-card-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  margin-top: var(--space-1);
}
.figure-card-note {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-top: var(--space-2);
}
.badge-simulated {
  display: inline-flex;
  align-items: center;
  margin-top: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.closeout-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
}
@media (max-width: 860px) {
  .closeout-two-col {
    grid-template-columns: 1fr;
  }
}
/* CL7: four unresolved-state subsections (failed payments, pending
   payments, terminal registration, MyTime sync). auto-fit rather than a
   fixed column count so it wraps on its own at narrower widths, matching
   .figure-grid's own responsive approach. */
.closeout-three-col {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-6);
}
.list-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.list-card-empty {
  padding: var(--space-5);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  text-align: center;
}
/* DSC35-S8a: Scheduled specials block, adds-up card, removed specials. */
.specials-section-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: calc(-1 * var(--space-2)) 0 var(--space-3);
  max-width: 70ch;
}
.sp-head,
.sp-row,
.sp-total {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px 120px;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) var(--space-5);
}
.sp-head {
  padding-top: var(--space-3);
  padding-bottom: var(--space-3);
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.sp-row {
  border-bottom: 1px solid var(--color-border);
  min-height: var(--touch-target-comfortable);
}
.sp-name {
  font-weight: var(--font-weight-semibold);
}
.sp-rule {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.sp-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.sp-drinks {
  font-size: var(--font-size-md);
}
.sp-amt {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  color: var(--color-success-text);
}
.sp-total {
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
}
.sp-total .sp-amt {
  font-size: var(--font-size-lg);
}
.recon {
  padding: var(--space-5);
}
.recon-line {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  font-variant-numeric: tabular-nums;
}
.recon-line .recon-label {
  color: var(--color-text-secondary);
}
.recon-line.recon-sum {
  border-top: 1px solid var(--color-border-strong);
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  font-weight: var(--font-weight-bold);
}
.recon-line.recon-sub .recon-label {
  padding-left: var(--space-4);
  font-size: var(--font-size-sm);
}
.recon-foot {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: var(--space-3) 0 0;
}
details.removed-specials > summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-primary);
}
details.removed-specials > summary::-webkit-details-marker {
  display: none;
}
.rm-title {
  font-weight: var(--font-weight-semibold);
}
.rm-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.rm-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.rm-amt {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.rm-chev {
  width: 24px;
  text-align: center;
  color: var(--color-text-tertiary);
  transition: transform var(--motion-fast);
}
details[open] .rm-chev {
  transform: rotate(90deg);
}
.rm-reasons {
  border-top: 1px solid var(--color-border);
}
.rm-reason {
  display: flex;
  justify-content: space-between;
  padding: var(--space-3) var(--space-5);
  font-size: var(--font-size-sm);
}
.rm-reason-detail {
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.specials-basis {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-top: var(--space-2);
}
.activity-row,
.unresolved-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.activity-row:last-child,
.unresolved-row:last-child {
  border-bottom: none;
}
.activity-name,
.unresolved-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.activity-detail,
.unresolved-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.activity-tag {
  flex-shrink: 0;
  white-space: nowrap;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
}
.activity-tag-plain {
  color: var(--color-text-primary);
  background: transparent;
  border-color: transparent;
}
.unresolved-amount {
  text-align: right;
  flex-shrink: 0;
}
.unresolved-amount-value {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.unresolved-amount-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.flagged-reason {
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-warning-subtle-border);
}

/* ---------- ALPHA-12 multi-guest tickets and split payments ---------- */

/* Amendment 2026-08-22 (item 3): the old chips-row-across-the-top design
   is gone. Add Guest is now one small, single control inside the ticket
   rail; guests themselves render as section headers inside #ticket-lines
   (see .line-section-header below and main.ts's renderTicketLines), not
   as chips here. Hidden entirely while state.orderId is undefined; once a
   ticket is loaded, always visible, whether or not any guest has been
   named yet, so adding the first guest is still one tap. */
/* UX13: moved from its own full-width row below the header into the
   header row's own trailing chip group (index.html's own comment on
   #add-guest-row). flex-shrink: 0 so this chip group never yields its own
   width to .ticket-id beside it: .ticket-id already truncates (its own
   overflow/ellipsis rule), which is the right element to give ground,
   since a chip's own label being clipped would hide what it does. */
.add-guest-row {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: var(--chrome-gap-tight);
}
.btn-add-guest {
  height: var(--chrome-row-height);
  white-space: nowrap;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px dashed var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-accent);
  font-size: var(--font-size-chrome);
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
/* UX39 (docs/backlog.md; docs/build-briefs/UX39-ticket-header-more-
   button.md, DEC-195): replaces Discount, Payments, Manage saved cards
   and Keep tab open, collapsed behind this one button. Matches
   .btn-line-edit's own established 44x44 icon-button shape exactly
   (same property values, styles.css's own .btn-line-edit rule) rather
   than inventing a new one, per the designer's own instruction; a
   distinct class rather than reusing .btn-line-edit's own selector,
   since this button lives in a different context (the ticket header,
   not a ticket line) and CSS's own cascade should not couple the two. */
.btn-ticket-more {
  flex-shrink: 0;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-ticket-more:active {
  background: var(--color-surface-sunken);
}

/* ALPHA-12: which of the three pay modes a Confirm applies to, shown
   above the amount only for "pay my drinks" and equal-split (see
   index.html's own comment on #pay-confirm-scope). */
.pay-confirm-scope {
  padding: 0 var(--space-5);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

/* Payments-track Slice 3: "Pay with" (Use saved card), same row-is-the-
   whole-touch-target shape .pay-confirm-scope's siblings use, tappable
   like .choice-option (opens the reusable choice sheet, see main.ts's
   openPayWithCardChoice). */
.pay-confirm-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: calc(100% - var(--space-5) * 2);
  margin: var(--space-2) var(--space-5) 0;
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  cursor: pointer;
}
.pay-confirm-card-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.pay-confirm-card-value {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.pay-confirm-manage-cards-link {
  display: block;
  margin: var(--space-2) var(--space-5) 0;
  background: none;
  border: none;
  padding: 0;
  color: var(--color-accent);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
  min-height: var(--touch-target-min);
}

/* Payments-track Slice 3: card-on-file consent screen. */
.card-consent-guest {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-2);
}
.card-consent-body {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-4);
}

/* SIG1 (docs/build-briefs/SIG1-signature-and-receipt.md): the touch-drawn
   signature canvas and DEC-016's printed/emailed/none receipt choice. */
.signature-instructions {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-3);
}
.signature-canvas {
  width: 100%;
  height: 240px;
  touch-action: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.signature-actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.signature-actions .btn-secondary {
  flex: 1;
  min-height: var(--touch-target-min);
}
.signature-actions .btn-pay {
  flex: 2;
  min-height: var(--touch-target-min);
}
.receipt-choice-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.receipt-choice-actions .btn-secondary {
  min-height: var(--touch-target-min);
}
.receipt-email-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.receipt-email-input {
  min-height: var(--touch-target-min);
  font-size: var(--font-size-md);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

/* Payments-track Slice 3: the saved-cards management list. Same row shape
   as .admin-terminal-row (a plain list, one action per row), reused here
   on the ring screen's own sheet system rather than the admin console's
   classes since the two screens never share styling state. */
.saved-card-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.saved-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
.saved-card-info {
  min-width: 0;
  flex: 1;
}
.saved-card-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.saved-card-guest {
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
/* The in-row remove confirm (main.ts's renderSavedCardRemoveConfirm):
   stacked, not the parent row's own side-by-side layout, so the message
   and both buttons each get full width rather than competing for the
   same row at touch-target width. */
.saved-card-row-confirm {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
}
.saved-card-row-confirm .saved-card-info {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}

/* A plain labeled wrapper around one text input inside a sheet, matching
   .search-row's own padding/border rhythm without borrowing its
   search-specific name. */
.field-row {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

/* ---------- Reusable choice sheet (main.ts's openChoiceSheet) ----------
   One sheet, four callers: the pay-mode picker, the "pay my drinks" guest
   picker, the add-drink guest picker, and the equal-split progress list
   (a mix of tappable pending shares, rendered as .choice-option buttons,
   and plain non-interactive "Collected" rows, rendered as
   .choice-option-done divs so a completed share is never mistaken for a
   still-tappable one). */
.choice-note {
  margin: 0 var(--space-5) var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
/* DSC36 (DEC-343): why a discount was not added. The same danger tones the
   PIN pad's error line uses, so the floor reads one "this did not work" red. */
.choice-error {
  margin: 0 var(--space-5) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
}
.choice-error[hidden] {
  display: none;
}
.choice-list {
  overflow-y: auto;
  padding: 0 var(--space-5) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* The split sheet can contain twelve multi-line shares. Let the list
   scroll instead of compressing each row until its amount lines overlap. */
.choice-list > .choice-option,
.choice-list > .choice-option-done {
  flex-shrink: 0;
}
/* GATE4 follow-up: an informational-mode row (openChoiceSheet's own
   infoRows), non-interactive and never styled as a tappable or
   already-done choice (.choice-option/.choice-option-done both read as
   "you could tap this" or "this was tapped"; neither is true of a plain
   fact like "Lines: every drink moves"). Same shape and tokens
   TM1's own pre-GATE4 .tab-merge-move-list li used, generalized here so
   any informational-mode caller gets it, not only TM1. */
.choice-list > .choice-detail-row {
  flex-shrink: 0;
}
.choice-detail-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
}
.choice-detail-row-label {
  font-weight: var(--font-weight-semibold);
  min-width: 70px;
}
.choice-detail-row-detail {
  color: var(--color-text-secondary);
}
/* GATE4 follow-up: the informational-mode note AFTER the detail rows,
   never .choice-note above (existing callers already use that neutral
   tone for a differently-toned instructional note BEFORE the list). Same
   info tone TM1's own pre-GATE4 .tab-merge-hold-note used; margin matches
   .choice-note's own horizontal spacing above rather than
   .tab-merge-hold-note's zero-margin, since that one relied on an
   already-padded parent wrapper (#admin-confirm-scrim's own
   .admin-confirm-body) this sheet does not have. */
.choice-info-note {
  display: block;
  margin: 0 var(--space-5) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font-size: var(--font-size-sm);
}
.choice-option {
  min-height: var(--touch-target-comfortable);
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  text-align: left;
  cursor: pointer;
}
/* REFDISC3 (DEC-308 a): a comped drink on the refund sheet. A real disabled
   button at the same 44px row height, unlike both a tappable row (solid
   border, filled) and the tan instruction banner (filled): transparent with a
   dashed border and a regular-weight label. Never color alone: its sublabel
   says "Comped, nothing to refund", kept at the primary text color so it reads
   in low light. */
.choice-option.choice-option-comped {
  background: transparent;
  border: 1px dashed var(--color-border-strong);
  cursor: default;
}
.choice-option.choice-option-comped .choice-option-label {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-primary);
}
.choice-option.choice-option-comped .choice-option-sublabel {
  color: var(--color-text-primary);
}
.choice-option-label {
  color: var(--color-text-secondary);
}
.choice-option-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.choice-option-sublabel {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
/* A collected share (or, as of Amendment 2026-08-22 seventh, a guest with
   no outstanding balance in the "pay my drinks" picker): same shape as a
   tappable option so the list reads consistently, but never a <button>
   and visually marked done via the same success token pairing
   .state-btn.paid uses, never color alone (the sublabel's own literal
   "Collected"/"Paid"/"No drinks yet" text carries the state too). */
.choice-option-done {
  min-height: var(--touch-target-comfortable);
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-success-subtle-border);
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
}
.choice-option-done .choice-option-sublabel {
  color: var(--color-success-strong);
}
/* Architect-gate CRITICAL correction ("abandoned split deadlock"),
   2026-08-21: the split-progress sheet's own "Cancel split" row, the exit
   an active plan never had before this fix. Same fixed semantic
   background/text token pairing .choice-option-done already establishes
   for "success," here for "danger" instead: never a component-surface/
   text-token pairing (design/README.md's own checked-pairs rule), and
   distinguished from an ordinary tappable share by more than color alone
   (its own literal "Cancel split" label plus a distinct sublabel, matching
   .choice-option-done's identical "never color alone" precedent). */
.choice-option-danger {
  border-color: var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.choice-option-danger .choice-option-sublabel {
  color: var(--color-danger-strong);
}
/* M4's refund picker rows reuse .choice-option and toggle .selected, the
   same accent-subtle pairing .liquor-row.selected established, with the
   same explicit accent-strong text (never the ambient theme text color)
   and never color alone: main.ts swaps the selected row's sublabel to a
   literal "Refunding ..." string alongside the visual change. */
.choice-option.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
.choice-option.selected .choice-option-label,
.choice-option.selected .choice-option-sublabel {
  color: var(--color-accent-strong);
}
/* DOCSBUG6: the refund sheet's notes and its two lists scroll as one region
   between the pinned header and footer. The lists inside do not scroll or
   shrink themselves, so a card row can never be drawn over by the drink list
   (.choice-list's own overflow-y: auto let each list shrink below its rows). */
.refund-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
.refund-body > .choice-list {
  overflow: visible;
  flex-shrink: 0;
}
/* The refund sheet's derived total: the sum of the selected rows' own
   server-supplied figures, restated where the confirm tap happens. */
.refund-total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-2) var(--space-1);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

/* PL1: the payment-link sheet's status line and its selectable url. A
   plain, touch-selectable block of text (a long-press on the floor's
   tablet selects it for copy) is sufficient this slice; no QR code. */
.payment-link-status {
  padding: var(--space-2) var(--space-1);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.payment-link-url {
  padding: var(--space-3) var(--space-2);
  margin: var(--space-1) 0 var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  word-break: break-all;
  user-select: text;
  -webkit-user-select: text;
}

/* ---------- Equal-split setup: share-count stepper ---------- */
.split-setup-body {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}
.split-setup-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.split-setup-stepper {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.btn-stepper {
  width: var(--touch-target-comfortable);
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.split-setup-count {
  min-width: 56px;
  text-align: center;
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
}
.split-setup-preview {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  text-align: center;
  min-height: 1.5em;
}

@media (max-width: 480px) {
  .tile-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
  .topbar {
    padding: var(--space-3);
  }
  .ticket-header,
  .ticket-lines,
  .ticket-totals,
  .ticket-actions {
    padding-left: var(--space-3);
    padding-right: var(--space-3);
  }
}

/* ---------- Inventory track (track/inventory) Slice 2: Counts ----------
   The Settings > Counts panel (section list, start/resume, history) and
   the count-session sheet (walk + review) and history-detail sheet. Built
   entirely on the same .scrim, .sheet, .admin-form-body, and
   .admin-chip-select classes every other admin sheet in this file
   already uses; nothing below introduces a new visual language. */

.admin-count-section-chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.admin-count-section-chip.inactive {
  border-color: var(--color-border);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}

.admin-count-history-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.admin-count-history-row {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  text-align: left;
  cursor: pointer;
}

/* T14 (docs/backlog.md): the MyTime ambiguous-reconciliation queue. */
.admin-reconciliation-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.admin-reconciliation-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.admin-reconciliation-row-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.admin-reconciliation-guest-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-reconciliation-reason {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-reconciliation-matches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Count-session sheet: progress header. */
.admin-count-progress {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.admin-count-progress-track {
  margin-top: var(--space-2);
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  overflow: hidden;
}
.admin-count-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  transition: width var(--motion-base) var(--motion-easing-standard);
}

/* INV2 (docs/backlog.md, PRD P0.7): assigned counter, reassign, and
   blind/visible mode, in the shared sheet header. */
.admin-count-governance-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}
.admin-count-assigned-counter {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1 1 auto;
}
#admin-count-reassign-panel {
  margin-top: var(--space-2);
}

/* Count-session sheet: the walk view's one-product-at-a-time card. Large,
   numeric-pad-friendly entry per design/principles.md's "words read in
   under two seconds" and CLAUDE.md's touch-only inputmode rule: the
   quantity field is the biggest, most prominent control on this card. */
.admin-count-product-card {
  margin-top: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}
.admin-count-product-name {
  display: block;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
.admin-count-product-status {
  margin: var(--space-1) 0 var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-count-quantity-input {
  width: 100%;
  height: var(--touch-target-primary);
  margin-bottom: var(--space-3);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  text-align: center;
}
.admin-count-quantity-input:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.admin-count-footer-row {
  display: flex;
  gap: var(--space-3);
}
.admin-count-footer-row .btn-primary,
.admin-count-footer-row .btn-secondary {
  flex: 1;
}
.admin-count-review-link {
  margin-top: var(--space-2);
}

/* Review and history-detail: the shared grouped variance list. */
.admin-count-review-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.admin-count-review-section-heading {
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.admin-count-review-section-heading:first-child {
  margin-top: 0;
}
.admin-count-review-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.admin-count-review-row-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-count-review-row-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

@media (max-width: 900px) {
  .admin-count-product-card {
    padding: var(--space-4);
  }
  .admin-count-quantity-input {
    height: var(--touch-target-comfortable);
    font-size: var(--font-size-xl);
  }
}

/* ---------- U1/U3: the three-tab Edit User modal ----------
   An ADMIN surface, run from a laptop per CLAUDE.md's scoped touch-only
   rule (owner ruling 2026-08-27), so a dense grid and hover affordances
   are legitimate here. Every control is still a real, tappable target at
   the same sizes the rest of this stylesheet uses, because the same
   screen has to stay usable on a tablet's software keyboard. */
.admin-user-edit-sheet {
  max-width: 760px;
  max-height: min(860px, 94vh);
}
.admin-user-edit-tabs {
  margin-top: var(--space-4);
  margin-bottom: 0;
}
.admin-user-edit-footer {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.admin-user-edit-footer-actions {
  margin-left: auto;
  display: flex;
  gap: var(--space-3);
}
.admin-user-active-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-comfortable);
  cursor: pointer;
}
.admin-user-active-toggle input[type="checkbox"] {
  width: 24px;
  height: 24px;
  margin: 10px;
}
.admin-user-active-toggle-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.admin-user-active-note {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  max-width: 22em;
}
.admin-user-location-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-user-location-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.admin-user-location-name {
  font-weight: var(--font-weight-semibold);
}

.admin-permission-toolbar {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  flex-wrap: wrap;
}
.admin-permission-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.admin-permission-empty {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.admin-permission-group {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.admin-permission-group-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border: none;
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  text-align: left;
  cursor: pointer;
}
.admin-permission-group-caret {
  width: 1em;
  flex-shrink: 0;
  color: var(--color-text-secondary);
}
.admin-permission-group-count {
  margin-left: auto;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
/* The GROUP rollup. Deliberately a separate control from the leaf
   three-way picker below: this one is a read-only summary of the
   children ("all the same" or "mixed"), never something you can set.
   Conflating the two is the main design risk U3 names. */
.admin-permission-rollup {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-secondary);
  background: var(--color-surface);
  white-space: nowrap;
}
.admin-permission-rollup-mixed {
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.admin-permission-rows {
  display: flex;
  flex-direction: column;
}
.admin-permission-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.admin-permission-row-main {
  flex: 1 1 20em;
  min-width: 0;
}
.admin-permission-row-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.admin-permission-row-controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
/* The source badge U3 calls "the one place not to copy the reference":
   without it an Admin cannot tell whether access came from a role or was
   set on this one person. */
.admin-permission-source {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.admin-permission-source-individual {
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.admin-permission-planned {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.admin-permission-capped {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  max-width: 20em;
}

/* DSC5: the discount attribute-scope editor.
   FOUR separately bordered, separately headed groups on their own row
   below the discount's own fields. The separation is not decoration: "what
   you stock" and "how it is sold" share two of their values and differ on
   the rest, so a merged list would look almost right and price the wrong
   lines. Each group keeps its own box and its own legend at every width. */
.admin-discount-scope {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  width: 100%;
}
.admin-discount-scope-summary {
  flex: 1 1 100%;
  margin: 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.admin-discount-scope-group {
  flex: 1 1 12rem;
  min-width: 10rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3) var(--space-3);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.admin-discount-scope-group legend {
  padding: 0 var(--space-2);
  color: var(--color-text-secondary);
  font-weight: 600;
  font-size: var(--font-size-sm);
}
/* DSC35-S5: the Schedule and Applies-to editor inside a discount's row.
   Tokens only. Every chip, switch and list is at least the touch minimum.
   A chip that is on says so with a check mark as well as colour. */
.admin-discount-special-wrap {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.admin-discount-special-toggle {
  align-self: flex-start;
  min-height: var(--touch-target-min);
}
.admin-special {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.admin-special-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.admin-special-summary-label,
.admin-special-group-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.admin-special-summary-text {
  font-size: var(--font-size-md);
  color: var(--color-text-primary);
}
.admin-special-body,
.admin-special-applies,
.admin-special-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.admin-special-body[hidden],
.admin-special-applies[hidden],
.admin-special-note[hidden],
.admin-special-warning[hidden] {
  display: none;
}
.admin-special-heading {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.admin-special-help {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-special-zone {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-special-warning {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
}
.admin-special-link {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-1);
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-decoration: underline;
  cursor: pointer;
}
.admin-special-switch {
  align-items: center;
}
.admin-special-switch-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.admin-special-switch-text {
  display: flex;
  flex-direction: column;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.admin-special-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.admin-special-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.admin-special-chip-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.admin-special-chip:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.admin-special-pair {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3) var(--space-4);
}
.admin-special-off {
  opacity: 0.6;
}
.admin-special-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1 1 10rem;
}
.admin-special-yearly {
  min-height: var(--touch-target-min);
}
.admin-special-covers {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.admin-special-picker {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 22rem;
  overflow-y: auto;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.admin-special-picker[hidden] {
  display: none;
}
.admin-special-pick {
  align-self: flex-start;
  min-height: var(--touch-target-min);
}
.admin-special-note {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-info-subtle-border);
  background: var(--color-info-subtle);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
}
/* DSC35-F3: the dark themes keep the light info tint, so the light primary text sat on a light box (about 1.1:1).
   Dark themes draw the note on the sunken surface instead; all three colours are tokens. */
[data-theme="snipsip-ink"] .admin-special-note,
[data-theme="charcoal"] .admin-special-note {
  background: var(--color-surface-sunken);
  border-color: var(--color-info-text);
  color: var(--color-text-primary);
}
.admin-special-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
}
.admin-special-save {
  min-height: var(--touch-target-primary);
}
.admin-special-status {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-special-problem {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
.admin-special-ok {
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
.admin-discount-schedule-status-shape {
  margin-inline-end: var(--space-1);
}

/* RT1: the role-template list in People and access. Rows are real touch
   targets at the --touch-target-comfortable tier, the same tier every
   other tappable list row in Settings uses, so e2e/usability.spec.ts's
   44px sweep passes for the same reason the rest of the panel does
   rather than by coincidence. */
.admin-role-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.admin-role-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  text-align: left;
  cursor: pointer;
}

/* RT2: the row splits into an open-the-editor button plus a switch-off
   control, so the row itself is no longer the button. The open half
   carries the touch-target floor, since that is what a finger lands on. */
.admin-role-row-open {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex: 1;
  min-height: var(--touch-target-comfortable);
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font-size: inherit;
  text-align: left;
  cursor: pointer;
}

/* A switched-off role stays visible and readable rather than vanishing,
   the same retire-never-hide treatment the deactivated-item lists use:
   an Admin has to be able to find it to switch it back on. */
.admin-role-row-retired .admin-role-row-name {
  color: var(--color-text-secondary);
}

.admin-role-row:hover {
  border-color: var(--color-border-strong);
}

.admin-role-row-name {
  font-weight: var(--font-weight-medium);
}

.admin-role-row-count {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

/* AU8 (docs/backlog.md): the manager-exceptions queue's floor-facing
   surface. Open Tabs' own badge count, the ticket rail's own banner, and
   the shared global sheet's rows and inline resolve panel. */
.badge-exception-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  margin-left: var(--space-2);
  padding: 0 6px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-full);
}

.ticket-manager-exception-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 0 0 var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
}
.ticket-manager-exception-text {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-warning-strong);
}

/* PAY5-F1 (docs/backlog.md; docs/build-briefs/PAY5-F1-terminal-notice-in-
   topbar.md): retires the PAY7 ticket-header chip's own .chip-warning/
   .ticket-terminal-not-set-detail/.ticket-terminal-not-set-text rules
   (they measured 19x22px, failing e2e/usability.spec.ts's 44px floor) and
   replaces them with the top bar's own terminal segment below. */

.manager-exceptions-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.manager-exception-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.manager-exception-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.manager-exception-tab-name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.manager-exception-amount {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}
.manager-exception-kind {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-primary);
}
.manager-exception-help {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
/* PAY14 (Section 8.2, D7 required change 1, approved by the
   ui-ux-designer in round 2): a disabled Resolve must look disabled.
   Scoped to the queue so no other screen changes; the same two tokens
   .btn-primary:disabled uses. It also makes the short busy state while a
   resolve is in flight look disabled, which is correct. */
.manager-exception-row .btn-secondary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
}
.manager-exception-age {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.manager-exception-resolve-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}
.manager-exception-note-input {
  width: 100%;
  min-height: var(--touch-target-primary);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
}
.manager-exception-resolve-actions {
  display: flex;
  gap: var(--space-2);
}
/* PAY14 Slice B (Section 8.2, D4-R): the Clear hold picker's rows, each an
   .ack-row label with its radio at the 44px floor (.ack-checkbox) and the
   whole row the tap target. The group sits inside the panel's own padding,
   so the rows drop .ack-row's sheet-edge margin. */
.manager-exception-clear-hold-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.manager-exception-clear-hold-group .ack-row {
  margin: 0;
}
.manager-exception-resolve-actions .btn-primary,
.manager-exception-resolve-actions .btn-secondary {
  flex: 1;
}

/* PO6 Slice 1 (docs/adr/ADR-003-purchasing-and-receiving-surfaces.md;
   docs/build-briefs/PO6-S1-order-list-and-detail.md). Read-only purchase
   order list and detail, mirroring .admin-user-row/.admin-user-list's own
   row-per-record shape rather than a <table>, matching every other list
   in this codebase (see admin.ts's own vendor/user lists). */
.purchasing-order-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.purchasing-order-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-height: var(--touch-target-comfortable);
}
.purchasing-order-vendor {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  flex: 2;
  min-width: 160px;
}
.purchasing-order-status {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 140px;
}
.purchasing-order-line-count,
.purchasing-order-estimated-total {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 100px;
}
.purchasing-order-detail-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
  margin: var(--space-4) 0;
}
.purchasing-order-detail-summary dt {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.purchasing-order-detail-summary dd {
  margin: 0;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.purchasing-status-history-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.purchasing-status-history-row {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.purchasing-status-history-headline {
  font-weight: var(--font-weight-semibold);
}
.purchasing-status-history-reason,
.purchasing-status-history-exception-reason,
.purchasing-status-history-resolution {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.purchasing-status-history-variance {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* PO6-S2-F1: the order detail's own line list, mirroring
   .purchasing-order-row's shape one level down. */
.purchasing-order-line-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.purchasing-order-line-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.purchasing-order-line-product {
  font-weight: var(--font-weight-semibold);
  flex: 2;
  min-width: 160px;
}
.purchasing-order-line-quantity,
.purchasing-order-line-unit-cost,
.purchasing-order-line-extended-cost {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 100px;
}

/* PO6 Slice 5 (docs/adr/ADR-003-purchasing-and-receiving-surfaces.md,
   Decision 4 slice 5; docs/build-briefs/PO6-S5-corrections-and-
   exceptions.md). Each order line's own nested "Receipts" list, and the
   inline per-receipt correction form. */
.purchasing-order-line-receipts {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}
.purchasing-order-line-receipt-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
}
.purchasing-order-line-receipt-summary {
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 160px;
}
.purchasing-order-line-receipt-correction-form {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.purchasing-order-line-receipt-correction-quantity-input,
.purchasing-order-line-receipt-correction-cost-input {
  width: 110px;
  flex: 0 0 auto;
}
.purchasing-order-line-receipt-correction-reason-input {
  flex: 1 1 200px;
}
.purchasing-order-line-receipt-correction-error,
.purchasing-order-line-receipt-correction-status {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
}
.purchasing-order-line-receipt-correction-approval {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* PO6 Slice 2 (docs/adr/ADR-003-purchasing-and-receiving-surfaces.md;
   docs/build-briefs/PO6-S2-cart-and-placement.md). The cart screen:
   proposals, product search results, and cart lines grouped by vendor.
   Mirrors .purchasing-order-list/.purchasing-order-row's own row-per-
   record shape. */
.purchasing-cart-proposal-list,
.purchasing-cart-product-results,
.purchasing-cart-vendor-groups,
.purchasing-cart-placed-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.purchasing-cart-proposal-row,
.purchasing-cart-product-result-row,
.purchasing-cart-placed-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target-comfortable);
}
.purchasing-cart-proposal-product,
.purchasing-cart-product-result-name,
.purchasing-cart-placed-vendor {
  font-weight: var(--font-weight-semibold);
  flex: 2;
  min-width: 160px;
}
.purchasing-cart-proposal-sources,
.purchasing-cart-proposal-onhand,
.purchasing-cart-proposal-par,
.purchasing-cart-proposal-suggested,
.purchasing-cart-placed-status,
.purchasing-cart-placed-total {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 100px;
}
/* UX16-F2 (docs/build-briefs/UX16-F2-negative-on-hand-shown-not-hidden.md;
   DEC-178): a plain warning beside a negative on-hand figure on the
   proposals row, never hidden or refused. Full-width so it reads as its
   own line under the row's other cells rather than competing with them
   for the same flex slot. */
.purchasing-cart-proposal-onhand-warning {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-left: 3px solid var(--color-warning-strong);
  padding: var(--chrome-gap-hairline) var(--space-2) var(--chrome-gap-hairline) var(--space-3);
}

/* UX16 (DEC-058) criterion 2: the "Add all below par to cart" button
   sits beside the "Draft proposals" heading rather than below it, the
   same header/action row shape .admin-panel-header already uses. */
.purchasing-cart-proposals-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.purchasing-cart-proposals-header .section-title {
  margin: 0;
}
/* INV8 (DEC-176) Section 2.5: the sort picker, sized to its own text
   rather than stretching across the header row. */
.purchasing-cart-proposals-header select.field-input {
  width: auto;
  min-width: 200px;
}
/* UX65: the "Add all below par to cart" disabled-reason text, on its own
   line within the flex-wrapped header row rather than crowding the
   button and sort picker, the same flex-basis:100% shape
   .purchasing-cart-proposal-unit-hint already uses. Margin reset because
   .admin-field-help (reused, not invented) carries its own top/bottom
   margin meant for a stacked field, not a header row. */
.purchasing-cart-proposals-header .purchasing-cart-add-all-below-par-reason {
  flex-basis: 100%;
  margin: 0;
}
/* INV8 (DEC-176) Section 2.5: the "set a container size or keg size to
   compare against par" hint, on its own line within the flex-wrapped
   proposal row rather than competing for space with the figures above
   it. */
.purchasing-cart-proposal-unit-hint {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-style: italic;
}

/* One card per vendor, so the grouping placement will produce -- one
   purchase order per card -- is visible before any of them is placed
   (ADR-003 Decision 4, Slice 2). UX66 part C
   (design/mockups/purchasing-cart-flow.html): a blocked card's border
   reads amber, a ready card's reads green, matching design/
   principles.md rule 1 (state lives in color, weight, and shape
   together, never color alone -- the status text and icon-equivalent
   weight change with it below, color is never the only signal). */
.purchasing-cart-vendor-group {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
}
.purchasing-cart-vendor-group--blocked {
  border-color: var(--color-warning-subtle-border);
}
.purchasing-cart-vendor-group--ready {
  border-color: var(--color-success-subtle-border);
}
.purchasing-cart-vendor-group-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.purchasing-cart-vendor-group-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.purchasing-cart-vendor-group-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
}
.purchasing-cart-vendor-group-status--blocked {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
}
.purchasing-cart-vendor-group-lines {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
/* UX66 part C: every blocker the group's own lines carry, one row each,
   with a direct fix link where one exists -- design/principles.md rule
   3, extended one step further: blocked with a visible way to stop
   being blocked, not just the reason. */
.purchasing-cart-vendor-group-blockers {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}
.purchasing-cart-vendor-group-blocker-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.purchasing-cart-vendor-group-blocker-text {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
  margin: 0;
}
/* CORE9: one heading, one list, one fix button, instead of a row and a button per blocker. */
.purchasing-cart-vendor-group-blocker-heading {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-warning-strong);
}
.purchasing-cart-vendor-group-blocker-list {
  margin: 0;
  padding-inline-start: var(--space-5);
}
.purchasing-cart-vendor-group-blocker-list .purchasing-cart-vendor-group-blocker-text {
  display: list-item;
}
.purchasing-cart-vendor-group-blocker-fix {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
  white-space: nowrap;
}
/* UX66 part C, design/principles.md rule 2 (one thumb, one obvious next
   action -- read here as one obvious mouse/pointer action, an admin
   surface per CLAUDE.md's touch-only scoping): the primary Place button
   gets its own footer row, full width, visually separated from the
   lines above it rather than sharing btn-compact sizing with every
   other button on the card. */
.purchasing-cart-vendor-group-footer {
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-3);
}
.purchasing-cart-vendor-group-place {
  width: 100%;
  min-height: var(--touch-target-comfortable);
  font-size: var(--font-size-base);
}

/* UX66 part C: the confirmation banner shown immediately after a
   vendor's order places (design/mockups/purchasing-cart-flow.html),
   reading as a distinct event rather than a row appended to "Just
   placed" below it. */
.purchasing-cart-confirmation-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
}
.purchasing-cart-confirmation-title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  color: var(--color-success-strong);
  margin: 0 0 var(--space-1) 0;
}
.purchasing-cart-confirmation-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: 0;
}
.purchasing-cart-confirmation-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.purchasing-cart-line-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
.purchasing-cart-line-product {
  font-weight: var(--font-weight-semibold);
  flex: 2;
  min-width: 160px;
}
.purchasing-cart-line-quantity-input {
  width: 90px;
  flex: 0 0 auto;
}
.purchasing-cart-line-unit-cost {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 100px;
}
.purchasing-cart-line-blockers {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
}

/* PO6 Slice 4 (docs/adr/ADR-003-purchasing-and-receiving-surfaces.md;
   docs/build-briefs/PO6-S4-receiving.md). The receiving screen. FLOOR
   RULE (DEC-053: chrome compressed first, content last): one compact
   banner line each for an open exception or a fully-received order, and
   every line's own entry row is a single wrapping flex row rather than a
   grid of labeled fields, so a small tablet viewport spends its height on
   the lines themselves. */
.purchasing-receiving-exception {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.purchasing-receiving-fully-received {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.purchasing-receiving-line-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.purchasing-receiving-line-row {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
}
.purchasing-receiving-line-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.purchasing-receiving-line-product {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.purchasing-receiving-line-quantities,
.purchasing-receiving-line-receipt-count {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.purchasing-receiving-line-closed {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.purchasing-receiving-line-entry {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.purchasing-receiving-line-quantity-input {
  width: 110px;
  flex: 0 0 auto;
}
.purchasing-receiving-line-cost-input {
  width: 110px;
  flex: 0 0 auto;
}
.purchasing-receiving-line-error {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
}

/* PO13: the "They sent something else" control on a receiving line, and the substitution marks. */
.purchasing-receiving-substitute {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}
.purchasing-receiving-substitute-panel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
  width: 100%;
  max-width: 480px;
}
.purchasing-receiving-substitute-panel[hidden] {
  display: none;
}
.purchasing-receiving-substitute-panel > .btn-secondary {
  align-self: flex-start;
}
.purchasing-receiving-substitute-results {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.purchasing-receiving-substitute-result-row,
.purchasing-receiving-substitute-chosen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-2) var(--space-4);
  min-height: var(--touch-target-comfortable);
}
.purchasing-receiving-substitute-result-name,
.purchasing-receiving-substitute-chosen-name {
  font-weight: var(--font-weight-semibold);
}
.purchasing-substitution-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.purchasing-substitution-flag {
  margin-left: var(--space-3);
  color: var(--color-warning-strong, var(--color-text-secondary));
  background: var(--color-warning-subtle, transparent);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

/* PO6 Slice 6 (docs/adr/ADR-003-purchasing-and-receiving-surfaces.md;
   docs/build-briefs/PO6-S6-outside-system-orders.md). Recording an order
   placed outside the product. FLOOR RULE like .purchasing-receiving-*
   above: comfortable touch targets throughout, the entry panel a single
   wrapping flex row rather than a labeled-field grid. */
.purchasing-outside-order-product-results,
.purchasing-outside-order-recorded-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.purchasing-outside-order-product-result-row,
.purchasing-outside-order-recorded-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target-comfortable);
}
.purchasing-outside-order-product-result-name,
.purchasing-outside-order-recorded-product {
  font-weight: var(--font-weight-semibold);
  flex: 2;
  min-width: 160px;
}
.purchasing-outside-order-recorded-quantity,
.purchasing-outside-order-recorded-cost,
.purchasing-outside-order-recorded-reference {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 1;
  min-width: 100px;
}
.purchasing-outside-order-entry {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
}
.purchasing-outside-order-entry-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.purchasing-outside-order-entry-product {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.purchasing-outside-order-entry > .field-input,
.purchasing-outside-order-entry > .admin-chip-select {
  margin-top: var(--space-3);
}
.purchasing-outside-order-quantity-input,
.purchasing-outside-order-cost-input {
  width: 140px;
}
.purchasing-outside-order-entry-error {
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
  margin-top: var(--space-2);
}
#purchasing-outside-order-submit {
  margin-top: var(--space-3);
}
/* VEN6 (docs/backlog.md, owner report on stage0, 2026-09-23): the vendor
   offer row's summary, preferred badge/button, and retired badge are
   three separate elements (renderBottleVendorOfferList, admin.ts) with
   no rule of their own here, so they rendered flush against each other
   with no visible gap at all -- the owner's own example, "ABC2GOPreferred"
   with no space between the vendor name and the badge. A flex row with
   the chrome-density gap (DEC-053's own --chrome-gap-target, the same
   token .admin-void-reason-row's gap variant uses at this row's own
   comfortable-density tier) is the whole fix: no color, weight, or
   content changes, only the missing separation between siblings. */
.admin-vendor-offer-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--chrome-gap-target);
}

/* ---------- STK1 (docs/build-briefs/STK1-86-setter.md; DEC-269): the 86
   setter. Floor 86 list button and right-anchored panel, the Undo toast,
   and Settings' Stock column, 86'd status and editor control. Built from
   design/mockups/core-86-setter-*.html; tokens only, no new colours. ---- */
.stock86-done:focus-visible,
.stock86-btn-back:focus-visible,
.stock86-btn-mark:focus-visible,
.stock86-chip:focus-visible,
.stock86-search:focus-visible,
.stock86-toast button:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.stock86-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(30, 20, 12, 0.38);
  z-index: var(--z-scrim);
}
.stock86-backdrop[hidden] {
  display: none;
}
.stock86-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(640px, 100vw);
  background: var(--color-bg);
  z-index: var(--z-sheet);
  box-shadow: var(--shadow-3);
  display: flex;
  flex-direction: column;
}
.stock86-head {
  height: 72px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
.stock86-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  margin: 0;
  line-height: 1.1;
}
.stock86-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.stock86-done {
  height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border-radius: var(--radius-md);
  border: none;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-bold);
}
.stock86-section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-5) var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  flex-shrink: 0;
}
.stock86-section-title b {
  color: var(--color-danger-strong);
}
#stock86-out-list {
  max-height: 34%;
  overflow-y: auto;
  flex-shrink: 0;
}
/* CORE7: the Out of stock section is the tile's OUT badge as a list: information, not an alarm, so the count is
   not red and the section is shorter than Out right now. */
.stock86-section-title--quiet b {
  color: var(--color-text-secondary);
}
#stock86-oos-list {
  max-height: 22%;
  overflow-y: auto;
  flex-shrink: 0;
}
.stock86-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-2) var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
.stock86-row--fresh {
  background: var(--color-danger-subtle);
}
.stock86-row-main {
  flex: 1;
  min-width: 0;
}
.stock86-row-name {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-md);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.stock86-row-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.stock86-btn-back,
.stock86-btn-mark {
  flex-shrink: 0;
  height: 52px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-weight: var(--font-weight-bold);
}
.stock86-btn-back {
  border: 1px solid var(--color-success);
  color: var(--color-success-text);
}
.stock86-btn-mark {
  min-width: 112px;
  border: 1px solid var(--color-danger);
  color: var(--color-danger-strong);
}
.stock86-btn-back:disabled,
.stock86-btn-mark:disabled {
  opacity: 0.55;
}
.stock86-empty {
  padding: var(--space-3) var(--space-5);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.stock86-findrow {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  flex-shrink: 0;
}
.stock86-search {
  flex: 1;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  padding: 0 var(--space-4);
  font-size: var(--font-size-md);
  min-width: 0;
}
.stock86-chips {
  display: flex;
  gap: var(--space-2);
  padding: 0 var(--space-5) var(--space-2);
  overflow-x: auto;
  flex-shrink: 0;
}
.stock86-chip {
  flex-shrink: 0;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.stock86-chip[aria-pressed="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.stock86-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.stock86-toast:not([hidden]) {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5);
}
.stock86-toast button {
  pointer-events: auto;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(255, 255, 255, 0.5);
  background: transparent;
  color: var(--color-text-on-dark);
  font-weight: var(--font-weight-bold);
}
/* Settings > Inventory: 86'd status (solid, white text), tinted row, the
   Stock column button. */
.inv-status-flagged86 {
  background: var(--color-danger-fill);
  color: var(--color-text-on-dark);
  border-color: var(--color-danger-fill);
}
.inv-table tbody tr.inv-row--86 {
  background: var(--color-danger-subtle);
}
.inv-col-stock {
  white-space: nowrap;
}
.inv-stock-btn {
  height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  border: 1px solid var(--color-danger);
  color: var(--color-danger-strong);
}
.inv-stock-btn--back {
  border-color: var(--color-success);
  color: var(--color-success-text);
}
.inv-stock-btn:disabled {
  opacity: 0.55;
}
.inv-stock-btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* Item editor, Stock & vendor tab: "On the floor right now". */
.stock86-segment {
  display: flex;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.stock86-segment button {
  flex: 1;
  height: var(--touch-target-comfortable);
  border: none;
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
}
.stock86-segment button[aria-checked="true"] {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.stock86-segment button[data-value="out"][aria-checked="true"] {
  background: var(--color-danger-fill);
  color: var(--color-text-on-dark);
}
.stock86-segment button:disabled {
  opacity: 0.55;
}
.stock86-segment button:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus) inset;
}
.stock86-editor-since {
  margin: var(--space-2) 0 0;
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-strong);
}
.stock86-row--gone {
  background: var(--color-success-subtle);
}
.admin-search-row--with-chips {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.admin-search-row--with-chips .search-input {
  flex: 1;
  min-width: 0;
}
/* ---------- M5: change a drink's price at the till ----------
   (docs/build-briefs/M5-till-price-change.md; DEC-282;
   design/mockups/m5-price-override.html). No new colours: the info colour
   marks "price changed", so it is never mistaken for a discount (green) or
   a problem (warning). Shares .scrim/.sheet/.sheet-header with every other
   floor sheet; only what is unique to this sheet is below. */
.price-change-sheet {
  max-width: 780px;
  max-height: min(740px, 94vh);
}
.po-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  padding: var(--space-3) var(--space-5);
  overflow-y: auto;
}
.po-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.po-menuprice {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}
.po-menuprice-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.po-menuprice-value {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.po-math {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-top: -6px;
}
.po-new {
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-2) var(--space-4);
  text-align: right;
}
.po-new.is-set {
  border-color: var(--color-accent-strong);
}
.po-new-label {
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  text-align: left;
}
.po-new-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.po-new.is-empty .po-new-value {
  color: var(--color-text-tertiary);
}
.po-diff {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  /* UX102: the delta line owns its 20px whether or not it has text, so the sheet does not shift 2px when it appears. */
  line-height: 20px;
  min-height: 20px;
  text-align: right;
  margin-top: 2px;
}
.po-diff.is-changed {
  color: var(--color-info-text);
}
/* M5-F1: the below-cost line sits directly under the "less than the menu
   price" line, amber, ONE line, left aligned like the closeout tag, with a
   bold lead. It is a warning, never a block. */
.po-belowcost {
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-warning-text);
  text-align: left;
  margin-top: var(--space-1);
}
.po-belowcost strong {
  font-weight: var(--font-weight-bold);
}
.po-presets {
  display: flex;
  gap: var(--space-2);
}
.po-preset {
  flex: 1;
  height: var(--touch-target-min);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.po-pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--touch-target-gap-min);
}
.po-key {
  /* Constant, never resized mid-entry. 48px: the pad, chips and the one-line
     below-cost warning (M5-F1) fit the floor tablet with no sheet scrolling. */
  height: calc(var(--touch-target-min) + var(--space-1));
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
}
.po-key:active {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.po-key-aux {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.po-heading {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.po-required {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}
.po-required.is-picked {
  color: var(--color-success-text);
}
.po-reasons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.po-reason {
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  overflow-wrap: anywhere;
}
.po-reason.is-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
  box-shadow: inset 0 0 0 1px var(--color-accent-strong);
}
/* AU14-F5 designer review: the picked reason carries a non-colour cue too, a check
   mark and a heavier border, so it never reads by colour alone. */
.reason-sheet .po-reason.is-on {
  box-shadow: inset 0 0 0 2px var(--color-accent-strong);
}
.reason-sheet .po-reason.is-on::before {
  content: "\2713\00a0";
}
.po-note {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
}
.po-note-info {
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
}
.po-note-warn {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-left: 3px solid var(--color-warning-strong);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
}
.po-note-plain {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.po-footer {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5) var(--space-4);
  border-top: 1px solid var(--color-border);
  flex-shrink: 0;
  align-items: center;
}
.po-footer .btn-secondary {
  flex: 1;
}
.po-footer .btn-primary {
  flex: 2;
  height: var(--touch-target-primary);
  font-size: var(--font-size-md);
}
@media (max-width: 900px) {
  .po-body {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }
  .price-change-sheet {
    max-height: 94vh;
  }
}
/* The "Price changed" strip on a ticket row: the same shape as the green
   Auto special strip, in the info colour. */
.line-price.has-price-change {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: var(--line-height-tight);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-bold);
}
.line-price-was {
  text-decoration: line-through;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-xs);
}
/* M5-R10: the strip is one button, the whole location is the touch target. Left:
   what changed and why; right: the change count and "History". */
.line-price-change {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-width: 0;
  min-height: 56px;
  margin-top: 2px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.lpc-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.lpc-l1 {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.tag-price-changed,
.line-price-change-name,
.line-price-change-amount {
  font: inherit;
  color: inherit;
}
.line-price-change-amount {
  white-space: nowrap;
}
.line-price-change-why {
  font-size: var(--font-size-xs);
  color: var(--color-info);
  overflow-wrap: anywhere;
}
.lpc-go {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding-left: var(--space-3);
  border-left: 1px solid var(--color-info-subtle-border);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}
.lpc-count {
  background: var(--color-info);
  color: #ffffff;
  border-radius: var(--radius-full);
  padding: 1px 8px;
  font-size: var(--font-size-xs);
}
.totals-price-changes[hidden] {
  display: none;
}
.totals-price-changes {
  display: block;
  color: var(--color-info);
  font-weight: var(--font-weight-semibold);
}
/* One quiet line on the manager PIN pad naming what is being approved. */
.pin-entry-context {
  font-size: var(--font-size-sm);
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-3);
}

/* AU14-F4 / DEC-276 (design/mockups/dec276-required-reasons.html): the
   required-reason sheet, the grey "Reopened" record strip and the closeout's
   "Actions with a reason" list. No new colours: tiles, notes and footer reuse
   the Change price sheet's .po-* pieces; grey (surface-sunken) is the record
   colour on purpose, because green already means a discount, amber a problem
   and blue a price change. */
.reason-sheet {
  max-width: 640px;
  max-height: min(740px, 94vh);
}
.rs-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  overflow-y: auto;
}
.rs-context {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}
.rs-context-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.rs-context-main b {
  font-size: var(--font-size-md);
  overflow-wrap: anywhere;
}
.rs-context-main span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.rs-context-change {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  white-space: nowrap;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.rs-context-change strong {
  font-size: var(--font-size-lg);
  color: var(--color-text-primary);
}
.rs-extra {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.rs-extra[hidden] {
  display: none;
}
.rs-extra-action {
  width: 100%;
  min-height: 56px;
  color: var(--color-success-strong);
  border-color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
.rs-extra-note {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.rs-context[hidden] {
  display: none;
}
.reason-sheet .po-footer .btn-primary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
}
.rec-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--space-2);
  margin: var(--space-2) 0;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.rec-strip[hidden] {
  display: none;
}
.rec-tag {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-primary);
}
.rec-who {
  overflow-wrap: anywhere;
}
/* AU14-F15: the "sold past an 86" strip under a drink on the ticket. One more
   full-width element under the row (the price change strip's own shape), grey
   like the reopen record because green already means a discount, amber a
   problem and blue a price change. Tag, who, and the reason in bold on one
   line while it fits. */
.line-stock-override {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--space-2);
  min-width: 0;
  margin-top: 2px;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.line-stock-override .rec-why {
  flex: 0 1 auto;
}
.rec-why {
  flex: 1 1 100%;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  overflow-wrap: anywhere;
}
.rec-why-none {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
/* AU14-F5: a manual discount taken off stays on the ticket, struck through
   (it takes nothing now), with the grey record strip right under it. The strip
   is the same .rec-strip the reopen record uses. */
.discount-line-removed .discount-line-name,
.discount-line-removed .discount-line-amount {
  text-decoration: line-through;
  color: var(--color-text-tertiary);
}
.discount-removed {
  border-bottom: 1px solid var(--color-border);
}
.discount-removed .discount-line {
  border-bottom: none;
}
.discount-removed .rec-strip {
  margin: 0 0 var(--space-2);
}
/* The count cards sit three to a row so the discount and 86 cards slot in
   beside the reopen card when those slices land; one card is a third of the
   width, never the whole row. A gap under them before the list. */
#closeout-actions-with-reason .figure-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-bottom: var(--space-3);
}
@media (max-width: 700px) {
  #closeout-actions-with-reason .figure-grid {
    grid-template-columns: 1fr;
  }
}
.ar-row {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  align-items: start;
}
.ar-row:last-child {
  border-bottom: none;
}
.ar-time {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}
.ar-main {
  min-width: 0;
}
.ar-what {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.ar-tag {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-primary);
  background: var(--color-surface-sunken);
  white-space: nowrap;
}
.ar-who {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.ar-tag-stock {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.ar-why {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: right;
  max-width: 260px;
  overflow-wrap: anywhere;
}
.ar-why-none {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
@media (max-width: 700px) {
  .ar-row {
    grid-template-columns: 64px minmax(0, 1fr);
  }
  .ar-why {
    grid-column: 2;
    text-align: left;
    max-width: none;
  }
}

/* M5 closeout: the Price changes card and block (design/mockups/m5-price-
   override-8-closeout-*.png). The info colour again, never green or amber
   except the one "Half off or more" flag. */
.figure-card-value.info {
  color: var(--color-info-text);
}
/* Designer finding 2 and 3: the block's own heading takes the section top
   margin (the generic .section-title:first-of-type rule zeroes it, because
   this heading is the first h2 inside its wrapper div), and its count is the
   info badge, not the amber one. Amber stays on "Half off or more" only. */
#closeout-price-changes .section-title {
  margin-top: var(--space-8);
}
#closeout-price-changes .section-count {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
}
.cpc-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  min-height: var(--touch-target-comfortable);
}
.cpc-row:last-child {
  border-bottom: none;
}
.cpc-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.cpc-money {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cpc-was {
  color: var(--color-text-tertiary);
  text-decoration: line-through;
  margin-right: var(--space-2);
  font-size: var(--font-size-sm);
}
.cpc-now {
  margin-right: var(--space-2);
}
.cpc-diff {
  font-weight: var(--font-weight-bold);
  color: var(--color-info-text);
}
.cpc-detail {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cpc-tag {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-info-subtle-border);
  background: var(--color-info-subtle);
  color: var(--color-info);
  white-space: nowrap;
}
.cpc-tag-warn {
  border-color: var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
/* M5-F1-F1: "Below cost" reads stronger than "Half off or more": a bold lead
   and the strong amber border. */
.cpc-tag-below-cost {
  border-color: var(--color-warning-strong);
}
.cpc-tag-below-cost strong {
  font-weight: var(--font-weight-bold);
}

/* M5-R10: each closeout row gains a History button with the change count. */
.cpc-history {
  min-height: 44px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}
.cpc-history-count {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  border-radius: var(--radius-full);
  padding: 1px 8px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}

/* M5-R10: the "Price history" row in the line's "..." sheet. */
#line-edit-sheet .line-edit-price-history {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  text-align: left;
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
#line-edit-sheet .line-edit-price-history[hidden] {
  display: none;
}
#line-edit-sheet .line-edit-price-history small {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}

/* M5-R10: the price history sheet (design/mockups/m5-r10-price-history.html). */
.price-history-sheet {
  max-width: 780px;
  /* UX100: about 92vh, with a margin under the sheet (its scrim's bottom padding), so Done is never flush to
     the screen edge. */
  max-height: 92vh;
  border-radius: var(--radius-xl);
}
#price-history-scrim {
  padding-bottom: var(--space-4);
}
/* UX100: the circled 44px close button of the approved mockup (design/mockups/m5-r10-price-history.html). */
.price-history-sheet .btn-icon {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-md);
}
.price-history-sheet .sheet-header {
  padding: var(--space-3) var(--space-5) var(--space-2);
}
.price-history-sheet .sheet-title {
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.ph-body {
  overflow-y: auto;
  padding: var(--space-3) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.ph-sum {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}
.ph-sum > div {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-4) var(--space-2);
}
.ph-sum-k {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--font-weight-semibold);
}
.ph-sum-v {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  line-height: 1.2;
}
.ph-sum-v small {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.ph-tl {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.ph-ev {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 0 var(--space-3);
  position: relative;
  padding-bottom: var(--space-2);
}
.ph-ev:last-child {
  padding-bottom: 0;
}
.ph-ev::before {
  content: "";
  position: absolute;
  left: 17px;
  top: 36px;
  bottom: 0;
  width: 2px;
  background: var(--color-border-strong);
}
.ph-ev:last-child::before {
  display: none;
}
.ph-dot {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-bold);
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}
.ph-putback .ph-dot {
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 2px dashed var(--color-text-secondary);
}
.ph-card {
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.ph-putback .ph-card {
  border-style: dashed;
  border-color: var(--color-border-strong);
}
.ph-now .ph-card {
  border-color: var(--color-accent-strong);
  box-shadow: inset 0 0 0 1px var(--color-accent-strong);
}
.ph-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.ph-when {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-weight: var(--font-weight-semibold);
}
.ph-money {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  white-space: nowrap;
}
.ph-from {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
  text-decoration: line-through;
  font-size: var(--font-size-sm);
}
.ph-diff {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  padding: 1px 8px;
  border-radius: var(--radius-sm);
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}
.ph-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-1) var(--space-4);
  margin: 0;
}
.ph-grid dt {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.ph-grid dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.ph-grid dd.ph-na {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.ph-tag {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  white-space: nowrap;
}
.ph-tag-went-up {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
}
.ph-tag-half-off,
.ph-tag-below-cost {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
}
.ph-tag-put {
  color: var(--color-text-primary);
  background: var(--color-surface);
  border-color: var(--color-border-strong);
}
.ph-tag-now {
  color: var(--color-text-on-accent);
  background: var(--color-accent-strong);
}
.ph-flags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ph-empty,
.ph-loading {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
}
.ph-failed {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  color: var(--color-danger-strong);
}
.ph-failed p {
  margin: 0;
}
@media (max-width: 640px) {
  .ph-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* With the 86 list open the toast centres over the dimmed menu on the left,
   so it never covers the panel's own rows. The toast follows the backdrop
   in the markup, which is what makes this sibling selector work. */

/* ---------------------------------------------------------------------
   RPT1-F4 (docs/build-briefs/RPT1-F4-my-tips-on-the-floor.md; DEC-285): the
   My Tips floor sheet. The shell (backdrop, panel, head, title, Done) is the
   86 list's own .stock86-* classes; only the total card, the chips, the night
   list and the footer are new, ported from design/mockups/rpt1-f4-my-tips.html
   on the same tokens, no new colours. */
.mytips-chips {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5) var(--space-3);
  flex-shrink: 0;
}
.mytips-chip {
  flex: 1;
  min-width: 0;
  height: 48px;
  padding: 0 var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.mytips-chip[aria-pressed="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-semibold);
}
.mytips-chip:focus-visible,
.stock86-backdrop .stock86-done:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.mytips-total {
  margin: var(--space-1) var(--space-5) var(--space-3);
  padding: var(--space-4) var(--space-6);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}
.mytips-total-range {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.mytips-total-amount {
  font-size: 3.5rem;
  line-height: 1.05;
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  margin: var(--space-2) 0 var(--space-1);
}
.mytips-total-amount.zero {
  color: var(--color-text-tertiary);
}
.mytips-total-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.mytips-night-note {
  margin: 0 var(--space-5) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font-size: var(--font-size-sm);
  flex-shrink: 0;
}
.mytips-night-note[hidden],
.mytips-list-title[hidden],
.mytips-days[hidden],
.mytips-empty[hidden] {
  display: none;
}
.mytips-list-title {
  padding: var(--space-2) var(--space-5);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  flex-shrink: 0;
}
.mytips-days {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  margin: 0 var(--space-5);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-1);
}
.mytips-day {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 60px;
  padding: var(--space-2) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.mytips-day:last-child {
  border-bottom: none;
}
.mytips-bar {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: var(--color-accent-subtle);
  z-index: 0;
}
.mytips-day > * {
  position: relative;
  z-index: 1;
}
.mytips-day > .mytips-bar {
  position: absolute;
}
.mytips-day-main {
  flex: 1;
  min-width: 0;
}
.mytips-day-name {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-md);
  line-height: var(--line-height-tight);
}
.mytips-day-date {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.mytips-day-amt {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
}
.mytips-day.none .mytips-day-name,
.mytips-day.none .mytips-day-amt {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.mytips-day.none .mytips-day-amt {
  font-size: var(--font-size-base);
}
.mytips-tag {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: 2px;
}
.mytips-tag.live {
  color: var(--color-info);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
}
.mytips-tag.best {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.mytips-empty {
  margin: 0 var(--space-5);
  padding: var(--space-8) var(--space-6);
  text-align: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.mytips-empty b {
  display: block;
  font-size: var(--font-size-lg);
  margin-bottom: var(--space-2);
}
.mytips-empty span {
  color: var(--color-text-secondary);
}
.mytips-foot {
  padding: var(--space-4) var(--space-5) var(--space-5);
  flex-shrink: 0;
  margin-top: auto;
}
.mytips-rule {
  font-weight: var(--font-weight-semibold);
}
.mytips-fine {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* ---------------------------------------------------------------------
   RPT1 (docs/build-briefs/RPT1-owner-reports-slice-1.md; DEC-268): the
   Reports group, ported from design/mockups/core-owner-reports-s1-*.html
   on the same tokens and the brass theme. Every selector is scoped under
   #admin-group-panel-reports so the mockup's short class names (.chip,
   .tag, .card, .kpi) never reach any other screen. Admin surface: a
   pointer and keyboard are assumed, yet every control is at least the
   44px comfortable target, nothing depends on hover, and no title
   tooltip carries meaning. The wide tables scroll sideways with the first
   column pinned.
   --------------------------------------------------------------------- */
#admin-group-panel-reports .num {
  font-variant-numeric: tabular-nums;
}
.reports-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  margin-bottom: var(--space-4);
}
.reports-nav-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.reports-nav-heading {
  margin: 0 var(--space-2) 0 0;
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .reports-reviews-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
#admin-group-panel-reports .reports-reviews-actions .btn-compact {
  min-height: var(--touch-target-min);
  border-radius: var(--radius-full);
}
#admin-group-panel-reports .chip,
.reports-nav .chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  white-space: nowrap;
  cursor: pointer;
}
#admin-group-panel-reports .chip.on,
.reports-nav .chip.on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .reports-hint {
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .reports-titlebar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .reports-title {
  margin: 0;
  font-size: var(--font-size-xl);
  letter-spacing: -0.01em;
  line-height: var(--line-height-tight);
}
/* UIFIX1 (DEC-500, SF-6): the older location reports carry the Reports frame: crumb, then one toolbar card. */
#admin-group-panel-reports .reports-crumb {
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .reports-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .reports-toolbar .rangebar {
  margin: 0;
  flex: 1 1 auto;
}
#admin-group-panel-reports .reports-toolbar .reports-download-wrap {
  margin-left: auto;
}
.reports-location-pill {
  cursor: default;
  padding-right: var(--space-2);
}
.reports-location-pill select,
.reports-location-pill #reports-location {
  min-height: 44px;
  min-width: 140px;
  border: 0;
  background: transparent;
  color: inherit;
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports
  .reports-toolbar:not(:has(#reports-location-wrap:not([hidden]))):not(
    :has(#reports-rangebar:not([hidden]))
  ):not(:has(#reports-download:not([hidden]))) {
  display: none;
}
body:has(#reports-view:not([hidden])) #admin-ops-title,
body:has(#reports-view:not([hidden])) #admin-ops-subtitle {
  display: none;
}
#admin-group-panel-reports .reports-sub {
  margin: var(--space-1) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  max-width: 62ch;
}
#admin-group-panel-reports .reports-download-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}
#admin-group-panel-reports .reports-download-status {
  margin: 0;
  min-height: 1em;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .btn-quiet {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-sm);
  cursor: pointer;
}
#admin-group-panel-reports .rangebar {
  display: flex;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .rangebar > span:first-child {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
#admin-group-panel-reports .rangebar .span {
  margin-left: auto;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .rangebar .span b {
  color: var(--color-text-primary);
}
#admin-group-panel-reports .reports-custom {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .reports-custom .field-input {
  min-height: var(--touch-target-comfortable);
}
#admin-group-panel-reports .reports-custom-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .reports-custom-error {
  flex-basis: 100%;
  margin: 0;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .fresh {
  display: flex;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .fresh b {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .fresh .spacer {
  flex: 1;
}
#admin-group-panel-reports .reports-status {
  margin-bottom: var(--space-4);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .reports-status-error {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
#admin-group-panel-reports .tag.info {
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}
#admin-group-panel-reports .tag.warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
#admin-group-panel-reports .kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .kpi {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4) var(--space-5);
}
#admin-group-panel-reports .kpi .k {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .kpi .v {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: var(--space-1);
  font-variant-numeric: tabular-nums;
}
#admin-group-panel-reports .kpi .d {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
  min-height: 1.2em;
}
#admin-group-panel-reports .delta {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .delta.up {
  color: var(--color-success-text);
}
#admin-group-panel-reports .delta.down {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .card h2 {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
#admin-group-panel-reports .card h2 small {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .reports-empty {
  text-align: center;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .reports-empty-range {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .bars {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  height: 132px;
  padding-top: var(--space-2);
}
#admin-group-panel-reports .bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: 100%;
  min-width: 0;
}
#admin-group-panel-reports .bar i {
  display: block;
  width: 100%;
  max-width: 84px;
  border-radius: var(--radius-sm) var(--radius-sm) 2px 2px;
  background: var(--color-accent);
  opacity: 0.88;
}
#admin-group-panel-reports .bar.nf i {
  background: repeating-linear-gradient(
    135deg,
    var(--color-accent) 0 6px,
    var(--color-accent-subtle-border) 6px 12px
  );
}
#admin-group-panel-reports .bar span {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .bar em {
  font-style: normal;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .tblwrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 calc(var(--space-5) * -1);
  padding: 0 var(--space-5);
}
#admin-group-panel-reports table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports th {
  font-size: var(--font-size-xs);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  text-align: right;
  padding: 0 var(--space-2);
  height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border-strong);
  white-space: nowrap;
  background: var(--color-surface);
}
#admin-group-panel-reports th.l,
#admin-group-panel-reports td.l {
  text-align: left;
}
#admin-group-panel-reports th.sort {
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .reports-sort {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
#admin-group-panel-reports td {
  padding: 0 var(--space-2);
  height: var(--touch-target-comfortable);
  text-align: right;
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#admin-group-panel-reports td.l {
  font-weight: var(--font-weight-medium);
}
#admin-group-panel-reports td.strong {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-base);
}
#admin-group-panel-reports td.neg {
  color: var(--color-text-secondary);
}
#admin-group-panel-reports td.zero {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports tr.total td {
  border-top: 2px solid var(--color-border-strong);
  border-bottom: none;
  font-weight: var(--font-weight-bold);
  background: var(--color-surface-sunken);
}
#admin-group-panel-reports .sticky {
  position: sticky;
  left: 0;
  background: var(--color-surface);
  z-index: 1;
  box-shadow: 1px 0 0 var(--color-border);
}
#admin-group-panel-reports tr.total .sticky {
  background: var(--color-surface-sunken);
}
#admin-group-panel-reports th.sticky {
  z-index: 2;
}
#admin-group-panel-reports .dlab {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
#admin-group-panel-reports .dlab small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .memo {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .memo b {
  color: var(--color-text-primary);
}
#admin-group-panel-reports .tie {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .tie::before {
  content: "\2713";
  font-weight: 700;
}
#admin-group-panel-reports .sharebar {
  display: flex;
  height: 18px;
  border-radius: var(--radius-full);
  overflow: hidden;
  gap: 2px;
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .sharebar span {
  display: block;
  height: 100%;
}
#admin-group-panel-reports .sw {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-right: var(--space-2);
  vertical-align: -1px;
}
#admin-group-panel-reports .pbar {
  display: inline-block;
  width: 72px;
  height: 8px;
  border-radius: 4px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  vertical-align: middle;
  margin-left: var(--space-3);
  overflow: hidden;
}
#admin-group-panel-reports .pbar i {
  display: block;
  height: 100%;
  background: var(--color-accent);
}
#admin-group-panel-reports .filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .showall {
  display: flex;
  justify-content: center;
  margin-top: var(--space-4);
}
#admin-group-panel-reports .foot {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin: var(--space-2) 0 var(--space-8);
}
#admin-group-panel-reports .kpis[data-count="3"] {
  grid-template-columns: repeat(3, 1fr);
}
#admin-group-panel-reports .kpis[data-count="2"] {
  grid-template-columns: repeat(2, 1fr);
}
#admin-group-panel-reports .kpis[data-count="1"] {
  grid-template-columns: 1fr;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .kpis,
  #admin-group-panel-reports .kpis[data-count="3"] {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ---------- INV31: Set starting stock (docs/build-briefs/INV31-set-starting-stock.md) ----------
   Ported from design/mockups/inv-opening-balance.html onto this file's own
   tokens; no new colours. Admin surface, built touch-first: every target is at
   least --touch-target-min, nothing depends on hover. While the screen is open
   the rest of Settings is hidden, so it reads as one full page. */
#admin-screen.admin-starting-stock-open .tabs-page > :not(#admin-starting-stock-screen) {
  display: none !important;
}
#admin-starting-stock-screen {
  max-width: 1120px;
  margin: 0 auto;
  overflow-wrap: anywhere;
}
#admin-starting-stock-screen button,
#admin-starting-stock-screen input {
  font: inherit;
}
/* The location and the sheets are drawn into slots; the slots must not become the
   sticky bar's containing block, or it would never stick. */
#ss-bar-slot,
#ss-sheet-slot {
  display: contents;
}

/* The callout and the quiet entry button in Settings > Inventory. */
.admin-starting-stock-callout {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  flex-wrap: wrap;
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.admin-starting-stock-callout-text {
  flex: 1 1 320px;
}
.admin-starting-stock-callout-text b {
  display: block;
}
.admin-starting-stock-callout-text span {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.ss-top {
  display: flex;
  align-items: center;
  margin-bottom: var(--space-3);
}
.ss-back {
  min-height: var(--touch-target-min);
}
.ss-crumb {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-1);
}
.ss-title {
  margin: 0;
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
}
.ss-lede {
  color: var(--color-text-secondary);
  margin: var(--space-2) 0 var(--space-5);
  max-width: 62ch;
}
.ss-rule {
  display: flex;
  gap: var(--space-3);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
.ss-rule b {
  color: var(--color-info);
}
.ss-choice-box {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
.ss-choice-box > span {
  flex: 1 1 320px;
}
.ss-choice-on {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}
.ss-notice {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}

/* Filters */
.ss-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.ss-filter-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
}
.ss-search {
  flex: 1 1 280px;
  min-height: var(--touch-target-min);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 0 var(--space-4);
  background: var(--color-surface);
  color: var(--color-text-primary);
}
.ss-search:focus {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.ss-seg {
  display: inline-flex;
  flex-wrap: wrap;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-1);
  gap: var(--space-1);
}
.ss-seg-button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-medium);
}
.ss-seg-button[aria-pressed="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
  font-weight: var(--font-weight-semibold);
}
.ss-chips,
.ss-tenths,
.ss-quick {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ss-chip {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.ss-chip-n {
  color: var(--color-text-tertiary);
  margin-left: var(--space-1);
}
.ss-chip[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.ss-chip[aria-pressed="true"] .ss-chip-n {
  color: var(--color-accent-strong);
}

/* List */
.ss-cat-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-6) 0 var(--space-2);
  padding: 0 var(--space-1);
}
.ss-cat-head h2 {
  margin: 0;
  font-size: var(--font-size-md);
}
.ss-cat-head span {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.ss-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.ss-row {
  border-bottom: 1px solid var(--color-border);
}
.ss-row:last-child {
  border-bottom: none;
}
.ss-row-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  text-align: left;
  border: none;
  background: transparent;
  color: inherit;
  padding: var(--space-3) var(--space-4);
  min-height: 68px;
}
button.ss-row-head {
  cursor: pointer;
}
.ss-row-open > .ss-row-head {
  background: var(--color-accent-subtle);
}
.ss-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ss-row-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.ss-row-meta {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}
.ss-row-state {
  flex: 0 0 168px;
  text-align: right;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.ss-val {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
}
.ss-val-sub {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.ss-todo {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.ss-row-entered {
  box-shadow: inset 5px 0 0 var(--color-success);
}
.ss-row-done {
  background: var(--color-surface-sunken);
}
.ss-row-done .ss-row-name {
  color: var(--color-text-secondary);
}
.ss-row-state-done {
  flex-basis: 320px;
}
.ss-done-why {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  max-width: 40ch;
  text-align: right;
}
.ss-row-msg {
  padding: var(--space-2) var(--space-4) var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
}
.ss-tag {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.ss-tag-done {
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-secondary);
}
.ss-tag-ok {
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.ss-tag-warn {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.ss-tag-bad {
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}

/* The editor, inside the row */
.ss-editor {
  padding: var(--space-4) var(--space-5) var(--space-5);
  background: var(--color-surface-sunken);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.ss-ed-grid {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
  align-items: flex-start;
}
.ss-ed-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.ss-ed-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.ss-stepper {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.ss-step-button {
  min-width: var(--touch-target-comfortable);
  height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.ss-num {
  min-width: 84px;
  text-align: center;
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.ss-unit {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-left: var(--space-1);
}
.ss-oz-field {
  width: 120px;
  min-height: var(--touch-target-comfortable);
  text-align: center;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}
.ss-oz-field:focus {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.ss-tenth {
  min-width: 52px;
  padding: 0 var(--space-2);
  font-size: var(--font-size-base);
  font-variant-numeric: tabular-nums;
}
.ss-total {
  font-size: var(--font-size-md);
}
.ss-total-oz,
.ss-total-hint {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.ss-ed-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
}
.ss-grow {
  flex: 1;
}
#admin-starting-stock-screen .ss-done-button {
  height: auto;
  min-height: 48px;
  padding: 0 var(--space-6);
}
.ss-danger-quiet {
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
}
.ss-note {
  display: flex;
  gap: var(--space-3);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
  align-items: center;
  flex-wrap: wrap;
}
.ss-note-text {
  flex: 1 1 260px;
}
#admin-starting-stock-screen .btn-secondary,
#admin-starting-stock-screen .btn-primary {
  height: auto;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}

.ss-empty {
  text-align: center;
  padding: var(--space-12) var(--space-5);
  color: var(--color-text-secondary);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
}
.ss-empty b {
  display: block;
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  margin-bottom: var(--space-2);
}
.ss-empty-actions {
  margin-top: var(--space-5);
}
#admin-starting-stock-screen > .ss-empty {
  margin-top: var(--space-6);
}

/* The running count */
.ss-bar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: var(--shadow-3);
  padding: var(--space-3) var(--space-5);
  margin-top: var(--space-5);
}
.ss-bar-hidden {
  display: none;
}
.ss-bar-in {
  max-width: 1120px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
}
.ss-counts {
  display: flex;
  gap: var(--space-6);
  flex: 1 1 380px;
  align-items: center;
}
.ss-count {
  display: flex;
  flex-direction: column;
  line-height: var(--line-height-tight);
}
.ss-count b {
  font-size: var(--font-size-xl);
  font-variant-numeric: tabular-nums;
}
.ss-count span {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.ss-count-muted b {
  color: var(--color-text-tertiary);
}
.ss-meter {
  flex: 1;
  min-width: 120px;
  height: 8px;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.ss-meter i {
  display: block;
  height: 100%;
  background: var(--color-success);
  border-radius: var(--radius-full);
  transition: width var(--motion-base) var(--motion-easing-standard);
}
.ss-meter-wide {
  margin: var(--space-2) 0 var(--space-4);
}
#admin-starting-stock-screen .ss-review {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-8);
}

/* Sheets: confirm, saving, result. Built in script, never static markup. */
.ss-backdrop {
  position: fixed;
  inset: 0;
  background: var(--color-scrim);
  z-index: var(--z-scrim);
}
.ss-sheet {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--z-sheet);
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.ss-sheet-h {
  padding: var(--space-5) var(--space-6) var(--space-3);
}
.ss-sheet-h h2 {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
}
.ss-sheet-h h2:focus {
  outline: none;
}
.ss-sheet-h p {
  margin: var(--space-2) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.ss-sheet-b {
  padding: 0 var(--space-6) var(--space-3);
  overflow: auto;
  flex: 1;
}
.ss-sheet-f {
  padding: var(--space-4) var(--space-6) var(--space-5);
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  flex-wrap: wrap;
  border-top: 1px solid var(--color-border);
}
.ss-tiles {
  display: flex;
  gap: var(--space-3);
  margin: var(--space-2) 0 var(--space-4);
  flex-wrap: wrap;
}
.ss-tile {
  flex: 1 1 140px;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.ss-tile b {
  display: block;
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums;
}
.ss-tile span {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.ss-sum {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.ss-sum li {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  min-height: 52px;
}
.ss-sum li:last-child {
  border-bottom: none;
}
.ss-sum-name {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--font-weight-medium);
}
.ss-sum-name small {
  display: block;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-xs);
}
.ss-sum-q {
  text-align: right;
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ss-sum-q small {
  display: block;
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.ss-sum-st {
  flex: 0 0 auto;
}
.ss-h3 {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin: var(--space-4) 0 var(--space-2);
}
.ss-lock-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: var(--space-4) 0 0;
}
.ss-fail-why {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
  font-weight: var(--font-weight-regular);
}

@media (max-width: 1000px) {
  .ss-row-state {
    flex-basis: 140px;
  }
  .ss-counts {
    gap: var(--space-4);
  }
  .ss-review {
    padding: 0 var(--space-5);
  }
}

/* ---------------------------------------------------------------------
   INV32 (docs/build-briefs/INV32-stock-on-hand-and-value.md; DEC-289): the
   Stock on hand and value report, ported from
   design/mockups/inv-report-stock-value.html on the same tokens and brass
   theme, scoped under the Reports panel like the RPT1 rules above. Every
   control is 44px or taller (a chip, a button, a category row at the 56px
   comfortable row height), nothing depends on hover, and no title tooltip
   carries meaning. The wide table scrolls sideways with Item pinned.
   --------------------------------------------------------------------- */
#admin-group-panel-reports .tag.ok {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border: 1px solid var(--color-success-subtle-border);
}
#admin-group-panel-reports .tag.low {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
#admin-group-panel-reports .tag.out {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  border: 1px solid var(--color-danger-subtle-border);
}
#admin-group-panel-reports .tag.e86 {
  background: var(--color-surface);
  color: var(--color-danger-strong);
  border: 1px solid var(--color-danger);
}
#admin-group-panel-reports .tags {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}
#admin-group-panel-reports .stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
}
#admin-group-panel-reports .stack small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .stack small.w {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports td.nc {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports td.muted {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports table.items td.neg {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports th.st,
#admin-group-panel-reports td.st {
  text-align: left;
}
#admin-group-panel-reports table.items {
  min-width: 900px;
}
#admin-group-panel-reports td.item,
#admin-group-panel-reports th.item {
  width: 260px;
  min-width: 260px;
  max-width: 260px;
}
#admin-group-panel-reports td.item {
  white-space: normal;
}
#admin-group-panel-reports td.item .dlab {
  text-align: left;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports tr.total.first td {
  border-top: none;
  border-bottom: 2px solid var(--color-border-strong);
}
#admin-group-panel-reports tr.cat {
  cursor: pointer;
}
#admin-group-panel-reports tr.cat.on td {
  background: var(--color-accent-subtle);
}
#admin-group-panel-reports .fgroup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .fgroup .lab {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  width: 100px;
  flex-shrink: 0;
}
#admin-group-panel-reports .chip .n {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .chip.on .n {
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .notice {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .notice b {
  color: var(--color-warning-strong);
}
#admin-group-panel-reports .notice.big {
  padding: var(--space-5) var(--space-6);
  font-size: var(--font-size-base);
}
#admin-group-panel-reports .kpi.warn .v {
  color: var(--color-warning-text);
}
#admin-group-panel-reports .kpi.bad .v {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .empty {
  padding: var(--space-10) var(--space-6);
  text-align: center;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .empty h3 {
  margin: 0 0 var(--space-2);
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .fgroup .lab {
    width: 100%;
  }
}

/* ---------- INV33: Usage and waste (docs/build-briefs/INV33-usage-and-waste.md; DEC-290) ----------
   Ported from design/mockups/inv-report-usage-waste.html onto this file's own
   tokens; no new colours. Scoped under the Reports panel's .uw body so the
   mockup's short class names never reach another screen. Every target is at
   least --touch-target-min, nothing depends on hover, nothing is in a tooltip.
   The wide item table scrolls inside its own wrapper with Item pinned, so the
   page itself never scrolls sideways. */
#admin-group-panel-reports .uw {
  min-width: 0;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .uw .notice {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .uw .notice b {
  color: var(--color-warning-strong);
}
#admin-group-panel-reports .uw .kpi .d2 {
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .uw .kpi .v small {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  letter-spacing: 0;
}
#admin-group-panel-reports .uw .kpi.warn .v {
  color: var(--color-warning-text);
}
#admin-group-panel-reports .uw .card h2 .btn-quiet {
  margin-left: auto;
}
#admin-group-panel-reports .uw .chip .n {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .uw .chip.on .n {
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .uw .fgroup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .uw .fgroup .lab {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  width: 100px;
  flex-shrink: 0;
}
#admin-group-panel-reports .uw .empty {
  padding: var(--space-8) var(--space-6);
  text-align: center;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .uw .empty h3 {
  margin: 0 0 var(--space-2);
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
}
#admin-group-panel-reports .uw .inline-cta {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-4);
}
#admin-group-panel-reports .uw .stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
}
#admin-group-panel-reports .uw .stack small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .uw .stack small.w {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .uw table.reasons {
  min-width: 600px;
}
#admin-group-panel-reports .uw table.cats {
  min-width: 760px;
}
#admin-group-panel-reports .uw table.items {
  min-width: 1040px;
}
#admin-group-panel-reports .uw td {
  padding: var(--space-2) var(--space-3);
  height: var(--touch-target-comfortable);
  vertical-align: middle;
}
#admin-group-panel-reports .uw th {
  padding: 0 var(--space-3);
}
#admin-group-panel-reports .uw td.rl {
  white-space: normal;
  min-width: 240px;
  max-width: 420px;
}
#admin-group-panel-reports .uw td.muted {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .uw td.neg {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .uw td.warnq {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .uw td.mixedmsg {
  text-align: left;
  white-space: normal;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .uw td.item,
#admin-group-panel-reports .uw th.item {
  width: 250px;
  min-width: 250px;
  max-width: 250px;
}
#admin-group-panel-reports .uw td.item {
  white-space: normal;
}
#admin-group-panel-reports .uw .dlab {
  text-align: left;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .uw .dlab .more {
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .uw .uw-item-button {
  display: block;
  width: 100%;
  min-height: var(--touch-target-min);
  padding: var(--space-1) 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
#admin-group-panel-reports .uw tr.cat {
  cursor: pointer;
}
#admin-group-panel-reports .uw tr.cat.on td,
#admin-group-panel-reports .uw tr.open td,
#admin-group-panel-reports .uw tr.open td.sticky {
  background: var(--color-accent-subtle);
}
#admin-group-panel-reports .uw tr.detail td {
  height: auto;
  padding: 0;
  white-space: normal;
  text-align: left;
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border-strong);
}
#admin-group-panel-reports .uw .dgrid {
  position: sticky;
  left: 0;
  width: min(880px, calc(100vw - 96px));
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
}
#admin-group-panel-reports .uw .dgrid h4 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .uw .dgrid ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .uw .dgrid li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}
#admin-group-panel-reports .uw .dgrid li b {
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
#admin-group-panel-reports .uw .dgrid p {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .tag.warn {
  white-space: normal;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .uw .fgroup .lab {
    width: 100%;
  }
  #admin-group-panel-reports .uw .dgrid {
    grid-template-columns: 1fr;
    width: min(640px, calc(100vw - 96px));
  }
}

/* ---------- INV34: Cost and margin (docs/build-briefs/INV34-cost-and-margin.md; DEC-291) ----------
   Ported from design/mockups/inv-report-cost-margin.html. The screen reuses the
   Usage and waste styles above (its root carries both .uw and .cm); only what
   is new is here. No new colours, every target at least --touch-target-min,
   nothing depends on hover. Scoped under the Reports panel. */
#admin-group-panel-reports .cm .notice.info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
}
#admin-group-panel-reports .cm .notice.info b {
  color: var(--color-info);
}
#admin-group-panel-reports .cm .strip {
  display: flex;
  gap: var(--space-2) var(--space-4);
  align-items: center;
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .cm .strip b {
  color: var(--color-text-primary);
}
#admin-group-panel-reports .cm .tag.open {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
#admin-group-panel-reports .cm table.cm-cats {
  min-width: 700px;
}
#admin-group-panel-reports .cm table.cm-items {
  min-width: 900px;
}
#admin-group-panel-reports .cm table.cm-days-table {
  min-width: 640px;
}
#admin-group-panel-reports .cm table.cm-list-table {
  min-width: 560px;
}
#admin-group-panel-reports .cm td.below {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .cm td.why {
  white-space: normal;
  text-align: left;
  min-width: 260px;
}
#admin-group-panel-reports .cm .kpi.bad .d {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .cm .dgrid ul li.tot {
  border-top: 1px solid var(--color-border-strong);
  padding-top: var(--space-1);
  margin-top: var(--space-1);
}
#admin-group-panel-reports .cm .dgrid li .dlab {
  max-width: 70%;
}
#admin-group-panel-reports .cm .dgrid li b {
  white-space: nowrap;
}
#admin-group-panel-reports .cm .tags {
  margin-top: var(--space-1);
}
#admin-group-panel-reports .cm .inline-cta.cm-left {
  justify-content: flex-start;
}
#admin-group-panel-reports .cm .legend {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .cm .legend .sw {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: var(--space-2);
  border-radius: 3px;
  vertical-align: -1px;
}
#admin-group-panel-reports .cm .legend .sw.sales {
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
}
#admin-group-panel-reports .cm .legend .sw.cost {
  background: var(--color-accent);
}
#admin-group-panel-reports .cm .chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 190px;
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .cm .chart .col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  gap: 4px;
}
#admin-group-panel-reports .cm .chart .bar {
  width: 100%;
  max-width: 72px;
  border-radius: 6px 6px 2px 2px;
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
#admin-group-panel-reports .cm .chart .bar i {
  display: block;
  width: 100%;
  background: var(--color-accent);
}
#admin-group-panel-reports .cm .chart .lab {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  white-space: nowrap;
  height: 16px;
}
#admin-group-panel-reports .cm .chart .val {
  font-size: var(--font-size-xs);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  height: 16px;
  white-space: nowrap;
}
#admin-group-panel-reports .cm .chart .col.worst .lab {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .cm .eq {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .cm .eq .box {
  flex: 1;
  min-width: 170px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
#admin-group-panel-reports .cm .eq .box.sum {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
#admin-group-panel-reports .cm .eq .box .k {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cm .eq .box .v {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
#admin-group-panel-reports .cm .eq .box .d {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cm .eq .op {
  align-self: center;
  font-size: var(--font-size-xl);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cm .cm-tie {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
#admin-group-panel-reports .cm .cm-tie .r {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .cm .cm-tie .r:last-child {
  border-bottom: 0;
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .cm .cm-tie .r small {
  display: block;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cm .cm-tie .r b {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .cm .eq .op {
    display: none;
  }
}

/* ---------- INV35-A1: Count variance (docs/build-briefs/INV35-A-count-variance.md; DEC-292) ----------
   Ported from design/mockups/inv-report-variance.html (the Count variance
   states) onto this file's own tokens; no new colours. Scoped under the Reports
   panel's .cv body so the mockup's short class names never reach another
   screen. Every target is at least --touch-target-min, nothing depends on
   hover, nothing is in a tooltip. Short is the danger colour and over is the
   info colour, and the sign and the word always carry it as well. The wide
   tables scroll inside their own wrappers with Item pinned, so the page itself
   never scrolls sideways. */
#admin-group-panel-reports .cv {
  min-width: 0;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .cv .notice {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .cv .notice b {
  color: var(--color-warning-strong);
}
#admin-group-panel-reports .cv .notice.info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
}
#admin-group-panel-reports .cv .notice.info b {
  color: var(--color-info);
}
#admin-group-panel-reports .cv .notice.big {
  padding: var(--space-5) var(--space-6);
  font-size: var(--font-size-base);
}
#admin-group-panel-reports .cv .kpi .d2 {
  margin-top: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .cv .kpi.bad .d {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .cv .strip {
  display: flex;
  gap: var(--space-2) var(--space-4);
  align-items: center;
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .cv .strip b {
  color: var(--color-text-primary);
}
#admin-group-panel-reports .cv .scope {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .cv .scope b {
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .cv .chip .n {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cv .chip.on .n {
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .cv .fgroup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
#admin-group-panel-reports .cv .fgroup .lab {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  width: 100px;
  flex-shrink: 0;
}
#admin-group-panel-reports .cv .empty {
  padding: var(--space-8) var(--space-6);
  text-align: center;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cv .empty h3 {
  margin: 0 0 var(--space-2);
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
}
#admin-group-panel-reports .cv .inline-cta {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-4);
}
#admin-group-panel-reports .cv .inline-cta.left {
  justify-content: flex-start;
}
#admin-group-panel-reports .cv .showall.left {
  justify-content: flex-start;
}
#admin-group-panel-reports .cv .stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
}
#admin-group-panel-reports .cv .stack.l {
  align-items: flex-start;
}
#admin-group-panel-reports .cv .stack small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cv .stack small.w {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .cv .lead {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.25;
}
#admin-group-panel-reports .cv .lead.left {
  align-items: flex-start;
  text-align: left;
}
#admin-group-panel-reports .cv .lead.right {
  align-items: flex-end;
}
#admin-group-panel-reports .cv .lead small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cv table.sess {
  min-width: 0;
}
#admin-group-panel-reports .cv table.items {
  min-width: 0;
}
#admin-group-panel-reports .cv table.hist {
  min-width: 0;
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .cv table.hist th {
  font-size: 11px;
  padding-left: 6px;
  padding-right: 6px;
  white-space: normal;
  line-height: 1.15;
}
#admin-group-panel-reports .cv table.hist td {
  padding-left: 6px;
  padding-right: 6px;
}
#admin-group-panel-reports .cv td {
  padding: var(--space-2) var(--space-3);
  height: var(--touch-target-comfortable);
  vertical-align: middle;
}
#admin-group-panel-reports .cv th {
  padding: 0 var(--space-3);
}
#admin-group-panel-reports .cv th.st,
#admin-group-panel-reports .cv td.st {
  text-align: left;
}
#admin-group-panel-reports .cv td.wrapc {
  white-space: normal;
  min-width: 150px;
  max-width: 220px;
}
#admin-group-panel-reports .cv td.muted {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .cv td.muted.left {
  text-align: left;
  white-space: normal;
}
#admin-group-panel-reports .cv td.nc {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv td.short {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv td.over {
  color: var(--color-info);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv td.warnq {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv td.mixedmsg {
  text-align: left;
  white-space: normal;
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cv td.item,
#admin-group-panel-reports .cv th.item {
  width: 230px;
  min-width: 230px;
  max-width: 230px;
}
#admin-group-panel-reports .cv td.item {
  white-space: normal;
}
#admin-group-panel-reports .cv .dlab {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  text-align: left;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .cv .dlab small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cv .dlab .more {
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv .dlab .tags {
  margin-top: 4px;
}
#admin-group-panel-reports .cv .cv-item-button {
  display: block;
  width: 100%;
  min-height: var(--touch-target-min);
  padding: var(--space-1) 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
#admin-group-panel-reports .cv tr.pick {
  cursor: pointer;
}
#admin-group-panel-reports .cv tr.pick.sel td,
#admin-group-panel-reports .cv tr.open td,
#admin-group-panel-reports .cv tr.open td.sticky {
  background: var(--color-accent-subtle);
}
#admin-group-panel-reports .cv tr.detail td {
  height: auto;
  padding: 0;
  white-space: normal;
  text-align: left;
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border-strong);
}
#admin-group-panel-reports .cv .dgrid {
  position: sticky;
  left: 0;
  width: min(100%, calc(100vw - 96px));
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
}
#admin-group-panel-reports .cv .dgrid .full {
  grid-column: 1 / -1;
}
#admin-group-panel-reports .cv .dgrid .hscroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
#admin-group-panel-reports .cv .dgrid h4 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .cv .dgrid ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cv .dgrid li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}
#admin-group-panel-reports .cv .dgrid li b {
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#admin-group-panel-reports .cv .dgrid li.tot {
  border-top: 1px solid var(--color-border-strong);
  padding-top: var(--space-1);
  margin-top: var(--space-1);
}
#admin-group-panel-reports .cv .dgrid p {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cv .hist-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: var(--space-2) 0 0;
}
#admin-group-panel-reports .cv .cv-tie {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
#admin-group-panel-reports .cv .cv-tie .r {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .cv .cv-tie .r:last-child {
  border-bottom: 0;
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .cv .cv-tie .r small {
  display: block;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .cv .cv-tie .r b {
  font-variant-numeric: tabular-nums;
  text-align: right;
}
#admin-group-panel-reports .cv .trend {
  display: flex;
  gap: 2px;
  justify-content: flex-end;
}
#admin-group-panel-reports .cv .tc {
  width: 34px;
  text-align: center;
  display: inline-block;
}
#admin-group-panel-reports .cv .tc .bar {
  display: block;
  height: 32px;
  position: relative;
  margin-bottom: 2px;
}
#admin-group-panel-reports .cv .tc .bar::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--color-border-strong);
}
#admin-group-panel-reports .cv .tc .bar i {
  position: absolute;
  left: 9px;
  right: 9px;
  border-radius: 2px;
}
#admin-group-panel-reports .cv .tc .bar i.s {
  top: 50%;
  background: var(--color-danger);
}
#admin-group-panel-reports .cv .tc .bar i.o {
  bottom: 50%;
  background: var(--color-info);
}
#admin-group-panel-reports .cv .tc .bar i.z {
  top: calc(50% - 1px);
  height: 3px;
  background: var(--color-text-tertiary);
}
#admin-group-panel-reports .cv .tc small {
  display: block;
  font-size: var(--font-size-xs);
  line-height: 1.1;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cv .tc small.s {
  color: var(--color-danger-strong);
}
#admin-group-panel-reports .cv .tc small.o {
  color: var(--color-info);
}
#admin-group-panel-reports .cv .tag {
  white-space: normal;
}
#admin-group-panel-reports .cv td.st .tag {
  white-space: nowrap;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .cv .fgroup .lab {
    width: 100%;
  }
  #admin-group-panel-reports .cv .dgrid {
    grid-template-columns: 1fr;
    width: min(100%, calc(100vw - 96px));
  }
}

/* ---------- INV35-B1: Receipts and spend (docs/build-briefs/INV35-B-receipts-and-spend.md; DEC-292) ----------
   Ported from design/mockups/inv-report-variance.html (the receipts states). The
   screen reuses the Usage and waste styles above (its root carries both .uw and
   .rs); only what is new is here. No new colours, every target at least
   --touch-target-min, nothing depends on hover. Scoped under the Reports panel.
   Appended, never interleaved, so a parallel report's rules merge beside these. */
#admin-group-panel-reports .rs .notice.info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
}
#admin-group-panel-reports .rs .notice.info b {
  color: var(--color-info);
}
#admin-group-panel-reports .rs .notice.big {
  padding: var(--space-5) var(--space-6);
}
#admin-group-panel-reports .rs .tag.open {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
#admin-group-panel-reports .rs .tags {
  margin-top: var(--space-1);
}
#admin-group-panel-reports .rs .chip.wrap {
  white-space: normal;
  text-align: left;
  height: auto;
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
  max-width: 100%;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .rs .stack.left {
  align-items: flex-start;
  text-align: left;
}
#admin-group-panel-reports .rs td.wrapc,
#admin-group-panel-reports .rs th.wrapc {
  white-space: normal;
  min-width: 180px;
  max-width: 280px;
  text-align: left;
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .rs table.rs-vendors-table {
  min-width: 760px;
}
#admin-group-panel-reports .rs table.rs-deliveries-table {
  min-width: 1080px;
}
#admin-group-panel-reports .rs table.rs-costs-table {
  min-width: 980px;
}
#admin-group-panel-reports .rs table.rs-corrections-table {
  min-width: 1080px;
}
#admin-group-panel-reports .rs tr.pick.on td,
#admin-group-panel-reports .rs tr.pick.on td.sticky {
  background: var(--color-accent-subtle);
}
#admin-group-panel-reports .rs .sharecell {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  justify-content: flex-end;
}
#admin-group-panel-reports .rs .sharecell .bar {
  display: inline-block;
  width: 64px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  overflow: hidden;
}
#admin-group-panel-reports .rs .sharecell .bar i {
  display: block;
  height: 100%;
  background: var(--color-accent);
}
#admin-group-panel-reports .rs .spark {
  display: inline-flex;
  align-items: flex-end;
  gap: 3px;
  height: 26px;
}
#admin-group-panel-reports .rs .spark i {
  display: block;
  width: 6px;
  border-radius: 2px;
  background: var(--color-border-strong);
}
#admin-group-panel-reports .rs .spark i.last {
  background: var(--color-accent);
}
#admin-group-panel-reports .rs .inline-cta.rs-left {
  justify-content: flex-start;
}
#admin-group-panel-reports .rs .dgrid ul li.tot {
  border-top: 1px solid var(--color-border-strong);
  padding-top: var(--space-1);
  margin-top: var(--space-1);
}
#admin-group-panel-reports .rs .dgrid li b {
  text-align: right;
}
#admin-group-panel-reports .rs .dgrid.rs-histgrid {
  grid-template-columns: 1fr;
}
#admin-group-panel-reports .rs .rs-hist h4 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .rs .rs-hist p {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .rs table.rs-points {
  min-width: 640px;
}

/* ---------- UX76: the Reports group uses the full page width (docs/build-briefs/UX76-reports-full-width.md) ----------
   The reports sat beside the Settings rail, so their column was about 860px at
   1440 and the wide tables scrolled sideways with no sign of it. While the
   Reports group is active admin.ts puts settings-shell-wide on the shell: the
   rail becomes the top chip row (the layout the narrow view already uses) and
   the page column widens. A wrapper that still scrolls carries
   data-scroll-cue (ui/src/scrollCue.ts) and a fade on the hidden edge. */
#admin-screen .tabs-page:has(.settings-shell-wide) {
  max-width: none;
}
.settings-shell.settings-shell-wide {
  flex-direction: column;
  align-items: stretch;
}
.settings-shell-wide .settings-rail {
  flex: 1 1 auto;
  position: static;
  width: 100%;
  flex-direction: row;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
}
.settings-shell-wide .settings-search-wrap {
  flex: 0 0 220px;
}
.settings-shell-wide .settings-rail-groups {
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-1);
}
.settings-shell-wide .settings-rail-item {
  flex: 0 0 auto;
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}
@media (max-width: 900px) {
  .settings-shell-wide .settings-rail {
    flex-direction: column;
    align-items: stretch;
  }
  .settings-shell-wide .settings-search-wrap {
    flex: 0 0 auto;
  }
}
#admin-group-panel-reports .reports-titlebar > div:first-child {
  flex: 1 1 320px;
  min-width: 0;
}
#admin-group-panel-reports .reports-download-wrap {
  flex: 0 0 auto;
  margin-left: auto;
}
#admin-group-panel-reports .fresh .btn-quiet {
  margin-left: auto;
}
#admin-group-panel-reports .scroll-cue {
  margin: 0 0 var(--space-1);
  text-align: right;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .tblwrap[data-scroll-cue="right"],
#admin-group-panel-reports .hscroll[data-scroll-cue="right"] {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
}
#admin-group-panel-reports .tblwrap[data-scroll-cue="left"],
#admin-group-panel-reports .hscroll[data-scroll-cue="left"] {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent);
  mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent);
}
#admin-group-panel-reports .tblwrap[data-scroll-cue="both"],
#admin-group-panel-reports .hscroll[data-scroll-cue="both"] {
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    #000 40px,
    #000 calc(100% - 40px),
    transparent
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 40px,
    #000 calc(100% - 40px),
    transparent
  );
}
/* INV32: the state chip sits under the item name only on a narrow page. */
#admin-group-panel-reports .state-under {
  display: none;
  margin-top: var(--space-1);
}
@media (max-width: 1000px) {
  #admin-group-panel-reports table.items .col-par,
  #admin-group-panel-reports table.items .col-state {
    display: none;
  }
  #admin-group-panel-reports .state-under {
    display: block;
  }
  #admin-group-panel-reports table.items {
    min-width: 0;
  }
  #admin-group-panel-reports td.item,
  #admin-group-panel-reports th.item {
    width: 200px;
    min-width: 200px;
    max-width: 200px;
  }
}
/* UX76: below 1000px a report table drops the columns that are not money, so
   the money columns fit without a sideways scroll (everything stays on a wide
   page, and Show details carries the rest). Counted rows only: a row that spans
   columns keeps its single cell. */
#admin-group-panel-reports .under-narrow {
  display: none;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .under-narrow {
    display: block;
  }
  #admin-group-panel-reports .uw table.items,
  #admin-group-panel-reports .uw table.cats,
  #admin-group-panel-reports .uw table.days,
  #admin-group-panel-reports .uw table.reasons,
  #admin-group-panel-reports .rs table.rs-vendors-table,
  #admin-group-panel-reports .rs table.rs-deliveries-table,
  #admin-group-panel-reports .rs table.rs-costs-table,
  #admin-group-panel-reports .rs table.rs-corrections-table {
    min-width: 0;
  }
  #admin-group-panel-reports .uw th,
  #admin-group-panel-reports .uw td,
  #admin-group-panel-reports .cv th,
  #admin-group-panel-reports .cv td {
    padding-left: var(--space-2);
    padding-right: var(--space-2);
  }
  #admin-group-panel-reports .uw td.item,
  #admin-group-panel-reports .uw th.item,
  #admin-group-panel-reports .cv td.item,
  #admin-group-panel-reports .cv th.item {
    width: 170px;
    min-width: 170px;
    max-width: 170px;
  }
  #admin-group-panel-reports
    .uw
    table.cats
    :is(th, td):not([colspan]):is(:nth-child(2), :nth-child(6), :nth-child(7)),
  #admin-group-panel-reports
    .uw
    table.cm-items
    :is(th, td):not([colspan]):is(:nth-child(2), :nth-child(5)),
  #admin-group-panel-reports .uw table.cm-days-table :is(th, td):not([colspan]):nth-child(2),
  #admin-group-panel-reports
    .cv
    table.items
    :is(th, td):not([colspan]):is(:nth-child(2), :nth-child(5), :nth-child(6)),
  #admin-group-panel-reports
    .cv
    table.sess
    :is(th, td):not([colspan]):is(:nth-child(3), :nth-child(5)),
  #admin-group-panel-reports
    .rs
    table.rs-vendors-table
    :is(th, td):not([colspan]):is(:nth-child(3), :nth-child(5)),
  #admin-group-panel-reports
    .rs
    table.rs-deliveries-table
    :is(th, td):not([colspan]):is(:nth-child(2), :nth-child(3)),
  #admin-group-panel-reports
    .rs
    table.rs-costs-table
    :is(th, td):not([colspan]):is(:nth-child(6), :nth-child(7)),
  #admin-group-panel-reports
    .rs
    table.rs-corrections-table
    :is(th, td):not([colspan]):is(:nth-child(2), :nth-child(3), :nth-child(7)) {
    display: none;
  }
}
/* INV35-A1: the open item's history is one table at full width, or one card per
   count below 1000px. */
#admin-group-panel-reports .cv .hist-cards {
  display: none;
}
#admin-group-panel-reports .cv table.hist td {
  white-space: nowrap;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}
#admin-group-panel-reports .cv table.hist td:first-child {
  white-space: normal;
  min-width: 200px;
  max-width: 320px;
}
#admin-group-panel-reports .cv .hist-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
#admin-group-panel-reports .cv .hist-card + .hist-card {
  margin-top: var(--space-3);
}
#admin-group-panel-reports .cv .hist-card .top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
}
#admin-group-panel-reports .cv .hist-card .top small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .cv .hist-card .three {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
}
#admin-group-panel-reports .cv .hist-card .fig {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
#admin-group-panel-reports .cv .hist-card .fig .k {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv .hist-card .fig .stack {
  align-items: flex-start;
}
#admin-group-panel-reports .cv .hist-card .fig.short {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv .hist-card .fig.over {
  color: var(--color-info);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cv .hist-card .btn-quiet {
  align-self: flex-start;
}
#admin-group-panel-reports .cv .hist-card .math {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .cv .hist-card .math[hidden] {
  display: none;
}
#admin-group-panel-reports .cv .hist-card .math .m {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-1);
}
#admin-group-panel-reports .cv .hist-card .math .stack {
  align-items: flex-end;
}
#admin-group-panel-reports .cv .hist-note {
  overflow-wrap: break-word;
  white-space: normal;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .cv .dgrid .hscroll {
    display: none;
  }
  #admin-group-panel-reports .cv .hist-cards {
    display: block;
  }
}

/* TF4-F2 (docs/build-briefs/TF4-F2-abc2go-vendor-switch.md; DEC-279;
   design/mockups/tf4-f2-abc2go-switch*.html). Settings > Purchasing > Vendors:
   the "This vendor is ABC2GO" switch row, the "ABC2GO export" tag, the
   nothing-marked warning, the success look of the shared vendor status line,
   and the two-vendor body of the move confirm. The switch itself reuses
   .admin-toggle-input/-track/-status. */
.abc2go-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  flex-shrink: 0;
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.abc2go-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-height: 56px;
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.abc2go-row--on {
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.abc2go-row-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.abc2go-row-title {
  font-weight: var(--font-weight-semibold);
}
.abc2go-row-help {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.abc2go-row .admin-toggle-label {
  margin-left: auto;
}
.abc2go-row:has(.admin-toggle-input:disabled) {
  cursor: default;
}
.abc2go-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
}
.abc2go-banner[hidden] {
  display: none;
}
.abc2go-banner svg {
  flex-shrink: 0;
  margin-top: 2px;
}
.admin-field-help.admin-vendor-status--ok {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
.abc2go-swap {
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}
.abc2go-swap-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
}
.abc2go-swap-row + .abc2go-swap-row {
  border-top: 1px solid var(--color-border);
}
.abc2go-swap-change {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* PO6-S2-F2 and PO8 (docs/build-briefs/PO8-cart-total-and-minimum.md;
   design/mockups/po-cart-total-minimum.html). The cart's estimated total,
   the order-by row, the minimum meter and its notes. Appended after the
   PO6 Slice 2 cart rules above, which it extends and in places overrides
   (the line row becomes a grid). State is icon plus words plus color,
   never color alone. */
.purchasing-cart-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
.purchasing-cart-icon {
  width: 20px;
  height: 20px;
  flex: none;
}
.purchasing-cart-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-6);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.purchasing-cart-summary[hidden] {
  display: none;
}
.purchasing-cart-summary-value {
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.purchasing-cart-summary-facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  flex: 1;
  min-width: 240px;
}
.purchasing-cart-summary-counts {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.purchasing-cart-summary-fine {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.purchasing-cart-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-full);
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
}
.purchasing-cart-total-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.purchasing-cart-vendor-group-name {
  min-width: 0;
  flex: 1 1 260px;
  overflow-wrap: anywhere;
}
.purchasing-cart-schedule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-3);
}
.purchasing-cart-schedule--warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
.purchasing-cart-schedule-text {
  margin: 0;
  flex: 1 1 220px;
  min-width: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.purchasing-cart-fix-button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.purchasing-cart-vendor-group-blocker-fix {
  min-height: var(--touch-target-min);
}
.purchasing-cart-line-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px 170px 120px auto;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  padding: var(--space-3) var(--space-4);
}
.purchasing-cart-line-product {
  min-width: 0;
  overflow-wrap: anywhere;
}
.purchasing-cart-line-quantity {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.purchasing-cart-line-quantity .purchasing-cart-line-quantity-input {
  width: 72px;
  min-height: var(--touch-target-min);
  text-align: center;
}
.purchasing-cart-line-unit {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.purchasing-cart-line-unit-cost {
  min-width: 0;
  flex: none;
}
.purchasing-cart-line-total {
  font-weight: var(--font-weight-semibold);
  text-align: right;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.purchasing-cart-no-price {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
}
.purchasing-cart-line-row .btn-compact {
  min-height: var(--touch-target-min);
}
.purchasing-cart-line-resolve {
  grid-column: 1 / -1;
  justify-self: start;
}
.purchasing-cart-line-blockers {
  grid-column: 1 / -1;
}
.purchasing-cart-vendor-group-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.purchasing-cart-total-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4) var(--space-6);
}
.purchasing-cart-total-block {
  min-width: 170px;
}
.purchasing-cart-total-value {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.purchasing-cart-total-value--partial {
  color: var(--color-warning-text);
}
.purchasing-cart-minimum {
  flex: 1 1 320px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.purchasing-cart-minimum-quiet {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  padding-top: var(--space-3);
}
.purchasing-cart-minimum-text {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.purchasing-cart-meter {
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  overflow: hidden;
}
.purchasing-cart-meter-fill {
  height: 100%;
  border-radius: var(--radius-full);
}
.purchasing-cart-meter-fill--ok {
  background: var(--color-success);
}
.purchasing-cart-meter-fill--warn {
  background: var(--color-warning);
}
.purchasing-cart-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
}
.purchasing-cart-note p {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.purchasing-cart-note--warn {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
.purchasing-cart-note--ok {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  font-weight: var(--font-weight-semibold);
}
.purchasing-cart-vendor-group-place {
  padding: var(--space-2) var(--space-4);
  overflow-wrap: anywhere;
}
@media (max-width: 900px) {
  .purchasing-cart-line-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "product remove"
      "qty total"
      "cost cost";
  }
  .purchasing-cart-line-product {
    grid-area: product;
  }
  .purchasing-cart-line-quantity {
    grid-area: qty;
  }
  .purchasing-cart-line-total {
    grid-area: total;
  }
  .purchasing-cart-line-unit-cost {
    grid-area: cost;
  }
  .purchasing-cart-line-row .btn-compact {
    grid-area: remove;
  }
  .purchasing-cart-line-blockers {
    grid-area: auto;
  }
  .purchasing-cart-summary-value {
    font-size: var(--font-size-2xl);
  }
}

/* PO7-S1 (docs/build-briefs/PO7-S1-invoice-attach.md). The Invoice card on the
   receiving screen and the purchase order detail (ui/src/invoiceCard.ts),
   after design/mockups/po-merge-invoice-receiving-attach.html. Touch only:
   every control is at least --touch-target-min, and nothing depends on hover. */
.invoice-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}

.invoice-card .section-title {
  margin-top: 0;
}

.invoice-capture-actions {
  display: flex;
  gap: var(--space-3);
  margin: var(--space-3) 0 var(--space-4);
}

.invoice-capture-button {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-comfortable);
  border: 1.5px dashed var(--color-border-strong);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  cursor: pointer;
}

.invoice-capture-button-busy {
  opacity: 0.6;
}

/* The native file input fills its label so a tap anywhere on the button opens
   the camera or the picker, and stays focusable for assistive technology. */
.invoice-file-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.invoice-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.invoice-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.invoice-row-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.invoice-thumb {
  width: 56px;
  height: 72px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.invoice-row-main {
  flex: 1;
  min-width: 0;
}

.invoice-file-name {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}

.invoice-file-meta {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-top: 2px;
}

.invoice-row-actions {
  display: flex;
  gap: var(--space-2);
}

.invoice-action-button {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
}

.invoice-empty {
  margin: 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}

.invoice-dup-warning {
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-size: var(--font-size-sm);
}

.invoice-dup-warning strong {
  display: block;
  margin-bottom: var(--space-1);
}

/* ---------- PO10: Update prices from a file (docs/build-briefs/PO10-vendor-price-list-import.md; DEC-294) ----------
   Ported from design/mockups/vendor-price-list-import.html onto this file's own
   tokens; no new colours. Admin surface, built touch-first: every target is at
   least --touch-target-min (the main action --touch-target-comfortable), nothing
   depends on hover, no keyboard rules. Every class here is pl-prefixed. While the
   screen is open the rest of Settings is hidden, so it reads as one full page. */
#admin-screen.admin-price-list-open .tabs-page > :not(#admin-price-list-screen) {
  display: none !important;
}
#admin-price-list-screen {
  max-width: 1120px;
  margin: 0 auto;
  overflow-wrap: anywhere;
}
#admin-price-list-screen button,
#admin-price-list-screen input,
#admin-price-list-screen label {
  font-family: inherit;
}
.pl-ico {
  width: 20px;
  height: 20px;
  flex: none;
}
.pl-ico-lg {
  width: 32px;
  height: 32px;
}
.pl-page-title {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-2);
}
.pl-page-sub {
  margin: 0 0 var(--space-5);
  color: var(--color-text-secondary);
  max-width: 70ch;
}
.pl-crumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.pl-btn {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
.pl-btn-primary {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-on-accent);
  background: var(--color-accent-strong);
  border: 0;
  border-radius: var(--radius-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  overflow-wrap: anywhere;
}
.pl-btn-primary:disabled,
.pl-btn-primary[disabled] {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  border: 1px solid var(--color-border);
}
.pl-btn-quiet {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: 0;
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}
.pl-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  border: 1px solid var(--color-border);
  padding: var(--space-5);
}
.pl-card + .pl-card {
  margin-top: var(--space-4);
}
.pl-card h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.pl-card p {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
}
.pl-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.pl-badge--quiet {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.pl-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-full);
}
.pl-chip--warn {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
}
.pl-chip--ok {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
}
.pl-chip--info {
  color: var(--color-info);
  background: var(--color-info-subtle);
}
.pl-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
.pl-note p {
  margin: 0;
  color: inherit;
}
.pl-note--warn {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
}
.pl-note--ok {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
}
.pl-note--info {
  color: var(--color-text-primary);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
}
.pl-note--danger {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
}
.pl-note strong {
  font-weight: var(--font-weight-bold);
}
.pl-steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}
.pl-step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-sm);
}
.pl-step-n {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-xs);
}
.pl-step--on {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-bold);
}
.pl-step--on .pl-step-n {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.pl-step--done .pl-step-n {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.pl-picker {
  /* DSC35-F3: anchors the visually hidden file input, so focusing it on tap does not scroll the page. */
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
  border: 2px dashed var(--color-border-strong);
}
.pl-picker--chosen {
  border-style: solid;
  border-color: var(--color-success-subtle-border);
  background: var(--color-success-subtle);
}
.pl-picker-text {
  flex: 1 1 260px;
  min-width: 0;
}
.pl-picker-name {
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.pl-picker-sub {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.pl-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.pl-col-box {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}
.pl-col-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
}
.pl-opt-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.pl-opt {
  min-height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.pl-opt--on {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  border-color: var(--color-accent-subtle-border);
}
.pl-two > .pl-card {
  margin-top: 0;
}
.pl-two {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}
.pl-plain-list {
  margin: 0;
  padding-left: var(--space-5);
  color: var(--color-text-secondary);
}
.pl-plain-list li {
  margin-bottom: var(--space-2);
}
.pl-plain-list strong {
  color: var(--color-text-primary);
}
.pl-never {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.pl-never li {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  color: var(--color-text-primary);
}
.pl-never .pl-ico {
  color: var(--color-success-text);
  margin-top: 2px;
}
.pl-cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.pl-tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.pl-tile {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4);
  min-height: var(--touch-target-min);
}
.pl-tile-n {
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums;
}
.pl-tile-l {
  font-weight: var(--font-weight-semibold);
}
.pl-tile-s {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.pl-tile--warn {
  border-color: var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
}
.pl-tile--warn .pl-tile-n,
.pl-tile--warn .pl-tile-l {
  color: var(--color-warning-strong);
}
.pl-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-5) 0 var(--space-3);
}
.pl-tab {
  min-height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}
.pl-tab-n {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-bold);
}
.pl-tab--on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.pl-tab--on .pl-tab-n {
  color: var(--color-accent-strong);
}
.pl-tab--flag .pl-tab-n {
  color: var(--color-warning-text);
}
.pl-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-3);
}
.pl-filter-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.pl-filter-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-tertiary);
  margin-right: var(--space-1);
}
.pl-plist {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.pl-phead,
.pl-prow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px 24px 96px 120px 112px;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
}
.pl-phead {
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-tertiary);
}
.pl-prow {
  border-top: 1px solid var(--color-border);
  min-height: 72px;
}
.pl-prow--held {
  background: var(--color-warning-subtle);
}
.pl-p-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.pl-p-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.pl-held-flag {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  color: var(--color-warning-text);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
}
.pl-p-prices {
  display: contents;
}
.pl-p-old,
.pl-p-new {
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-semibold);
}
.pl-p-old {
  color: var(--color-text-secondary);
}
.pl-p-new {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.pl-p-arrow {
  color: var(--color-text-tertiary);
  text-align: center;
}
.pl-lbl {
  display: none;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  margin-right: var(--space-2);
}
.pl-none {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.pl-delta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pl-delta .pl-ico {
  width: 16px;
  height: 16px;
}
.pl-delta--up {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
}
.pl-prow--held .pl-delta--up {
  background: var(--color-surface);
}
.pl-delta--down {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
}
.pl-delta--new {
  color: var(--color-info);
  background: var(--color-info-subtle);
}
.pl-switch {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: transparent;
  border: 0;
  padding: 0;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}
.pl-switch-track {
  width: 48px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  display: inline-flex;
  align-items: center;
  padding: 3px;
  flex: none;
}
.pl-switch-knob {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
}
.pl-switch[aria-checked="true"] .pl-switch-track {
  background: var(--color-accent-strong);
  justify-content: flex-end;
}
.pl-switch[aria-checked="true"] .pl-switch-text {
  color: var(--color-accent-strong);
}
.pl-switch[aria-checked="false"] .pl-switch-text {
  color: var(--color-text-secondary);
}
.pl-more-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.pl-applybar {
  margin-top: var(--space-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.pl-ab-text {
  flex: 1 1 280px;
  min-width: 0;
}
.pl-ab-main {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
}
.pl-ab-sub {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.pl-ab-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.pl-issue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.pl-issue {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3) var(--space-4);
  align-items: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-1);
}
.pl-issue--bad {
  border-color: var(--color-warning-subtle-border);
}
.pl-issue-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.pl-issue-why {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  margin-top: var(--space-1);
  overflow-wrap: anywhere;
}
.pl-issue-do {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-top: var(--space-1);
}
.pl-issue-fact {
  margin-top: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.pl-fact {
  font-size: var(--font-size-sm);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  font-variant-numeric: tabular-nums;
}
.pl-section-h {
  margin: var(--space-6) 0 var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.pl-section-h:first-of-type {
  margin-top: 0;
}
.pl-section-p {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
  max-width: 70ch;
}
.pl-tab-note {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.pl-sum-table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-3) 0 var(--space-4);
}
.pl-sum-table td {
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
  vertical-align: top;
}
.pl-sum-table td:last-child {
  text-align: right;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-left: var(--space-4);
}
.pl-sum-sub {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-regular);
}
.pl-done-hero {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}
.pl-done-ico {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-full);
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.pl-done-ico .pl-ico {
  width: 28px;
  height: 28px;
}
.pl-done-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
}
.pl-audit {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.pl-audit strong {
  color: var(--color-text-primary);
}
.pl-errs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}
.pl-err {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-1);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.pl-err--warn {
  border-color: var(--color-warning-subtle-border);
}
.pl-err--danger {
  border-color: var(--color-danger-subtle-border);
}
.pl-err-where {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-tertiary);
}
.pl-err h2 {
  margin: 0;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.pl-err p {
  margin: 0;
  color: var(--color-text-secondary);
}
.pl-err-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: auto;
}
.pl-err .pl-btn-primary {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  font-size: var(--font-size-sm);
}
.pl-fine {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin-top: var(--space-4);
}

@media (max-width: 1100px) {
  .pl-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .pl-cols,
  .pl-two,
  .pl-errs {
    grid-template-columns: minmax(0, 1fr);
  }
  .pl-phead {
    display: none;
  }
  .pl-prow {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "item sw" "prices delta";
    gap: var(--space-2) var(--space-4);
    padding: var(--space-4);
  }
  .pl-p-item {
    grid-area: item;
  }
  .pl-p-sw {
    grid-area: sw;
    justify-self: end;
  }
  .pl-p-prices {
    grid-area: prices;
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
  }
  .pl-p-delta {
    grid-area: delta;
    justify-self: end;
  }
  .pl-lbl {
    display: inline;
  }
}

.pl-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
.pl-back {
  gap: var(--space-2);
}
.pl-never-title {
  margin-top: var(--space-5);
}
.pl-card h2 {
  font-size: var(--font-size-md);
}
.pl-err {
  margin-bottom: var(--space-4);
}
.pl-err .pl-opt-row {
  margin-top: var(--space-1);
}
.pl-result-rows {
  margin-top: var(--space-4);
}
.pl-result-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
}
.pl-result-row strong {
  font-variant-numeric: tabular-nums;
}
.pl-card-entry {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  margin: var(--space-3) 0;
}
/* One column box (the price to use) fills the card instead of leaving half of it empty. */
.pl-cols {
  grid-template-columns: minmax(0, 1fr);
}
.pl-card-last {
  flex: 1 1 260px;
  margin: 0;
}
.pl-card-open {
  height: auto;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
}
.pl-applybar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
}

/* PO7-S2 (docs/build-briefs/PO7-S2-invoice-ocr-draft.md). The reading status
   under each attached invoice and its read-only draft (ui/src/invoiceCard.ts),
   after the line-group and total-bar language of
   design/mockups/po-merge-invoice-invoice-review.html. Touch only: the status
   action is at least --touch-target-min and nothing depends on hover. */
.invoice-reading {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.invoice-reading-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.invoice-reading-status {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.invoice-reading-drafted {
  color: var(--color-success-text);
}

.invoice-reading-failed {
  color: var(--color-danger-strong);
}

.invoice-reading-unavailable {
  color: var(--color-text-tertiary);
}

.invoice-draft {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  padding: var(--space-4);
}

.invoice-draft-note {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}

.invoice-draft-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  font-size: var(--font-size-sm);
}

.invoice-draft-facts dt,
.invoice-draft-totals dt {
  color: var(--color-text-tertiary);
}

.invoice-draft-facts dd,
.invoice-draft-totals dd {
  margin: 0;
}

.invoice-draft-value {
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}

.invoice-draft-confidence {
  margin-left: var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.invoice-draft-lines {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}

.invoice-draft-lines th {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.invoice-draft-lines th,
.invoice-draft-lines td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}

.invoice-draft-lines th:nth-child(n + 2),
.invoice-draft-lines td:nth-child(n + 2) {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.invoice-draft-lines td:first-child {
  overflow-wrap: anywhere;
}

.invoice-draft-totals {
  display: grid;
  grid-template-columns: 1fr max-content;
  gap: var(--space-2) var(--space-6);
  margin: 0;
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
}

.invoice-draft-total-value {
  text-align: right;
  font-weight: var(--font-weight-bold);
}

/* One divider between attached files, now that each file carries its own
   reading line and can carry a draft. */
.invoice-row-group + .invoice-row-group {
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

/* UX77 (docs/build-briefs/UX77-designer-findings-0304.md): the designer's
   DEC-194 findings on DOCSBUG4, INV31, TF4-F2, PO8 and PO7-S1. Appended only;
   each rule names the earlier block it adjusts. */

/* DOCSBUG4: the On hand block stays pinned at the top of the sheet body while
   the Recent movements list scrolls beneath it. A sticky element only sticks
   inside its own parent, so the two wrappers above it give their box up
   (display: contents) and the block's parent becomes the whole tab panel. */
.inv-info-grid,
.inv-info-media {
  display: contents;
}
.inv-onhand-block {
  position: sticky;
  /* The sheet body pads its top by --space-4; pin over that padding so no
     list row shows above the block. */
  top: calc(-1 * var(--space-4) - 2px);
  z-index: 2;
  margin-top: 0;
  padding: calc(var(--space-4) + 2px) 0 var(--space-3);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* INV31 (design/mockups/inv-opening-balance.html): the $0 cost line now sits
   between the tiles and the confirm list, so it takes its space from below. */
.ss-lock-note {
  margin: 0 0 var(--space-4);
}
/* INV31: primary buttons in the confirm, saving and result sheets and the
   Review location at the mockup's size and weight: md text, semibold, 56px tall,
   wide padding. The editor's Done stays at the mockup's 48px. */
#admin-starting-stock-screen .ss-sheet-f .btn-primary,
#admin-starting-stock-screen .ss-review {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-8);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
#admin-starting-stock-screen .ss-sheet-f .btn-secondary {
  min-height: var(--touch-target-comfortable);
  font-size: var(--font-size-base);
}
/* INV31: tenths chips never shrink below the 44px touch floor in either direction. */
#admin-starting-stock-screen .ss-tenth {
  flex: 0 0 auto;
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
}
/* INV31: the shared screen rule above (min 44, padding space-5) came later in
   the file than .ss-done-button and won; the mockup's Done is 48px. */
#admin-starting-stock-screen .btn-primary.ss-done-button {
  min-height: 48px;
  padding: 0 var(--space-6);
}

/* TF4-F2 (design/mockups/tf4-f2-abc2go-switch*.html): the whole "This vendor is
   ABC2GO" row is the switch's tap target. The switch's own label is stretched
   over the row (the row is position: relative), so a tap anywhere on it is a
   native tap on that label. The text underneath is not interactive. */
.abc2go-row .admin-toggle-label::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.abc2go-row .admin-toggle-label {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
}
/* TF4-F2: the success line leads with its check icon. */
.admin-field-help.admin-vendor-status--ok {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.admin-vendor-status--ok svg {
  flex: none;
}
/* TF4-F2: the mockup's delivery-day chips are white until selected. .admin-chip
   (tip presets, tinted always) is shared, so only the vendor day chips, which
   carry data-day, change. */
.admin-chip[data-day]:not(.admin-chip--selected) {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-medium);
}

/* PO8 (design/mockups/po-cart-total-minimum.html): the editable quantity box is
   white. .field-input's sunken beige reads as a read-only field. */
.purchasing-cart-line-quantity .purchasing-cart-line-quantity-input {
  background: var(--color-surface);
}

/* PO7-S1 (design/mockups/po-merge-invoice-*.html): "Back to orders" keeps its
   label on one line (it wrapped to three at 1280); the title takes what is
   left and wraps instead. */
#purchasing-order-detail-back {
  white-space: nowrap;
  flex: none;
}
#purchasing-order-detail-vendor {
  min-width: 0;
  overflow-wrap: anywhere;
}
/* PO7-S1: a rejected file's message is the red notice card (the mockup's
   .dup-warning: danger tint, border, padding, radius), not bare red text. */
.invoice-card .invoice-error {
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: var(--space-3) 0;
}

/* PO7-S3 (docs/build-briefs/PO7-S3-invoice-review-and-variance.md). The invoice
   review screen inside the Invoice card (ui/src/invoiceReviewView.ts), after
   design/mockups/po-merge-invoice-invoice-review.html: Matched, Needs your
   attention, Held back and a totals location. Each row is a heading line (the item,
   why it is here, one button) and, for matched rows, a strip of figures laid
   label over value so six figures fit at tablet width. Touch only: every
   control is at least --touch-target-min and nothing depends on hover. */
.invoice-review {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.review-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.review-title {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}

.review-back {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
}

.review-subtitle {
  margin: 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.review-section-title {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}

.review-section-count {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}

.review-section-help {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.review-group {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

.review-empty {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}

.review-line {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}

.review-line:last-child {
  border-bottom: none;
}

.review-line-flagged {
  background: var(--color-warning-subtle);
}

.review-group-held .review-line {
  background: var(--color-danger-subtle);
}

.review-line-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.review-line-name {
  flex: 1;
  min-width: 0;
}

.review-line-product {
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}

.review-line-reason {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.review-reason-source {
  color: var(--color-text-tertiary);
}

.review-reason-unmatched {
  color: var(--color-warning-text);
}

.review-reason-held {
  color: var(--color-danger-strong);
}

.review-row-button {
  flex-shrink: 0;
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.review-line-detail {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-secondary);
}

.review-line-note {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.review-figures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 0.8fr)) repeat(2, minmax(0, 1fr)) minmax(0, 1.5fr);
  gap: var(--space-2) var(--space-3);
}

.review-figure {
  display: flex;
  flex-direction: column;
  gap: var(--space-hairline);
  min-width: 0;
}

.review-figure-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.review-figure-value {
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.review-diff-up {
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}

.review-flags {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.review-flag {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}

.review-edit {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}

.review-edit-fields {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.review-edit-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1 1 220px;
  min-width: 0;
}

.review-edit-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.review-edit-select,
.review-edit-input {
  min-height: var(--touch-target-min);
  width: 100%;
  box-sizing: border-box;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
}

.review-edit-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.review-edit-button {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
}

.review-edit-error {
  margin: 0;
}

.review-total-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.review-total-figures {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.review-total-label {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.review-total-value {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}

.review-total-note {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.review-confirm {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  max-width: 100%;
}

.review-confirm-button {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-border);
  color: var(--color-text-tertiary);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.review-confirm-note {
  margin: 0;
  max-width: 420px;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  text-align: right;
}

/* UX78 (docs/build-briefs/UX78-recheck-findings-1005.md): the vendor's own
   active switch carries the visible words "Vendor active"; each vendor contact
   field keeps a visible label above it; the receiving Cost field is wide enough
   for its whole "Cost per bottle $" placeholder at 1280 (the row already wraps). */
.admin-vendor-active-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.admin-vendor-active-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.admin-vendor-row .admin-vendor-field-label {
  margin-top: var(--space-3);
}
.purchasing-receiving-line-cost-input {
  width: 200px;
  max-width: 100%;
}

/* ---------- PO7-S4: confirm the reviewed invoice (docs/build-briefs/PO7-S4-invoice-confirm-and-cost.md) ----------
   Appended to PO7-S3's review block above and built from its own tokens; no new
   colours. The mockup draws only the disabled Confirm invoice, so the enabled
   button, the confirm step and the Confirmed panel are drawn here from the same
   vocabulary (accent for the one primary action, success for a confirmed state)
   and are for the designer. Touch only: every target is at least
   --touch-target-min, nothing depends on hover. */

.review-confirm-button:not(:disabled) {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
  cursor: pointer;
}

.review-confirm-step {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 420px;
  padding: var(--space-4);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
}

.review-confirm-step[hidden] {
  display: none;
}

.review-confirm-step-text {
  margin: 0;
  font-size: var(--font-size-sm);
  text-align: left;
}

.review-confirm-step-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.review-confirm-yes,
.review-confirm-no {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}

.review-confirm-error {
  margin: 0;
  text-align: left;
}

.review-confirmed {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-lg);
}

.review-confirmed-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-lg);
  color: var(--color-success-strong);
}

.review-confirmed-by {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
}

.review-confirmed-totals {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.review-confirmed-lines {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.review-confirmed-line {
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.review-confirmed-product {
  font-weight: var(--font-weight-semibold);
}

.review-confirmed-figures {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.review-confirmed-outcome {
  font-size: var(--font-size-sm);
}

.review-outcome-conflicting_costs,
.review-outcome-cost_unresolved,
.review-outcome-receipt_already_corrected,
.review-outcome-receipt_without_cost {
  color: var(--color-warning-text);
}

.review-lock-pending {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
}

.review-lock-text {
  margin: 0;
  font-size: var(--font-size-sm);
}

.review-lock-button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}
/* ---------- TEN8: Software Owner console (docs/build-briefs/TEN8-create-franchisee.md) ----------
   Built from design/mockups/ux70-software-owner-console.html on the existing tokens and
   theme. An admin surface for SnipSip staff on a laptop or desktop. */

#software-owner-screen .so-shell {
  max-width: 1320px;
  margin: 0 auto;
  padding: var(--space-5);
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
}

.so-nav {
  flex: 0 0 240px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  position: sticky;
  top: var(--space-5);
}

.so-nav-item {
  appearance: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: left;
  border: 1px solid transparent;
  background: none;
  border-radius: var(--radius-md);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  cursor: pointer;
}

.so-nav-item[hidden] {
  display: none;
}

.so-nav-item[aria-current="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}

.so-nav-item:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}

.so-content {
  flex: 1;
  min-width: 0;
}

.so-banner {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.so-brand {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-lg);
  letter-spacing: -0.01em;
}

.so-tier-badge {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-3);
}

.so-page-title {
  margin-bottom: var(--space-4);
}

.so-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
}

.so-toolbar {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.so-toolbar-text {
  margin: 0;
}

.so-help {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: 0 0 var(--space-3);
}

.so-error-row {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.so-error-row[hidden] {
  display: none;
}

.so-error-row .admin-error {
  margin: 0;
}

.so-table {
  width: 100%;
  border-collapse: collapse;
}

.so-table th {
  text-align: left;
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border-strong);
}

.so-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  vertical-align: middle;
}

.so-table tr:last-child td {
  border-bottom: none;
}

.so-row-primary {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

.so-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  white-space: nowrap;
}

.so-badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.so-badge-good {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}

.so-badge-warn {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
}

.so-badge-bad {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
}

.so-badge-neutral {
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border-color: var(--color-border-strong);
}

#software-owner-onboard-form {
  /* TEN13-F1: wide enough that the Customer type row fits above Create at 1280x800 (the first-screen rule). */
  max-width: 800px;
}

#software-owner-onboard-form .field-input {
  width: 100%;
}

.so-field-help {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}

.so-settings-box {
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}

.so-settings-box .so-help {
  margin: 0;
}

.so-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

.so-created {
  max-width: 640px;
}

.so-created-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-3);
}

.so-handoff {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: 0 0 var(--space-4);
}

/* ONB1: the handoff prints on its own. Everything else is hidden for print, the card is placed at the top of the page,
   and the screen-only buttons are dropped. */
@media print {
  body * {
    visibility: hidden;
  }
  #software-owner-handoff,
  #software-owner-handoff *,
  #software-owner-first-owner-handoff,
  #software-owner-first-owner-handoff *,
  #software-owner-welcome-panel,
  #software-owner-welcome-panel * {
    visibility: visible;
  }
  #software-owner-handoff,
  #software-owner-first-owner-handoff,
  #software-owner-welcome-panel {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    border: 1px solid #000;
  }
  #software-owner-handoff .so-actions,
  #software-owner-first-owner-print,
  #software-owner-welcome-panel .so-actions,
  #software-owner-welcome-panel .so-welcome-row button {
    display: none;
  }
}

/* ONBW1-S1 (DEC-416; design/mockups/onboarding-wizard/so-6-welcome): the Send the welcome message panel. */
.so-welcome {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-welcome-hint {
  margin: 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.so-welcome-row {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
}

.so-welcome-label {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.so-welcome-input {
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface, transparent);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
}

textarea.so-welcome-input {
  resize: none;
  overflow-wrap: anywhere;
  word-break: break-all;
  font-family: var(--font-mono, ui-monospace, monospace);
}

.so-welcome-result {
  margin: 0;
  min-height: 1.25rem;
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
}

.so-welcome-code {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--font-size-lg);
  letter-spacing: 0.08em;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.so-welcome-banner {
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken, rgba(0, 0, 0, 0.04));
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
}

.so-handoff-title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-3);
}

.so-handoff-rows {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.so-handoff-rows dt {
  color: var(--color-text-secondary);
}

.so-handoff-rows dd {
  margin: 0;
  color: var(--color-text-primary);
}

.so-setupcode-value {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--font-size-lg);
  letter-spacing: 0.08em;
  font-weight: var(--font-weight-semibold);
  /* 2026-10-09: in a narrow customer card the code wrapped over four lines and lost its last
     character. It takes its own full-width row, under its label, and never breaks. */
  grid-column: 1 / -1;
  white-space: nowrap;
  overflow-wrap: normal;
}

.so-created-lines {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  overflow-wrap: anywhere;
}

#software-owner-onboard-form .admin-field .admin-error {
  margin: 0;
  min-height: 0;
}

/* ---------- TEN9 (DEC-297): software owner sign-in page ----------
   ui/software-owner.html. A desktop page on the existing tokens and the existing field,
   button and error classes; only the layout below is new. The top bar follows the UX70
   software owner console mockup (wordmark, tier badge, the signed-in person, Sign out). */
.so-wordmark {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-lg);
  letter-spacing: -0.01em;
}

.so-tier-badge {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  padding: 2px var(--space-3);
  border-radius: var(--radius-sm);
}

/* Top-aligned, never vertically centred: a tall card (the enrolment form on a short
   screen) starts at the top and the page scrolls, it is never clipped. */
.so-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-4) var(--space-12);
}

.so-card {
  width: 100%;
  max-width: 480px;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-8);
}

.so-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  margin: 0 0 var(--space-1);
  overflow-wrap: anywhere;
}

.so-title:focus {
  outline: none;
}

.so-title:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}

.so-subtitle {
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-4);
  overflow-wrap: anywhere;
}

.so-step {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.so-note,
.so-hint,
.so-count {
  margin: var(--space-4) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  line-height: var(--line-height-relaxed);
}

.so-hint {
  margin-top: var(--space-1);
}

.so-count {
  margin-top: var(--space-1);
  font-weight: var(--font-weight-medium);
}

/* Success and neutral notices are never red. */
.so-status {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-relaxed);
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
}

.so-status[data-tone="success"] {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}

#so-add-copy-status {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
}

.so-field-row {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
}

.so-field-row .field-input {
  flex: 1 1 auto;
  min-width: 0;
}

.so-show {
  flex: 0 0 auto;
  min-width: 72px;
  padding: 0 var(--space-3);
}

.so-code-input {
  height: auto;
  min-height: calc(var(--touch-target-comfortable) * 1.4);
  padding: var(--space-2) var(--space-4);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  resize: none;
  overflow-wrap: anywhere;
}

.so-submit {
  width: 100%;
  margin-top: var(--space-4);
}

.so-link {
  display: block;
  margin: var(--space-4) auto 0;
  padding: var(--space-2) var(--space-3);
  background: none;
  border: none;
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-medium);
  text-decoration: underline;
  cursor: pointer;
}

.so-home {
  width: 100%;
  max-width: 960px;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.so-home-head .so-limits {
  margin-top: var(--space-1);
}

.so-panel {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  padding: var(--space-6) var(--space-8);
}

.so-panel-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-4);
}

.so-state {
  margin: 0;
  color: var(--color-text-secondary);
}

.so-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.so-table th,
.so-table td {
  text-align: left;
  padding: var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--color-border);
  overflow-wrap: anywhere;
  vertical-align: middle;
}

.so-table th {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.so-table th:nth-child(3) {
  width: 120px;
}

.so-table th:nth-child(4) {
  width: 210px;
}

.so-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.so-row-button {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
}

.so-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}

.so-pill::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: currentColor;
}

.so-pill-active {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border: 1px solid var(--color-success-subtle-border);
}

.so-pill-invited {
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}

.so-pill-disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-strong);
}

.so-reason {
  background: var(--color-surface-sunken);
}

.so-reason .btn-secondary,
.so-reason .btn-danger {
  width: auto;
  margin: var(--space-3) var(--space-2) 0 0;
}

.so-add-form {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: var(--space-4);
  align-items: end;
}

.so-add-form .field-label {
  margin-top: 0;
}

.so-code {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
}

.so-code:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.so-code-value {
  display: block;
  margin-top: var(--space-3);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.08em;
  line-height: var(--line-height-relaxed);
  overflow-wrap: anywhere;
  user-select: all;
}

.so-code-actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.so-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

/* ---------- TEN9-F2: the Software Owner console on the software owner page ----------
   Customers and Onboard (TEN8) now sit beside the accounts list in ui/software-owner.html.
   The left navigation reuses TEN8's .so-nav rules above; only the shell layout, the wider
   signed-in page and the customers table's column widths are new. */
.so-home.so-home-console {
  max-width: 1200px;
}

.so-console {
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
  width: 100%;
}

.so-console .so-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.so-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.so-view[hidden],
.so-console .so-panel[hidden] {
  display: none;
}

/* TEN13 added Type and Franchisor after Customer (the UX70 mockup's order), so the columns are now
   Customer, Type, Franchisor, Data region, Status, Legal profile, Added. Shares of the table's width,
   because fixed pixel widths no longer fit seven columns beside the console's left navigation. */
.so-table.so-customers th:nth-child(1) {
  width: 22%;
}

.so-table.so-customers th:nth-child(2) {
  width: 13%;
}

.so-customers td:nth-child(2) {
  padding-right: var(--space-4);
}

.so-table.so-customers th:nth-child(3) {
  width: 16%;
}

.so-table.so-customers th:nth-child(4) {
  width: 7%;
}

.so-table.so-customers th:nth-child(5) {
  width: 15%;
}

.so-table.so-customers th:nth-child(6) {
  width: 17%;
}

.so-table.so-customers th:nth-child(7) {
  width: 10%;
}
/* ---------- UX79: Settings uses the width the screen has (docs/build-briefs/UX79-reports-fill-width.md) ----------
   The admin column no longer has a cap, so on a wide screen tables and reports
   grow with it. Forms and prose keep a readable line length: a text or number
   field never stretches past 480px, a paragraph stops at 90 characters, and
   the setup checklist keeps its row short so a label stays near its action.
   Reports are left alone: their tables and tiles fill the column. */
#admin-screen .admin-setup-checklist {
  max-width: 1100px;
}
#admin-screen [id^="admin-group-panel-"]:not(#admin-group-panel-reports) .field-input,
#admin-screen [id^="admin-group-panel-"]:not(#admin-group-panel-reports) .field-input-affix {
  max-width: 480px;
}
#admin-screen [id^="admin-group-panel-"]:not(#admin-group-panel-reports) p {
  max-width: 90ch;
}
/* KPI tiles: more room on a wide screen, so the figure never crowds its note. */
#admin-group-panel-reports .kpi .v {
  font-size: clamp(var(--font-size-2xl), 1.6vw, 2.5rem);
}

/* ---------- Software owner console review (TEN9 follow-up) ----------
   Desktop only, by owner ruling (2026-08-27): the console is managed from a laptop or PC, so
   nothing here is sized or tested for a tablet. */
.so-row-primary,
.so-created-title,
.so-table td {
  overflow-wrap: anywhere;
}

.so-table td {
  min-width: 0;
}

.so-nav .so-limits {
  margin: var(--space-3) var(--space-4) 0;
  font-size: var(--font-size-xs);
}

/* Name and first location side by side, region and starting settings side by side, so the
   Create button is on the first screen at 1280x800. */
.so-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3) var(--space-6);
  align-items: start;
}

/* TEN13-F1: the franchisor picker takes the whole row, under the Customer type and Data region pair. */
#software-owner-franchisor-field {
  grid-column: 1 / -1;
}

/* TEN13-F1: an empty error line takes no room, so the added Customer type row does not push Create below the
   first screen at 1280x800. An error that appears takes its room then. */
#software-owner-onboard-form .so-form-grid .admin-error:empty {
  display: none;
}

.so-form-grid .admin-field,
.so-form-grid #software-owner-franchisor-field {
  margin-bottom: 0;
}

.so-type-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.so-type-row .admin-chip-select {
  margin-bottom: 0;
}

.so-type-filter {
  margin-bottom: var(--space-4);
}

.so-type-filter[hidden] {
  display: none;
}

.so-form-grid [hidden] {
  display: none;
}

.so-form-grid .so-settings-box {
  grid-column: 1 / -1;
  margin-top: 0;
  margin-bottom: var(--space-2);
}

.so-warning {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-md);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
}

.so-actions .btn-danger,
.so-reason .btn-danger {
  width: auto;
}

/* PO7-S4-F1 (docs/build-briefs/PO7-S4-F1-invoice-line-kinds.md, DEC-299): invoice line
   kinds on the review screen. Built after design/mockups/po7-s4-f1-*.html. */
.review-row-actions {
  display: flex;
  gap: var(--space-2);
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.review-other-line .review-line-head {
  flex-wrap: wrap;
}

.review-other-line-left {
  background: var(--color-warning-subtle);
}

.review-kind-chip {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.review-kind-chip-minus {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}

.review-kind-chip-left {
  background: transparent;
  color: var(--color-warning-strong);
}

.review-other-amount {
  min-width: 92px;
  text-align: right;
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

.review-other-amount-minus {
  color: var(--color-success-text);
}

.review-sheet-wrap {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
}

.review-sheet-scrim {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
}

.review-sheet {
  position: absolute;
  z-index: var(--z-sheet);
  max-height: 92vh;
  overflow-y: auto;
  box-sizing: border-box;
  padding: var(--space-5) var(--space-6) var(--space-6);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}

.review-sheet-title {
  margin: 0;
  font-size: var(--font-size-lg);
}

.review-sheet-line {
  margin: var(--space-1) 0 var(--space-4);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}

.review-sheet-fix {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
}

.review-sheet-warning {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-size: var(--font-size-sm);
}

.review-sheet-fixrow {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
  max-width: 240px;
}

.review-kind-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.review-kind-tile {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-primary);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}

.review-kind-tile-current {
  border-color: var(--color-accent-strong);
  box-shadow: 0 0 0 2px var(--color-accent-strong);
}

.review-kind-tile:disabled {
  opacity: 0.6;
}

.review-kind-sign {
  flex: none;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}

.review-kind-sign-minus {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}

.review-kind-words {
  display: block;
  min-width: 0;
}

.review-kind-title {
  display: block;
  font-size: var(--font-size-base);
}

.review-kind-sentence {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
  line-height: 1.25;
}

.review-kind-suggest {
  margin-left: auto;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  background: var(--color-info-subtle);
  color: var(--color-info);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.review-kind-leave {
  justify-content: center;
}

.review-sheet-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.review-sheet-note {
  max-width: 460px;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.review-sheet-cancel {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}

@media (min-width: 1000px) {
  .review-sheet {
    left: 50%;
    top: 50%;
    width: 760px;
    max-width: calc(100vw - var(--space-6));
    transform: translate(-50%, -50%);
    border-radius: var(--radius-xl);
  }
}

@media (max-width: 999px) {
  .review-sheet {
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }
}

.review-evf-block {
  margin-top: var(--space-6);
}

.review-evf {
  width: 100%;
  border-collapse: collapse;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  font-size: var(--font-size-sm);
}

.review-evf th {
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
  text-align: right;
  text-transform: uppercase;
}

.review-evf th:first-child,
.review-evf td:first-child {
  text-align: left;
}

.review-evf td {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.review-evf td:first-child {
  font-weight: var(--font-weight-medium);
  font-variant-numeric: normal;
}

.review-evf-none {
  color: var(--color-text-tertiary);
}

.review-evf-minus {
  color: var(--color-success-text);
}

.review-evf-tone-notcounted td {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}

.review-evf-tone-total td {
  background: var(--color-surface-sunken);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
}

.review-printed-check {
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}

.review-printed-ok {
  border-color: var(--color-success-subtle-border);
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}

.review-printed-warn {
  border-color: var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}

.review-printed-title {
  display: block;
  font-variant-numeric: tabular-nums;
}

.review-confirm-step-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-md);
}

@media (max-width: 900px) {
  .review-evf th,
  .review-evf td {
    padding: var(--space-3) var(--space-3);
  }
}

@media (max-width: 599px) {
  .review-kind-grid {
    grid-template-columns: 1fr;
  }
}

.review-other-line .review-line-reason {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}

.review-other-line-left .review-line-reason {
  color: var(--color-warning-strong);
}

.invoice-review > .review-confirm-step {
  max-width: none;
  margin-top: var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}

.invoice-review > .review-confirm-step .review-confirm-step-actions {
  justify-content: flex-start;
}

/* ---------- UX80 (docs/build-briefs/UX80-operations-menu.md; DEC-298): account menu and moved screens ----------
   One appended block. The two level account menu, the operations view frame on
   the admin screen, the Ordering switch and the Stock levels list. Tokens only;
   no hover rule anywhere (touch). Width of Settings and Reports is UX79's. */
.account-trigger {
  position: relative;
}
.account-trigger-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--radius-full);
  background: var(--color-danger-solid);
  color: #fff;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--color-surface);
}
.account-dropdown {
  width: 372px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 84px);
  overflow-y: auto;
  padding: var(--space-2);
  border-radius: var(--radius-lg);
}
.account-menu-level {
  display: flex;
  flex-direction: column;
}
.account-menu-who {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
}
.account-menu-avatar {
  width: 40px;
  height: 40px;
  font-size: var(--font-size-sm);
}
.account-menu-who-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.account-menu-who-name {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
.account-menu-who-role {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.account-menu-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-primary);
  font-size: var(--font-size-md);
  text-align: left;
}
.account-menu-row:active {
  background: var(--color-surface-sunken);
}
.account-menu-row-tall {
  min-height: 56px;
}
.account-menu-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.account-menu-label {
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-tight);
}
.account-menu-sub {
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.account-menu-sub:empty {
  display: none;
}
.account-menu-row-accent .account-menu-label {
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.account-menu-row-quiet .account-menu-label {
  color: var(--color-text-secondary);
}
.account-menu-chevron {
  width: 10px;
  height: 16px;
  flex: none;
  color: var(--color-text-tertiary);
}
.account-menu-chevron-back {
  color: var(--color-accent-strong);
}
.account-menu-rule {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-2) var(--space-3);
}
.account-menu-group-title {
  color: var(--color-text-primary);
  margin: 0;
  padding: var(--space-1) var(--space-3) var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.account-menu-section {
  padding: var(--space-3) var(--space-3) var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.account-menu-badge {
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  margin-left: 0;
}
.account-menu-badge-red {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  border: 1px solid var(--color-danger-subtle-border);
}
.account-menu-badge-orange {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
.account-menu-badge-none {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-strong);
}
.account-menu-badge-blue {
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}

/* The operations view frame on #admin-screen: Settings chrome hidden, the view
   names itself. */
#admin-screen.admin-ops-mode #admin-setup-checklist,
#admin-screen.admin-ops-mode .settings-rail {
  display: none;
}
.ops-view-header {
  align-items: flex-start;
}
.ops-view-heading {
  min-width: 0;
}
.ops-view-back {
  flex: none;
  min-height: var(--touch-target-min);
}
.ops-eyebrow {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.ordering-switch-slot {
  margin-bottom: var(--space-4);
}
.ordering-switch {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}
.ordering-switch-button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.ordering-switch-button[aria-current="page"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.ordering-switch-count {
  margin-left: var(--space-2);
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background: var(--color-info-subtle);
  color: var(--color-info);
  font-size: var(--font-size-xs);
}
.admin-price-list-picker-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) 0;
}
.admin-price-list-picker-name {
  font-weight: var(--font-weight-semibold);
}
#admin-stock-levels-panel .admin-panel-header {
  margin-bottom: var(--space-3);
}
#admin-stock-levels-panel.admin-stock-detail-open > :not(#admin-stock-detail-panel) {
  display: none;
}
.admin-stock-detail-head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.admin-stock-detail-head .section-title {
  margin: 0;
}
.ordering-switch-slot {
  margin-bottom: var(--space-6);
}
/* The item's stock panel is inline in the page, not in a sheet body: pin On hand
   flush with the top of the page scroller (the sheet rule offsets it by the
   sheet body's own padding). */
#admin-stock-detail-panel .inv-onhand-block {
  top: 0;
  padding-top: var(--space-3);
}

/* INV35-B1-F1 (docs/build-briefs/INV35-B1-F1-delivery-vendor-picker.md; DEC-300; design/mockups/
   inv35-b1-f1-receive-vendor.html, built on design/tokens.css and the brass theme only). The
   "Receive stock (no purchase order)" screen: a labelled form in two columns (the entry, and
   Recorded this visit), an optional Vendor row that opens the "Pick a vendor" sheet, and Record
   delivery pinned to the bottom of the screen. Every target is 44px or taller, nothing depends on
   hover, and long vendor names wrap. */
.receive-stock-page {
  max-width: 1200px;
}
/* The title and its one-line explanation stack, as in the design, so the title never wraps. */
.receive-stock-page .tabs-page-header {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
}
.receive-stock-page .tabs-page-header .admin-page-subtitle {
  margin: 0;
  max-width: 70ch;
}
.receive-stock-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}
.receive-stock-main,
.receive-stock-side {
  min-width: 0;
}
.receive-stock-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4) var(--space-5);
}
.receive-stock-card .section-title {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  letter-spacing: normal;
  text-transform: none;
  color: var(--color-text-primary);
}
.receive-stock-card .tabs-empty {
  padding: 0;
  text-align: left;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.receive-stock-card .purchasing-outside-order-recorded-list {
  margin-bottom: 0;
  gap: 0;
}
.receive-stock-card .purchasing-outside-order-recorded-row {
  gap: var(--space-1) var(--space-3);
  padding: var(--space-3) 0;
  border: 0;
  border-top: 1px solid var(--color-border);
  border-radius: 0;
  background: none;
}
.receive-stock-card .purchasing-outside-order-recorded-row:first-child {
  border-top: 0;
}
.receive-stock-card .purchasing-outside-order-recorded-product {
  flex: 1 1 100%;
  min-width: 0;
  overflow-wrap: anywhere;
}
.receive-stock-card .purchasing-outside-order-recorded-quantity,
.receive-stock-card .purchasing-outside-order-recorded-reference {
  flex: 0 1 auto;
  min-width: 0;
}
.receive-stock-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: var(--space-4);
}
.receive-stock-grid .purchasing-outside-order-cost-input {
  width: 100%;
}
.receive-stock-field {
  margin-top: var(--space-3);
  min-width: 0;
}
.receive-stock-grid .receive-stock-field {
  margin-top: 0;
}
.receive-stock-label {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.receive-stock-optional {
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.receive-stock-qty-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.receive-stock-qty-row .admin-chip-select {
  margin-bottom: 0;
}
.receive-stock-qty-row .purchasing-outside-order-quantity-input {
  width: 88px;
}
.purchasing-outside-order-entry .purchasing-outside-order-entry-header {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.purchasing-outside-order-entry .purchasing-outside-order-reference-input {
  width: 100%;
}
.purchasing-outside-order-recorded-vendor {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
/* Room under the form so the pinned bar never covers its last field. */
#purchasing-outside-order-screen .receive-stock-page {
  padding-bottom: calc(var(--touch-target-comfortable) + var(--space-20));
}
.receive-stock-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 80px;
  padding: var(--space-3) var(--space-5);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -4px 16px rgba(20, 18, 15, 0.06);
}
.receive-stock-bar-note {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.receive-stock-bar .receive-stock-submit {
  flex: none;
  min-width: 260px;
  height: var(--touch-target-comfortable);
  padding: 0 var(--space-8);
  margin-top: 0;
}
#purchasing-outside-order-screen .receive-stock-bar #purchasing-outside-order-submit {
  margin-top: 0;
}

/* The vendor row. One big tap target that opens the list, never a text field. */
.receive-vendor-box {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.receive-vendor-box:disabled {
  cursor: default;
  color: var(--color-text-tertiary);
}
.receive-vendor-box.is-set {
  border-color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
}
.receive-vendor-box-text {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.receive-vendor-box.is-empty .receive-vendor-box-text {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.receive-vendor-box-name {
  font-weight: var(--font-weight-semibold);
}
.receive-vendor-box-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.receive-vendor-change {
  flex: none;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
}
.receive-vendor-chevron {
  width: 10px;
  height: 16px;
  flex: none;
  color: var(--color-text-tertiary);
}
.receive-vendor-tag {
  display: inline-flex;
  align-items: center;
  flex: none;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.receive-vendor-tag.is-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
/* Between two items the vendor is still picked; this strip says so and offers Clear. */
.receive-vendor-carry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-strong);
  background: var(--color-accent-subtle);
}
.receive-vendor-carry-text {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.receive-vendor-carry .btn-secondary {
  flex: none;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
}
.receive-vendor-chosen-row {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
}
.receive-vendor-chosen-row .receive-vendor-clear {
  flex: none;
  min-width: var(--touch-target-min);
  height: auto;
  padding: 0 var(--space-4);
}
.receive-vendor-suggest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.receive-vendor-help {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.receive-vendor-help.is-warn {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-warning-strong);
}
.receive-vendor-load-failed {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-danger-strong);
}
.receive-vendor-chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.receive-vendor-chip.is-on {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}

/* The "Pick a vendor" sheet: centered, a fixed height, only the list scrolls, so the search box
   and the footer never move and the way to finish stays in reach above a keyboard. */
.receive-vendor-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-scrim);
}
.receive-vendor-sheet {
  width: 600px;
  max-width: calc(100vw - 32px);
  max-height: none;
  height: min(720px, calc(100dvh - 48px));
  border-radius: var(--radius-xl);
}
.receive-vendor-sheet:focus {
  outline: none;
}
.receive-vendor-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.receive-vendor-title {
  flex: 1;
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}
.receive-vendor-head .btn-secondary {
  flex: none;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
}
.receive-vendor-searchbox {
  position: relative;
  flex: none;
  margin: 0 var(--space-5) var(--space-2);
}
.receive-vendor-search {
  width: 100%;
  height: var(--touch-target-comfortable);
  padding: 0 calc(var(--touch-target-min) + var(--space-2)) 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font: inherit;
}
/* The sheet draws its own 44px clear button; hide the browser's small built-in one. */
.receive-vendor-search::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
.receive-vendor-search:focus {
  outline: none;
  border-color: var(--color-accent-strong);
  box-shadow: var(--shadow-focus);
  background: var(--color-surface);
}
.receive-vendor-search-clear {
  position: absolute;
  top: 6px;
  right: 6px;
  min-width: var(--touch-target-min);
  min-height: var(--touch-target-min);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--color-text-secondary);
  font: inherit;
  cursor: pointer;
}
.receive-vendor-recent {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-1) var(--space-5) var(--space-2);
}
.receive-vendor-recent-label {
  margin-right: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.receive-vendor-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-3);
  -webkit-overflow-scrolling: touch;
}
.receive-vendor-letter {
  padding: var(--space-3) var(--space-3) var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.receive-vendor-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.receive-vendor-row-name {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-tight);
}
.receive-vendor-row-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
.receive-vendor-row.is-selected {
  background: var(--color-accent-subtle);
}
.receive-vendor-row.is-selected .receive-vendor-row-name {
  font-weight: var(--font-weight-bold);
  color: var(--color-accent-strong);
}
.receive-vendor-row.is-off .receive-vendor-row-name {
  color: var(--color-text-secondary);
}
.receive-vendor-none {
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-border);
  border-radius: 0;
}
.receive-vendor-check {
  width: 22px;
  height: 22px;
  flex: none;
  color: var(--color-accent-strong);
}
.receive-vendor-empty {
  margin: var(--space-4) var(--space-3);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.receive-vendor-foot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-5);
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

@media (max-width: 900px) {
  .receive-stock-cols {
    grid-template-columns: minmax(0, 1fr);
  }
  .receive-stock-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .receive-stock-bar {
    padding: var(--space-3) var(--space-4);
  }
  .receive-stock-bar .receive-stock-submit {
    min-width: 200px;
  }
  .receive-vendor-sheet {
    height: min(720px, calc(100dvh - 96px));
  }
}

/* ---------- LOC1-G1-F1 7a (DEC-301): legal details on the software owner console ----------
   The Entity, Contacts and Billing address groups on the Onboard form and on a customer's
   Legal details panel, in the UX70 mockup's order. Desktop only (owner ruling 2026-08-27). The
   need tags use the existing warning and neutral tones; nothing new in the palette. */
.so-legal-group {
  margin: 0 0 var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  min-width: 0;
}

.so-legal-legend {
  padding: 0 var(--space-2);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.so-legal-help {
  margin: 0 0 var(--space-3);
}

.so-legal-grid .admin-field {
  min-width: 0;
}

.so-legal-grid .so-legal-wide {
  grid-column: 1 / -1;
}

.so-need {
  display: inline-block;
  margin-left: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}

.so-need-golive {
  color: var(--color-warning-text);
}

#software-owner-profile-form {
  max-width: 640px;
}

#software-owner-profile-form .field-input {
  width: 100%;
}

#software-owner-profile-form .admin-field .admin-error {
  margin: 0;
  min-height: 0;
}

.so-legal-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

/* The Onboard form keeps the legal groups collapsed by default so Create stays on the first
   screen at 1280x800; opening them shows the same fields the Legal details panel carries. */
.so-legal-details {
  margin: 0 0 var(--space-2);
}

.so-legal-summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

.so-legal-summary:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}

.so-legal-details[open] > .so-legal-summary {
  margin-bottom: var(--space-4);
}

.so-legal-cell .btn-secondary {
  white-space: nowrap;
}

/* Customer detail (owner scope addition 2026-10-06, from the UX70 customer detail mockup): the
   sections are cards on the console's surface, one idea each, with the page title carrying the
   customer's name. */
.so-detail-card {
  margin: 0 0 var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  max-width: 720px;
}

.so-detail-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}

#software-owner-rename-form .field-input {
  width: 100%;
}

.so-row-link {
  padding: 0;
  text-align: left;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
}

#software-owner-profile-form.so-detail-card {
  max-width: 720px;
}

.so-detail-card .so-legal-group {
  border-color: transparent;
  padding-left: 0;
  padding-right: 0;
}

/* ---------- Customer detail, design review changes (2026-10-06) ---------- */
.so-help:empty {
  display: none;
}

/* One-line label row: the label on the left, the need tag on the right and never wrapped, so
   side-by-side inputs line up. Quiet tones for Optional and 30 days, emphasis for go-live only. */
.so-label-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}

.so-label-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.so-need {
  margin-left: 0;
  flex: none;
  white-space: nowrap;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}

.so-need-golive {
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}

.so-same-billing {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* A picker that matches the text inputs: one custom chevron, no native arrow. */
select.field-input {
  appearance: none;
  padding-right: var(--space-7, 2.25rem);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--color-text-secondary) 50%),
    linear-gradient(135deg, var(--color-text-secondary) 50%, transparent 50%);
  background-position:
    calc(100% - 18px) 55%,
    calc(100% - 12px) 55%;
  background-size:
    6px 6px,
    6px 6px;
  background-repeat: no-repeat;
}

.so-back-link {
  display: inline-block;
  margin: 0 0 var(--space-3);
  padding: 0;
  font-size: var(--font-size-sm);
}

.so-detail-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: 0 0 var(--space-2);
}

.so-detail-head .so-panel-title {
  margin: 0;
  overflow-wrap: anywhere;
  min-width: 0;
}

.so-detail-subtitle {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}

/* UX98: one wide area holding a responsive grid of cards, not a 300px side column. The Legal details form takes
   the full row and comes first, so its own two-column fields keep fitting; the cards below it fill the rest.
   .so-detail-side only groups the cards in the markup, so it adds no box of its own. */
.so-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
  grid-auto-flow: row dense;
  gap: var(--space-4);
  /* UX101: cards in one row share a height, so a short card and a tall one pair as a row, not as a ragged gap. */
  align-items: stretch;
}

/* UX101: Card payments is a grid item, as wide as the grid, above the Legal details form. */
.so-detail-grid .so-cp-card {
  grid-column: 1 / -1;
  order: -2;
  margin-bottom: 0;
}

/* UX101: the two short cards close the grid together, so no short card is stretched beside a tall one. */
#software-owner-royalty-card,
#software-owner-setupcode-card {
  order: 2;
}

/* UX101: the type pill is as wide as its text, not the card. */
.so-current-name > .so-badge {
  display: inline-block;
  width: auto;
  max-width: 100%;
}

.so-detail-side {
  display: contents;
}

#software-owner-profile-form.so-detail-card {
  grid-column: 1 / -1;
  order: -1;
}

.so-detail-grid .so-detail-card,
#software-owner-profile-form.so-detail-card {
  max-width: none;
  margin-bottom: 0;
  min-width: 0;
}

.so-detail-card .so-legal-legend {
  padding: 0;
  font-size: var(--font-size-base);
}

.so-detail-card .so-legal-group {
  margin-bottom: var(--space-5);
}

.so-detail-card .so-legal-help,
.so-detail-card > .so-help {
  margin-bottom: var(--space-4);
}

.so-current-name {
  margin: 0 0 var(--space-3);
  overflow-wrap: anywhere;
}

.so-current-name > span {
  display: block;
}

.so-rename-input {
  resize: none;
  overflow: hidden;
  line-height: 1.35;
  /* UX101: one line sits in the middle of the 44px box; the script grows the box for a longer name. */
  height: auto;
  min-height: var(--touch-target-comfortable);
  padding-block: calc((var(--touch-target-comfortable) - 1.35em - 2px) / 2);
}

.so-actions-inline {
  align-items: center;
  flex-wrap: wrap;
}

.so-inline-status {
  display: inline-block;
  min-width: 12ch;
  font-size: var(--font-size-sm);
  color: var(--color-success-text);
}

.so-savebar {
  /* UX101: the location sits at the foot of its own card and never floats over fields (it was sticky to the viewport). */
  position: static;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--color-border);
}

.so-row-link {
  overflow-wrap: anywhere;
  text-align: left;
}

.so-customers td:first-child {
  max-width: 260px;
}

.so-customers td:nth-child(5),
.so-customers td:nth-child(6) {
  max-width: 150px;
}

.so-customers td:nth-child(5) .so-badge,
.so-customers td:nth-child(6) .so-badge {
  white-space: normal;
}

.so-legal-grid {
  align-items: end;
}

.so-rename-input {
  font: inherit;
}

/* UX98: a button or a label on the detail page is one line. A row of actions wraps between buttons, never
   inside one. */
.so-detail-card button,
.so-cp-card button,
#software-owner-profile-panel .so-link {
  white-space: nowrap;
}

.so-detail-card .so-label-text {
  white-space: nowrap;
}

/* TEN22: the EIN field in the legal fields. Show sits inside the field at its right end; Change sits at the right
   of the caption. Tokens only. */
.so-label-row:has(.so-ein-change) {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.so-ein-wrap {
  position: relative;
  display: block;
}

.so-ein-wrap .field-input {
  padding-right: calc(var(--space-6) * 2);
}

.so-ein-wrap .so-ein-recorded {
  letter-spacing: 0.04em;
}

.so-ein-show,
.so-ein-change {
  padding: 0 var(--space-3);
  background: none;
  border: none;
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

.so-ein-show {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
}

.so-ein-change {
  padding: 0;
  text-decoration: underline;
}

.so-ein-show:focus-visible,
.so-ein-change:focus-visible {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
}

/* CL6-F1-F3 (docs/build-briefs/CL6-F1-F3-timezone-required.md; DEC-281,
   DEC-286; design/mockups/cl6-f1-f3-timezone-required*.html). Tokens only, no
   new colour. Settings half: the "Needs setup" rail tag, the warning card, the
   Business day card and the Session inactivity card. Floor half: the refusal
   sheet, which lives inside #choice-scrim (the reason-sheet precedent, because
   check:chrome-ratchet refuses a new scrim) and centres that scrim while it is
   shown. Every target is 44px or taller; nothing needs hover. */
.settings-rail-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.settings-rail-tag,
.bd-tag {
  display: inline-flex;
  align-items: center;
  flex: none;
  white-space: nowrap;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.settings-rail-tag {
  height: 24px;
}
.settings-rail-tag[hidden],
.bd-tag[hidden],
.bd-alert[hidden],
.bd-why[hidden],
.bd-note[hidden],
.bd-sheet[hidden] {
  display: none;
}
.bd-tag {
  height: 28px;
  padding: 0 10px;
  font-weight: var(--font-weight-semibold);
}
.bd-tag-ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.bd-alert {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  margin-bottom: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  box-shadow: inset 4px 0 0 var(--color-warning-strong);
}
.bd-alert-icon {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-warning-strong);
  color: var(--color-warning-subtle);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-bold);
}
.bd-alert-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-md);
  color: var(--color-warning-strong);
}
.bd-alert p {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-warning-strong);
}
.bd-alert p + p {
  margin-top: var(--space-1);
}
.bd-card {
  margin-bottom: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
}
.bd-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-1);
}
.bd-card-title {
  margin: 0;
  font-size: var(--font-size-lg);
}
.bd-help {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.bd-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
.bd-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.bd-label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.bd-label-row {
  min-height: 28px;
}
.bd-label-row .field-label {
  margin: 0;
}
.bd-field .field-input {
  min-height: var(--touch-target-comfortable);
  width: 100%;
}
.bd-field .field-input.bd-needs-pick {
  border-color: var(--color-warning-strong);
  box-shadow: 0 0 0 3px var(--color-warning-subtle);
}
.bd-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.bd-actions .btn-primary,
.bd-actions .btn-secondary {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  white-space: nowrap;
}
.bd-actions .btn-primary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
}
.bd-actions .btn-secondary:disabled {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
}
.bd-why {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.bd-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-session-inactivity-card .field-input {
  width: 240px;
  max-width: 100%;
  min-height: var(--touch-target-comfortable);
}
.scrim.bd-scrim-centered {
  align-items: center;
}
.bd-sheet {
  width: 600px;
  max-width: calc(100% - var(--space-8));
  padding: var(--space-8);
  gap: var(--space-4);
  border-radius: var(--radius-xl);
  max-height: calc(100% - var(--space-8));
  overflow-y: auto;
}
.bd-sheet-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}
.bd-sheet-title {
  margin: 0;
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
}
.bd-sheet-text {
  margin: 0;
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
  line-height: var(--line-height-normal);
}
.bd-sheet-safe {
  margin: 0;
  display: flex;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
.bd-sheet-buttons {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.bd-sheet-buttons .btn-primary,
.bd-sheet-buttons .btn-secondary {
  flex: 1;
  min-height: var(--touch-target-comfortable);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.bd-sheet-buttons .btn-secondary {
  font-weight: var(--font-weight-semibold);
}
.bd-sheet-buttons [hidden] {
  display: none;
}
@media (max-width: 900px) {
  .bd-fields {
    grid-template-columns: 1fr;
  }
  #admin-session-inactivity-card .field-input {
    width: 100%;
  }
}

/* TEN10 (DEC-310): the software owner console's Help section. Desktop styling, existing tokens. */
.so-help-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-help-item {
  appearance: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  text-align: left;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  color: inherit;
  font: inherit;
}

.so-help-item:active {
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
}

.so-help-item:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}

.so-help-item-title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.so-help-item-summary {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.so-help-guide-title {
  margin-top: var(--space-4);
}

.so-help-guide-title:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.so-help-guide-summary {
  margin: 0 0 var(--space-4);
  color: var(--color-text-secondary);
}

.so-help-article {
  max-width: 880px;
  line-height: 1.55;
}

.so-help-article p,
.so-help-article ul {
  margin: 0 0 var(--space-4);
}

.so-help-article li + li {
  margin-top: var(--space-2);
}

.so-help-heading {
  font-weight: var(--font-weight-semibold);
  margin: var(--space-6) 0 var(--space-3);
}

h3.so-help-heading {
  font-size: var(--font-size-lg);
}

h4.so-help-heading {
  font-size: var(--font-size-base);
}

.so-help-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--space-4);
}

.so-help-table th,
.so-help-table td {
  text-align: left;
  vertical-align: top;
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  overflow-wrap: break-word;
  word-break: normal;
}

/* The first column is a label (Group, Field, Row) or a short message: wide enough that no
   ordinary word is broken in it. */
.so-help-table th:first-child,
.so-help-table td:first-child {
  min-width: 9rem;
}

.so-help-table th {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.so-help-figure {
  margin: 0 0 var(--space-5);
}

.so-help-image {
  display: block;
  max-width: 360px;
  width: 100%;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.so-help-figure figcaption {
  margin-top: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* ---------------------------------------------------------------------
   TAX2-S1-F1 (docs/build-briefs/TAX2-S1-F1-tax-rate-settings.md): the Sales tax section of Settings,
   Money and pricing. Ported from design/mockups/tax2-s1-f1-tax-rate-settings.html onto existing
   tokens only. Touch only: no hover rules, every control 44px or taller.
   --------------------------------------------------------------------- */
#admin-tax-rate-section {
  margin-bottom: var(--space-6);
}
.taxs-ico {
  width: 20px;
  height: 20px;
  flex: none;
}
.taxs-ico-holder {
  display: inline-flex;
  flex: none;
}
.taxs-chev {
  width: 10px;
  height: 16px;
  flex: none;
  color: var(--color-text-tertiary);
}
.taxs-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.taxs-head-text {
  min-width: 0;
}
.taxs-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}
.taxs-help {
  margin: var(--space-1) 0 var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.taxs-head .taxs-help {
  margin-bottom: 0;
}
.taxs-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  border: 1px solid var(--color-border);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.taxs-card--sched {
  border-color: var(--color-info-subtle-border);
}
.taxs-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}
.taxs-card-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.taxs-btn-primary {
  white-space: nowrap;
  flex: none;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
}
.taxs-btn-primary[disabled] {
  background: var(--color-border-strong);
  color: var(--color-text-secondary);
  box-shadow: none;
  cursor: default;
}
.taxs-btn-secondary {
  flex: none;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
}
.taxs-tag {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  white-space: nowrap;
  flex: none;
}
.taxs-tag--ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.taxs-tag--info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
  color: var(--color-info);
}
.taxs-big {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin: var(--space-2) 0 var(--space-3);
}
.taxs-big-n {
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.taxs-big-w {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.taxs-parts {
  border-top: 1px solid var(--color-border);
}
.taxs-part {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 48px;
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
}
.taxs-part-n {
  font-weight: var(--font-weight-medium);
}
.taxs-part-v {
  font-weight: var(--font-weight-semibold);
}
.taxs-part--zero {
  color: var(--color-text-tertiary);
}
.taxs-part--zero .taxs-part-v {
  font-weight: var(--font-weight-regular);
}
.taxs-part--total {
  border-bottom: 0;
  background: var(--color-surface-sunken);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  margin-top: var(--space-2);
  font-weight: var(--font-weight-bold);
}
.taxs-part--total .taxs-part-v {
  font-weight: var(--font-weight-bold);
}
.taxs-fine {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  margin: var(--space-3) 0 0;
}
.taxs-note {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  margin-bottom: var(--space-4);
}
.taxs-note--warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.taxs-note--danger {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}
.taxs-note--ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.taxs-note--tight {
  margin-top: var(--space-3);
}
.taxs-note .taxs-ico-holder {
  margin-top: 1px;
}
.taxs-note-text {
  flex: 1;
  min-width: 0;
}
.taxs-note-text b {
  font-weight: var(--font-weight-bold);
}
.taxs-note-text .taxs-btn-secondary {
  margin-top: var(--space-2);
  display: flex;
  width: fit-content;
}
.taxs-seg {
  display: inline-flex;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: 4px;
  gap: 4px;
  margin-bottom: var(--space-4);
}
.taxs-seg-btn {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  display: inline-flex;
  align-items: center;
  border: 0;
  background: transparent;
  border-radius: var(--radius-md);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.taxs-seg-btn--on {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.taxs-group-t {
  font-weight: var(--font-weight-bold);
  margin: var(--space-5) 0 var(--space-1);
}
.taxs-frow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
  min-height: 72px;
}
.taxs-parts-form .taxs-frow:first-child,
.taxs-frow:first-child {
  border-top: 1px solid var(--color-border);
}
.taxs-fl {
  flex: 1;
  min-width: 0;
}
.taxs-fl label {
  display: block;
  font-weight: var(--font-weight-semibold);
}
.taxs-fh {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.taxs-step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
}
.taxs-sb {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}
.taxs-pct {
  position: relative;
  display: inline-block;
}
.taxs-pct::after {
  content: "%";
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  pointer-events: none;
}
.taxs-input {
  width: 120px;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  padding: 0 34px 0 var(--space-3);
  font: inherit;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  text-align: right;
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}
.taxs-pct--bad .taxs-input,
.taxs-input--bad {
  border-color: var(--color-danger);
  background: var(--color-danger-subtle);
  box-shadow: 0 0 0 1px var(--color-danger);
}
.taxs-ferr {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  margin-top: var(--space-1);
}
.taxs-ferr[hidden],
.taxs-note[hidden],
#admin-tax-rate-section [hidden] {
  display: none;
}
.taxs-dategrid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0 var(--space-3);
}
.taxs-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  display: inline-flex;
  align-items: center;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  cursor: pointer;
}
.taxs-chip--on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.taxs-dateinput {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.taxs-input--date {
  width: 220px;
  max-width: 100%;
  text-align: left;
  padding: 0 var(--space-4);
}
.taxs-result {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-6);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin: var(--space-4) 0;
}
.taxs-result--bad {
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
}
.taxs-result--bad .taxs-result-v {
  color: var(--color-danger-strong);
}
.taxs-result-k {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.taxs-result-v {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums;
}
.taxs-result-v--small {
  font-size: var(--font-size-lg);
}
.taxs-result-cmp {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex-basis: 100%;
}
.taxs-savebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-4);
}
.taxs-why {
  flex: 1;
  min-width: 200px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.taxs-hist {
  border-top: 1px solid var(--color-border);
}
.taxs-hist-sum {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-2) 0;
  cursor: pointer;
}
.taxs-hist-sum::-webkit-details-marker {
  display: none;
}
.taxs-hist-tx {
  flex: 1;
  min-width: 0;
}
.taxs-hist-1 {
  font-weight: var(--font-weight-semibold);
  margin: 0;
}
.taxs-hist-2 {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.taxs-hist-rate {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  font-variant-numeric: tabular-nums;
}
.taxs-hist[open] .taxs-chev {
  transform: rotate(90deg);
}
.taxs-hist-body {
  padding: 0 0 var(--space-4);
  margin-left: var(--space-2);
}
.taxs-who {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin: var(--space-2) 0 0;
}
.taxs-tag--muted {
  color: var(--color-text-secondary);
}
@media (max-width: 900px) {
  .taxs-head {
    flex-direction: column;
  }
  .taxs-frow {
    flex-wrap: wrap;
  }
}

/* ---------- AU17: Change history (docs/build-briefs/AU17-change-history.md; design/mockups/au17-*.html) ----------
   Drawn by ui/src/changeHistory.ts inside the operations frame. Built only on the shared tokens. Every
   control is 44px or taller and nothing depends on hover. The detail sheet is a side sheet at 1000px and
   wider and a bottom sheet below. */
#admin-change-history-panel {
  display: block;
}
#admin-change-history-panel[hidden] {
  display: none;
}
.ch-root {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ch-ico {
  width: 20px;
  height: 20px;
  flex: none;
}
.ch-download-note {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ch-btn-secondary,
.ch-btn-primary,
.ch-btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border-radius: var(--radius-md);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  white-space: nowrap;
}
.ch-btn-secondary {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.ch-btn-primary {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border: none;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
}
.ch-btn-quiet {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
}
.ch-btn-secondary:disabled,
.ch-btn-primary:disabled {
  opacity: 0.5;
  cursor: default;
}
.ch-btn-wide {
  width: 100%;
}
.ch-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.ch-filters[hidden] {
  display: none;
}
.ch-filters {
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.ch-rangebar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.ch-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  cursor: pointer;
}
.ch-chip.ch-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.ch-rangebar-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: flex-end;
}
.ch-summary-left {
  display: flex;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
  flex-wrap: wrap;
}
.ch-range-span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ch-range-span b {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}
.ch-custom-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.ch-custom-row[hidden],
.ch-activebar[hidden] {
  display: none;
}
.ch-pickrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--space-3);
}
.ch-fld {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.ch-fld label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.ch-sel,
.ch-txt {
  width: 100%;
  height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background-color: var(--color-surface);
  color: var(--color-text-primary);
  padding: 0 var(--space-4);
  font: inherit;
}
.ch-sel {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'><path d='M1.5 1.5l5.5 5.5 5.5-5.5' fill='none' stroke='%237a452e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 16px center;
}
.ch-search {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><circle cx='7.5' cy='7.5' r='5.5' fill='none' stroke='%238a5e4c' stroke-width='2'/><path d='M12 12l4.5 4.5' stroke='%238a5e4c' stroke-width='2' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: 14px center;
  padding-left: 44px;
}
.ch-search::placeholder {
  color: var(--color-text-tertiary);
}
.ch-sel.ch-on,
.ch-txt.ch-on {
  border-color: var(--color-accent-strong);
  background-color: var(--color-accent-subtle);
}
.ch-activebar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.ch-apill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2) 0 var(--space-4);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.ch-apill-x {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--color-accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.ch-apill-x .ch-ico {
  width: 16px;
  height: 16px;
}
.ch-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0 var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex-wrap: wrap;
}
.ch-summary:empty {
  display: none;
}
.ch-summary b {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}
.ch-results {
  padding: 0 var(--space-5) var(--space-3);
  overflow: hidden;
}
.ch-results-empty {
  padding-bottom: var(--space-5);
}
.ch-head,
.ch-row,
.ch-skel {
  display: grid;
  grid-template-columns: 132px 200px 180px minmax(0, 1fr) 36px;
  gap: var(--space-4);
  align-items: center;
}
.ch-head {
  height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border-strong);
  font-size: var(--font-size-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.ch-day {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-4) 0 var(--space-2);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
}
.ch-day small {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
.ch-row {
  min-height: 68px;
  padding: var(--space-2) 0;
  border: 0;
  border-top: 1px solid var(--color-border);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  width: 100%;
  cursor: pointer;
}
.ch-day + .ch-row {
  border-top: 0;
}
.ch-row.ch-row-sel {
  background: var(--color-accent-subtle);
  margin: 0 calc(var(--space-3) * -1);
  padding: var(--space-2) var(--space-3);
  width: calc(100% + var(--space-3) * 2);
  border-radius: var(--radius-md);
  border-top-color: transparent;
}
.ch-when {
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-medium);
}
.ch-who {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-medium);
  min-width: 0;
}
.ch-nm {
  min-width: 0;
  overflow-wrap: anywhere;
}
.ch-avatar {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  flex: none;
}
.ch-avatar-sm {
  width: 28px;
  height: 28px;
  font-size: 11px;
}
.ch-avatar-gray {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.ch-tag {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.ch-tag-access {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
  color: var(--color-info);
}
.ch-tag-legal {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.ch-what {
  min-width: 0;
  line-height: var(--line-height-normal);
  overflow-wrap: anywhere;
}
.ch-was {
  color: var(--color-text-secondary);
}
.ch-b {
  font-weight: var(--font-weight-bold);
}
.ch-more {
  display: inline-block;
  margin-left: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-full);
  padding: 2px 10px;
  vertical-align: 1px;
}
.ch-hid {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.ch-chev {
  width: 10px;
  height: 16px;
  color: var(--color-text-tertiary);
  justify-self: end;
}
.ch-mtop {
  display: none;
}
.ch-root mark {
  background: var(--color-warning-subtle);
  color: inherit;
  border-radius: 3px;
  padding: 0;
}
.ch-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) 0 var(--space-3);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  text-align: center;
}
.ch-lockline {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  text-align: center;
}
.ch-coverage {
  margin: 0;
  max-width: 78ch;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.ch-skel {
  min-height: 68px;
  border-top: 1px solid var(--color-border);
}
.ch-bar {
  display: block;
  height: 16px;
  border-radius: 8px;
  background: linear-gradient(
    90deg,
    var(--color-surface-sunken) 25%,
    var(--color-border) 50%,
    var(--color-surface-sunken) 75%
  );
  background-size: 200% 100%;
  animation: ch-shimmer 1.4s linear infinite;
}
.ch-w1 {
  width: 70%;
}
.ch-w2 {
  width: 85%;
}
.ch-w3 {
  width: 60%;
}
.ch-w4 {
  width: 92%;
}
@keyframes ch-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}
.ch-loadnote {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  margin: var(--space-4) 0 var(--space-2);
}
.ch-spin {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 3px solid var(--color-border-strong);
  border-top-color: var(--color-accent-strong);
  animation: ch-spin 0.9s linear infinite;
  flex: none;
}
@keyframes ch-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ch-bar,
  .ch-spin {
    animation: none;
  }
}
.ch-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-16) var(--space-6);
  gap: var(--space-3);
}
.ch-badge {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-2);
}
.ch-badge .ch-ico {
  width: 32px;
  height: 32px;
}
.ch-empty h2 {
  margin: 0;
  font-size: var(--font-size-lg);
}
.ch-empty p {
  margin: 0;
  color: var(--color-text-secondary);
  max-width: 46ch;
}
.ch-acts {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}
/* detail sheet */
.ch-scrim {
  position: fixed;
  inset: 0;
  background: var(--color-scrim);
  z-index: var(--z-scrim);
}
.ch-scrim[hidden],
.ch-panel[hidden] {
  display: none;
}
.ch-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 500px;
  max-width: 100%;
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
  z-index: var(--z-sheet);
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
}
.ch-grab {
  display: none;
  width: 44px;
  height: 5px;
  border-radius: 3px;
  background: var(--color-border-strong);
  margin: var(--space-2) auto 0;
}
.ch-ph {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) var(--space-4);
}
.ch-ph-text {
  flex: 1;
  min-width: 0;
}
.ch-ph h2 {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.ch-ey {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-1);
}
.ch-xbtn {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-full);
  border: 0;
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  cursor: pointer;
}
.ch-pbody {
  flex: 1;
  overflow: auto;
  padding: 0 var(--space-5) var(--space-4);
}
.ch-meta {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-sm);
}
.ch-meta dt {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.ch-meta dd {
  margin: 0;
  font-weight: var(--font-weight-medium);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  overflow-wrap: anywhere;
}
.ch-chg-h {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  margin: var(--space-2) 0;
}
.ch-chg {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}
.ch-fl {
  font-weight: var(--font-weight-semibold);
  margin-bottom: var(--space-2);
  overflow-wrap: anywhere;
}
.ch-beforeafter {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.ch-ba {
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  min-height: var(--touch-target-min);
  min-width: 0;
}
.ch-ba small {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ch-ba span {
  display: block;
  font-size: var(--font-size-md);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.ch-was-box {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.ch-now {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border: 1px solid var(--color-success-subtle-border);
}
.ch-now span {
  font-weight: var(--font-weight-bold);
}
.ch-hidden {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  border: 1px dashed var(--color-border-strong);
}
.ch-hidden span {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.ch-callout {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  margin-bottom: var(--space-3);
}
.ch-pfoot {
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.ch-mini-list {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 0 var(--space-4);
}
.ch-mrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-3);
  align-items: center;
  min-height: 52px;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}
.ch-mrow:first-child {
  border-top: 0;
}
.ch-mrow-head {
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  min-height: var(--touch-target-min);
}
.ch-mrow .ch-a {
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 70px;
}
.ch-mrow .ch-b {
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  min-width: 70px;
  text-align: right;
}
/* The role editor's one-line hint under a permission's name. */
.admin-permission-hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-top: 2px;
}
/* mid width, 1280 */
@media (max-width: 1360px) {
  .ch-head,
  .ch-row,
  .ch-skel {
    grid-template-columns: 112px 168px 150px minmax(0, 1fr) 28px;
    gap: var(--space-3);
  }
  .ch-panel {
    width: 460px;
  }
}
/* tablet portrait, 820 */
@media (max-width: 1000px) {
  .ch-rangebar-actions {
    margin-left: 0;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
  }
  .ch-rangebar-actions .ch-btn-secondary {
    width: 100%;
  }
  .ch-download-note {
    order: 2;
    text-align: center;
  }
  .ch-pickrow {
    grid-template-columns: 1fr 1fr;
  }
  .ch-pickrow .ch-fld-search {
    grid-column: 1 / -1;
  }
  .ch-head {
    display: none;
  }
  .ch-row,
  .ch-skel {
    grid-template-columns: minmax(0, 1fr) 28px;
    grid-template-areas:
      "top chev"
      "what chev"
      "area chev";
    gap: var(--space-2) var(--space-3);
    padding: var(--space-3) 0;
  }
  .ch-row > .ch-when,
  .ch-row > .ch-who {
    display: none;
  }
  .ch-row > .ch-mtop {
    grid-area: top;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
  }
  .ch-row > .ch-mtop b {
    color: var(--color-text-primary);
    font-variant-numeric: tabular-nums;
  }
  .ch-row > .ch-what {
    grid-area: what;
  }
  .ch-row > .ch-areacell {
    grid-area: area;
  }
  .ch-row > .ch-chev {
    grid-area: chev;
    align-self: center;
  }
  .ch-skel > :nth-child(1),
  .ch-skel > :nth-child(2) {
    display: none;
  }
  .ch-panel {
    top: auto;
    left: 0;
    right: 0;
    width: 100%;
    height: 76%;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }
  .ch-grab {
    display: block;
  }
}

/* ---------- AU18: the Audit log's Activity tab (docs/build-briefs/AU18-location-audit-log.md) ----------
   Reuses the Change history's .ch-* rows, chips and fields. The row is not a button (nothing opens), and its
   last cell is a 44px link, so the grid's last column is 44px instead of the chevron's 36px. */
.al-tabs {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.al-pickrow {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
/* TEN11-S5: the Support access tab. */
.al-support-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}
.al-support-head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.al-support-changes {
  margin: 0;
  padding-left: var(--space-4);
  white-space: pre-wrap;
}
.al-support-row .ch-btn-secondary {
  align-self: flex-start;
  min-height: 44px;
}
.al-head,
.al-row,
.al-skel {
  grid-template-columns: 132px 200px 180px minmax(0, 1fr) 44px;
}
.al-row {
  cursor: default;
}
.al-what {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.al-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.al-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: var(--radius-md);
  color: var(--color-text-secondary);
  text-decoration: none;
}
.al-open-none {
  pointer-events: none;
}
.al-open .ch-chev {
  justify-self: center;
}
@media (max-width: 1360px) {
  .al-head,
  .al-row,
  .al-skel {
    grid-template-columns: 112px 168px 150px minmax(0, 1fr) 44px;
  }
}
@media (max-width: 1000px) {
  .al-pickrow {
    grid-template-columns: 1fr 1fr;
  }
  .al-row,
  .al-skel {
    grid-template-columns: minmax(0, 1fr) 44px;
  }
  .al-row > .al-open {
    grid-area: chev;
    align-self: center;
  }
}

/* ---------- TAX2-S2: the Sales tax worksheet (docs/build-briefs/TAX2-S2-sales-tax-worksheet.md) ----------
   Drawn into #reports-body by ui/src/salesTaxWorksheet.ts, to design/mockups/tax2-1-september.html.
   Existing tokens only. Every control is 44px or taller, nothing depends on hover, and only the Day by
   day table scrolls sideways, inside its own box. */
#admin-group-panel-reports .stw {
  min-width: 0;
}
#admin-group-panel-reports .stw-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: flex-start;
  margin-bottom: var(--space-4);
}
/* UIFIX1 (SF-6): the report toolbar above already names the location, so the worksheet does not say it a second time. */
#admin-group-panel-reports .stw-controls .stw-ctl:has(.stw-loc) {
  display: none;
}
#admin-group-panel-reports .stw-ctl {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
#admin-group-panel-reports .stw-clabel {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
/* Plain text, not a chip: there is one location and nothing to tap (designer review #2). */
#admin-group-panel-reports .stw-loc {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .stw-period {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
#admin-group-panel-reports .stw-plabel {
  min-width: 9.5em;
  text-align: center;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-md);
}
#admin-group-panel-reports .stw-arrow {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: 50%;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
#admin-group-panel-reports .stw-arrow:disabled {
  opacity: 0.4;
  cursor: default;
}
#admin-group-panel-reports .stw-seg {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
#admin-group-panel-reports .stw-seg button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: calc(var(--radius-md) - 2px);
  background: transparent;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-sm);
  cursor: pointer;
}
#admin-group-panel-reports .stw-seg button.on {
  background: var(--color-surface);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-1);
}
/* TAX2-S2-F1: the period kinds, the two date pickers of Custom, and the saved-default mark. Tokens only. */
#admin-group-panel-reports .stw-ctlrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
}
#admin-group-panel-reports .stw-makedefault {
  min-height: var(--touch-target-min);
}
#admin-group-panel-reports .stw-dates {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}
#admin-group-panel-reports .stw-datelab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-date {
  width: auto;
  min-width: 11em;
  min-height: var(--touch-target-comfortable);
}
#admin-group-panel-reports .stw-savefail {
  flex-basis: 100%;
  margin: 0;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .stw .fresh {
  margin-bottom: var(--space-5);
}
#admin-group-panel-reports .stw-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}
@media (max-width: 1000px) {
  #admin-group-panel-reports .stw-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
#admin-group-panel-reports .stw-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}
#admin-group-panel-reports .stw-grid .card,
#admin-group-panel-reports .stw-side .card {
  margin: 0;
}
#admin-group-panel-reports .stw-sum {
  display: flex;
  flex-direction: column;
}
#admin-group-panel-reports .stw-srow {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}
#admin-group-panel-reports .stw-ln {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border-radius: var(--radius-sm);
  padding: 3px var(--space-2);
  text-align: center;
  white-space: nowrap;
}
#admin-group-panel-reports .stw-srow.nobadge {
  grid-template-columns: minmax(0, 1fr) auto;
}
#admin-group-panel-reports .stw-srow.minor .stw-ln {
  background: transparent;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
#admin-group-panel-reports .stw-sl {
  display: flex;
  flex-direction: column;
  line-height: 1.3;
  min-width: 0;
}
#admin-group-panel-reports .stw-sl small {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-sa {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
#admin-group-panel-reports .stw-srow.minor .stw-sa,
#admin-group-panel-reports .stw-srow.minor .stw-sl b {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-srow.key {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  border-bottom-color: transparent;
  padding: var(--space-3);
  margin: 2px calc(var(--space-3) * -1);
}
#admin-group-panel-reports .stw-srow.key .stw-sa {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .stw-srow.negative .stw-sa {
  color: var(--color-warning-text);
}
#admin-group-panel-reports .stw-sgroup {
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  padding: var(--space-4) 0 var(--space-1);
}
#admin-group-panel-reports .stw-how {
  margin-top: var(--space-4);
}
#admin-group-panel-reports .stw-how summary {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-min);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  cursor: pointer;
}
#admin-group-panel-reports .stw-how ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
#admin-group-panel-reports .stw-adv {
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .stw-chklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
#admin-group-panel-reports .stw-chk {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  min-height: var(--touch-target-comfortable);
}
#admin-group-panel-reports .stw-chk:last-child {
  border-bottom: 0;
}
#admin-group-panel-reports .stw-ck {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  margin-top: 2px;
}
#admin-group-panel-reports .stw-ck.ok {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  border: 1px solid var(--color-success-subtle-border);
}
#admin-group-panel-reports .stw-ck.warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border: 1px solid var(--color-warning-subtle-border);
}
#admin-group-panel-reports .stw-ck.info {
  background: var(--color-info-subtle);
  color: var(--color-info);
  border: 1px solid var(--color-info-subtle-border);
}
#admin-group-panel-reports .stw-ct {
  display: flex;
  flex-direction: column;
  flex: 1 1 14em;
  min-width: 0;
  line-height: 1.35;
}
#admin-group-panel-reports .stw-ct span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-chk.warn .stw-ct b {
  color: var(--color-warning-strong);
}
#admin-group-panel-reports .stw-seebtn {
  align-self: flex-start;
  margin-top: var(--space-2);
  white-space: normal;
  text-align: center;
}
#admin-group-panel-reports .stw-passed-toggle {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--touch-target-min);
  margin-top: var(--space-2);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-success-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  text-align: left;
  cursor: pointer;
}
#admin-group-panel-reports .stw-passed-list {
  margin-top: var(--space-2);
}
#admin-group-panel-reports .stw-checklist-lines {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
#admin-group-panel-reports .stw-cmpt {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .stw-cmpt th {
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-tertiary);
  text-align: right;
  height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border-strong);
  padding: 0 var(--space-2);
}
#admin-group-panel-reports .stw-cmpt td {
  height: var(--touch-target-min);
  text-align: right;
  padding: 0 var(--space-2);
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
}
#admin-group-panel-reports .stw-cmpt td.l,
#admin-group-panel-reports .stw-cmpt th.l {
  text-align: left;
  font-weight: var(--font-weight-medium);
}
#admin-group-panel-reports .stw-cmpt td.selc {
  font-weight: var(--font-weight-bold);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
#admin-group-panel-reports .stw-cmpt td.diff {
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text);
}
#admin-group-panel-reports .stw-cnote {
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-daily {
  margin-top: var(--space-5);
}
#admin-group-panel-reports .stw-tblwrap {
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}
#admin-group-panel-reports .stw-daily table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--font-size-sm);
}
#admin-group-panel-reports .stw-daily th {
  font-size: var(--font-size-xs);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  text-align: right;
  padding: 0 var(--space-3);
  height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border-strong);
  white-space: nowrap;
  background: var(--color-surface);
}
#admin-group-panel-reports .stw-daily th.l,
#admin-group-panel-reports .stw-daily td.l {
  text-align: left;
}
#admin-group-panel-reports .stw-daily td {
  padding: 0 var(--space-3);
  height: var(--touch-target-min);
  text-align: right;
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#admin-group-panel-reports .stw-daily td.l {
  font-weight: var(--font-weight-medium);
}
#admin-group-panel-reports .stw-daily td.strong {
  font-weight: var(--font-weight-bold);
}
#admin-group-panel-reports .stw-daily td.neg {
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .stw-daily td.zero {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .stw-daily tr.hl td {
  background: var(--color-warning-subtle);
}
#admin-group-panel-reports .stw-daily tr.total td {
  border-top: 2px solid var(--color-border-strong);
  border-bottom: none;
  font-weight: var(--font-weight-bold);
  background: var(--color-surface-sunken);
}
#admin-group-panel-reports .stw-sticky {
  /* A fixed width, so a flag label under a date wraps instead of widening the column. */
  width: 11em;
  min-width: 11em;
  max-width: 11em;
  position: sticky;
  left: 0;
  background: var(--color-surface);
  z-index: 1;
  box-shadow: 1px 0 0 var(--color-border);
}
#admin-group-panel-reports .stw-daily tr.hl td.stw-sticky {
  background: var(--color-warning-subtle);
}
#admin-group-panel-reports .stw-daily tr.total td.stw-sticky {
  background: var(--color-surface-sunken);
}
#admin-group-panel-reports .stw-daily th.stw-sticky {
  z-index: 2;
}
#admin-group-panel-reports .stw-dlab {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
#admin-group-panel-reports .stw-dlab small {
  white-space: normal;
  font-size: var(--font-size-xs);
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .stw-foot {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: var(--space-4) 0 0;
}

/* ---------- R5, R6, R7: role management dialogs, the staged role editor and the Access tab ----------
   Ported from design/mockups/roles-r5-*.html, roles-r6-*.html and roles-r7-*.html (owner approved
   2026-10-07), built on the same tokens. Admin surface: every control is 44px or taller, nothing
   depends on hover. The role scrim switches between a centred dialog and a right-hand drawer with
   the two modifier classes below; the sheets inside it are siblings, one visible at a time. */
.scrim.rl-centered {
  align-items: center;
}
.scrim.rl-drawer {
  align-items: stretch;
  justify-content: flex-end;
}
.scrim.rl-drawer > #admin-role-edit-sheet {
  max-width: 680px;
  width: min(680px, 100%);
  max-height: none;
  height: 100%;
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
}
.sheet.rl-dlg {
  width: min(var(--rl-dw, 600px), calc(100% - var(--space-8)));
  max-width: none;
  max-height: calc(100% - var(--space-12));
  border-radius: var(--radius-xl);
}
.rl-dh {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) var(--space-3);
}
.rl-dh-text {
  flex: 1;
  min-width: 0;
}
.rl-ey {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-1);
}
.rl-title {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.rl-x {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  color: var(--color-text-primary);
}
.rl-db {
  flex: 1;
  overflow: auto;
  padding: 0 var(--space-5) var(--space-4);
  font-size: var(--font-size-base);
}
.rl-db p {
  margin: 0 0 var(--space-3);
}
.rl-df {
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: 1px solid var(--color-border);
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.rl-note {
  flex: 1;
  min-width: 200px;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: 0;
}
.rl-note b {
  color: var(--color-text-primary);
}
.rl-muted {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.rl-sec {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin: var(--space-4) 0 var(--space-2);
}
.rl-btn {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  white-space: nowrap;
}
.rl-btn.rl-small {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}
.rl-btn.rl-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.rl-btn.rl-danger {
  background: var(--color-danger-solid);
  border-color: var(--color-danger-solid);
  color: #fff;
}
.rl-btn:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
  cursor: default;
}
.rl-callout {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}
.rl-callout.rl-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.rl-callout.rl-bad {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}
.rl-callout.rl-good {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.rl-callout b {
  font-weight: var(--font-weight-bold);
}
.rl-field-label {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-1);
}
.rl-input {
  display: block;
  width: 100%;
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  padding: 0 var(--space-4);
  font: inherit;
  font-size: var(--font-size-md);
  box-sizing: border-box;
}
.rl-input.rl-err {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-subtle);
}
.rl-err-text {
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  margin-top: var(--space-2);
}
.rl-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.rl-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  gap: var(--space-2);
  cursor: pointer;
}
.rl-chip.rl-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.rl-chip:disabled,
.rl-chip.rl-dis {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
  border-style: dashed;
  cursor: default;
}
.rl-chip.rl-static {
  cursor: default;
}
.rl-av {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  flex: none;
}
.rl-av.rl-av-sm {
  width: 28px;
  height: 28px;
}
.rl-tag {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  white-space: nowrap;
}
.rl-tag.rl-role {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.rl-tag.rl-you {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.rl-tag.rl-good {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.rl-tag.rl-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.rl-tag.rl-bad {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}
.rl-opt-list {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: var(--space-3);
}
.rl-opt {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 60px;
  padding: 0 var(--space-4);
  border: 0;
  border-top: 1px solid var(--color-border);
  width: 100%;
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rl-opt:first-child {
  border-top: 0;
}
.rl-opt-text {
  flex: 1;
  min-width: 0;
}
.rl-opt-text small {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.rl-opt-text b {
  font-weight: var(--font-weight-semibold);
}
.rl-opt.rl-opt-danger .rl-opt-text b {
  color: var(--color-danger-strong);
}
.rl-opt-go {
  color: var(--color-text-tertiary);
}
.rl-person {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-3);
  border-top: 1px solid var(--color-border);
  padding: var(--space-3) 0;
}
.rl-person:first-child {
  border-top: 0;
}
.rl-who {
  flex: 1;
  min-width: 0;
  font-weight: var(--font-weight-medium);
}
.rl-who small {
  display: block;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-sm);
}
.rl-person-chips {
  width: 100%;
  padding-left: 48px;
  box-sizing: border-box;
}
.rl-chg {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
}
.rl-chg:first-child {
  border-top: 0;
}
.rl-sym {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-bold);
  flex: none;
  font-size: 16px;
}
.rl-sym.rl-up {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.rl-sym.rl-down {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.rl-sym.rl-mid {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.rl-tx {
  flex: 1;
  min-width: 0;
}
.rl-tx b {
  font-weight: var(--font-weight-semibold);
}
.rl-tx small {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.rl-savebar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-warning-subtle);
  flex-shrink: 0;
}
.rl-savebar-text {
  flex: 1;
  min-width: 180px;
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-strong);
}
.rl-was {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  margin-top: var(--space-1);
}
.rl-changed-row {
  background: var(--color-warning-subtle);
  border-radius: var(--radius-md);
}
.rl-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.rl-tile {
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
}
.rl-tile-n {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.rl-tile-k {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.rl-tile.rl-g {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.rl-tile.rl-a {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.rl-tile.rl-r {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.rl-excard {
  border: 1px solid var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
}
.rl-excard-top {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}
.rl-excard-top b {
  font-weight: var(--font-weight-bold);
  flex: 1;
  min-width: 140px;
}
.rl-arrow {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-3);
}
.rl-area {
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}
.rl-area:first-child {
  border-top: 0;
}
.rl-area-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  min-height: var(--touch-target-min);
}
.rl-area-head b {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
}
.rl-area-head .rl-more {
  margin-left: auto;
}
.rl-task-list {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-3);
  overflow: hidden;
}
.rl-task {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 52px;
  padding: 0 var(--space-4);
  width: 100%;
  border: 0;
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rl-task:first-child {
  border-top: 0;
}
.rl-task.rl-on {
  background: var(--color-accent-subtle);
  font-weight: var(--font-weight-semibold);
}
.rl-task-text {
  flex: 1;
  min-width: 0;
}
.rl-seg {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.rl-seg-opt {
  flex: 1;
  min-width: 104px;
  min-height: var(--touch-target-min);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.2;
  cursor: pointer;
}
.rl-seg-opt.rl-on.rl-allow {
  background: var(--color-success-subtle);
  border-color: var(--color-success);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-bold);
}
.rl-seg-opt.rl-on.rl-ask {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-bold);
}
.rl-seg-opt.rl-on.rl-deny {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold);
}
.rl-seg-opt.rl-roles-own {
  outline: 1px solid var(--color-text-tertiary);
  outline-offset: 2px;
}
.rl-seg-opt {
  flex-direction: column;
}
.rl-own-caption {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}
.rl-seg-opt:disabled {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
  border-style: dashed;
  cursor: default;
}
.rl-role-row-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.admin-role-row-tag {
  margin-left: var(--space-2);
}
@media (max-width: 900px) {
  .rl-tiles {
    grid-template-columns: 1fr;
  }
  .rl-person-chips {
    padding-left: 0;
  }
}

/* R6 (design review): a selected setting in the role editor keeps its value colour, as in
   roles-r6-1: green Allowed, orange Needs manager approval, neutral Not allowed. */
#admin-role-edit-permission-grid
  .admin-chip-option-input[data-value="allowed"]:checked
  ~ .admin-chip-option-label {
  background: var(--color-success-subtle);
  border-color: var(--color-success);
  color: var(--color-success-strong);
}
#admin-role-edit-permission-grid
  .admin-chip-option-input[data-value="approval_required"]:checked
  ~ .admin-chip-option-label {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning);
  color: var(--color-warning-strong);
}
#admin-role-edit-permission-grid
  .admin-chip-option-input[data-value="denied"]:checked
  ~ .admin-chip-option-label {
  background: var(--color-surface-sunken);
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
}

/* R5/R6/R7 (design review): section labels keep their space above (the dialog paragraph rule
   would otherwise squeeze it), and the person's selected role chip shows its check mark. */
.rl-db p.rl-sec {
  margin: var(--space-5) 0 var(--space-2);
}
.rl-db p.rl-sec:first-child {
  margin-top: 0;
}
.rl-err-text {
  margin-bottom: var(--space-3);
}
#admin-user-edit-roles .admin-chip-option-input:checked ~ .admin-chip-option-label::before {
  content: "\2713\00a0";
}
.rl-db .rl-chips + p {
  margin-top: var(--space-3);
}

/* PO7-S4-F4: the price reading of a matched line whose order unit holds more than one bottle.
   Two 44px choices and one sentence that says what the choice did. */
.review-reading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}
.review-reading-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.review-reading-option {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.review-reading-option.review-reading-current {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.review-reading-option:disabled {
  opacity: 0.55;
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
}
.review-reading-note {
  flex-basis: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.review-reading-note.review-reading-note-flagged {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
.review-confirmed-reading {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* PO7-S4-F3: the receive screen's cost caption stays on screen, and the "Recording ..." sentence
   has a full-width row of its own with its height held, so nothing moves as it fills in. */
.purchasing-receiving-line-cost-caption {
  display: flex;
  flex-direction: column;
  gap: var(--space-hairline);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.purchasing-receiving-line-both-readings {
  flex-basis: 100%;
  min-height: 1.5em;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ---------- SEC2-S3: tablet setup, picker line, Settings > Tablets ----------
   Built from design/mockups/sec2-s3-*.html and nothing but design/tokens.css and the active theme. Touch
   only: no hover rules, every target 44px or taller. The setup screen is drawn by ui/src/terminalSetup.ts,
   the Tablets panel by ui/src/tablets.ts. */

#terminal-setup-screen {
  padding: var(--space-5);
}
.setup-wrap {
  width: 100%;
  max-width: 1160px;
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: var(--space-6);
  align-items: stretch;
}
.setup-wrap.setup-solo {
  display: block;
  max-width: 640px;
}
.setup-card {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--color-border);
  padding: var(--space-6) var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.setup-brand {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
  margin: 0;
  line-height: var(--line-height-tight);
}
/* UX99 (DEC-357): the location name under the card's lockup. One line that wraps instead of overflowing. */
.brand-location {
  display: block;
  margin-top: var(--space-2);
  text-align: center;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.setup-lead {
  margin: 0;
  color: var(--color-text-secondary);
}
.setup-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.setup-code {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: var(--space-2) 0;
}
.setup-cell {
  flex: 1 1 0;
  min-width: 0;
  max-width: 60px;
  height: 72px;
  border-radius: var(--radius-md);
  border: 2px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.setup-cell.is-current {
  border-color: var(--color-accent-strong);
  background: var(--color-surface);
  box-shadow: var(--shadow-focus);
}
.setup-cell.is-bad {
  border-color: var(--color-danger);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.setup-cell.is-off {
  opacity: 0.55;
}
.setup-dash {
  width: 12px;
  height: 3px;
  border-radius: 2px;
  background: var(--color-text-tertiary);
  flex: none;
}
.setup-msg {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}
.setup-msg b {
  display: block;
  font-size: var(--font-size-base);
  margin-bottom: 2px;
}
.setup-msg .setup-ico {
  margin-top: 2px;
}
.setup-msg.setup-msg-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.setup-msg.setup-msg-info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
  color: var(--color-info);
}
.setup-ico {
  width: 20px;
  height: 20px;
  flex: none;
}
.setup-connect {
  width: 100%;
  min-height: var(--touch-target-primary);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
}
.setup-connect:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
  border: 1px solid var(--color-border);
  cursor: default;
}
.setup-secondary {
  flex: none;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  white-space: nowrap;
  cursor: pointer;
}
.setup-secondary:disabled {
  opacity: 0.45;
  cursor: default;
}
.setup-secondary.setup-secondary-strong {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.setup-server {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.setup-server-text b {
  display: block;
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.setup-server-edit {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.setup-server-edit .field-label {
  margin-top: 0;
}
.setup-server-edit-actions {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
}
.setup-pad {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-xl);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.setup-keys {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: var(--space-2);
}
.setup-key {
  height: 76px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
  padding: 0;
}
.setup-pad.is-off .setup-key,
.setup-pad.is-off .setup-pad-button {
  opacity: 0.45;
  box-shadow: none;
}
.setup-pad-foot {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.setup-pad-button {
  min-height: var(--touch-target-comfortable);
  font-size: var(--font-size-base);
}
.setup-hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  text-align: center;
  margin: 0;
}
.setup-big-ok {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-success-subtle);
  border: 2px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
  display: flex;
  align-items: center;
  justify-content: center;
}
.setup-ico.setup-ico-big {
  width: 36px;
  height: 36px;
}
.setup-facts {
  margin: var(--space-2) 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3) var(--space-5);
  align-items: baseline;
}
.setup-facts dt {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.setup-facts dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-md);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
@media (max-width: 900px) {
  .setup-wrap {
    grid-template-columns: 1fr;
    max-width: 720px;
  }
  .setup-card {
    padding: var(--space-6);
  }
  .setup-key {
    height: 68px;
  }
}

.user-picker-card .login-title,
.user-picker-card .login-subtitle {
  text-align: center;
}
/* One flow: the icon sits inline at the start of the sentence and the whole line is centred together. */
.user-picker-device-line .setup-ico {
  display: inline-block;
  vertical-align: -4px;
  margin-right: var(--space-2);
}
.user-picker-device-line {
  margin: 0;
  padding-top: var(--user-picker-gap, var(--space-4));
  line-height: var(--line-height-tight);
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  text-align: center;
  text-wrap: balance;
}
.user-picker-device-line b {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}

/* Settings > Tablets */
.tablets-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  border: 1px solid var(--color-border);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.tablets-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}
.tablets-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}
.tablets-help {
  margin: var(--space-1) 0 var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.tablets-primary {
  white-space: nowrap;
  flex: none;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
  box-shadow: var(--shadow-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
}
.tablets-primary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  box-shadow: none;
  border: 1px solid var(--color-border);
  cursor: default;
}
.tablets-secondary {
  flex: none;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
}
.tablets-secondary.tablets-sheet-button {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  font-size: var(--font-size-base);
}
.tablets-danger {
  flex: none;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-danger-fill);
  color: var(--color-text-on-dark);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.tablets-danger-quiet {
  flex: none;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
}
.tablets-more {
  width: 100%;
  margin-top: var(--space-2);
  background: var(--color-surface-sunken);
}
.tablets-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 72px;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
}
.tablets-row:first-of-type {
  border-top: 0;
}
.tablets-row-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.tablets-row-icon .setup-ico {
  width: 26px;
  height: 26px;
}
.tablets-row-text {
  flex: 1;
  min-width: 0;
}
.tablets-row-name {
  font-weight: var(--font-weight-semibold);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  overflow-wrap: anywhere;
}
.tablets-row-line {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.tablets-row-actions {
  display: flex;
  gap: var(--space-2);
  flex: none;
}
.tablets-row.is-revoked .tablets-row-name,
.tablets-row.is-revoked .tablets-row-line {
  color: var(--color-text-tertiary);
}
.tablets-tag {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.tablets-tag.is-good {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.tablets-tag.is-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.tablets-count {
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-bold);
}
.tablets-count.is-low {
  color: var(--color-warning-text);
}
.tablets-meter {
  display: flex;
  align-items: center;
  gap: 6px;
}
.tablets-pip {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-border-strong);
}
.tablets-pip.is-on {
  background: var(--color-accent-strong);
}
.tablets-meter.is-full .tablets-pip.is-on {
  background: var(--color-warning);
}
.tablets-empty {
  margin: 0;
  padding: var(--space-4) 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.tablets-status {
  margin: 0 0 var(--space-4);
}

.tablets-scrim {
  position: fixed;
  inset: 0;
  background: var(--color-scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  z-index: var(--z-scrim);
}
.tablets-sheet {
  width: 100%;
  max-width: 680px;
  max-height: calc(100vh - 2 * var(--space-5));
  overflow-y: auto;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  z-index: var(--z-sheet);
}
.tablets-sheet h2 {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
  line-height: var(--line-height-tight);
}
.tablets-sheet .tablets-help {
  margin: calc(-1 * var(--space-2)) 0 0;
}
.tablets-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-2);
}
.tablets-seg {
  display: flex;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: 4px;
  gap: 4px;
}
.tablets-seg button {
  flex: 1;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 0;
  background: transparent;
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
  text-align: center;
  line-height: var(--line-height-tight);
  cursor: pointer;
}
.tablets-seg button[aria-pressed="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.tablets-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.tablets-chip {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}
.tablets-chip[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
  box-shadow: inset 0 0 0 1px var(--color-accent-strong);
}
.tablets-chip.is-locked {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  cursor: default;
}
.tablets-sheet-foot {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  flex-wrap: wrap;
}
.tablets-codebox {
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
  padding: var(--space-5);
  text-align: center;
}
.tablets-bigcode {
  font-size: 3.25rem;
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  white-space: nowrap;
  margin: 0;
}
.tablets-timerline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--font-size-md);
}
.tablets-timerline .tablets-count {
  font-size: var(--font-size-xl);
}
.tablets-bar {
  height: 8px;
  border-radius: 4px;
  background: var(--color-border);
  margin-top: var(--space-3);
  overflow: hidden;
}
.tablets-bar i {
  display: block;
  height: 100%;
  background: var(--color-success);
  border-radius: 4px;
}
.tablets-bar.is-low i {
  background: var(--color-warning);
}
.tablets-binds {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0;
}
.tablets-binds dt {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.tablets-binds dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
@media (max-width: 900px) {
  .tablets-card-head {
    flex-wrap: wrap;
  }
  .tablets-row {
    flex-wrap: wrap;
  }
  .tablets-row-text {
    flex-basis: calc(100% - 64px);
  }
  .tablets-row-actions {
    margin-left: 60px;
  }
  .tablets-bigcode {
    font-size: 2.5rem;
  }
}
.tablets-note {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.setup-msg b.setup-wait {
  display: inline;
  margin: 0;
  font-size: inherit;
  font-variant-numeric: tabular-nums;
}
.tablets-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.tablets-field > .tablets-label {
  margin: 0;
}
.tablets-field > .tablets-help {
  margin: 0;
}
/* UX130: the Locations Add form spaces its labelled fields as the Location address form does (field-label margins). */
.tablets-location-form .tablets-field {
  gap: 0;
}
@media (max-width: 900px) {
  /* Portrait: "Add a tablet" wraps under the help text; keep it clear of the first row divider. */
  .tablets-card-head .tablets-primary {
    margin-bottom: var(--space-3);
  }
}

/* UX84 (DEC-336): the Paste code button under the setup code boxes. Built from .setup-secondary; only its row is new. */
.setup-paste-row {
  display: flex;
  justify-content: flex-start;
  margin-top: calc(var(--space-2) * -1);
}

/* UX89: the Name this device step. Built from .setup-card, .setup-connect and .setup-secondary; only the suggestion
   row and the full width continue button are new. Every target is 44px or taller. */
.setup-name-help {
  text-align: left;
}
.setup-name-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.setup-name-suggestions .setup-secondary {
  min-height: var(--touch-target-min);
}
.setup-name-continue {
  width: 100%;
  min-height: var(--touch-target-min);
}

/* TEN14 (docs/build-briefs/TEN14-franchisor-accounts-signin.md): the "Franchisor sign-in accounts" card on a franchisor
   customer's detail in the software owner console, and the franchisor page's signed-in shell. Built from the existing
   so- classes and tokens; only the account list layout and the shell's width are new. */
.so-fa-list {
  list-style: none;
  margin: var(--space-3) 0;
  padding: 0;
}

.so-fa-item {
  /* One column: the detail's left column is narrow, so the buttons sit under the person, not beside them. */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.so-fa-item:last-child {
  border-bottom: 0;
}

.so-fa-who {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  overflow-wrap: anywhere;
}

.so-fa-email {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.so-fa-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* UX97 (docs/build-briefs/UX97-console-enrolment-result-sheet.md): the franchisor invite hand-over sheet in the
   software owner console, built at runtime by softwareOwnerInviteSheet.ts on the shared .scrim and .sheet and
   shaped like the franchisor console's created-link panel (.fr-team-*). Every value wraps inside its own box. */
.so-invite-scrim {
  align-items: center;
}
.so-invite-sheet {
  width: min(520px, 100% - var(--space-6));
  max-height: 96vh;
  border-radius: var(--radius-xl);
}
.so-invite-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.so-invite-title {
  margin: 0;
  min-width: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.so-invite-flag {
  flex-shrink: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.so-invite-body {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.so-invite-kv {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  margin: 0;
  font-size: var(--font-size-sm);
}
.so-invite-kv dt {
  color: var(--color-text-secondary);
}
.so-invite-kv dd {
  margin: 0;
  min-width: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.so-invite-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.so-invite-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.so-invite-box {
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--font-size-xs);
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.so-invite-code {
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  user-select: all;
}
.so-invite-wide {
  width: 100%;
}
.so-invite-row {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  min-width: 0;
}
.so-invite-row .so-invite-box {
  flex: 1;
}
.so-invite-small {
  flex-shrink: 0;
  width: auto;
}
.so-invite-expires {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.so-invite-foot {
  padding: var(--space-3) var(--space-5) var(--space-4);
  border-top: 1px solid var(--color-border);
  flex-shrink: 0;
}

.so-fa-reason {
  grid-column: 1 / -1;
  padding: var(--space-4);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}

.so-fa-reason .btn-secondary,
.so-fa-reason .btn-danger {
  width: auto;
  margin: var(--space-3) var(--space-2) 0 0;
}

.so-fa-form {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.so-card.so-franchisor-shell {
  max-width: 960px;
}

/* ---------- TEN15 (docs/build-briefs/TEN15-franchisor-console-shell-and-franchise-list.md): franchisor console ----------
   ui/franchisor.html, signed in. Built from design/mockups/ux70-franchisor-console.html (side navigation, content
   column, card, data table) on the existing tokens and the topbar and badge classes of the TEN9 page. A desktop
   surface; targets stay at the comfortable touch size. */
.fr-shell {
  max-width: 1320px;
  margin: 0 auto;
  padding: var(--space-5);
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
}

.fr-nav {
  flex: 0 0 240px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  position: sticky;
  top: var(--space-5);
}

.fr-nav-item {
  appearance: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: left;
  border: 1px solid transparent;
  background: none;
  border-radius: var(--radius-md);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  cursor: pointer;
}

.fr-nav-item[aria-current="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}

.fr-nav-item:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}

.fr-content {
  flex: 1;
  min-width: 0;
}

.fr-page-title {
  margin: 0 0 var(--space-1);
}

.fr-content .so-subtitle,
.fr-content .so-limits {
  margin: 0 0 var(--space-1);
}

.fr-card {
  margin-top: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
}

.fr-card-title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-4);
}

.fr-card-help {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: var(--space-4) 0 0;
}

.fr-table {
  width: 100%;
  border-collapse: collapse;
}

.fr-table th {
  text-align: left;
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border-strong);
}

.fr-table td,
.fr-table tbody th {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  vertical-align: middle;
  overflow-wrap: anywhere;
}

.fr-table tbody th {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--font-size-sm);
}

.fr-table tr:last-child td,
.fr-table tr:last-child th {
  border-bottom: none;
}

.fr-empty-title {
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-1);
}

.fr-retry {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}

/* ---------- TEN17 (docs/build-briefs/TEN17-brand-settings-and-theme.md): franchisor console, Brand section ----------
   The choices (fonts and base as radios, a color input) and the live preview. The preview sets the brand's custom
   properties on its own element, so everything inside it uses the draft's colors and fonts through the ordinary
   tokens, and the Prepared and Not Prepared chips use the FIXED state tokens, which a brand never changes. Colors
   and fonts only: sizes, spacing and layout here are the console's own. */
.fr-brand-layout {
  margin-top: var(--space-4);
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
  flex-wrap: wrap;
}

.fr-brand-form {
  flex: 1 1 340px;
  min-width: 300px;
  max-width: 460px;
  display: grid;
  gap: var(--space-3);
}

.fr-brand-fieldset {
  border: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.fr-brand-fieldset .field-label {
  margin-top: 0;
  padding: 0;
}

.fr-brand-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.fr-brand-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  cursor: pointer;
}

.fr-brand-choice:has(input:checked) {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}

.fr-brand-choice:has(input:focus-visible) {
  box-shadow: var(--shadow-focus);
}

.fr-brand-choice:has(input:disabled) {
  cursor: default;
}

.fr-brand-choice input {
  width: var(--space-5);
  height: var(--space-5);
  margin: 0;
  accent-color: var(--color-accent-strong);
}

.fr-brand-color-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.fr-brand-color {
  width: var(--touch-target-comfortable);
  height: var(--touch-target-comfortable);
  padding: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  cursor: pointer;
}

.fr-brand-color:disabled {
  cursor: default;
}

.fr-brand-hex {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  letter-spacing: 0.04em;
}

.fr-brand-preview {
  flex: 1 1 320px;
  min-width: 300px;
  max-width: 440px;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.fr-brand-preview-title {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}

.fr-brand-ticket {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.fr-brand-ticket-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.fr-brand-ticket-title {
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.fr-brand-ticket-tab {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.fr-brand-lines {
  list-style: none;
  margin: 0;
  padding: 0;
}

.fr-brand-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-md);
  color: var(--color-text-primary);
}

.fr-brand-line-name {
  flex: 1;
  min-width: 0;
}

.fr-brand-line-price {
  font-family: var(--font-family-numeric);
  color: var(--color-text-secondary);
}

.fr-brand-chip {
  border-radius: var(--radius-full);
  padding: 2px var(--space-3);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.fr-brand-chip-prepared {
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
}

.fr-brand-chip-not-prepared {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}

.fr-brand-total {
  display: flex;
  justify-content: space-between;
  padding: var(--space-3) 0;
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.fr-brand-actions {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
}

.fr-brand-fake {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--space-5);
  cursor: default;
  user-select: none;
}

.fr-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

/* ---------- TEN18 (docs/build-briefs/TEN18-publish-discounts-adopt-by-receipt.md): franchisor console, Publishing ----------
   Each published discount is a bordered block: name, terms in words and status on one line, then the franchisees'
   answers (the .fr-table and badge classes above). The Publish a discount sheet is built at runtime
   (src/franchisorPublishSheet.ts) from the shared .scrim/.sheet classes and centered on this desktop page. */
.fr-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.fr-card-head .fr-card-title {
  margin: 0;
}
.fr-publishing-new {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
}
.fr-pub-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.fr-pub {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--color-surface);
}
.fr-pub-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}
.fr-pub-name {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.fr-pub-terms {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
}
.fr-pub-meta {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.fr-pub-side {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}
.fr-pub-withdraw {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  white-space: nowrap;
}
.fr-share-decide {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
  max-width: 28rem;
}
.fr-share-note-label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.fr-share-decide-buttons {
  display: flex;
  gap: var(--space-3);
}
.fr-pub-answers {
  margin-top: var(--space-3);
}
.fr-pub-answers > summary {
  cursor: pointer;
  min-height: var(--touch-target-min);
  display: flex;
  align-items: center;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.fr-publish-scrim {
  align-items: center;
}
.fr-publish-sheet {
  border-radius: var(--radius-xl);
  max-width: 560px;
}
.fr-publish-body {
  padding: var(--space-4) var(--space-5);
  max-height: calc(100vh - 220px);
  overflow-y: auto;
}
.fr-publish-picker {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-height: 260px;
  overflow-y: auto;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-publish-locations {
  margin-top: var(--space-3);
}
.fr-publish-all {
  margin-bottom: var(--space-2);
  font-weight: var(--font-weight-semibold);
}
.fr-publish-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.fr-publish-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.fr-publish-group-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  overflow-wrap: anywhere;
}
.fr-publish-group-all {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.fr-publish-pick {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  padding-left: var(--space-4);
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}
.fr-publish-pick input {
  flex-shrink: 0;
  margin-top: var(--space-1);
}
.fr-publish-confirm {
  margin: 0;
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
  color: var(--color-text-primary);
}
.fr-publish-error {
  margin: 0;
  padding: var(--space-2) var(--space-5) 0;
}

/* ---------- TEN18 (docs/build-briefs/TEN18-publish-discounts-adopt-by-receipt.md): Settings > Discounts, From <network> ----------
   The offers area above the discount list and the read-only row for an adopted copy. They reuse the Settings
   discount list's tokens, the section title and the badge classes; nothing here sets a color of its own. */
.admin-network-offers {
  margin: 0 0 var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.admin-network-offer-list {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-network-offer {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}
.admin-network-offer:last-child {
  border-bottom: none;
}
.admin-network-offer-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.admin-network-offer-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-network-offer-terms {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-network-offer-actions {
  display: flex;
  gap: var(--space-2);
  flex-shrink: 0;
}
.admin-discount-row-network {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.admin-network-copy-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.admin-network-copy-terms {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.admin-network-copy-note {
  flex-basis: 100%;
  margin: 0;
}
/* TEN21-F2 (owner, 2026-10-09): a mistake in a required field must catch the eye. An invalid field gets the
   danger border (--color-danger on the sunken field fill and the card both clear 3:1), the message under it is
   the danger text, and the top line of the form counts what needs fixing. */
#software-owner-onboard-form [aria-invalid="true"],
#software-owner-profile-form [aria-invalid="true"],
#software-owner-rename-form [aria-invalid="true"] {
  border: 2px solid var(--color-danger);
}

#software-owner-onboard-form .so-error-summary:not(:empty),
#software-owner-profile-form .admin-error:not(:empty)#software-owner-profile-form-error {
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold, 700);
}

#software-owner-onboard-form .so-error-summary:empty {
  display: none;
}

/* TEN21-F2: a field's message is always the danger text, whatever label or grid rule it sits inside. */
#software-owner-onboard-form .admin-field .admin-error:not(:empty),
#software-owner-profile-form .admin-field .admin-error:not(:empty),
#software-owner-rename-form .admin-error:not(:empty) {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-medium);
}

/* DSC37-F1 (owner directive TEN21-F2, 2026-10-09: a missed or refused field needs to stand out in bright red).
   A refused Settings discount save reuses the TEN21-F2 look: the control the save started from gets the 2px danger
   border (an outline on a checkbox), and the server's sentence is a bold danger-bordered block, inside the
   discount's row or inside the Add Discount popout. */
.admin-discount-row [aria-invalid="true"],
.admin-discount-add-sheet [aria-invalid="true"] {
  border: 2px solid var(--color-danger);
}
.admin-discount-row input[type="checkbox"][aria-invalid="true"],
.admin-discount-add-sheet input[type="checkbox"][aria-invalid="true"] {
  border: 0;
  outline: 3px solid var(--color-danger);
  outline-offset: 2px;
}
.admin-discount-field-error,
.admin-discount-add-sheet .admin-discount-add-error:not(:empty) {
  flex-basis: 100%;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold, 700);
  white-space: normal;
}
.admin-discount-add-sheet .admin-discount-add-error:not(:empty) {
  margin: var(--space-2) var(--space-5) 0;
}

/* PAY1 Slice 3 (docs/build-briefs/PAY1-S3-standup-onboarding.md; design/mockups/pay1-s3-console-card-payments.html).
   The software owner console's Card payments card and its sheets. Labels and states only. */
.so-cp-card {
  margin-bottom: var(--space-5);
  max-width: none;
}

.so-cp-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.so-cp-head .so-detail-title {
  flex: 1;
  margin: 0;
}

/* ONB2 S1: the "Ready to go live" list on a customer's detail. One row per requirement: state, label, detail, fix. */
.so-golive-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-golive-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.so-golive-state {
  min-width: 64px;
  justify-content: center;
}

.so-golive-state-done {
  color: var(--color-success-strong);
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
}

.so-golive-state-todo {
  color: var(--color-warning-strong);
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
}

.so-golive-state-na,
.so-golive-state-unknown {
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
  border-color: var(--color-border-strong);
}

.so-golive-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 180px;
}

.so-golive-label {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

.so-golive-detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.so-cp-locations {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-cp-location {
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  padding: var(--space-4);
}

.so-cp-location-good {
  border-left-color: var(--color-success-strong);
}

.so-cp-location-warn {
  border-left-color: var(--color-warning-strong);
}

.so-cp-location-bad {
  border-left-color: var(--color-danger-strong);
}

.so-cp-location-neutral {
  border-left-color: var(--color-border-strong);
}

.so-cp-location-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}

.so-cp-location-titles {
  min-width: 0;
}

.so-cp-location-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}

.so-cp-location-account {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.so-cp-fact {
  margin-top: var(--space-2);
  overflow-wrap: anywhere;
}

.so-cp-code,
.so-cp-checked {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}

.so-cp-section {
  margin-top: var(--space-4);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}

.so-cp-needs {
  list-style: none;
  margin: var(--space-1) 0 0;
  padding: 0;
}

.so-cp-need {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}

.so-cp-need:first-child {
  border-top: 0;
}

.so-cp-need-mark {
  min-width: 56px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.so-cp-need-pending .so-cp-need-mark {
  color: var(--color-warning-text);
}

.so-cp-need-done .so-cp-need-mark {
  color: var(--color-success-text);
}

.so-cp-actions {
  margin-top: var(--space-3);
}

dialog.so-cp-dialog {
  width: 560px;
  max-width: calc(100vw - 32px);
  padding: 0;
  border: 0;
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-3);
}

dialog.so-cp-dialog::backdrop {
  background: var(--color-scrim);
}

.so-cp-dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.so-cp-dialog-title {
  margin: 0;
  font-size: var(--font-size-lg);
  overflow-wrap: anywhere;
}

.so-cp-close {
  flex: none;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  color: var(--color-text-secondary);
  font-size: var(--font-size-xl);
  cursor: pointer;
}

#software-owner-cp-dialog-body {
  padding: var(--space-4) var(--space-5);
}

dialog.so-cp-dialog .admin-error {
  margin: 0 var(--space-5) var(--space-3);
}

.so-cp-dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-bg);
}

.so-cp-label {
  display: block;
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.so-cp-picks {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.so-cp-pick {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 64px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
}

.so-cp-pick:has(input:checked) {
  border-color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
}

.so-cp-pick-off {
  opacity: 0.6;
  cursor: default;
}

.so-cp-pick-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.so-cp-pick-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}

.so-cp-pick-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}

.so-cp-summary {
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.so-cp-summary-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}

.so-cp-summary-row:first-child {
  border-top: 0;
}

.so-cp-summary-row dt {
  color: var(--color-text-secondary);
}

.so-cp-summary-row dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  text-align: right;
  overflow-wrap: anywhere;
}

.so-cp-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-cp-field .field-input {
  width: 100%;
}

.so-cp-attest {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
}

.so-cp-attest input {
  width: 24px;
  height: 24px;
  flex: none;
}

/* BANK1 (docs/build-briefs/BANK1-bank-accounts-in-app.md). Settings > Tabs and payment > Bank accounts: one card, three rows. */
.ba-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.ba-row {
  padding: var(--space-4);
  border-left: 4px solid var(--color-border-strong);
}

.ba-row + .ba-row {
  border-top: 1px solid var(--color-border);
}

.ba-row-good {
  border-left-color: var(--color-success-strong);
}

.ba-row-warn {
  border-left-color: var(--color-warning-strong);
}

.ba-row-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--touch-target-min);
}

.ba-row-main {
  min-width: 0;
}

.ba-row-title {
  font-weight: var(--font-weight-semibold);
}

.ba-row-caption,
.ba-row-detail {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.ba-row-side {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.ba-chip {
  white-space: nowrap;
}

.ba-row-side .btn-compact {
  min-height: var(--touch-target-min);
}

.ba-confirm {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.ba-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.ba-confirm-actions .btn-compact {
  min-height: var(--touch-target-min);
}

/* PAY1 Slice 3 (design/mockups/pay1-s3-settings-card-payments.html). Settings > Tabs and payment > Card payments. */
.cp-section {
  margin-bottom: var(--space-6);
}

.cp-status-line {
  margin: 0 0 var(--space-3);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.cp-location {
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  padding: var(--space-4);
}

.cp-location-good {
  border-left-color: var(--color-success-strong);
}

.cp-location-warn {
  border-left-color: var(--color-warning-strong);
}

.cp-location-bad {
  border-left-color: var(--color-danger-strong);
}

.cp-location-neutral {
  border-left-color: var(--color-border-strong);
}

.cp-location-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}

.cp-location-titles {
  min-width: 0;
}

.cp-location-name-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.cp-location-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}

.cp-tag {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  white-space: nowrap;
}

.cp-location-account {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.cp-fact {
  margin-top: var(--space-2);
  overflow-wrap: anywhere;
}

.cp-heading {
  margin-top: var(--space-4);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}

.cp-needs {
  list-style: none;
  margin: var(--space-1) 0 0;
  padding: 0;
}

.cp-need {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}

.cp-need:first-child {
  border-top: 0;
}

.cp-need-mark {
  min-width: 56px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.cp-need-pending .cp-need-mark {
  color: var(--color-warning-text);
}

.cp-need-done .cp-need-mark {
  color: var(--color-success-text);
}

.cp-actions {
  margin-top: var(--space-4);
}

.cp-error {
  margin: var(--space-3) 0 0;
}

.cp-others {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}

.cp-other {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}

.cp-other:first-child {
  border-top: 0;
}

.cp-other-name {
  overflow-wrap: anywhere;
}

.so-cp-card .so-help:empty,
.so-cp-card .admin-error:empty,
dialog.so-cp-dialog .admin-error:empty,
.cp-section .cp-status-line:empty {
  display: none;
}

.cp-location-head-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* The Done and Needed marks read on any theme: bold secondary text, with Needed in the primary text colour. */
.so-cp-need-mark,
.cp-need-mark {
  color: var(--color-text-secondary);
}

.so-cp-need-pending .so-cp-need-mark,
.cp-need-pending .cp-need-mark {
  color: var(--color-text-primary);
}

/* TEN16-F2 (docs/build-briefs/TEN16-F2-owner-reads-royalty.md): the read-only Royalty card on a franchisee's detail in
   the software owner console. The detail's left column is narrow, so the history is a list, one entry per rate. */
.so-royalty-rows {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  margin: 0 0 var(--space-4);
}

.so-royalty-rows dt {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}

.so-royalty-rows dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.so-royalty-subtitle {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}

.so-royalty-na {
  margin: 0 0 var(--space-3);
}

.so-royalty-history {
  list-style: none;
  margin: 0;
  padding: 0;
}

.so-royalty-history li {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  overflow-wrap: anywhere;
}

.so-royalty-history li:last-child {
  border-bottom: 0;
}

.so-royalty-history-meta {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

#software-owner-royalty-card[hidden],
#software-owner-royalty-body[hidden],
.so-royalty-na[hidden] {
  display: none;
}

/* ---------- TEN14-F3 (docs/build-briefs/TEN14-F3-franchisor-team-screen.md; DEC-349): franchisor console, Team ----------
   Ported from the designer's artboard design/mockups/ten14-f3-franchisor-team.html onto this file's tokens. The team
   list is the console's .fr-table; the side sheet (Invite, link, confirmation, Change role) is built at runtime by
   src/franchisorTeamSheet.ts from the shared .scrim/.sheet classes and docked right. Row actions are visible buttons
   (nothing depends on hover), every control is at least the minimum touch target, long emails wrap. Errors are the
   artboard's: a pale red chip under the field, a 2px red border on the field (a brighter red on Ink, where the
   token's dark red would be near-invisible), and a red count box on top. */
.fr-team-invite {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
}
.fr-team-small {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: auto;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.fr-team-table {
  table-layout: fixed;
}
.fr-team-table th:nth-child(1) {
  width: 30%;
}
.fr-team-table th:nth-child(2) {
  width: 15%;
}
.fr-team-table th:nth-child(3) {
  width: 11%;
}
.fr-team-table th:nth-child(4) {
  width: 15%;
}
.fr-team-table th:nth-child(5) {
  width: 29%;
}
.fr-team-table th,
.fr-team-table td {
  white-space: nowrap;
  overflow-wrap: normal;
}
.fr-team-table tbody th {
  white-space: normal;
  overflow-wrap: anywhere;
}
.fr-team-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-semibold);
}
.fr-team-email {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  overflow-wrap: anywhere;
}
.fr-team-sub {
  margin-top: 2px;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
}
.fr-team-you {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  padding: 1px 8px;
}
.fr-team-na,
.fr-team-empty {
  color: var(--color-text-tertiary);
}
.fr-team-empty {
  margin: 0;
  padding: var(--space-5) var(--space-3);
  font-size: var(--font-size-md);
}
.fr-team-table td.fr-team-actions {
  text-align: right;
  white-space: normal;
}
.fr-team-actions .fr-team-small {
  margin: 2px 0 2px var(--space-2);
}
/* UIFIX3: one Actions menu per Team row; the cell never wraps or clips. */
.fr-team-table td.fr-team-actions {
  white-space: nowrap;
}
.fr-team-row-flash > * {
  background: var(--color-accent-subtle);
}

.fr-team-scrim {
  align-items: stretch;
  justify-content: flex-end;
  --fr-err-border: var(--color-danger);
}
[data-theme="snipsip-ink"] .fr-team-scrim {
  --fr-err-border: #ff6a5c;
}
.fr-team-sheet {
  width: min(520px, 100%);
  max-width: none;
  max-height: none;
  height: 100%;
  border-radius: 0;
  border-left: 1px solid var(--color-border-strong);
}
.fr-team-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.fr-team-sheet-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.fr-team-sheet-title:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.fr-team-sheet-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.fr-team-sheet-body > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.fr-team-sheet-body > div[hidden] {
  display: none;
}
.fr-team-sheet-foot {
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  flex-shrink: 0;
}
.fr-team-foot-set {
  display: flex;
  gap: var(--space-3);
}
.fr-team-foot-set > button {
  flex: 1;
  width: auto;
}
.fr-team-field {
  min-width: 0;
}
.fr-team-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.fr-team-flag {
  margin-left: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.fr-team-sheet .field-input[aria-invalid="true"] {
  border: 2px solid var(--fr-err-border);
}
.fr-team-error {
  margin: var(--space-2) 0 0;
  padding: 6px var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  border: 1px solid var(--color-danger-subtle-border);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
}
.fr-team-page-error {
  margin: 0 0 var(--space-4);
}
.fr-team-error-general {
  margin: 0;
}
.fr-team-summary {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--fr-err-border);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-bold);
}
.fr-team-roles {
  display: grid;
  gap: var(--space-3);
  border-radius: var(--radius-md);
}
.fr-team-roles[aria-invalid="true"] .fr-team-role-opt {
  border: 2px solid var(--fr-err-border);
}
.fr-team-role-opt {
  appearance: none;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 72px;
  padding: var(--space-3) var(--space-4);
  text-align: left;
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font: inherit;
  cursor: pointer;
}
.fr-team-role-opt:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.fr-team-role-dot {
  flex: 0 0 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--color-border-strong);
}
.fr-team-role-opt[aria-checked="true"] {
  border: 2px solid var(--color-accent-strong);
  background: var(--color-accent-subtle);
}
.fr-team-role-opt[aria-checked="true"] .fr-team-role-dot {
  border-color: var(--color-accent-strong);
  background: radial-gradient(circle, var(--color-accent-strong) 0 45%, transparent 50%);
}
.fr-team-role-opt b {
  display: block;
  font-weight: var(--font-weight-bold);
}
.fr-team-role-opt small {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.fr-team-role-opt[aria-checked="true"] small {
  color: var(--color-text-primary);
}
.fr-team-kv {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  font-size: var(--font-size-sm);
}
.fr-team-kv dt {
  color: var(--color-text-tertiary);
}
.fr-team-kv dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.fr-team-linkbox {
  padding: var(--space-4);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--font-size-sm);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.fr-team-copy {
  width: 100%;
}

@media (max-width: 1000px) {
  .fr-team-table {
    table-layout: auto;
  }
  .fr-team-table thead {
    display: none;
  }
  .fr-team-table tr {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
  }
  .fr-team-table tbody th,
  .fr-team-table td {
    border-bottom: none;
    padding: 0 var(--space-3);
  }
  .fr-team-table td[data-label]::before {
    content: attr(data-label) " ";
    color: var(--color-text-tertiary);
    font-size: var(--font-size-xs);
    margin-right: 6px;
  }
  .fr-team-table td.fr-team-actions {
    grid-column: 1 / -1;
    text-align: left;
  }
}

/* ---------- TEN19 (docs/build-briefs/TEN19-publish-recipes.md): publishing a recipe, and the location's Map ingredients step ----------
   They reuse the console's sheet, the Settings offers area, the badge classes and the form field classes; nothing here
   sets a color of its own. */
.fr-publish-kind {
  margin-bottom: var(--space-3);
}
.fr-publish-slots {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.fr-publish-slot {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  align-items: center;
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.fr-publish-slot > :nth-child(1),
.fr-publish-slot > :nth-child(2) {
  grid-column: span 2;
}
.fr-publish-slot-input {
  min-width: 0;
}
.admin-network-recipe-offer {
  flex-wrap: wrap;
}
.admin-network-recipe-map {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) 0 0;
}
.admin-network-recipe-map-row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 2fr);
  gap: var(--space-3);
  align-items: center;
}
.admin-network-recipe-map-slot {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.admin-network-recipe-map-price {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: center;
}
.admin-network-recipe-map-actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* REC7-S1: the franchisee's "Publish to my locations" form, inline in Settings > Recipes. Admin desktop surface. */
.admin-own-recipe-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3) 0;
}
.admin-own-recipe-slots {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.admin-own-recipe-slot {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  align-items: center;
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.admin-own-recipe-slot > :nth-child(1),
.admin-own-recipe-slot > :nth-child(2) {
  grid-column: span 2;
}
.admin-own-recipe-slot-input {
  min-width: 0;
}
.admin-own-recipe-locations {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.admin-own-recipe-actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* ---------- TEN14-F7 (docs/build-briefs/TEN14-F7-adoption-report.md): franchisor console, Reports > Adoption ----------
   Each report block reuses .fr-pub and .fr-table; only the two pickers, the download button and the wrapping totals row
   are new. Desktop admin surface, so a keyboard and pointer are assumed. */
.fr-reports-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.fr-reports-filter {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 14rem;
}
.fr-reports-download {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  white-space: nowrap;
}
.fr-report-totals {
  flex-wrap: wrap;
  justify-content: flex-end;
}
.fr-report-table {
  margin-top: var(--space-3);
  width: 100%;
  table-layout: fixed;
}
.fr-report-table th:nth-child(1) {
  width: 32%;
}
.fr-report-table th:nth-child(2) {
  width: 34%;
}
.fr-report-table th:nth-child(3) {
  width: 17%;
}
.fr-report-table th:nth-child(4) {
  width: 17%;
}
.fr-report-table td:nth-child(4) {
  white-space: nowrap;
}

/* ---------- TEN13-F5 (docs/build-briefs/TEN13-F5-franchisor-adds-franchisees.md): Franchisees card and sheet ----------
   The card is a .so-detail-card; its Add franchisees sheet is built at runtime (src/softwareOwnerFranchiseesSheet.ts)
   from the shared .scrim/.sheet classes and centered on this desktop page. Checkbox rows are 44px touch targets. */
.so-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.so-card-head .so-detail-title {
  margin: 0;
}
.so-frs-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.so-frs-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}
.so-frs-row-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--font-weight-medium);
}
.so-frs-none,
.so-onboard-franchisees-none {
  margin: 0;
  color: var(--color-text-secondary);
}
.so-frs-scrim {
  align-items: center;
}
.so-frs-sheet {
  border-radius: var(--radius-xl);
  max-width: 560px;
}
.so-frs-body {
  padding: var(--space-4) var(--space-5);
}
.so-frs-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border);
}
.so-frs-count {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.so-frs-list {
  max-height: 340px;
  overflow-y: auto;
}
.so-frs-pick {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  white-space: normal;
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
}
.so-frs-toolbar .so-frs-all {
  min-height: var(--touch-target-min);
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
}
.so-frs-pick input,
.so-frs-all input {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.so-frs-pick-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.so-frs-pick-note {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.so-frs-confirm {
  margin: 0;
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
}
.so-frs-error {
  margin: 0;
  padding: var(--space-2) var(--space-5) 0;
}
.so-onboard-franchisees {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}
.so-onboard-franchisees-legend {
  padding: 0;
  margin-bottom: var(--space-1);
  font-weight: var(--font-weight-medium);
}
.so-onboard-franchisees-list {
  max-height: 220px;
  overflow-y: auto;
}

/* TEN13-F5 review fix: the detail's cards sit in a narrow column, so the card head and each row wrap, and the
   sheet's footer buttons share the width equally. */
.so-card-head {
  flex-wrap: wrap;
}
.so-frs-row {
  flex-wrap: wrap;
}
.so-frs-row-name {
  flex: 1 1 100%;
}
.so-frs-sheet .admin-confirm-actions > button {
  flex: 1 1 0;
}

/* UX101: buttons in a detail card keep room either side of the label. */
.so-detail-card button.btn-primary,
.so-detail-card button.btn-secondary,
.so-cp-card button.btn-primary,
.so-cp-card button.btn-secondary {
  padding-inline: var(--space-5);
}

/* UX101: the consoles' one toast slot (consoleToast.ts). Fixed to the bottom left, outside the footprint of every
   centered sheet (the widest is 560px wide, so at 1280px its left edge is past 360px and this slot ends before it),
   above the scrim, so it never covers a sheet title or a field. */
.console-toast {
  position: fixed;
  left: var(--space-4);
  bottom: var(--space-4);
  max-width: 280px;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
  background: var(--color-text-primary);
  color: var(--color-surface);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  z-index: var(--z-toast);
}
.console-toast[hidden] {
  display: none;
}

/* UX101: a franchisee checkbox row is the whole row, 44px or taller, with the label wrapping the checkbox, the name
   and the tag. A row that cannot be picked is dimmed and carries its "In <network>" tag at full strength. */
.so-frs-pick {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  min-height: var(--touch-target-min);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.so-frs-pick:has(input:disabled) {
  cursor: not-allowed;
  background: var(--color-surface-sunken);
}
.so-frs-pick:has(input:disabled) input,
.so-frs-pick:has(input:disabled) .so-frs-pick-name {
  opacity: 0.55;
}
.so-frs-pick .so-frs-pick-name {
  flex: 1 1 12rem;
}
.so-frs-pick-note {
  /* A long network name drops under the row's name instead of squeezing it. */
  margin-left: calc(22px + var(--space-3));
  max-width: calc(100% - 22px - var(--space-3));
  overflow-wrap: anywhere;
  padding: 2px var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  white-space: normal;
}

/* UX101: the Pending chip on the Adoption report reads in the primary text color on its sunken fill (11:1 or better
   on every theme; the secondary text color it had measured 5.9:1 on Brass). */
#fr-reports-section .so-badge-neutral {
  color: var(--color-text-primary);
}

/* UX101: on Snip & Sip Ink the light warning tint is a bright slab on a dark page. A dark amber surface with light
   amber text and a mid amber border keeps the warning readable (e2e/ux101-console-design-review.spec.ts asserts it). */
[data-theme="snipsip-ink"] .so-warning {
  background: #3b2a12;
  border-color: #b9791f;
  color: #f6d9a8;
}

/* UX101: an error border wins over the focus ring. A focused invalid field keeps its danger border and gets a
   danger-colored ring, never the neutral accent ring that hid the red border. */
input[aria-invalid="true"]:focus-visible,
select[aria-invalid="true"]:focus-visible,
textarea[aria-invalid="true"]:focus-visible,
.field-input.field-input-invalid:focus-visible {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-subtle-border);
}

/* ---------- UX38: the Settings "All N sections" list (docs/build-briefs/UX38-settings-all-sections-list.md, DEC-359 PROVISIONAL) ----------
   Option A of design/mockups/ux38-settings-width-a.html and -a-open.html. The button sits at the right end of the
   sticky one-row strip; the list opens inside the same sticky nav, right-aligned under it, so the strip stays put
   while the list is open. Width is untouched (UX79 lifted the cap). */
.admin-section-jump-all {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-strong);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  white-space: nowrap;
  cursor: pointer;
}
.admin-section-jump-all:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.admin-section-jump-caret::before {
  content: "\25BE";
}
.admin-section-jump-all[aria-expanded="true"] .admin-section-jump-caret::before {
  content: "\25B4";
}
.admin-section-jump-pop {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-2));
  width: 340px;
  max-width: 100%;
  max-height: calc(100vh - var(--space-8));
  overflow-y: auto;
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  z-index: calc(var(--z-sticky) + 5);
}
.admin-section-jump-pop[hidden] {
  display: none;
}
.admin-section-jump-pop-head {
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.admin-section-jump-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.admin-section-jump-row:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--color-focus-ring);
}
.admin-section-jump-row[aria-current="true"] {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.admin-section-jump-here {
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.admin-section-jump-here[hidden] {
  display: none;
}

/* ---------- UX104 (docs/build-briefs/UX104-console-clickthrough-fixes.md): the consoles after the 2026-10-10 click-through ----------
   Tokens only. Desktop admin surfaces. */

/* Every console button keeps room either side of its label. .btn-primary carries no inline padding in the shared
   sheet, so Create customer, Onboard new customer and Add owner fell back to the browser default (1px 6px). */
.so-page .btn-primary,
.so-page .btn-secondary,
.so-page .btn-danger,
.fr-shell .btn-primary,
.fr-shell .btn-secondary,
.fr-shell .btn-danger {
  padding-inline: var(--space-4);
}

/* A secondary button that cannot be pressed reads as blocked, not as live (Download CSV on an empty report). */
.so-page .btn-secondary:disabled,
.fr-shell .btn-secondary:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
}

/* A programmatically focused heading is a focus target for assistive technology, not a control: no ring. */
.so-panel-title:focus,
.so-title:focus,
.so-created-title:focus,
.fr-page-title:focus,
.fr-page-title:focus-visible,
.so-title:focus-visible,
.so-help-guide-title:focus {
  outline: none;
  box-shadow: none;
}

/* Customers: the card uses the width the screen has, headers stay whole words, and a pill is one line. */
.so-home.so-home-console {
  max-width: 1600px;
}
.so-table.so-customers th {
  white-space: nowrap;
  overflow-wrap: normal;
  letter-spacing: 0.02em;
}
.so-table.so-customers th:nth-child(1) {
  width: 14%;
}
.so-table.so-customers th:nth-child(2) {
  width: 12%;
}
.so-table.so-customers th:nth-child(3) {
  width: 11%;
}
.so-table.so-customers th:nth-child(4) {
  width: 12%;
}
.so-table.so-customers th:nth-child(5) {
  width: 11%;
}
.so-table.so-customers th:nth-child(6) {
  width: 14%;
}
.so-table.so-customers th:nth-child(7) {
  width: 8%;
}
.so-table.so-customers th:nth-child(8) {
  width: 18%;
}
.so-customers td:first-child,
.so-customers td:nth-child(5),
.so-customers td:nth-child(6) {
  max-width: none;
}
.so-customers .so-badge,
.so-customers td:nth-child(5) .so-badge,
.so-customers td:nth-child(6) .so-badge {
  white-space: nowrap;
}
.so-customers .so-row-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
}

/* Software owners: Actions is a real column, every row button sits in it, left-aligned under its header. */
#so-accounts-table th {
  white-space: nowrap;
  overflow-wrap: normal;
}
#so-accounts-table th:nth-child(1) {
  width: 16%;
}
#so-accounts-table th:nth-child(2) {
  width: 24%;
}
#so-accounts-table th:nth-child(3) {
  width: 11%;
}
#so-accounts-table th:nth-child(4) {
  width: 16%;
}
#so-accounts-table th:nth-child(5) {
  width: 33%;
}
#so-accounts-table td {
  overflow-wrap: break-word;
}
.so-account-actions {
  margin-top: 0;
  align-items: center;
}

/* Customer detail: the rename form is one full row above the cards, opened by the Rename button. */
#software-owner-rename-form {
  grid-column: 1 / -1;
  order: -3;
  max-width: none;
}

/* Onboard form: the defaults read as plain text and Legal details as a plain disclosure, neither as a disabled input. */
.so-settings-box {
  background: none;
  border: 0;
  padding: 0;
  border-radius: 0;
}
.so-legal-summary {
  min-height: var(--touch-target-min);
  align-items: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.so-same-billing {
  min-height: var(--touch-target-min);
}
.so-same-billing input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
}
.so-need-run {
  margin: var(--space-2) 0 0;
}

/* Franchisor console: the session note is the foot of the navigation; a card head with one child pushes it right;
   Set rate shares the Team rows' 44px. */
.fr-nav .so-limits {
  margin: var(--space-3) var(--space-4) 0;
  font-size: var(--font-size-xs);
}
.fr-card-head > :only-child {
  margin-left: auto;
}
.fr-team-table td.fr-team-actions .fr-team-you {
  display: inline-block;
}
.fr-team-table th:last-child {
  text-align: right;
}

/* UX103 (docs/build-briefs/UX103-settings-clickthrough-fixes.md): the Menu panel's vocabulary lists were one column of
   100px cards (8,871px tall at 1280x800). They lay out in as many columns as the width allows, with tighter card
   padding; the row's switch stays a 44px target. The jump strip and every heading are untouched. */
#admin-group-panel-menu .admin-void-reason-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: var(--space-2) var(--space-3);
}
#admin-group-panel-menu .admin-void-reason-row {
  padding: var(--space-2) var(--space-4);
  min-height: var(--touch-target-min);
}
#admin-group-panel-menu .admin-void-reason-row--stacked {
  gap: var(--space-2);
}
#admin-group-panel-menu .admin-void-reason-row--stacked .admin-item-kind-mechanism-wrap,
#admin-group-panel-menu .admin-void-reason-row--stacked .admin-field-help {
  margin-top: 0;
  margin-bottom: 0;
}

/* UX103: a PIN policy or Session inactivity hint sits directly under the field it describes, close to it and clear of
   the next label; Save is the full-height button at the left. */
#admin-pin-policy .field-input + .admin-field-help,
#admin-session-inactivity-card .field-input + .admin-field-help {
  margin: var(--space-1) 0 var(--space-4);
}
#admin-pin-policy .admin-settings-save-row .btn-primary {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-6);
}

/* UX103: the waiting codes meter says what its dots count ("0 of 5"). */
.tablets-meter-count {
  margin-left: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}

/* ---------- UX106 (docs/build-briefs/UX106-console-card-payments-clickthrough2.md): customer detail and Card payments after
   the second 2026-10-10 click-through. Tokens only. Desktop admin surfaces. ---------- */

/* Below 1000px the console navigation is a row above the content, so the forms get the whole width, and a label
   row that carries a tag wraps the tag under the label instead of laying it over. */
@media (max-width: 999px) {
  .so-page .so-console {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
  }
  .so-page .so-console .so-nav {
    flex: none;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    position: static;
    width: 100%;
  }
  .so-page .so-console .so-nav .so-nav-item {
    flex: 0 0 auto;
  }
  .so-page .so-console .so-nav .so-limits {
    flex: 1 0 100%;
    margin: 0;
  }
  .so-page .so-console .so-content {
    width: 100%;
    min-width: 0;
  }
  .so-detail-card .so-label-row {
    flex-wrap: wrap;
  }
}

/* Location heads share one height in every state. */
.so-cp-location-head {
  align-items: center;
  min-height: var(--touch-target-min);
}

/* Details: the provider's own words, closed by default; the toggle is a 44px target. */
.so-cp-details {
  margin-top: var(--space-2);
}
.so-cp-details-toggle {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-min);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.so-cp-details-toggle:focus-visible {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
}

/* Setup dialog option rows: the real radio fills the row, invisibly; a drawn 24px radio shows the choice. */
.so-cp-pick {
  position: relative;
}
.so-cp-pick-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.so-cp-pick-input:disabled {
  cursor: not-allowed;
}
.so-cp-radio {
  flex: none;
  position: relative;
  box-sizing: border-box;
  width: 24px;
  height: 24px;
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
}
.so-cp-radio::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: var(--radius-full);
  background: transparent;
}
.so-cp-pick-input:checked + .so-cp-radio {
  border-color: var(--color-accent-strong);
}
.so-cp-pick-input:checked + .so-cp-radio::after {
  background: var(--color-accent-strong);
}
.so-cp-pick:has(.so-cp-pick-input:focus-visible) {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
}
.so-cp-pick-off {
  opacity: 1;
  background: var(--color-surface-sunken);
}
.so-cp-pick-off .so-cp-radio {
  border-color: var(--color-border);
  background: var(--color-surface-sunken);
}
.so-cp-pick-chip {
  flex: none;
  margin-left: auto;
}

/* UX105 (docs/build-briefs/UX105-inventory-purchasing-clickthrough-fixes.md): the vendor list has no bullet, the
   internal notes box uses the app text style (a textarea falls back to monospace and the 44px input height), and
   the order list's "when" cell shares the row like the other cells. */
.admin-vendor-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.admin-vendor-row .admin-vendor-notes {
  height: auto;
  min-height: calc(var(--touch-target-comfortable) * 1.5);
  padding: var(--space-3) var(--space-4);
  font: inherit;
  resize: vertical;
}
.purchasing-order-when {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  flex: 2;
  min-width: 180px;
}
/* UX105: the stock section's intro stays in the page as the par and bin fields' accessible description
   (aria-describedby) but is not drawn; the heading and the labels already name the location. */
.admin-stock-intro {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.admin-inline-link--tap {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
}
/* UX108: the empty shell that paints first, until the first real screen is shown (main.ts hideAllScreens). */
#boot-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg);
}
#boot-retry {
  min-height: var(--touch-target-min);
}
/* ---------- UX102 (docs/build-briefs/UX102-floor-clickthrough-fixes.md): floor fixes from the 2026-10-10 click-through ---------- */

/* Paid state. Nothing is due: the disabled "Pay $0.00" and its "Nothing unpaid" warning are not drawn (the
   reason element keeps its text for assistive tech and the tests that read it). What is left is one
   compact summary: the "All paid" prompt with its one action, and the charge as a plain line under it, so
   the ticket's own lines keep their height. */
.ticket-actions.is-nothing-due .action-row-primary,
.ticket-actions.is-nothing-due .pay-block-reason {
  display: none;
}
.ticket-actions.is-nothing-due .pay-status.success {
  background: none;
  text-align: left;
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
  padding: var(--space-1) var(--space-5) 0;
  color: var(--color-success-text);
}
.zero-due-prompt-actions button.btn-pay {
  font-size: var(--font-size-base);
}
.pay-tip-split {
  padding: var(--space-2) var(--space-3);
}
.pay-tip-split-title {
  margin-bottom: var(--space-1);
}

/* Portrait (820x1180): the ticket stacks under the menu. The menu used to keep 45vh and take whatever it wanted,
   which left the ticket about one line. The two panes now split the height 45 to 55, the menu scrolls inside its
   share, and the ticket rail scrolls whatever does not fit. */
@media (max-width: 900px) {
  .menu-pane {
    min-height: 0;
    flex: 45 1 0;
  }
  .ticket-rail {
    flex: 55 1 0;
    min-height: 0;
  }
}

/* The hold and manager-exception banner is a one line chip with its View button, not a block. The View button
   keeps the 44px touch target; the chip adds only 4px of padding around it. */
.ticket-manager-exception-banner {
  margin: 0;
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  border-radius: 0;
  border-width: 1px 0;
}
.ticket-manager-exception-text {
  font-size: var(--font-size-chrome);
  line-height: var(--line-height-chrome);
}
.ticket-manager-exception-banner .btn-compact {
  min-height: var(--touch-target-min);
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  flex-shrink: 0;
}

/* The "All paid" prompt on the dark themes is a dark green surface with light green text, not a pale slab. */
[data-theme="snipsip-ink"] .zero-due-prompt,
[data-theme="charcoal"] .zero-due-prompt {
  background: #16301f;
  border-color: #2f6f4e;
}
[data-theme="snipsip-ink"] .zero-due-prompt-text,
[data-theme="charcoal"] .zero-due-prompt-text {
  color: var(--color-success-text);
}
.zero-due-prompt {
  margin-top: var(--space-2);
}

/* Sheet scale (UX102): three widths, 640 (choice and short forms), 760 (a form with fields), 960 (two columns).
   Edit line was 760 and Change price 780; both are 760. */
.price-change-sheet {
  max-width: 760px;
}

/* Toast slot, signed in (UX102): docked to the bottom of the menu pane (main.ts dockToastSlot sets the clear
   distances). Before sign-in, and over a bottom-anchored sheet, the slot keeps the UX100 place under the header. */
.toast-slot[data-dock="bottom"] {
  top: auto;
  bottom: var(--toast-clear-bottom, var(--space-4));
  right: var(--toast-clear-right, 0);
}
#app-shell:has(.stock86-backdrop:not([hidden])) .toast-slot[data-dock="bottom"] {
  right: min(640px, 100vw);
}

/* Reader chip, not set up (UX102): one label, "No reader", on every screen (it no longer collapses to "Reader" on a
   crowded header). On the dark themes it is a dark amber surface with light amber text, as the Ink warning panel
   is (UX101), not a pale peach pill that reads as a toggle. */
[data-theme="snipsip-ink"] .topbar-terminal-warning,
[data-theme="charcoal"] .topbar-terminal-warning {
  background: #3b2a12;
  border-color: #b9791f;
  color: #f6d9a8;
}

/* The account count badge sits on the trigger's corner. The header's right group scrolls sideways when its content
   is wider than its box, and the badge used to hang 6px outside the trigger, which made the group 5px too wide (a
   scrollbar line under the chips) and clipped the badge's top. The group now carries 6px of padding on the badge's
   side and takes the same back as negative margin, so the badge sits inside the box and nothing else moves. */
.topbar-right {
  padding: 6px 6px 0 0;
  margin: -6px -6px 0 0;
}

/* Visually hidden, still in the page for assistive tech and for text the tests read. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Ticket line after a price change (UX102): the price and the struck menu price share one row, as every other line's
   price sits under its name, so the name keeps the row. The "Price changed" location is one line, still one 44px tap
   target; on the dark themes it is a dark blue location with light blue text, quieter than the drink line above it. */
.line-price.has-price-change {
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-2);
}
.line-price-change {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
}
.lpc-go {
  min-height: var(--touch-target-min);
}
[data-theme="snipsip-ink"] .line-price-change,
[data-theme="charcoal"] .line-price-change {
  background: #16263a;
  border-color: #2a5c8a;
  color: var(--color-info-text);
}
[data-theme="snipsip-ink"] .line-price-change-why,
[data-theme="charcoal"] .line-price-change-why {
  color: var(--color-info-text);
}
[data-theme="snipsip-ink"] .lpc-go,
[data-theme="charcoal"] .lpc-go {
  border-left-color: #2a5c8a;
}

/* 86 list, a row that came back in stock: on the dark themes a dark green row, so the light text on it keeps its
   contrast (the pale green row carried light text at 1.1:1 on Ink). */
[data-theme="snipsip-ink"] .stock86-row--gone,
[data-theme="charcoal"] .stock86-row--gone {
  background: #16301f;
}

/* Ordering: 12px between the Cart / Orders / Receive stock switch and the heading under it, and the header
   action beside the user control is a 44px button like every other header control. */
.ordering-switch {
  margin-bottom: var(--space-3);
}
#topbar-secondary-action {
  height: var(--touch-target-min);
}

/* Ring screen tiles (UX102): a shelf-priced spirit tile does not repeat "Shelf price"; it is read by assistive tech. */
.tile-price.tile-price-quiet {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The Recipe button's reserved room is narrower and the price never wraps, so "From $10.75" stays on one line and
   cocktail tiles keep one height. */
.tile-wrapper--recipe-visible .tile-price {
  padding-right: 64px;
  white-space: nowrap;
}
.tile-recipe-button {
  min-width: 56px;
}

/* Account menu (UX102): no sub-label under any row, so every row is one height. The sub-label text stays in the page
   (the group hint is still computed) and is not drawn. */
.account-menu-sub {
  display: none;
}
.account-menu-row-tall {
  min-height: 48px;
}

/* PIN pad (UX102): before the first digit the display is a row of empty circles, not a blank band. The circles are
   drawn, not text, so the display still reads empty. */
.pin-entry-display:empty::before {
  content: "\25CB\25CB\25CB\25CB";
  color: var(--color-text-tertiary);
}

/* Operations screens (Stock levels, Count stock, Reports): the way back is on the left, where Home is, not on the
   right end of the title row. */
.ops-view-header {
  flex-direction: row;
  justify-content: flex-start;
  gap: var(--space-4);
}
.ops-view-back {
  order: -1;
}

/* Closeout status banner (UX102): a compact one-line block (its two sentences are gone), and on the dark themes a dark
   blue (not finalized) or dark green (finalized) surface with light text, not a pale slab. */
.status-banner {
  align-items: center;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
.status-icon {
  width: 32px;
  height: 32px;
}
[data-theme="snipsip-ink"] .status-banner,
[data-theme="charcoal"] .status-banner {
  background: #16263a;
  border-color: #2a5c8a;
}
[data-theme="snipsip-ink"] .status-banner .status-title,
[data-theme="snipsip-ink"] .status-banner .status-body,
[data-theme="charcoal"] .status-banner .status-title,
[data-theme="charcoal"] .status-banner .status-body {
  color: var(--color-info-text);
}
[data-theme="snipsip-ink"] .status-banner-success,
[data-theme="charcoal"] .status-banner-success {
  background: #16301f;
  border-color: #2f6f4e;
}
[data-theme="snipsip-ink"] .status-banner-success .status-title,
[data-theme="snipsip-ink"] .status-banner-success .status-body,
[data-theme="charcoal"] .status-banner-success .status-title,
[data-theme="charcoal"] .status-banner-success .status-body {
  color: var(--color-success-text);
}

.lpc-go {
  padding-left: var(--space-2);
  gap: var(--space-1);
}
.lpc-chevron {
  font-size: var(--font-size-lg);
  line-height: 1;
}

/* A paid ticket in portrait: the "All paid" prompt is one row (the text left, the button right) and the line list
   keeps room for three rows; the rail scrolls whatever then does not fit. */
@media (max-width: 900px) {
  .zero-due-prompt {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}
.ticket-rail:has(.ticket-actions.is-nothing-due) .ticket-lines {
  min-height: 190px;
}

/* The hold and manager-exception chip on the dark themes: a dark amber surface with light amber text. */
[data-theme="snipsip-ink"] .ticket-manager-exception-banner,
[data-theme="charcoal"] .ticket-manager-exception-banner {
  background: #3b2a12;
  border-color: #b9791f;
}
[data-theme="snipsip-ink"] .ticket-manager-exception-text,
[data-theme="charcoal"] .ticket-manager-exception-text {
  color: #f6d9a8;
}

/* 86 list category chips (UX102): the row snaps to a whole chip and fades at the right edge, so a chip is never cut
   mid-way with nothing to say there is more. The fade is narrower than the row's own right padding, so the last chip
   is clear of it when the row is scrolled to the end. */
.stock86-chips {
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--space-5);
  mask-image: linear-gradient(to right, #000 calc(100% - 16px), transparent);
}
.stock86-chip {
  scroll-snap-align: start;
}

/* ---------- SPLIT1: By amount pad ----------
   A button pad (no text field). Built on the same sheet, token and touch-target classes as the PIN pad and the
   equal-split stepper; the digit keys are the comfortable touch size or larger. */
.amount-pad-balance {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.amount-pad-body {
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  overflow-y: auto;
  min-height: 0;
}
.amount-pad-field {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 2px solid var(--color-accent-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  text-align: right;
}
.amount-pad-field.is-over {
  border-color: var(--color-danger-strong);
  color: var(--color-danger-strong);
}
.amount-pad-over {
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-sm);
}
.amount-pad-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.amount-pad-chip {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.amount-pad-chip.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.amount-pad-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--touch-target-gap-min);
}
.amount-pad-key {
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.amount-pad-key-quiet {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.amount-pad-key:active:not(:disabled) {
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.amount-pad-footer {
  display: flex;
  gap: var(--space-3);
}
.amount-pad-footer .btn-pay {
  flex: 2;
}
.amount-pad-footer .btn-secondary {
  flex: 1;
}

/* TERM8-F1: Settings > Tabs and payment > Card reader tips (ui/src/readerTips.ts). */
.rt-section {
  margin-bottom: var(--space-6);
}

.rt-locations {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.rt-location-name {
  margin: 0 0 var(--space-3);
  font-weight: var(--font-weight-semibold);
}

.rt-state {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.rt-group {
  margin-top: var(--space-4);
}

.rt-inputs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 12rem));
  gap: var(--space-3);
}

.rt-threshold {
  max-width: 12rem;
}

.rt-section .btn-primary,
.rt-section .btn-secondary {
  min-height: var(--touch-target-comfortable);
  padding-inline: var(--space-6);
}

/* ---------- UX109 (docs/build-briefs/UX109-floor-menu-search.md): floor menu search ----------
   The field sits at the left end of the strip row. While a query is active the strip is hidden and the field takes
   the row. */
.menu-index-row {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  min-width: 0;
  /* The row keeps the strip's height while the strip is hidden, so the grid does not jump. */
  min-height: var(--index-strip-height);
  background: var(--color-bg);
}
.menu-index-row .alphabet-strip {
  flex: 1;
  min-width: 0;
}
.menu-index-row.is-searching .alphabet-strip {
  display: none;
}
.menu-search {
  position: relative;
  flex: 0 0 220px;
  margin: 0 var(--space-2) 0 var(--space-5);
}
.menu-index-row.is-searching .menu-search {
  flex: 1 1 auto;
  margin-right: var(--space-5);
}
.menu-search-input {
  box-sizing: border-box;
  width: 100%;
  height: var(--touch-target-min);
  padding: 0 var(--touch-target-min) 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-md);
}
.menu-search-input:focus-visible,
.menu-search-clear:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.menu-search-clear {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg, 20px);
  line-height: 1;
  cursor: pointer;
}
.menu-search-clear[hidden] {
  display: none;
}

/* CORE5: the +1 chip in the ticket header repeats the newest drink. Same chip row and height as
   .btn-add-guest (tokens only); a solid fill so it reads as an action, 44px minimum width. */
.btn-ticket-repeat {
  height: var(--chrome-row-height);
  min-width: var(--touch-target-min);
  white-space: nowrap;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-chrome);
  font-weight: var(--font-weight-bold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.btn-ticket-repeat:hover {
  background: var(--color-surface-sunken);
}
.btn-ticket-repeat:disabled {
  opacity: 0.5;
  cursor: default;
}
.btn-ticket-repeat:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* CORE5: the count on a grouped row ("x6"), text so it never relies on colour. */
.line-group-count {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
}

/* CORE13: the closeout prints. Only the closeout screen is drawn; the shell stops being a
   viewport-height scroller so a long day runs onto further pages; buttons and the Finalize sheet are
   left off paper. */
.closeout-export-status {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
#reports-location,
#closeout-location {
  min-height: 44px;
  min-width: 160px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
}
@media print {
  html,
  body,
  #app-shell {
    height: auto;
    min-height: 0;
    overflow: visible;
  }
  #app-shell > *:not(#closeout-screen),
  body > *:not(#app-shell) {
    display: none !important;
  }
  #closeout-screen,
  #closeout-screen * {
    visibility: visible;
  }
  #closeout-screen .closeout-day-nav,
  #closeout-screen .closeout-freshness,
  #closeout-screen .closeout-stale-note,
  #closeout-screen button,
  #closeout-screen #closeout-finalize-availability {
    display: none !important;
  }
  #closeout-screen .figure-card,
  #closeout-screen .activity-row,
  #closeout-screen .status-banner {
    break-inside: avoid;
  }
}

.closeout-outside-collection-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* ---------- ONBW1-S3 setup wizard (docs/build-briefs/ONBW1-S3-owner-wizard.md; design/mockups/onboarding-wizard/wizard.css) ---------- */
/* The location owner's guided setup. Touch only: every control is 56px or larger (the main ones 64px), nothing depends on hover.
   Designed at iPad landscape 1180x820 and portrait 820x1180. Tokens only; the screen is drawn in the brass look (data-theme is
   set to brass on this screen while the default theme is showing). */

.setup-wizard {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  overflow: hidden;
}
.setup-wizard[hidden] {
  display: none;
}
.setup-wizard-top {
  flex: none;
  height: 64px;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-8);
  background: var(--color-brand-brown);
  color: var(--color-brand-cream);
  border-bottom: 3px solid var(--color-brand-red);
}
.setup-wizard-brand {
  font-weight: 800;
  font-size: var(--font-size-md);
  letter-spacing: 0.2px;
}
.setup-wizard-brand small {
  margin-left: 10px;
  font-weight: 500;
  font-size: var(--font-size-sm);
  color: var(--color-brand-cream-muted);
}
.setup-wizard-stepline {
  flex: 1;
  text-align: center;
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-brand-cream-muted);
}
.setup-wizard-finish-later {
  min-height: 48px;
  padding: 0 var(--space-5);
  border-radius: var(--radius-full);
  border: 1.5px solid rgba(246, 234, 216, 0.45);
  background: transparent;
  color: var(--color-brand-cream);
  font-size: var(--font-size-sm);
  font-weight: 700;
  cursor: pointer;
}
.setup-wizard-finish-later[hidden] {
  display: none;
}
.setup-wizard-segments {
  flex: none;
  list-style: none;
  margin: 0;
  display: flex;
  gap: var(--space-2);
  padding: 14px var(--space-8) 0;
  background: var(--color-bg);
}
.setup-wizard-segments[hidden] {
  display: none;
}
.setup-wizard-segment {
  flex: 1;
}
.setup-wizard-segment i {
  display: block;
  height: 8px;
  border-radius: 4px;
  background: var(--color-border);
}
.setup-wizard-segment b {
  display: block;
  margin-top: 6px;
  font-size: var(--font-size-xs);
  font-weight: 700;
  color: var(--color-text-tertiary);
  white-space: nowrap;
}
.setup-wizard-segment[data-state="done"] i {
  background: var(--color-success);
}
.setup-wizard-segment[data-state="done"] b {
  color: var(--color-success-text);
}
.setup-wizard-segment[data-state="current"] i {
  background: var(--color-accent);
}
.setup-wizard-segment[data-state="current"] b {
  color: var(--color-accent-strong);
}
.setup-wizard-main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.setup-wizard-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-6) var(--space-12) var(--space-6);
}
.setup-wizard-footer {
  flex: none;
  min-height: 96px;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-8);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -6px 18px rgba(70, 30, 13, 0.07);
}
.setup-wizard-footer .setup-wizard-reason {
  flex: 1;
}
.setup-wizard-reason {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
}
.setup-wizard-reason:empty {
  display: block;
}

/* Buttons */
.ow-btn {
  min-height: 64px;
  padding: 0 var(--space-8);
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-md);
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  cursor: pointer;
}
.ow-btn[hidden] {
  display: none;
}
.ow-btn:disabled {
  color: var(--color-text-tertiary);
  cursor: default;
}
.ow-btn-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  min-width: 260px;
  box-shadow: var(--shadow-2);
}
.ow-btn-primary:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
  box-shadow: none;
}
.ow-btn-quiet {
  border-color: transparent;
  background: transparent;
  color: var(--color-accent-strong);
  box-shadow: none;
}
.ow-btn-quiet:disabled {
  color: var(--color-text-tertiary);
}
.ow-btn-good {
  background: var(--color-success-strong);
  border-color: var(--color-success-strong);
  color: var(--color-text-on-accent);
}
.ow-btn-wide {
  flex: 1;
}
.ow-btn-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}
.ow-btn-primary.ow-btn-on {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-focus);
}

/* Layout */
.ow-col {
  width: 100%;
  max-width: 820px;
}
.ow-col-wide {
  max-width: 1020px;
}
.ow-kicker {
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--color-accent-strong);
}
.ow-title {
  margin: 0;
  font-family: var(--font-family-display, inherit);
  font-size: var(--font-size-2xl);
  line-height: 1.15;
  font-weight: 800;
}
.ow-hint {
  margin: 10px 0 0;
  font-family: var(--font-family-accent);
  font-style: var(--font-style-accent, italic);
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}
.ow-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.ow-col > .ow-card,
.ow-col > .ow-picks,
.ow-col > .ow-chips,
.ow-col > .ow-list,
.ow-col > .ow-mode,
.ow-col > .ow-cols,
.ow-col > .ow-row,
.ow-col > .ow-tiles {
  margin-top: var(--space-6);
}
.ow-col > .ow-card + .ow-card,
.ow-col > .ow-card + .ow-banner,
.ow-col > .ow-banner {
  margin-top: var(--space-4);
}
.ow-row {
  display: flex;
  gap: var(--space-4);
  align-items: stretch;
}
.ow-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-8);
  align-items: start;
}
@media (max-width: 900px) {
  .ow-cols {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }
  .setup-wizard-body {
    padding-left: var(--space-8);
    padding-right: var(--space-8);
  }
}
.ow-grow2 {
  flex: 2;
}

/* Fields */
.ow-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
  min-width: 0;
}
.ow-label {
  font-weight: 700;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ow-caps {
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.ow-input {
  min-height: 64px;
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  padding: 0 var(--space-5);
  font: inherit;
  font-size: var(--font-size-md);
  font-weight: 600;
  width: 100%;
  box-sizing: border-box;
}
.ow-input:focus {
  outline: none;
  border-color: var(--color-accent-strong);
  box-shadow: var(--shadow-focus);
}
.ow-padfield,
.ow-padvalue {
  display: flex;
  align-items: center;
  text-align: left;
  cursor: pointer;
}
.ow-padvalue {
  font-size: var(--font-size-xl);
  font-weight: 800;
  cursor: default;
}
.ow-word {
  text-align: center;
  font-size: var(--font-size-lg);
  font-weight: 800;
  min-width: 0;
}

/* Choices */
.ow-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.ow-chip {
  min-height: 64px;
  padding: 0 var(--space-6);
  border-radius: var(--radius-full);
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-md);
  font-weight: 700;
  cursor: pointer;
}
.ow-chip[aria-pressed="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.ow-picks {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.ow-pick {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 104px;
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-xl);
  border: 2px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-2);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.ow-pick[aria-checked="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle);
}
.ow-pick-ico {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 16px;
  background: var(--color-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  font-weight: 800;
  color: var(--color-accent-strong);
}
.ow-pick-title {
  flex: 1;
  font-size: var(--font-size-lg);
  font-weight: 800;
}
.ow-radio {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--color-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ow-pick[aria-checked="true"] .ow-radio {
  border-color: var(--color-accent-strong);
  background: var(--color-accent-strong);
}
.ow-pick[aria-checked="true"] .ow-radio::after {
  content: "";
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-text-on-accent);
}

/* Cards and values */
.ow-card {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--color-border);
  padding: var(--space-6) 28px;
}
.ow-big {
  font-size: 56px;
  font-weight: 800;
  line-height: 1.1;
}
.ow-hugevalue {
  font-size: 72px;
  font-weight: 800;
  line-height: 1.05;
  margin-top: 6px;
  font-variant-numeric: tabular-nums lining-nums;
}
.ow-bigvalue {
  display: block;
  width: 100%;
  min-height: 96px;
  margin-top: var(--space-3);
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 56px;
  font-weight: 800;
  cursor: pointer;
}
.ow-sub {
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
}
.ow-sumline {
  margin: 6px 0 var(--space-3);
  color: var(--color-text-secondary);
  font-weight: 600;
}
.ow-tag {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 14px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: 700;
  border: 1px solid transparent;
  white-space: nowrap;
}
.ow-tag-ok {
  background: var(--color-success-subtle);
  color: var(--color-success-text);
  border-color: var(--color-success-subtle-border);
}
.ow-tag-warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
  border-color: var(--color-warning-subtle-border);
}
.ow-tag-info {
  background: var(--color-info-subtle);
  color: var(--color-info-text);
  border-color: var(--color-info-subtle-border);
}
.ow-tag-todo {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  border-color: var(--color-border);
}
.ow-banner {
  padding: 18px var(--space-6);
  border-radius: var(--radius-lg);
  font-weight: 700;
  font-size: var(--font-size-md);
}
.ow-banner-info {
  background: var(--color-info-subtle);
  border: 1.5px solid var(--color-info-subtle-border);
  color: var(--color-info-text);
}
.ow-banner-warn {
  background: var(--color-warning-subtle);
  border: 1.5px solid var(--color-warning-subtle-border);
  color: var(--color-warning-text);
}
.ow-error {
  min-height: 0;
  color: var(--color-danger-text, var(--color-warning-text));
  font-weight: 700;
}
.ow-error:empty {
  display: none;
}
.ow-note {
  margin: var(--space-3) 0 0;
  color: var(--color-text-secondary);
}
.ow-keyrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  font-size: var(--font-size-md);
  border-top: 1px solid var(--color-border);
}
.ow-keyrow:first-child {
  border-top: 0;
}
/* BANK1: a Bank accounts row in the setup wizard: the title, then the owner's one line under it on its own line. */
.ow-bank-title {
  display: block;
  font-weight: var(--font-weight-semibold);
}
.ow-keyrow b.ow-bank-detail {
  white-space: nowrap;
}
.ow-bank-caption {
  display: block;
  margin: 0;
  font-family: inherit;
  font-style: normal;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ow-keyrow b {
  font-weight: 800;
}
.ow-center {
  justify-content: center;
  border-top: 0;
}

/* Steppers */
.ow-stepper {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.ow-step {
  width: 64px;
  height: 64px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 30px;
  cursor: pointer;
}
.ow-step:disabled {
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
  cursor: default;
}
.ow-stepval {
  min-width: 132px;
  min-height: 64px;
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-lg);
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.ow-stepval:disabled {
  cursor: default;
  color: var(--color-text-primary);
}
.ow-stepval-none {
  color: var(--color-text-tertiary);
  font-weight: 600;
  border-style: dashed;
  cursor: default;
}

/* Sales tax */
.ow-mode {
  display: flex;
  gap: 6px;
  padding: 6px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  width: max-content;
  max-width: 100%;
}
.ow-mode-btn {
  min-height: 56px;
  padding: 0 28px;
  border-radius: var(--radius-full);
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.ow-mode-on {
  background: var(--color-surface);
  box-shadow: var(--shadow-2);
  color: var(--color-accent-strong);
}
.ow-trows {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--color-border);
  overflow: hidden;
}
.ow-trow {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 84px;
  padding: var(--space-2) var(--space-5);
  border-top: 1px solid var(--color-border);
}
.ow-trow:first-child {
  border-top: 0;
}
.ow-trow-name {
  flex: 1;
  min-width: 0;
  font-weight: 700;
  font-size: var(--font-size-md);
}
.ow-trow-name small {
  display: block;
  margin-top: 2px;
  font-weight: 500;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ow-trow .ow-stepval {
  min-width: 112px;
}
.ow-tax-right {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.ow-total {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Tips */
.ow-tiles {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.ow-tile {
  flex: 1;
  min-height: 110px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 44px;
  font-weight: 800;
}
.ow-tile:disabled {
  color: var(--color-text-primary);
}
.ow-tile-edit {
  border-color: var(--color-accent);
  cursor: pointer;
}

/* Lists */
.ow-list {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--color-border);
  overflow: hidden;
}
.ow-li {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: 76px;
  padding: var(--space-3) var(--space-6);
  border-top: 1px solid var(--color-border);
  width: 100%;
  box-sizing: border-box;
}
.ow-li:first-child {
  border-top: 0;
}
.ow-li-button {
  background: transparent;
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.ow-li-main {
  flex: 1;
  min-width: 0;
}
.ow-li-title {
  font-weight: 700;
  font-size: var(--font-size-md);
}
.ow-li-sub {
  margin-top: 2px;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.ow-li-value {
  font-weight: 700;
  color: var(--color-text-secondary);
}
.ow-avatar {
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: 14px;
  background: var(--color-surface-sunken);
  color: var(--color-accent-strong);
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ow-check {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  background: var(--color-success);
  color: var(--color-text-on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
}
.ow-circle {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  border: 2.5px solid var(--color-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.ow-circle-wait {
  border-color: var(--color-warning);
  color: var(--color-warning-strong);
}
.ow-checkline {
  margin-top: var(--space-2);
  font-weight: 700;
  font-size: var(--font-size-md);
}
.ow-grouphead {
  margin: var(--space-6) 4px 10px;
  font-size: var(--font-size-sm);
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.ow-leftcol .ow-grouphead:first-child {
  margin-top: 0;
}
.ow-leftcol .ow-li .ow-btn {
  min-height: 56px;
  padding: 0 var(--space-6);
  font-size: var(--font-size-base);
}

/* The first drink */
.ow-bottlecard {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
}
.ow-bottlecard-empty {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  border-style: dashed;
  box-shadow: none;
}
.ow-price .ow-hugevalue {
  margin-bottom: var(--space-3);
}
.ow-priceline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-md);
}
.ow-priceline b {
  font-weight: 800;
}

/* People */
.ow-dots {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  margin: var(--space-4) 0;
}
.ow-dots i {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2.5px solid var(--color-border-strong);
}
.ow-dots i[data-filled="true"] {
  background: var(--color-text-primary);
  border-color: var(--color-text-primary);
}
.ow-keys {
  display: grid;
  grid-template-columns: repeat(3, 96px);
  gap: 12px;
  justify-content: center;
}
.ow-key {
  height: 72px;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 30px;
  font-weight: 700;
  cursor: pointer;
}
.ow-key-fn {
  background: var(--color-surface-sunken);
  font-size: var(--font-size-md);
}

/* Card reader and printer */
.ow-illus {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.ow-drawing {
  width: 100%;
  max-width: 300px;
  height: auto;
  color: #3a2a22;
}
.ow-steps {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-bottom: var(--space-4);
}
.ow-stepline {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}
.ow-stepnum {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-md);
}
.ow-steptext {
  padding-top: 6px;
  font-size: var(--font-size-md);
}
.ow-steptext small {
  display: block;
  margin-top: 2px;
  color: var(--color-text-secondary);
  font-weight: 500;
  font-size: var(--font-size-base);
}
.ow-words {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.ow-dash {
  font-size: 30px;
  font-weight: 800;
  color: var(--color-text-tertiary);
}
.ow-reader-right {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.ow-testcard {
  text-align: center;
}
.ow-code {
  font-size: var(--font-size-2xl);
  font-weight: 800;
  letter-spacing: 3px;
  margin: var(--space-3) 0;
}

/* Sheets */
.ow-scrim {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(70, 30, 13, 0.38);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.ow-sheet {
  width: 560px;
  max-width: 100%;
  background: var(--color-surface);
  border-radius: 28px 28px 0 0;
  padding: var(--space-6) var(--space-8) var(--space-8);
  box-shadow: var(--shadow-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-height: 100%;
  overflow: auto;
}
.ow-sheet-tall {
  width: 760px;
}
.ow-sheet-title {
  font-weight: 800;
  font-size: var(--font-size-lg);
}
.ow-sheet-actions {
  display: flex;
  gap: var(--space-4);
  justify-content: flex-end;
}
.ow-sheet-list {
  max-height: 480px;
  overflow: auto;
}
.ow-pad-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}
.ow-pad-value {
  min-height: 72px;
  display: flex;
  align-items: center;
  font-size: 56px;
  font-weight: 800;
  font-variant-numeric: tabular-nums lining-nums;
}
.ow-pad-reason {
  min-height: 24px;
  text-align: center;
  color: var(--color-warning-text);
  font-weight: 700;
}

.so-plan-change {
  display: grid;
  gap: 12px;
  margin-top: 16px;
  max-width: 420px;
}

.so-plan-change-confirm {
  display: grid;
  gap: 8px;
}

/* BILL1-F11: the Adjust price control on the Subscription card. Typed fields; chips are shortcuts. */
.so-override {
  display: grid;
  gap: 12px;
  margin-top: 16px;
  max-width: 420px;
}

.so-override-form fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

.so-override-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.so-override-active {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  justify-content: space-between;
}

.so-plan-history {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

/* BILL1-F10 (DEC-391): the locations on a franchisor's network bill. Tokens only. */
#software-owner-billing-locations-block {
  margin: var(--space-4) 0;
}

#software-owner-billing-open-franchisor,
#software-owner-billing-move,
#software-owner-billing-move-confirm + #software-owner-billing-portal {
  margin-top: var(--space-3);
}

#software-owner-billing-move-confirm {
  margin-top: var(--space-3);
}

.so-table.so-billing-locations {
  margin-top: var(--space-2);
}

.so-table.so-billing-locations th:nth-child(3),
.so-table.so-billing-locations td:nth-child(3) {
  width: 160px;
}

.so-table.so-billing-locations th:nth-child(4),
.so-table.so-billing-locations td:nth-child(4) {
  width: 150px;
  text-align: right;
}

/* ---------- TEN25 (docs/build-briefs/TEN25-owner-dashboard.md): the Software Owner dashboard and its navigation.
   Tokens only, from the approved mockup design/mockups/ten-owner-dashboard-full-1440x900.html. Admin surface, touch
   friendly: every tile and row is a 44px or taller button, no hover state, no typing. ---------- */
.so-home.so-home-dashboard {
  max-width: 1440px;
}

/* UIUX9: group existing destinations without adding rows or hiding actions. */
.fr-nav-item.fr-nav-group-start {
  margin-top: var(--space-2);
}
.so-nav-item.so-nav-with-icon {
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: var(--space-3);
}

.so-nav-icon {
  width: 22px;
  height: 22px;
  flex: none;
}

.so-nav-item:disabled {
  cursor: default;
  opacity: 0.55;
}

.so-nav-divider {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--space-3);
  width: calc(100% - 2 * var(--space-3));
}

.so-dash-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-6);
}

.so-dash-asof {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums lining-nums;
}

.so-dash-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.so-dash-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5) var(--space-6);
  min-width: 0;
  border: 0;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
}

.so-dash-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.so-dash-card-title {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.so-dash-kpis {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;
  gap: var(--space-4);
}

button.so-dash-kpi {
  display: block;
  cursor: pointer;
  min-height: 128px;
}

.so-dash-kpi:focus-visible,
.so-dash-row:focus-visible,
.so-dash-pill:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}

.so-dash-kpi-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums lining-nums;
}

.so-dash-kpi-first .so-dash-kpi-value {
  color: var(--color-accent-strong);
}

.so-dash-kpi-sub {
  margin-top: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
}

.so-dash-na {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}

.so-dash-kpi-value.so-dash-na {
  font-size: var(--font-size-2xl);
}

.so-dash-delta {
  display: inline-flex;
  align-items: center;
  font-weight: var(--font-weight-semibold);
}

.so-dash-delta-up {
  color: var(--color-success-text);
}

.so-dash-delta-down {
  color: var(--color-danger-strong);
}

.so-dash-arrow {
  width: 18px;
  height: 18px;
}

.so-dash-grid {
  display: grid;
  gap: var(--space-4);
}

.so-dash-grid-wide {
  grid-template-columns: 2fr 1fr;
}

.so-dash-grid-three {
  grid-template-columns: repeat(3, 1fr);
}

.so-dash-grid-two {
  grid-template-columns: 1fr 1fr;
}

.so-dash-chart text {
  font-family: var(--font-family-base);
  fill: var(--color-text-secondary);
  font-size: 12px;
}

.so-dash-chart .so-dash-latest-label {
  font-weight: 700;
  fill: var(--color-text-primary);
  font-size: 14px;
}

.so-dash-gridline {
  stroke: var(--color-border);
  stroke-width: 1;
}

.so-dash-line {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 3;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.so-dash-area {
  fill: var(--color-accent);
  opacity: 0.08;
}

.so-dash-dot {
  fill: var(--color-accent);
}

.so-dash-latest {
  fill: var(--color-accent);
  stroke: var(--color-surface);
  stroke-width: 3;
}

.so-dash-chart-empty {
  min-height: var(--space-16);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xl);
}

.so-dash-count {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--space-3);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  font-variant-numeric: tabular-nums lining-nums;
}

button.so-dash-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) 0;
  border: 0;
  border-top: 1px solid var(--color-border);
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.so-dash-card-head + button.so-dash-row,
.so-dash-card-title + button.so-dash-row {
  border-top: 0;
}

.so-dash-row-text {
  flex: 1;
  min-width: 0;
}

.so-dash-row-title {
  display: block;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}

.so-dash-row-detail {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}

.so-dash-chevron {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--color-text-tertiary);
}

.so-dash-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.so-dash-chip::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
}

.so-dash-chip-danger {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}

.so-dash-chip-danger::before {
  background: var(--color-danger-strong);
  border-radius: 50%;
}

.so-dash-chip-warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}

.so-dash-chip-warn::before {
  background: var(--color-warning-strong);
  transform: rotate(45deg);
}

.so-dash-chip-info {
  background: var(--color-info-subtle);
  color: var(--color-info-text);
}

.so-dash-chip-info::before {
  background: var(--color-info);
  border-radius: 2px;
}

.so-dash-lab {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: var(--space-3) 0 var(--space-1);
  font-size: var(--font-size-sm);
}

.so-dash-lab b {
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums lining-nums;
}

.so-dash-bar {
  height: 12px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  overflow: hidden;
  display: flex;
  gap: 2px;
}

.so-dash-bar i {
  display: block;
  height: 100%;
}

.so-dash-fill {
  background: var(--color-accent);
}

.so-dash-fill-2 {
  opacity: 0.6;
}

.so-dash-fill-3 {
  opacity: 0.3;
}

.so-dash-big {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums lining-nums;
}

.so-dash-big-unit {
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
  font-weight: 500;
}

.so-dash-big-danger {
  color: var(--color-danger-strong);
}

.so-dash-big-warn {
  color: var(--color-warning-strong);
}

.so-dash-big-good {
  color: var(--color-success-text);
}

.so-dash-pair {
  display: flex;
  gap: var(--space-8);
}

.so-dash-small {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}

.so-dash-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

button.so-dash-pill {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  color: inherit;
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}

.so-dash-card-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-4);
}

.so-dash-percent {
  font-variant-numeric: tabular-nums lining-nums;
}

.so-dash-key {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}

.so-dash-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: -1px;
}

.so-dash-seg-enabled {
  background: var(--color-accent);
}

.so-dash-seg-setting_up {
  background: var(--color-accent);
  opacity: 0.6;
}

.so-dash-seg-failed {
  background: var(--color-danger-strong);
}

.so-dash-seg-not_started {
  background: var(--color-surface-sunken);
  box-shadow: inset 0 0 0 1px var(--color-border);
}

@media (max-width: 1279px) {
  .so-dash-kpis {
    grid-template-columns: repeat(3, 1fr);
  }
  .so-dash-grid-wide,
  .so-dash-grid-three,
  .so-dash-grid-two {
    grid-template-columns: 1fr;
  }
}

/* TEN23 (DEC-390): the royalty per location. The franchisor customer page reads Franchisees, Legal business, Billing,
   Locations, Sign-in accounts; the Franchisees card lists each franchisee with its locations and their royalty; the royalty
   sheet is the design's (design/reviews/franchisor-page/03 and 04). Tokens only. */
.so-detail-grid.so-franchisor-page {
  grid-template-columns: 1fr;
}

.so-detail-grid.so-franchisor-page .so-detail-card {
  order: 6;
}

.so-franchisor-page #software-owner-rename-form {
  order: -10;
}

.so-franchisor-page #software-owner-franchisees-card {
  order: 1;
}

.so-franchisor-page #software-owner-profile-form.so-detail-card {
  order: 2;
}

.so-franchisor-page #software-owner-billing-card,
.so-franchisor-page #software-owner-billing-placeholder {
  order: 3;
}

.so-franchisor-page #software-owner-locations-card {
  order: 4;
}

.so-franchisor-page #software-owner-franchisor-accounts-card {
  order: 5;
}

.so-billing-placeholder {
  display: none;
}

/* A franchisor is not a franchisee: the read-only franchisee Royalty card has nothing to say on its page. */
.so-franchisor-page #software-owner-royalty-card {
  display: none;
}

.so-franchisor-page #software-owner-billing-card[hidden] + .so-billing-placeholder {
  display: block;
}

.roy-fr {
  display: block;
  border-top: 1px solid var(--color-border);
  padding: 0;
}

.roy-fr:first-child {
  border-top: 0;
}

.roy-fr-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto minmax(150px, auto) auto;
  align-items: center;
  gap: var(--space-3);
  min-height: 68px;
  cursor: pointer;
}

.roy-fr-toggle {
  appearance: none;
  width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text-tertiary);
  font: inherit;
  font-size: var(--font-size-md);
  cursor: pointer;
}

.roy-fr-who {
  min-width: 0;
  padding: var(--space-2) 0;
}

.roy-fr-name {
  min-width: 0;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.roy-fr-count {
  display: grid;
  font-size: var(--font-size-base);
}

.roy-loc-sub {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: 400;
}

.roy-link {
  appearance: none;
  border: 0;
  background: none;
  min-height: 44px;
  padding: 0 var(--space-4);
  color: var(--color-accent-strong);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.roy-locs {
  margin: 0 0 var(--space-4) 36px;
  padding: var(--space-2) var(--space-5) var(--space-4);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}

.roy-loc-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.roy-loc {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border);
}

.roy-loc:first-child {
  border-top: 0;
}

.roy-loc-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) auto;
  gap: var(--space-4);
  align-items: center;
}

.roy-loc-name {
  font-weight: 600;
}

.roy-rate-value {
  font-size: var(--font-size-md);
  font-weight: 700;
}

.roy-loc-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.roy-btn {
  height: var(--touch-target-min);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  white-space: nowrap;
}

.roy-pending {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--font-size-sm);
}

.roy-hist {
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--font-size-sm);
  background: var(--color-surface);
  border-radius: var(--radius-md);
}

.roy-hist[hidden] {
  display: none;
}

.roy-hist li {
  display: grid;
  grid-template-columns: 150px 1fr 1fr;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}

.roy-hist li:first-child {
  border-top: 0;
}

.roy-hist-current,
.roy-hist-current .roy-hist-value {
  font-weight: 700;
}

.roy-unlink {
  margin-top: var(--space-3);
}

.roy-group {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border);
}

.roy-group:first-child {
  border-top: 0;
}

.roy-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
}

.roy-group-name {
  margin: 0;
  font-size: var(--font-size-md);
}

/* FRADFUND1: the inline fund rate form under a franchisee row. */
.fund-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.fund-form .field-label {
  display: grid;
  gap: var(--space-1);
}

.fund-form .field-error {
  flex-basis: 100%;
  margin: 0;
}

.roy-sheet {
  border-radius: var(--radius-xl);
  width: 560px;
  max-width: calc(100vw - var(--space-6));
  max-height: calc(100vh - var(--space-6));
  overflow-y: auto;
  padding: var(--space-6) var(--space-8);
}

.roy-scrim {
  align-items: center;
  justify-content: center;
}

.roy-title {
  margin: 0;
  font-size: var(--font-size-lg);
}

.roy-inforce {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.roy-seg {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: var(--space-5) 0;
  padding: 4px;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}

.roy-seg button {
  appearance: none;
  border: 0;
  background: none;
  min-height: 48px;
  border-radius: var(--radius-sm);
  font: inherit;
  font-weight: 600;
  color: var(--color-text-secondary);
  cursor: pointer;
}

.roy-seg button.roy-on {
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
}

.roy-stepper {
  display: grid;
  grid-template-columns: 72px 1fr 72px;
  align-items: center;
  gap: var(--space-4);
}

.roy-step {
  appearance: none;
  height: 72px;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  font-size: 32px;
  font-weight: 500;
  color: var(--color-text-primary);
  cursor: pointer;
}

.roy-readout {
  text-align: center;
  font-size: 56px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
}

.roy-readout small {
  display: block;
  margin-top: 6px;
  font-size: var(--font-size-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--color-text-tertiary);
}

.roy-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.roy-chips-start {
  justify-content: flex-start;
  margin-top: 0;
}

.roy-chip {
  appearance: none;
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  border-radius: var(--radius-full);
  font: inherit;
  font-weight: 600;
  color: var(--color-text-primary);
  cursor: pointer;
}

.roy-chip-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}

.roy-label {
  margin: var(--space-5) 0 var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
}

.roy-date {
  margin-top: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font: inherit;
  color: var(--color-text-primary);
}

.roy-date[hidden] {
  display: none;
}

.roy-pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.roy-key {
  appearance: none;
  min-height: 56px;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  font: inherit;
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--color-text-primary);
  cursor: pointer;
}

.roy-confirm {
  margin: var(--space-5) 0 0;
}

.roy-error {
  min-height: 1.4em;
}

.roy-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
/* TEN24: the software owner console's Audit log. */
.so-audit-filters {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr)) auto;
  gap: var(--space-3);
  align-items: end;
  margin-bottom: var(--space-3);
}

.so-audit-export {
  display: flex;
  gap: var(--space-3);
  align-items: center;
}

.so-audit-table {
  table-layout: fixed;
}

.so-audit-table th:nth-child(1) {
  width: 17%;
}

.so-audit-table th:nth-child(2) {
  width: 16%;
}

.so-audit-table th:nth-child(3) {
  width: 19%;
}

.so-audit-table th:nth-child(4) {
  width: 18%;
}

.so-audit-table td {
  vertical-align: top;
  overflow-wrap: anywhere;
}

.so-audit-role {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.so-audit-pager {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  justify-content: flex-end;
  margin-top: var(--space-4);
}

.so-audit-pager .so-state {
  margin: 0 auto 0 0;
}

/* TEN11-F1: the Support session location (first child of #app-shell) and the ended screen. Built by supportEntry.ts. */
.support-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex: 0 0 auto;
  min-height: var(--touch-target-min);
  padding: var(--space-1) var(--space-4);
  background: var(--color-surface-sunken);
  border-bottom: 2px solid var(--color-accent-strong);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.support-bar-label {
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.support-bar-who {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-text-primary);
}
.support-bar-left {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.support-bar-end {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
}
.support-ended {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  background: var(--color-surface);
  color: var(--color-text-primary);
  text-align: center;
}
.support-ended-title {
  margin: 0;
  font-size: var(--font-size-xl);
}
.support-ended-hint {
  margin: 0;
  color: var(--color-text-secondary);
}

.so-customers .so-row-button[data-testid="software-owner-row-support"] {
  white-space: nowrap;
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}

/* BILL1-F9, OWNERPLANS1, OWNERAI1: the Plans and AI pages of the software owner console. Tokens only. */
.so-plans-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.so-plans-head .so-panel-title {
  margin-bottom: 0;
}

.so-plans-count {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.so-num,
.so-table th.so-num,
.so-table td.so-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.so-none {
  color: var(--color-text-tertiary);
}

.so-plans-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-medium);
}

.so-plans-banner[hidden],
.so-plans-skeleton[hidden],
.so-plans-empty[hidden],
.so-plans-count[hidden] {
  display: none;
}

.so-plans-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-4) 0;
}

.so-plans-skeleton .skel {
  height: 18px;
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
}

.so-plans-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-8) 0;
  color: var(--color-text-secondary);
}

.so-plans-empty strong {
  color: var(--color-text-primary);
  font-size: var(--font-size-md);
}

.so-plans-table th,
.so-plans-table td {
  width: auto;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  white-space: nowrap;
  overflow: hidden;
  overflow-wrap: normal;
  text-overflow: ellipsis;
}

.so-plans-table td {
  height: 64px;
  padding-top: 0;
  padding-bottom: 0;
}

.so-plans-table th {
  text-overflow: clip;
}

.so-plans-name {
  font-weight: var(--font-weight-semibold);
}

.so-plans-table tr:last-child td {
  border-bottom: 0;
}

.so-plans-retired td {
  height: 56px;
  color: var(--color-text-secondary);
}

.so-plans-retired .so-plans-name {
  font-weight: var(--font-weight-medium);
}

.so-plans-group td {
  height: auto;
  padding-top: var(--space-6);
  padding-bottom: var(--space-2);
  border-bottom: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.so-plans-actions {
  text-align: right;
}

.so-plans-action-box {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
}

.so-plans-action-box .btn-secondary,
.so-plans-confirm .btn-secondary,
.so-plans-confirm .btn-danger {
  width: auto;
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}

.btn-text-danger {
  height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

.btn-text-danger:hover {
  background: var(--color-danger-subtle);
}

.so-plans-table tr.confirming td {
  background: var(--color-danger-subtle);
}

.so-plans-confirm {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  min-width: 0;
}

.so-plans-confirm-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-strong);
}

/* Add plan: a centered modal dialog on the console's own dialog (dialog.so-cp-dialog), never a side drawer. */
dialog.so-plans-dialog {
  width: 520px;
  overflow: hidden;
}

.so-plans-dialog[open] {
  display: block;
}

.so-plans-form {
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 64px);
}

.so-plans-dialog-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
}

.so-plans-dialog-body .admin-field {
  margin-bottom: var(--space-3);
}

.so-plans-section {
  margin: var(--space-3) 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.so-plans-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.so-plans-picker {
  margin-bottom: var(--space-3);
}

.so-plans-picker[hidden] {
  display: none;
}

.so-plans-picker-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}

/* One joined control: minus, field, plus, then the small preset chips beneath. */
.so-plans-picker .group-in {
  display: flex;
  align-items: center;
}

.so-plans-picker .group-in .btn-stepper {
  flex: 0 0 var(--touch-target-comfortable);
  width: var(--touch-target-comfortable);
  height: 40px;
  border-radius: 0;
  background: var(--color-surface-sunken);
  font-size: var(--font-size-lg);
}

.so-plans-picker .group-in .btn-stepper:first-child {
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  border-right: 0;
}

.so-plans-picker .group-in .btn-stepper:last-child {
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  border-left: 0;
}

.so-plans-readout {
  height: 40px;
  min-width: 0;
  border-radius: 0;
  text-align: center;
}

.so-plans-picker .admin-chip-select {
  margin: var(--space-2) 0 0;
}

.so-plans-picker .admin-chip-option-label {
  min-height: 32px;
  padding: 0 var(--space-3);
}

/* OWNERAI1: the AI page. */
.so-ai-card {
  max-width: none;
}

.so-ai-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.so-ai-title-row .so-detail-title {
  margin: 0;
}

.so-ai-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--space-6);
}

.so-ai-foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.so-ai-status {
  margin: 0;
  color: var(--color-text-secondary);
}

.so-ai-refusal {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}

.so-ai-refusal[hidden] {
  display: none;
}

.so-ai-refusal .btn-secondary {
  flex: none;
  height: var(--touch-target-min);
}

.so-ai-providers {
  list-style: none;
  margin: 0;
  padding: 0;
}

.so-ai-provider {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.so-ai-provider-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

dialog.so-ai-dialog {
  width: min(560px, 92vw);
}

.so-ai-steps {
  display: flex;
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: var(--space-3) var(--space-5);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.so-ai-step-current {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-medium);
}

.so-ai-wizard-body {
  padding: var(--space-3) var(--space-5);
}

.so-ai-review {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0;
}

.so-ai-review dd {
  margin: 0;
}

.so-ai-rates {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
}

.so-ai-rate {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}

.so-ai-rate-form {
  display: grid;
  grid-template-columns: 2fr 1fr 2fr auto;
  gap: 0 var(--space-3);
  align-items: start;
}

.so-ai-rate-form .btn-secondary {
  margin-top: calc(var(--font-size-sm) * 1.5 + var(--space-1));
}

.so-ai-rate-form .so-ai-status {
  grid-column: 1 / -1;
}

/* ---------- ID1 (docs/build-briefs/ID1-id-verified-ticket-action.md; design/mockups/id1/) ----------
   The ID Verified row between the drinks and the totals: a 44px "ID Verified" button until a check is recorded, then a
   green done row (who, when) with Change. The method sheet reuses the two-column choice sheet; the last method spans
   both columns, as in the approved mockup. The Location settings "Service" row sits in a .bd-card. */
.idrow {
  flex: none;
  padding: var(--space-2) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.idrow[hidden] {
  display: none;
}
.id-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  height: 44px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
/* RCPT2: the Receipt row of a closed ticket (ui/src/ticketReceipt.ts). */
.rcptrow {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--color-border);
}
.rcptrow[hidden] {
  display: none;
}
.rcpt-row,
.rcpt-edit {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.rcpt-tx {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  line-height: var(--line-height-tight);
}
.rcpt-tx span {
  overflow: hidden;
  font-size: var(--font-size-sm);
  text-overflow: ellipsis;
  color: var(--color-text-secondary);
}
.rcpt-btn {
  display: grid;
  place-items: center;
  flex: none;
  height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rcpt-input {
  flex: 1;
  min-width: 0;
  height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
}
.id-btn svg {
  width: 20px;
  height: 20px;
  color: var(--color-accent);
}
.id-done {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.id-done .ck {
  display: grid;
  place-items: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-success-strong);
  color: var(--color-text-on-dark);
  font-weight: var(--font-weight-bold);
}
.id-done .tx {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  line-height: var(--line-height-tight);
}
.id-done .tx b {
  font-size: var(--font-size-base);
}
.id-done .tx span {
  font-size: var(--font-size-sm);
}
.id-done .chg {
  display: grid;
  place-items: center;
  flex: none;
  height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-success-subtle-border);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.choice-sheet-two-col .choice-list .choice-option[data-testid="id-method-other_government_id"] {
  grid-column: 1 / -1;
}
.svc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 56px;
}
.svc-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.svc-title {
  font-weight: var(--font-weight-semibold);
}
/* ID1-F2 (DEC-398): the Off / Optional / Required control on Settings > Location > Service. */
.svc-seg {
  display: grid;
  grid-template-columns: repeat(3, minmax(88px, 128px));
  gap: 4px;
  padding: 4px;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.svc-seg-btn {
  min-height: 44px;
  border: 0;
  border-radius: calc(var(--radius-md) - 2px);
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.svc-seg-btn[aria-checked="true"] {
  background: var(--color-surface);
  color: var(--color-accent-strong);
  box-shadow: var(--shadow-2);
}
.svc-seg-btn:disabled {
  cursor: default;
  opacity: 0.6;
}
.svc-seg-btn[aria-checked="true"]:disabled {
  opacity: 1;
}
/* ID1-F2: the "ID not checked" sheet. Verify now is the large primary; Skip sits under it. */
.choice-option.choice-option-primary {
  min-height: 72px;
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.choice-option.choice-option-primary .choice-option-label {
  color: inherit;
}
.svc-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
/* CORE7-F1 (docs/build-briefs/CORE7-F1-86-visibility-in-settings.md): drinks and ingredients in Stock levels,
   the inline 86 panel, and the History lines under a row in the 86 list. Built on the STK1 rules above. */
#admin-stock-levels-panel.admin-menu86-open > :not(#admin-menu86-panel) {
  display: none;
}
.inv-table caption.admin-bottle-group-heading {
  caption-side: top;
  text-align: left;
}
.inv-stock-via {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
}
.stock86-row {
  flex-wrap: wrap;
}
.stock86-btn-history {
  flex-shrink: 0;
  height: 52px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.stock86-btn-history:disabled {
  opacity: 0.55;
}
.stock86-btn-history:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.stock86-history {
  flex-basis: 100%;
  margin: 0;
  padding: 0 0 var(--space-2) var(--space-5);
  list-style: none;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.stock86-history[hidden] {
  display: none;
}
#admin-menu86-panel .stock86-history {
  padding-left: 0;
}
.inv-table--menu {
  table-layout: fixed;
}
#admin-menu86-panel > .section-title {
  margin-top: var(--space-4);
}
#admin-menu86-panel .stock86-editor-since {
  margin-bottom: 0;
}

/* UX116 (docs/build-briefs/UX116-function-hubs.md; design/mockups/function-hubs/): the four function hubs. Tiles
   are tappable summaries, buttons are the rows the old drill-in list held. Every control is at least 44px. A
   tile that reads N/A is a plain card, not a button. */
#function-hub-screen .tabs-page {
  max-width: none;
  padding: var(--space-5) var(--space-8) var(--space-8);
}
.hub {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.hub[hidden] {
  display: none;
}
.hub-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.hub-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  display: inline-flex;
  align-items: center;
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  cursor: pointer;
}
.hub-chip-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.hub-chip-static {
  cursor: default;
}
.hub-chip[hidden] {
  display: none;
}
.hub-grid {
  display: grid;
  gap: var(--space-3);
}
.hub-grid:empty {
  display: none;
}
.hub-grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.hub-grid-lower-inventory {
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}
.hub-grid-lower-one {
  grid-template-columns: minmax(0, 1fr);
}
.hub-tile {
  position: relative;
  min-height: 112px;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-2);
  font: inherit;
  text-align: left;
}
button.hub-tile {
  cursor: pointer;
}
.hub-tile-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.hub-tile-k {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.hub-tile-v {
  margin-top: var(--space-1);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.hub-tile-s {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.hub-tile-go::before {
  content: "\203a" / "";
}
.hub-tile-go {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  font-size: var(--font-size-lg);
  line-height: 1;
  color: var(--color-text-tertiary);
}
.hub-tile-na .hub-tile-v {
  color: var(--color-text-tertiary);
}
.hub-tile-warn .hub-tile-v {
  color: var(--color-danger-strong);
}
.hub-tile-amber .hub-tile-v {
  color: var(--color-warning-strong);
}
.hub-delta {
  font-weight: var(--font-weight-bold);
}
.hub-delta-up {
  color: var(--color-success-strong);
}
.hub-delta-down {
  color: var(--color-danger-strong);
}
.hub-list {
  justify-content: flex-start;
}
.hub-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 3px 0;
  font-size: var(--font-size-base);
}
.hub-row-name {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.hub-row-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hub-row-meta {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.hub-row-right {
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.hub-row-empty,
.hub-list-na {
  color: var(--color-text-tertiary);
}
.hub-pill {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  padding: 2px 8px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.hub-pill-red {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.hub-pill-amber {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.hub-groups {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}
.hub-groups-inventory,
.hub-groups-ordering,
.hub-groups-shift {
  grid-template-columns: minmax(0, 1fr);
}
.hub-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.hub-group[hidden] {
  display: none;
}
.hub-group-flat {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}
.hub-group-heading {
  margin: 0 0 2px var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.hub-group-heading[hidden] {
  display: none;
}
.hub-btn {
  min-height: 56px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.hub-btn[hidden] {
  display: none;
}
.hub-btn-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.hub-btn-sub {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}
.hub-btn-chev::before {
  content: "\203a" / "";
}
.hub-btn-chev {
  margin-left: auto;
  font-size: var(--font-size-lg);
  line-height: 1;
  color: var(--color-accent-strong);
}
.hub-btn .account-menu-badge + .hub-btn-chev {
  margin-left: 0;
}
.hub-btn .account-menu-badge {
  margin-left: auto;
}
.hub-btn-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
}
.hub-btn-primary .hub-btn-sub,
.hub-btn-primary .hub-btn-chev {
  color: var(--color-text-on-accent);
  opacity: 0.85;
}
/* Phone width (design/mockups/function-hubs/reports-hub-390x844.html): two tile columns, buttons one per row,
   nothing wider than the screen. */
@media (max-width: 700px) {
  #function-hub-screen .tabs-page {
    padding: var(--space-4);
  }
  .hub-head {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }
  .hub-grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .hub-grid-lower-inventory,
  .hub-group-flat {
    grid-template-columns: minmax(0, 1fr);
  }
  .hub-wide {
    grid-column: 1 / -1;
  }
  .hub-tile-v {
    font-size: var(--font-size-xl);
  }
}

/* RPT2 (docs/build-briefs/RPT2-menu-profitability.md; design/mockups/rpt-menu-profitability/): the Menu profitability
   report body, drawn by ui/src/menuProfitability.ts. Built on the design tokens only. Every control is 44px or taller;
   nothing depends on hover. A laptop shows the table; at 1000px and below each drink is one expandable card (so the
   money columns are never behind a sideways scroll, and a phone never scrolls sideways). */
.mp {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.mp-qs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}
.mp-q {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  padding: var(--space-3) var(--space-4);
  min-height: 76px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.mp-q.on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
.mp-q .k {
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.mp-q .v {
  font-size: var(--font-size-lg);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
.mp-q .v small {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
  margin-left: var(--space-2);
}
.mp-q .d {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.mp-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}
.mp-dot.ok {
  background: var(--color-success);
}
.mp-dot.amb {
  background: var(--color-warning);
}
.mp-dot.inf {
  background: var(--color-info);
}
.mp-dot.red {
  background: var(--color-danger);
}
.mp-tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.mp-tgt {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
}
.mp-step {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.mp-step-btn {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: var(--font-size-lg);
  color: var(--color-accent-strong);
}
.mp-step-btn:disabled {
  color: var(--color-text-tertiary);
}
.mp-step-value {
  min-width: 64px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: 1px solid var(--color-border);
  border-right: 1px solid var(--color-border);
  font-size: var(--font-size-md);
  font-weight: 800;
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}
.mp-error {
  color: var(--color-danger-strong);
  font-weight: 700;
}
.mp-sort {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
}
.mp-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.mp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}
.mp-table th {
  font-size: var(--font-size-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  font-weight: 700;
  text-align: right;
  padding: 0 var(--space-3);
  height: 44px;
  border-bottom: 1px solid var(--color-border-strong);
  white-space: nowrap;
  background: var(--color-surface-sunken);
}
.mp-table th.l,
.mp-table td.l {
  text-align: left;
}
.mp-table td {
  padding: 0 var(--space-3);
  height: 52px;
  text-align: right;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.mp-table td.l {
  font-weight: 600;
  font-size: var(--font-size-base);
}
.mp-table tr:last-child td {
  border-bottom: 0;
}
.mp-table td.na {
  color: var(--color-text-tertiary);
  font-weight: 600;
}
.mp-table td.hi {
  color: var(--color-danger-strong);
  font-weight: 700;
}
.mp-table td.strong {
  font-weight: 800;
}
.mp-table td.hit {
  font-weight: 800;
  color: var(--color-accent-strong);
}
.mp-pill {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  vertical-align: middle;
  margin-left: var(--space-2);
}
.mp-pill.ok {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.mp-pill.amb {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.mp-pill.inf {
  background: var(--color-info-subtle);
  color: var(--color-info);
}
.mp-pill.red {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.mp-pill.mute {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border);
}
.mp-empty {
  margin: 0;
  padding: var(--space-4);
  color: var(--color-text-tertiary);
  font-weight: 600;
}
.mp-cards {
  display: none;
}
.mp-dc {
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-4);
  min-height: 64px;
}
.mp-dc:last-child {
  border-bottom: 0;
}
.mp-dc-t {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
}
.mp-dc-t b {
  font-size: var(--font-size-base);
  line-height: 1.25;
}
.mp-dc-t .c {
  color: var(--color-accent-strong);
  font-size: var(--font-size-lg);
}
.mp-l2 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin-top: 2px;
}
.mp-l2 > div,
.mp-more > div {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.mp-l2 span,
.mp-more span {
  display: block;
  font-size: var(--font-size-md);
  font-weight: 800;
  color: var(--color-text-primary);
  letter-spacing: 0;
  text-transform: none;
}
.mp-l2 span.hi {
  color: var(--color-danger-strong);
}
.mp-l2 span.na,
.mp-more span.na {
  color: var(--color-text-tertiary);
}
.mp-more {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--color-border);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-3) var(--space-4);
}
.mp-more .hitbox {
  grid-column: 1 / -1;
  background: var(--color-accent-subtle);
  border: 1px solid var(--color-accent-subtle-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.mp-more .hitbox span {
  color: var(--color-accent-strong);
}
.mp-more .hitbox .mp-pill {
  margin-left: 0;
}
.mp-more .hitbox .sub {
  display: inline;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  font-weight: 400;
}
@media (max-width: 1000px) {
  .mp-table-card {
    display: none;
  }
  .mp-cards {
    display: block;
  }
}
@media (max-width: 700px) {
  .mp-qs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .mp-tools {
    flex-direction: column;
    align-items: stretch;
  }
  .mp-tgt {
    justify-content: space-between;
  }
  .mp-sort > span {
    display: none;
  }
  .mp-sort .chip {
    flex: 1;
    justify-content: center;
    padding: 0 var(--space-3);
  }
}

/* ---------- TEN14-F8-F1 (docs/build-briefs/TEN14-F8-F1-franchisor-audit-view.md): franchisor console, Audit log ----------
   Reuses .fr-card, .fr-table and the Reports pickers; only the column widths and the pager are new. Desktop admin
   surface, so a keyboard and pointer are assumed. */
.fr-audit-table {
  width: 100%;
  table-layout: fixed;
}
.fr-audit-table th:nth-child(1) {
  width: 17%;
}
.fr-audit-table th:nth-child(2) {
  width: 17%;
}
.fr-audit-table th:nth-child(3) {
  width: 20%;
}
.fr-audit-table td {
  vertical-align: top;
  overflow-wrap: anywhere;
}
.fr-audit-line {
  margin: 0;
}
.fr-audit-pager {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  justify-content: flex-end;
  margin-top: var(--space-4);
}
.fr-audit-pager .so-state {
  margin: 0 auto 0 0;
}

/* INVXFER1-S2 (docs/build-briefs/INVXFER1-stock-transfers-between-bars.md section 9; design/mockups/invxfer1-s2/): the
   stock transfer screens. The screens draw their own header, so the shell's operations header is hidden for them.
   Colors are tokens only, so every theme (including the dark one) follows. */
.admin-ops-mode[data-ops-view="transfers"] #admin-ops-header {
  display: none;
}
.xfer {
  font-variant-numeric: tabular-nums;
}
.xfer-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.xfer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.xfer-head-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}
.xfer-back {
  flex: none;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 22px;
  line-height: 1;
}
.xfer-eyebrow {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}
.xfer-title {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: 1.15;
  overflow-wrap: break-word;
}
.xfer-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.xfer-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.xfer-chip.xfer-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.xfer-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
}
.xfer-btn-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
}
.xfer-btn-danger {
  color: var(--color-danger-strong);
  border-color: var(--color-danger-strong);
}
.xfer-btn-small {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
}
.xfer-btn-wide {
  width: 100%;
  min-height: 64px;
  font-size: var(--font-size-lg);
}
.xfer-btn:disabled,
.xfer-step:disabled,
.xfer-whole:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
  box-shadow: none;
}
.xfer-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  min-width: 0;
}
.xfer-card-col {
  display: flex;
  flex-direction: column;
}
.xfer-pad {
  padding: var(--space-4);
  gap: var(--space-3);
}
.xfer-card-scroll {
  overflow: auto;
}
.xfer-grow {
  flex: 1;
}
.xfer-k {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.xfer-v {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  overflow-wrap: anywhere;
}
.xfer-sectitle {
  padding: var(--space-3) var(--space-4) var(--space-2);
}
.xfer-pad .xfer-sectitle {
  padding: 0;
}
.xfer-empty {
  margin: 0;
  padding: var(--space-5);
  color: var(--color-text-secondary);
}
.xfer-error {
  margin: 0;
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.xfer-confirm {
  margin: 0;
  font-weight: var(--font-weight-semibold);
}
.xfer-pill {
  justify-self: start;
  align-self: center;
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border-radius: var(--radius-full);
  font-size: 13px;
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
}
.xfer-pill-sent {
  background: var(--color-info-subtle);
  color: var(--color-info-text);
}
.xfer-pill-received {
  background: var(--color-success-subtle);
  color: var(--color-success-text);
}
.xfer-pill-cancelled {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.xfer-rows {
  display: flex;
  flex-direction: column;
}
.xfer-trow {
  display: grid;
  grid-template-columns: 140px 1fr 170px 100px 32px;
  align-items: center;
  gap: var(--space-4);
  min-height: 72px;
  padding: 0 var(--space-5);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: none;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
}
.xfer-trow:last-child {
  border-bottom: 0;
}
.xfer-route {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  overflow-wrap: break-word;
}
.xfer-arrow {
  margin: 0 var(--space-2);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
.xfer-when {
  font-weight: var(--font-weight-semibold);
}
.xfer-count {
  color: var(--color-text-secondary);
}
.xfer-go {
  color: var(--color-text-tertiary);
  font-size: 22px;
  text-align: right;
}
.xfer-to {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.xfer-two {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 520px);
  gap: var(--space-5);
  align-items: start;
}
.xfer-two-receive {
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
}
.xfer-two-detail {
  grid-template-columns: minmax(0, 1fr) minmax(0, 360px);
}
.xfer-lines {
  display: flex;
  flex-direction: column;
}
.xfer-ln {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 76px;
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.xfer-ln:last-child {
  border-bottom: 0;
}
.xfer-ln > :first-child {
  flex: 1 1 120px;
  min-width: 110px;
}
.xfer-n {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  overflow-wrap: break-word;
}
.xfer-s {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.xfer-qty {
  font-weight: var(--font-weight-bold);
  text-align: right;
}
.xfer-stepper-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.xfer-stepper {
  display: inline-grid;
  grid-template-columns: 52px 68px 52px;
  align-items: center;
}
.xfer-step {
  height: 56px;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 26px;
  font-weight: var(--font-weight-medium);
  text-align: center;
  line-height: 1;
}
.xfer-step:first-child {
  border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.xfer-step:last-child {
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.xfer-stepper output {
  height: 56px;
  display: grid;
  place-items: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  border-block: 1px solid var(--color-border-strong);
  background: var(--color-surface);
}
.xfer-stepper-wrap {
  flex: none;
}
.xfer-unit {
  min-width: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.xfer-whole,
.xfer-remove {
  min-width: var(--touch-target-min);
  height: var(--touch-target-min);
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-bold);
}
.xfer-foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
}
.xfer-short-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.xfer-short {
  margin: 0;
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.xfer-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.xfer-opt {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-align: center;
}
.xfer-opt.xfer-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
  box-shadow: inset 0 0 0 1px var(--color-accent-strong);
}
@media (max-width: 760px) {
  .xfer-head {
    flex-wrap: wrap;
  }
  .xfer-two,
  .xfer-two-receive,
  .xfer-two-detail {
    grid-template-columns: minmax(0, 1fr);
  }
  .xfer-trow {
    grid-template-columns: auto minmax(0, 1fr) 24px;
    grid-template-areas:
      "pill route go"
      "when count go";
    row-gap: var(--space-1);
    padding: var(--space-3) var(--space-4);
  }
  .xfer-trow > :nth-child(1) {
    grid-area: pill;
  }
  .xfer-trow > :nth-child(2) {
    grid-area: route;
  }
  .xfer-trow > :nth-child(3) {
    grid-area: when;
    font-size: var(--font-size-sm);
  }
  .xfer-trow > :nth-child(4) {
    grid-area: count;
    font-size: var(--font-size-sm);
  }
  .xfer-trow > :nth-child(5) {
    grid-area: go;
  }
  .xfer-ln {
    flex-wrap: wrap;
  }
  .xfer-stepper {
    grid-template-columns: 48px 64px 48px;
  }
  .xfer-step,
  .xfer-stepper output {
    height: 48px;
  }
  .xfer-whole,
  .xfer-remove {
    height: 48px;
  }
}

/* ---------- CASH1-S1-U1 (docs/build-briefs/CASH1-S1-U1-drawer-screens.md): cash drawer sheet. Ported from
   design/mockups/cash1-cash-and-drawers.html; every value is a token. ---------- */
/* Denomination grid */
.cash-sum {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.cash-sum > div {
  flex: 1;
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
.cash-sum > div.big {
  flex: 1.4;
  background: var(--color-accent-subtle);
}
.cash-sum .l {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.cash-sum .v {
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}
.cash-sum .v.ok {
  color: var(--color-success-strong);
}
.cash-sum .v.bad {
  color: var(--color-danger-strong, var(--color-danger));
}
.cash-denoms {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--space-5);
  padding: var(--space-3) var(--space-4);
}
.cash-denoms h4 {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.cash-drow {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 56px;
  border-bottom: 1px solid var(--color-border);
}
.cash-drow:last-child {
  border-bottom: none;
}
.cash-dname {
  width: 64px;
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.cash-step {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  padding: 0;
}
.cash-step.plus {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.cash-step:disabled {
  opacity: 0.4;
}
.cash-qty {
  width: 40px;
  text-align: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.cash-qty.zero {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.cash-dline {
  margin-left: auto;
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
  min-width: 84px;
  text-align: right;
}

/* Menu / lists */
.cash-status {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cash-status b {
  color: var(--color-text-primary);
}
.cash-kick-failed {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.cash-kick-failed b {
  color: var(--color-danger-strong);
}
.cash-reasons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
}
.cash-reasons button {
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.cash-reasons button.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.cash-field-label {
  padding: var(--space-3) var(--space-4) 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.cash-amount-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: var(--space-3) var(--space-4) var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-md);
}
.cash-amount-row b {
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
}
.cash-amount-row .link {
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.cash-result {
  text-align: center;
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.cash-result-value {
  font-family: var(--font-family-display);
  font-size: 64px;
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
  color: var(--color-warning-text);
}
.cash-result-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cash-pairs {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-3);
  padding: 0 var(--space-4) var(--space-3);
}
.cash-pairs > div {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
.cash-pairs .l {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
}
.cash-pairs .v {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.cash-approve {
  margin: 0 var(--space-4) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-warning-subtle);
  box-shadow: inset 3px 0 0 var(--color-warning-strong);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}
.cash-approve button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-strong);
  background: var(--color-surface);
  color: var(--color-warning-strong);
  font: inherit;
  font-weight: var(--font-weight-bold);
}
.cash-sheet-foot {
  display: flex;
  gap: var(--space-3);
}
.cash-sheet-foot .btn-secondary {
  flex: 1;
}
.cash-sheet-foot .btn-primary,
.cash-sheet-foot .btn-pay {
  flex: 2;
}

.cash-sheet {
  max-width: 720px;
}
.cash-sheet-wide {
  max-width: 960px;
}
.cash-body {
  display: block;
}
.cash-error {
  margin: var(--space-2) var(--space-4) 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong, var(--color-danger));
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.cash-loading,
.cash-na {
  padding: var(--space-4);
  color: var(--color-text-secondary);
}
.cash-pairs-one {
  grid-template-columns: 1fr;
}
.cash-result-over,
.cash-result-short {
  color: var(--color-warning-text);
}
.cash-result-even {
  color: var(--color-success-strong);
}

/* CASH1-S3: the drawer menu tiles (mockup 5a) and the amount row as a button (mockup 5b). */
.cash-menu {
  padding: var(--space-3) var(--space-4);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.cash-menu button {
  min-height: 88px;
  text-align: left;
  padding: 0 var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-1);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.cash-menu button small {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-tertiary);
}
button.cash-amount-row {
  width: calc(100% - var(--space-4) * 2);
  min-height: var(--touch-target-comfortable);
  border: 0;
  font: inherit;
  font-size: var(--font-size-md);
  color: var(--color-text-primary);
  text-align: left;
}

/* ---------- CASH1-S2-U1 (docs/build-briefs/CASH1-S2-U1-pay-screens.md): the Card or Cash choice at Pay, the Cash screen and
   the Change due screen. Ported from design/mockups/cash1-cash-and-drawers.html; every value is a token. ---------- */
.pay-tender-row {
  margin: var(--space-2) var(--space-5) 0;
}
.pay-tender-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
}
.pay-tender-choices {
  display: flex;
  gap: var(--space-2);
}
.pay-tender-choices .btn-tip-preset {
  flex-direction: row;
}
.cash-tender-due {
  text-align: center;
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.cash-tender-due-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cash-tender-due-value {
  font-family: var(--font-family-display);
  font-size: 56px;
  font-weight: var(--font-weight-bold);
  line-height: 1.1;
}
.cash-tender-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
}
.cash-tender-opt {
  min-height: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.cash-tender-opt-sub {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.cash-tender-opt.selected {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.cash-tender-change-preview {
  text-align: center;
  padding: 0 var(--space-4) var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.cash-pairs-two {
  grid-template-columns: 1fr 1fr;
}
.cash-tender-nochange {
  font-size: 40px;
}
.svc-seg-two {
  grid-template-columns: repeat(2, minmax(88px, 128px));
}
.cash-body-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.cash-result-value.cash-tender-change-value {
  color: var(--color-success-text);
}

/* CASH1-S5: the three drawer figures under the Take cash switch. */
.cash-setting-rule {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--space-5) 0 var(--space-4);
}

.cash-setting-field {
  width: 160px;
}

.cash-setting-input {
  width: 100%;
  min-height: 44px;
  text-align: right;
}

.cash-setting-row {
  margin-bottom: var(--space-3);
}

/* ---------- RCPT1-S3: Awaiting tip ----------
   design/mockups/rcpt1-s3 (floor-rail-awaiting-tip, tip-sheet-entry, tip-sheet-over-cap, open-tabs-awaiting-tip). The sheet rides the
   Confirm Payment sheet's own two-column layout (.pay-confirm-sheet); only what that layout does not already give is here. Tokens only. */
#awaiting-tip-sheet {
  max-width: 960px;
}
.ticket-awaiting-badge {
  font-size: var(--font-size-sm);
}
#awaiting-tip-actions .awaiting-tip-reprint {
  min-height: var(--touch-target-comfortable);
  flex: 1;
}
#awaiting-tip-actions .btn-pay {
  flex: 2;
}
.awaiting-tip-live {
  margin-top: var(--space-2);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
.awaiting-tip-live.is-danger,
.awaiting-tip-cap.is-danger {
  color: var(--color-danger-strong);
}
.awaiting-tip-over {
  border: 1px solid var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-top: var(--space-3);
  margin-bottom: var(--space-2);
}
.awaiting-tip-over-title {
  font-weight: var(--font-weight-bold);
  color: var(--color-danger-strong);
  margin-bottom: var(--space-3);
}
.awaiting-tip-over-options {
  display: grid;
  gap: var(--space-2);
}
.awaiting-tip-over-options .btn-secondary {
  min-height: var(--touch-target-comfortable);
  text-align: left;
  padding: 0 var(--space-4);
}
.awaiting-tip-error {
  margin-top: var(--space-2);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.awaiting-tip-cap {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-top: var(--space-2);
}
#awaiting-tip-input {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}
#awaiting-tip-input.is-over {
  border-color: var(--color-danger-strong);
}
#awaiting-tip-none[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}

/* EXP1-S1: the Export menu every report screen shares (ui/src/exportMenu.ts). It opens under its trigger. */
.export-menu {
  position: relative;
  display: inline-flex;
}

.export-menu-list {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: var(--z-sticky);
  display: flex;
  flex-direction: column;
  min-width: 160px;
  margin-top: var(--space-1);
  padding: var(--space-1);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-2);
}

.export-menu-list[hidden] {
  display: none;
}

.export-menu-item {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-medium);
  text-align: left;
  cursor: pointer;
}

.export-menu-item:hover,
.export-menu-item:focus-visible {
  background: var(--color-surface-sunken);
}

/* ---------- INVIMP1: Import inventory (docs/build-briefs/INVIMP1-inventory-import.md; design/mockups/invimp1/) ----------
   A full-page overlay opened from the setup wizard's Drinks step and from Settings, Inventory items. Ported from the
   design boards onto this file's own tokens; no new colours. Admin surface, built touch-first: every target is at
   least --touch-target-min, nothing depends on hover, no keyboard rules. Every class here is ii- or inventory-import
   prefixed. Phone width (390px) stacks the column rows and the preview rows. */
.inventory-import {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text-primary);
  overflow: auto;
}
.inventory-import[hidden] {
  display: none;
}
.inventory-import button,
.inventory-import input,
.inventory-import label {
  font-family: inherit;
  font-size: inherit;
}
.ii-bar {
  flex: none;
  min-height: 56px;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-6);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  font-weight: var(--font-weight-semibold);
}
.ii-bar-sub {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-regular);
}
.ii-body {
  flex: 1;
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-wrap: anywhere;
}
.ii-sp {
  flex: 1;
}
.ii-grow {
  flex: 1;
}
.ii-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.ii-wrap {
  flex-wrap: wrap;
}
.ii-actions {
  padding-top: var(--space-3);
}
.ii-gap {
  margin-top: var(--space-4);
}
.ii-tert {
  color: var(--color-text-tertiary);
}
.ii-head {
  font-weight: var(--font-weight-semibold);
}
.ii-title {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}
.ii-rail {
  display: flex;
  gap: var(--space-2);
  padding: 0;
  margin: 0 0 var(--space-3);
  list-style: none;
}
.ii-step {
  flex: 1;
  min-width: 0;
  border-top: 6px solid var(--color-border);
  padding-top: var(--space-2);
  overflow-wrap: anywhere;
}
.ii-step-done {
  border-top-color: var(--color-accent-strong);
}
.ii-step[aria-current="step"] {
  font-weight: var(--font-weight-bold);
}
.ii-map-head {
  border: 0;
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}
.ii-app-field .ii-select {
  width: 100%;
}
.ii-samples,
.ii-opt-expects,
.ii-head {
  overflow-wrap: anywhere;
  white-space: normal;
}
.ii-vocabulary summary {
  min-height: var(--touch-target-min);
  padding-top: var(--space-2);
  cursor: pointer;
}
.ii-unmatched-values {
  max-height: 240px;
  overflow-y: auto;
  overflow-wrap: anywhere;
}
.ii-problem {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  color: var(--color-danger-strong);
  background: var(--color-danger-subtle);
  font-weight: var(--font-weight-semibold);
}
.ii-primary,
.ii-secondary,
.ii-ghost {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
}
.ii-primary {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  border: 0;
}
.ii-primary:disabled {
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  cursor: default;
}
.ii-primary-large {
  min-width: 240px;
  min-height: 56px;
}
.ii-secondary {
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
}
.ii-ghost {
  min-height: var(--touch-target-min);
  background: transparent;
  color: var(--color-accent-strong);
  border: 0;
}
.ii-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-5);
}
.ii-drop {
  /* DSC35-F3: anchors the visually hidden file input, so focusing it on tap does not scroll the page. */
  position: relative;
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-xl);
  background: var(--color-surface-sunken);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-8);
  text-align: center;
}
.ii-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.ii-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ii-tab {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 0;
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
.ii-tab[aria-pressed="true"] {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-semibold);
}
.ii-pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.ii-pill-new,
.ii-pill-ok {
  background: var(--color-success-subtle);
  color: var(--color-success-text);
}
.ii-pill-upd {
  background: var(--color-info-subtle);
  color: var(--color-info-text);
}
.ii-pill-err {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.ii-pill-req {
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
}
.ii-columns {
  padding-top: var(--space-2);
  padding-bottom: 0;
}
.ii-map {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 28px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
}
.ii-map > * {
  min-width: 0;
}
.ii-map:first-child {
  border-top: 0;
}
.ii-arrow {
  color: var(--color-text-tertiary);
  text-align: center;
}
.ii-samples {
  overflow-wrap: anywhere;
  white-space: normal;
}
.ii-select {
  min-height: 48px;
  width: 100%;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  padding: 0 var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  cursor: pointer;
  text-align: left;
}
.ii-select:has(.ii-opt-lines) {
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}
.ii-opt-lines {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  width: 100%;
}
.ii-opt-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.ii-opt-source {
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
  white-space: normal;
}
.ii-opt-expects {
  font-size: var(--font-size-sm);
}
.ii-read {
  grid-column: 1 / -1;
  font-size: var(--font-size-sm);
}
.ii-read-ok {
  color: var(--color-success-text);
}
.ii-read-bad {
  color: var(--color-danger-strong);
}
.ii-select-skip {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
}
.ii-select-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
}
.ii-scrim {
  position: fixed;
  inset: 0;
  z-index: 1001;
  background: var(--color-scrim);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-6) var(--space-4);
  overflow: auto;
}
.ii-picker {
  width: min(520px, 100%);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.ii-picker-title {
  margin: 0;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.ii-picker-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.ii-stats {
  gap: var(--space-3);
}
.ii-stat {
  flex: 1;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-4) var(--space-5);
}
.ii-stat b {
  display: block;
  font-size: var(--font-size-xl);
  line-height: 1.1;
}
.ii-stat span {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.ii-stat-g b {
  color: var(--color-success-text);
}
.ii-stat-b b {
  color: var(--color-info-text);
}
.ii-stat-r b {
  color: var(--color-danger-strong);
}
.ii-check {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 48px;
}
.ii-check input {
  width: 28px;
  height: 28px;
}
.ii-prows {
  padding: 0 var(--space-2);
}
.ii-prow {
  display: grid;
  grid-template-columns: minmax(0, 3fr) repeat(5, minmax(0, 1fr)) minmax(0, 2fr);
  align-items: center;
  border-top: 1px solid var(--color-border);
  min-height: 48px;
}
.ii-prow.ii-phead {
  border-top: 0;
  min-height: 36px;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.ii-pcell {
  padding: var(--space-2) var(--space-3);
  overflow-wrap: anywhere;
}
.ii-pmore {
  grid-column: 1 / -1;
  padding-top: 0;
  font-size: var(--font-size-sm);
}
.ii-empty {
  padding: var(--space-4) var(--space-3);
}
.ii-frow {
  display: grid;
  grid-template-columns: 64px minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}
.ii-frow.ii-phead {
  border-top: 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.ii-failed {
  margin-top: var(--space-3);
}
@media (max-width: 640px) {
  .ii-bar {
    padding: 0 var(--space-4);
  }
  .ii-body {
    padding: var(--space-4);
    gap: var(--space-3);
  }
  .ii-card {
    padding: var(--space-4);
  }
  .ii-drop {
    padding: var(--space-6) var(--space-4);
  }
  .ii-primary-large {
    min-width: 0;
    width: 100%;
  }
  .ii-map {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2);
  }
  .ii-arrow {
    display: none;
  }
  .ii-stat {
    padding: var(--space-3);
  }
  .ii-stat b {
    font-size: var(--font-size-lg);
  }
  .ii-prow.ii-phead {
    display: none;
  }
  .ii-prow {
    grid-template-columns: 1fr auto;
    padding: var(--space-2) 0;
  }
  .ii-prow .ii-pcell:nth-child(n + 2):nth-child(-n + 6) {
    display: none;
  }
  .ii-prow .ii-pstatus {
    grid-column: 2;
    grid-row: 1;
  }
}
body.inventory-import-open {
  overflow: hidden;
}
/* EXP1-S6: the Google Sheet item carries a short second line, and a failed sign-in a short note under the trigger. */
.export-menu-item-google {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding-block: var(--space-2);
}

.export-menu-item-sub {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
}

.export-menu-note {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: var(--z-sticky);
  min-width: 220px;
  margin: var(--space-1) 0 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
}

.export-menu-note[hidden] {
  display: none;
}

/* RCPT1-S7: Settings > Location > Receipt printers. */
.pr-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.pr-row-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}
.pr-steps {
  margin: 0;
  padding-left: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--font-size-md);
}
.pr-box {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.pr-url,
.pr-code {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
  user-select: all;
}
.pr-url {
  font-size: var(--font-size-md);
}
.pr-code {
  font-size: var(--font-size-lg);
  letter-spacing: 0.06em;
}
.pr-code-life {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
@media (max-width: 640px) {
  .tablets-row:has(.pr-row-actions) {
    flex-wrap: wrap;
  }
  .pr-row-actions {
    justify-content: flex-start;
    width: 100%;
  }
}
/* UX120 (docs/build-briefs/UX120-vendors-compact-collapsible-list.md): Settings, Vendors is one collapsed row per
   vendor (name, chips, price list value, chevron); the open editor is a grouped grid, two columns on a wide
   screen and one on a phone. Shipped spacing tokens only. */
.admin-vendor-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.admin-vendor-row {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  min-width: 0;
}
.admin-vendor-row[data-expanded="true"] {
  border-color: var(--color-border-strong);
}
.admin-vendor-summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  flex-wrap: wrap;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-4);
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.admin-vendor-summary-name {
  flex: 1 1 10rem;
  min-width: 10rem;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.admin-vendor-summary-chips {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.admin-vendor-off-chip {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-secondary);
}
.admin-vendor-summary-prices {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.admin-vendor-chevron {
  display: inline-flex;
  flex: none;
  margin-left: auto;
  transition: transform 120ms ease;
}
.admin-vendor-summary[aria-expanded="true"] .admin-vendor-chevron {
  transform: rotate(180deg);
}
.admin-vendor-editor {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.admin-vendor-editor[hidden] {
  display: none;
}
.admin-vendor-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3) var(--space-4);
}
.admin-vendor-head .admin-vendor-field--name {
  flex: 1 1 260px;
}
.admin-vendor-head .abc2go-row,
.admin-vendor-head .admin-vendor-active-row {
  flex: 0 1 auto;
  min-height: var(--touch-target-comfortable);
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  gap: var(--space-3);
}
.admin-vendor-head .abc2go-row--on {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.admin-vendor-head .abc2go-row--on .abc2go-row-help,
.admin-vendor-head .abc2go-row--on .admin-toggle-status {
  color: var(--color-success-strong);
}
.admin-vendor-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.admin-vendor-group-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.admin-vendor-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3) var(--space-4);
}
.admin-vendor-grid:empty,
.admin-vendor-wide:empty {
  display: none;
}
@media (min-width: 720px) {
  .admin-vendor-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.admin-vendor-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.admin-vendor-field .field-input,
.admin-vendor-field .field-input-affix {
  width: 100%;
  min-width: 0;
}
.admin-vendor-row .admin-vendor-field-label {
  margin-top: 0;
}
.admin-vendor-wide {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.admin-vendor-wide .pl-card-entry {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.admin-vendor-wide .pl-card-entry .admin-field-help {
  margin: 0;
}

/* ---------- UX121 (docs/build-briefs/UX121-floor-menu-filters.md): floor menu filters ----------
   The group sits to the right of the letters and never shrinks, so the letter strip is what swipes when the row
   is tight. */
.menu-filters {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: var(--space-2);
  padding: 0 var(--space-4) 0 var(--space-3);
  border-left: 1px solid var(--color-border);
  position: relative;
}
.menu-filter-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
  cursor: pointer;
}
.menu-filter-chip[aria-pressed="true"],
.menu-filter-chip.is-on {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.menu-filter-chip:focus-visible,
.menu-filter-base-clear:focus-visible,
.menu-filter-list button:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.menu-filter-caret {
  font-size: 11px;
  opacity: 0.7;
}
.menu-filter-base {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.menu-filter-base.has-base .menu-filter-base-button {
  padding-right: var(--space-2);
  border-radius: var(--radius-full) 0 0 var(--radius-full);
  border-right: 0;
}
.menu-filter-base-clear {
  width: var(--touch-target-min);
  min-height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-accent-strong);
  border-left: 0;
  border-radius: 0 var(--radius-full) var(--radius-full) 0;
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.menu-filter-base-clear[hidden],
.menu-filter-scrim[hidden],
.menu-filter-list[hidden] {
  display: none;
}
.menu-filter-scrim {
  position: fixed;
  inset: 0;
  z-index: 5;
}
.menu-filter-list {
  position: absolute;
  z-index: 6;
  top: calc(100% + 2px);
  right: 0;
  width: 316px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: var(--space-2);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-1);
}
.menu-filter-list button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text);
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.menu-filter-list button.is-all {
  grid-column: 1 / -1;
  border-bottom: 1px solid var(--color-border);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.menu-filter-list button[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-bold);
}
.menu-filter-count {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.menu-index-row:not(.is-searching) .menu-search {
  flex-basis: 190px;
}
.menu-filter-result {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-1);
}
.menu-filter-result-text {
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-medium);
}
.menu-filter-result button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 0;
  background: transparent;
  color: var(--color-accent-strong);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

/* ---------- INVCOUNT2-S2 (docs/build-briefs/INVCOUNT2-S2-count-table-screen.md): the table-based count screen ----------
   Layout and controls follow design/mockups/count-table-*.html in the app's own light theme. Every colour, space,
   radius and size is a token; nothing is tappable below --touch-target-min. No :hover rule carries meaning. */
.ct-root {
  position: fixed;
  inset: 0;
  z-index: var(--z-sheet);
  background: var(--color-bg);
  color: var(--color-text-primary);
  display: flex;
  flex-direction: column;
}
.ct-root[hidden] {
  display: none;
}
.ct-screen {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.ct-spacer {
  flex: 1;
}
.ct-top {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--touch-target-primary);
  padding: var(--space-2) var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.ct-exit {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-title {
  margin: 0;
  font-size: var(--font-size-xl);
}
.ct-progress {
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
}
.ct-progress strong {
  font-size: var(--font-size-lg);
  color: var(--color-text-primary);
}
.ct-bar {
  width: 200px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  overflow: hidden;
}
.ct-bar-wide {
  width: 240px;
}
.ct-bar-fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-success);
}
.ct-holder {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.ct-btn {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-btn-primary {
  background: var(--color-accent-strong);
  border-color: transparent;
  color: var(--color-text-on-accent);
}
.ct-btn-small {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
}
.ct-btn:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
  cursor: default;
}
.ct-icon-btn {
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
.ct-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4) 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-switch-knob {
  position: relative;
  width: 44px;
  height: 26px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
}
.ct-switch-knob::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--color-text-tertiary);
}
.ct-switch.is-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
  color: var(--color-accent-strong);
}
.ct-switch.is-on .ct-switch-knob {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
}
.ct-switch.is-on .ct-switch-knob::after {
  left: 20px;
  background: var(--color-text-on-accent);
}
.ct-switch:disabled {
  opacity: 0.6;
}
.ct-tabs {
  display: flex;
  overflow-x: auto;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
  padding: 0 var(--space-3);
}
.ct-tab {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-hairline);
  min-width: var(--touch-target-primary);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-1) var(--space-5);
  border: none;
  border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-tab-count {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
.ct-tab.is-active {
  border-bottom-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.ct-tools {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  flex-shrink: 0;
}
.ct-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-picker small {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.ct-segment {
  display: inline-flex;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
}
.ct-segment-btn {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: none;
  border-right: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-segment-btn:last-child {
  border-right: none;
}
.ct-segment-btn.is-active {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.ct-table {
  --ct-cols: 56px minmax(150px, 1.6fr) minmax(110px, 1fr) 84px 168px 168px 96px 72px 52px;
  flex: 1;
  min-height: 0;
  margin: 0 var(--space-5);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.ct-table.no-last {
  --ct-cols: 56px minmax(150px, 1.6fr) minmax(110px, 1fr) 168px 168px 96px 72px 52px;
}
.ct-review-table {
  --ct-cols: minmax(180px, 2fr) 130px 100px 100px 110px 96px;
}
.ct-head,
.ct-row,
.ct-review-row {
  display: grid;
  grid-template-columns: var(--ct-cols);
  align-items: center;
  column-gap: var(--space-2);
  padding: 0 var(--space-4);
}
.ct-head {
  min-height: var(--touch-target-min);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.ct-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.ct-row,
.ct-review-row {
  min-height: 68px;
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.ct-row.is-current {
  background: var(--color-accent-subtle);
  box-shadow: inset 4px 0 0 var(--color-accent-strong);
}
.ct-marker {
  display: grid;
  place-items: center;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border-radius: var(--radius-full);
  border: 2px solid var(--color-border-strong);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-bold);
}
.ct-marker.is-counted {
  border-color: var(--color-success);
  background: var(--color-success-subtle);
}
.ct-item {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ct-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.ct-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ct-size {
  display: flex;
  flex-direction: column;
  font-size: var(--font-size-sm);
}
.ct-size small {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.ct-last {
  text-align: right;
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
  padding-right: var(--space-2);
}
.ct-stepper {
  display: flex;
  align-items: stretch;
  height: var(--touch-target-comfortable);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
}
.ct-stepper-na {
  align-items: center;
  justify-content: center;
  border-style: dashed;
  background: var(--color-surface-sunken);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.ct-step {
  flex: none;
  width: 52px;
  border: none;
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.ct-step-plus {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.ct-step:disabled {
  opacity: 0.45;
  cursor: default;
}
.ct-step-value {
  flex: 1;
  display: grid;
  place-items: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.ct-part {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-part small {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
.ct-part-value {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.ct-part-none {
  border-style: dashed;
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
}
.ct-part:disabled {
  opacity: 0.45;
  cursor: default;
}
.ct-total {
  text-align: right;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.ct-empty {
  margin: 0;
  padding: var(--space-8);
  text-align: center;
  color: var(--color-text-tertiary);
}
.ct-foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--touch-target-primary);
  padding: var(--space-3) var(--space-5);
  flex-shrink: 0;
}
.ct-foot-label {
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}
.ct-foot-label strong {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
}
.ct-popover-layer {
  position: fixed;
  inset: 0;
  z-index: 5;
}
.ct-popover-backdrop {
  position: absolute;
  inset: 0;
  border: none;
  background: transparent;
}
.ct-popover {
  position: absolute;
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.ct-menu {
  display: flex;
  flex-direction: column;
  min-width: 220px;
  max-height: 60vh;
  overflow-y: auto;
}
.ct-menu-item {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  text-align: left;
  cursor: pointer;
}
.ct-menu-item.is-active {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.ct-part-title {
  margin: 0 0 var(--space-2);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.ct-part-grid {
  display: grid;
  grid-template-columns: repeat(5, var(--touch-target-comfortable));
  gap: var(--space-2);
}
.ct-part-option {
  min-height: var(--touch-target-comfortable);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.ct-part-option.is-active {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.ct-sheet-layer {
  position: fixed;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.ct-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
}
.ct-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: 90vh;
  padding: var(--space-6) var(--space-6) var(--space-8);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.ct-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.ct-sheet-heading {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  flex-wrap: wrap;
  min-width: 0;
}
.ct-sheet-title {
  margin: 0;
  font-size: var(--font-size-xl);
  overflow-wrap: anywhere;
}
.ct-sheet-sub {
  font-size: var(--font-size-base);
  color: var(--color-text-secondary);
}
.ct-sheet-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 0;
  overflow-y: auto;
}
.ct-sheet-label {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.ct-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ct-chip {
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.ct-chip.is-active {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.ct-chip:disabled {
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
  background: var(--color-surface-sunken);
  cursor: default;
}
.ct-sheet-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}
.ct-find {
  display: flex;
  gap: var(--space-3);
  min-height: 0;
  height: min(520px, 62vh);
}
.ct-find-list {
  flex: 1;
  overflow-y: auto;
}
.ct-find-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  min-height: var(--touch-target-comfortable);
  padding: var(--space-2) var(--space-3);
  border: none;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-primary);
  text-align: left;
  cursor: pointer;
}
.ct-find-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: var(--font-size-md);
}
.ct-find-text small,
.ct-find-section {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ct-az {
  display: flex;
  flex-direction: column;
  flex: none;
  width: var(--touch-target-comfortable);
  overflow-y: auto;
}
.ct-az-letter {
  flex: none;
  min-height: var(--touch-target-min);
  border: none;
  background: transparent;
  color: var(--color-accent-strong);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.ct-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) 0;
  flex-shrink: 0;
}
.ct-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.ct-card-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ct-card-value {
  font-size: var(--font-size-2xl);
}
.ct-card.is-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
}
.ct-card.is-warn .ct-card-value {
  color: var(--color-warning-strong);
}
.ct-card.is-short .ct-card-value,
.ct-diff.is-short {
  color: var(--color-danger-strong);
}
.ct-card.is-over .ct-card-value,
.ct-diff.is-over {
  color: var(--color-info-text);
}
.ct-figure {
  text-align: right;
  font-size: var(--font-size-md);
}
.ct-diff {
  font-weight: var(--font-weight-bold);
}
.ct-pill-status {
  justify-self: start;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.ct-pill-status.is-counted {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.ct-pill-status.is-not-counted {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.ct-report-line {
  display: flex;
  justify-content: space-between;
  margin: 0;
  font-size: var(--font-size-md);
}
.ct-report-list {
  overflow-y: auto;
  max-height: 40vh;
}
.ct-report-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--touch-target-min);
  align-items: center;
  border-bottom: 1px solid var(--color-border);
}
.ct-report-row span {
  color: var(--color-text-secondary);
}
.ct-review-table .ct-head span:nth-child(n + 3):nth-child(-n + 5) {
  text-align: right;
}
.ct-table:not(.no-last):not(.ct-review-table) .ct-head span:nth-child(4),
.ct-table:not(.ct-review-table) .ct-head span:nth-last-child(2) {
  text-align: right;
}

/* B6 (docs/build-briefs/B6-barcode-receive.md; design/mockups/b6-scan-receive.html): the scan overlay on the receiving
   screen. Built on the shared tokens only, so it takes the app's own theme. Every control is 44px or taller, nothing
   depends on hover, and there is no text field. */
.b6-scan-open {
  margin-left: auto;
  min-height: var(--touch-target-min);
}
.b6-layer {
  position: fixed;
  inset: 0;
  z-index: var(--z-sheet);
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text-primary);
}
.b6-layer[hidden],
.b6-layer [hidden] {
  display: none !important;
}
.b6-top {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: 0 var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
.b6-back {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 0;
  background: none;
  color: var(--color-accent-strong);
  font: inherit;
  font-weight: var(--font-weight-semibold);
}
.b6-title {
  margin: 0;
  font-size: var(--font-size-lg);
}
.b6-spacer {
  flex: 1;
}
.b6-main {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
}
.b6-card {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.b6-card-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.b6-card-title {
  flex: 1;
  margin: 0;
  font-size: var(--font-size-md);
}
.b6-tag {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.b6-tag:empty {
  display: none;
}
.b6-tag-ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.b6-tag-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.b6-cam {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #16140f;
}
.b6-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.b6-cam-top {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  right: var(--space-4);
  display: flex;
  gap: var(--space-3);
  align-items: center;
}
.b6-pill {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
  font: inherit;
  font-weight: var(--font-weight-semibold);
}
.b6-pill-on {
  background: #fff;
  color: #16140f;
}
.b6-frame {
  position: relative;
  width: min(520px, 80%);
  aspect-ratio: 2 / 1;
  pointer-events: none;
}
.b6-frame i {
  position: absolute;
  width: 44px;
  height: 44px;
  border: 5px solid #fff;
  opacity: 0.95;
}
.b6-frame i:nth-child(1) {
  left: 0;
  top: 0;
  border-right: 0;
  border-bottom: 0;
  border-radius: 14px 0 0 0;
}
.b6-frame i:nth-child(2) {
  right: 0;
  top: 0;
  border-left: 0;
  border-bottom: 0;
  border-radius: 0 14px 0 0;
}
.b6-frame i:nth-child(3) {
  left: 0;
  bottom: 0;
  border-right: 0;
  border-top: 0;
  border-radius: 0 0 0 14px;
}
.b6-frame i:nth-child(4) {
  right: 0;
  bottom: 0;
  border-left: 0;
  border-top: 0;
  border-radius: 0 0 14px 0;
}
.b6-line {
  position: absolute;
  left: 14px;
  right: 14px;
  top: 50%;
  height: 3px;
  background: #fff;
  opacity: 0.7;
}
.b6-frame[data-state="hit"] i {
  border-color: #6fe39a;
}
.b6-frame[data-state="hit"] .b6-line {
  background: #6fe39a;
  opacity: 1;
  box-shadow: 0 0 14px #6fe39a;
}
.b6-frame[data-state="miss"] i {
  border-color: #ff7b72;
}
.b6-frame[data-state="miss"] .b6-line {
  background: #ff7b72;
  opacity: 1;
  box-shadow: 0 0 14px #ff7b72;
}
.b6-hint {
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  text-align: center;
  color: #fff;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.b6-hint:empty {
  display: none;
}
.b6-found {
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
}
.b6-found-name {
  flex: 1;
  min-width: 0;
}
.b6-found-name b {
  display: block;
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.b6-found-name > span {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.b6-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.b6-chips-pad {
  margin: 0;
  padding: 0 var(--space-5) var(--space-3);
}
.b6-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
}
.b6-chip[aria-pressed="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.b6-chip:disabled {
  opacity: 0.45;
}
.b6-step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.b6-step button {
  width: 72px;
  height: 72px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: 38px;
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.b6-step button.b6-plus {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.b6-q {
  min-width: 88px;
  text-align: center;
  font-size: 44px;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.b6-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-3);
}
.b6-na {
  display: flex;
  height: 100%;
  align-items: center;
  justify-content: center;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.b6-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 68px;
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.b6-row[data-fresh="true"] {
  background: var(--color-accent-subtle);
  border-radius: var(--radius-md);
}
.b6-row-text {
  flex: 1;
  min-width: 0;
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.b6-row-text small {
  display: block;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
}
.b6-row-error {
  color: var(--color-danger-strong);
}
.b6-row-n {
  min-width: 44px;
  text-align: right;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.b6-mini {
  display: flex;
  gap: var(--space-2);
}
.b6-mini button {
  width: 52px;
  height: 52px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: 28px;
  font-weight: var(--font-weight-bold);
}
.b6-foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.b6-sum {
  flex: 1;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.b6-foot .btn-primary:disabled {
  opacity: 0.4;
}
.b6-denied,
.b6-review {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-8);
  text-align: center;
}
.b6-denied-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: var(--radius-full);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.b6-denied-title {
  margin: 0;
  font-size: var(--font-size-xl);
}
.b6-review-label {
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.b6-acts {
  display: flex;
  gap: var(--space-3);
  width: min(560px, 100%);
}
.b6-acts .btn-primary,
.b6-acts .btn-secondary {
  flex: 1;
  justify-content: center;
  min-height: var(--touch-target-comfortable);
}
.b6-backdrop {
  position: absolute;
  inset: 0;
  z-index: var(--z-sheet);
  background: var(--color-scrim);
}
.b6-sheet {
  position: absolute;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
}
.b6-sheet-center {
  left: 50%;
  top: 50%;
  width: min(620px, 94%);
  padding: var(--space-6);
  transform: translate(-50%, -50%);
}
.b6-sheet-center h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xl);
}
.b6-code {
  margin: var(--space-3) 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-family: ui-monospace, monospace;
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.b6-code-old {
  margin-bottom: 0;
  text-decoration: line-through;
  color: var(--color-text-secondary);
}
.b6-replace-item {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.b6-sheet-pick {
  left: 50%;
  top: 24px;
  bottom: 24px;
  width: min(700px, 96%);
  transform: translateX(-50%);
}
.b6-sheet-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.b6-sheet-head h3 {
  flex: 1;
  margin: 0;
  font-size: var(--font-size-lg);
  overflow-wrap: anywhere;
}
.b6-az {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 var(--space-5) var(--space-2);
}
.b6-az button {
  min-width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-bold);
}
.b6-az button[aria-pressed="true"] {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.b6-plist {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-3);
}
.b6-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 60px;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
}
.b6-option b {
  flex: 1;
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}
.b6-option small {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
}
.b6-option[aria-pressed="true"] {
  background: var(--color-accent-subtle);
}
.b6-option[aria-pressed="true"] b {
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-bold);
}
.b6-sheet-error {
  margin: 0;
  padding: 0 var(--space-5) var(--space-2);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
.b6-sfoot {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
}
.b6-sfoot .btn-primary {
  width: 100%;
}
.b6-sfoot .btn-primary:disabled {
  opacity: 0.4;
}

/* UX125: Popular Now is one row of five equal columns at every width; a long name wraps inside its tile. */
.menu-section--popular .tile-grid {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.ct-table:not(.no-last):not(.ct-review-table) .ct-head span:nth-child(4) {
  padding-right: var(--space-3);
}

/* ---------- PO7-S5: scan an invoice to receive (docs/build-briefs/PO7-S5-invoice-scan-receive.md) ----------
   Built on the design tokens only, from design/mockups/invoice-scan-receive.html. Touch only: every control is a plain
   button of 44px or more, there is no hover rule and no text field. The two sheets sit on .receive-scan-backdrop, which
   is not a .scrim on purpose (check:chrome-ratchet refuses a new scrim copy). */
.receiving-header-main {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}
.receiving-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.receive-scan-root {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  height: calc(100dvh - var(--topbar-height));
  box-sizing: border-box;
}
.receive-scan-root[hidden] {
  display: none;
}
.receive-scan-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
}
.receive-scan-back {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 0;
  background: none;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  cursor: pointer;
}
.receive-scan-back-chevron {
  font-size: var(--font-size-xl);
  margin-right: var(--space-1);
}
.receive-scan-title {
  margin: 0;
  font-size: var(--font-size-lg);
  letter-spacing: -0.01em;
}
.receive-scan-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--space-4);
  flex: 1;
  min-height: 0;
}
.receive-scan-left,
.receive-scan-right {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}
.receive-scan-card {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.receive-scan-card-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.receive-scan-card-title {
  flex: 1;
  margin: 0;
  font-size: var(--font-size-md);
}
.receive-scan-tag {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.receive-scan-tag.is-ok {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.receive-scan-tag.is-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.receive-scan-ico {
  width: 22px;
  height: 22px;
  flex: none;
}
.receive-scan-na {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  text-align: center;
}
.receive-scan-notice {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
}
.receive-scan-foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex: none;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.receive-scan-foot[hidden] {
  display: none;
}
.receive-scan-wide {
  flex: 1;
}
.receive-scan-big {
  display: flex;
  flex-direction: column;
  flex: 1;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-5);
}
.receive-scan-big .btn-primary,
.receive-scan-big .btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-5);
  font-size: var(--font-size-lg);
}
.receive-scan-big .btn-primary {
  min-height: var(--touch-target-primary);
}
.receive-scan-vendor-name {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
/* Lines */
.receive-scan-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-3);
}
.receive-scan-simple-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-1) var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.receive-scan-simple-row .receive-scan-line-name {
  flex: 1;
}
.receive-scan-row-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 70px 196px 132px;
  align-items: center;
  gap: var(--space-3);
  min-height: 68px;
  padding: var(--space-1) var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.receive-scan-row-grid.is-head {
  min-height: 34px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  border-bottom: 1px solid var(--color-border-strong);
}
.receive-scan-row-grid.is-center,
.receive-scan-row-grid .is-center {
  text-align: center;
}
.receive-scan-row-grid.is-unmatched {
  grid-template-columns: minmax(0, 1fr) 332px;
  background: var(--color-surface-sunken);
}
.receive-scan-row-grid.is-low {
  box-shadow: inset 4px 0 0 var(--color-warning-strong);
}
.receive-scan-row-grid.is-skipped {
  opacity: 0.7;
}
.receive-scan-line-cell {
  min-width: 0;
}
.receive-scan-line-name {
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.receive-scan-line-sub {
  display: block;
  margin-top: 2px;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}
.receive-scan-mark {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 3px var(--space-3) 0 0;
  color: var(--color-warning-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.receive-scan-mark .receive-scan-ico {
  width: 14px;
  height: 14px;
}
.receive-scan-line-error {
  margin-top: 3px;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.receive-scan-skipped {
  margin-top: 3px;
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.receive-scan-ordered {
  text-align: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.receive-scan-stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}
.receive-scan-step {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: 28px;
  font-weight: var(--font-weight-bold);
  line-height: 1;
  cursor: pointer;
}
.receive-scan-step:disabled {
  color: var(--color-text-tertiary);
  border-color: var(--color-border);
}
.receive-scan-qty-wrap {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  min-width: 52px;
}
.receive-scan-qty {
  min-width: 52px;
  padding: 2px 0;
  text-align: center;
  border-radius: var(--radius-md);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.receive-scan-packed {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  line-height: 1.2;
  text-align: center;
}
.receive-scan-row-grid.is-low .receive-scan-qty {
  background: var(--color-warning-subtle);
  outline: 2px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.receive-scan-row-grid.is-done .receive-scan-qty {
  color: var(--color-text-primary);
}
.receive-scan-accept {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 52px;
  border-radius: var(--radius-md);
  border: 2px solid var(--color-accent-strong);
  background: var(--color-surface);
  color: var(--color-accent-strong);
  font: inherit;
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.receive-scan-accept:disabled {
  opacity: 0.4;
}
.receive-scan-row-grid.is-done .receive-scan-accept {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
  opacity: 1;
}
.receive-scan-line-actions {
  display: flex;
  gap: var(--space-2);
}
.receive-scan-line-actions .btn-primary,
.receive-scan-line-actions .btn-secondary {
  flex: 1;
  height: 52px;
  padding: 0 var(--space-3);
}
.receive-scan-sum {
  flex: 1;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.receive-scan-sum b {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
}
.receive-scan-blocker {
  margin-left: var(--space-3);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-bold);
}
/* Invoice card */
.receive-scan-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.receive-scan-field span {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.receive-scan-field b {
  font-variant-numeric: tabular-nums;
  text-align: right;
  overflow-wrap: anywhere;
}
.receive-scan-field.is-low b {
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--color-warning-subtle);
  outline: 2px solid var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}
.receive-scan-duplicate {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-bold);
}
.receive-scan-paper {
  display: flex;
  flex: 1;
  min-height: 0;
  margin: var(--space-3);
  overflow: hidden;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
.receive-scan-preview-canvas {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.receive-scan-preview {
  display: flex;
  flex: 1;
  min-height: 0;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
  background: var(--color-surface-sunken);
}
/* Camera */
.receive-scan-cam {
  position: relative;
  display: flex;
  flex: 1;
  min-height: 0;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #16140f;
}
.receive-scan-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #16140f;
}
.receive-scan-corners {
  position: absolute;
  inset: var(--space-5) 140px var(--space-5) var(--space-5);
  pointer-events: none;
}
.receive-scan-corners i {
  position: absolute;
  width: 44px;
  height: 44px;
  border: 5px solid #fff;
}
.receive-scan-cam.is-on .receive-scan-corners i {
  border-color: #6fe39a;
}
.receive-scan-corners i:nth-child(1) {
  left: 0;
  top: 0;
  border-right: 0;
  border-bottom: 0;
  border-radius: 14px 0 0 0;
}
.receive-scan-corners i:nth-child(2) {
  right: 0;
  top: 0;
  border-left: 0;
  border-bottom: 0;
  border-radius: 0 14px 0 0;
}
.receive-scan-corners i:nth-child(3) {
  left: 0;
  bottom: 0;
  border-right: 0;
  border-top: 0;
  border-radius: 0 0 0 14px;
}
.receive-scan-corners i:nth-child(4) {
  right: 0;
  bottom: 0;
  border-left: 0;
  border-top: 0;
  border-radius: 0 0 14px 0;
}
.receive-scan-shutter {
  position: absolute;
  right: var(--space-5);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  padding: 0;
  border-radius: 50%;
  border: 6px solid #fff;
  background: transparent;
  cursor: pointer;
}
.receive-scan-shutter i {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: #fff;
}
.receive-scan-shutter:disabled {
  opacity: 0.4;
}
.receive-scan-flip {
  position: absolute;
  left: var(--space-4);
  top: var(--space-4);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.receive-scan-blocked {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
  width: min(360px, 90%);
  color: #fff;
  text-align: center;
}
.receive-scan-blocked h3 {
  margin: 0;
  font-size: var(--font-size-xl);
}
/* Pages */
.receive-scan-pages {
  display: grid;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  grid-template-columns: 1fr 1fr;
  align-content: start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
}
.receive-scan-page {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.receive-scan-page.is-selected {
  outline: 3px solid var(--color-accent-strong);
}
.receive-scan-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 150px;
  margin: var(--space-2);
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  cursor: pointer;
  overflow: hidden;
}
.receive-scan-thumb-canvas {
  max-width: 100%;
  max-height: 100%;
}
.receive-scan-page-cap {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-2) var(--space-2);
  font-weight: var(--font-weight-semibold);
}
.receive-scan-page-cap .btn-secondary {
  height: var(--touch-target-min);
  margin-left: auto;
}
.receive-scan-add {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 150px;
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-accent-strong);
  font: inherit;
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
/* Reading */
.receive-scan-reading {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-5);
  text-align: center;
}
.receive-scan-reading h3 {
  margin: 0;
  font-size: var(--font-size-xl);
}
.receive-scan-cancel {
  min-width: 200px;
}
.receive-scan-spinner {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 7px solid var(--color-surface-sunken);
  border-top-color: var(--color-accent-strong);
  animation: receive-scan-spin 1s linear infinite;
}
@keyframes receive-scan-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .receive-scan-spinner {
    animation: none;
  }
}
.receive-scan-skeletons {
  padding-top: var(--space-4);
}
.receive-scan-skeleton {
  height: 44px;
  margin: 0 var(--space-4) var(--space-2);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
/* Done */
.receive-scan-done {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  text-align: center;
}
.receive-scan-done h3 {
  margin: 0;
  font-size: var(--font-size-xl);
}
.receive-scan-okc {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.receive-scan-okc .receive-scan-ico {
  width: 46px;
  height: 46px;
}
.receive-scan-stats {
  display: flex;
  gap: var(--space-3);
  width: 100%;
}
.receive-scan-stat {
  flex: 1;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.receive-scan-stat b {
  display: block;
  font-size: 32px;
  font-variant-numeric: tabular-nums;
}
.receive-scan-stat span {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
/* Sheets */
.receive-scan-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-scrim);
}
.receive-scan-backdrop[hidden] {
  display: none;
}
.receive-scan-sheet {
  width: 700px;
  max-width: calc(100vw - 32px);
  height: min(720px, calc(100dvh - 48px));
  max-height: none;
  border-radius: var(--radius-xl);
}
.receive-scan-sheet.is-center {
  width: 520px;
  height: auto;
  padding: var(--space-6);
  gap: var(--space-4);
}
.receive-scan-sheet-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
  padding: var(--space-4) var(--space-5) var(--space-2);
}
.is-center .receive-scan-sheet-head {
  padding: 0;
}
.receive-scan-sheet-title {
  flex: 1;
  margin: 0;
  font-size: var(--font-size-lg);
}
.is-center > .receive-scan-sheet-title {
  font-size: var(--font-size-xl);
}
.receive-scan-source {
  flex: none;
  margin: 0 var(--space-5) var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-family: var(--font-family-mono, ui-monospace, monospace);
  font-size: var(--font-size-md);
  overflow-wrap: anywhere;
}
.receive-scan-chips,
.receive-scan-letters {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0 var(--space-5) var(--space-2);
}
.receive-scan-chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.receive-scan-chip.is-on {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.receive-scan-letter {
  min-width: var(--touch-target-min);
  height: var(--touch-target-min);
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.receive-scan-letter.is-on {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.receive-scan-plist {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  overflow-y: auto;
  padding: 0 var(--space-3);
}
.receive-scan-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
  width: 100%;
  min-height: 60px;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.receive-scan-row b {
  flex: 1;
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}
.receive-scan-row small {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
}
.receive-scan-row.is-selected {
  background: var(--color-accent-subtle);
}
.receive-scan-row.is-selected b {
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-bold);
}
.receive-scan-sheet-foot {
  display: flex;
  flex: none;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
}
.is-center > .receive-scan-sheet-foot {
  padding: 0;
  border-top: 0;
}
.receive-scan-sheet-foot > * {
  flex: 1;
}

/* Barcode scanning inside the invoice scan (B6's decoder): a small camera, a frame and the line just ticked. */
.receive-scan-spacer {
  flex: 1;
}
.receive-scan-mini {
  position: relative;
  flex: none;
  height: 230px;
  overflow: hidden;
  background: #16140f;
}
.receive-scan-mini .receive-scan-video {
  width: 100%;
  height: 100%;
}
.receive-scan-mini-frame {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 300px;
  max-width: 80%;
  height: 130px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.receive-scan-mini-frame i {
  position: absolute;
  width: 30px;
  height: 30px;
  border: 4px solid #6fe39a;
}
.receive-scan-mini-frame i:nth-child(1) {
  left: 0;
  top: 0;
  border-right: 0;
  border-bottom: 0;
}
.receive-scan-mini-frame i:nth-child(2) {
  right: 0;
  top: 0;
  border-left: 0;
  border-bottom: 0;
}
.receive-scan-mini-frame i:nth-child(3) {
  left: 0;
  bottom: 0;
  border-right: 0;
  border-top: 0;
}
.receive-scan-mini-frame i:nth-child(4) {
  right: 0;
  bottom: 0;
  border-left: 0;
  border-top: 0;
}
.receive-scan-hit {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success-subtle-border);
  color: var(--color-success-strong);
}
.receive-scan-hit b {
  flex: 1;
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.receive-scan-hit-n {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.receive-scan-blocked.is-light {
  align-self: center;
  margin: var(--space-6) auto;
  color: var(--color-text-primary);
}

/* ---------- AUTOPAR1 (docs/build-briefs/AUTOPAR1-automatic-par-levels.md; DEC-410): Automatic par levels ----------
   Ported from design/mockups/autopar-1..6 onto this file's own tokens. Admin surface: every control is at least
   var(--touch-target-min) tall. The Items and Par levels tabs live inside #admin-group-panel-inventory; while the Par
   levels tab shows, everything else in the group (the item list, the count areas, the cards) steps aside by CSS, so the
   permission gates on those panels (their own [hidden]) are never touched. */
#admin-group-panel-inventory[data-autopar-tab="levels"]
  > :not(#admin-autopar-tabs):not(#admin-autopar-levels):not(.ap-scrim) {
  display: none;
}
.ap-tabs {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.ap-tab {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
}
.ap-tab[aria-selected="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.ap-card {
  margin-bottom: var(--space-4);
}
.ap-switch-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 64px;
}
.ap-switch-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
.ap-sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ap-na {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.ap-switch-state {
  min-width: 28px;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}
.ap-switch {
  position: relative;
  flex: none;
  width: 64px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
}
.ap-switch-knob {
  position: absolute;
  top: 7px;
  left: 4px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
}
.ap-switch[aria-checked="true"] {
  background: var(--color-success-strong);
}
.ap-switch[aria-checked="true"] .ap-switch-knob {
  transform: translateX(26px);
}
.ap-switch:disabled {
  opacity: 0.55;
}
.ap-list {
  display: flex;
  flex-direction: column;
}
.ap-dim {
  opacity: 0.55;
}
.ap-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 72px;
  border-top: 1px solid var(--color-border);
}
.ap-row:first-child {
  border-top: 0;
}
.ap-row-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
.ap-row-title {
  flex: 1;
  font-weight: var(--font-weight-semibold);
}
.ap-row-text .ap-row-title {
  flex: none;
}
.ap-row-button {
  flex: none;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  font-size: var(--font-size-sm);
}
.ap-stepper {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.ap-step-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--touch-target-comfortable);
  height: var(--touch-target-comfortable);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.ap-step-button:disabled {
  opacity: 0.4;
}
.ap-step-value {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: 112px;
  height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-variant-numeric: tabular-nums;
}
.ap-step-value b {
  font-size: var(--font-size-xl);
}
.ap-step-value span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ap-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.ap-spacer {
  flex: 1;
}
.ap-vendor-chips,
.ap-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ap-chip {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.ap-chip[aria-pressed="true"],
.ap-chip[aria-checked="true"] {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.ap-chip-day {
  min-width: 56px;
  padding: 0;
}
.ap-updated {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-strong);
}
.ap-table-card {
  padding-top: var(--space-4);
  padding-bottom: var(--space-2);
}
.ap-table-head,
.ap-table-row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) 84px 92px 150px 230px 64px;
  gap: var(--space-3);
  align-items: center;
}
.ap-table-head {
  padding-bottom: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.ap-table-row {
  min-height: 68px;
  border-top: 1px solid var(--color-border);
}
.ap-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.ap-item {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ap-item-name {
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.ap-rate b {
  font-variant-numeric: tabular-nums;
}
.ap-rate span {
  margin-left: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.ap-auto {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-variant-numeric: tabular-nums;
}
.ap-auto b {
  font-size: var(--font-size-lg);
}
.ap-would {
  font-size: var(--font-size-xs);
}
.ap-delta {
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.ap-delta-up {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.ap-delta-down {
  background: var(--color-info-subtle);
  color: var(--color-info);
}
.ap-delta-same {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.ap-delta-held {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.ap-accept {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}
.ap-lock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  justify-self: end;
  width: var(--touch-target-min);
  height: var(--touch-target-min);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-tertiary);
}
.ap-lock-on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-strong);
  color: var(--color-accent-strong);
}
.ap-lock:disabled {
  opacity: 0.55;
}
.ap-locked .ap-auto b {
  color: var(--color-text-tertiary);
}
.ap-empty {
  margin: 0;
  padding: var(--space-4) 0;
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-semibold);
}
.ap-scrim {
  align-items: center;
}
.ap-sheet {
  max-width: 600px;
  border-radius: var(--radius-lg);
}
.ap-sheet-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  overflow-y: auto;
}
.ap-kicker {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
}
.ap-kicker:empty {
  display: none;
}
.ap-label {
  margin-top: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
}
.ap-pace-amount {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.ap-seg {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.ap-seg-button {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
}
.ap-seg-button[aria-checked="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.ap-covers {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.ap-covers b {
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
}
.ap-covers span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.ap-sheet-actions .btn-primary,
.ap-sheet-actions .btn-secondary {
  min-height: var(--touch-target-min);
}
.ap-sheet-actions {
  justify-content: flex-end;
}
.ap-sheet-actions > * {
  flex: none;
  width: auto;
  padding: 0 var(--space-5);
}
.ap-sheet-actions > :first-child {
  margin-right: auto;
}
.ap-sheet-actions .btn-danger {
  background: var(--color-danger-strong);
  border-color: var(--color-danger-strong);
  color: var(--color-text-on-accent);
}
.ap-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.ap-option {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 72px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: inherit;
  font: inherit;
  text-align: left;
}
.ap-option-on {
  border-color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
  box-shadow: inset 0 0 0 1px var(--color-accent-strong);
}
.ap-option-dot {
  flex: none;
  width: 24px;
  height: 24px;
  border: 2px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
}
.ap-option-on .ap-option-dot {
  border-color: var(--color-accent-strong);
  box-shadow: inset 0 0 0 5px var(--color-accent-strong);
}
.ap-option-text {
  display: flex;
  flex-direction: column;
}
.ap-option-title {
  font-weight: var(--font-weight-semibold);
}
.admin-vendor-pace-chip {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.admin-vendor-pace-chip--set {
  background: var(--color-info-subtle);
  border: 1px solid var(--color-info-subtle-border);
  color: var(--color-info);
}
.admin-vendor-pace-chip--day {
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-secondary);
}
.admin-vendor-pace-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.admin-vendor-pace-actions {
  display: inline-flex;
  gap: var(--space-2);
}

/* ---------- UX131: the Customers table scrolls sideways inside its card (docs/build-briefs/UX131-customers-table-ipad.md) ----------
   Same pattern as .tblwrap and .stw-tblwrap: a wrapper with overflow-x. Each column keeps a minimum
   width that fits its content, chips never wrap, so nothing overlaps at iPad portrait. */
.so-table-scroll {
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
  /* UIFIX1 (SF-5): a table wider than its card shows a fade at the edge it continues past, so nothing is cut off silently. */
  background:
    linear-gradient(to right, var(--color-surface) 30%, transparent) left center / 32px 100%
      no-repeat local,
    linear-gradient(to left, var(--color-surface) 30%, transparent) right center / 32px 100%
      no-repeat local,
    linear-gradient(to right, rgb(0 0 0 / 0.18), transparent) left center / 14px 100% no-repeat
      scroll,
    linear-gradient(to left, rgb(0 0 0 / 0.18), transparent) right center / 14px 100% no-repeat
      scroll;
}

.so-table.so-customers {
  table-layout: auto;
  min-width: 940px;
}

.so-table.so-customers th,
.so-table.so-customers td {
  width: auto;
  max-width: none;
  padding: var(--space-3) var(--space-3);
  overflow-wrap: normal;
}

.so-table.so-customers th {
  white-space: nowrap;
}

.so-table.so-customers th:nth-child(1),
.so-table.so-customers td:nth-child(1) {
  min-width: 170px;
  overflow-wrap: anywhere;
}

.so-table.so-customers th:nth-child(2),
.so-table.so-customers td:nth-child(2) {
  min-width: 120px;
}

.so-table.so-customers th:nth-child(3),
.so-table.so-customers td:nth-child(3) {
  min-width: 140px;
  overflow-wrap: anywhere;
}

.so-table.so-customers th:nth-child(4),
.so-table.so-customers td:nth-child(4) {
  min-width: 100px;
}

/* TEN8-F5: Locations is column 5 (a plain number), so Status and Legal profile are 6 and 7, Added 8, Support 9. */
.so-table.so-customers th:nth-child(5),
.so-table.so-customers td:nth-child(5) {
  min-width: 100px;
  white-space: nowrap;
}

.so-table.so-customers th:nth-child(6),
.so-table.so-customers td:nth-child(6),
.so-table.so-customers th:nth-child(7),
.so-table.so-customers td:nth-child(7) {
  min-width: 170px;
}

.so-table.so-customers th:nth-child(8),
.so-table.so-customers td:nth-child(8) {
  min-width: 110px;
  white-space: nowrap;
}

.so-table.so-customers th:nth-child(9),
.so-table.so-customers td:nth-child(9) {
  min-width: 160px;
}

.so-table.so-customers .so-badge {
  white-space: nowrap;
}

.so-table.so-customers .so-row-button {
  min-height: max(44px, var(--touch-target-min));
  white-space: nowrap;
}

/* ---------- UX132 (docs/build-briefs/UX132-ipad-floor-layout.md): the ring screen on an iPad ----------
   The menu pane is about 700px wide beside the ticket rail on an iPad. Search and the filters share the first row;
   the letters wrap onto the row under them, so every letter shows with no hidden sideways scroll. */
.menu-index-row {
  flex-wrap: wrap;
  row-gap: 0;
  padding-top: var(--space-2);
}
.menu-index-row .menu-search,
.menu-index-row:not(.is-searching) .menu-search {
  flex: 1 1 190px;
  min-width: 0;
}
.menu-index-row .menu-filters {
  flex: 0 0 auto;
  margin-left: auto;
  border-left: 0;
  padding: 0 var(--space-4) 0 0;
}
.menu-index-row .alphabet-strip {
  order: 3;
  flex: 1 1 100%;
  flex-wrap: wrap;
  height: auto;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-5) var(--space-1);
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}
.menu-section {
  margin-bottom: var(--space-5);
}

/* A tile is as tall as its content, and a name wraps to three lines at most. */
.tile {
  min-height: 0;
  padding: var(--space-3) var(--space-4);
}
.tile-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* The Recipe pill shares the price row only where the tile is wide enough for both. Narrower, it sits on its own line
   under the price, so the full price always shows. */
.tile-wrapper {
  container-type: inline-size;
}
@container (max-width: 215px) {
  .tile-wrapper--recipe-visible .tile {
    padding-bottom: calc(var(--space-12) + var(--space-1));
  }
  .tile-wrapper--recipe-visible .tile-price {
    padding-right: 0;
  }
  .tile-wrapper--recipe-visible .tile-recipe-button {
    right: auto;
    left: var(--space-4);
  }
}

/* Popular Now: one row. Five columns when they fit at the minimum tile width, otherwise the row scrolls sideways;
   a tile is never squeezed and never wraps onto a second row. */
.menu-section--popular .tile-grid {
  display: grid;
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(150px, 1fr);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: var(--space-1);
}

/* Open tabs: a ticket name that wraps to two lines keeps room above and below inside its card. */
#open-tabs-screen .tab-card {
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}

/* Split equally: Cancel and Start split share the footer row at the same height, so Start split is a full target
   and never sits small under Cancel. */
#split-setup-sheet .sheet-footer {
  display: flex;
  gap: var(--space-3);
}
#split-setup-sheet .sheet-footer > button {
  flex: 1 1 0;
  min-width: 0;
}

/* Pay: the client save row keeps a gap under the Card and Cash choices when they stack. */
#pay-save-client-row {
  margin-top: var(--space-3);
}

/* 86 list: the category chips wrap onto more rows, so every one is on screen with no hidden sideways scroll. */
.stock86-chips {
  flex-wrap: wrap;
  overflow-x: visible;
  mask-image: none;
}

/* ---------- ONBW1-S1 welcome link (DEC-416; design/mockups/onboarding-wizard/b0-1-welcome, b0-3-pin) ---------- */
/* The first screens a new owner sees on the device. Touch only: every control is 56px or larger, nothing depends on
   hover. Built for iPad landscape 1180x820 and portrait 820x1180 (and the mini, 1133x744). */

#welcome-screen {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--color-bg);
  color: var(--color-text-primary);
}

#welcome-screen[hidden] {
  display: none;
}

.welcome-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.welcome-top {
  flex: none;
  height: 64px;
  display: flex;
  align-items: center;
  padding: 0 32px;
  background: var(--color-brand-brown);
  color: var(--color-brand-cream);
  border-bottom: 3px solid var(--color-brand-red);
}

.welcome-brand {
  font-weight: 800;
  font-size: var(--font-size-md);
}

.welcome-brand small {
  margin-left: 10px;
  font-weight: 500;
  font-size: var(--font-size-sm);
  color: var(--color-brand-cream-muted);
}

.welcome-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 28px 48px 0;
}

.welcome-col {
  width: 100%;
  max-width: 820px;
}

.welcome-heading {
  margin: 0;
  font-weight: 800;
  font-size: var(--font-size-2xl);
  line-height: 1.15;
}

.welcome-hint {
  margin: 10px 0 0;
  font-family: var(--font-family-accent);
  font-style: var(--font-style-accent);
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}

.welcome-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 36px;
}

.welcome-stack-pin {
  gap: 28px;
  margin-top: 24px;
}

.welcome-card {
  padding: 32px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: var(--shadow-2);
}

.welcome-sum {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-md);
}

.welcome-sum:first-child {
  border-top: 0;
}

.welcome-sum b {
  font-weight: 800;
  text-align: right;
  overflow-wrap: anywhere;
}

.welcome-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 24px;
  border-radius: var(--radius-lg);
  background: var(--color-success-subtle);
  border: 1.5px solid var(--color-success-subtle-border);
  color: var(--color-success-text);
  font-weight: 700;
  font-size: var(--font-size-md);
}

.welcome-check {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-success);
  color: #fff;
  font-weight: 800;
}

.welcome-dots {
  display: flex;
  gap: 16px;
  justify-content: center;
}

.welcome-dots i {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2.5px solid var(--color-border-strong);
}

.welcome-dots i.filled {
  background: var(--color-text-primary);
  border-color: var(--color-text-primary);
}

.welcome-pad {
  display: grid;
  grid-template-columns: repeat(3, 96px);
  gap: 12px;
  justify-content: center;
}

.welcome-key {
  height: 80px;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  box-shadow: var(--shadow-1);
  font-size: 30px;
  font-weight: 700;
  color: var(--color-text-primary);
  touch-action: manipulation;
}

.welcome-key-fn {
  background: var(--color-surface-sunken);
  font-size: var(--font-size-md);
}

.welcome-error {
  margin: 0;
  min-height: 1.4em;
  text-align: center;
  color: var(--color-danger-text, var(--color-text-primary));
  font-weight: 700;
}

.welcome-foot {
  flex: none;
  height: 96px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 32px;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -6px 18px rgba(70, 30, 13, 0.07);
}

.welcome-note {
  flex: 1;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.welcome-primary,
.welcome-secondary {
  min-height: 64px;
  padding: 0 32px;
  border-radius: var(--radius-lg);
  font-weight: 700;
  font-size: var(--font-size-md);
  touch-action: manipulation;
}

.welcome-primary {
  min-width: 260px;
  border: 1.5px solid var(--color-accent-strong);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  box-shadow: var(--shadow-2);
}

.welcome-primary.off,
.welcome-primary:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
  box-shadow: none;
}

.welcome-secondary {
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
}

/* ONBW1-S3: footer buttons never wrap their words; the tax rows keep their name column. */
.setup-wizard-footer .ow-btn {
  white-space: nowrap;
  padding: 0 var(--space-6);
}
.setup-wizard-footer .ow-btn-primary {
  min-width: 200px;
}
.setup-wizard-footer .setup-wizard-reason {
  min-width: 0;
}
.ow-trow-name {
  flex: 1 1 150px;
}
.ow-trow .ow-stepper {
  flex: none;
}
.ow-trow .ow-btn-quiet {
  min-height: 56px;
  padding: 0 var(--space-3);
  font-size: var(--font-size-base);
}
.ow-trow .ow-stepper {
  gap: var(--space-2);
}
.ow-trow .ow-stepval {
  min-width: 96px;
}

/* ONBW1-S4 (docs/build-briefs/ONBW1-S4-owner-console-steps.md; DEC-416; design/mockups/onboarding-wizard/so-1-type
   to so-5-plan): the Onboard flow, one question group per screen. Built on the console's own tokens. */
.so-wizard {
  max-width: 720px;
}

.so-wizard-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.so-wizard-head .so-link {
  min-height: var(--touch-target-min);
}

.so-wizard-count {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.so-progress {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-5);
  padding: 0;
  list-style: none;
}

.so-progress-step {
  padding-top: var(--space-1);
  border-top: 6px solid var(--color-border);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.so-progress-step.is-current {
  border-top-color: var(--color-accent);
  color: var(--color-accent-strong);
}

.so-progress-step.is-done {
  border-top-color: var(--color-success);
  color: var(--color-success-strong);
}

.so-wizard-title {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}

.so-wizard-title:focus {
  outline: none;
}

.so-step[hidden] {
  display: none;
}

.so-step {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.so-wizard .field-input {
  min-height: 56px;
}

.so-wizard .admin-field {
  margin-bottom: 0;
}

.so-wizard .admin-error:empty {
  display: none;
}

.so-choice-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.so-choice {
  display: flex;
}

.so-choice-card {
  display: flex;
  flex: 1;
  align-items: center;
  gap: var(--space-4);
  min-height: 88px;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  text-align: left;
}

.so-choice-mark {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
}

.so-choice-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.so-choice-name {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
}

.so-choice-note {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
}

.so-same-name {
  margin-top: var(--space-2);
  min-height: var(--touch-target-min);
}

.so-advanced {
  margin-top: var(--space-2);
}

.so-advanced[open] > .so-legal-summary {
  margin-bottom: var(--space-3);
}

/* The page title already names the group, so its legend is read aloud but not drawn twice. */
.so-wizard .so-legal-legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.so-wizard .so-legal-group {
  margin: 0;
  padding: 0;
  border: 0;
}

.so-wizard-footer {
  position: sticky;
  bottom: 0;
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-3) 0;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

.so-wizard-footer .btn-primary {
  margin-left: auto;
  min-width: 200px;
}

.so-wizard-footer .btn-primary,
.so-wizard-footer .btn-secondary {
  min-height: 56px;
}

.so-choice-card,
.so-choice-card * {
  text-transform: none;
  letter-spacing: normal;
}

.so-wizard-head .so-link {
  margin: 0;
  text-align: left;
}

/* PAY2-S8 (docs/build-briefs/PAY2-S8-royalty-adjustments-disputes-views-exports.md): the location's Royalty charges panel
   under the Royalty statement, and the franchisor's dispute and resolve forms. Tables scroll sideways inside their own
   section so an iPad never scrolls the page; every control is at least the touch minimum tall. */
.rc-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.rc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.rc-title,
.rc-section-title {
  margin: 0;
}

.rc-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.rc-carried {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.rc-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  overflow-x: auto;
}

.rc-table {
  width: 100%;
  border-collapse: collapse;
}

.rc-table th,
.rc-table td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
  vertical-align: middle;
}

.rc-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.rc-na {
  margin: 0;
  color: var(--color-text-tertiary);
}

.rc-dispute-button,
.rc-form .btn-primary,
.rc-form .btn-secondary {
  min-height: 44px;
}

.rc-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-width: 480px;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.rc-form .field-input {
  min-height: 44px;
}

.rc-credit {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.rc-credit[hidden] {
  display: none;
}

/* PAY2-S9 (docs/build-briefs/PAY2-S9-royalty-one-view.md): the one monthly royalty table. It scrolls inside its card instead
   of crushing its columns; names break at spaces only, money, rate lines and the debit date never wrap, and Resolve keeps
   the touch minimum. The same classes draw the location's own row in Reports. */
.fr-table-scroll {
  overflow-x: auto;
}

.rm-table {
  min-width: 960px;
}

/* FRADFUND1: the Fund fee column's rate sits under the amount, small, never wrapped. */
.rm-table td.rm-num .rm-owner {
  white-space: nowrap;
}

.rm-table th,
.rm-table td {
  overflow-wrap: normal;
  padding-left: 3px;
  padding-right: 3px;
}

.rm-table th {
  letter-spacing: 0;
}

.rm-table th.rm-place,
.rm-table th:first-child {
  min-width: 112px;
  text-align: left;
}

.rm-table th.rm-place,
#admin-group-panel-reports .rm-table th.rm-place {
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  letter-spacing: normal;
  text-transform: none;
  white-space: normal;
}

/* The Export menu items of the royalty views read on one line each. */
#fr-monthly-section .export-menu-list,
.rc-actions .export-menu-list {
  width: max-content;
}

#fr-monthly-section .export-menu-item,
.rc-actions .export-menu-item {
  white-space: nowrap;
}

.rm-table td.rm-num,
.rm-table tfoot td.rm-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.rm-rate-line,
.rm-debit {
  white-space: nowrap;
}

.rm-debit {
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
}

.rm-dispute {
  white-space: nowrap;
}

.rm-dispute .rm-action {
  display: block;
  margin-top: var(--space-1);
}

.rm-owner {
  font-weight: var(--font-weight-regular, 400);
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.rm-action {
  min-height: var(--touch-target-min);
  white-space: nowrap;
  padding: 0 var(--space-4);
}

.rm-table tfoot th,
.rm-table tfoot td {
  border-top: 1px solid var(--color-border-strong);
  border-bottom: none;
  font-weight: var(--font-weight-semibold);
}

.rm-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0;
}

.rm-facts dt {
  color: var(--color-text-tertiary);
}

.rm-facts dd {
  margin: 0;
}

.rc-form .field-input {
  font-family: inherit;
}

/* TEN20: the franchise list's figures. Right aligned, tabular figures; the table keeps its own horizontal scroll if the columns
   outgrow the card, so the page never scrolls sideways. */
.fr-card:has(> .fr-table-scroll) {
  overflow: hidden;
}
.fr-table-scroll {
  overflow-x: auto;
  max-width: 100%;
}
.fr-table .fr-figure,
.fr-table .fr-figure-head,
.fr-table .fr-figure-group {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fr-table .fr-figure-group {
  border-left: 1px solid var(--color-border);
  text-align: center;
}
.fr-table .fr-figure-head:nth-child(odd) {
  border-left: 1px solid var(--color-border);
}
.fr-table td.fr-figure:nth-child(2n + 3) {
  border-left: 1px solid var(--color-border);
}

/* ---------- TEN17-F1 (docs/build-briefs/TEN17-F1-brand-logo.md): the franchise brand logo ----------
   The console top bar shows it beside the network name; the Brand section holds the upload block. Fixed heights and
   contain-fit so any shape of logo sits in the same box; colors come from the ordinary tokens. */
.fr-network-logo {
  height: 28px;
  width: auto;
  max-width: 160px;
  object-fit: contain;
  display: block;
}

.fr-network-logo[hidden],
.fr-logo-img[hidden] {
  display: none;
}

.fr-logo-block {
  margin-top: var(--space-4);
  display: grid;
  gap: var(--space-2);
  max-width: 460px;
}

.fr-logo-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.fr-logo-frame {
  width: 160px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  overflow: hidden;
}

.fr-logo-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

/* TEN17-F1: the franchise network's logo in the floor header's left group, shown only while the member has the
   brand color scheme applied. A fixed height, contain-fit, no interaction; the center lockup is untouched. */
.topbar-network-logo {
  height: 28px;
  width: auto;
  max-width: 120px;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
}

.topbar-network-logo[hidden] {
  display: none;
}

/* TEN17-F1: in iPad portrait the header's left column also holds the home button and the location name, so the logo
   gets a smaller cap there and never takes width from the name. */
@media (max-width: 900px) {
  .topbar-network-logo {
    max-width: 64px;
  }
}

/* TEN17-F5: the font dropdown beside Remove, and the purchased font upload row (desktop width, DEC-424). */
.fr-brand-font-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.fr-brand-select {
  flex: 1 1 auto;
  min-width: 0;
}

.fr-font-upload-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.fr-font-file-name {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
}

.fr-font-license {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0;
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
}

.fr-font-license input {
  width: var(--space-5);
  height: var(--space-5);
  margin: 0;
  accent-color: var(--color-accent-strong);
}
/* ---------- UX14-F2 (docs/build-briefs/UX14-F2-keyboard-safe-sheets.md) ----------
   ui/src/keyboardInset.ts writes --keyboard-occluded-height and
   --keyboard-visible-top from window.visualViewport (Safari on iPad shrinks
   only that, never the layout viewport). The scrim becomes exactly the visible
   area and the sheet is capped to it, so a sheet's body scrolls and its footer
   stays above the keyboard. With no keyboard both variables are 0px. */
.scrim,
.confirm-scrim {
  top: var(--keyboard-visible-top, 0px);
  bottom: var(--keyboard-occluded-height, 0px);
}
html.keyboard-up .scrim > .sheet,
html.keyboard-up .scrim > [id$="-sheet"],
html.keyboard-up .confirm-scrim > .confirm-dialog {
  max-height: 100%;
}

/* ---------- CRB1 (docs/build-briefs/CRB1-custom-report-builder-core.md; design/mockups/report-builder/03a and 03c) ----------
   The custom report builder, drawn inside the Reports body. Admin surface at 1440x900 (DEC-424): a laptop with a pointer
   and keyboard, so controls sit at 36px, not the floor's 44px. Every color, size and font reads a token. The theme is
   Snip & Sip Light unless the person has a theme of their own (main.ts configureReportsTheme). */
.cr {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.cr-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.cr-title {
  flex: 1;
  min-width: 0;
  max-width: 560px;
  height: 40px;
  padding: 0 var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}
.cr-title:hover:not(:disabled),
.cr-title:focus {
  border-color: var(--color-border-strong);
  background: var(--color-surface);
}
.cr-title::placeholder {
  color: var(--color-text-tertiary);
}
.cr-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.cr-btn-primary,
.cr-btn-quiet {
  height: 36px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.cr-btn-primary {
  border: 1px solid var(--color-accent-strong);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.cr-btn-primary:disabled {
  opacity: 0.6;
  cursor: default;
}
.cr-btn-quiet {
  border: 1px solid transparent;
  background: transparent;
  color: var(--color-text-secondary);
}
.cr-cols {
  display: grid;
  grid-template-columns: 240px 320px minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}
.cr-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.cr-label {
  font-size: 11px;
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-1);
}
.cr-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.cr-select,
.cr-input,
.cr-search {
  height: 36px;
  width: 100%;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
}
.cr-select:disabled,
.cr-input:disabled {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
}
.cr-add {
  border-style: dashed;
  color: var(--color-text-tertiary);
}
.cr-data-select {
  font-weight: var(--font-weight-semibold);
}
.cr-fields {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: var(--space-2);
}
.cr-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: 32px;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  text-align: left;
  cursor: pointer;
}
.cr-field:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.cr-field.on {
  background: var(--color-accent-subtle);
}
.cr-field:disabled {
  color: var(--color-text-tertiary);
  cursor: default;
}
.cr-field-kind {
  width: 20px;
  flex: none;
  text-align: center;
  font-size: 10px;
  font-weight: var(--font-weight-bold);
  color: var(--color-text-tertiary);
}
.cr-field.on .cr-field-kind {
  color: var(--color-accent-strong);
}
.cr-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 36px;
  padding: 0 var(--space-2) 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
}
.cr-row-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cr-agg {
  flex: none;
  width: 92px;
  height: 28px;
  border-color: transparent;
  background: transparent;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.cr-x {
  flex: none;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
.cr-x:hover:not(:disabled) {
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
}
.cr-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.cr-as-of-now {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--space-3);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  font-size: 13px;
}
.cr-pair-rows {
  grid-template-columns: auto 120px;
  align-items: center;
  justify-content: start;
}
.cr-pair-rows .cr-row-label {
  flex: none;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cr-filter {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.cr-filter-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.cr-filter-body {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.cr-op {
  flex: 1 1 110px;
  width: auto;
}
.cr-value {
  flex: 1 1 110px;
  width: auto;
  min-width: 0;
}
.cr-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.cr-card-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font-size: var(--font-size-base);
}
.cr-ran {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.cr-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.cr-table-wrap {
  overflow-x: auto;
}
.cr-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
/* The Reports panel sets its own table cells by id, right aligned and touch tall; the builder's table is a laptop grid. */
#admin-group-panel-reports .cr-table th {
  text-align: left;
  height: auto;
  font-size: 11px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  white-space: nowrap;
}
#admin-group-panel-reports .cr-table td {
  text-align: left;
  height: auto;
  padding: 9px var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: normal;
  white-space: normal;
  overflow-wrap: anywhere;
  min-width: 140px;
}
#admin-group-panel-reports .cr-table th.num,
#admin-group-panel-reports .cr-table td.num {
  text-align: right;
  min-width: 0;
  white-space: nowrap;
  font-family: var(--font-family-numeric);
  font-variant-numeric: tabular-nums lining-nums;
}
#admin-group-panel-reports .cr-table td.na {
  color: var(--color-text-tertiary);
}
#admin-group-panel-reports .cr-table tbody tr:last-child td {
  border-bottom: 0;
}
#admin-group-panel-reports .cr-table tfoot td {
  font-weight: var(--font-weight-bold);
  border-top: 1px solid var(--color-border-strong);
  border-bottom: 0;
}
.cr-empty {
  display: grid;
  place-items: center;
  min-height: 420px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-tertiary);
}
.cr-cut {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.cr-error {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-sm);
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
}
.cr-loading {
  color: var(--color-text-secondary);
}

/* ---------- CRB2 (docs/build-briefs/CRB2-custom-report-saved-reports.md; design/mockups/report-builder/01 and 04a) ----------
   The Reports home (the saved list with its All, Mine and Scheduled tabs) and a saved report, drawn in the same Reports body as
   the builder. Admin surface at 1440x900: 36px controls, tokens only, Snip & Sip Light unless the person has a theme of their own. */
.cr-btn-outline {
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-primary);
}
.cr-btn-outline:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.cr-visibility {
  width: auto;
  min-width: 110px;
}
.cr-home-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  justify-content: flex-end;
  min-height: 36px;
}
.cr-list-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  min-width: 0;
}
.cr-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.cr-tabs {
  display: flex;
  gap: var(--space-5);
}
.cr-tab {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  height: 40px;
  padding: 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.cr-tab.on {
  color: var(--color-text-primary);
  border-bottom-color: var(--color-accent-strong);
}
.cr-tab-count {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-tertiary);
}
.cr-list-search {
  width: 260px;
  margin-bottom: var(--space-2);
}
.cr-list-body {
  padding: 0 var(--space-4) var(--space-2);
}
.cr-list-empty {
  display: grid;
  place-items: center;
  min-height: 160px;
  color: var(--color-text-tertiary);
}
.cr-name-cell {
  white-space: nowrap;
}
.cr-name {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.cr-name:hover,
.cr-name:focus-visible {
  text-decoration: underline;
}
.cr-tag {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 1px var(--space-2);
  border-radius: 999px;
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.cr-back {
  align-self: flex-start;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  font-size: var(--font-size-sm);
  cursor: pointer;
}
.cr-back:hover {
  text-decoration: underline;
}
.cr-saved-head {
  align-items: flex-start;
}
.cr-saved-title {
  margin: 0;
  min-width: 0;
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
  color: var(--color-text-primary);
  overflow-wrap: anywhere;
}
.cr-saved .cr-actions {
  position: relative;
  flex: none;
}
.cr-more {
  padding: 0 var(--space-3);
}
.cr-menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  z-index: 5;
  min-width: 180px;
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-2);
}
.cr-menu-item {
  height: 36px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  text-align: left;
  cursor: pointer;
}
.cr-menu-item:hover,
.cr-menu-item:focus-visible {
  background: var(--color-surface-sunken);
}
.cr-confirm {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
}
.cr-version-row {
  max-width: 420px;
}

/* ---------- CRB5 (docs/build-briefs/CRB5-franchisor-custom-reports.md; design/mockups/report-builder/05) ----------
   The franchisor console's custom report builder. It reuses the cr-* rules above; this block adds the card in Snip & Sip Light
   (the theme rules are keyed on data-theme, set on the card by src/franchisorCustomReports.ts unless the console renders a
   saved brand), the Locations chip and the franchisee-then-location tree. Admin surface at 1440x900: 36px controls, tokens only. */
.fr-custom[data-theme] {
  background: var(--color-bg);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
}
.fr-custom .cr-cols {
  grid-template-columns: 220px 280px minmax(0, 1fr);
  gap: var(--space-4);
}
.cr-picker-wrap {
  position: relative;
}
.cr-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  height: 36px;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  cursor: pointer;
}
.cr-chip:disabled {
  color: var(--color-text-tertiary);
  background: var(--color-surface-sunken);
  cursor: default;
}
.cr-chip-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cr-chip-caret {
  color: var(--color-text-tertiary);
}
.cr-picker {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: 6;
  width: 360px;
  max-width: calc(100vw - var(--space-8));
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
}
.cr-picker-top {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.cr-picker-foot {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.cr-spacer {
  flex: 1;
}
.cr-tree {
  display: flex;
  flex-direction: column;
  max-height: 340px;
  min-height: 80px;
  overflow-y: auto;
  padding: var(--space-2);
}
.cr-tree-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 36px;
  padding-right: var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
}
.cr-tree-row:hover {
  background: var(--color-surface-sunken);
}
.cr-tree-franchisee .cr-tree-name {
  font-weight: var(--font-weight-semibold);
}
.cr-tree-location {
  padding-left: calc(var(--space-6) + var(--space-3));
}
.cr-tree-name {
  min-width: 0;
  overflow-wrap: anywhere;
}
.cr-tree-count {
  margin-left: auto;
  flex: none;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.cr-tree-caret {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-tertiary);
  font: inherit;
  cursor: pointer;
}
.cr-check {
  flex: none;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--color-accent-strong);
}
.cr-export-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* ---------- CRB3 (docs/build-briefs/CRB3-custom-report-sales-datasets-charts.md; design/mockups/report-builder/03a, 02b, 04a) ----------
   Charts, drawn as plain SVG by ui/src/reportChart.ts, and the compare columns of the table. Every color reads a theme token
   through the series palette below (accent first, then neutral steps of the theme's own text and border colors, so a chart
   never introduces a hue the theme did not choose; the semantic hues stay reserved for state), never a literal color. */
.cr-chart-card,
.cr-chart {
  --cr-series-0: var(--color-accent);
  --cr-series-1: var(--color-text-secondary);
  --cr-series-2: var(--color-border-strong);
  --cr-series-3: var(--color-accent-subtle-border);
  --cr-series-4: var(--color-accent-strong);
  --cr-series-5: var(--color-text-tertiary);
}
.cr-chart-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.cr-chart-na {
  min-height: 160px;
  align-items: center;
  justify-content: center;
  color: var(--color-text-tertiary);
}
.cr-chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.cr-chart-title {
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
}
.cr-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.cr-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.cr-sw {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
}
.cr-sw-0 {
  background: var(--cr-series-0);
}
.cr-sw-1 {
  background: var(--cr-series-1);
}
.cr-sw-2 {
  background: var(--cr-series-2);
}
.cr-sw-3 {
  background: var(--cr-series-3);
}
.cr-sw-4 {
  background: var(--cr-series-4);
}
.cr-sw-5 {
  background: var(--cr-series-5);
}
.cr-chart-svg {
  width: 100%;
  height: auto;
  display: block;
}
.cr-chart-svg text {
  font-family: var(--font-family-base);
  font-size: 12px;
  fill: var(--color-text-tertiary);
}
.cr-chart-svg .cr-chart-label {
  font-size: 12px;
  fill: var(--color-text-secondary);
}
.cr-chart-svg .cr-chart-value {
  font-size: 12px;
  font-weight: var(--font-weight-semibold);
  fill: var(--color-text-primary);
}
.cr-chart-svg .cr-chart-big {
  font-family: var(--font-family-display);
  font-size: 44px;
  font-weight: var(--font-weight-bold);
  fill: var(--color-text-primary);
}
.cr-chart-svg .cr-grid {
  stroke: var(--color-border);
  stroke-width: 1;
}
.cr-chart-svg .cr-axis {
  stroke: var(--color-border-strong);
  stroke-width: 1;
}
.cr-chart-svg .cr-line {
  fill: none;
}
.cr-chart-svg .cr-slice {
  stroke: var(--color-surface);
  stroke-width: 2;
}
.cr-fill-0 {
  fill: var(--cr-series-0);
}
.cr-fill-1 {
  fill: var(--cr-series-1);
}
.cr-fill-2 {
  fill: var(--cr-series-2);
}
.cr-fill-3 {
  fill: var(--cr-series-3);
}
.cr-fill-4 {
  fill: var(--cr-series-4);
}
.cr-fill-5 {
  fill: var(--cr-series-5);
}
.cr-stroke-0 {
  stroke: var(--cr-series-0);
}
.cr-stroke-1 {
  stroke: var(--cr-series-1);
}
.cr-stroke-2 {
  stroke: var(--cr-series-2);
}
.cr-stroke-3 {
  stroke: var(--cr-series-3);
}
.cr-stroke-4 {
  stroke: var(--cr-series-4);
}
.cr-stroke-5 {
  stroke: var(--cr-series-5);
}
.cr-showas {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
}
.cr-showas-btn {
  height: 52px;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.cr-showas-btn svg {
  width: 20px;
  height: 16px;
}
.cr-showas-btn[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.cr-showas-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
#admin-group-panel-reports .cr-table td.cr-cmp-prior {
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .cr-table td.cr-change-up {
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cr-table td.cr-change-down {
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
#admin-group-panel-reports .cr-table td.cr-change-flat,
#admin-group-panel-reports .cr-table td.cr-change-na {
  color: var(--color-text-tertiary);
}
.cr-pair-compare {
  grid-template-columns: auto minmax(0, 1fr);
}

/* TEN26: a franchisor customer's network time zone and the More menu (Unmark as franchisor) sit under the customer
   name instead of in a Franchise network card. Tokens only. */
.so-franchisor-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  margin: 0 0 var(--space-3);
}

.so-franchisor-controls .so-franchisor-zone {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
}

.so-franchisor-controls .so-franchisor-zone .admin-field {
  margin: 0;
  min-width: 320px;
}

.so-franchisor-controls .so-franchisor-zone .so-actions {
  margin: 0;
}

.so-more {
  min-width: 0;
}

.so-more > summary {
  list-style: none;
  cursor: pointer;
}

.so-more > summary::-webkit-details-marker {
  display: none;
}

.so-more[open] > .so-actions {
  margin: var(--space-2) 0 0;
}

.so-franchisor-controls #software-owner-franchisor-feedback {
  flex-basis: 100%;
}

.so-franchisor-controls #software-owner-franchisor-feedback:empty {
  display: none;
}

/* REC7-S4: one desktop recipe list. The tile owns origin, sharing and adoption. */
#admin-drink-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: start;
}
#admin-drink-list > .admin-drink-row,
#admin-drink-list > .admin-network-recipe-offer,
#admin-drink-list > .admin-recipe-legacy-tile {
  margin: 0;
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  min-width: 0;
  align-self: start;
}
#admin-drink-list > .admin-drink-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-4);
}
#admin-drink-list > .admin-network-recipe-offer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
}
#admin-drink-list .admin-network-offer-actions,
#admin-drink-list .admin-network-recipe-map {
  grid-column: 1 / -1;
}
/* RECUX2-F1: the franchisor's method on a location's saved drink; plain text, nothing in it is editable. */
.admin-recipe-method {
  margin: var(--space-3) 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
.admin-recipe-method-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-md);
}
.admin-recipe-method-fact {
  margin: 0 0 var(--space-1);
}
.admin-recipe-method-steps {
  margin: var(--space-2) 0;
  padding-left: var(--space-5);
}
/* RECUX2-F2: a franchisor Menu category heading in the location's drink list. */
.admin-drink-group-title {
  grid-column: 1 / -1;
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}
.admin-recipe-origin {
  margin-top: var(--space-2);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.admin-recipe-sharing-indicator {
  display: inline-block;
  margin: var(--space-3) var(--space-2) 0 0;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
}
.admin-recipe-sharing-open {
  justify-self: start;
}
.admin-recipe-form-tabs {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}
.admin-recipe-form-tabs [aria-selected="true"] {
  color: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
}
.admin-recipe-sharing-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
}
.admin-recipe-sharing-group {
  margin-bottom: var(--space-5);
}
.admin-recipe-sharing-group .admin-discount-check {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.admin-recipe-sharing-version {
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.admin-recipe-sharing-version p {
  margin: var(--space-3) 0;
}
@media (max-width: 1000px) {
  #admin-drink-list,
  .admin-recipe-sharing-columns {
    grid-template-columns: 1fr;
  }
}

/* MOD2-S1 item configuration uses full label targets. */
.addon-property-control {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  cursor: pointer;
}
.addon-property-control input {
  width: 20px;
  height: 20px;
  accent-color: var(--color-accent-strong);
}
#admin-item-addon-fields {
  display: grid;
  gap: 8px;
}
#admin-item-addon-fields[hidden],
#admin-item-addon-stock-fields[hidden] {
  display: none;
}

/* CUSTOMER1-S1: desktop customer navigation, using the supplied customer-detail map. */
.so-customer-tabs {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  border-bottom: 1px solid var(--color-border);
  margin-block: var(--space-4);
}
.so-customer-tabs [role="tab"] {
  flex: 0 0 auto;
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--color-text-secondary);
  font: inherit;
  cursor: pointer;
}
.so-customer-tabs [aria-selected="true"] {
  border-bottom-color: var(--color-accent);
  color: var(--color-text-primary);
  font-weight: 600;
}
.so-detail-grid > .so-customer-panel {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  align-items: start;
}
.so-customer-panel[hidden],
.so-customer-tabs [hidden],
.so-customer-save[hidden] {
  display: none;
}
.so-customer-panel > #software-owner-profile-form,
.so-customer-panel > #software-owner-customer-audit-view,
.so-customer-panel > #software-owner-franchisees-card {
  grid-column: 1 / -1;
}
.so-customer-save {
  margin-block: var(--space-3);
}
.so-customer-panel > .so-franchisor-controls {
  grid-column: 1 / -1;
}

.so-customer-panel .so-billing-details {
  grid-column: 1 / -1;
}

.cr-template-library {
  margin-top: 24px;
  padding: 24px;
}
.cr-template-row,
.cr-template-publisher {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.cr-template-row {
  padding: 12px 0;
}
.cr-template-spec {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr);
  gap: 12px;
}
.cr-template-spec dd {
  margin: 0;
  overflow-wrap: anywhere;
}
.cr-template-dialog {
  width: min(820px, calc(100vw - 64px));
  max-height: calc(100vh - 80px);
  overflow: auto;
  padding: 28px;
  border: 1px solid var(--color-border, #d6c5b3);
  border-radius: 16px;
  background: var(--color-surface, #fffdf8);
  color: var(--color-text-primary, #432818);
}
.cr-template-dialog label {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
}

/* CRB7: the desktop drafting panel reuses ordinary builder controls. */
.cr-ai-panel {
  margin: 12px 0;
  padding: 12px 16px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #d8d8d0);
  border-radius: 12px;
}
.cr-ai-panel[hidden] {
  display: none;
}
.cr-ai-panel h3 {
  margin: 0 0 8px;
}
.cr-ai-content {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.cr-ai-content p {
  flex-basis: 100%;
  margin: 4px 0;
}
.cr-ai-content textarea {
  width: 100%;
  min-height: 88px;
  resize: vertical;
}
.cr-ai-panel select {
  min-height: 44px;
  margin-bottom: 8px;
}

/* CRB10: personal metrics on the desktop Reports home. */
.cr-personal-tiles {
  margin: 16px 0;
}
.cr-tile-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 12px;
}
.cr-personal-tile {
  padding: 16px;
  border: 1px solid var(--color-border);
  border-radius: 12px;
  background: var(--color-surface);
  min-width: 0;
}
.cr-personal-tile p {
  margin: 8px 0;
  overflow-wrap: anywhere;
}
.cr-personal-tile .cr-tile-value {
  font-size: 1.7rem;
  font-variant-numeric: tabular-nums;
}
.cr-personal-tile .cr-actions {
  flex-wrap: wrap;
}

/* CRB11 scheduled delivery in saved reports. */
.cr-report-schedules {
  margin-top: 1.25rem;
}
.cr-schedule {
  border-bottom: 1px solid var(--color-border, #d8d8d8);
  padding: 0.75rem 0;
}
.cr-schedule-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(12rem, 1fr));
  gap: 0.8rem;
  max-width: 52rem;
}
.cr-schedule-form label {
  display: grid;
  gap: 0.3rem;
}
.cr-schedule-form fieldset {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.cr-schedule-form fieldset label {
  display: flex;
  align-items: center;
  gap: 0.3rem;
}
.cr-schedule-form h4,
.cr-schedule-form [role="status"] {
  grid-column: 1 / -1;
}

/* RCPT2-F6: current client receipt preference, within the existing receipt sheet. */
#client-receipt-email-editor {
  padding: var(--space-3) 0;
}
#client-receipt-email-value {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: var(--space-2) 0;
}
#client-receipt-email-save-choice {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
}
#client-receipt-email-keep {
  width: 1.25rem;
  height: 1.25rem;
}
#client-receipt-email-editor button {
  min-height: var(--touch-target-min);
}

/* DSC2-F1: the control stays below the full guest name in the scrolling rail. */
.guest-service-today {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-3);
}

.guest-service-today-toggle {
  min-height: var(--touch-target-min);
  width: 100%;
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: var(--space-2) var(--space-3);
}

.guest-service-today-toggle[aria-checked="true"] {
  background: var(--color-accent);
  color: var(--color-text-on-accent);
}

.guest-service-today-status {
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

/* PO15 is a visible draft-field switch saved with the item form. */
.stock-ordering-switch {
  appearance: none;
  width: 44px;
  height: 28px;
  margin: 8px 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 14px;
  background:
    radial-gradient(circle at 13px 50%, var(--color-text-secondary) 9px, transparent 10px),
    var(--color-surface-sunken);
  cursor: pointer;
  flex-shrink: 0;
}
.stock-ordering-switch:checked {
  background:
    radial-gradient(circle at 30px 50%, var(--color-surface) 9px, transparent 10px),
    var(--color-accent-strong);
}
.stock-ordering-switch:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.stock-ordering-switch ~ .admin-toggle-track {
  display: none;
}

/* UX137 reader selection stays outside the clipped topbar lane. */
.topbar-reader-trigger {
  min-height: 44px;
  cursor: pointer;
  font: inherit;
}
.topbar-terminal-ok[data-health="unknown"]::before {
  background: var(--color-text-tertiary);
}
.reader-dropdown {
  flex-direction: column;
  align-items: stretch;
  border-color: var(--color-border);
  width: min(340px, calc(100vw - 16px));
  max-height: min(480px, calc(100dvh - 100px));
  overflow-y: auto;
}
.reader-dropdown h2 {
  margin: 0;
  font-size: var(--font-size-md);
}
.reader-dropdown-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  width: 100%;
  min-height: 44px;
  padding: var(--space-2);
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  text-align: left;
  overflow-wrap: anywhere;
}
.reader-dropdown-status {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

/* CLI1: identification metadata remains inside the existing whole-result tap target. */
.add-guest-result-row .add-guest-result-phone {
  white-space: normal;
  overflow-wrap: anywhere;
}
.add-guest-result-row .add-guest-result-badges {
  flex-wrap: wrap;
  max-width: 150px;
}
.cli-duplicates-page {
  padding: var(--space-5);
  overflow: auto;
  min-height: 0;
}
.cli-duplicates-table-wrap {
  overflow-x: auto;
}
.cli-duplicates-table {
  width: 100%;
  border-collapse: collapse;
}
.cli-duplicates-table th,
.cli-duplicates-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  overflow-wrap: anywhere;
  max-width: 260px;
}

/* AI limits are dollar settings, separate from completed spend and pending requests. */
.cr-ai-settings-card {
  margin: var(--space-4) 0;
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.cr-ai-settings-card h3 {
  margin-top: 0;
}
.cr-ai-dollar-input {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-min);
  width: min(100%, 280px);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
}
.cr-ai-dollar-input input {
  min-width: 0;
  width: 100%;
  min-height: var(--touch-target-min);
  border: 0;
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
}
.cr-ai-settings-card button,
.cr-ai-settings-card select,
.cr-ai-cap-row button {
  min-height: var(--touch-target-min);
}
.cr-ai-enable-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.cr-ai-enable-switch {
  appearance: none;
  width: 44px;
  height: 28px;
  margin: 8px 0;
  flex-shrink: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 14px;
  background:
    radial-gradient(circle at 13px 50%, var(--color-text-secondary) 9px, transparent 10px),
    var(--color-surface-sunken);
  cursor: pointer;
}
.cr-ai-enable-switch:checked {
  background:
    radial-gradient(circle at 30px 50%, var(--color-surface) 9px, transparent 10px),
    var(--color-accent-strong);
}
.cr-ai-enable-switch:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.cr-ai-limit-reached {
  color: var(--color-warning-text);
}
.cr-ai-person-limits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-4);
}

/* CRB14: bounded source field lists and nested picker calculations. */
.cr-composite-fields {
  max-height: 16rem;
  overflow-y: auto;
  overflow-wrap: anywhere;
}
.cr-expression {
  border-left: 1px solid var(--color-border);
  padding-left: var(--space-2);
  min-width: 0;
}
.cr-expression .cr-section {
  min-width: 0;
}

/* TEN8-F1-S3: the approved desktop permit list and inline editor. */
.location-permits {
  margin-top: var(--space-4);
  min-width: 0;
}
.location-permits-heading,
.location-permits-actions,
.location-permits-number {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.location-permits-heading {
  justify-content: space-between;
}
.location-permits-records {
  overflow-x: auto;
}
.location-permits-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.location-permits-table th,
.location-permits-table td {
  padding: var(--space-3) var(--space-2);
  vertical-align: middle;
}
.location-permits-table th {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  border-bottom: 1px solid var(--color-border);
}
.location-permits-authority {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.location-permits-mask {
  flex: 1;
  white-space: nowrap;
}
.location-permits-editor {
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-3);
  padding-top: var(--space-4);
}
.location-permits-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
}
.location-permits-field {
  min-width: 0;
}
.location-permits-field label {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.location-permits-wide {
  grid-column: span 2;
}
.location-permits-number {
  min-height: 40px;
  flex-wrap: wrap;
}
.location-permits-actions {
  justify-content: flex-end;
  flex-wrap: wrap;
  padding: var(--space-4) 0;
}
.location-permits-actions .admin-error {
  flex: 1;
  margin: 0;
}
@media (max-width: 1100px) {
  .location-permits-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* FRAN1: existing console frame, a bounded editor and explicit definition/location tabs. */
.fr-definition-search {
  max-width: 400px;
  margin-bottom: 20px;
}
.fr-definition-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
}
.fr-definition-tabs [aria-pressed="true"] {
  color: var(--color-accent-strong);
  box-shadow: inset 0 -3px var(--color-accent-strong);
}
.fr-publish-sheet {
  max-width: 1010px;
  width: min(1010px, calc(100vw - 48px));
  max-height: calc(100dvh - 48px);
  display: flex;
  flex-direction: column;
}
.fr-publish-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.fr-definition-addon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 12px 0;
}
.fr-definition-addon .field-input {
  flex: 1;
  min-width: 150px;
}
.fr-definition-addon .admin-discount-check {
  flex: 0 0 auto;
}
#fr-recipe-addons h3 {
  margin-top: 24px;
}
.fr-pub-side {
  flex-wrap: wrap;
}
.fr-publish-pick {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.fr-definition-latest {
  max-height: 220px;
  overflow: auto;
  text-align: left;
}

.fr-definition-tabs {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-surface);
  padding-block: 8px;
}
.fr-publish-slot {
  grid-template-columns: 1.4fr 1fr 80px 80px 1fr auto;
}
.fr-publish-slot > :nth-child(1),
.fr-publish-slot > :nth-child(2) {
  grid-column: auto;
}

/* FRANBILL1: layout only, scoped to the franchisor Billing mount and selected theme. */
.fr-shell:has(#fr-ai-billing-section:not([hidden])) {
  max-width: none;
}
.fr-ai-billing-layout .cr-ai-billing {
  width: 100%;
  max-width: none;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.fr-ai-billing-layout .cr-ai-billing-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.fr-ai-billing-layout .cr-ai-billing-heading h3,
.fr-ai-billing-layout .cr-ai-billing-heading h4 {
  margin: 0;
  font-size: var(--font-size-lg);
}
.fr-ai-billing-layout .cr-ai-billing-toolbar {
  align-items: center;
  margin: 0;
}
.fr-ai-billing-layout .cr-ai-billing-month {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-sm);
}
.fr-ai-billing-layout .cr-ai-billing-month select {
  min-width: 230px;
  width: auto;
}
.fr-ai-billing-layout .cr-ai-usage-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-ai-billing-layout .cr-ai-usage-table {
  width: 100%;
  min-width: 1000px;
  table-layout: fixed;
}
.fr-ai-billing-layout .cr-ai-usage-table th,
.fr-ai-billing-layout .cr-ai-usage-table td {
  width: auto;
  padding: var(--space-4) var(--space-3);
  text-align: left;
  font-size: var(--font-size-sm);
  line-height: 1.45;
  vertical-align: top;
  overflow-wrap: break-word;
}
.fr-ai-billing-layout .cr-ai-usage-table th {
  text-transform: none;
  letter-spacing: normal;
  font-weight: var(--font-weight-semibold);
}
.fr-ai-billing-layout .cr-ai-usage-table thead th {
  background: var(--color-surface-sunken);
  vertical-align: bottom;
}
.fr-ai-billing-layout .cr-ai-usage-table .cr-ai-number,
.fr-ai-billing-layout .cr-ai-cap-used,
.fr-ai-billing-layout .cr-ai-cap-pending {
  text-align: right;
  white-space: nowrap;
  overflow-wrap: normal;
  font-variant-numeric: tabular-nums;
}
.fr-ai-billing-layout .cr-ai-usage-table thead .cr-ai-number {
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
}
.fr-ai-billing-layout .cr-ai-date,
.fr-ai-billing-layout .cr-ai-money {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fr-ai-billing-layout .cr-ai-limit-units {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-ai-billing-layout .cr-ai-usage-table .cr-ai-usage-empty {
  padding: var(--space-8) var(--space-4);
  text-align: center;
  color: var(--color-text-secondary);
}
.fr-ai-billing-layout .cr-ai-usage-table tfoot th,
.fr-ai-billing-layout .cr-ai-usage-table tfoot td {
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-semibold);
  border-bottom: 0;
}
/* FRBILL2: the Billing page's two sections, scoped to the franchisor Billing mount. */
.fr-ai-billing-layout .fb-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.fr-ai-billing-layout .fb-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.fr-ai-billing-layout .fb-section + .fb-section {
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border);
}
.fr-ai-billing-layout .fb-section-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.fr-ai-billing-layout .fb-title {
  margin: 0;
  font-size: var(--font-size-xl);
}
.fr-ai-billing-layout .fb-note,
.fr-ai-billing-layout .cr-ai-billing-note {
  margin: 0;
  max-width: 80ch;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  line-height: 1.45;
}
.fr-ai-billing-layout .cr-ai-billing-note {
  margin-bottom: var(--space-4);
}
.fr-ai-billing-layout .fb-body,
.fr-ai-billing-layout .fb-pay-slot {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}
.fr-ai-billing-layout .fb-pay-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}
.fr-ai-billing-layout .fb-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: 0;
}
.fr-ai-billing-layout .fb-fact dt {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.fr-ai-billing-layout .fb-fact dd {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.fr-ai-billing-layout .fb-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.fr-ai-billing-layout .fb-toolbar select {
  width: auto;
  min-width: 200px;
}
.fr-ai-billing-layout .fb-table {
  width: 100%;
  min-width: 760px;
}
.fr-ai-billing-layout .fb-table th,
.fr-ai-billing-layout .fb-table td {
  padding: var(--space-3);
  text-align: left;
  font-size: var(--font-size-sm);
  vertical-align: middle;
}
.fr-ai-billing-layout .fb-table .fb-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fr-ai-billing-layout .fb-table .fb-date {
  white-space: nowrap;
}
.fr-ai-billing-layout .fb-table .fb-empty {
  padding: var(--space-8) var(--space-4);
  text-align: center;
  color: var(--color-text-secondary);
}
.fr-ai-billing-layout .fb-table tfoot th,
.fr-ai-billing-layout .fb-table tfoot td {
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-semibold);
}
.fr-ai-billing-layout .fb-link {
  white-space: nowrap;
}
.rm-row-focus {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: -2px;
}
.fr-ai-billing-layout .cr-ai-billing-limits {
  margin-top: var(--space-8);
}
.fr-ai-billing-layout .cr-ai-billing-limits h4,
.fr-ai-billing-layout .cr-ai-billing-limits h5 {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-lg);
}
.fr-ai-billing-layout .cr-ai-cap-head,
.fr-ai-billing-layout .cr-ai-cap-row {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) 110px 110px 185px 90px;
  column-gap: var(--space-4);
  row-gap: var(--space-2);
  align-items: center;
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.fr-ai-billing-layout .cr-ai-cap-head {
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.fr-ai-billing-layout .cr-ai-cap-head > :nth-child(2),
.fr-ai-billing-layout .cr-ai-cap-head > :nth-child(3) {
  text-align: right;
}
.fr-ai-billing-layout .cr-ai-cap-name {
  min-width: 0;
  overflow-wrap: break-word;
  font-weight: var(--font-weight-semibold);
}
.fr-ai-billing-layout .cr-ai-cap-form {
  display: contents;
}
.fr-ai-billing-layout .cr-ai-cap-form .cr-ai-dollar-input,
.fr-ai-billing-layout .cr-ai-cap-readonly {
  grid-column: 4;
}
.fr-ai-billing-layout .cr-ai-cap-form .cr-ai-dollar-input {
  width: 100%;
  background: var(--color-surface);
}
.fr-ai-billing-layout .cr-ai-cap-form button {
  grid-column: 5;
}
.fr-ai-billing-layout .cr-ai-cap-status {
  grid-column: 4 / 6;
  font-size: var(--font-size-sm);
}
.fr-ai-billing-layout .cr-ai-cap-status:empty {
  display: none;
}
@media (max-width: 1100px) {
  .fr-ai-billing-layout .cr-ai-cap-head {
    display: none;
  }
  .fr-ai-billing-layout .cr-ai-cap-row {
    grid-template-columns: minmax(140px, 1fr) minmax(120px, 185px) 90px;
  }
  .fr-ai-billing-layout .cr-ai-cap-name {
    grid-column: 1 / -1;
  }
  .fr-ai-billing-layout .cr-ai-cap-form .cr-ai-dollar-input,
  .fr-ai-billing-layout .cr-ai-cap-readonly {
    grid-column: 2;
  }
  .fr-ai-billing-layout .cr-ai-cap-form button {
    grid-column: 3;
  }
  .fr-ai-billing-layout .cr-ai-cap-status {
    grid-column: 2 / 4;
  }
}

/* TEN8-F1-S4: customer-scoped legal document collection using the selected console theme. */
.so-customer-panel.so-documents > * {
  grid-column: 1 / -1;
}
.so-documents > .so-status:empty {
  display: none;
}
.so-documents-entity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  font-weight: var(--font-weight-semibold);
}
.so-documents-entity select {
  width: min(100%, 400px);
}
.so-documents-heading,
.so-documents-actions,
.so-documents-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.so-documents-heading {
  justify-content: space-between;
}
.so-documents-heading h3,
.so-documents-heading h4 {
  margin: 0;
}
.so-document-chain {
  margin-bottom: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}
.so-document-current,
.so-document-history-row {
  padding: var(--space-5);
}
.so-document-chain p {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  overflow-wrap: break-word;
}
.so-document-acceptance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.so-document-acceptance p {
  flex-basis: 100%;
}
.so-document-history {
  padding: 0 var(--space-5) var(--space-4);
}
.so-document-history summary {
  min-height: var(--touch-target-min);
  padding-block: var(--space-3);
  color: var(--color-accent-strong);
  cursor: pointer;
}
.so-document-history-row {
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}
.so-documents-scrim {
  align-items: center;
}
.so-documents-dialog {
  width: min(790px, calc(100vw - 48px));
  max-width: 790px;
  max-height: calc(100dvh - 48px);
  border-radius: var(--radius-xl);
  display: flex;
  flex-direction: column;
  padding: var(--space-5);
  gap: var(--space-4);
}
.so-documents-editor {
  overflow-y: auto;
  min-height: 0;
}
.so-document-facts {
  display: grid;
  grid-template-columns: 145px minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  padding: var(--space-4);
  margin: 0 0 var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
}
.so-document-facts dt {
  color: var(--color-text-secondary);
}
.so-document-facts dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: break-word;
}
.so-document-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  font-weight: var(--font-weight-semibold);
}
.so-document-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
}
.so-document-confirm {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
}
.so-document-confirm input {
  flex: 0 0 auto;
  margin-top: var(--space-1);
  width: 22px;
  height: 22px;
  accent-color: var(--color-accent-strong);
}
.so-documents-footer {
  justify-content: flex-end;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

/* TEN27: current-network desktop dashboard, using the selected console theme. */
.fr-dashboard {
  margin-top: var(--space-4);
  min-width: 0;
}
.fr-dashboard [hidden] {
  display: none !important;
}
.fr-dashboard-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--space-3);
}
.fr-dashboard-scope,
.fr-dashboard-filters,
.fr-dashboard-notice,
.fr-dashboard-registry {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}
.fr-dashboard-scope,
.fr-dashboard-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.fr-dashboard-scope p,
.fr-dashboard-registry p,
.fr-dashboard-card p {
  margin: 0;
}
.fr-dashboard-scope p {
  overflow-wrap: anywhere;
  line-height: var(--line-height-normal);
}
.fr-dashboard button,
.fr-dashboard select,
.fr-dashboard input[type="date"],
.fr-dashboard summary {
  min-height: 44px;
  font-family: inherit;
}
.fr-dashboard button {
  flex-shrink: 0;
}
.fr-dashboard-filters {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.fr-dashboard-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.fr-dashboard-field .field-input {
  width: auto;
  min-width: 150px;
  margin: 0;
}
.fr-dashboard-location-picker {
  position: relative;
  min-width: 190px;
}
.fr-dashboard-location-picker summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  color: var(--color-text-primary);
  list-style: none;
  cursor: pointer;
}
.fr-dashboard-location-picker summary::after {
  content: "⌄";
}
.fr-dashboard-location-picker summary:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.fr-dashboard-choices {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  z-index: 5;
  min-width: 280px;
  max-width: min(400px, 80vw);
  max-height: 320px;
  overflow: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  padding: var(--space-2);
}
.fr-dashboard-choices label {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  color: var(--color-text-primary);
}
.fr-dashboard-choices input {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--color-accent);
}
.fr-dashboard-choices span {
  overflow-wrap: anywhere;
}
.fr-dashboard-basis {
  display: flex;
  gap: var(--space-2) var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-dashboard-figures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}
.fr-dashboard-card {
  min-width: 0;
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-dashboard h2 {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.fr-dashboard-value {
  overflow-x: auto;
  display: block;
  margin: var(--space-3) 0 var(--space-2);
  font-size: var(--font-size-2xl);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fr-dashboard-muted {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-normal);
}
.fr-dashboard-rankings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.fr-dashboard-ranking-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.fr-dashboard-ranking-title span {
  flex-shrink: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.fr-dashboard-table-scroll {
  overflow-x: auto;
}
.fr-dashboard table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}
.fr-dashboard th {
  text-align: left;
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  padding-bottom: var(--space-2);
}
.fr-dashboard td {
  border-top: 1px solid var(--color-border);
  padding: var(--space-2) 0;
  vertical-align: top;
  overflow-wrap: anywhere;
}
.fr-dashboard td:first-child {
  width: 26px;
  color: var(--color-text-secondary);
}
.fr-dashboard .fr-dashboard-numeric {
  text-align: right;
  padding-left: var(--space-3);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  overflow-wrap: normal;
}
.fr-dashboard-empty {
  padding: var(--space-5) 0;
  color: var(--color-text-secondary);
}
.fr-dashboard-registry {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-4);
  font-size: var(--font-size-sm);
}
.fr-dashboard-registry h2 {
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-1);
}
.fr-dashboard-statuses {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.fr-dashboard-registry strong {
  margin-left: var(--space-2);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 1100px) {
  .fr-dashboard-rankings {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 800px) {
  .fr-dashboard-figures {
    grid-template-columns: 1fr;
  }
}

/* The network offer notice is a flow row below the shared header, never an overlay on ticket controls. */
.purchase-approval-notice {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-5);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  border-bottom: 1px solid var(--color-warning-subtle-border);
}
/* DEC-501: the approval count badge in the topbar, replacing the banner. */
.topbar-approval-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-warning-subtle-border);
  border-radius: var(--radius-full);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
}
.topbar-approval-badge[hidden] {
  display: none;
}
.topbar-approval-count {
  min-width: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-warning-strong);
  color: var(--color-surface);
  text-align: center;
}
.purchase-cancel-action {
  color: var(--color-danger-strong);
}
.purchase-cancel-dialog {
  width: min(90%, 36rem);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  background: var(--color-surface);
  color: var(--color-text-primary);
}
.purchase-cancel-dialog::backdrop {
  background: var(--color-scrim);
}
.purchase-cancel-dialog label {
  display: block;
  margin-bottom: var(--space-2);
}
.purchase-cancel-dialog select {
  width: 100%;
  min-height: var(--touch-target-comfortable);
}
.purchase-cancel-actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.purchase-cancel-actions > button {
  flex: 1;
  width: auto;
}

/* INVPAR1: one catalog with stock/par controls, Lock in the final column. */
.ap-unified-settings-summary,
.ap-unified-actions,
.ap-unified-tools {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.ap-unified-settings-summary {
  padding: var(--space-3) 0;
}
.ap-unified-settings-summary h3 {
  margin: 0 auto 0 0;
}
.ap-unified-settings-body {
  padding-bottom: var(--space-4);
}
.ap-unified-tools {
  margin-bottom: var(--space-3);
}
.ap-unified-tools label {
  min-width: 14rem;
}
.inv-table--unified .inv-col-package {
  width: auto;
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
  white-space: normal;
  font-weight: var(--font-weight-regular);
}
.inv-table--unified {
  table-layout: fixed;
}
.inv-table--unified .inv-col-onhand,
.inv-table--unified .inv-col-par,
.inv-table--unified .inv-col-auto,
.inv-table--unified .inv-col-used,
.inv-table--unified .inv-col-lock,
.inv-table--unified th:not(:first-child) {
  text-align: right;
  vertical-align: middle;
}
.inv-table--unified .ap-auto,
.inv-table--unified .ap-rate {
  align-items: flex-end;
}
.inv-table--unified .ap-lock {
  margin-left: auto;
}
.inv-table--unified th:not(:first-child) .inv-sort-btn {
  justify-content: flex-end;
}
.inv-table--unified .inv-numeric-header {
  padding-inline: var(--space-4);
}
.ap-recalculation-status {
  font-size: var(--font-size-sm);
}
/* RECUX1: ingredient selection and draft cost remain inside the recipe editor. */
.admin-recipe-picker {
  width: min(640px, calc(100% - 32px));
  max-height: 85vh;
  overflow: auto;
  padding: 24px;
  border: 1px solid var(--line, #dce1de);
  border-radius: 12px;
}
.admin-recipe-picker::backdrop {
  background: #16271d55;
}
.admin-recipe-picker .admin-component-item {
  width: 100%;
}
.admin-recipe-picker .admin-component-item-option {
  min-height: 44px;
  width: 100%;
}
.admin-recipe-picker input {
  width: 100%;
}
.admin-recipe-cost-summary {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 20px;
  padding: 16px;
  border: 1px solid var(--line, #dce1de);
  border-radius: 8px;
}
.admin-recipe-line-cost {
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.admin-component-item > strong {
  display: block;
}

/* CRB16: one batch source selector shared by report hosts. */
.cr-source-dialog {
  width: min(640px, calc(100% - 32px));
  max-height: 85vh;
  padding: 24px;
  border: 1px solid var(--color-border);
  border-radius: 12px;
}
.cr-source-dialog::backdrop {
  background: #16271d55;
}
.cr-source-options {
  max-height: 360px;
  overflow: auto;
  margin: 16px 0;
}
.cr-source-choice {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
}
.cr-source-choice input {
  width: 20px;
  height: 20px;
}
.cr-source-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.cr-creation-choice {
  padding: var(--space-5);
}
.cr-creation-methods {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin: var(--space-5) 0;
}
.cr-creation-methods button {
  min-height: 48px;
}

.cr-wizard {
  display: grid;
  gap: 1rem;
}
.cr-wizard-progress,
.cr-wizard-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.cr-wizard-content {
  display: grid;
  gap: 1rem;
}
.cr-wizard-content > .cr-col {
  width: auto;
  min-width: 0;
  max-width: none;
}
.cr-wizard-footer {
  justify-content: flex-end;
}

/* NETBANNER1: bounded native review dialog using existing offer rows. */
.shared-offers-dialog {
  width: min(72rem, calc(100vw - 3rem));
  max-height: calc(100dvh - 4rem);
  overflow: auto;
  box-sizing: border-box;
  padding: 1.5rem;
  border: 1px solid var(--color-border-strong);
  border-radius: 1rem;
  color: var(--color-text-primary);
  background: var(--color-surface);
}
.shared-offers-dialog::backdrop {
  background: rgb(0 0 0 / 35%);
}
.shared-offers-dialog > section {
  margin-block: 1.5rem;
}
.shared-offers-dialog button {
  min-height: 44px;
}

.fr-discount-policy {
  margin-block-end: 1.5rem;
  padding-block-end: 1rem;
  border-bottom: 1px solid var(--color-border-strong);
}
.fr-discount-policy-actions {
  display: flex;
  gap: 0.75rem;
  margin-block-start: 1rem;
}
.fr-discount-policy input {
  min-width: 44px;
  min-height: 44px;
  vertical-align: middle;
}

/* MODRM1 approved recipe-owned ingredient choice rows. */
.modrm1-choice-group {
  margin-block: 1rem;
  padding: 1rem;
  border: 1px solid var(--color-border-strong);
  border-radius: 0.5rem;
}
.modrm1-choice-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-block-end: 1rem;
}
.modrm1-choice-header > input {
  flex: 1;
  min-width: 0;
}
.modrm1-choice-header > label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.modrm1-choice-row {
  display: grid;
  grid-template-columns: minmax(10rem, 1fr) 5.5rem 5.5rem 8rem auto;
  align-items: end;
  gap: 0.75rem;
  margin-block: 0.75rem;
}
.modrm1-choice-field {
  display: grid;
  gap: 0.375rem;
  min-width: 0;
}
.modrm1-choice-field > input,
.modrm1-choice-field > select {
  width: 100%;
  min-height: 44px;
}
.modrm1-choice-row > button,
.modrm1-choice-header > button {
  min-height: 44px;
}
@media (max-width: 1000px) {
  .modrm1-choice-row {
    grid-template-columns: minmax(10rem, 1fr) 5.5rem 5.5rem;
  }
}

.ingredient-choice-control {
  display: grid;
  gap: 0.5rem;
  width: 100%;
  margin-block: 0.75rem;
}
.ingredient-choice-control > select {
  width: 100%;
  min-height: 56px;
}

/* SETIA1: existing editors share one selected-kind setup surface. */
.setia1-tabs {
  display: flex;
  gap: 20px;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 20px;
}
.setia1-tabs button {
  min-height: 44px;
  padding: 10px 4px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.setia1-tabs button[aria-selected="true"] {
  border-bottom: 3px solid currentColor;
  font-weight: 700;
}
.setia1-kind-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 24px 0 16px;
}
.setia1-kind-jump button[aria-pressed="true"] {
  outline: 2px solid currentColor;
  outline-offset: 1px;
}
.setia1-kind-editors {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}
.setia1-kind-editors > .admin-subsection {
  margin: 0;
  min-width: 0;
}
.setia1-section-heading {
  display: flex;
  align-items: center;
  gap: 8px;
}
.setia1-section-heading h2 {
  margin: 0;
}
@media (max-width: 1000px) {
  .setia1-kind-editors {
    grid-template-columns: 1fr;
  }
}

/* Software owner onboarding starting settings. */
.so-defaults {
  min-width: 0;
}
.so-defaults-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.so-defaults-toolbar > span {
  margin-right: auto;
}
.so-defaults-group {
  border-bottom: 1px solid var(--color-border);
}
.so-defaults-group > summary {
  display: flex;
  gap: 10px;
  align-items: center;
  min-height: 58px;
  cursor: pointer;
  font-weight: 600;
}
.so-defaults-summary {
  margin-left: auto;
  max-width: 55%;
  text-align: right;
  font-size: 13px;
  font-weight: 400;
  overflow-wrap: anywhere;
}
.so-defaults-row {
  display: grid;
  grid-template-columns: 22px minmax(150px, 1fr) minmax(140px, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 10px 0 10px 24px;
  border-top: 1px solid var(--color-border);
}
.so-defaults-value {
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}
.so-defaults-editor,
.so-defaults-confirm,
.so-defaults-node-error {
  grid-column: 2 / -1;
}
.so-defaults-editor {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.so-defaults-editor .field-input {
  flex: 1;
  min-width: 180px;
}
.so-defaults-confirm {
  display: flex;
  align-items: center;
  gap: 10px;
}
.so-defaults-review {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) 2fr;
  gap: 12px;
}
.so-defaults-review dd {
  margin: 0;
  overflow-wrap: anywhere;
}
.so-defaults-review-row {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.so-wizard[data-page="defaults"],
.so-wizard[data-page="review"] {
  max-width: 1100px;
}
.so-defaults-fields {
  display: grid;
  flex: 1;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
}

.admin-vendor-ordering-preferences {
  display: grid;
  gap: 12px;
  min-width: 0;
}
.admin-vendor-ordering-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.admin-vendor-ordering-preferences [hidden] {
  display: none;
}
/* NAMES1: approved desktop naming/contact flow and explicit identity confirmation. */
.so-naming-preview {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) 2fr;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-4);
  margin: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow-wrap: anywhere;
}
.so-naming-preview dd {
  margin: 0;
}
.so-step[data-onboard-page="owner"]:not([hidden]) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3) var(--space-4);
}
.so-step[data-onboard-page="owner"] > .so-form-grid,
.so-step[data-onboard-page="owner"] > label:has(#software-owner-administrator),
#software-owner-contact-error,
#software-owner-administrator-fields {
  grid-column: 1 / -1;
}
.so-step[data-onboard-page="owner"] > [hidden] {
  display: none;
}
.so-names-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.so-names-dialog {
  width: min(620px, calc(100vw - 48px));
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
}
.so-names-dialog::backdrop {
  background: rgb(0 0 0 / 35%);
}
.so-names-dialog form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.so-names-dialog .so-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}
.so-names-dialog .so-naming-preview {
  display: block;
}

/* OWNERPLANS2: native centered pricing dialog, preserving the Add plan layout. */
dialog.so-plan-pricing-dialog {
  width: min(680px, calc(100vw - 48px));
}
.so-plan-pricing-dialog .so-cp-dialog-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
.so-plan-pricing-header-current {
  display: grid;
  grid-template-columns: auto auto;
  gap: var(--space-1) var(--space-2);
  margin: 0;
  font-size: var(--font-size-sm);
}
.so-plan-pricing-header-current dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}
.so-plan-pricing-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.so-plan-pricing-table th,
.so-plan-pricing-table td {
  padding: var(--space-2);
  text-align: right;
  border-bottom: 1px solid var(--color-border);
}
.so-plan-pricing-table th:first-child {
  text-align: left;
  padding-left: 0;
}
.so-plan-pricing-table thead th,
.so-plan-pricing-table td:last-child {
  font-size: var(--font-size-sm);
}
.so-plan-pricing-table thead th {
  color: var(--color-text-secondary);
}
.so-plan-pricing-input {
  display: inline-flex;
  align-items: center;
  width: 112px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 0 var(--space-2);
}
.so-plan-pricing-input .field-input {
  min-width: 0;
  width: 100%;
  text-align: right;
  border: 0;
  background: transparent;
  padding-inline: var(--space-1);
  font-variant-numeric: tabular-nums;
}
.so-plan-pricing-input:focus-within {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
}
.so-plan-pricing-date-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.so-plan-pricing-date-row .field-input {
  width: 170px;
}
.so-plan-pricing-date-row span {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.so-plan-pricing-audience {
  border: 0;
  padding: 0;
  margin: var(--space-4) 0;
}
.so-plan-pricing-audience legend {
  margin-bottom: var(--space-2);
}
.so-plan-pricing-segments {
  display: flex;
  gap: var(--space-1);
  padding: var(--space-1);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.so-plan-pricing-audience .admin-policy-radio-option {
  flex: 1;
  gap: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  color: inherit;
  background: transparent;
}
.so-plan-pricing-audience .admin-policy-radio-option:has(input:checked) {
  color: inherit;
  background: transparent;
}
.so-plan-pricing-audience label span {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target-min);
  padding: var(--space-2);
  border-radius: var(--radius-md);
}
.so-plan-pricing-audience input:checked + span {
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  font-weight: var(--font-weight-semibold);
}
.so-plan-pricing-audience input:disabled + span {
  opacity: 0.6;
}
.so-plan-pricing-effect {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.so-plan-pricing-effect p {
  margin: 0;
}
.so-plan-pricing-effect .admin-field-help {
  margin-top: var(--space-2);
  font-family: inherit;
  font-style: normal;
}
.so-plan-pricing-dialog #so-plan-pricing-fee-label {
  display: inline-flex;
  align-items: center;
}
.so-plan-pricing-summary {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-4) 0;
}
.so-plan-pricing-summary dt {
  color: var(--color-text-secondary);
}
.so-plan-pricing-summary dd {
  margin: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}
.so-plan-pricing-reviewed-effect {
  margin: 0 0 var(--space-4);
}
.so-plan-pricing-consequences {
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
}
.so-plan-pricing-consequences p {
  margin: var(--space-2) 0;
}
.so-plan-pricing-foot {
  flex-wrap: wrap;
}
.so-plan-pricing-why {
  margin-right: auto;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.so-plan-pricing-scheduled td {
  padding: var(--space-3) var(--space-4);
}
.so-plan-pricing-scheduled .so-plans-action-box {
  margin-top: var(--space-2);
}
.so-plan-pricing-dialog [hidden] {
  display: none;
}

/* TEN17-F5-F2: Brand font selector. */
.fr-font-picker {
  position: relative;
  flex: 1;
  min-width: 0;
}
.fr-font-picker-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  text-align: left;
}
.fr-font-picker-name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 23px;
  line-height: 1.35;
}
.fr-font-picker-popup {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 30;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
}
.fr-font-picker-popup[hidden] {
  display: none;
}
.fr-font-picker-list {
  max-height: 324px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
}
.fr-font-picker-group {
  padding: 10px 12px 6px;
  color: var(--color-text-secondary);
  font:
    600 12px system-ui,
    sans-serif;
}
.fr-font-picker-option {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  min-height: 62px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.fr-font-picker-active {
  outline: 2px solid var(--color-border);
  outline-offset: -2px;
}
.fr-font-picker-check {
  flex: 0 0 20px;
  font:
    600 18px system-ui,
    sans-serif;
}
.fr-font-picker-option .fr-font-picker-name {
  flex: 1 1 160px;
}
.fr-font-picker-meta {
  font:
    12px system-ui,
    sans-serif;
  color: var(--color-text-secondary);
}
.fr-font-picker-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--color-border);
}
.fr-font-picker-footer button {
  min-height: 44px;
  min-width: 44px;
}
.fr-font-picker > [role="status"] {
  display: block;
  font:
    14px system-ui,
    sans-serif;
  color: var(--color-text-secondary);
}

/* RPTCAT0: shared location and franchisor canned report frame. */
.canned-content,
.canned-saved {
  min-width: 0;
  width: 100%;
}
.canned-heading,
.canned-toolbar,
.canned-actions,
.canned-result-meta {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin: 12px 0;
}
.canned-heading h2 {
  margin: 0;
}
.canned-toolbar {
  padding: 12px 16px;
  background: var(--color-surface-sunken);
  border-radius: 10px;
  justify-content: space-between;
}
.canned-filters {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  padding: 18px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
}
.canned-filters label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 150px;
}
.canned-filters fieldset {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  max-height: 280px;
  overflow: auto;
}
.canned-filters fieldset label {
  flex-direction: row;
  align-items: center;
  min-width: 180px;
}
.canned-saved select,
.canned-saved input {
  min-height: 40px;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--color-text-primary);
  background: var(--color-surface);
}
.canned-saved button {
  min-height: 40px;
  cursor: pointer;
}
.canned-saved button:disabled {
  cursor: default;
  opacity: 0.5;
}
.canned-result-meta {
  font-size: 0.85rem;
  color: var(--color-text-tertiary);
}
.canned-table-scroll {
  width: 100%;
  overflow: auto;
  margin: 16px 0;
  border: 1px solid var(--color-border);
  border-radius: 8px;
}
.canned-table-scroll table {
  border-collapse: collapse;
  width: 100%;
  font-variant-numeric: tabular-nums;
}
.canned-table-scroll caption {
  text-align: left;
  font-weight: 700;
  padding: 12px;
}
.canned-table-scroll th,
.canned-table-scroll td {
  white-space: nowrap;
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}
.canned-table-scroll th {
  background: var(--color-surface-sunken);
  font-size: 0.85rem;
}
.canned-chart {
  margin: 18px 0;
}
.canned-chart-picture {
  overflow: auto;
  width: 100%;
  margin-top: 12px;
}
.canned-chart svg {
  color: var(--color-text-primary);
  font-family: inherit;
  max-width: none;
}
.canned-chart text {
  fill: currentColor;
  font-size: 12px;
}
.canned-axis {
  stroke: currentColor;
  stroke-opacity: 0.35;
}
.canned-line {
  stroke: var(--color-accent);
  stroke-width: 2;
  fill: none;
}
.canned-point {
  fill: var(--color-accent);
}
.canned-series-0 {
  fill: #537b64;
}
.canned-series-1 {
  fill: #a9763c;
}
.canned-series-2 {
  fill: #6b79a2;
}
.canned-series-3 {
  fill: #9e6675;
}
.canned-series-4 {
  fill: #69999e;
}
.canned-series-5 {
  fill: #8c8846;
}
.canned-content details,
.canned-saved details {
  margin: 16px 0;
}

/* FRDISC1: approved Discounts layout only. Recipes retain their existing presentation. */
.frdisc-page > .fr-card-head {
  display: none;
}
.frdisc-policy {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.frdisc-policy-text {
  flex: 1;
}
.frdisc-policy-label {
  display: inline-flex;
  align-items: center;
  font-weight: var(--font-weight-semibold);
}
.frdisc-policy-text p {
  margin: var(--space-1) 0;
  font-size: var(--font-size-sm);
}
.frdisc-policy-state {
  font-weight: var(--font-weight-semibold);
}
.frdisc-policy-switch {
  position: relative;
  flex: none;
  width: 64px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.frdisc-policy-switch::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 8px;
  width: 56px;
  height: 32px;
  border-radius: 16px;
  background: var(--color-text-tertiary);
}
.frdisc-policy-switch::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 11px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
}
.frdisc-policy-switch[aria-checked="true"]::before {
  background: var(--color-accent-strong);
}
.frdisc-policy-switch[aria-checked="true"]::after {
  transform: translateX(24px);
}
.frdisc-policy-switch:disabled {
  opacity: 0.5;
  cursor: default;
}
.frdisc-policy-switch:focus-visible {
  outline: 3px solid var(--color-accent-strong);
  outline-offset: 2px;
}
.frdisc-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.frdisc-toolbar h2 {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-lg);
  margin: 0;
}
.frdisc-list-tally {
  margin-right: auto;
  white-space: nowrap;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.frdisc-toolbar .fr-definition-search {
  width: 260px;
  min-height: 44px;
  margin: 0;
}
.frdisc-page .fr-pub-list {
  gap: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.frdisc-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 112px 292px 150px;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.frdisc-row:last-child {
  border-bottom: 0;
}
.frdisc-name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--font-size-md);
}
.frdisc-terms {
  margin: var(--space-1) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.frdisc-badge {
  display: inline-flex;
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-xs);
}
.frdisc-locations {
  color: var(--color-accent-strong);
  background: transparent;
  border: 0;
  min-height: 44px;
  text-align: left;
  cursor: pointer;
}
.frdisc-tally {
  display: flex;
  gap: var(--space-1);
  border: 0;
  background: transparent;
  text-align: left;
  min-height: 44px;
  cursor: pointer;
}
.frdisc-count {
  display: flex;
  flex-direction: column;
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}
.frdisc-count strong {
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
}
.frdisc-count small {
  font-size: var(--font-size-xs);
}
.frdisc-count-accepted,
.frdisc-tone-good {
  color: var(--color-accent-strong);
  background: var(--color-accent-subtle);
}
.frdisc-row-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
.frdisc-menu {
  position: relative;
}
.frdisc-menu > summary {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  list-style: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--font-size-xl);
}
.frdisc-menu > summary::-webkit-details-marker {
  display: none;
}
.frdisc-menu-options {
  position: absolute;
  right: 0;
  top: 48px;
  z-index: 10;
  min-width: 180px;
  padding: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-2);
}
.frdisc-menu-options button {
  display: block;
  width: 100%;
  text-align: left;
  margin: 0;
}
dialog.frdisc-policy-confirm,
dialog.frdisc-response {
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  width: min(480px, calc(100vw - 48px));
  padding: var(--space-5);
}
dialog.frdisc-policy-confirm::backdrop,
dialog.frdisc-response::backdrop {
  background: var(--color-scrim);
}
.frdisc-policy-confirm h3,
.frdisc-response h3 {
  margin-top: 0;
}
.frdisc-policy-confirm-actions,
.frdisc-response-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.frdisc-response-list {
  max-height: 55vh;
  overflow: auto;
}
.frdisc-response-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.frdisc-response-row small {
  display: block;
  color: var(--color-text-secondary);
}
.frdisc-page [hidden] {
  display: none;
}

.frdisc-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 112px 292px 150px;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.frdisc-policy[hidden],
.frdisc-toolbar[hidden],
.frdisc-columns[hidden],
.frdisc-no-match[hidden] {
  display: none;
}

/* CATNET1: shared identity and local matching, no private operating columns. */
.catalog-network {
  min-width: 0;
}
.catalog-network .catalog-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-3);
}
.catalog-network .catalog-summary h2,
.catalog-network .catalog-summary p {
  margin: 0;
}
.catalog-network .catalog-summary p {
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.catalog-network .catalog-summary button {
  flex-shrink: 0;
}
.catalog-network .catalog-workspace {
  padding-block: var(--space-3);
}
.catalog-network .catalog-workspace[hidden] {
  display: none;
}
.catalog-network .catalog-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block: var(--space-3);
}
.catalog-network button,
.catalog-network input,
.catalog-network select {
  min-height: 44px;
}
.catalog-network button {
  padding: var(--space-2) var(--space-3);
}
.catalog-network .catalog-product,
.catalog-network .catalog-candidate {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.catalog-network .catalog-product > :first-child {
  flex: 1;
  min-width: 180px;
  overflow-wrap: anywhere;
}
.catalog-network .catalog-alert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--color-surface-sunken);
}
.catalog-network .catalog-editor {
  margin-block: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.catalog-network .catalog-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
.catalog-network .catalog-fields label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.catalog-network .catalog-fields > .catalog-actions,
.catalog-network .catalog-fields > div,
.catalog-network .catalog-fields > p {
  grid-column: 1 / -1;
}

/* PAY1-S4-F10: display status in the existing checkout sheet. */
.pay-reader-cart-status {
  flex: 0 0 auto;
  margin: 0 1.5rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border-color, #bbb);
  border-radius: 0.5rem;
  overflow-wrap: anywhere;
}
.pay-reader-cart-status[hidden] {
  display: none;
}
.rt-cart-pause {
  padding-bottom: 1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border-color, #bbb);
}

/* ---------- RPTLAYOUT1-F1-S1 (docs/build-briefs/RPTLAYOUT1-F1-S1-reports-home-results.md; design/mockups/reports-experience.html):
   the shared Reports home and results, desktop sized (1440x900), drawn by ui/src/reportsExperience.ts and
   ui/src/locationPicker.ts. Every color is a --color-* token of the active theme, never a literal white, so Snip & Sip Light
   and Ink both stay legible. The circled ? keeps its pop-out and drops the Close button (DEC-466: hover or tap opens it, an
   outside tap or Escape closes it). ---------- */
.rx {
  --rx-gap: var(--space-5);
  color: var(--color-text-primary);
  font-family: var(--font-family-base);
  width: 100%;
  min-width: 0;
}
.rx h1,
.rx h2 {
  font-family: var(--font-family-display);
  margin: 0;
  letter-spacing: -0.01em;
}
.rx h1 {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}
.rx-grow {
  flex: 1;
}
.rx-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
.rx-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.rx-btn {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  cursor: pointer;
}
.rx-btn:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.rx-btn-primary {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-text-on-accent);
}
.rx-btn-primary:hover:not(:disabled) {
  background: var(--color-accent-strong);
}
.rx button:disabled,
.rx-field:disabled {
  opacity: 0.5;
  cursor: default;
}
.rx button:focus-visible,
.rx input:focus-visible,
.rx select:focus-visible,
.rx [tabindex]:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.rx-field {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  width: 100%;
}
.rx-field::placeholder {
  color: var(--color-text-tertiary);
}
.rx-notice {
  margin: 0 0 var(--space-3);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}
/* RPTEXPORT1: a notice that reports something that worked (a connected account, an opened sheet) is not an error. */
.rx-notice.ok {
  color: var(--color-text-primary);
}
.rx-notice-link {
  color: var(--color-link, var(--color-text-primary));
  text-decoration: underline;
}
.rx-empty-line {
  margin: 0;
  padding: var(--space-4);
  color: var(--color-text-tertiary);
}
/* home */
.rx-head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.rx-search {
  width: 300px;
  flex: none;
}
.rx-two {
  display: grid;
  align-items: start;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}
.rx-section {
  font-family: var(--font-family-base);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin: 0 0 var(--space-2);
}
.rx-group {
  margin-bottom: var(--space-6);
}
.rx-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--space-3);
}
.rx-grid-favorites {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.rx-card-report {
  position: relative;
  display: flex;
  height: 96px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.rx-card-open {
  flex: 1;
  min-width: 0;
  padding: var(--space-3) 56px var(--space-3) var(--space-5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  border: 0;
  border-radius: var(--radius-lg);
  background: transparent;
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.rx-card-open:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.rx-card-title,
.rx-card-meta {
  display: block;
}
/* RPTHOME-F1: every card is the same height; a title holds two lines at most and ends in an ellipsis. */
.rx-card-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  line-height: 1.3;
}
.rx-card-meta {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.rx-card-meta {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}
.rx-card-report.disabled .rx-card-open {
  color: var(--color-text-tertiary);
  cursor: default;
}
.rx-star {
  position: absolute;
  right: 4px;
  top: 2px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-border-strong);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.rx-star.on {
  color: var(--color-accent);
}
.rx-crumb .rx-star {
  position: static;
  width: 48px;
  height: 48px;
}
.rx-recent-list {
  overflow: hidden;
}
.rx-recent-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 56px;
  padding: var(--space-2) var(--space-5);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-primary);
  text-align: left;
  cursor: pointer;
}
.rx-recent-row:last-child {
  border-bottom: 0;
}
.rx-recent-row:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.rx-recent-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.rx-recent-text small,
.rx-recent-when {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
}
.rx-recent-when {
  margin-left: auto;
  white-space: nowrap;
}
/* results */
.rx-crumb {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.rx-back {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-3) 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-accent-strong);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rx-controls,
.rx-extras {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
}
.rx-extras {
  flex-wrap: wrap;
}
/* UIFIX1 (SF-1): a filter pill is one line ("Dates: Last 30 days"), the same height as the Export button, and never wraps. */
.rx-sel {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
  min-height: 48px;
  min-width: 140px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.rx-sel-label {
  color: var(--color-text-tertiary);
  font-weight: var(--font-weight-medium);
}
.rx-sel-caret {
  color: var(--color-text-tertiary);
  font-size: 0.75em;
}
.rx-pill-wrap {
  position: relative;
  flex: none;
}
.rx-menu-wrap {
  position: relative;
  flex: none;
}
.rx-export-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
}
.rx-menu {
  position: absolute;
  z-index: 50;
  top: calc(100% + 6px);
  right: 0;
  width: 280px;
  max-width: calc(100vw - 32px);
  padding: var(--space-2);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.rx-menu-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-4);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.rx-menu-item:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}
.rx-menu-item:disabled {
  color: var(--color-text-tertiary);
}
.rx-menu-reason {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
  white-space: normal;
}
.rx-sel.open {
  border-color: var(--color-accent);
}
.rx-sel-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
.rx-sel-text small {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
}
.rx-scrim {
  position: fixed;
  inset: 0;
  z-index: 40;
}
.rx-pop {
  position: absolute;
  z-index: 50;
  top: calc(100% + 6px);
  left: 0;
  width: 360px;
  max-width: calc(100vw - 32px);
  padding: var(--space-4);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.rx-pop.locations {
  width: 360px;
}
.rx-pop-head,
.rx-picker-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.rx-pop-title,
.rx-picker-title,
.rx-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.rx-presets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.rx-chip-btn {
  min-height: var(--touch-target-min);
  white-space: nowrap;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rx-chip-btn.on {
  background: var(--color-accent-subtle);
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}
.rx-custom {
  margin-bottom: var(--space-3);
}
.rx-custom-inputs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: end;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.rx-custom-inputs .rx-btn {
  grid-column: 1 / -1;
}
.rx-date {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  flex: 1;
}
.rx-switch {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 48px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rx-switch i {
  position: relative;
  flex: none;
  width: 52px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
}
.rx-switch i::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 3px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--color-surface);
  transition: left 0.15s;
}
.rx-switch.on i {
  background: var(--color-accent);
}
.rx-switch.on i::after {
  left: 23px;
}
.rx-seg {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.rx-seg button {
  min-height: 42px;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rx-seg button.on {
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
}
.rx-picker .rx-seg {
  display: flex;
}
.rx-picker .rx-seg button {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: var(--space-1) var(--space-2);
  line-height: 1.15;
  white-space: normal;
  text-align: center;
}
.rx-vis {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.rx-vis.single {
  grid-template-columns: minmax(0, 1fr);
}
.rx-chart {
  padding: 0;
  min-width: 0;
}
.rx-chart .cr-chart-card {
  border: 0;
  background: transparent;
}
/* UIFIX1 (SF-2): the headline figures are one strip above the table, not a 300px column beside a chart. */
.rx-totals {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-8);
  padding: var(--space-3) var(--space-5);
  margin-bottom: var(--space-4);
}
.rx-total {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}
.rx-total-value {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-2);
}
.rx-total-value b {
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  color: var(--color-text-primary);
}
.rx-delta {
  display: inline-block;
  margin-top: 2px;
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
}
.rx-delta.up {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}
.rx-delta.down {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}
.rx-delta.flat {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.rx-table-card {
  overflow: hidden;
}
.rx-table-scroll {
  /* UIFIX1 (SF-2): the table is as tall as its rows, so there is no scroll box inside the page and the Total row is the
     table's last row. It scrolls sideways only when it is wider than its card, and a fade at the edge says so. */
  overflow-x: auto;
  overflow-y: hidden;
  background:
    linear-gradient(to right, var(--color-surface) 30%, transparent) left center / 32px 100%
      no-repeat local,
    linear-gradient(to left, var(--color-surface) 30%, transparent) right center / 32px 100%
      no-repeat local,
    linear-gradient(to right, rgb(0 0 0 / 0.28), transparent) left center / 14px 100% no-repeat
      scroll,
    linear-gradient(to left, rgb(0 0 0 / 0.28), transparent) right center / 14px 100% no-repeat
      scroll;
}
.rx-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-variant-numeric: tabular-nums lining-nums;
}
.rx-table th,
#admin-group-panel-reports .rx-table th,
.rx-table td,
#admin-group-panel-reports .rx-table td {
  padding: 0 var(--space-4);
  min-height: 44px;
  height: 44px;
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  white-space: nowrap;
  text-transform: none;
  letter-spacing: normal;
}
.rx-table .num,
#admin-group-panel-reports .rx-table .num {
  text-align: right;
}
.rx-table thead th,
#admin-group-panel-reports .rx-table thead th {
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
}
.rx-th {
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.rx-th.on {
  color: var(--color-accent-strong);
}
.rx-table tfoot td,
#admin-group-panel-reports .rx-table tfoot td {
  background: var(--color-accent-subtle);
  border-top: 2px solid var(--color-accent-subtle-border);
  border-bottom: 0;
  font-weight: var(--font-weight-bold);
}
.rx-foot {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
}
/* states */
.rx-state {
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--space-2);
  min-height: 0;
  padding: var(--space-5);
  text-align: center;
}
/* UIFIX1 (SF-3): an empty or failed page is one sentence and one next action in a short row, never a 300px card. */
.rx-state-compact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  min-height: 64px;
  padding: var(--space-3) var(--space-5);
  text-align: left;
}
.rx-state-compact h2 {
  font-size: var(--font-size-base);
}
.rx-state-compact p {
  margin: 0;
}
/* The row sheet: the whole row, in full, for anything the table cuts off. */
.rx-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 0.5);
}
.rx-sheet {
  width: min(480px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow: auto;
  padding: var(--space-5);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.rx-sheet h2 {
  margin-bottom: var(--space-3);
}
.rx-sheet-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0 0 var(--space-4);
}
.rx-sheet-list dt {
  color: var(--color-text-secondary);
}
.rx-sheet-list dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.rx-state h2 {
  font-size: var(--font-size-lg);
}
.rx-state p {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
}
.rx-actions {
  display: flex;
  gap: var(--space-3);
}
.rx-skel {
  background: linear-gradient(
    90deg,
    var(--color-surface-sunken) 25%,
    var(--color-border) 50%,
    var(--color-surface-sunken) 75%
  );
  background-size: 200% 100%;
  animation: rx-shimmer 1.3s infinite linear;
  border-radius: var(--radius-md);
}
.rx-skel-chart {
  min-height: 250px;
}
.rx-skel-totals {
  min-height: 250px;
}
.rx-skel-table {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
}
.rx-skel-table .rx-skel-row {
  height: 28px;
}
.rx-state .rx-skel {
  height: 28px;
  width: 100%;
  max-width: 560px;
}
@keyframes rx-shimmer {
  to {
    background-position: -200% 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .rx-skel {
    animation: none;
  }
}
/* the shared location picker (LOCPICK1) */
.rx-picker-body {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-top: var(--space-3);
}
.rx-picker-find {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2);
  background: var(--color-surface-sunken);
}
.rx-picker-find .rx-field:first-child {
  flex: 1;
}
.rx-picker-find select {
  width: 130px;
  flex: none;
}
.rx-picker-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-1);
  min-height: 48px;
  padding: 0 var(--space-2);
  border-bottom: 1px solid var(--color-border);
}
.rx-picker-count {
  margin-left: auto;
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
}
.rx-link {
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  white-space: nowrap;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.rx-link.on {
  background: var(--color-accent-subtle);
}
.rx-picker-list {
  height: 168px;
  overflow: auto;
}
.rx-picker-none {
  margin: 0;
  padding: var(--space-4);
  color: var(--color-text-tertiary);
}
.rx-pr {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-primary);
  text-align: left;
  cursor: pointer;
}
.rx-pr.group {
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-bold);
  cursor: default;
}
.rx-pr.child {
  padding-left: 40px;
}
.rx-pr-group-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rx-fold {
  width: 32px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
}
.rx-pr-note {
  margin-left: auto;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
}
.rx-ck {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  border: 2px solid var(--color-border-strong);
  border-radius: 7px;
  color: var(--color-text-on-accent);
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
}
.rx-ck.rd {
  border-radius: 50%;
}
.rx-ck.on,
.rx-ck.mid {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.rx-ck.on::after {
  content: "\2713";
}
.rx-ck.rd.on::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-text-on-accent);
}
.rx-ck.mid::after {
  content: "\2212";
}
.rx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  max-height: 84px;
  padding: var(--space-2);
  overflow: auto;
  border-top: 1px solid var(--color-border);
}
.rx-chip {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 4px 0 12px;
  border: 1px solid var(--color-accent-subtle-border);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.rx-chip-x {
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 1.125rem;
  cursor: pointer;
}
.rx-picker-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* RPTLAYOUT1-F1-S1: the hub's entry to the Reports home. */
.hub-all-reports {
  margin-left: auto;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-5);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

/* RPTLAYOUT1-F1-S1: the franchisor console draws the home in Snip & Sip Light on its default theme. */
.rx[data-theme] {
  background: var(--color-bg);
  color: var(--color-text-primary);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}

/* RPTLAYOUT1-F1-S1: while the Reports home or results is on screen it carries its own title, so the host's page title and its
   one-line blurb step aside (a CSS-only rule: it follows the DOM, so nothing needs to remember to bring them back). */
body:has(.rx) #admin-ops-title,
body:has(.rx) #admin-ops-subtitle,
body:has(.rx) #fr-home-title {
  display: none;
}

/* RPTLAYOUT1-F1-S1: the leading words column keeps one line, with any second words column (the franchisee) as muted text under
   it; the figure columns are narrow and their headings may wrap, so a long real name never pushes the figures off the card. */
.rx-table td.rx-lead,
#admin-group-panel-reports .rx-table td.rx-lead {
  max-width: 320px;
  min-width: 180px;
  line-height: 1.25;
  padding-top: var(--space-1);
  padding-bottom: var(--space-1);
}
.rx-row-open {
  display: block;
  width: 100%;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rx-lead-name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rx-lead-note {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
}
.rx-table thead th,
#admin-group-panel-reports .rx-table thead th {
  white-space: nowrap;
  line-height: 1.15;
}
.rx-table td,
#admin-group-panel-reports .rx-table td {
  height: 44px;
}

/* RPTLAYOUT1-F1-S1: the chart keeps a fixed height so the table and its total row stay in view at 1440x900. */
.rx-chart-section {
  margin-top: var(--space-4);
}
.rx-chart-toggle {
  margin-bottom: var(--space-3);
}
.rx-chart .cr-chart-card {
  padding: var(--space-3) var(--space-4);
}

/* ---------- RPTLAYOUT1-F1-S3 (docs/build-briefs/RPTLAYOUT1-F1-S3-guided-report-builder.md; design/mockups/reports-experience.html
   builder scenes): the guided custom report builder, drawn by ui/src/reportBuilderFlow.ts and its results screen
   ui/src/reportBuilderResults.ts. It rides the .rx frame and the rx-* controls above; every color is a --color-* token, so the
   light and Ink themes both read. Desktop sized (1440x900). ---------- */
.rb-head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.rb-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.rb-gap {
  margin-top: var(--space-4);
}
.rb-muted {
  color: var(--color-text-secondary);
}
.rb-steps {
  display: flex;
  align-items: center;
  margin-bottom: var(--space-5);
}
.rb-stp {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-1);
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  white-space: nowrap;
}
.rb-stp i {
  display: grid;
  place-items: center;
  flex: none;
  width: 30px;
  height: 30px;
  border: 2px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-style: normal;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}
.rb-stp.on {
  color: var(--color-text-primary);
}
.rb-stp.on i {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-text-on-accent);
}
.rb-stp.done i {
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}
.rb-stp:disabled {
  cursor: default;
  opacity: 0.6;
}
.rb-line {
  flex: 1;
  min-width: 16px;
  height: 2px;
  margin: 0 var(--space-3);
  background: var(--color-border-strong);
}
.rb-line.done {
  background: var(--color-accent);
}
.rb-start {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  max-width: 900px;
  margin: var(--space-8) auto 0;
}
.rb-choice-wrap {
  position: relative;
  display: flex;
}
.rb-choice {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 230px;
  padding: var(--space-6);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-1);
  text-align: left;
  cursor: pointer;
}
.rb-choice:hover:not(:disabled) {
  border-color: var(--color-accent);
}
.rb-choice:disabled {
  cursor: default;
}
.rb-choice h2 {
  font-size: var(--font-size-xl);
}
.rb-big {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-family: var(--font-family-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
}
.rb-bill {
  position: absolute;
  left: var(--space-6);
  bottom: var(--space-5);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 30px;
  padding: 0 var(--space-1) 0 var(--space-3);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}
.rb-ai .rb-bill {
  position: static;
}
.rb-work {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--space-5);
  align-items: start;
}
.rb-work.full {
  display: block;
  max-width: 900px;
}
.rb-pane {
  padding: var(--space-5);
}
.rb-pane h2 {
  margin-bottom: var(--space-1);
}
.rb-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 320px;
}
.rb-find {
  margin-bottom: var(--space-2);
}
.rb-sources {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  max-height: 460px;
  overflow-y: auto;
}
.rb-src {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 52px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.rb-src.on {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle);
}
.rb-src:disabled {
  cursor: default;
  opacity: 0.5;
}
.rb-ck {
  flex: none;
  width: 22px;
  height: 22px;
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.rb-ck.on {
  border-color: var(--color-accent);
  background: var(--color-accent);
  box-shadow: inset 0 0 0 3px var(--color-surface);
}
.rb-join {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}
.rb-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.rb-groups {
  max-height: 260px;
  overflow-y: auto;
}
.rb-frow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.rb-flabel {
  width: 84px;
  flex: none;
}
.rb-relative {
  position: relative;
}
.rb-pop {
  top: calc(100% + 6px);
  left: 0;
}
.rb-filter .rb-remove {
  margin-left: auto;
}
.rb-add-select {
  max-width: 320px;
}
.rb-ai {
  max-width: 820px;
  margin: var(--space-5) auto 0;
}
.rb-ai-text {
  min-height: 110px;
  padding: var(--space-3);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  resize: vertical;
}
.rb-ai-note {
  margin: 0 0 var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text-secondary);
}
.rb-foot {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
}
.rb-big-btn {
  min-height: 52px;
  padding: 0 var(--space-6);
}
.rb-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-2);
}
.rb-days .wide {
  grid-column: span 2;
}
.rb-schedule {
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}
.rb-preview {
  position: sticky;
  top: 0;
  padding: var(--space-4);
}
.rb-preview h3 {
  margin: 0;
  font-size: var(--font-size-md);
}
.rb-live {
  margin-left: auto;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
}
.rb-live:empty {
  display: none;
}
.rb-live.busy {
  color: var(--color-accent-strong);
}
.rb-preview .rb-row {
  margin-bottom: var(--space-3);
}
.rb-preview-blank {
  min-height: 220px;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
}
.rb-preview-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.rb-preview-chart .cr-chart-svg {
  max-height: 200px;
}
.rb-preview-scroll {
  max-height: 340px;
  overflow: auto;
}
.rb-skel {
  height: 22px;
}
.rb-preview-state {
  padding: var(--space-5);
  text-align: center;
}
.rb-preview-state h4 {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  color: var(--color-text-primary);
}
.rb-dialog-layer {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
}
.rb-scrim {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
}
.rb-dialog {
  position: relative;
  width: 480px;
  max-width: calc(100vw - 48px);
  padding: var(--space-5);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-3);
}
.rb-ack-text {
  margin: 0 0 var(--space-2);
  color: var(--color-text-secondary);
}
.rb-done {
  max-width: 640px;
  margin: var(--space-10) auto 0;
  padding: var(--space-6);
  text-align: center;
}
.rb-check {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin: 0 auto var(--space-3);
  border-radius: 50%;
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
  font-size: 30px;
}
.rb-actions {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.rb-fail {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  color: var(--color-danger-strong);
  font-weight: var(--font-weight-semibold);
}

/* TERMREADER1 (DEC-487): the card reader a card payment will use, and the small link that changes it. */
.pay-confirm-reader-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-2) var(--space-5) 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.pay-confirm-switch-reader-link {
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--space-2);
  background: none;
  border: none;
  color: var(--color-accent);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

/* LOCPICK1: the publish dialog holds the definition and the shared inline location picker side by side, with no tabs. */
.fr-publish-sheet {
  max-width: 1180px;
  width: min(1180px, calc(100vw - 48px));
}
.fr-publish-columns {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--space-6);
  align-items: start;
}
.fr-publish-locations {
  margin-top: 0;
}
.fr-publish-picker {
  display: block;
  max-height: none;
  overflow: visible;
  padding: 0;
  border: 0;
}
.fr-publish-picker-hint {
  color: var(--color-danger-strong);
}
.rx-picker.inline .rx-picker-body {
  margin-top: var(--space-2);
}
.rx-picker.inline .rx-picker-list {
  height: auto;
  max-height: 262px;
}
.fr-publish-columns .fr-publish-slot {
  grid-template-columns: 1fr 1fr;
}
.rx-picker.inline .rx-pr {
  min-height: 34px;
}
.rx-picker.inline .rx-ck {
  width: 16px;
  height: 16px;
  border-width: 1.5px;
  border-radius: 4px;
  font-size: 11px;
}
.rx-picker.inline .rx-ck.rd {
  border-radius: 50%;
}
.rx-picker-hint {
  margin: var(--space-2) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.rx-chip.more {
  padding: 0 12px;
  border-color: var(--color-border);
  background: var(--color-surface-sunken);
  color: var(--color-text-primary);
  cursor: pointer;
}

/* FRFRESH1: the Location data freshness table, on the Dashboard and under the Franchisees list. */
.fr-fresh {
  margin-top: var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-fresh h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.fr-fresh-summary {
  margin: 0 0 var(--space-1);
  color: var(--color-text-primary);
}
.fr-fresh-muted {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-fresh-table th,
.fr-fresh-table td {
  text-align: left;
  vertical-align: top;
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  border-top: 1px solid var(--color-border);
  width: auto;
}
.fr-fresh-table thead th {
  border-top: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.fr-fresh-table .fr-fresh-number {
  font-variant-numeric: tabular-nums;
}
.fr-fresh-table tbody th {
  white-space: nowrap;
}
.fr-fresh-table .fr-fresh-flag {
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-strong);
}

/* FRCOMPS1: the Discounts and comps report (franchisor console, desktop sized). */
.fr-dc-help {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.fr-dc-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
  margin-bottom: var(--space-2);
}
.fr-dc-custom {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
}
.fr-dc-level {
  margin: var(--space-3) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-dc-level-text {
  margin: 0 0 var(--space-2);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.fr-dc-level-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.fr-dc-level-input {
  width: 8rem;
}
.fr-dc-muted {
  margin: var(--space-1) 0 var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-dc-summary {
  margin: 0 0 var(--space-1);
  color: var(--color-text-primary);
}
.fr-dc-table th,
.fr-dc-table td {
  text-align: left;
  vertical-align: top;
  font-size: var(--font-size-sm);
  color: var(--color-text-primary);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-2);
  border-top: 1px solid var(--color-border);
  width: auto;
}
.fr-dc-table thead th {
  border-top: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.fr-dc-table .fr-dc-number {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.fr-dc-table .fr-dc-total {
  font-weight: var(--font-weight-semibold);
}
.fr-dc-table .fr-dc-network th,
.fr-dc-table .fr-dc-network td {
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface);
}
.fr-dc-table tr.fr-dc-above th,
.fr-dc-table tr.fr-dc-above td {
  background: var(--color-danger-subtle);
}
.fr-dc-table tr.fr-dc-above th:first-child {
  border-left: 4px solid var(--color-danger-strong);
}
.fr-dc-name {
  display: block;
  font-weight: var(--font-weight-semibold);
}
.fr-dc-toggle {
  margin-top: var(--space-1);
  min-height: 2rem;
  padding: 0 var(--space-2);
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-primary);
  cursor: pointer;
}
.fr-dc-detail > td {
  padding-left: var(--space-5);
  background: var(--color-surface);
}
.fr-dc-lines th,
.fr-dc-lines td {
  border-top: 1px solid var(--color-border);
}
.fr-dc-lines .fr-dc-group {
  font-weight: var(--font-weight-semibold);
}
.fr-dc-lines .fr-dc-indent {
  padding-left: var(--space-5);
  font-weight: var(--font-weight-regular);
}
.fr-dc-table .fr-dc-number {
  white-space: nowrap;
}
.fr-dc-table .fr-dc-status {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}
.fr-dc-muted-line {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-regular);
}
.fr-dc-table {
  width: 100%;
}
.fr-dc-lines {
  width: 100%;
}
.fr-dc-lines td:nth-child(n + 3) {
  text-align: right;
  white-space: nowrap;
}
.fr-dc-level-label {
  margin-top: var(--space-2);
}
.fr-dc-lines th:nth-child(n + 3) {
  text-align: right;
}
.fr-dc-level-row .fr-dc-level-text {
  margin: 0 var(--space-4) 0 0;
}
.fr-dc-level-row .fr-dc-level-label {
  margin: 0;
}
.fr-dc-level {
  padding: var(--space-2) var(--space-4);
}
.fr-dc-level {
  margin: 0 0 0 auto;
  padding: 0;
  border: 0;
  background: transparent;
}
.fr-dc-toggle {
  white-space: nowrap;
}

/* ---------- RECUX2 (docs/build-briefs/RECUX2-franchisor-add-recipe.md; design/mockups/franchisor-add-recipe.html): the franchisor Add and
   Edit recipe dialog. One page of four numbered sections with a left checklist, and the Menu categories dialog. Desktop sized; every
   color and size is a design token. ---------- */
.fr-publish-sheet.fr-recipe-sheet {
  max-width: 1010px;
  width: min(1010px, calc(100vw - 40px));
  height: calc(100dvh - 58px);
  max-height: calc(100dvh - 58px);
}
.fr-recipe-sheet .fr-publish-body {
  padding: 0;
  max-height: none;
  scroll-behavior: smooth;
}
.fr-recipe-sheet .fr-publish-error:empty {
  display: none;
}
.fr-recipe-sheet #fr-publish-form-actions {
  align-items: center;
  justify-content: flex-end;
}
.fr-rc-hint {
  margin-right: auto;
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-hint[hidden] {
  display: none;
}
.fr-rc {
  display: grid;
  grid-template-columns: 196px minmax(0, 1fr);
  align-items: start;
}
.fr-rc[hidden] {
  display: none;
}
.fr-rc-rail {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5) var(--space-3) var(--space-5) var(--space-5);
  min-height: 100%;
  border-right: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}
.fr-rc-rail-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.fr-rc-rail-item.on {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
}
.fr-rc-dot {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--color-text-secondary);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  font-size: var(--font-size-xs);
}
.fr-rc-rail-item.done .fr-rc-dot {
  border-color: var(--color-success-strong);
  background: var(--color-success-strong);
  color: var(--color-text-on-accent);
}
.fr-rc-rail-item.bad .fr-rc-dot {
  border-color: var(--color-danger);
  background: var(--color-danger);
  color: var(--color-text-on-accent);
}
.fr-rc-main {
  min-width: 0;
  padding: 0 var(--space-6) var(--space-6);
}
.fr-rc-main > .fr-pub-meta {
  margin: var(--space-3) 0 0;
}
.fr-rc-section {
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--color-border);
}
.fr-rc-section:last-child {
  border-bottom: 0;
}
.fr-rc-sh {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.fr-rc-sh h3 {
  margin: 0;
  font-size: var(--font-size-md);
}
.fr-rc-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-full);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  align-items: start;
}
.fr-rc-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.fr-rc-newcat {
  margin-top: var(--space-1);
}
.fr-rc-err {
  color: var(--color-danger-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-err[hidden] {
  display: none;
}
.fr-rc-field.bad > .field-input,
.fr-rc-cell.bad > .field-input,
.fr-rc-cell.bad > .fr-rc-pick {
  border-color: var(--color-danger);
  background: var(--color-danger-subtle);
}
.fr-rc-targets.bad {
  border-radius: var(--radius-md);
  outline: 2px solid var(--color-danger);
  outline-offset: 2px;
}
/* Ingredients */
.fr-rc-ing-head,
.fr-rc-ing {
  display: grid;
  grid-template-columns: minmax(200px, 1.7fr) 86px 118px minmax(110px, 1fr) 78px;
  gap: var(--space-2);
  align-items: start;
}
.fr-rc-ing-head {
  margin-bottom: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-ing {
  position: relative;
  margin-bottom: var(--space-2);
}
.fr-rc-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.fr-rc-pick {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 38px;
  width: 100%;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  line-height: 1.25;
  cursor: pointer;
}
.fr-rc-pick .ph {
  color: var(--color-text-secondary);
}
.fr-rc-pick small {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-rc-pick.chosen {
  border-color: var(--color-accent-subtle-border);
  background: var(--color-accent-subtle);
}
.fr-rc-pick:disabled {
  cursor: default;
}
.fr-rc-remove[hidden] {
  display: none;
}
.fr-rc-menu {
  position: absolute;
  z-index: 30;
  top: 44px;
  left: 0;
  width: 420px;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.fr-rc-menu-search {
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}
.fr-rc-menu-list {
  max-height: 230px;
  overflow: auto;
}
.fr-rc-opt {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.fr-rc-opt:hover,
.fr-rc-opt:focus-visible {
  background: var(--color-surface-sunken);
}
.fr-rc-opt small {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-rc-menu-none {
  padding: var(--space-4);
  color: var(--color-text-secondary);
}
.fr-rc-menu-none p {
  margin: 0 0 var(--space-2);
}
.fr-rc-loading {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
}
.fr-rc-card {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  margin-bottom: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: 1.5px dashed var(--color-accent-subtle-border);
  border-radius: var(--radius-md);
  background: var(--color-accent-subtle);
}
.fr-rc-card.fail {
  border-color: var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
}
.fr-rc-card-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-card.fail .fr-rc-card-icon {
  background: var(--color-danger);
}
.fr-rc-card h4 {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-base);
}
.fr-rc-card p {
  max-width: 560px;
  margin: 0 0 var(--space-3);
  line-height: 1.45;
}
.fr-rc-card-actions {
  display: flex;
  gap: var(--space-2);
}
.fr-rc-ingwrap.ghost .fr-rc-ing-head,
.fr-rc-ingwrap.ghost .fr-rc-ings,
.fr-rc-ingwrap.ghost #fr-publish-slot-add {
  opacity: 0.5;
  pointer-events: none;
}
/* How to make it */
.fr-rc-sub {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold, 700);
}
.fr-rc-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-top: var(--space-1);
}
.fr-rc-chip {
  min-height: 28px;
  padding: 2px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-xs);
  cursor: pointer;
}
.fr-rc-steps {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.fr-rc-step {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: var(--space-2);
  align-items: start;
}
.fr-rc-step-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin-top: 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}
.fr-rc-step textarea {
  min-height: 56px;
  resize: vertical;
}
.fr-rc-step-controls {
  display: flex;
  gap: var(--space-1);
}
.fr-rc-step-controls [hidden] {
  display: none;
}
/* Who gets it */
.fr-rc-targets > .fr-publish-locations {
  margin-top: 0;
}
.fr-rc-adoption {
  margin-top: var(--space-4);
}
.fr-rc-adoption .fr-publish-adoption {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  border: 0;
}
.fr-rc-adoption .fr-publish-adoption legend {
  margin-bottom: var(--space-2);
  padding: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold, 700);
}
.fr-rc-adoption .admin-discount-check {
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.fr-rc-adoption .admin-discount-check:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle);
}
.fr-adopt-text {
  display: flex;
  flex-direction: column;
}
.fr-adopt-text small {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-adopt-text small[hidden] {
  display: none;
}
/* The Recipes page button and the Menu categories dialog */
.fr-publishing-menu-categories {
  margin-left: var(--space-2);
}
.fr-mc-dialog {
  width: min(560px, calc(100vw - 48px));
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-3);
}
.fr-mc-dialog::backdrop {
  background: var(--color-scrim);
}
.fr-mc-title {
  margin: 0 0 var(--space-1);
  font-size: var(--font-size-lg);
}
.fr-mc-intro {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
}
.fr-mc-list {
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
  max-height: 340px;
  overflow: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.fr-mc-row,
.fr-mc-empty {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.fr-mc-row:last-child,
.fr-mc-empty:last-child {
  border-bottom: 0;
}
.fr-mc-empty {
  color: var(--color-text-secondary);
}
.fr-mc-pos {
  flex: none;
  width: 24px;
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.fr-mc-name {
  flex: 1;
  min-width: 0;
  font-weight: var(--font-weight-semibold);
  overflow-wrap: anywhere;
}
.fr-mc-count {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.fr-mc-controls {
  display: flex;
  gap: var(--space-1);
}
.fr-mc-rename {
  flex: 1;
}
.fr-mc-add {
  display: flex;
  gap: var(--space-2);
  align-items: flex-end;
  margin-bottom: var(--space-3);
}
.fr-mc-add[hidden] {
  display: none;
}
.fr-mc-add-field {
  flex: 1;
}
.fr-mc-actions {
  display: flex;
  justify-content: flex-end;
}
.fr-mc-status:empty {
  display: none;
}
/* The location's read only view of a recipe's build instructions */
.admin-network-recipe-build {
  margin: var(--space-2) 0 0;
  padding: 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.admin-network-recipe-build li {
  margin-left: var(--space-5);
}
.fr-recipe-sheet #fr-publish-form-actions .btn-secondary,
.fr-recipe-sheet #fr-publish-form-actions .btn-primary {
  flex: none;
  min-width: 96px;
}
.fr-recipe-sheet #fr-publish-form-actions {
  justify-content: flex-end;
}
.fr-rc .field-input {
  background: var(--color-surface);
}
.fr-rc .fr-rc-field.bad > .field-input,
.fr-rc .fr-rc-cell.bad > .field-input {
  background: var(--color-danger-subtle);
}
.fr-rc .field-input:disabled {
  background: var(--color-surface-sunken);
}

/* RECUX2: the rail sticks inside the scrolling dialog body; fields, buttons and the picker are compact so the sections read at a glance. */
.fr-rc {
  align-items: stretch;
}
.fr-rc-rail {
  display: block;
  position: static;
  padding: 0;
  min-height: 0;
}
.fr-rc-rail-inner {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5) var(--space-3) var(--space-5) var(--space-5);
}
.fr-rc .field-input,
.fr-rc .fr-rc-pick {
  min-height: 40px;
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
}
.fr-rc .fr-rc-pick {
  padding-block: var(--space-1);
}
.fr-rc .btn-secondary,
.fr-rc .btn-primary {
  min-height: 36px;
  padding: var(--space-1) var(--space-4);
  font-size: var(--font-size-sm);
}
.fr-rc .fr-rc-chip {
  min-height: 28px;
  padding: 2px var(--space-3);
}
.fr-rc-ing-head,
.fr-rc-ing {
  grid-template-columns: minmax(200px, 1.7fr) 86px 118px minmax(110px, 1fr) 92px;
}
.fr-rc .fr-rc-remove {
  padding-inline: var(--space-2);
}
.fr-rc .rx-picker.inline .rx-picker-list {
  max-height: 150px;
}
.fr-rc-section {
  padding: var(--space-4) 0;
}
.fr-rc .fr-publish-locations > .field-label {
  margin-top: 0;
}
.fr-rc textarea.field-input {
  font: inherit;
  font-size: var(--font-size-sm);
}
.fr-rc .fr-publish-locations > #fr-publish-locations-title {
  display: none;
}
.fr-rc .rx-picker.inline .rx-picker-list {
  max-height: 120px;
}
.fr-mc-dialog .btn-secondary,
.fr-mc-dialog .btn-primary {
  min-height: 36px;
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
}
.fr-mc-controls .btn-secondary {
  min-width: 36px;
}
.fr-mc-dialog .field-input {
  min-height: 40px;
  background: var(--color-surface);
  font-size: var(--font-size-sm);
}
.fr-mc-controls .btn-secondary:disabled {
  opacity: 0.45;
}

/* FRSCALE1 (docs/build-briefs/FRSCALE1-royalty-at-scale.md): the shared franchisor list and the Royalty page built on it
   (design/mockups/royalty-at-scale.html). Desktop sized. Tokens only; a chip is never colour alone (symbol plus words). */
.fr-royalty-page {
  margin-top: var(--space-2);
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
}

.fl-tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-4);
}

.fl-tab {
  appearance: none;
  border: 0;
  background: transparent;
  padding: var(--space-3) var(--space-5);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  min-height: var(--touch-target-comfortable);
  cursor: pointer;
}

.fl-tab[aria-selected="true"] {
  color: var(--color-accent-strong);
  border-bottom-color: var(--color-accent-strong);
}

.fl-tab:focus-visible,
.fl-btn:focus-visible,
.fl-link:focus-visible,
.fl-chev:focus-visible,
.fl-rname:focus-visible,
.fl-gname-button:focus-visible,
.fl-varies:focus-visible,
.fl-x:focus-visible,
.fl-ctl:focus-visible,
.fl-table th button:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.fl-tools {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-3);
  flex-wrap: wrap;
}

.fl-title-row {
  gap: var(--space-3);
}

.fl-lab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
}

.fl-grow {
  flex: 1;
  min-width: 180px;
}

.fl-sp {
  margin-left: auto;
}

.fl-ctl {
  min-height: 38px;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
}

.fl-btn {
  appearance: none;
  min-height: 38px;
  padding: var(--space-1) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  white-space: nowrap;
  cursor: pointer;
}

.fl-btn:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}

.fl-btn:disabled {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  color: var(--color-text-tertiary);
  cursor: default;
}

.fl-btn-primary {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}

.fl-btn-primary:hover:not(:disabled) {
  background: var(--color-accent);
}

.fl-btn-small {
  min-height: 32px;
  padding: 0 var(--space-3);
}

.fl-link {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-accent-strong);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.fl-link-light {
  color: var(--color-text-on-accent);
}

.fl-strip {
  display: grid;
  grid-template-columns: repeat(var(--fl-tiles, 6), minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.fl-kpi {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  min-width: 0;
}

.fl-kpi small {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.fl-kpi b {
  display: block;
  font-size: var(--font-size-lg);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fl-kpi i {
  font-style: normal;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}

.fl-kpi-bad {
  border-color: var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
}

.fl-kpi-bad b {
  color: var(--color-danger-strong);
}

.fl-banner {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
  font-weight: var(--font-weight-semibold);
}

.fl-banner-ok {
  background: var(--color-success-subtle);
  color: var(--color-success-strong);
}

.fl-banner-bad {
  background: var(--color-danger-subtle);
  color: var(--color-danger-strong);
}

.fl-banner-warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}

.fl-wrap {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.fl-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.fl-table th {
  background: var(--color-surface-sunken);
  text-align: left;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-secondary);
  padding: 0;
  border-bottom: 1px solid var(--color-border);
}

.fl-table th button {
  appearance: none;
  width: 100%;
  border: 0;
  background: transparent;
  text-align: inherit;
  font: inherit;
  color: inherit;
  padding: var(--space-3) var(--space-2);
  min-height: 38px;
  cursor: pointer;
}

.fl-table th.fl-num button {
  text-align: right;
}

.fl-table th[aria-sort] button {
  color: var(--color-text-primary);
}

.fl-table th.fl-plain {
  padding: var(--space-3) var(--space-2);
}

.fl-table td {
  padding: 0 var(--space-2);
  height: 40px;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
  font-size: var(--font-size-sm);
}

.fl-table td.fl-wrap-cell {
  white-space: normal;
}

.fl-table .fl-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.fl-table .fl-check {
  padding: 0 var(--space-2);
  text-align: center;
  overflow: visible;
}

.fl-table td.fl-name {
  white-space: normal;
}

.fl-table td.fl-name .fl-sub {
  white-space: nowrap;
}

.fl-table-plain .fl-grp td {
  background: var(--color-surface);
  font-weight: var(--font-weight-regular);
  height: 44px;
}

.fl-table-plain .fl-grp td.fl-name {
  font-weight: var(--font-weight-bold);
}

.fl-table-plain .fl-loc td {
  background: var(--color-surface-sunken);
}

.fl-table input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--color-accent-strong);
}

.fl-grp td {
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-semibold);
  height: 42px;
}

.fl-loc td {
  background: var(--color-surface);
}

.fl-loc .fl-name-row {
  padding-left: var(--space-10);
}

.fl-clickable {
  cursor: pointer;
}

.fl-clickable:hover td {
  background: var(--color-accent-subtle);
}

.fl-row-focus td {
  background: var(--color-accent-subtle);
  box-shadow: inset 0 0 0 1px var(--color-accent-subtle-border);
}

.fl-sub {
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-xs);
}

.fl-chev {
  appearance: none;
  border: 0;
  background: transparent;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
  vertical-align: middle;
}

.fl-chev:hover {
  background: var(--color-border);
}

.fl-rname,
.fl-gname-button {
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  padding: var(--space-1) 0;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.fl-gname-button {
  font-weight: var(--font-weight-bold);
}

.fl-varies {
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-strong);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.fl-chips {
  display: inline-flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  align-items: center;
  white-space: normal;
  padding: var(--space-1) 0;
}

.fl-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 24px;
  padding: 1px var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: normal;
}

.fl-chip-good {
  background: var(--color-success-subtle);
  border-color: var(--color-success-subtle-border);
  color: var(--color-success-strong);
}

.fl-chip-info {
  background: var(--color-info-subtle);
  border-color: var(--color-info-subtle-border);
  color: var(--color-info-text);
}

.fl-chip-bad {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger-subtle-border);
  color: var(--color-danger-strong);
}

.fl-chip-warn {
  background: var(--color-warning-subtle);
  border-color: var(--color-warning-subtle-border);
  color: var(--color-warning-strong);
}

.fl-chip-neutral {
  background: var(--color-surface-sunken);
  border-color: var(--color-border-strong);
  color: var(--color-text-secondary);
}

.fl-chip-symbol {
  font-weight: var(--font-weight-bold);
}

.fl-pager {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
}

.fl-empty {
  padding: var(--space-12) var(--space-5);
  text-align: center;
  color: var(--color-text-secondary);
}

.fl-empty b {
  display: block;
  font-size: var(--font-size-md);
  color: var(--color-text-primary);
  margin-bottom: var(--space-1);
}

.fl-selected-strip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
}

.fl-selected-strip[hidden] {
  display: none;
}

.fl-selected-strip .fl-btn {
  background: var(--color-surface);
  color: var(--color-accent-strong);
  border-color: var(--color-surface);
}

/* The side panel and the bulk dialog are built at runtime. */
.fl-panel-holder {
  --fl-panel-top: 0px;
}

.fl-veil {
  position: fixed;
  inset: var(--fl-panel-top) 0 0 0;
  background: var(--color-scrim);
  opacity: 0.45;
  z-index: 79;
}

.fl-panel {
  position: fixed;
  top: var(--fl-panel-top);
  right: 0;
  bottom: 0;
  width: 440px;
  max-width: 100%;
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
  box-shadow: var(--shadow-3);
  z-index: 80;
  display: flex;
  flex-direction: column;
}

.fl-panel:focus {
  outline: none;
}

.fl-panel-head {
  padding: var(--space-4) var(--space-5) var(--space-2);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  justify-content: space-between;
}

.fl-panel-head h2 {
  margin: 0;
  font-size: var(--font-size-lg);
}

.fl-panel-sub {
  display: block;
  margin-top: var(--space-1);
}

.fl-x {
  appearance: none;
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  font-size: var(--font-size-xl);
  line-height: 1;
  border-radius: var(--radius-md);
  color: var(--color-text-secondary);
  cursor: pointer;
}

.fl-x:hover {
  background: var(--color-surface-sunken);
}

.fl-panel-body {
  padding: var(--space-1) var(--space-5) var(--space-4);
  overflow: auto;
  flex: 1;
}

.fl-panel-foot {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  align-items: center;
}

.fl-hint {
  margin-right: auto;
  color: var(--color-danger-strong);
  font-size: var(--font-size-xs);
}

.fl-sec {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.fl-facts {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr auto;
}

.fl-facts dt,
.fl-facts dd {
  margin: 0;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-sm);
}

.fl-facts dt {
  color: var(--color-text-secondary);
}

.fl-facts dd {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-semibold);
}

.fl-facts .fl-tot {
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.fl-box {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
}

.fl-box-bad {
  border-color: var(--color-danger-subtle-border);
  background: var(--color-danger-subtle);
}

.fl-box-warn {
  border-color: var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
}

.fl-box-text {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
}

.fl-resolve-slot {
  margin-top: var(--space-3);
}

.fl-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.fl-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  margin-bottom: var(--space-3);
}

.fl-form .fl-field {
  margin-bottom: 0;
}

.fl-field .fl-ctl {
  font-weight: var(--font-weight-regular);
  width: 100%;
}

.fl-actions {
  display: flex;
  gap: var(--space-2);
}

.fl-error {
  margin: 0;
  color: var(--color-danger-strong);
  font-size: var(--font-size-xs);
}

.fl-edit-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-xs);
}

.fl-edit-table th {
  text-align: left;
  background: var(--color-surface-sunken);
  padding: var(--space-2) var(--space-2);
  color: var(--color-text-secondary);
}

.fl-edit-table td {
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  height: 44px;
}

.fl-pick {
  min-height: 32px;
  width: 112px;
  font-size: var(--font-size-xs);
}

.fl-now {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
}

.fl-sched {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--font-size-sm);
}

.fl-sched li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.fl-hist {
  font-size: var(--font-size-xs);
}

.fl-hist div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.fl-dialog-holder {
  position: fixed;
  inset: 0;
  z-index: 85;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fl-dialog-veil {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
}

.fl-dialog {
  position: relative;
  width: 460px;
  max-width: 94vw;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: var(--space-5) var(--space-6);
}

.fl-dialog h2 {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-lg);
}

.fl-dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-3);
  align-items: center;
}

.fl-state-empty .fl-empty b {
  font-size: var(--font-size-md);
}

/* UIFIX1 (DEC-500, SF-6): the older franchisor reports carry the Reports frame's crumb in place of the pill row and the
   console page title. */
.fr-reports-crumb h1 {
  margin: 0;
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}
body:has(#fr-reports-crumb:not([hidden])) #fr-home-title {
  display: none;
}
#fr-reports-section .fr-card-head .fr-card-title,
#fr-dc-section .fr-card-title {
  display: none;
}
#fr-reports-section .fr-card-head,
#fr-dc-section .fr-card-head {
  justify-content: flex-end;
}

/* UIFIX1 (SF-3): an empty page is one sentence in a short row. */
.rc-panel .rc-empty-sentence {
  margin: 0;
  padding: var(--space-3) var(--space-2);
  color: var(--color-text-secondary);
}

/* FRMERGE1: the group row's arrow sits inline, left of the name, with the chip and count in one column beside it. */
.fl-gline {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
}

.fl-gline .fl-chev {
  flex: none;
}

.fl-gbody {
  min-width: 0;
  padding-top: var(--space-1);
}

/* FRLOC1 (docs/build-briefs/FRLOC1-franchisor-locations.md): the Locations page and its side panel. */
.fl-big {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}

.fl-zero {
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
}

.fl-warnings {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* FRDETAIL1 (docs/build-briefs/FRDETAIL1-franchisee-dashboard.md; design/style-guide.md): the franchisee dashboard in the franchisor
   console. Reuses the shared .fl-strip, .fl-kpi, .fl-wrap, .fl-table, .fl-chip and .fl-link; tokens only. */
body:has(.fd-page:not([hidden])) #fr-home-title {
  display: none;
}

.fd-page {
  display: grid;
  gap: var(--space-6);
  max-width: 1400px;
}

.fd-section {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.fd-crumb {
  margin-bottom: 0;
}

.fd-h1 {
  margin: 0;
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
}

.fd-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-8);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.fd-fact {
  min-width: 0;
}

.fd-fact dt {
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
}

.fd-fact dd {
  margin: 0;
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fd-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.fd-head .fd-seg {
  margin-left: auto;
}

.fd-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}

.fd-sub-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.fd-seg {
  display: inline-flex;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.fd-seg-button {
  appearance: none;
  min-height: 38px;
  padding: var(--space-1) var(--space-4);
  border: 0;
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  white-space: nowrap;
  cursor: pointer;
}

.fd-seg-button + .fd-seg-button {
  border-left: 1px solid var(--color-border-strong);
}

.fd-seg-button[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-semibold);
}

.fd-seg-button:focus-visible {
  outline: none;
  box-shadow: inset var(--shadow-focus);
}

.fd-chart {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}

.fd-svg {
  display: block;
  width: 100%;
  height: 220px;
}

.fd-grid {
  stroke: var(--color-border);
  stroke-width: 1;
}

.fd-axis {
  fill: var(--color-text-secondary);
  font-size: 12px;
}

.fd-mark {
  fill: var(--color-accent);
}

.fd-chart-sum,
.fd-chart-empty,
.fd-note,
.fd-empty,
.fd-asof {
  margin: 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.fd-chart-sum {
  margin-top: var(--space-2);
}

.fd-empty {
  padding: var(--space-3) 0;
}

.fd-block {
  display: grid;
  gap: var(--space-2);
}

.fd-more {
  justify-self: start;
}

.fd-two {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.fd-drinks {
  min-width: 0;
}

.fd-table tfoot td {
  border-top: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  font-weight: var(--font-weight-semibold);
}

.fd-message {
  margin-top: var(--space-4);
}

.fd-table .fl-sub {
  display: block;
}

.fd-table th {
  padding: var(--space-2) var(--space-3);
}

.fd-table td {
  padding-left: var(--space-3);
  padding-right: var(--space-3);
}

.fd-h1:focus {
  outline: none;
}

/* LEGAL1-F1: the Privacy and Terms footer links on every sign-in screen and console, and the required agreement checkbox. */
.legal-links {
  display: flex;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-4) var(--space-6);
  font-size: var(--font-size-sm);
}
.legal-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  padding: 0 var(--space-2);
  color: var(--color-accent-strong);
  text-decoration: underline;
}
.legal-links a:focus-visible,
.legal-agree a:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.legal-agree {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin: var(--space-4) 0;
  min-height: var(--touch-target-min);
  font-size: var(--font-size-base);
  color: var(--color-text-primary);
  line-height: var(--line-height-relaxed);
}
.legal-agree input[type="checkbox"] {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
}
.legal-agree a {
  color: var(--color-accent-strong);
  text-decoration: underline;
}
/* The sign-in screens centre one card in a full-height flex row; the footer links sit at the foot of the screen, not beside it. */
#terminal-setup-screen,
#user-picker-screen,
#pin-entry-screen {
  position: relative;
}
#terminal-setup-screen > .legal-links,
#user-picker-screen > .legal-links,
#pin-entry-screen > .legal-links {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding-bottom: var(--space-4);
}

/* ---------- OWNADDLOC1 (docs/build-briefs/OWNADDLOC1-add-location-existing-customer.md; P0.39; design/style-guide.md) ----------
   Add location on a customer's Locations card: a runtime sheet (src/softwareOwnerAddLocation.ts) and a setup list under
   each location. State is words first (Done, To do, N/A, Unavailable); colour only reinforces it. */
.so-addloc-sheet {
  border-radius: var(--radius-xl);
  max-width: 560px;
}
.so-addloc-body {
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-height: calc(100vh - 240px);
  overflow-y: auto;
}
.so-addloc-entity {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  min-width: 0;
}
.so-addloc-legend {
  padding: 0 var(--space-1);
  font-weight: var(--font-weight-medium);
}
.so-addloc-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  color: var(--color-text-primary);
}
.so-addloc-choice input {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: var(--space-1);
}
.so-addloc-choice-name {
  display: block;
  overflow-wrap: anywhere;
}
.so-addloc-choice-note {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.so-addloc-choice-off {
  color: var(--color-text-secondary);
}
.so-addloc-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: var(--space-3);
}
.so-addloc-own {
  margin: 0;
}
.so-addloc-error {
  margin: 0;
  padding: var(--space-2) var(--space-5) 0;
}
.so-addloc-setup {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.so-addloc-setup-line {
  display: grid;
  grid-template-columns: 14em 6em minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target-min);
  padding: var(--space-1) 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-base);
}
.so-addloc-setup-label {
  color: var(--color-text-primary);
}
.so-addloc-setup-rest {
  min-width: 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.so-addloc-setup-rest ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.so-addloc-setup-rest p {
  margin: 0;
}
.so-addloc-setup-note {
  margin: 0;
}
.so-addloc-locations,
.so-locations-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
}
.so-addloc-location {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
}
.so-addloc-location-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
}
.so-addloc-location-name {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-lg);
}
.so-addloc-location-meta {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#software-owner-locations-card {
  grid-column: 1 / -1;
}

/* ===================================================================================================
   UIFIX6 (docs/build-briefs/UIFIX6-franchisor-owner-page-fixes.md, design/style-guide.md sections 7, 8, 10)
   Franchisor and Software Owner page fixes. Tokens only.
   ========================================================================================================== */

/* PAGE-1, owner #1 and #2: the sign-in links use the console link color, and the empty error slots close up so the
   button follows the field. */
.so-card .so-note a {
  color: var(--color-accent-strong);
  text-decoration: underline;
}
#fr-signin-form .field-error:empty,
#so-signin-form .field-error:empty {
  display: none;
}

/* PAGE-3: Refresh and Edit sit together in the date band; one muted line carries the update time. */
.fr-dashboard-band-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 0 0 auto;
}
.fr-dashboard-figures-note {
  grid-column: 1 / -1;
}

/* PAGE-2: Add product, Add kind and Add category open as a right side sheet like the Team invite, with the footer
   pinned. The Catalog activation panel is a quiet info line instead of a boxed error. */
#fr-catalog-section .catalog-editor:has(> form) {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: var(--z-sheet);
  width: min(480px, 100%);
  margin: 0;
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-y: auto;
  background: var(--color-surface);
  border: 0;
  border-left: 1px solid var(--color-border-strong);
  border-radius: 0;
  box-shadow: 0 0 0 100vmax rgb(0 0 0 / 0.35);
}
#fr-catalog-section .catalog-editor > h3 {
  margin: 0;
  font-size: var(--font-size-lg);
}
#fr-catalog-section .catalog-editor .catalog-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
#fr-catalog-section .catalog-editor .catalog-fields > .catalog-actions {
  position: sticky;
  bottom: calc(var(--space-5) * -1);
  margin: auto calc(var(--space-5) * -1) calc(var(--space-5) * -1);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  flex-wrap: nowrap;
  justify-content: space-between;
}
#fr-catalog-section .catalog-editor .catalog-fields > .catalog-actions > button {
  flex: 1 1 0;
}
#fr-catalog-section .catalog-editor .catalog-fields > .catalog-actions > button[type="submit"] {
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  border-color: transparent;
}
#fr-catalog-section .catalog-editor:not(:has(> form)) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 0;
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
}
#fr-catalog-section .catalog-editor:not(:has(> form)) p {
  margin: 0;
  color: var(--color-text-secondary);
}
#fr-catalog-section .catalog-editor:not(:has(> form)) .catalog-actions {
  margin: 0;
}
#fr-catalog-section .catalog-network input[type="search"],
#fr-catalog-section input[type="search"] {
  flex: 1 1 280px;
  min-width: 260px;
}
#fr-catalog-section .catalog-actions select {
  min-width: 160px;
}

/* PAGE-5: one heading size on Billing, the month label above its field, Refresh small and secondary. */
.fr-ai-billing-layout .cr-ai-billing > h4,
.fr-ai-billing-layout .cr-ai-billing-heading h4 {
  margin: 0;
  font-size: var(--font-size-xl);
}
.fr-ai-billing-layout .fb-toolbar,
.fr-ai-billing-layout .cr-ai-billing-month {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}
.fr-ai-billing-layout .cr-ai-billing > button {
  min-height: var(--touch-target-min);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
}

/* PAGE-6: a logo frame with no logo says so; Save sits in a sticky footer strip under the form. */
.fr-logo-frame:has(> .fr-logo-img[hidden])::after {
  content: "No logo";
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
}
.fr-brand-savebar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-2);
  padding: var(--space-3) 0;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}
.fr-brand-savebar .so-submit {
  width: auto;
  min-width: 160px;
  margin-top: 0;
}
.fr-brand-savebar .fr-card-help {
  margin: 0;
}

/* PAGE-7: the empty recipe list sits under its search field with one next action. */
#fr-publishing-empty .fr-pub-empty-add {
  margin-top: var(--space-2);
}
#fr-publishing-empty .fr-pub-empty-add[hidden] {
  display: none;
}

/* PAGE-10: one line per audit event; the full lines open on tap. */
.fr-audit-toggle {
  display: flex;
  align-items: flex-start;
  width: 100%;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.fr-audit-toggle .fr-audit-summary-text {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.fr-audit-toggle[aria-expanded="true"] .fr-audit-summary-text {
  font-weight: var(--font-weight-semibold);
}
.fr-audit-lines[hidden] {
  display: none;
}
.fr-audit-lines {
  padding-bottom: var(--space-2);
}
.fr-audit-pager button[hidden] {
  display: none;
}

/* Owner: the customer Save row sticks to the foot of the window; an empty Customer column and the Documents picker with
   nothing to pick are not drawn; the Access cards share a row height; the go-live card takes the full width. */
.so-customer-save {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  padding: var(--space-3) 0;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}
.so-audit-no-customer th:nth-child(4),
.so-audit-no-customer td:nth-child(4) {
  display: none;
}
.admin-field[hidden] {
  display: none;
}
.so-documents-entity[hidden] {
  display: none;
}
#software-owner-customer-panel-access {
  align-items: stretch;
}
#software-owner-customer-panel-overview > #software-owner-golive-card {
  grid-column: 1 / -1;
}
/* Owner Dashboard #7: a tile sub-line wraps instead of touching the card edge; one remaining card takes the row. */
.so-dash-kpi-sub {
  overflow-wrap: anywhere;
}
.so-dash-grid-two > :only-child {
  grid-column: 1 / -1;
}
.so-golive-fix {
  min-width: 200px;
  justify-content: center;
}

/* ===================================================================================================
   UIFIX4 (docs/build-briefs/UIFIX4-rows-chips-cards-wizards.md, design/style-guide.md sections 8, 9 and 16)
   Row actions, chips that do not wrap, equal-height cards and the wizard shell. Tokens only.
   ========================================================================================================== */

/* SF-17 and UIFIX3: one Actions menu per row, for every table (rowMenu.ts). A row with more than one action shows one
   "Actions" trigger; the options open under it, right aligned, above the table that holds the row. */
.row-menu {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}
.row-menu-trigger {
  height: var(--touch-target-min);
  min-height: var(--touch-target-min);
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.row-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-1));
  z-index: var(--z-ticket-rail);
  min-width: 200px;
  display: flex;
  flex-direction: column;
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
}
.row-menu-panel[hidden] {
  display: none;
}
.row-menu-panel > .row-menu-item {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  min-height: var(--touch-target-comfortable);
  margin: 0;
  padding: 0 var(--space-3);
  border-color: transparent;
  text-align: left;
  white-space: nowrap;
}
.row-menu-panel > .row-menu-item.btn-danger,
.row-menu-panel > .row-menu-item.btn-text-danger {
  color: var(--color-danger-strong);
}
/* The action cells that hold a menu keep one line and line up on the right in every row. */
.so-plans-action-box,
.so-account-actions,
.admin-user-actions,
.fr-team-table td.fr-team-actions {
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
}
.fr-team-table td.fr-team-actions {
  display: table-cell;
  text-align: right;
  white-space: nowrap;
  vertical-align: middle;
}
.fr-team-actions .fr-team-small {
  vertical-align: middle;
}
/* The "You" chip sits beside the name on the signed-in person's row (the Actions cell holds only buttons). */
.fr-team-name .fr-team-you {
  flex: 0 0 auto;
  white-space: nowrap;
}
/* A repeated Mark out is a plain outlined button, not a red one on every row: the red Out chip already says the item
   is out, and a screen carries at most one outlined red button. Back in stock keeps its green. */
.inv-stock-btn:not(.inv-stock-btn--back),
.stock86-btn-mark {
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
}

/* SF-18: a chip, pill or badge is one line. A long status words a shorter chip; it never wraps to a second line. */
.so-pill,
.so-badge,
.admin-user-badge,
.admin-chip-option-label,
.purchasing-cart-chip,
.frdisc-badge,
.frdisc-count,
.fr-team-you,
.stock86-chip,
.so-ai-current,
.so-progress-step {
  white-space: nowrap;
}
.purchasing-cart-chip {
  flex: 0 0 auto;
}

/* SF-19: cards in one row share a height. A customer's tab panel stretches its cards, so a short card pairs with a tall
   one as a row and not as a ragged gap; the dashboard rows already stretch. */
.so-detail-grid > .so-customer-panel {
  align-items: stretch;
}
.so-dash-grid > .so-dash-card {
  height: 100%;
}

/* SF-20: the wizard shell. The Onboard flow is one centred column, its steps are numbered and readable, the step name
   is not repeated as "Step 3 of 7" on screen (the count stays for screen readers), and the AI provider wizard gets
   numbered steps and two-up price boxes. */
.so-wizard {
  max-width: 800px;
  margin-inline: auto;
}
.so-wizard[data-page="defaults"],
.so-wizard[data-page="review"] {
  max-width: 1100px;
}
.so-wizard-count {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.so-progress {
  grid-auto-columns: minmax(max-content, 1fr);
  counter-reset: sostep;
}
.so-progress-step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-2);
  font-size: var(--font-size-xs);
  counter-increment: sostep;
}
.so-progress-step::before {
  content: counter(sostep);
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  border: 1px solid currentColor;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.so-progress-step.is-current::before {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.so-progress-step.is-done::before {
  content: "\2713";
  background: var(--color-success-subtle);
}
.so-progress-step.is-done > span[aria-hidden="true"] {
  display: none;
}
.so-wizard-body {
  padding-bottom: var(--space-4);
}
dialog.so-ai-dialog {
  width: min(640px, 92vw);
}
.so-ai-steps {
  counter-reset: aistep;
  align-items: center;
}
.so-ai-step {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
  counter-increment: aistep;
}
.so-ai-step::before {
  content: counter(aistep);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  border: 1px solid currentColor;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.so-ai-step-current::before {
  background: var(--color-accent-strong);
  border-color: var(--color-accent-strong);
  color: var(--color-text-on-accent);
}
.so-ai-step-done::before {
  content: "\2713";
  background: var(--color-success-subtle);
}
.so-ai-price-grid .admin-field {
  margin: 0;
}
.so-ai-price-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: end;
}

/* ===================================================================================================
   UIFIX2 (docs/build-briefs/UIFIX2-sheets-forms-states.md, design/style-guide.md sections 7, 8, 10, 16)
   Sheets, forms, toasts, failure states and sticky strips. Tokens only.
   ========================================================================================================== */

/* SF-9: with a sheet open the toast sits above that sheet (main.ts toastSheetBox), centered on the sheet, so it
   never lies over a button in the sheet or its footer. */
.toast-slot[data-dock="sheet"] {
  top: var(--toast-sheet-top, var(--toast-slot-top));
  bottom: auto;
  left: var(--toast-sheet-left, 0);
  right: var(--toast-sheet-right, 0);
}

/* SF-8: one sheet. An admin sheet (the Settings and manager forms and their confirm sheets) is centered with room
   on every side, never edge to edge, 640px at most, capped at the viewport minus the safe area, with its header and
   footer pinned and only the body scrolling. 24px padding on header, body and footer. Floor sheets keep their own
   iPad shape. A drawer (the role editor, the franchisor Team invite) is not a sheet and is left alone. */
.scrim:has(> .admin-form-sheet):not(.rl-drawer),
.scrim:has(> .admin-confirm-sheet),
.scrim:has(> .manager-exceptions-sheet) {
  align-items: center;
  box-sizing: border-box;
  padding: var(--space-6) var(--space-4);
}
.scrim:not(.rl-drawer) > .admin-form-sheet,
.scrim > .admin-confirm-sheet,
.scrim > .manager-exceptions-sheet {
  border-radius: var(--radius-xl);
  max-height: calc(100dvh - var(--space-12) - env(safe-area-inset-top, 0px));
}
.admin-form-sheet .sheet-header,
.admin-confirm-sheet .sheet-header,
.manager-exceptions-sheet .sheet-header {
  padding: var(--space-6) var(--space-6) var(--space-4);
}
.admin-form-sheet > .sheet-body,
.admin-confirm-sheet > .sheet-body,
.manager-exceptions-sheet > .sheet-body {
  padding: var(--space-4) var(--space-6);
}
.admin-form-sheet > .sheet-footer,
.admin-confirm-sheet > .sheet-footer {
  padding: var(--space-4) var(--space-6) var(--space-6);
}

/* SF-8: the footer pair. Cancel (secondary) sits left of Save (primary), the same height and the same width. Both take
   half the row less half the gap as their basis: a basis of 0 would still add each button's own padding and border, and
   the two buttons carry different ones. The
   error line, when a footer has one, stays above the pair. The one rule covers the sheet footers, the confirm rows
   and the Add user and Add item rows, so no screen carries a wide Cancel beside a small Save. */
.sheet-actions {
  display: flex;
  gap: var(--space-3);
}
.sheet-actions > .btn-primary,
.sheet-actions > .btn-secondary,
.sheet-actions > .btn-danger,
.admin-confirm-actions > .btn-primary,
.admin-confirm-actions > .btn-secondary,
.admin-confirm-actions > .btn-danger,
.confirm-actions > .btn-primary,
.confirm-actions > .btn-secondary,
.confirm-actions > .btn-danger {
  flex: 1 1 calc((100% - var(--space-3)) / 2);
  box-sizing: border-box;
  min-width: 0;
  width: auto;
  min-height: var(--touch-target-comfortable);
}
.admin-confirm-actions {
  padding-inline: var(--space-6);
}
/* A Cancel and Save row that lives inside a scrolling sheet body (the Add user steps) is pinned to the body's bottom,
   so Save never scrolls out of reach. */
.admin-form-sheet .sheet-body > section > .confirm-actions,
.admin-form-sheet .sheet-body > .confirm-actions {
  position: sticky;
  bottom: calc(-1 * var(--space-4));
  z-index: 1;
  margin: var(--space-4) calc(-1 * var(--space-6)) calc(-1 * var(--space-4));
  padding: var(--space-4) var(--space-6);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

/* SF-8: form rhythm inside a sheet. A label sits 4px above its input, fields are 16px apart, sections 32px apart.
   A row of two fields keeps the same gap above it, so a label never touches the input above. */
.admin-form-sheet .sheet-body .admin-field-row {
  margin-top: var(--space-4);
}
.admin-form-sheet .sheet-body > .admin-field-row:first-child,
.admin-form-sheet .sheet-body > section > .admin-field-row:first-child {
  margin-top: 0;
}
/* A label that opens a wrapper (a field group inside the form) still sits 16px under the field above it. */
.admin-form-sheet .sheet-body div:not(:first-child) > .field-label:first-child {
  margin-top: var(--space-4);
}
.admin-form-sheet .sheet-body .admin-field-row .field-label:first-child {
  margin-top: 0;
}
.admin-form-sheet .sheet-body .section-title,
.admin-form-sheet .sheet-body .admin-subsection-title {
  margin-top: var(--space-8);
}
.admin-form-sheet .sheet-body .section-title:first-child,
.admin-form-sheet .sheet-body .admin-subsection-title:first-child {
  margin-top: 0;
}
.admin-form-sheet .sheet-body .field-label {
  text-transform: none;
}
.admin-form-sheet .sheet-body .field-input {
  margin-bottom: 0;
}

/* SF-10: the one failure state (src/failureState.ts). Plain sentence, "!" so colour is never alone, a styled
   Try again. */
.failure-state {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger-subtle-border);
  border-radius: var(--radius-md);
  color: var(--color-danger-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.failure-state-symbol {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-full);
  background: var(--color-danger-strong);
  color: var(--color-text-on-dark);
  font-weight: var(--font-weight-bold);
}
.failure-state-text {
  flex: 1 1 auto;
  min-width: 0;
}
.failure-state-retry {
  flex: 0 0 auto;
  min-height: var(--touch-target-min);
}

/* SF-11: a sticky strip is opaque, throws a shadow and reserves its height. The Settings jump strip sticks to the very
   top of the scroll area, so no content shows above it, and carries a shadow. The starting-stock count strip (already opaque, with this shadow) and the
   onboarding Back and Continue strip take the same treatment, and the scroll area
   keeps the strip's height clear when something is scrolled into view or focused. */
:root {
  --sticky-strip-height: calc(var(--space-16) + var(--space-4));
}
.admin-section-jump {
  top: 0;
  background: var(--color-surface);
  box-shadow: var(--shadow-2);
}
#app-shell {
  scroll-padding-bottom: var(--sticky-strip-height);
}
.so-wizard-footer {
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.so-wizard-footer {
  margin-inline: calc(-1 * var(--space-4));
  padding-inline: var(--space-4);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
#admin-starting-stock-screen .ss-rule {
  color: var(--color-info);
}

/* SF-12: Settings shell. "Set up this location" folds to one 56px row with its progress count; the group's own
   content starts right under it. */
#admin-screen .admin-setup-checklist:has(> .admin-setup-checklist-list[hidden]) {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-comfortable);
  padding: 0 var(--space-4);
  margin-bottom: var(--space-4);
}
.admin-setup-checklist:has(> .admin-setup-checklist-list[hidden]) .admin-setup-checklist-header {
  flex: 1 1 auto;
  align-items: center;
  margin-bottom: 0;
}
.admin-setup-checklist:has(> .admin-setup-checklist-list[hidden]) .admin-setup-checklist-title {
  font-size: var(--font-size-md);
}

/* SF-8: the Software Owner dialogs take the same pair: two buttons share the footer equally, Cancel left. A footer
   with one button (Done) keeps its natural width. */
.so-cp-dialog-foot:has(> button + button) {
  padding-inline: var(--space-6);
}
.so-cp-dialog-foot:has(> button + button) > button {
  flex: 1 1 calc((100% - var(--space-3)) / 2);
  box-sizing: border-box;
  min-width: 0;
  min-height: var(--touch-target-comfortable);
}

/* SF-8: labels inside a sheet are sentence case; ALL CAPS stays for table headers. */
.admin-form-sheet .sheet-body .section-title,
.admin-form-sheet .sheet-body .admin-subsection-title {
  text-transform: none;
  letter-spacing: normal;
}

/* SF-8 on the floor: the Cancel and primary pair in the Pay, Add guest and Split sheets is one height and one width
   (the primary used to be twice as wide). The primary keeps the thumb-zone height and Cancel matches it. */
.pay-confirm-actions .btn-secondary,
.pay-confirm-actions .btn-pay,
.pay-confirm-actions .btn-primary {
  flex: 1 1 calc((100% - var(--space-3)) / 2);
  box-sizing: border-box;
  min-width: 0;
  min-height: var(--touch-target-primary);
}
#split-setup-sheet .sheet-footer > button {
  flex: 1 1 calc((100% - var(--space-3)) / 2);
  box-sizing: border-box;
  min-height: var(--touch-target-primary);
}

/* SF-8: on a portrait iPad a sheet is 90% of the width, never edge to edge. A sheet with a narrower cap of its own
   (640 and 760 wide) keeps it; the drawers (role editor, Team invite) are not sheets and keep their own width. The
   Confirm Payment sheet keeps the full width: its test-payment title row needs it to hold the close control. */
@media (max-width: 900px) and (orientation: portrait) {
  .scrim:not(.rl-drawer):not(.fr-team-scrim) > .sheet:not(.pay-confirm-sheet) {
    width: 90%;
  }
}

/* ---------- UIFIX5 (docs/build-briefs/UIFIX5-location-page-fixes.md; design/style-guide.md sections 2, 3, 14): floor page fixes ----------
   iPad landscape and portrait, touch only, tokens only. */

/* Device setup: the code and the keypad are one centred panel, and the server address sits behind an Advanced row. */
.setup-wrap:not(.setup-solo) {
  max-width: 1080px;
  gap: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
  padding: var(--space-6);
  column-gap: var(--space-6);
  align-self: center;
}
.setup-wrap:not(.setup-solo) > .setup-card {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
}
.setup-advanced {
  margin-top: auto;
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-2);
}
.setup-advanced-toggle {
  display: flex;
  align-items: center;
  min-height: var(--touch-target-min);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  cursor: pointer;
}
.setup-advanced[open] .setup-server {
  margin-top: 0;
  border-top: 0;
}
.setup-advanced .setup-server-edit {
  padding-top: var(--space-3);
}

/* Who is signing in: first name over the rest of the name, every tile the same height. */
.user-tile-list > .user-tile .user-tile-name {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  line-height: var(--line-height-tight);
}
.user-tile-first {
  font-weight: var(--font-weight-bold);
}
.user-tile-rest {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  min-height: 1.2em;
}

/* PIN pad: Enter takes the wide slot and Back the narrow one; the portrait pad is 720px wide. */
.pin-pad-actions .pin-pad-cancel {
  flex: 1 1 0;
}
.pin-pad-actions .pin-pad-submit {
  flex: 2 1 0;
}
@media (orientation: portrait) and (min-width: 760px) {
  .pin-pad-card {
    max-width: 720px;
  }
}

/* Open tabs: every card is 112px (the plan said 120px; 112px keeps all 12 tabs on the 800px floor screen, UX14), a merge note is the second line inside it, and a chip with a zero count is not drawn. */
#open-tabs-list .tab-card {
  height: 112px;
  min-height: 112px;
  padding-block: var(--space-3);
  overflow: hidden;
}
#open-tabs-list .tab-main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-1);
  min-width: 0;
}
#open-tabs-list .tab-main > .tab-server:empty,
#open-tabs-list .tab-main > .tab-why[hidden] {
  display: none;
}
#open-tabs-list .tab-badges {
  margin-top: 0;
}
#open-tabs-list .tab-merge-trail {
  margin-top: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  line-height: var(--line-height-tight);
}
.tab-find-chips:not(:has(.tab-find-chip:not([hidden]))) {
  display: none;
}
.tab-find-chips:not(:has(.tab-find-chip:not([hidden]) ~ .tab-find-chip:not([hidden])))
  .tab-find-chip-divider {
  display: none;
}

/* Merge mode: a 44px banner, and a marked tab carries a check badge. */
.tab-merge-mode-banner {
  min-height: var(--touch-target-min);
  padding-block: var(--space-1);
  margin-bottom: var(--space-3);
}
.tab-card.tab-merge-marked::after {
  content: "\2713";
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
}

/* Ticket menu: the tiles in a section share one height. The letter row keeps wrapping: UX14 and UX121 require every letter
   to show with no hidden sideways scroll, which the plan's one-line scrolling row would break. */
.menu-section:not(.menu-section--popular) .tile-grid {
  grid-auto-rows: 1fr;
}
.menu-section:not(.menu-section--popular) .tile-wrapper {
  align-self: stretch;
}
.menu-section:not(.menu-section--popular) .tile-wrapper > .tile,
.menu-section:not(.menu-section--popular) .tile-grid > .tile {
  height: 100%;
  box-sizing: border-box;
}

/* Ticket rail: the header reads at 16px, Repeat last says what it does, Assign is a 44px chip. */
.ticket-header-row {
  height: auto;
  min-height: var(--chrome-row-height);
  flex-wrap: wrap;
  row-gap: var(--space-1);
}
.ticket-header-row > .ticket-id {
  flex: 1 1 8rem;
}
.ticket-header-row > .add-guest-row {
  margin-left: auto;
}
.ticket-id,
.ticket-id .ticket-age {
  font-size: var(--font-size-sm);
}
.btn-ticket-repeat {
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}
.line-assign-guest-button {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  background: transparent;
  border: 1px solid var(--color-accent);
  width: fit-content;
}
.btn-ticket-more.is-single-action {
  width: auto;
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
  white-space: nowrap;
  color: var(--color-text-primary);
}

/* Base filter: a bordered popover under its button, counts beside the names. */
.menu-filter-list {
  border: 1px solid var(--color-border-strong);
  top: calc(100% + var(--space-2));
}
.menu-filter-list button {
  justify-content: flex-start;
}
.menu-filter-list button.is-all {
  justify-content: flex-start;
}

/* Edit line: six actions in a 3 by 2 grid, Void drink last and in red. */
#line-edit-sheet .line-edit-actions {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
#line-edit-sheet .line-edit-actions.is-many {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
#line-edit-sheet .line-edit-actions > #line-edit-remove {
  order: 99;
}

/* Liquor picker: the required chip sits under the title, the list says when there is more below, and a row that is out
   says so in words. */
.liquor-sub {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}
.liquor-sub .required-flag {
  order: -1;
  max-width: 100%;
}
.liquor-more-below {
  position: relative;
  flex-shrink: 0;
  height: var(--space-8);
  margin-top: calc(-1 * var(--space-8));
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: var(--space-1);
  background: linear-gradient(to bottom, transparent, var(--color-surface));
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  pointer-events: none;
}
.liquor-more-below[hidden] {
  display: none;
}
.liquor-row--out {
  opacity: 0.55;
}
.liquor-row--out .stock-state-badge {
  display: none;
}
#liquor-sheet .liquor-price-final.out-of-stock {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-strong);
  min-width: 0;
}

/* Pay: the custom amount takes the rest of its row beside Add and No tip, and Split is a 44px outlined button in the
   footer. */
.tip-custom-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-2);
}
.tip-custom-row .tip-custom-input {
  min-width: 0;
}
.pay-confirm-actions .pay-confirm-split-link {
  flex: 0 0 auto;
  min-height: var(--touch-target-min);
  margin: 0;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  background: transparent;
}
.pay-confirm-actions .pay-confirm-split-link[hidden] {
  display: none;
}

/* Card reader pill: a 300px popover under the pill, and a row to set a reader up. */
.reader-dropdown {
  width: min(300px, calc(100vw - 2 * var(--space-2)));
  margin-top: var(--space-1);
}
.reader-dropdown-setup {
  justify-content: center;
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}

/* ---------- UIFIX5: manager screens ---------- */
/* Past counts: the closed counts alone, with no Start, Resume or Take over above them. */
#admin-counts-panel[data-landing="past"] #admin-counts-start-row,
#admin-counts-panel[data-landing="past"] > .section-title {
  display: none;
}

/* Purchase orders: the buttons sit in one row of their own, right aligned, on every order. */
.purchasing-order-row .purchasing-order-estimated-total {
  text-align: right;
}
.purchasing-order-actions {
  display: flex;
  flex: 1 1 100%;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Purchasing cart: the one status is a chip, and the figures keep fixed columns so rows line up. */
.purchasing-cart-proposal-row {
  flex-wrap: nowrap;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-product {
  flex: 1 1 120px;
  min-width: 120px;
}
.purchasing-cart-proposal-row [data-testid="purchasing-cart-proposal-add"] {
  flex: 0 0 auto;
  white-space: nowrap;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-sources {
  flex: 0 0 auto;
  min-width: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-onhand {
  flex: 0 0 120px;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-par {
  flex: 0 0 80px;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-suggested {
  flex: 0 0 130px;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-onhand,
.purchasing-cart-proposal-row .purchasing-cart-proposal-par,
.purchasing-cart-proposal-row .purchasing-cart-proposal-suggested {
  min-width: 0;
  white-space: nowrap;
}
.purchasing-cart-proposal-row .purchasing-cart-proposal-onhand-warning,
.purchasing-cart-proposal-row .purchasing-cart-proposal-unit-hint {
  flex-basis: 100%;
}
.purchasing-cart-proposal-row:has(
  .purchasing-cart-proposal-onhand-warning,
  .purchasing-cart-proposal-unit-hint
) {
  flex-wrap: wrap;
}

/* Closeout summary: the banner is a two column row (words left, Finalize right), and the toolbar starts at the left edge. */
#closeout-not-finalized-banner > div:last-child {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "title action"
    "note action";
  align-items: center;
  column-gap: var(--space-4);
}
#closeout-not-finalized-banner .status-title {
  grid-area: title;
}
#closeout-not-finalized-banner #closeout-finalize-button {
  grid-area: action;
  margin-top: 0;
}
#closeout-not-finalized-banner #closeout-finalize-availability {
  grid-area: note;
}
.closeout-freshness {
  justify-content: flex-start;
}

/* New custom report: the two choices start at the page gutter, not centred in a narrow column. */
.rb-start {
  margin: var(--space-6) 0 0;
}

/* Recipes list: three columns on a desktop. */
#admin-drink-list {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Inventory items: the catalog location label and its picker sit on one row with a gap. */
.catalog-network > label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

/* Discounts: one Manager approval card holding both picks and one Save. */
.admin-approval-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  max-width: 480px;
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.admin-approval-card .field-input {
  width: 100%;
}
.admin-approval-card .field-label {
  margin-top: 0;
}
.admin-approval-card .btn-compact {
  margin-top: var(--space-2);
}

/* Devices: the last-used time sits on the title line. */
.tablets-row-name .tablets-row-last-used {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
}

/* OWNSUSP1 (docs/build-briefs/OWNSUSP1-suspend-reinstate-cancel.md; PRD P0.32): the Account standing card on a customer's Overview.
   Rows reuse .so-fa-item; the confirm is inline under the list and the history is a quiet list of sentences. */
.so-standing-confirm {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-3) 0;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.so-standing-confirm[hidden] {
  display: none;
}
.so-standing-confirm .so-actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}
.so-standing-confirm .so-actions button {
  flex: 1 1 0;
  max-width: 320px;
}
.so-standing-history {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#software-owner-standing-card .so-fa-actions .fl-chip {
  white-space: nowrap;
}

/* ---------- OWNTEAM1 (docs/build-briefs/OWNTEAM1-owner-console-team.md; design/style-guide.md): Software Owner Team page ---------- */
.so-team-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.so-team-head .so-panel-title {
  margin: 0;
}
.so-team-lead {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.so-team-hint {
  margin: var(--space-2) 0 0;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-xs);
}
.so-team-access {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.so-team-check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--touch-target-comfortable);
  padding: var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
.so-team-check input {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  flex: none;
}
.so-team-check b {
  display: block;
  font-weight: var(--font-weight-semibold);
}
.so-team-check small {
  display: block;
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
}
.so-team-table th:nth-child(1) {
  width: 27%;
}
.so-team-table th:nth-child(2) {
  width: 14%;
}
.so-team-table th:nth-child(3) {
  width: 13%;
}
.so-team-table th:nth-child(4) {
  width: 14%;
}
.so-team-table th:nth-child(5) {
  width: 18%;
}
.so-team-table th:nth-child(6) {
  width: 14%;
}
.so-team-table td[data-label="Access"],
.so-team-table td[data-label="Passkeys"],
.so-team-table .so-team-passkeys-row > td {
  white-space: normal;
  overflow-wrap: anywhere;
}
.so-team-passkeys-row > td {
  padding: var(--space-3) var(--space-4) var(--space-4);
  background: var(--color-surface-subtle, transparent);
}
.so-team-passkeys-title {
  margin: 0 0 var(--space-2);
  font-weight: var(--font-weight-semibold);
}
.so-team-passkeys-host .so-table {
  margin-bottom: var(--space-3);
}

/* ---------- UIFIX3 (docs/build-briefs/UIFIX3-frame-header-approval-badge.md): console frame, SF-14 ----------
   One side nav (200px, 48px rows, 12px indent, one-line labels) and one page container (24px gutter, content up to
   1200px, tables and reports up to 1400px) on the franchisor and Software Owner consoles. The container is left
   aligned and never switches width per page, so the nav stays put when a page such as Billing opens. */
.fr-shell,
#software-owner-screen .so-shell {
  max-width: none;
  margin: 0;
  padding: var(--space-5);
  gap: var(--space-5);
}
.so-page:has(.so-home-console:not([hidden])) {
  align-items: flex-start;
  padding: var(--space-5);
}
.so-home.so-home-console {
  max-width: none;
}
.fr-nav,
.so-nav {
  flex: 0 0 200px;
  width: 200px;
  gap: 0;
}
.fr-nav-item,
.so-nav-item {
  min-height: 48px;
  padding: 0 var(--space-3);
  justify-content: flex-start;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-direction: row;
  align-items: center;
}
.so-nav-item.so-nav-with-icon {
  gap: var(--space-2);
}
.fr-content,
.so-content {
  max-width: 1200px;
}
.fr-content:has(table, [data-testid="rx-dates"]),
.so-content:has(table, [data-testid="rx-dates"]) {
  max-width: 1400px;
}
.fr-shell:has(#fr-ai-billing-section:not([hidden])) .fr-content {
  max-width: 1200px;
}
@media (max-width: 999px) {
  .fr-nav,
  .so-nav {
    flex-basis: auto;
    width: 100%;
  }
}

/* HELPHOVER1 (docs/build-briefs/HELPHOVER1-hover-help-no-info-icons.md; design/style-guide.md section 11): help is a hover and focus tooltip on the element it explains. Fixed, placed and clamped by script. */
.hover-tip {
  position: fixed;
  z-index: 60;
  box-sizing: border-box;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-text-primary);
  color: var(--color-surface);
  box-shadow: var(--shadow-2, var(--shadow-1));
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-regular);
  line-height: 1.35;
  pointer-events: none;
}
.has-hover-help:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* FRBILL3 (docs/build-briefs/FRBILL3-one-billing-page.md; DEC-505): Billing has three tabs; the royalty page sits inside it without a second card. */
.fr-ai-billing-layout .fb-page {
  gap: var(--space-5);
}
.fr-ai-billing-layout .fb-page > .fl-tabs {
  margin-bottom: 0;
}
.fr-ai-billing-layout .fr-royalty-page {
  padding: 0;
  border: 0;
  box-shadow: none;
  background: transparent;
}

/* PAY1-S7-F1 (docs/build-briefs/PAY1-S7-F1-live-money-checklist-screen.md; design/style-guide.md sections 5 and 8): the
   Live payments checklist in Snip & Sip Admin. Tokens only; reuses .so-table, .so-badge and the row menu. */
.lm-status {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
}
.lm-mode {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.lm-progress {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.lm-notice:empty {
  display: none;
}
.lm-table-wrap {
  overflow: visible;
  margin-bottom: var(--space-6);
}
.lm-subtitle {
  margin: var(--space-8) 0 var(--space-3);
  font-size: var(--font-size-lg);
}
.lm-table td {
  vertical-align: top;
}
.lm-name-button {
  min-height: var(--touch-target-min);
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text-primary);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}
.lm-items {
  table-layout: fixed;
}
.lm-items th:nth-child(1) {
  width: 27%;
}
.lm-items th:nth-child(2) {
  width: 13%;
}
.lm-items th:nth-child(3) {
  width: 17%;
}
.lm-items th:nth-child(4) {
  width: 30%;
}
.lm-items th:nth-child(5) {
  width: 13%;
}
.lm-evidence {
  overflow-wrap: anywhere;
  color: var(--color-text-secondary);
}
.lm-muted {
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}
.lm-inline {
  margin-left: var(--space-1);
}
.lm-locations th:nth-child(1) {
  width: 36%;
}
.lm-locations th:nth-child(2) {
  width: 34%;
}
.lm-locations th:nth-child(3) {
  width: 30%;
}
.lm-actions-col {
  width: 1%;
  text-align: right;
  white-space: nowrap;
}
.lm-dialog-body {
  padding: var(--space-4) var(--space-5);
}
.lm-history {
  margin-top: var(--space-4);
}
.lm-history-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
}
.lm-history-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.lm-history-entry {
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
  overflow-wrap: anywhere;
  color: var(--color-text-secondary);
}
.lm-note {
  min-height: 96px;
  font: inherit;
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
}

/* NAVICONS1 (docs/build-briefs/NAVICONS1-menu-icons-all-consoles.md; design/style-guide.md "Navigation icons"): the outline icon left of a
   franchisor nav item or a Settings rail item. The icon itself is the Admin console's .so-nav-icon (22px, currentColor); this only
   gives the franchisor item and the rail item the same icon-then-label row and 8px gap as the Admin nav. */
.fr-nav-item {
  gap: var(--space-2);
}
.settings-rail-item {
  gap: var(--space-2);
  text-align: left;
}
.settings-rail-item .so-nav-icon {
  flex: none;
}

/* HEADER1 (docs/build-briefs/HEADER1-one-console-header.md; design/style-guide.md "Console header"): one header in the
   location, franchisor and Snip & Sip Admin consoles. The three columns, height, padding, border and background are the
   floor's .topbar; this only gives the context name one size and weight everywhere, the small "Franchisor" label, and the
   centered lockup one size in every console. Theme colours come from the tokens each console already loads (DEC-500). */
.topbar-left .location,
.console-context-name {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.01em;
  line-height: var(--line-height-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.console-context-label {
  flex: none;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-tertiary);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.topbar-center .brand-logo {
  height: 32px;
}
[data-theme="brass"] .topbar .console-context-name {
  color: var(--color-brand-cream);
}
[data-theme="brass"] .topbar .console-context-label {
  color: var(--color-brand-cream-muted);
}
[data-theme="brass"] #fr-topbar,
[data-theme="brass"] #so-topbar {
  box-shadow: none;
  border-bottom-color: var(--color-border);
}
.console-context-name[hidden] {
  display: none;
}

/* HELPHOVER1-F1 (docs/build-briefs/HELPHOVER1-F1-help-icons-all-consoles.md; owner 2026-10-22: "They should be vertically centered with the
   text"): the favorite star sits at the right of a Reports card, vertically centered on the card, so it lines up with the title text for
   a one, two or three line title. It stays a 44px touch target. A card grows past 96px only when a title and its meta line need it. */
.rx-card-report {
  height: auto;
  min-height: 96px;
}
.rx-card-title {
  -webkit-line-clamp: 3;
  line-clamp: 3;
}
.rx-card-report > .rx-star {
  top: 50%;
  transform: translateY(-50%);
}

/* SF-15: one 56px page header, and no blank band from the empty error line above the first card. */
.fr-content > .fr-page-title {
  display: flex;
  align-items: center;
  min-height: 56px;
  margin: 0 0 var(--space-3);
}
.fr-content > .field-error:empty {
  display: none;
}

/* STALEBUNDLE1: the "new version ready" banner (ui/src/newVersionCheck.ts). A plain block directly below the page
   header, so it never covers a button, and it stays out of the way of the floor, which never shows it. */
.new-version-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-5);
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-primary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.new-version-banner[hidden] {
  display: none;
}
.new-version-banner-reload {
  height: var(--touch-target-min);
  padding: 0 var(--space-4);
}

/* BILLSTMT1: the Billing overview shared by the location and franchisor consoles (ui/src/billingStatements.ts). */
.bs-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
  padding-bottom: var(--space-8);
}
.bs-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
}
.bs-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 260px;
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.bs-tile-label {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.bs-tile-amount {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bs-tile-facts {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  font-size: var(--font-size-sm);
}
.bs-tile-fact {
  display: flex;
  gap: var(--space-2);
}
.bs-tile-fact dt {
  color: var(--color-text-secondary);
}
.bs-tile-fact dd {
  margin: 0;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.bs-bank-slot:empty {
  display: none;
}
.bs-title {
  margin: 0;
  font-size: var(--font-size-lg);
}
.bs-table {
  width: 100%;
  min-width: 520px;
}
.bs-table th,
.bs-table td {
  padding: var(--space-3);
  text-align: left;
  font-size: var(--font-size-sm);
  vertical-align: middle;
}
.bs-table .fb-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.bs-table .fb-date {
  white-space: nowrap;
}
.bs-table .fl-chip {
  white-space: nowrap;
}
.so-detail-card.so-statements-card {
  grid-column: 1 / -1;
  width: 100%;
  max-width: none;
}
.so-statements-card .so-table td,
.so-statements-card .so-table th {
  white-space: nowrap;
}
.bs-tile-since {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.bs-payment {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

/* ERRTRACK1 (docs/build-briefs/ERRTRACK1-error-tracking.md): the failure notice a person sees when a screen breaks.
   One card at the bottom of the page; the reference code is large enough to read aloud. The floor variant has a 64px
   Try again and no Copy code. */
.error-notice {
  position: fixed;
  left: 50%;
  bottom: var(--space-4);
  transform: translateX(-50%);
  z-index: 60;
  width: min(720px, calc(100vw - var(--space-8)));
  box-shadow: var(--shadow-3);
}
.error-notice .failure-state {
  margin: 0;
  background: var(--color-danger-subtle);
  flex-wrap: nowrap;
}
.failure-state-detail {
  display: block;
  margin-top: var(--space-1);
  font-weight: var(--font-weight-regular);
  color: inherit;
}
.failure-state-code {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  font-weight: var(--font-weight-bold);
}
.error-notice-floor .failure-state {
  font-size: var(--font-size-md);
  padding: var(--space-4) var(--space-5);
}
.error-notice-floor .failure-state-code {
  font-size: var(--font-size-xl);
}
.error-notice-floor .failure-state-retry {
  min-height: var(--touch-target-primary);
  min-width: calc(var(--space-16) + var(--space-8));
  font-size: var(--font-size-base);
}
.error-notice .failure-state .btn-secondary {
  white-space: nowrap;
}

/* BANK1 follow-up: the location Billing page's AI usage card (it sits under the Bank accounts card). Full width like the card
   above it, normal column widths, headings and money on one line, and each limit as one line with its input below
   (design/style-guide.md sections 5 and 12). Scoped to the location console's Billing panel; the franchisor page has its own. */
#admin-group-panel-network .cr-ai-billing {
  max-width: none;
  width: 100%;
  overflow-x: auto;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table {
  width: 100%;
  min-width: 900px;
  table-layout: auto;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table th {
  white-space: nowrap;
  text-align: left;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table th.cr-ai-number,
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table td.cr-ai-number {
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table td {
  white-space: nowrap;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-usage-table .cr-ai-usage-empty {
  white-space: normal;
}
#admin-group-panel-network .cr-ai-billing .cr-ai-cap-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) 0;
}

/* NOTIFPREF1 (design/style-guide.md sections 3, 7, 9, 10; design/mockups/entbasics/notifpref1-notification-settings.html): the
   Notifications page, shared by the location, franchisor and Snip & Sip Admin consoles. Tokens only. */
.notif-back {
  margin-bottom: var(--space-3);
}
.notif-sub {
  margin: 0 0 var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
}
.notif-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: var(--space-4);
  align-items: stretch;
}
.notif-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: var(--space-2) var(--space-5) var(--space-3);
  position: relative;
  min-width: 0;
}
.notif-card-locked {
  margin-top: var(--space-4);
}
.notif-title {
  margin: 0;
  padding: var(--space-3) 0 var(--space-1);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.notif-help {
  margin: 0 0 var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}
.notif-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  border-bottom: 1px solid var(--color-border);
}
.notif-row:last-child {
  border-bottom: 0;
}
.notif-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.notif-text b {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}
.notif-text span {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.notif-saved {
  font-size: var(--font-size-xs);
  color: var(--color-success-strong);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.notif-problem:empty {
  display: none;
}
.notif-lock {
  width: 44px;
  display: flex;
  justify-content: center;
}
.notif-lock-icon {
  width: 20px;
  height: 20px;
  color: var(--color-text-secondary);
}
.notif-locked-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  column-gap: var(--space-8);
}

/* SUPPORT1 (docs/build-briefs/SUPPORT1-get-help-and-support.md; mockups design/mockups/entbasics/support1-get-help-and-support.html): Get help
   sheet, Report a problem form, My requests, and the Support section of Snip & Sip Admin. Tokens only; one set of classes for the
   three consoles (ui/src/supportHelp.ts, ui/src/softwareOwnerSupportRequests.ts). */
.support-scrim {
  align-items: center;
  padding: var(--space-6);
}
.support-sheet {
  max-width: 640px;
  max-height: min(820px, 92vh);
  border-radius: var(--radius-xl);
}
.support-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 64px;
  padding: 0 var(--space-6);
  border-bottom: 1px solid var(--color-border);
  flex: none;
}
.support-sheet-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.support-sheet-title:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.support-sheet-body {
  padding: var(--space-6);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.support-sheet-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
  flex: none;
}
.support-sheet-foot:empty {
  display: none;
}
.support-sheet-foot button {
  min-width: 140px;
  min-height: 48px;
}
.support-choice {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 64px;
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.support-choice:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.support-choice-text {
  flex: 1;
  min-width: 0;
}
.support-choice-title {
  display: block;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}
.support-chevron {
  font-size: var(--font-size-lg);
  color: var(--color-text-secondary);
}
.support-count {
  min-width: 22px;
  height: 22px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-accent-strong);
  color: var(--color-text-on-accent);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}
.support-help {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.support-note {
  margin: var(--space-4) 0 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.support-strong {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
}
.support-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
}
.support-field .field-input {
  width: 100%;
  min-height: 44px;
}
.support-field textarea.field-input {
  min-height: 96px;
  resize: none;
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
}
.support-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}
.support-error {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-strong);
}
.support-error[hidden] {
  display: none;
}
.support-error-general {
  margin-top: var(--space-2);
}
.support-seg {
  display: inline-flex;
  align-self: flex-start;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
}
.support-seg button {
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 0;
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
}
.support-seg button + button {
  border-left: 1px solid var(--color-border-strong);
}
.support-seg button[aria-pressed="true"] {
  background: var(--color-accent-subtle);
  color: var(--color-accent-strong);
  font-weight: var(--font-weight-semibold);
}
.support-seg button:focus-visible {
  outline: none;
  box-shadow: inset var(--shadow-focus);
}
.support-sent {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}
.support-sent-line {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.support-ref {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}
.support-chip {
  white-space: nowrap;
  flex: none;
}

/* My requests: a page under the header, list and thread side by side. */
.support-page {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: var(--support-page-top, var(--topbar-height));
  z-index: calc(var(--z-scrim) - 1);
  overflow-y: auto;
  padding: var(--space-5) var(--space-6);
  background: var(--color-bg);
  color: var(--color-text-primary);
}
.support-page-head,
.support-admin-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  margin-bottom: var(--space-3);
}
.support-page-title {
  margin: 0;
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
}
.support-page-title:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.support-grow {
  flex: 1;
}
.support-page-body {
  display: grid;
  grid-template-columns: 380px minmax(0, 1fr);
  gap: var(--space-6);
  max-width: 1200px;
  align-items: start;
}
.support-list,
.support-thread,
.support-card,
.support-empty {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.support-list {
  overflow: hidden;
}
.support-list-row {
  display: block;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.support-list-row:last-child {
  border-bottom: 0;
}
.support-list-row[aria-current="true"] {
  background: var(--color-accent-subtle);
}
.support-list-row:focus-visible {
  outline: none;
  box-shadow: inset var(--shadow-focus);
}
.support-list-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.support-list-title {
  min-width: 0;
  overflow-wrap: anywhere;
}
.support-thread {
  display: flex;
  flex-direction: column;
  min-height: 420px;
  max-height: calc(100vh - var(--topbar-height) - 160px);
  overflow: hidden;
}
.support-pad {
  padding: var(--space-5);
}
.support-thread-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex: none;
}
.support-thread-title {
  margin: 0;
  font-size: var(--font-size-lg);
  overflow-wrap: anywhere;
}
.support-messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
}
.support-bubble {
  max-width: 78%;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
}
.support-bubble-you,
.support-bubble-staff {
  align-self: flex-end;
  background: var(--color-accent-subtle);
  border-color: var(--color-accent-subtle-border);
}
.support-bubble-support,
.support-bubble-customer {
  align-self: flex-start;
  background: var(--color-surface-sunken);
}
.support-bubble-who {
  margin-bottom: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.support-bubble-who b {
  color: var(--color-text-primary);
}
.support-bubble-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.support-composer {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  flex: none;
}
.support-composer .field-input {
  flex: 1;
  min-height: 48px;
}
.support-composer .btn-primary {
  min-height: 48px;
  min-width: 96px;
}
.support-thread > .support-error {
  padding: 0 var(--space-5) var(--space-3);
}
.support-empty {
  grid-column: 1 / -1;
  max-width: 1148px;
  padding: var(--space-6) var(--space-5);
  text-align: center;
}
.support-empty-title {
  display: block;
  font-size: var(--font-size-md);
  margin-bottom: var(--space-1);
}
.support-empty .btn-primary {
  margin-top: var(--space-4);
}
.support-failure {
  margin: var(--space-4);
}

/* Snip & Sip Admin: the Support section. */
.support-admin-tools {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.support-search {
  width: min(320px, 100%);
  min-height: 44px;
}
.support-tabs button {
  white-space: nowrap;
}
.support-admin-content .support-empty {
  max-width: none;
}
.support-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-size: var(--font-size-sm);
}
.support-table th {
  height: 36px;
  padding: 0 var(--space-4);
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}
.support-table td {
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}
.support-table tbody tr:last-child td {
  border-bottom: 0;
}
.support-table .support-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.support-table-row {
  cursor: pointer;
}
.support-table-row:hover,
.support-table-row:focus-visible {
  background: var(--color-accent-subtle);
  outline: none;
}
.support-sub {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.support-status-link {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.support-admin-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: var(--space-5);
  align-items: start;
}
.support-admin-thread {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
  min-height: 460px;
}
.support-messages-admin {
  max-height: 520px;
}
.support-admin-composer {
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.support-admin-composer .support-composer {
  padding: 0;
  border-top: 0;
}
.support-admin-input {
  min-height: 72px;
  resize: vertical;
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
}
.support-note-card {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px dashed var(--color-warning-subtle-border);
  background: var(--color-warning-subtle);
  color: var(--color-warning-strong);
}
.support-note-card .support-bubble-who,
.support-note-card .support-bubble-who b {
  color: var(--color-warning-strong);
}
.support-status-line {
  margin: 0;
  align-self: center;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.support-admin-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.support-card {
  padding: var(--space-4) var(--space-5);
}
.support-card .field-input {
  width: 100%;
  min-height: 44px;
  margin-bottom: var(--space-3);
}
.support-buttons {
  display: flex;
  gap: var(--space-2);
}
.support-buttons button {
  flex: 1 1 auto;
  min-height: 44px;
  white-space: nowrap;
}
.support-kv {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: var(--space-2) var(--space-3);
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-sm);
}
.support-kv dt {
  color: var(--color-text-secondary);
}
.support-kv dd {
  margin: 0;
  font-weight: var(--font-weight-medium);
  overflow-wrap: anywhere;
}
.so-nav-label {
  flex: 1;
}

/* PAYEXPORT1: the preview table in Settings > Users > Payroll (Gusto). Uses the shared tokens only. */
.pg-table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-3) 0;
}
.pg-table th,
.pg-table td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}
.pg-table th {
  font-size: var(--font-size-sm);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.pg-table .pg-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.pg-table .pg-warn {
  color: var(--color-danger);
}
.pg-table .pg-total td {
  font-weight: var(--font-weight-semibold);
  border-top: 2px solid var(--color-border);
}
#admin-payroll-section select {
  min-height: 44px;
  max-width: 100%;
}
.pg-row {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.2fr) minmax(0, 1.5fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  list-style: none;
}
.pg-name {
  font-weight: 600;
  overflow-wrap: anywhere;
}
.pg-email {
  overflow-wrap: anywhere;
  color: var(--color-text-secondary);
}
.pg-footer {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

/* STATUSPAGE1: the System status row is a link (opens the public status page in a new tab), drawn like the button rows. */
a.account-menu-row {
  text-decoration: none;
  box-sizing: border-box;
}

/* ---------- ABCRPT1: Spirits used vs sold (ABC) (docs/build-briefs/ABCRPT1-abc-spirits-used-vs-sold.md) ----------
   Drawn into #reports-body by ui/src/abcSpirits.ts. The month control and the tables reuse the Sales tax worksheet's
   rules above; only the two figure tiles are new. Existing tokens only. */
#admin-group-panel-reports .abc-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
#admin-group-panel-reports .abc-tile {
  min-width: 14em;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
#admin-group-panel-reports .abc-tile-value {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
#admin-group-panel-reports .abc-tile-note {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
#admin-group-panel-reports .abc .stw-daily th {
  white-space: normal;
  line-height: 1.2;
  height: auto;
  min-height: var(--touch-target-min);
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
  vertical-align: bottom;
}
#admin-group-panel-reports .abc .stw-daily td.abc-brand {
  white-space: normal;
  min-width: 12em;
  max-width: 17em;
  line-height: 1.25;
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}

/* JOBSCHED1 (docs/build-briefs/JOBSCHED1-scheduled-jobs-times.md): the Scheduled jobs section of Snip & Sip Admin
   (ui/src/softwareOwnerScheduledJobs.ts). Tokens only; the table is the shared .fl-table. */
.sj-head {
  display: flex;
  align-items: center;
  min-height: 56px;
}
.sj-title {
  margin: 0;
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
}
.sj-help {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}
.sj-table-wrap {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow-x: auto;
}
.sj-table td {
  height: 64px;
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
  vertical-align: middle;
}
.sj-name .sj-job-title {
  display: block;
}
.sj-sub {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  white-space: normal;
}
.sj-warn {
  display: block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-strong);
  white-space: normal;
}
.sj-chip {
  margin-left: var(--space-2);
  white-space: nowrap;
}
.sj-action {
  text-align: right;
}
.sj-scrim {
  align-items: center;
  padding: var(--space-6);
}
.sj-sheet {
  width: 100%;
  max-width: 640px;
  max-height: min(820px, 92vh);
  border-radius: var(--radius-xl);
  display: flex;
  flex-direction: column;
}
.sj-sheet-head {
  display: flex;
  align-items: center;
  min-height: 64px;
  padding: 0 var(--space-6);
  border-bottom: 1px solid var(--color-border);
  flex: none;
}
.sj-sheet-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
}
.sj-sheet-title:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.sj-sheet-body {
  padding: var(--space-6);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.sj-sheet-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
  flex: none;
}
.sj-sheet-actions {
  display: flex;
  gap: var(--space-3);
  margin-left: auto;
}
.sj-sheet-foot button {
  min-height: 48px;
}
.sj-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.sj-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}
.sj-select {
  min-height: 44px;
  width: 100%;
}
.sj-time {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.sj-time .sj-select {
  width: auto;
  min-width: 96px;
}
.sj-zone {
  margin-left: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.sj-error {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-danger-strong);
}
.sj-error[hidden] {
  display: none;
}
.sj-fixed {
  margin: 0 0 var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-sm);
}
.sj-switch {
  margin-bottom: var(--space-2);
}
.sj-confirm {
  margin: 0;
  font-size: var(--font-size-sm);
  max-width: 320px;
}

/* UIUX13: subscription, payment summary and editable contact retain reading order at full card width. */
#software-owner-customer-panel-billing > #software-owner-billing-card,
#software-owner-customer-panel-billing > #software-owner-billing-placeholder,
#software-owner-customer-panel-billing > #software-owner-billing-contact-card {
  grid-column: 1 / -1;
}

/* UIUX12: subordinate product creation retains the recipe workspace behind a modal dialog. */
.recipe-catalog-product {
  width: min(640px, calc(100vw - var(--space-12)));
  max-height: calc(100dvh - var(--space-12));
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-3);
}
.recipe-catalog-product[open] {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.recipe-catalog-product::backdrop {
  background: var(--color-scrim);
}
.recipe-catalog-product h2 {
  margin: 0;
  font-size: var(--font-size-lg);
}
.recipe-catalog-product .catalog-fields {
  overflow-y: auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.recipe-catalog-product label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.recipe-catalog-product input,
.recipe-catalog-product select {
  color: var(--color-text-primary);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  font: inherit;
}
.recipe-catalog-product-actions {
  display: flex;
  gap: var(--space-3);
  flex-shrink: 0;
}
.recipe-catalog-product-actions button {
  flex: 1;
}
.recipe-catalog-product [role="status"] {
  margin: 0;
  flex-shrink: 0;
}

/* UIUX10: compact discount editing; recipe authoring retains its existing workspace. */
.fr-publish-sheet:not(.fr-recipe-sheet) {
  width: min(640px, calc(100vw - var(--space-12)));
  max-width: 640px;
}
.fr-publish-sheet:not(.fr-recipe-sheet) .fr-publish-columns {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
}
.fr-publish-sheet:not(.fr-recipe-sheet) > .fr-publish-body {
  padding: var(--space-6);
  min-height: 0;
  max-height: none;
  flex: 1 1 auto;
  overflow-y: auto;
}
.fr-publish-sheet:not(.fr-recipe-sheet) > .admin-confirm-actions,
.fr-publish-sheet:not(.fr-recipe-sheet) > #fr-revision-reload {
  flex-shrink: 0;
}
.fr-publish-sheet:not(.fr-recipe-sheet) > #fr-revision-reload {
  margin: var(--space-2) var(--space-6);
}
/* Retained write reviews can be long. Keep their complete content scrollable above the actions. */
.fr-publish-sheet:not(.fr-recipe-sheet) > .fr-publish-error {
  flex: 0 1 auto;
  min-height: 0;
  max-height: 25dvh;
  overflow-y: auto;
  overflow-wrap: anywhere;
  padding: var(--space-2) var(--space-6);
}
.fr-publish-sheet:not(.fr-recipe-sheet) > .fr-publish-error:empty {
  display: none;
}
/* One recovery scroll surface keeps keyboard scrolling on the complete retained review. */
.fr-publish-sheet:not(.fr-recipe-sheet) > .fr-publish-error .fr-definition-latest {
  max-height: none;
  overflow: visible;
}
