/* ==========================================================================
   THE PHONE LAYOUT — stage 1 (2026-10-12)

   ⛔ ONE SWITCH, TWO CONDITIONS. Every rule in this file is
       · under `html.phone-next`  — the class client/index.html sets from localStorage['httl.phoneNext'] === '1'
       · inside `@media (max-width: 640px)` — the app's own phone breakpoint (DESIGN.md: "640px, the dominant mobile
         breakpoint"; it is where the floating buttons, the stat groups and the tables' label lines already turn)
     so without the class, or on a wider screen, this file matches nothing and the app is exactly as it was.
     tools/verify-phone-layout.js reads this file and fails on a rule that breaks either condition, and
     client/src/lib/phoneNext.js holds the SAME two conditions for the markup.

   WHAT IT ANSWERS — the audit of 2026-10-12 at 430x932 (iPhone Pro Max), 41 screens:
     · 644 of 645 fields had text under 16px, so iPhone Safari zoomed the page on every tap into one   → §1
     · 4,335 of 4,740 buttons and links were under 44px, the size a fingertip needs                    → §1
     · 2,059 pieces of text were under 12px                                                              → §0
     · three round buttons floated over the page in 154 places, and over the open menu                  → §2
     · the menu button was 38px and its rows 30px                                                        → §2
     · nothing allowed for the notch, the home bar, or a browser bar that comes and goes (100vh)        → §2, §3
     · every list turned each row into one tall card (an MPO: 13 lines, 990px)                           → §5
     · a page's main button sat a screen or more down                                                    → §6

   ⛔ THE MUSCLE-MEMORY RULE HOLDS HERE TOO (DESIGN.md). Nothing in this file renames, removes or re-orders a
   control. It changes size, housing and spacing at phone width only.

   Colour: the top bar is the same near-black chrome as the rail, in both themes, so — like `.page-title` and
   `.side` in app.css — it carries the chrome's own literals; so does the glass of the bar of tabs (§2), whose tint
   is chosen against what lies behind it. Everything on the paper uses tokens.
   ========================================================================== */
@media (max-width: 640px) {

/* ---------- §0  The measures, and the type steps at phone size ---------- */
html.phone-next {
  --ph-top: 52px;                                    /* the top bar, before the notch */
  --ph-bar: 60px;                                    /* the floating bar of tabs: a 52px tab, 4px of capsule round it */
  --ph-dock-gap: max(10px, calc(var(--ph-safe-b) - 12px));   /* how far it stands off the foot of the screen */
  /* what the bar takes off the foot (its height, 8px of air above it, its gap) — less the safe area, which every
     user of this adds back itself */
  --ph-bottom: calc(var(--ph-bar) + 8px + var(--ph-dock-gap) - var(--ph-safe-b));
  --ph-strip: 0px;                                   /* what the tabs take off the top: nothing */
  --ph-tap: 44px;                                    /* the smallest thing a fingertip hits reliably */
  --ph-safe-t: env(safe-area-inset-top, 0px);
  --ph-safe-b: env(safe-area-inset-bottom, 0px);
  --ph-safe-l: env(safe-area-inset-left, 0px);
  --ph-safe-r: env(safe-area-inset-right, 0px);
  /* iPhone Safari zooms the whole page when a field's text is under 16 CSS px. Not a taste: a threshold. */
  --ph-field: max(16px, 1.053rem);
  /* The SAME eight type steps, re-valued for a screen held at arm's length. The two smallest steps (9.1px and 10px
     on a desk) both rise to 12px — the floor — and each step above moves up one notch with them:
       micro 9.1 → 12 · xs 10 → 12 · sm 11.2 → 13 · body 12.2 → 14 · lg 14.4 → 16.   h2, h1 and display stay.
     In rem, like the desk values, so a person's own text-size setting still scales them. */
  --fs-micro: .79rem;
  --fs-xs: .79rem;
  --fs-sm: .855rem;
  --fs-body: .92rem;
  --fs-lg: 1.053rem;
  -webkit-text-size-adjust: 100%;
}

/* ---------- §1  Every screen at once: fields, and things a finger presses ---------- */
/* !important, deliberately and only here: dozens of component rules and utility classes set a field's size for the
   desk (the page jump, the search scope, dialog grids), and the zoom is triggered by ANY one of them winning. */
html.phone-next :is(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]), select, textarea, [contenteditable=""], [contenteditable="true"]) {
  font-size: var(--ph-field) !important;
}
html.phone-next :is(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="hidden"]), select) {
  min-height: var(--ph-tap);
}
/* A button's BOX grows to 44px (not only an invisible halo), so what looks pressable and what is pressable agree. */
html.phone-next :is(button, .btn, summary, [role="button"], [role="tab"], [role="menuitem"], [role="menuitemcheckbox"], [role="option"]) {
  min-height: var(--ph-tap);
  min-width: var(--ph-tap);
}
html.phone-next a.btn { display: inline-flex; align-items: center; justify-content: center; }
/* A link drawn as a link-button stands in a row of buttons ("Open the sheet ↗" beside "Read now"; "Open the
   account" on an order's credit panel) and was 22px tall there ([MEASURED 2026-10-13] 101.6 x 22) — its <button>
   twin already has the floor from the rule above. Its words sit in the middle of it. */
html.phone-next a.btn-link { display: inline-flex; align-items: center; min-height: var(--ph-tap); }
/* The stretch above moves a button's edges, not what is in it: a button that lays its content out as a flex row and
   says nothing about where it sits keeps it at the left (or the top) of the bigger box. Swept on 40 screens
   ([MEASURED 2026-10-12], after the owner caught the Dashboard's bug button, §4b): the Credit page's tab buttons
   were 15–17px left of centre; an item's "our price" opener rode 12px high (its parts are set on one baseline, so it
   takes the floor as equal padding above and below instead of as a height). */
html.phone-next .cq-btn { justify-content: center; }
/* A row's glyph-only "Send to a VA" / "Needs review" button (Warehouse, Live & Sold, eBay Item Review — unfolded):
   a 44px square whose 13px glyph sat 7.5px left of centre ([MEASURED 2026-10-13], the centring sweep on 87 states).
   Centred, and the glyph at the size the other glyph-only squares have (20px). */
html.phone-next .rv-btn.compact { justify-content: center; }
html.phone-next .rv-btn.compact svg { width: 20px; height: 20px; }
html.phone-next .our-price button.our-open { min-height: 0; padding: 12px 0; }
/* A tick box or radio is pressed through its label: the label is the 44px target (20px box + 12px above and below),
   and the box itself is easier to see than the desk's 13px one. */
html.phone-next input:is([type="checkbox"], [type="radio"]) { width: 20px; height: 20px; flex: none; }
html.phone-next label:has(> input[type="checkbox"], > input[type="radio"]) { padding-block: 12px; min-width: var(--ph-tap); margin-bottom: 0; }
/* A label and its control share a centre line (standing rule R1); a field that runs to several lines keeps its
   label at the top. */
html.phone-next .kv { align-items: center; }
html.phone-next .kv dt:not(.kv-group-start) { padding-top: 0; }
html.phone-next .kv dt:has(+ dd > textarea) { align-self: start; padding-top: 12px; }
html.phone-next .plat-chip { font-size: var(--fs-xs); }
/* The Text-On-Tint Rule (DESIGN.md), applied where it had not been: these four chips set the green LAMP colour as
   text on the green tint — 3.74:1 [MEASURED 2026-10-12 on a Paid chip]. The token made for that pairing is 5.10:1. */
html.phone-next .badge:is(.Live, .Paid, .Completed, .Goodprice) { color: var(--green-text); }
html.phone-next .panel { padding: 16px 14px; }
/* The pencil that opens a field for editing: 30px on a desk, with a 44px halo. Here the box itself is 44px and the
   negative margin gives the difference back, so the heading it sits in does not grow. */
html.phone-next .edit-pencil-btn { width: var(--ph-tap); height: var(--ph-tap); margin: -7px; }
html.phone-next .panel h2 .edit-pencil-btn { margin-left: auto; margin-right: -7px; }
/* A slider is dragged by its 28px box on a desk; the box is the target here too. */
html.phone-next input[type="range"] { min-height: var(--ph-tap); }
/* A hint inside a field may be smaller than what is typed into it (the zoom looks at the field's own size), so
   more of a long hint — "Search order #, customer, company, phone…" — is readable before it is cut. */
html.phone-next :is(input, textarea)::placeholder { font-size: var(--fs-sm); }
/* Small text that is not on the type steps: the utility class the charts' labels use, and the matrix's lock. */
html.phone-next .text-xs { font-size: var(--fs-xs); }
html.phone-next .perm-lock { font-size: var(--fs-xs); }

/* THE OLD CARD TABLES, until each list moves to the rows of §5. At phone width a table is already a stack of
   cards with one line per column (app.css "Responsive data tables"). Two things keep those usable meanwhile:
   · a link in a line (a customer, an order number, an eBay number) was an 18px strip. It gets a 44px-tall box whose
     extra height is given back by a negative margin, so the lines do not move: the box reaches into the gap above
     and below its own text and no further than the middle of the neighbouring line's gap;
   · a button in a line is a real 44px button (app.css holds these at 26px for a dense desk row).
   ⚠ What this does NOT do: shorten them. A card line is 33px here against 30px before, because its text follows the
   body step from 12 to 14px — so these lists run about a tenth longer until they get those rows
   ([MEASURED 2026-10-12] Call History 208 → 238 screens; MPO Logs, converted, 147 → 21). */
html.phone-next main td a:not(.btn) { display: inline-block; padding-block: 13px; margin-block: -13px; min-width: var(--ph-tap); }
/* 13px above and below a line of text is 44px where the line is 18px tall and 43px where it is 17 ([MEASURED
   2026-10-12] the SKU links inside the fitment worklist's groups: 44 x 43, 250 of them). The floor is held by the
   box itself, whatever the line — here and for every other link boxed the same way in this file. */
html.phone-next :is(main td a:not(.btn), .kv dd > a, .ph-row-kv dd a, .vm-from a, main p.hint a:not(.btn)) { min-height: var(--ph-tap); box-sizing: border-box; }
/* A phone number that dials is a button set as text: the same 44px box, the same given-back margin. */
html.phone-next .phone-link { margin-block: -12px; }
html.phone-next a.chip { display: inline-flex; align-items: center; min-height: var(--ph-tap); }
html.phone-next .tm-default { font-size: var(--fs-xs); }
html.phone-next .rtable tbody button.ghost,
html.phone-next .rv-btn.compact,
html.phone-next .rtable tbody td.dt-util .rv-btn.compact { min-height: var(--ph-tap); height: auto; margin-top: 0; margin-bottom: 0; }
/* The same for a link that IS a fact on a detail page (a customer's name, a phone number), and the page's own
   small text links. */
html.phone-next .kv dd > a { display: inline-block; padding-block: 13px; margin-block: -13px; min-width: var(--ph-tap); }
html.phone-next :is(.dash-feed-all, .dash-panel-head a, .panel h2 > a, a.ca-open, a.mkt-sold) { display: inline-flex; align-items: center; min-height: var(--ph-tap); }
/* The role table's tick boxes have no label to carry the target (the column and the row name them), so the box
   itself is the 44px target and draws a 20px tick box at its centre; the cell's own padding makes the room. */
html.phone-next .perm-cell { padding: 0; }
html.phone-next input.perm-check {
  -webkit-appearance: none; appearance: none; width: var(--ph-tap); height: var(--ph-tap); margin: 0;
  display: inline-grid; place-items: center; background: transparent; border: 0; border-radius: var(--r-ctl);
}
html.phone-next input.perm-check::before {
  content: ''; width: 20px; height: 20px; box-sizing: border-box; border-radius: var(--r-sm);
  border: 1.5px solid var(--line-strong); background: var(--paper);
}
html.phone-next input.perm-check:checked::before {
  border-color: var(--accent);
  background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0b' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 14px no-repeat;
}
html.phone-next input.perm-check:disabled::before { opacity: .55; }

/* Menus that open from a button (the account menu, row menus). */
html.phone-next [role="menu"] :is([role="menuitem"], [role="menuitemcheckbox"]) { font-size: var(--fs-body); padding-top: 0; padding-bottom: 0; }

/* ---------- §2  The frame: top bar, the floating bar of tabs, the menu ("More") ---------- */
html.phone-next .shell { min-height: 100dvh; }
html.phone-next .mobile-bar {
  height: calc(var(--ph-top) + var(--ph-safe-t));
  padding: var(--ph-safe-t) max(8px, var(--ph-safe-r)) 0 max(14px, var(--ph-safe-l));
}
html.phone-next .mobile-bar .side-logo { height: var(--ph-top); padding: 9px 0; min-width: var(--ph-tap); }
html.phone-next :is(.ph-bar-tools, .ph-bar-slot) { display: flex; align-items: center; gap: var(--sp-3); }
/* "Report a bug", beside the phone button: the same quiet disc, with the bug in the report's own red (the chrome's
   brighter step of it, as the dark theme uses on dark). One tap from any page. */
html.phone-next .ph-bar-bug {
  display: grid; place-items: center; padding: 0;
  width: var(--ph-tap); height: var(--ph-tap); border-radius: 50%;
  border: 0; background: rgba(255, 255, 255, .1); color: #e1746b;
}
html.phone-next .ph-bar-bug:hover { background: rgba(255, 255, 255, .1); }
html.phone-next .ph-bar-bug svg { width: 20px; height: 20px; }
/* The phone button, in the top bar (CallDock renders it here). Outside `.call-dock` its corner dress no longer
   applies, so it is dressed for the chrome: a quiet disc, the same status pip, and the accent only while a call is
   live — light is information. */
html.phone-next .mobile-bar .call-dock-fab {
  position: relative; display: grid; place-items: center; padding: 0;
  width: var(--ph-tap); height: var(--ph-tap); border-radius: 50%;
  border: 0; background: rgba(255, 255, 255, .1); color: #e8ecef;
}
html.phone-next .mobile-bar .call-dock-fab:hover { background: rgba(255, 255, 255, .1); }
html.phone-next .mobile-bar .call-dock-fab .call-dock-fab-ic { width: 20px; height: 20px; }
html.phone-next .mobile-bar .call-dock-fab .call-dock-dot { top: 7px; right: 7px; width: 9px; height: 9px; box-shadow: 0 0 0 2px #232528; }
html.phone-next .mobile-bar .call-dock-fab:is(.busy, [aria-expanded="true"]) { background: var(--accent); color: var(--black); }

/* THE BAR OF TABS — liquid glass, floating (owner, 2026-10-12: "I like D and E; D on darker screens (like nav, which
   is always dark) and probably dark-mode … and E on lighter screens … Is it possible to use both for different
   screens? If so, do that."). One shape, and its glass is always the opposite of what lies behind it:
     a light page (light theme)           dark glass — the chrome's near-black at 80% (at 68% the lit word measured 4.60:1)
     a dark page (dark theme)             clear glass, lighter than the page
     the menu open (black, both themes)   clear glass — a white film, and the words turn dark on it
   Home · Review · More share one capsule; Find is a round button of its own beside it, the way an iPhone's own apps
   set search apart. The page scrolls under both. 60px: a 52px tab (44px is the fingertip floor) with 4px of capsule
   round it. The bar stands 10px off the foot, or 12px into the home indicator's room where there is one.
   The top bar stays solid: at the top of a page nothing is behind it but paper, and dark glass over white paper
   measured flat grey (#5a5a5a at 72%) — beside the black menu it read as a fault. */
html.phone-next {
  --ph-g-bg: rgba(14, 15, 17, .8); --ph-g-ink: #fff; --ph-g-on: rgba(255, 255, 255, .16);
  --ph-g-blur: blur(22px) saturate(180%);
  --ph-g-edge: inset 0 1px 0 rgba(255, 255, 255, .22), inset 0 0 0 1px rgba(255, 255, 255, .08), 0 10px 30px rgba(10, 10, 11, .3);
  --ph-g-sheen: linear-gradient(180deg, rgba(255, 255, 255, .1), rgba(255, 255, 255, 0) 46%);
}
html.phone-next.dark {
  --ph-g-bg: rgba(52, 57, 64, .58);
  --ph-g-edge: inset 0 1px 0 rgba(255, 255, 255, .24), inset 0 0 0 1px rgba(255, 255, 255, .09), 0 10px 30px rgba(0, 0, 0, .5);
}
html.phone-next:has(.side.open) {
  --ph-g-bg: rgba(255, 255, 255, .62); --ph-g-ink: #17191c; --ph-g-on: rgba(23, 25, 28, .1);
  --ph-g-edge: inset 0 1px 0 rgba(255, 255, 255, .9), inset 0 0 0 1px rgba(255, 255, 255, .45), 0 10px 30px rgba(10, 10, 11, .18), 0 1px 3px rgba(10, 10, 11, .14);
  --ph-g-sheen: linear-gradient(180deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 46%);
}
/* DESIGN.md: "Users who ask for reduced transparency get a solid surface instead." The same three, with nothing
   showing through — each the colour its glass makes over what it sits on. (The one nested query the guard allows.) */
@media (prefers-reduced-transparency: reduce) {
  html.phone-next { --ph-g-bg: #0e0f11; --ph-g-blur: none; }
  html.phone-next.dark { --ph-g-bg: #2b2f35; }
  html.phone-next:has(.side.open) { --ph-g-bg: #9e9e9e; }
}
html.phone-next main { padding-bottom: calc(var(--ph-bottom) + var(--ph-safe-b)); }
html.phone-next .ph-tabs {
  position: fixed; z-index: 41;
  left: max(12px, var(--ph-safe-l)); right: max(12px, var(--ph-safe-r)); bottom: var(--ph-dock-gap);
  display: flex; align-items: stretch; height: var(--ph-bar);
}
html.phone-next .ph-tabs::before {
  content: ''; position: absolute; inset: 0 calc(var(--ph-bar) + 10px) 0 0; border-radius: var(--r-pill);
  background-color: var(--ph-g-bg); background-image: var(--ph-g-sheen); box-shadow: var(--ph-g-edge);
  -webkit-backdrop-filter: var(--ph-g-blur); backdrop-filter: var(--ph-g-blur);
  transition: background-color var(--dur-fast) var(--ease);
}
html.phone-next .ph-tab {
  flex: 1 1 0; position: relative; margin: 4px 2px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 0; border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--ph-g-ink); font-size: var(--fs-xs); font-weight: 500; line-height: 1.2;
  transition: color var(--dur-fast) var(--ease);
}
html.phone-next .ph-tab:first-child { margin-left: 4px; }
html.phone-next .ph-tab:hover { background: transparent; }
html.phone-next .ph-tab .ic { width: 22px; height: 22px; opacity: 1; }
/* The lit tab: a brighter lozenge of the same glass, and its word in bold. */
html.phone-next .ph-tab.on { background: var(--ph-g-on); font-weight: 700; }
html.phone-next .ph-tab:focus-visible { outline-offset: -3px; }
/* Find: the round button beside the capsule (12px + the tab's own 2px = the capsule's 4px rim and a 10px gap). Its
   word stays for screen readers. `order` holds it last until PhoneTabBar.jsx lists it last itself. */
html.phone-next .ph-tab-find {
  order: 9; flex: 0 0 var(--ph-bar); margin: 0 0 0 12px; border-radius: 50%;
  background-color: var(--ph-g-bg); background-image: var(--ph-g-sheen); box-shadow: var(--ph-g-edge);
  -webkit-backdrop-filter: var(--ph-g-blur); backdrop-filter: var(--ph-g-blur);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
html.phone-next .ph-tab-find:hover { background-color: var(--ph-g-bg); background-image: var(--ph-g-sheen); }
html.phone-next .ph-tab-find.on { background-color: var(--ph-g-bg); background-image: var(--ph-g-sheen); box-shadow: var(--ph-g-edge), 0 0 0 2px var(--accent); }
html.phone-next .ph-tab-find .ic { width: 24px; height: 24px; }
html.phone-next .ph-tab-find .ph-tab-l { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* How many are waiting for this person — the flag button's own number. */
html.phone-next .ph-tab-n {
  position: absolute; top: 5px; left: calc(50% + 6px);
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill);
  display: grid; place-items: center;
  background: var(--accent); color: var(--black); font-size: var(--fs-xs); font-weight: 700; line-height: 1;
}

/* "More" is the menu: the same drawer, opened from the bar instead of from a 38px button. It runs to the foot of the
   screen, under the bar; its account block is pinned to the foot (AppShell), so THAT block keeps the bar's room
   clear — as padding on the menu itself, rows showed again below the pinned block. */
html.phone-next .side > .sticky { padding-bottom: calc(8px + var(--ph-bottom) + var(--ph-safe-b)); }
html.phone-next .side {
  top: calc(var(--ph-top) + var(--ph-safe-t) + var(--ph-strip));
  bottom: 0;
  padding: 0 var(--ph-safe-r) 0 var(--ph-safe-l);
  overscroll-behavior: contain;
}
html.phone-next .side nav { padding: 6px 8px 8px; gap: 2px; }
html.phone-next .side nav :is(a, button) { min-height: 48px; }
html.phone-next .side nav a .nav-label { font-size: var(--fs-lg); }
html.phone-next .side nav .ic { width: 20px; height: 20px; }
html.phone-next .side nav > .group\/grp { margin-top: 6px; padding-top: 6px; border-top-color: #1e2126; }
/* A group's heading is a divider, kept quiet — but at 60% it measured 2.99:1 on the black; 80% is 4.7:1. */
html.phone-next .side nav button .nav-label > span { opacity: .8; }
html.phone-next .side [aria-haspopup="menu"] { min-height: 56px; }
/* A tap leaves "hover" stuck on the last thing pressed until something else is tapped; on the dark chrome that
   painted a light block over white text. The pressed look on these rows is the app's own (data-state, :active). */
html.phone-next .side [aria-haspopup="menu"]:hover:not([data-state="open"]) { background: transparent; }

/* What used to float keeps clear of the bar of tabs. (The flag and bug buttons are not rendered at all on the
   phone layout — AppShell — so the room app.css kept under every page for them is not taken either.) */
html.phone-next .view-inner { padding: 12px 12px 24px; }
html.phone-next .call-dock {
  left: 0; right: 0; bottom: calc(var(--ph-bottom) + var(--ph-safe-b));
  flex-direction: column; align-items: stretch; gap: 0;
}
html.phone-next .call-dock-panel {
  width: auto; margin: 0 8px 8px;
  max-height: calc(100dvh - var(--ph-top) - var(--ph-safe-t) - var(--ph-strip) - var(--ph-bottom) - var(--ph-safe-b) - 16px);
}
html.phone-next .call-dock-alerts { position: static; width: auto; max-width: none; margin: 0 8px 8px; align-items: stretch; }
html.phone-next .job-strip { bottom: calc(var(--ph-bottom) + var(--ph-safe-b) + 8px); left: 8px; width: calc(100vw - 16px); }
html.phone-next .bgd-dock { --bgd-bottom: calc(var(--ph-bottom) + var(--ph-safe-b) + 12px); }
html.phone-next .cr-undo { right: 8px; bottom: calc(var(--ph-bottom) + var(--ph-safe-b) + 8px); }
html.phone-next [data-sonner-toaster][data-y-position="bottom"] { bottom: calc(var(--ph-bottom) + var(--ph-safe-b) + 12px) !important; }
/* …and of a page's own action bar (65px), where there is one: "Order updated" landed on top of Save changes. */
html.phone-next:has(.ph-actionbar) [data-sonner-toaster][data-y-position="bottom"] { bottom: calc(var(--ph-bottom) + var(--ph-safe-b) + 77px) !important; }

/* ---------- §3  Dialogs are sheets: full width, from the foot of the screen, never taller than it ---------- */
html.phone-next .dlg-overlay { display: flex; flex-direction: column; justify-content: flex-end; padding: 0; }
html.phone-next .modal,
html.phone-next .modal.narrow,
html.phone-next .modal.wide {
  width: 100%; max-width: none; --dlg-w: 100vw; margin: 0;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: 22px 16px calc(20px + var(--ph-safe-b));
  max-height: calc(100dvh - var(--ph-safe-t) - 12px);
  overscroll-behavior: contain;
  /* A sheet this size is the working surface, not a pane floating over one: solid paper. The frosted glass of the
     desk dialog went dull grey over a dimmed page here ([MEASURED 2026-10-11] #d4d4d5 behind a form's labels) and a
     full-screen blur is the costliest thing a phone can be asked to paint. */
  background: var(--paper); backdrop-filter: none; -webkit-backdrop-filter: none;
}
html.phone-next.dark .modal { background: var(--paper); }
/* The calendar: a day is a 44px square here (32x30 on a desk), so the month is 308px wide and still one screen. */
html.phone-next .dp-pop { max-width: calc(100vw - 16px); }
html.phone-next :is(.dp-dow, .dp-grid) { grid-template-columns: repeat(7, var(--ph-tap)); }
html.phone-next .dp-day { width: var(--ph-tap); height: var(--ph-tap); }
/* The action row stays at the foot of the sheet, over the home indicator's room. */
html.phone-next .modal > .actions {
  bottom: calc(-20px - var(--ph-safe-b));
  margin: var(--sp-6) -16px calc(-20px - var(--ph-safe-b));
  padding: var(--sp-5) 16px calc(var(--sp-5) + var(--ph-safe-b));
  flex-wrap: wrap;
}
html.phone-next .modal > .actions > :is(button, .btn) { flex: 1 1 auto; min-height: 48px; }
html.phone-next .modal h2 { font-size: var(--fs-lg); margin-right: 40px; }
/* The × every dialog closes with: 28px on a desk. */
html.phone-next .modal > button[aria-label="Close"] { width: var(--ph-tap); height: var(--ph-tap); right: 6px; top: 8px; }

/* Find: the search the menu's "Search…" opens, as a full screen with a way out a thumb can reach. */
html.phone-next [role="dialog"]:has(> [cmdk-root]) {
  inset: 0; width: 100%; max-width: none; height: 100dvh; translate: none; transform: none;
  border: 0; border-radius: 0; display: flex; flex-direction: column;
  padding: var(--ph-safe-t) var(--ph-safe-r) 0 var(--ph-safe-l);
}
html.phone-next [cmdk-root] { flex: 1 1 auto; min-height: 0; border-radius: 0; }
html.phone-next [cmdk-input-wrapper] { padding: 6px 92px 6px 12px; }
/* The field draws its own magnifier (app.css gives every search field one), so the wrapper's second one goes. */
html.phone-next [cmdk-input-wrapper] > svg { display: none; }
html.phone-next [cmdk-input] { height: 48px; padding-top: 0; padding-bottom: 0; }
html.phone-next [cmdk-list] { flex: 1 1 auto; max-height: none; padding-bottom: calc(8px + var(--ph-safe-b)); overscroll-behavior: contain; }
html.phone-next [cmdk-item] { min-height: 48px; font-size: var(--fs-lg); }
html.phone-next [cmdk-group-heading] { font-size: var(--fs-xs); }
html.phone-next .ph-find-close {
  position: absolute; top: calc(var(--ph-safe-t) + 8px); right: calc(var(--ph-safe-r) + 8px); z-index: 2;
  border: 0; background: transparent; color: var(--accent-deep); font-size: var(--fs-lg); font-weight: 600; padding: 0 8px;
}
html.phone-next .ph-find-close:hover { background: transparent; }

/* ---------- §4  A page's own strip and toolbar ---------- */
html.phone-next .page-title { padding: 10px 12px; margin-bottom: 12px; gap: var(--sp-4) var(--sp-5); border-radius: var(--r-lg); }
html.phone-next .page-title > :is(button, .btn) { flex: 1 1 auto; }
html.phone-next .toolbar { gap: var(--sp-4); margin-bottom: 10px; }
/* A chip naming a filter in use stays a chip (32px): its × is a 44px target that reaches past the chip's own edge
   rather than swelling it, and the rows of chips sit far enough apart that two targets never share a pixel. */
html.phone-next .filter-chips { margin: 0 0 10px; gap: 14px var(--sp-4); }
html.phone-next .filter-chip { padding: 0 0 0 12px; min-height: 32px; font-size: var(--fs-body); }
html.phone-next .filter-chip button { width: var(--ph-tap); height: var(--ph-tap); margin: -6px 0; }
html.phone-next .chips-clear-all { padding: 0 8px; }

/* The filters, folded behind one button that says how many are in use (ui/PhoneFilters.jsx). */
html.phone-next .ph-filters-btn { display: inline-flex; align-items: center; gap: var(--sp-3); padding: 0 12px; flex: none; }
html.phone-next .ph-filters-btn svg { width: 18px; height: 18px; }
html.phone-next .ph-filters-btn:hover { background: var(--btn-face); }
html.phone-next .ph-filters-btn:is(.active, [aria-expanded="true"]) { border-color: var(--accent); }
html.phone-next .ph-filters-n {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
  display: grid; place-items: center; background: var(--accent); color: var(--black);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
}
html.phone-next .ph-filters {
  flex: 1 1 100%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-5);
  padding: 12px; background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card);
}
html.phone-next .ph-filter { margin: 0; padding: 0; min-width: 0; }
html.phone-next .ph-filter-l { display: block; margin-bottom: 4px; font-size: var(--fs-xs); font-weight: 500; color: var(--muted); }
html.phone-next .ph-filter select { width: 100%; max-width: none; }
html.phone-next .ph-filter.wide { grid-column: 1 / -1; }
/* Done / Clear all: always at the right — beside the last dropdown when their number is odd, under it when even. */
html.phone-next .ph-filters-foot { grid-column: 2; }
html.phone-next .ph-filters-foot { display: flex; align-items: flex-end; justify-content: flex-end; gap: var(--sp-4); }

/* ---------- §4b  The Dashboard's first screen ----------
   The order is set in pages/Dashboard.jsx (what waits for you · the warnings · today's numbers · who is clocked in).
   Here the warnings give back the height they took: each was a 78px band whose headline wrapped at title size, and
   five of them pushed today's numbers off the first screen ([MEASURED 2026-10-12, 430x932, an admin]). The headline
   keeps its weight and its lamp colour and is set at body size; the band is as tall as its "Review" control. */
html.phone-next .ua-region { gap: var(--sp-3); margin-bottom: 12px; }
html.phone-next .ua-head { padding: 4px 6px 4px 12px; gap: var(--sp-4); }
html.phone-next .ua-headline { font-size: var(--fs-body); line-height: 1.3; gap: var(--sp-4); align-items: center; }
html.phone-next .ua-body { padding: 0 12px 12px; }
html.phone-next .stat-groups { gap: var(--sp-3); margin-bottom: 12px; }
/* A numbers row: its figures are buttons, so each is 44px tall now — the label and figure sit in the middle of that
   (they rode 12px high, top-aligned in the taller box), and the row gives back the padding the taller buttons replaced. */
html.phone-next .sg-chip { justify-content: center; }
html.phone-next .sg-head.sec-head { padding: 4px 12px; }
html.phone-next .dash-title { margin-bottom: 10px; }
/* "Report a bug" in the Needs-review head. §1 grew its box to the 44px floor and left the glyph as a 25px-tall button
   had it: 13px, hard against the left padding — 8.5px left of centre in a box more than three times its size
   ([MEASURED 2026-10-12]; owner the same day: "the icon not centered, stretched, looks arbitrarily optimized").
   A square of the floor's size with the glyph in its middle, at the size the top bar's bug has in the same 44px
   (20px) — one bug, one proportion. On a touch screen a tap leaves "hover" stuck, which opened the words out and
   pushed the glyph aside again; the words stay in the button for screen readers and stay folded here. */
html.phone-next .rv-dash-bug { justify-content: center; width: var(--ph-tap); padding: 0; }
html.phone-next .rv-dash-bug svg { width: 20px; height: 20px; }
html.phone-next .rv-dash-bug:is(:hover, :focus-visible) .rv-dash-bug-label { max-width: 0; opacity: 0; margin-left: 0; }

/* ---------- §5  A list: three lines a record, state first, the whole row its link (ui/PhoneList.jsx) ----------
   The row the owner chose (2026-10-12, "row B (state first)"), for every list:
       line 1   the state chip(s)                    ·  the amount, at the right
       line 2   who or what, then a quieter second name
       line 3   the number, in mono                  ·  the date
   The markup is written in that order, so what is seen, what is read out and what a keyboard reaches agree. */
html.phone-next .ph-list {
  list-style: none; margin: 0 0 14px; padding: 0; overflow: hidden;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card);
}
html.phone-next .ph-list.dt-pending-list { opacity: .55; }
html.phone-next .ph-list-empty { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card); padding: 24px 12px; text-align: center; color: var(--muted); }
html.phone-next .ph-row { display: grid; grid-template-columns: minmax(0, 1fr) var(--ph-tap); border-bottom: 1px solid var(--line-soft); }
html.phone-next .ph-row:last-child { border-bottom: 0; }
html.phone-next .ph-row-main {
  display: flex; flex-direction: column; justify-content: center; gap: 4px; min-width: 0; min-height: 60px;
  padding: 10px 4px 10px 14px; color: var(--ink); text-decoration: none;
}
/* An item's picture at the row's left (ui/PhoneList.jsx — the table's own picture cell). The desk thumbnail's own
   dress: 44px square, the small radius, cropped to the square and never stretched; the diagonal ring when an item
   has no picture. The box has its size before the picture arrives, so a row never moves when one loads. */
html.phone-next .ph-row-main.has-thumb { flex-direction: row; align-items: flex-start; justify-content: flex-start; gap: var(--sp-3); }
html.phone-next .ph-row-lines { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
/* ⛔ ROWS GET NO TALLER FOR HAVING A PICTURE (what the owner was told). A picture to the left of the text takes 52px
   of the title's width, and a title that fitted two lines then needs three ([MEASURED 2026-10-12] Live & Sold: all
   25 rows went from two title lines to three, 106px to 122px). The width is given back from the other side: on a
   row with a picture the arrow keeps its place at the right but is as tall as the first line only, and the title
   and the number line run under it to the row's edge — 344px for the title, where it had 342 before the picture. */
html.phone-next .ph-row:has(> .ph-row-main.has-thumb) > .ph-row-main { grid-column: 1 / -1; grid-row: 1; padding: 10px 4px 10px 6px; }
html.phone-next .ph-row:has(> .ph-row-main.has-thumb) > .ph-row-more { align-self: start; height: var(--ph-tap); z-index: 1; }
html.phone-next .ph-row-main.has-thumb .ph-row-lines > :first-child { padding-right: 40px; }
html.phone-next .ph-row-thumb { flex: none; width: 44px; height: 44px; border-radius: var(--r-sm); overflow: hidden; background: var(--line-soft); }
html.phone-next .ph-row-thumb :is(img, .noimg) { display: block; width: 44px; height: 44px; border-radius: var(--r-sm); }
html.phone-next .ph-row-thumb img { object-fit: cover; }
html.phone-next .ph-row-thumb .noimg {
  box-sizing: border-box; border: 1px solid var(--line);
  background:
    linear-gradient(to top right, transparent calc(50% - 1px), var(--line) calc(50% - 1px), var(--line) calc(50% + 1px), transparent calc(50% + 1px)),
    var(--line-soft);
}
/* A list whose rows open a window, or nothing: the row is a button, undressed to look exactly like the link. */
html.phone-next button.ph-row-main { width: 100%; align-items: stretch; border: 0; border-radius: 0; background: transparent; font: inherit; text-align: left; }
html.phone-next button.ph-row-main:hover { background: transparent; }
html.phone-next .ph-row-main:active { background: var(--accent-wash); }
html.phone-next .ph-row-l1 { display: flex; align-items: center; gap: var(--sp-4); min-width: 0; }
/* (a row with no state: its name leads the first line, the amount at the right of it — ui/PhoneList.jsx) */
html.phone-next .ph-row-l1-name { align-items: baseline; }
html.phone-next .ph-row-l1-name > .ph-row-title { flex: 1 1 auto; }
html.phone-next .ph-row-chips { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 4px var(--sp-3); font-size: var(--fs-sm); color: var(--muted); }
/* A cell that stacks its flags one under another for a narrow table column (eBay Item Review's Flags) sets them
   side by side here, where the line is the full width of the row. */
html.phone-next .ph-row-chips :is(.flag-stack, .stack-badges) { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-3); }
/* Words that are a state but not a chip on the desk either (a call's outcome): plain, cut at the line's end. */
html.phone-next .ph-row-note { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.phone-next .ph-row-amt { flex: none; color: var(--ink); font-size: var(--fs-lg); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.25; }
/* The name keeps its room; the second name beside it takes what is left and is the one that is cut when both do not
   fit (it is in full under the row's arrow, and on the record). */
html.phone-next .ph-row-title { min-width: 0; display: flex; align-items: baseline; gap: var(--sp-3); font-size: var(--fs-lg); line-height: 1.25; }
html.phone-next .ph-row-title b { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
html.phone-next .ph-row-sub { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-body); font-weight: 400; }
/* An item's title is the whole description of the thing ("2019-2021 Toyota RAV4 LED Headlight LH OEM"), and it is
   how two items are told apart: cut at one line it loses the side and the lamp type. So it runs to as many lines
   as it needs, up to three — at body size, where an 80-character eBay title is two lines and the longest on file
   three ([MEASURED 2026-10-12] at the name's 16px, 59 of 100 item titles were cut at two lines; at body size,
   6 of 100 still were). */
html.phone-next .ph-row-title.wrap { display: block; font-size: var(--fs-body); line-height: 1.35; }
html.phone-next .ph-row-title.wrap b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; white-space: normal; overflow-wrap: anywhere; }
html.phone-next .ph-row-title.wrap .ph-row-sub { display: block; }
html.phone-next .ph-row-l3 { display: flex; align-items: center; gap: var(--sp-4); min-width: 0; font-size: var(--fs-sm); color: var(--muted); }
/* (The size is set on each piece, not only on the line: `.mono` carries a size of its own that would win over an
   inherited one.) */
html.phone-next .ph-row-ref { color: var(--ink); font-size: var(--fs-sm); overflow-wrap: anywhere; }
html.phone-next .ph-row-date { font-size: var(--fs-sm); white-space: nowrap; font-variant-numeric: tabular-nums; }
html.phone-next .ph-row-tail { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* (a third line that may wrap — a stock row's four counts, a send's recipient — keeps all of it instead of cutting the end) */
html.phone-next .ph-row-l3.wrap { flex-wrap: wrap; row-gap: 2px; }
html.phone-next .ph-row-l3.wrap .ph-row-tail { white-space: normal; overflow: visible; }
/* Settings → Phone alerts (pages/PhoneAlertsSettings.jsx). A row that cannot be ticked yet takes the room a tick row
   has (its label is the 44px target: 12px above and below), so the list keeps one rhythm; and the device's buttons
   each take the line when two do not fit on one (measured: 303px of buttons in 312px with their gap — they wrapped
   at their own, different widths). */
html.phone-next .pa-alert-coming { padding-block: 12px; margin-bottom: 0; }
html.phone-next .pa-device .tc-actions > button { flex: 1 1 auto; }
/* The folded "What was sent lately" line is a 44px target (§1) with its words left at the top of it — 13.5px above
   the middle ([MEASURED 2026-10-13]). Half of what the floor adds goes above the line, whatever the line's height. */
html.phone-next .pa-recent > summary { box-sizing: border-box; padding-top: calc((var(--ph-tap) - 1lh) / 2); }
/* Settings → Connection by person (pages/ConnTimingSettings.jsx): its table is rows here. A figure well above the
   team keeps the table's own mark — the amber text, bold (the table's `td.ct-high`); "Everyone" keeps its band. */
html.phone-next .ct-mark { color: var(--amber-text); font-weight: 700; }
html.phone-next .ph-row.ct-team-row { background: var(--line-soft); }
/* …on which the row's grey third line measured 4.43:1 ([MEASURED 2026-10-13]); the darker grey kept for text on a
   tinted band. */
html.phone-next .ph-row.ct-team-row .ph-row-tail { color: var(--muted-text); }
/* A scheduled report's second lines ("Top Items · Monday restock list", "Next …", the last run's time) are set at
   0.78rem by a utility class — 11.9px here, a hair under the floor — so they take the smallest step like every other. */
html.phone-next [class~="text-[0.78rem]"] { font-size: var(--fs-xs); }
html.phone-next .ph-row-more {
  grid-column: 2; grid-row: 1; align-self: stretch; display: grid; place-items: center;
  padding: 0; border: 0; border-radius: 0; background: transparent; color: var(--muted);
}
html.phone-next .ph-row-more:hover { background: transparent; }
html.phone-next .ph-row-more svg { width: 18px; height: 18px; transition: transform var(--dur-base) var(--ease); }
html.phone-next .ph-row.open .ph-row-more svg { transform: rotate(180deg); }
html.phone-next .ph-row.open .ph-row-more { color: var(--accent-deep); }
/* The arrow's "all details": every column of the table, under its own name. */
/* (Its label and value are set exactly as a line of the old card tables is — the same thing, a column's name and
   its value: label at the smallest step, weight 600, muted; value at body size.) */
html.phone-next .ph-row-all { grid-column: 1 / -1; padding: 0 14px; border-top: 1px solid var(--line-soft); background: var(--bg); }
html.phone-next .ph-row-all dl { margin: 0; }
html.phone-next .ph-row-kv { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6); min-height: var(--ph-tap); border-bottom: 1px solid var(--line-soft); }
html.phone-next dl > .ph-row-kv:last-child { border-bottom: 0; }
html.phone-next .ph-row-kv dt { flex: none; color: var(--muted); font-size: var(--fs-micro); font-weight: 600; }
html.phone-next .ph-row-kv dd { margin: 0; min-width: 0; text-align: right; font-size: var(--fs-body); overflow-wrap: anywhere; }
html.phone-next .ph-row-kv dd a { display: inline-block; padding: 13px 0 13px 16px; min-width: var(--ph-tap); }
html.phone-next .ph-row-kv dd .stack-badges { align-items: flex-end; }
html.phone-next .ph-row-kv dd select { max-width: 100%; }
/* A column with no name that is not marked as the row's buttons but carries one all the same (Pull from Pinnacle's
   "Pulled from Pinnacle"): on a line of its own, at the left edge with the row's other controls. (The picture
   column is not one of these any more — an item's picture is at the left of its row.) */
html.phone-next .ph-row-kv.bare { justify-content: flex-start; padding: 10px 0; }
html.phone-next .ph-row-kv.bare dd { text-align: left; }
/* A column with no name that carries the row's buttons: the same buttons, side by side, at the foot. */
html.phone-next .ph-row-acts { padding: 10px 0; border-top: 1px solid var(--line-soft); }
html.phone-next .ph-row-acts, html.phone-next .ph-row-acts > span { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); }
html.phone-next .ph-row-acts button { margin-block: 3px; }
/* Ticking rows (the lists that have the table's tick boxes): "Select row" opens the unfolded details, a ticked row
   carries the accent down its edge, and "Select all rows" stands above the list once one is ticked. */
html.phone-next .ph-row-pick { font-size: var(--fs-body); font-weight: 500; }
html.phone-next .ph-row:is(.ph-picked, .row-pinned) { box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-wash); }
html.phone-next .ph-list-selall { display: flex; align-items: center; gap: var(--sp-4); padding-inline: 14px; margin-bottom: 6px; font-size: var(--fs-body); font-weight: 500; }
/* A list inside a panel (a customer's orders, an order's items) sits flush in it, and a table's foot row (an
   order's Total) is the line under the list: its word at the left, its figure where the rows' amounts are. */
html.phone-next .panel > .ph-list:last-child { margin-bottom: 0; }
html.phone-next .ph-list-total { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-5); padding: 4px 49px 0 15px; font-size: var(--fs-lg); font-weight: 600; }
/* Where a page's "go to …" button lands: clear of the top bar. */
html.phone-next .ph-anchor { height: 0; scroll-margin-top: calc(var(--ph-top) + var(--ph-safe-t) + 8px); }

/* ---------- §6  A detail page: facts first, its actions in a bar that stays in reach (ui/PhoneActions.jsx) ---------- */
/* It floats like the tabs under it: a rounded slab inside the page's 12px margin, 8px above the bar. */
html.phone-next .ph-actionbar-slot { position: sticky; z-index: 30; bottom: calc(var(--ph-bottom) + var(--ph-safe-b)); margin: 12px 0 0; }
html.phone-next .ph-actionbar-slot:empty { display: none; }
html.phone-next .view-inner:has(.ph-actionbar) { padding-bottom: 0; }
html.phone-next .ph-actionbar {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 6px; border-radius: 30px;
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line), 0 10px 30px rgba(10, 10, 11, .18), 0 1px 3px rgba(10, 10, 11, .14);
}
html.phone-next .ph-actionbar > :is(button, .btn) { min-height: 48px; flex: none; border-radius: var(--r-pill); }
html.phone-next .ph-actionbar > .primary { flex: 1 1 auto; font-size: var(--fs-lg); }
html.phone-next .ph-actionbar > :last-child:not(.primary) { flex: 1 1 auto; }
/* The same block of actions the title strip holds on a desk, laid out as a list in the "Actions" sheet. The strip's
   own rules are scoped to the strip (dark chrome), so here the buttons are the paper's ordinary buttons. */
html.phone-next .ph-actions-sheet .pt-actions { display: flex; flex-direction: column; }
html.phone-next .ph-actions-sheet .pt-group { display: flex; flex-direction: column; gap: var(--sp-3); padding: 12px 0; border-top: 1px solid var(--line-soft); }
html.phone-next .ph-actions-sheet .pt-group:first-child { border-top: 0; padding-top: 0; }
html.phone-next .ph-actions-sheet .pt-group:last-child { padding-bottom: 0; }
html.phone-next .ph-actions-sheet .pt-group-controls { display: flex; flex-direction: column; gap: var(--sp-4); }
html.phone-next .ph-actions-sheet .pt-group-controls > :is(button, .btn) { width: 100%; min-height: 48px; justify-content: flex-start; text-align: left; font-size: var(--fs-lg); text-decoration: none; }
html.phone-next .ph-actions-sheet .pt-status { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--muted); }
html.phone-next .ph-actions-sheet .pt-status .ic { width: 14px; height: 14px; }
/* A page whose strip is a plain run of buttons (an item): the same run, one under another. */
html.phone-next .ph-actions-sheet { display: flex; flex-direction: column; gap: var(--sp-4); }
html.phone-next .ph-actions-sheet > :is(button, .btn) { width: 100%; min-height: 48px; justify-content: flex-start; text-align: left; font-size: var(--fs-lg); }

/* ---------- §8  Screens that keep their own structure ----------
   Not every screen is a list of records. These keep the markup they have — a voicemail is a card with a player, a
   fitment row is a small form, a state's shipping rates are six fields — and get only what a phone needs. */
/* Voicemail: the caller's name is a link set in a line of text — 20px tall, 66 of them on the page ([MEASURED
   2026-10-12]). The same 44px box, with the difference given back so the card's lines do not move. */
html.phone-next .vm-from a { display: inline-block; padding-block: 12px; margin-block: -12px; min-width: var(--ph-tap); }
/* The fitment worklist: each row is a decision — a model name, why it needs a person, eBay's candidates to tick, a
   note, and the button. As a card table it set every one of those in the right-hand 58% of the card beside its
   column's name, which broke "TESLA MODEL 3" into four lines and the reason into twelve ([SEEN 2026-10-12]). Here
   the three wide parts (the model, the reason, eBay's candidates) take the card's full width under their column's
   name; the count and the note keep their one line ([MEASURED] stacking all six made the page 136.8 screens from
   130.1). Nothing is re-ordered. */
html.phone-next .fit-table td:not(.num):not(:has(.fit-note)) { display: block; text-align: left; padding: 8px 0; }
html.phone-next .fit-table td:not(.num):not(:has(.fit-note))::before { display: block; margin-bottom: 2px; }
/* (the desk table's column divider would be a stray line down the card's right edge, against the reason's text;
   and every part starts at the card's own left edge — the one-line parts were 12px in from the stacked ones) */
html.phone-next .fit-table td { border-right: 0; padding-left: 0; padding-right: 0; }
html.phone-next .fit-table td.fit-actions { white-space: normal; }
html.phone-next .fit-table td.fit-actions button + button { margin-left: var(--sp-4); }
html.phone-next .fit-table td:has(.fit-note) { align-items: center; }
html.phone-next .fit-table td .fit-note { flex: 1 1 auto; min-width: 0; width: auto; }
html.phone-next .fit-pair { text-align: left; }
/* A group under "Everything else holding fitment back", once opened, was a 420px window of cards that scrolled
   inside the page ([MEASURED 2026-10-12] with every group open the page's own end left 84,067px of cards below it,
   inside those windows). On a phone the cards flow in the page, as every other card table's do. */
html.phone-next .fit-block-group .table-wrap { max-height: none; overflow: visible; }
/* Shipping rates: a state's six rates were six full-width lines (a figure and its ✕ at the far right of each); two
   to a line, each under its item type's name, a state is half as tall. Same fields, same order. */
html.phone-next .rtable tbody tr:has(> td.ship-col) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--sp-6); }
html.phone-next .rtable tr:has(> td.ship-col) > td:first-child { grid-column: 1 / -1; }
html.phone-next .rtable td.ship-col { display: block; text-align: left; padding: 6px 0 8px; border-bottom: 0; border-right: 0; }
html.phone-next .rtable td.ship-col::before { display: block; margin-bottom: 2px; }
/* A document's inline code (a version number in the credit terms) follows the text around it — 0.86 of it, which
   is 11.8px here. The floor is the smallest step. */
html.phone-next .doc-body code { font-size: max(.86em, var(--fs-xs)); }
/* A report's figure tiles, two to a line: the columns were sized by what was in them, so "Units sold" took 490px
   and "Revenue" was left 240px, where "$62,493.20" ran under its own change figure and off the tile ([SEEN
   2026-10-12]). Equal halves, and the change figure drops under the number when the two do not fit side by side. */
html.phone-next .lost-stats, html.phone-next .lost-stats.cols-5 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
html.phone-next .lost-stats .stat { min-width: 0; }
html.phone-next .stat .n-row { flex-wrap: wrap; row-gap: 2px; }
/* A link inside a line of explanation ("…on the Users page") is a line of text tall — 18px. The same 44px box as
   a link in a table's line, with the difference given back so the paragraph does not move. */
html.phone-next main p.hint a:not(.btn) { display: inline-block; padding-block: 13px; margin-block: -13px; }
/* A customer's credit panel: its heading shares a line with a state chip and up to three buttons, and on a phone
   the words "Credit account" broke in two beside them ([SEEN 2026-10-12]). The buttons take the line under the
   heading, at the left; the heading and its chip keep theirs. */
html.phone-next .credit-acct > h2 { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); }
html.phone-next .credit-acct > h2 .credit-acct-actions { flex: 1 1 100%; }

}
