/* Inventory & Sales — shared styles */
* { box-sizing: border-box; touch-action: manipulation; } /* taps never double-tap-zoom on iOS */
/* iOS Safari auto-zooms any focused input under 16px — keep ALL fields at 16px minimum */
input, select, textarea { font-size: 16px; }
/* Belt-and-suspenders: on phones NOTHING may drop a form control below 16px.
   This !important floor beats any component rule OR inline style, so no text
   box, dropdown or number field can ever focus-zoom the page. Desktop keeps
   its component-specific sizes (no zoom there). */
@media (max-width: 700px) {
  input, select, textarea { font-size: 16px !important; }
}
/* Dropdowns match normal text boxes everywhere (macOS renders native selects tiny) */
select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  width: 100%; padding: 11px 36px 11px 12px;
  border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); cursor: pointer;
  background: #fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2367748c' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 12px center;
}
:root {
  --bg: #f2f4f7;
  --card: #ffffff;
  --ink: #1a2233;
  --muted: #67748c;
  --line: #e4e8ef;
  --surface-1: #f4f6f9;      /* subtle row band — ledger order grouping + totals */
  --primary: #6d28d9;        /* app theme: purple */
  --primary-dark: #5b21b6;
  --primary-light: #ede9fe;  /* light purple button fill */
  --primary-press: #ddd6fe;
  --green: #059669;
  --red: #dc2626;
  --amber: #b45309;
  --radius: 14px;
  --shadow: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .04);
}
html, body {
  margin: 0; padding: 0;
  background: var(--bg); color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px; line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  /* UC-011: iOS Safari font boosting inflated SOME text blocks (and stuck
     after landscape rotation) — the app's own sizes are the only sizes. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

.topbar {
  background: #1e0a47; color: #fff;
  padding: 12px 18px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 50;
}
.topbar .brand { font-weight: 700; font-size: 17px; letter-spacing: .2px; }
.topbar .who { color: #c4b5fd; font-size: 14px; }
.topbar .spacer { flex: 1; }
.topbar a { color: #ddd6fe; font-size: 14px; font-weight: 600; }
/* Buttons in the header: light chip on the dark purple bar */
.topbar .btn, .topbar .btn.primary {
  background: var(--primary-light); border-color: var(--primary-light); color: var(--primary-dark);
}
.topbar .btn:hover, .topbar .btn.primary:hover { background: var(--primary-press); }

.wrap { max-width: 980px; margin: 0 auto; padding: 18px 14px 80px; }
.wrap.narrow { max-width: 560px; }
/* The Sales Ledger has many columns, so its card alone breaks out wider than
   the 980px page and re-centers on the viewport; every other card keeps the
   page width. Desktop only — on phones it's full-width like the rest. */
@media (min-width: 701px) {
  #lg-collapse {
    width: min(1240px, calc(100vw - 32px));
    /* Re-center this wider-than-page card on the viewport with margin math
       only — NOT a transform. A non-identity transform promotes the card to
       its own compositor layer, which Chromium sometimes fails to clear when
       the Accounting tab flips to display:none, leaving a ghost of the ledger
       painted over other pages. Pure margin keeps it in the normal layer. */
    margin-left: calc(50% - min(1240px, calc(100vw - 32px)) / 2);
  }
}

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 18px; margin-bottom: 16px;
}
.card h2 { margin: 0 0 12px; font-size: 18px; }
/* Desktop pages (admin/manager): divider line under every card title */
body.desktop .card > h2 {
  border-bottom: 1.5px solid var(--line);
  padding-bottom: 12px; margin-bottom: 14px;
}
/* Desktop pages: dropdowns and text fields stay a tidy width instead of
   stretching across the whole page */
body.desktop .field select,
body.desktop .field input { max-width: 340px; }
.card h3 { margin: 18px 0 8px; font-size: 15px; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1.5px solid var(--primary); background: var(--primary); color: #fff;
  border-radius: 8px; padding: 10px 16px; font-size: 15px; font-weight: 600;
  cursor: pointer; transition: background .12s, transform .05s;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: var(--primary-dark); }
.btn:active { transform: scale(.98); }
.btn.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn.primary:hover { background: var(--primary-dark); }
.btn.green { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn.green:hover { background: var(--primary-dark); }
.btn.danger { background: #fff; border-color: #fca5a5; color: var(--red); }
.btn.big { width: 100%; padding: 16px; font-size: 17px; border-radius: 12px; }
.btn.small { padding: 5px 10px; font-size: 13px; border-radius: 8px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* Period picker as a segmented control: the selected range is filled, the
   others sit as outlines so it's clear which window you're looking at. */
.range-btn { background: #fff; color: var(--primary); }
.range-btn:hover { background: var(--primary-light); }
.range-btn.active, .range-btn.active:hover { background: var(--primary); color: #fff; }

.field { margin-bottom: 14px; }
.field label { display: block; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 11px 12px; font-size: 16px;
  border: 1px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(109, 40, 217, .14);
}
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row > .field { flex: 1; min-width: 130px; margin-bottom: 0; }

.grid { display: grid; gap: 10px; }
.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) {
  .grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
}

table.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th {
  text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--muted); padding: 8px 10px; border-bottom: 2px solid var(--line);
  white-space: nowrap;
}
.tbl td { padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
/* Tall multi-line cells (e.g. transfer items): pin every column to the top row */
.tbl.top td { vertical-align: top; padding-top: 12px; }
.tbl tr:last-child td { border-bottom: none; }
.tbl td.num, .tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tfoot td { font-weight: 700; border-top: 2px solid var(--line); }
.tbl-scroll { overflow-x: auto; }
/* A table whose rows carry an Options dropdown must not clip it — those tables
   (Batches, Products) are narrow enough not to need horizontal scroll. */
.tbl-scroll:has(.menu-wrap) { overflow: visible; }
/* Dense variant for wide, column-heavy tables (the sales ledger) so all
   columns fit one line on desktop. */
.tbl.compact { font-size: 12.5px; }
.tbl.compact th, .tbl.compact td { padding: 6px 7px; }
.tbl.compact th { white-space: nowrap; }
/* Sales Ledger: a stronger rule opens each order; its lines share one shade */
#s-body tr.lg-ord-top > td { border-top: 2px solid var(--line); }
/* Compact type tag in the Txn column (FC / CS / IN); hover shows the full
   label + field salesman name via the title attribute. */
.txn-badge {
  /* keeps the hover tooltip (title=) but a normal cursor — the ?-cursor read
     as something being wrong rather than "there's a hint here" */
  display: inline-block; font-size: 10.5px; font-weight: 700; line-height: 1.4;
  padding: 0 5px; border-radius: 5px; vertical-align: middle; cursor: default;
  background: var(--primary-light); color: var(--primary-dark);
}
/* Where the order's money IS (owner rule 2026-07-22): traffic-light states
   on every owner counter order in the ledger. */
.txn-badge.tb-paid { background: #d1fae5; color: #065f46; }
.txn-badge.tb-await { background: #fef3c7; color: #92400e; }
.txn-badge.tb-open { background: #eef1f5; color: var(--muted); }
/* Structured dialog bodies (owner rule 2026-07-22): money popups reuse the
   same order-block + mathbox markup as the rest of the app, and scroll rather
   than truncate. */
.dlg-body { max-height: 52vh; overflow-y: auto; margin: 2px -4px 4px; padding: 0 4px; }
.dlg-body .mathbox { margin-top: 6px; }
.dlg-order { padding: 8px 2px; border-top: 1px dashed var(--line); }
.dlg-order:first-child { border-top: none; padding-top: 2px; }
/* Inventory stock chip: desktop shows "Quantity:", mobile swaps to "qty:"
   (the mobile override lives in the max-width media query). */
.q-short { display: none; }

/* Inside-sale modal line rows (desktop widths; per-cell mobile labels hidden) */
.is-table .is-qty { width: 70px; }
.is-table .is-price { width: 90px; }
.is-table .m-lbl { display: none; }

/* Inside-sale checklist modal: the WHOLE modal scrolls (top fields included)
   and only the money footer sticks — same on mobile and desktop. Wider on
   desktop for the product list. */
.is-modal { display: block; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: 0; }
/* Wider than the standard 480px modal for the product list — .modal.is-modal
   outranks the base .modal max-width; screen width still caps it on phones. */
.modal.is-modal { max-width: 720px; }
.is-scroll { margin: 0; padding: 0; }
.is-foot {
  position: sticky; bottom: 0; z-index: 2; background: #fff;
  border-top: 1.5px solid var(--line); margin-top: 10px; padding-top: 12px;
  /* Side padding so the right-aligned totals + Amount Paid don't hug the edge */
  padding-left: 12px; padding-right: 12px;
  padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -6px 14px rgba(15, 23, 42, .08);
}
/* Amount Paid uses the app's standard text-box look (matches .field input) — it
   sits in a flex row, not a .field, so the styling is applied directly. Value is
   bold; the box stays consistent with every other input. */
#is-paid {
  box-sizing: border-box; width: 150px; max-width: 150px;
  padding: 11px 12px; font-size: 16px; font-weight: 700;
  border: 1px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink);
}
#is-paid:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(109, 40, 217, .14);
}
/* Header + each card's head share ONE grid, so the columns line up:
   [checkbox] Product | Batch | Price | Stock. Two grids only align when their
   column widths are identical fixed values — hence the shared template. */
.is-hd, .is-head {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 70px 82px 44px;
  gap: 8px; align-items: center;
}
.is-hd {
  margin: 14px 0 6px; padding: 0 12px;
  font-size: 11px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase; color: var(--muted);
}
.is-hd .r { text-align: right; }
/* Phones: tighten the side columns and ease the name font so typical
   "Product (X)" names fit whole; a genuinely long name still ellipsizes and
   the A/B/C card color carries the class. (Name is a span — the 16px input
   zoom-floor doesn't apply here.) */
@media (max-width: 700px) {
  .is-hd, .is-head { grid-template-columns: 22px minmax(0, 1fr) 56px 68px 28px; gap: 6px; }
  .is-head .is-name { font-size: 14.5px; }
  .is-head .is-batch { font-size: 12px; }
}
.is-item {
  border: 1.5px solid var(--line); border-radius: 10px;
  padding: 9px 12px; margin-bottom: 8px;
}
/* The whole card carries the product's A/B/C class color */
.is-item.is-a { border-color: #86efac; background: #f0fdf4; }
.is-item.is-b { border-color: #93c5fd; background: #eff6ff; }
.is-item.is-c { border-color: #fdba74; background: #fff7ed; }
/* Selected = a purple ring over the class color, so both read at once */
.is-item.on { box-shadow: inset 0 0 0 2px var(--primary); }
.is-head { cursor: pointer; -webkit-user-select: none; user-select: none; }
.is-head .is-sel { width: 21px; height: 21px; margin: 0; accent-color: var(--primary); }
.is-head .is-name { min-width: 0; font-weight: 600; display: flex; align-items: center; gap: 5px; }
.is-head .is-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Age chip in the tight row: compact, and let it never shrink away */
.is-head .age-chip { margin-left: 0; flex-shrink: 0; padding: 1px 6px; font-size: 11px; }
.is-head .is-batch {
  color: var(--muted); font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.is-head .is-price-ref { text-align: right; white-space: nowrap; color: var(--muted); font-size: 13px; }
.is-head .is-ref { text-align: right; white-space: nowrap; font-weight: 700; }
.is-inputs { display: none; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; padding-left: 32px; }
.is-item.on .is-inputs { display: flex; }
.is-inputs .m-lbl { font-size: 12px; font-weight: 600; color: var(--muted); }
.is-inputs input { width: 68px; min-height: 32px; padding: 4px 8px; text-align: center; }
.is-inputs .is-line { margin-left: auto; font-weight: 700; white-space: nowrap; }
/* Collapsible sub-section inside a container card (facilities inside the
   Facilities card; Managers/Field/Settings/Password inside This Facility) —
   a hairline divider separates them, and the header row is tap-friendly. */
/* Container cards (Facilities, This Facility) drop the title divider — each
   sub-section already carries its own top divider, so keeping the h2 rule
   would double the line right under the heading. */
body.desktop .container-card > h2 { border-bottom: none; padding-bottom: 0; margin-bottom: 6px; }
.fac-sub { border-top: 1px solid var(--line); }
/* Breathing room between the facility-name row (with Platform Admins) and the
   first section (Managers) in the Facility Settings card. */
#tf-name-row { margin-bottom: 16px; }
/* Add-manager / add-field-salesman rows get a divider above (separating them
   from the roster list) so the sections read clearly. */
.staff-add { border-top: 1px solid var(--line); margin-top: 12px; padding-top: 14px; }
.fac-sub > .collapse-h, .fac-sub > div:first-child { padding: 12px 0 12px; }
/* proper header look (override .card h3's uppercase-muted styling) */
.fac-sub .collapse-h h3 { font-size: 16px; color: var(--ink); text-transform: none; letter-spacing: 0; margin: 0; }
.fac-sub.collapsed .collapse-body { display: none; }
.fac-sub .collapse-body { padding-bottom: 12px; }
/* Balances card: the two collapsible sections (Awaiting Confirmation, Payment
   History) read as distinct accordion bars — filled/bordered/rounded, spaced
   apart, with a bottom rule when open — instead of hairline rows that run
   together. Scoped to this card so Settings sub-sections are untouched. */
#collections-card .fac-sub {
  border: 1px solid var(--line); border-top: 1px solid var(--line);
  border-radius: 10px; margin-top: 12px; overflow: hidden;
}
#collections-card .fac-sub > .collapse-h {
  padding: 13px 14px; background: var(--bg);
}
#collections-card .fac-sub > .collapse-h:hover { background: #e9edf3; }
#collections-card .fac-sub:not(.collapsed) > .collapse-h { border-bottom: 1px solid var(--line); }
#collections-card .fac-sub .collapse-body { padding: 12px 14px; }
#collections-card .fac-sub .collapse-h .caret { color: var(--ink); }

.badge {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 12.5px; font-weight: 700;
  /* a pill whose text wraps turns into a tall blob — never wrap mid-badge;
     a pill longer than its container ellipsizes instead of overflowing */
  white-space: nowrap; max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; vertical-align: bottom;
}
.badge.ok { background: #d1fae5; color: #065f46; }
.badge.low { background: #fef3c7; color: #92400e; }
.badge.out { background: #fee2e2; color: #991b1b; }
.badge.gray { background: #eef1f5; color: var(--muted); }
/* Quantity badges: light green fill, darker green outline, squarer corners */
.badge.qty {
  background: #dcfce7; color: #166534;
  border: 1px solid #16a34a; border-radius: 6px;
}
/* Product name chip + plain-text quantity. Chip color follows the (A)/(B)/(C)
   classification in the product name; unclassified products default to green. */
.nm-chip {
  /* Rounded product pill, unified with the sales cards: pale A/B/C fill,
     class-colored border, default-ink text (not class-colored). Keeps its
     rounder pill corners — only the colors changed. */
  display: inline-block; background: #f0fdf4; color: var(--ink);
  border: 1.5px solid #86efac; border-radius: 10px;
  padding: 4px 10px; font-weight: 700; font-size: 15px;
}
/* Inside a scrollable table a wrapped chip becomes a tall blob — keep it one
   line and let .tbl-scroll pan horizontally instead */
.tbl .nm-chip { white-space: nowrap; }
.nm-chip.cls-b { background: #eff6ff; border-color: #93c5fd; }
.nm-chip.cls-c { background: #fff7ed; border-color: #fdba74; }
/* Custom Label row (Batch Labels page): batch codes are long, so on phones
   stack it — batch on top, name below, the Download button below that and
   right-aligned. Desktop keeps the three fields inline. */
@media (max-width: 700px) {
  #cl-row { flex-direction: column; align-items: stretch; }
  #cl-row > .field { width: 100%; min-width: 0; }
  #cl-row .cl-golbl { display: none; }
  #cl-row .cl-gowrap { justify-content: flex-end; min-height: 0; }
}
.nm-chip.sm { font-size: 12.5px; padding: 2px 8px; font-weight: 600; }
.nm-chip.lg { font-size: 18px; padding: 6px 12px; }
/* Batch age chips, traffic-light aging: green = oldest (move it first),
   yellow = older middle batches, red = newest */
.age-chip {
  display: inline-block; padding: 2px 8px; border-radius: 6px;
  font-size: 12.5px; font-weight: 700; margin-left: 6px;
}
.age-chip.oldest { background: var(--green); color: #fff; }
.age-chip.mid { background: #facc15; color: #713f12; }
.age-chip.new { background: var(--red); color: #fff; }
/* Name chip + age chip always ride side by side — never wrap apart */
.chip-pair { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; max-width: 100%; }
.chip-pair .age-chip { margin-left: 0; flex-shrink: 0; }
/* Age chip inside a pick button: tighter so the button stays compact */
button .age-chip { margin-left: 4px; padding: 1px 6px; font-size: 11.5px; }

/* Dropdown menu (facility card "Manage ▾" etc.): a light-purple trigger and a
   floating panel of actions — collapses a cluster of buttons into one control */
.menu-wrap { position: relative; display: inline-block; }
.menu-pop {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 30;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .16); padding: 6px; min-width: 190px;
  display: none;
}
.menu-wrap.open .menu-pop { display: block; }
.menu-pop button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 9px 12px; border-radius: 7px; font-size: 14px; color: var(--ink); cursor: pointer;
}
.menu-pop button:hover { background: var(--primary-light); }
.menu-pop button.danger { color: var(--red); }
.menu-pop .menu-sep { border-top: 1px solid var(--line); margin: 5px 2px; }
/* Phone guard: the panel must never be wider than the screen itself
   (clampMenu() in admin.html shifts it back on-screen after open) */
@media (max-width: 480px) {
  .menu-pop { max-width: calc(100vw - 24px); }
}
/* Sell-page topbar Options menu: the topbar spacer pushes the button to the
   RIGHT edge, so the pop keeps the default right:0 anchor (opens inward) and
   gets finger-size rows for one-thumb use at the counter. */
.menu-pop.mob { min-width: 232px; max-width: calc(100vw - 24px); }
.menu-pop.mob button { padding: 12px 14px; font-size: 15.5px; font-weight: 600; }

/* Accounting math-box drill-downs: tappable rows expand an indented detail
   list (pros by salesman, fee lines with their required note, open balances) */
.mp-click { cursor: pointer; }
.mp-click:hover { background: var(--primary-light); border-radius: 6px; }
.mp-caret { color: var(--muted); font-size: 11px; display: inline-block; width: 12px; }
.mp-sub {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 3px 0 3px 18px; font-size: 13px; color: var(--ink);
}
.mp-sub .money { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Return picker: one tappable row per price tier, the way the ticket rang up */
.ret-tier {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px;
  margin-top: 6px; font-size: 14px; cursor: pointer;
}
.ret-tier:hover { background: var(--primary-light); border-color: var(--primary); }
.ret-tier.done { opacity: .55; cursor: default; }
.ret-tier.done:hover { background: none; border-color: var(--line); }

/* Per-row action-button cluster (products, batches, staff rows): real gaps
   instead of literal-space separators, wraps cleanly on narrow screens */
.row-actions { display: inline-flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }

/* Transfer status chips: light purple until confirmed, solid purple once received */
.status-chip {
  display: inline-block; padding: 4px 12px; border-radius: 8px;
  font-size: 12.5px; font-weight: 700;
  background: var(--primary-light); border: 1.5px solid var(--primary); color: var(--primary-dark);
}
.status-chip.filled { background: var(--primary); color: #fff; }

/* Quantity chip: light purple, matching the Customer Total style (owner's pick) */
.qty-chip {
  /* was a purple pill — quantities read as plain bold text now, matching how
     numbers are listed everywhere else in the app */
  display: inline-block; background: none; color: var(--ink);
  border: none; border-radius: 0;
  padding: 0; font-weight: 700; font-size: 14.5px;
}
/* Sale modal: the in-stock count is the number the seller checks before every
   sale — bigger there than the listing-size text used elsewhere */
#sale-modal .qty-chip { font-size: 17px; }
.qty-text { color: var(--ink); font-weight: 600; font-size: 14px; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; box-shadow: var(--shadow);
  /* A tile may shrink below its content: without this, one long money value
     widens its grid track and pushes the whole strip past the card edge.
     fitStatStrip (shared.js) then shrinks the text to fit INSIDE the tile. */
  min-width: 0;
}
/* Phones: every stat strip is exactly 2-up — overrides the dashboard's inline
   4-col so tiles keep readable width; minmax(0,1fr) so tracks never grow past
   the card no matter how long the number gets. */
@media (max-width: 700px) {
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
.stat .lbl { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.stat .val { font-size: 24px; font-weight: 800; margin-top: 2px; font-variant-numeric: tabular-nums; }
.stat .val.green { color: var(--green); }
.stat .val.red { color: var(--red); }
/* KPI tiles on the Accounting page reuse .stat: a third note line, plus an
   amber "needs action" variant for pending confirmations */
.stat .note { margin-top: 3px; }
.stat.warn { background: #fffbeb; border-color: #fbbf24; }
.stat.warn .val { color: #b45309; }
/* Window tags (U14): every money tile names its clock. Period-following tiles
   carry the live window in the accent color; standing tiles a quiet gray. The
   tag sits top-right so the label row stays clean. */
/* UC-007 (owner, 2026-07-26): the chip KEEPS its pill shape — it just moves
   from the right float to centered at the tile top, with a faint rule under
   it and the tile data below. Tiles without a chip render no rule. */
.stat .win {
  display: block; width: fit-content; margin: 0 auto 8px;
  font-size: 9px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); border-radius: 99px;
  padding: 3px 9px; line-height: 1; background: var(--bg); white-space: nowrap;
}
.stat .win + .lbl { border-top: 1px solid var(--line); padding-top: 8px; }
.stat .win.live { color: var(--primary-dark); border-color: var(--primary-press); background: var(--primary-light); }
/* Changing the period softly washes the tiles that follow it — the chips that
   move answer visibly; the standing ones sit still. */
@keyframes chip-pulse {
  0% { background: var(--primary-light); }
  100% { background: var(--card); }
}
.stat.pulse { animation: chip-pulse .7s ease-out; }
@media (prefers-reduced-motion: reduce) { .stat.pulse { animation: none; } }
/* Money-action buttons on phones (U9): Accept/Reject and Record Payment get
   real thumb targets — everything else keeps the compact .small. */
.btn.small.touch { padding: 9px 14px; font-size: 14px; }
/* Queue count on the money tab button — the "waiting on this console" nudge
   visible from every tab (settlements + payments awaiting acceptance). */
.tab-count {
  margin-left: 6px; display: inline-block; vertical-align: 1px;
  background: var(--primary); color: #fff; border-radius: 99px;
  font-size: 11px; font-weight: 700; line-height: 1.5; padding: 0 7px;
}
/* Avg Sale Price tile: three compact class lines instead of one big .val, so it
   sits as a normal stat tile in the flow grid. Smaller font on phones keeps each
   "(A) $000.00 (00 units)" line on one row inside the 2-up cell. */
.stat.avg-chip .avg-lines { margin-top: 4px; font-size: 13px; line-height: 1.7; }
.stat.avg-chip .avg-lines > div { padding: 1px 0; white-space: nowrap; }
.stat.avg-chip .avg-lines .avg-units { font-size: .85em; }
@media (max-width: 700px) { .stat.avg-chip .avg-lines { font-size: 11px; line-height: 1.65; } }
/* Tiny class badge: the (A)/(B)/(C) marker as a small pill in the A/B/C colors
   (A green, B blue, C orange) — pale fill + class-colored border, ink text like
   .nm-chip. Only the letter is a badge, not the whole line. */
.cls-badge {
  display: inline-block; min-width: 16px; text-align: center;
  background: #f0fdf4; border: 1px solid #86efac; border-radius: 5px;
  padding: 0 4px; font-weight: 800; font-size: 10.5px; line-height: 15px;
  color: var(--ink); vertical-align: baseline;
}
.cls-badge.cls-b { background: #eff6ff; border-color: #93c5fd; }
.cls-badge.cls-c { background: #fff7ed; border-color: #fdba74; }

/* Role gating: applyRoleUi stamps body.partner for a partner admin; each
   side's cards/tabs simply never exist for the other */
body.partner .owner-only { display: none !important; }
/* A partner runs one facility, so the Batches "Total" column just repeats the
   Qty — hide it for them (owner keeps it for its multi-facility breakdown). */
body.partner .col-total { display: none; }
body:not(.partner) .partner-only { display: none !important; }

/* Segmented picker (Your product / LMP product / All) */
.seg { display: inline-flex; background: var(--bg); border: 1px solid var(--line); border-radius: 9px; padding: 3px; gap: 2px; }
.seg button {
  border: 0; background: transparent; color: var(--muted); font: inherit; font-weight: 600;
  font-size: 13px; padding: 6px 12px; border-radius: 7px; cursor: pointer; white-space: nowrap;
}
.seg button.on { background: #fff; color: var(--ink); box-shadow: 0 1px 3px rgba(15,23,42,.15); }

/* Collapsible card sections (Sales Ledger, Payment History, Activity Log) */
.collapse-h {
  width: 100%; display: flex; align-items: center; gap: 8px; background: none;
  border: 0; padding: 0; font: inherit; color: var(--ink); cursor: pointer; text-align: left;
}
.collapse-h .caret { margin-left: auto; color: var(--muted); transition: transform .15s ease; }
.collapse-card.collapsed .caret { transform: rotate(-90deg); }
.collapse-card.collapsed .collapse-body { display: none; }

/* Slim in-card banner (partner: "what you owe lives on Payments") */
.note-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--primary-light); border: 1px solid var(--primary);
  border-radius: 10px; padding: 10px 14px; font-size: 14px;
}

/* Phones: filter rows (Activity Log, Ledger) must wrap, never clip — date
   inputs give up their fixed minimum and share the row */
@media (max-width: 520px) {
  .row > .field { min-width: 105px; }
  .row .field input[type="date"] { min-width: 0; max-width: 100%; }
}

/* Tabs */
.tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.tabs button {
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  padding: 8px 14px; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer;
}
.tabs button.active { background: var(--primary); border-color: var(--primary); color: #fff; }

/* Modal */
.modal-back {
  position: fixed; inset: 0; background: rgba(16, 24, 40, .55);
  display: none; align-items: flex-end; justify-content: center; z-index: 100;
  padding: 0;
}
.modal-back.open { display: flex; }
.modal {
  background: #fff; width: 100%; max-width: 480px;
  border-radius: 18px 18px 0 0;
  /* extra bottom padding keeps buttons clear of the iPhone address bar / home indicator */
  padding: 20px 18px calc(30px + env(safe-area-inset-bottom, 0px));
  max-height: 96vh; max-height: 96dvh; overflow-y: auto;
}
@media (min-width: 640px) {
  .modal-back { align-items: center; padding: 20px; }
  .modal { border-radius: 18px; }
}
.modal h2 { margin: 0 0 4px; font-size: 19px; }
/* The page behind ANY open popup stays put — every popup in the app is a
   .modal-back (static or dynamically created), so one selector covers all. */
html:has(.modal-back.open), body:has(.modal-back.open) { overflow: hidden; }

/* Partner Payments page: math box and pros list share the row on desktop so
   the card fills instead of one narrow column floating in white space. */
.pay-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
@media (max-width: 700px) { .pay-grid { grid-template-columns: 1fr; } }

/* Phones: date inputs have a wide intrinsic minimum on iOS — clamp them to
   their field so the ledger / activity-log From+To pickers never overlap each
   other or spill past the card edge. */
@media (max-width: 700px) {
  .row .field { min-width: 0; }
  .lg-filters .field, .log-filters .field { flex: 1 1 46%; min-width: 0; }
  /* iOS Safari: native date inputs carry an intrinsic minimum width that
     ignores flex sizing entirely — the From/To pickers overlapped each other
     and spilled past the card. Stripping the native appearance (mobile only)
     makes them obey their field; our .field input styling supplies the look. */
  .field input[type="date"] {
    width: 100%; max-width: 100%; min-width: 0;
    -webkit-appearance: none; appearance: none;
    display: block; height: 46px;
  }
  .field input[type="date"]::-webkit-date-and-time-value { text-align: left; }
}
/* Return popup: the pick list can run long — Close rides the bottom of the
   visible area instead of hiding below a full page of scroll. */
#ret-close {
  position: sticky; bottom: 0;
  box-shadow: 0 -10px 14px -8px rgba(16, 24, 40, .25);
}
/* Action buttons stay visible even when tall popup content scrolls */
.modal .modal-actions {
  position: sticky; bottom: 0; background: #fff;
  padding-top: 10px; margin-bottom: -6px;
}
.modal .sub { color: var(--muted); font-size: 14px; margin-bottom: 14px; }

/* Quantity stepper */
.stepper { display: flex; align-items: stretch; gap: 6px; }
.stepper button {
  width: 46px; min-height: 42px; font-size: 20px; font-weight: 700;
  border: 1.5px solid var(--primary);
  border-radius: 6px;
  background: var(--primary);          /* solid dark purple, matching all buttons */
  color: #fff;
  cursor: pointer;
}
.stepper button:active { background: var(--primary-dark); }
.stepper input {
  flex: 1; text-align: center; font-size: 18px; font-weight: 700;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--ink);
  -moz-appearance: textfield; appearance: textfield;
}
/* the +/− buttons replace the browser's tiny number spinners */
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* plain number boxes with no spinner arrows */
input.no-spin::-webkit-outer-spin-button,
input.no-spin::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input.no-spin { -moz-appearance: textfield; appearance: textfield; }
/* Compact variant for placing the stepper in a header line */
.stepper.inline { flex-shrink: 0; }
.stepper.inline button { width: 42px; }
.stepper.inline input { flex: 0 0 52px; width: 52px; }
/* Mini variant for table rows (e.g. transfer send-qty) */
.stepper.mini { gap: 4px; justify-content: flex-end; }
.stepper.mini button { width: 30px; min-height: 30px; font-size: 15px; border-radius: 5px; }
.stepper.mini button:disabled { opacity: .4; cursor: not-allowed; }
.stepper.mini input { flex: 0 0 54px; width: 54px; min-height: 30px; padding: 2px; font-size: 15px; }
/* Phones: the transfer batch list must not scroll sideways. The +/− buttons
   go (typing beats tap-tap-tap there anyway), the Batch ID and stock columns
   fold away — stock re-appears as "· N" beside the product chip (.t-have,
   desktop-hidden), long names ellipsize, paddings tighten. Desktop keeps the
   full table. Covers admin AND manager (same form). */
.t-have { display: none; }
@media (max-width: 700px) {
  .stepper.mini button { display: none; }
  .stepper.mini input { flex: 0 0 58px; width: 58px; min-height: 38px; font-size: 16px; }
  td input[data-talias] { max-width: 92px !important; }
  table:has(#t-lines) th:nth-child(1), #t-lines td:nth-child(1),
  table:has(#t-lines) th:nth-child(3), #t-lines td:nth-child(3) { display: none; }
  table:has(#t-lines) th, #t-lines td { padding-left: 5px; padding-right: 5px; }
  /* fixed layout: the table CANNOT outgrow the card — content ellipsizes */
  table:has(#t-lines) { table-layout: fixed; width: 100%; }
  table:has(#t-lines) th:nth-child(4), #t-lines td:nth-child(4) { width: 68px; }
  table:has(#t-lines) th:nth-child(5), #t-lines td:nth-child(5) { width: 102px; }
  table:has(#t-lines) th { white-space: normal; }
  table:has(#t-lines) th .muted { display: none; }  /* "(display name)" hint */
  #t-lines td { overflow: hidden; }
  #t-lines .nm-chip {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; display: inline-block; vertical-align: middle;
  }
  .t-have { display: inline; }
}

/* Sale math summary */
.mathbox {
  background: #f8fafc; border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; margin: 14px 0; font-size: 15px;
}
/* Money rows everywhere (not just inside a mathbox — the Confirm Order popup
   lists lines bare, and text was running straight into the dollar figure).
   The gap guarantees daylight even when a long name pushes into the money. */
.mrow { display: flex; justify-content: space-between; gap: 16px; padding: 3px 0; }
.mrow.total { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 8px; font-weight: 800; font-size: 17px; }
.mrow .money { white-space: nowrap; }

/* Available Products (sell page): one tall, tappable row per product in a
   table layout — Product | Price | Quantity — colored by A/B/C classification */
.prod-head {
  display: grid; gap: 8px; padding: 0 12px 6px;
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; color: var(--muted);
}
.prod-row {
  display: grid; gap: 8px; align-items: center;
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  /* Same scheme as the inside-sale cards: pale A/B/C tint, class-colored
     border, default-ink text (not class-colored), muted secondary info. */
  background: #f0fdf4; border: 1.5px solid #86efac; color: var(--ink);
  border-radius: 10px;
  padding: 12px; margin: 0;
}
.prod-row + .prod-row { margin-top: 8px; }
.prod-row.cls-b { background: #eff6ff; border-color: #93c5fd; }
.prod-row.cls-c { background: #fff7ed; border-color: #fdba74; }
.prod-row:active { transform: scale(.99); }
.prod-row .p-name { font-weight: 600; font-size: 15px; }
.prod-row .p-price { font-weight: 500; color: var(--muted); }
.prod-row .p-qty { font-weight: 700; }
.prod-head .num, .prod-row .num { text-align: right; }

/* Scanner overlay */
#scan-overlay {
  position: fixed; inset: 0; background: #000; z-index: 200; display: none;
  flex-direction: column;
}
#scan-overlay.open { display: flex; }
#scan-overlay .scan-top { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px; color: #fff; }
#qr-reader { flex: 1; overflow: hidden; }
#qr-reader video { object-fit: cover; }

.muted { color: var(--muted); }
.small { font-size: 13px; }
.right { text-align: right; }
.mt { margin-top: 14px; }
.money { font-variant-numeric: tabular-nums; }
.pos { color: var(--green); font-weight: 700; }
.neg { color: var(--red); font-weight: 700; }

/* Toasts sit dead-center so they can't be missed (bottom felt buried).
   pointer-events:none keeps taps working right through them. */
.toast {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: #101828; color: #fff; padding: 14px 22px; border-radius: 12px;
  /* Above every modal/dialog layer (they sit at 400) — an error on a popup
     must land on top of the popup, never behind it. */
  font-size: 15px; font-weight: 600; z-index: 700; box-shadow: 0 8px 24px rgba(0,0,0,.25);
  opacity: 0; transition: opacity .2s; pointer-events: none; max-width: 90vw; text-align: center;
}
.toast.show { opacity: 1; }
.toast.err { background: var(--red); }

/* Custom product dropdown (Inside Sale modal): name left, stock right, code
   muted — a scannable list where a native select ran everything together. */
.dd { position: relative; }
.dd-btn {
  width: 100%; text-align: left; background: #fff; color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
  font-size: 15px; cursor: pointer;
}
.dd-btn:after { content: "▾"; float: right; color: var(--muted); }
.dd-pop {
  display: none; position: absolute; top: calc(100% + 4px); left: 0; z-index: 60;
  min-width: 300px; max-height: 280px; overflow: auto;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow);
}
.dd.open .dd-pop { display: block; }
.dd-pop button {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  width: 100%; padding: 10px 12px; background: #fff; border: 0;
  border-bottom: 1px solid var(--line); text-align: left; font-size: 14px;
  color: var(--ink); cursor: pointer; white-space: nowrap;
}
.dd-pop button:last-child { border-bottom: 0; }
.dd-pop button:hover { background: var(--primary-light); }
.dd-meta { color: var(--muted); font-size: 12px; }

.empty { text-align: center; color: var(--muted); padding: 26px 10px; font-size: 14.5px; }
/* Three distinct looks for the same container (mega-review): a failed load is
   tinted red so it can't be mistaken for a real empty; a still-loading state
   pulses so motion signals "working" vs a static "nothing here". A two-line
   empty pairs a headline with a quiet next-step sub-line. */
.empty.err { color: var(--red); }
.empty .sub { display: block; margin-top: 5px; font-size: 13px; opacity: .8; }
.empty.loading { animation: emptyPulse 1.6s ease-in-out infinite; }
@keyframes emptyPulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
/* "Live" indicator for auto-refreshing feeds — its own small rule (not the
   period-tag token), a quiet purple pill with a soft breathing dot. */
.live-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--primary); background: var(--primary-light);
  padding: 2px 8px; border-radius: 999px; vertical-align: middle;
}
.live-pill::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--primary); animation: livePulse 1.8s ease-in-out infinite;
}
@keyframes livePulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* Toggle switch */
.switch { position: relative; width: 48px; height: 28px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; background: #cbd5e1; border-radius: 999px;
  transition: background .15s; cursor: pointer;
}
.switch .track::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  background: #fff; border-radius: 50%; transition: left .15s;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.switch input:checked + .track { background: var(--green); }
.switch input:checked + .track::after { left: 23px; }
.setting-row { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.setting-row:last-child { border-bottom: none; }
.setting-row .info { flex: 1; }
.setting-row .info .t { font-weight: 600; }
.setting-row .info .d { font-size: 13px; color: var(--muted); }

/* Mobile fallback for the desktop consoles (admin/manager): functional, not
   fancy. Scoped to small screens only — desktop rendering is untouched. */
@media (max-width: 700px) {
  /* tab bar becomes its own card: all tabs visible, no scrolling */
  body.desktop .tabs {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow); padding: 10px;
  }
  body.desktop .tabs button { padding: 9px 6px; font-size: 13px; }
  /* forms stack one field per line; fields use the full width */
  body.desktop .row { flex-wrap: wrap !important; }
  body.desktop .row > .field { flex: 1 1 100% !important; }
  /* ...except paired fields (ledger + log Salesperson/Product, From/To) which
     sit two-up at half width each; min-width:0 stops date inputs overrunning */
  body.desktop .row > .field.half { flex: 1 1 calc(50% - 5px) !important; min-width: 0 !important; }
  /* desktop-sized buttons are marginal thumb targets — give row buttons (Add
     facility/manager/salesman etc.) a proper 46px tap height on phones */
  body.desktop .row > .btn { min-height: 46px; padding-top: 12px; padding-bottom: 12px; }
  /* free the desktop max-width AND pin to the field — a select otherwise keeps
     its intrinsic width (longest option name) and overflows the viewport */
  body.desktop .field select, body.desktop .field input {
    max-width: none; width: 100%; box-sizing: border-box;
  }
  /* dashboard stats: two per row instead of five crushed columns */
  body.desktop .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  /* Create Bulk Inventory: quantity stepper + target price share a line */
  body.desktop .row > .field:has(> .stepper) { flex: 0 0 auto !important; }
  body.desktop .row > .field:has(> #b-new-price) { flex: 1 1 0 !important; min-width: 110px; }
  /* Transfer History: shrink the "Transfer" header to "#" so columns fit */
  body.desktop th.th-xfer { font-size: 0; }
  body.desktop th.th-xfer::before { content: "#"; font-size: 12px; }
  /* Batches card: "Batch ID" header shrinks to "ID"; action buttons drop to
     their own right-aligned line under each row */
  body.desktop th.th-bid { font-size: 0; }
  body.desktop th.th-bid::before { content: "ID"; font-size: 12px; }
  body.desktop table.batches thead th:last-child { display: none; }
  body.desktop table.batches tr {
    display: grid; grid-template-columns: 1.1fr 1.6fr .9fr 1fr .5fr;
    align-items: start;
  }
  /* partner has no Total column — drop its grid track and hide the cell (the
     mobile "th/td display:block" rule outspecifies the base .col-total hide) */
  body.desktop.partner table.batches tr { grid-template-columns: 1.1fr 1.6fr .9fr 1fr; }
  body.desktop.partner table.batches .col-total { display: none; }
  body.desktop table.batches th,
  body.desktop table.batches td { display: block; border-bottom: 0; }
  body.desktop table.batches thead tr { border-bottom: 2px solid var(--line); }
  body.desktop table.batches tbody tr { border-bottom: 1px solid var(--line); }
  body.desktop table.batches tbody tr:last-child { border-bottom: none; }
  body.desktop table.batches td:last-child {
    grid-column: 1 / -1; text-align: right; padding-top: 10px; padding-bottom: 12px;
  }
  /* Products: same stacked-grid rows so the Options menu drops to its own line */
  body.desktop table.products thead th:last-child { display: none; }
  body.desktop table.products tr {
    display: grid; grid-template-columns: 1.6fr 1fr .7fr .7fr; align-items: start;
  }
  body.desktop table.products th,
  body.desktop table.products td { display: block; border-bottom: 0; }
  body.desktop table.products thead tr { border-bottom: 2px solid var(--line); }
  body.desktop table.products tbody tr { border-bottom: 1px solid var(--line); }
  body.desktop table.products tbody tr:last-child { border-bottom: none; }
  body.desktop table.products td:last-child {
    grid-column: 1 / -1; text-align: right; padding-top: 10px; padding-bottom: 12px;
  }
  body.desktop .wrap { padding-left: 10px; padding-right: 10px; }

  /* Owner report M2: the Sales Breakdown date inputs are bare (not .field-
     wrapped), so they miss the stacking rules and overflow iPhone width.
     Pin them full-width, and neutralize the desktop "margin-top:18px" Apply
     alignment hacks that leave a stray gap once fields stack. */
  body.desktop input[type="date"] { max-width: none !important; width: 100%; box-sizing: border-box; }
  body.desktop .row > input[type="date"] { flex: 1 1 100% !important; }
  body.desktop #set-range-label { flex: 1 1 100% !important; }
  body.desktop .row > .btn[style*="margin-top"] { margin-top: 0 !important; }

  /* M3/M4: action-button clusters (facility staff rows, product/staff table
     rows, the card-heading Manage menu) drop to their own line and wrap
     instead of shoving content off-screen. */
  body.desktop .card > h2 > span[style*="float"] { float: none !important; display: block; margin-top: 8px; text-align: right; }
  /* inventory stock chip: shorten "Quantity:" to "qty:" on phones */
  body.desktop .q-long { display: none; }
  body.desktop .q-short { display: inline; }
  body.desktop td.right, body.desktop td[style*="right"] {
    white-space: normal !important;
  }
  /* Live-inventory ±1 steppers are desktop-only; phones type a number + Set */
  body.desktop .adj-steppers { display: none; }

  /* Facility Settings name row on phones: label on its own line, input + Save
     share the next line, Platform Admins drops below, then a little breathing
     room before the Managers section. */
  #tf-name-row .tf-name-label { flex: 1 1 100%; }
  #tf-name-row #set-company-name { flex: 1 1 auto; max-width: none !important; }
  #tf-name-row .tf-spacer { display: none; }
  #tf-name-row .tf-admins { flex: 1 1 100%; }

  /* Inside-sale modal on phones: product selector on its own line, then
     Qty / Price / line-total / delete on the next line (headers hidden). */
  .is-table thead { display: none; }
  .is-table, .is-table tbody { display: block; }
  .is-table tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px;
    padding: 10px 0; border-bottom: 1px solid var(--line);
  }
  .is-table td { display: flex; align-items: center; gap: 6px; border: 0; padding: 0; }
  .is-table td.is-cell-prod { flex: 1 1 100%; }
  .is-table .is-batch { width: 100%; }
  .is-table .is-qty, .is-table .is-price { width: 74px; }
  .is-table .m-lbl { display: inline; font-size: 12px; color: var(--muted); }
  .is-table td.is-cell-line { margin-left: auto; font-weight: 600; }
}

@media print {
  .topbar, .tabs, .no-print { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border: none; }
}

/* In-page settlement-card math (2026-07-23): the page-scale variant of the
   dialog mathbox — same rows, compact type and padding, so inbox cards match
   the console instead of shouting at popup size. */
.mathbox.compact { padding: 8px 12px; margin: 8px 0 0; font-size: 13px; }
.mathbox.compact .mrow { padding: 2px 0; }
.mathbox.compact .mrow.total { font-size: 13.5px; padding-top: 6px; margin-top: 4px; }
