/* =============================================================================
   Storefront components.  Every value below comes from a token in tokens.css.
   A literal length or color in this file is a bug: it is a value a tenant can
   never reach.  (Shadows and a handful of alpha overlays are the exception and
   are noted where they occur.)
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--body);
  font-family: var(--font-text);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
input, select { font: inherit; color: inherit; }
:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.hide { display: none !important; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.lbl {
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  letter-spacing: .09em; text-transform: uppercase; color: var(--muted);
}
.muted { color: var(--muted); }
.ink { color: var(--ink); }

/* ---------------------------------------------------------- app header ---- */
.hdr {
  display: flex; align-items: center; justify-content: space-between;
  height: calc(var(--control-h-lg) + var(--space-3));
  padding-inline: var(--space-6);
  background: var(--brand); color: var(--on-brand);
}
.hdr-l { display: flex; align-items: center; gap: var(--space-7); min-width: 0; }
.brandmark {
  font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-md); letter-spacing: -.01em; white-space: nowrap;
}
.nav { display: flex; gap: var(--space-5); font-size: var(--text-sm); }
.nav button { opacity: .88; padding-block: var(--space-1); border-bottom: var(--border-emph) solid transparent; }
.nav button[aria-current="true"] { opacity: 1; font-weight: var(--weight-bold); border-bottom-color: var(--on-brand); }
.hdr-r { display: flex; align-items: center; gap: var(--space-4); font-size: var(--text-sm); }
.who { opacity: .9; }
.cartbtn {
  display: flex; align-items: center; gap: var(--space-2);
  background: rgba(255,255,255,.16);          /* overlay on brand, not a token */
  padding: var(--space-1) var(--space-3); border-radius: var(--radius-sm);
  font-weight: var(--weight-medium);
}

/* tenant switch — prototype chrome, not part of the product */
.tswitch { display: flex; align-items: center; gap: var(--space-2); }
.tswitch select {
  height: var(--chip-h); border: 0; border-radius: var(--radius-sm);
  background: rgba(255,255,255,.18); color: var(--on-brand);
  padding-inline: var(--space-2); font-size: var(--text-xs);
}

/* ------------------------------------------------------------- shell ------ */
.bar {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-3) var(--space-6);
  background: var(--surface); border-bottom: var(--border-hair) solid var(--rule);
}
.bar h1 { font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--ink); margin: 0; }
.shell { max-width: var(--shell-max); margin: 0 auto; padding: var(--space-6); }
/* The rail spans both rows so the count can sit above the price panel without
   leaving the filters. Named areas because the order has to change on narrow
   screens and source order should not have to. */
.shop {
  display: grid;
  grid-template-columns: var(--filter-rail) minmax(0,1fr);
  gap: var(--space-6);
  align-items: start;
}

/* THE WHOLE RESULT SET FOLLOWS YOU.
   The filter rail is far taller than the results, so without this the answer
   scrolls away exactly while you work the controls that change it. Making only
   the count sticky was worse than nothing: it became a lid, and the price, the
   tier ladder and the buttons slid underneath it.
   The column scrolls internally when it outgrows the viewport, so nothing at
   the bottom of it becomes unreachable. */
.results {
  position: -webkit-sticky;
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: calc(100vh - var(--space-7));
  max-height: calc(100dvh - var(--space-7));
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* room for the scrollbar so a focus ring is never clipped against the edge */
  padding-right: 2px;
}

/* Inside that travelling column the count is the panel's header and pins to its
   top, so the one number the filters are changing is never the thing that
   scrolls away. The flat shadow paints the flex gap in page colour, so nothing
   shows through the strip beneath it as content passes under. */
.results > .count {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
  box-shadow: 0 var(--space-4) 0 var(--bg), var(--shadow-sm);
}
.card { background: var(--surface); border: var(--border-hair) solid var(--rule); border-radius: var(--radius-lg); }
.stack { display: flex; flex-direction: column; gap: var(--space-4); }

/* -------------------------------------------------------- filter rail ----- */
.rail { overflow: hidden; }
.rail-top { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); }
.grp { border-top: var(--border-hair) solid var(--rule); padding: var(--space-5); }
.grp.sunk { background: var(--sunk); }
.grp-h { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-3); gap: var(--space-2); }
.hint { margin-top: var(--space-2); font-size: var(--text-xs); color: var(--muted); line-height: var(--leading-snug); }

.link { color: var(--brand); font-weight: var(--weight-medium); font-size: var(--text-sm); }
.link:hover { color: var(--brand-hover); text-decoration: underline; }

/* bucket selector — rendered from config, never a range slider */
.buckets { display: flex; flex-direction: column; gap: var(--space-2); }
.bucket {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  width: 100%; text-align: left;
  padding: var(--space-2) var(--space-3);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-md);
  background: var(--surface); transition: border-color var(--dur-fast) var(--ease);
}
.bucket:hover { border-color: var(--muted); }
.bucket .dot {
  width: 15px; height: 15px; border-radius: var(--radius-pill);
  border: 1.5px solid var(--rule-strong); flex-shrink: 0;
}
.bucket-l { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--ink); }
.bucket .px { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--muted); }
.bucket[aria-pressed="true"] { border: var(--border-emph) solid var(--count); background: var(--count-soft); }
.bucket[aria-pressed="true"] .bucket-l { font-weight: var(--weight-bold); }
.bucket[aria-pressed="true"] .dot { border: 4.5px solid var(--count); background: var(--surface); }
.bucket[aria-pressed="true"] .px { color: var(--count); font-weight: var(--weight-bold); }

/* the targeting basket */
.basket {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-content: flex-start;
  padding: var(--space-3); min-height: 96px;
  background: var(--surface); border: var(--border-hair) solid var(--rule-strong);
  border-radius: var(--radius-md);
}
.basket.empty { align-items: center; justify-content: center; }
.chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: var(--chip-h); padding-inline: var(--space-2);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink);
  white-space: nowrap; max-width: 100%;
}
.chip.geo { border-color: var(--count); background: var(--count-soft); }
.chip.neg { border-color: var(--warn); color: var(--warn); }
.chip .x { color: var(--muted); font-size: var(--text-sm); line-height: 1; padding-inline: 2px; }
.chip .x:hover { color: var(--danger); }
.builders { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.btn-ghost {
  height: var(--control-h); padding-inline: var(--space-3);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-sm);
  background: var(--surface); font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--body); display: inline-flex; align-items: center; gap: var(--space-2);
}
.btn-ghost:hover { border-color: var(--muted); color: var(--ink); }

/* segmented control */
.seg { display: flex; border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-md); overflow: hidden; }
.seg button {
  flex: 1; padding: var(--space-2); text-align: center; font-size: var(--text-sm);
  background: var(--surface); border-right: var(--border-hair) solid var(--rule);
}
.seg button:last-child { border-right: 0; }
.seg button[aria-pressed="true"] { background: var(--count-soft); color: var(--count); font-weight: var(--weight-bold); }

/* attribute registry controls */
.attr { margin-bottom: var(--space-4); }
.attr:last-child { margin-bottom: 0; }
.attr-l { font-size: var(--text-sm); color: var(--body); margin-bottom: var(--space-2); }
.attr-row { display: flex; align-items: center; gap: var(--space-3); }
.attr-row input[type="range"] { flex: 1; accent-color: var(--brand); }
.pills { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.pill {
  height: var(--chip-h); padding-inline: var(--space-2);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-sm);
  background: var(--surface); font-size: var(--text-sm); color: var(--ink);
}
.pill[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); font-weight: var(--weight-bold); }
.sel {
  width: 100%; height: var(--control-h); padding-inline: var(--space-3);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-size: var(--text-sm);
}
.twin { display: flex; gap: var(--space-2); }
.twin > div { flex: 1; min-width: 0; }
.acbox {
  display: flex; flex-wrap: wrap; gap: var(--space-1); min-height: var(--control-h);
  padding: var(--space-1); border: var(--border-hair) solid var(--rule-strong);
  border-radius: var(--radius-sm); background: var(--surface);
}
.acbox input { width: 100%; border: 0; outline: 0; background: none; font-size: var(--text-sm); padding: var(--space-1); }

/* ------------------------------------------------------- count readout ---- */
.count { padding: var(--space-6) var(--space-7); }
.count-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-6); flex-wrap: wrap; }
.bignum {
  display: flex; align-items: baseline; gap: var(--space-3);
}
.bignum b {
  font-family: var(--font-display); font-size: var(--text-count); font-weight: var(--weight-bold);
  line-height: 1; letter-spacing: -.03em; color: var(--count);
  font-variant-numeric: tabular-nums;
  transition: opacity var(--swap-count) var(--ease), color var(--swap-count) var(--ease);
}
/* RECOMPUTING — the previous figure stays legible. Never a blank, never a spinner. */
.count[data-state="working"] .bignum b { opacity: .38; }
/* STALE — it stops implying it is current rather than lying about freshness. */
.count[data-state="stale"] { border-color: var(--warn); }
.count[data-state="stale"] .bignum b { color: var(--muted); }
.supp { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4); font-size: var(--text-sm); }
.freshness { text-align: right; flex-shrink: 0; }
.badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  background: var(--ok-soft); color: var(--ok);
}
.badge .led { width: 6px; height: 6px; border-radius: var(--radius-pill); background: currentColor; }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.work { background: var(--sunk); color: var(--muted); }
.stamp { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-2); }
.zero-help { margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink); }

/* ------------------------------------------------------------ price ------- */
.pricegrid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--space-7); padding: var(--space-6) var(--space-7); }
.qty { display: flex; align-items: center; border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-md); overflow: hidden; max-width: 220px; }
.qty button { width: 42px; height: var(--control-h-lg); display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: var(--text-md); }
.qty button:hover { background: var(--sunk); color: var(--ink); }
.qty input {
  flex: 1; min-width: 0; text-align: center; border: 0; outline: 0; background: none;
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--ink); font-variant-numeric: tabular-nums;
  border-inline: var(--border-hair) solid var(--rule);
  height: var(--control-h-lg);
}
.bigprice { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--ink); font-variant-numeric: tabular-nums; }

/* the next-rung nudge */
.nudge {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-4) var(--space-7);
  background: var(--count-soft); border-top: var(--border-hair) solid var(--rule);
}
/* flex:1 keeps the button on the same row as the sentence instead of letting
   the paragraph claim the full width and push it to a line of its own */
.nudge p { flex: 1; min-width: 22ch; margin: 0; font-size: var(--text-base); color: var(--ink); line-height: var(--leading-snug); }
.btn-count {
  height: var(--control-h); padding-inline: var(--space-4); margin-left: auto;
  border: 1.5px solid var(--count); border-radius: var(--radius-sm);
  color: var(--count); font-weight: var(--weight-bold); font-size: var(--text-sm);
  display: inline-flex; align-items: center; white-space: nowrap;
}
.btn-count:hover { background: var(--count); color: var(--surface); }

/* volume ladder */
.ladder { padding: var(--space-5) var(--space-7) var(--space-6); border-top: var(--border-hair) solid var(--rule); }
/* The ladder is a control, not a diagram: each rung sets the quantity to that
   tier's entry point. Labels reserve two lines so a wrapped range like
   "10k-24,999" never pushes its own price out of line with its neighbours. */
.rungs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--border-hair);
  background: var(--rule);
  border: var(--border-hair) solid var(--rule);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.rung {
  display: flex; flex-direction: column; justify-content: flex-start; align-items: center;
  gap: 2px;
  background: var(--surface); border: 0;
  padding: var(--space-2) var(--space-1);
  min-height: var(--tap-min);
  text-align: center; cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.rung:hover { background: var(--sunk); }
.rung:active { background: var(--count-soft); }
/* A tier the current inventory cannot fill is still tappable; it is dimmed and
   it says what it would need, rather than being an inert control that reads as
   a broken one. */
.rung.short .r-l, .rung.short .r-p { opacity: .5; }
.rung .r-x {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em;
  color: var(--warn); margin-top: 1px;
}
.rung .r-l {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted);
  line-height: 1.25; min-height: 2.5em;          /* two lines, always */
  display: flex; align-items: center; justify-content: center;
}
.rung .r-p {
  font-family: var(--font-display); font-size: var(--text-base);
  font-weight: var(--weight-bold); color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.rung.now { background: var(--count-soft); }
.rung.now .r-l, .rung.now .r-p { color: var(--count); }
.rung.next { box-shadow: inset 0 0 0 1.5px var(--count); }

/* ------------------------------------------------------------ buttons ----- */
.btn {
  height: var(--control-h-lg); padding-inline: var(--space-7);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand); color: var(--on-brand); border-radius: var(--radius-md);
  font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-base);
}
.btn:hover { background: var(--brand-hover); }
.btn[disabled] { background: var(--sunk); color: var(--muted); cursor: not-allowed; }
.btn-2 {
  height: var(--control-h-lg); padding-inline: var(--space-5);
  display: inline-flex; align-items: center; justify-content: center;
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-md);
  background: var(--surface); font-weight: var(--weight-medium); font-size: var(--text-sm); color: var(--body);
}
.btn-2:hover { border-color: var(--muted); color: var(--ink); }
.cta-row { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }

/* ------------------------------------------------------------ notices ----- */
.note { display: flex; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-radius: var(--radius-sm); font-size: var(--text-sm); line-height: var(--leading-snug); }
.note svg { flex-shrink: 0; margin-top: 2px; }
.note.warn { background: var(--warn-soft); border-left: var(--border-accent) solid var(--warn); color: var(--ink); }
.note.ok { background: var(--ok-soft); color: var(--ink); align-items: center; }
.note.bad { background: var(--danger-soft); border-left: var(--border-accent) solid var(--danger); color: var(--ink); align-items: center; }

/* ------------------------------------------------------------- modal ------ */
.scrim {
  position: fixed; inset: 0; background: rgba(10,12,16,.44);  /* scrim, not a token */
  display: flex; align-items: center; justify-content: center; padding: var(--space-4);
  z-index: var(--z-modal);
}
.modal { background: var(--surface); border-radius: var(--radius-lg); width: 100%; max-width: 520px; max-height: 86vh; display: flex; flex-direction: column; box-shadow: var(--shadow-md); }
.modal-h { display: flex; align-items: center; justify-content: space-between; padding: var(--space-5); border-bottom: var(--border-hair) solid var(--rule); }
.modal-h h3 { margin: 0; font-family: var(--font-display); font-size: var(--text-md); font-weight: var(--weight-bold); color: var(--ink); }
.modal-b { padding: var(--space-5); overflow-y: auto; }
.modal-f { display: flex; gap: var(--space-3); justify-content: flex-end; padding: var(--space-5); border-top: var(--border-hair) solid var(--rule); }
.field { margin-bottom: var(--space-4); }
.field:last-child { margin-bottom: 0; }
.field label { display: block; font-size: var(--text-sm); color: var(--body); margin-bottom: var(--space-2); }
.field input, .field textarea, .field select {
  width: 100%; padding: var(--space-2) var(--space-3);
  border: var(--border-hair) solid var(--rule-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-size: var(--text-base);
}
.field textarea { min-height: 96px; resize: vertical; font-family: var(--font-mono); font-size: var(--text-sm); }
.picker { display: flex; flex-direction: column; gap: var(--space-1); max-height: 300px; overflow-y: auto; }
.picker button { display: flex; justify-content: space-between; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); font-size: var(--text-sm); text-align: left; }
.picker button:hover { background: var(--sunk); }
.picker button[aria-pressed="true"] { background: var(--count-soft); color: var(--count); font-weight: var(--weight-bold); }

/* -------------------------------------------------------------- cart ------ */
.line { padding: var(--space-5); border-bottom: var(--border-hair) solid var(--rule); }
.line:last-of-type { border-bottom: 0; }
.line-h { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); }
.line-h b { font-family: var(--font-display); font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--ink); }
.line-p { font-family: var(--font-display); font-size: var(--text-md); font-weight: var(--weight-bold); color: var(--ink); font-variant-numeric: tabular-nums; }
.line-d { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); line-height: var(--leading-normal); }
.line-a { display: flex; gap: var(--space-4); margin-top: var(--space-2); }
.totals { display: flex; align-items: baseline; justify-content: space-between; padding: var(--space-5); border-top: var(--border-emph) solid var(--rule-strong); }
.totals .t-n { font-family: var(--font-display); font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--ink); font-variant-numeric: tabular-nums; }
.two-col { display: grid; grid-template-columns: minmax(0,1.3fr) minmax(0,1fr); gap: var(--space-6); align-items: start; }
.uselist { display: flex; flex-direction: column; gap: var(--space-2); font-size: var(--text-sm); line-height: var(--leading-snug); color: var(--ink); }
.uselist div { display: flex; gap: var(--space-2); }
.yes { color: var(--ok); font-weight: var(--weight-bold); }
.no { color: var(--danger); font-weight: var(--weight-bold); }
.checkrow { display: flex; gap: var(--space-2); align-items: flex-start; margin-top: var(--space-4); padding-top: var(--space-4); border-top: var(--border-hair) solid var(--rule); font-size: var(--text-sm); line-height: var(--leading-snug); }
.checkrow input { margin-top: 3px; accent-color: var(--brand); width: 16px; height: 16px; flex-shrink: 0; }

/* ------------------------------------------------------------ orders ------ */
.ord { padding: var(--space-5); border-bottom: var(--border-hair) solid var(--rule); }
.ord:last-child { border-bottom: 0; }
.ord-h { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); flex-wrap: wrap; }
.tag { display: inline-flex; padding: 3px var(--space-2); border-radius: var(--radius-pill); font-size: 10.5px; font-weight: var(--weight-bold); letter-spacing: .04em; background: var(--ok-soft); color: var(--ok); }
.ord-actions { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.ord-actions .btn-2 { flex: 1; height: var(--control-h); }

/* Hidden by default; the narrow-screen block at the end of this file turns it
   on. Declared HERE, above that block, so the media query wins the cascade. */
.dock { display: none; }

/* ------------------------------------------------------------ footer ------ */
.proto-note {
  max-width: var(--shell-max); margin: 0 auto;
  padding: var(--space-5) var(--space-6) var(--space-9);
  font-size: var(--text-xs); color: var(--muted); line-height: var(--leading-normal);
}
.proto-note b { color: var(--body); }
.devbar {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  padding: var(--space-3) var(--space-6);
  background: var(--sunk); border-bottom: var(--border-hair) solid var(--rule);
  font-size: var(--text-xs); color: var(--muted);
}
.devbar label { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; }

/* ------------------------------------------------------ platform line ----- */
.platform {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  align-items: baseline; justify-content: space-between;
  max-width: var(--shell-max); margin: 0 auto;
  padding: var(--space-5) var(--space-6) calc(var(--space-8) + env(safe-area-inset-bottom, 0px));
  border-top: var(--border-hair) solid var(--rule);
  font-size: var(--text-xs); color: var(--muted);
}
.platform .pb b { color: var(--body); font-weight: var(--weight-bold); }

/* ---------------------------------------------------------- brand mark ---- */
/* A supplied logo ships as supplied. No filter, no opacity, no recolor, no crop.
   The one thing set here is height, so it sits on the same baseline as a
   wordmark tenant's text. */
.brandlogo { display: block; width: auto; max-width: 240px; }

/* ------------------------------------------------------------ csv view ---- */
.csvout {
  margin: 0; padding: var(--space-3);
  background: var(--sunk); border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--text-xs); line-height: 1.6;
  color: var(--ink); white-space: pre; overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* =============================================================== iOS ======
   Most mobile traffic here is Safari on iOS, which differs from Chrome in ways
   that are invisible until someone opens it on a phone. Each rule below fixes
   a specific one.
   ========================================================================== */

/* Safari inflates text in landscape unless told not to. */
html { -webkit-text-size-adjust: 100%; }

/* Kill the grey flash on tap, keep a real focus ring for keyboards. */
button, a, label, summary, [role="button"] {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;          /* also removes the 300ms click delay */
}

/* Safari styles form controls its own way; normalise then restate our own. */
input, select, textarea {
  -webkit-appearance: none;
  appearance: none;
  border-radius: var(--radius-sm);
  background-color: var(--surface);
}
/* Removing the appearance removes the select chevron, so draw one back. */
select.sel, .field select {
  padding-right: var(--space-7);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7484' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}

/* iOS zooms the whole page when a field under 16px takes focus. The only fix is
   to never ship a focusable field under 16px on a phone. The class selectors
   are listed explicitly because a bare element selector loses the cascade to
   the component rules that set these sizes in the first place. */
@media (max-width: 820px) {
  input, select, textarea,
  .sel, .field input, .field select, .field textarea,
  .qty input, .acbox input, .tswitch select {
    font-size: 16px;
  }
}

/* Range input has no default look once appearance is off. */
input[type="range"] { width: 100%; height: 24px; background: transparent; }
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 2px; background: var(--rule);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; margin-top: -9px;
  border-radius: var(--radius-pill);
  background: var(--surface); border: 2px solid var(--brand);
}
input[type="range"]::-moz-range-track { height: 4px; border-radius: 2px; background: var(--rule); }
input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: var(--radius-pill);
  background: var(--surface); border: 2px solid var(--brand);
}

/* On a finger, a 24px control is a miss. Every interactive thing gets a real
   target on touch, whatever the tenant's density setting says. */
@media (pointer: coarse) {
  .chip { height: auto; min-height: 32px; padding-block: var(--space-1); }
  .chip .x { min-width: 28px; min-height: 28px; display: inline-flex;
             align-items: center; justify-content: center; margin-right: -4px; }
  .link { padding-block: var(--space-2); display: inline-block; }

  .pill, .btn-ghost, .seg button, .sel, .acbox input,
  .tswitch select, .picker button, .rung, .cartbtn, .nav button {
    min-height: var(--tap-min);
  }
  .pill, .btn-ghost { padding-block: var(--space-2); }
  .acbox { min-height: var(--tap-min); align-items: center; }
  /* the checkbox stays small; its label is the target, so give the label one */
  .checkrow { min-height: var(--tap-min); align-items: center; }
  .checkrow input { width: 22px; height: 22px; }
  /* a range you have to hit within 24px is a range nobody drags accurately */
  input[type="range"] { height: var(--tap-min); }
}

/* Modal: dvh keeps it off the URL bar's changing height, the inset keeps the
   footer buttons above the home indicator, and contained overscroll stops the
   page behind it from rubber-banding. */
.modal { max-height: 86vh; max-height: 86dvh; }
.modal-b { -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.scrim {
  padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  padding-top: calc(var(--space-4) + env(safe-area-inset-top, 0px));
}

/* Long unbroken values (emails, pasted ZIP runs) must wrap rather than widen
   the page; iOS is less forgiving about this than Chrome. */
.line-d, .hint, .stamp { overflow-wrap: anywhere; }

/* ========================================================== responsive ==== */
@media (max-width: 1100px) {
  /* One column. A sticky results column would swallow a phone screen, so the
     answer travels in a thin docked bar instead and the full panel sits in
     normal flow above the filters. */
  .shop { grid-template-columns: minmax(0,1fr); }
  .results {
    position: static; max-height: none; overflow: visible; padding-right: 0;
    order: -1;
  }
  /* With the column static, the count's sticky would resolve against the page
     and turn it back into a lid over the price card. The docked bar carries the
     answer on a phone, so the count simply scrolls. */
  .results > .count { position: static; box-shadow: none; }
  .two-col { grid-template-columns: minmax(0,1fr); }
  .dock { display: block; }
  /* clear the docked bar so it never covers the last of the filters */
  body { padding-bottom: 84px; }
}

/* ------------------------------------------------------- docked answer ---- */
.dock-in {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky);
  background: var(--surface);
  border-top: var(--border-emph) solid var(--rule-strong);
  box-shadow: 0 -6px 20px -12px rgba(0,0,0,.35);
  padding: var(--space-3) var(--space-4);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: var(--space-4);
}
.dock-n { min-width: 0; }
.dock-n .k { font-size: 10.5px; font-weight: var(--weight-bold); letter-spacing: .09em;
             text-transform: uppercase; color: var(--muted); display: block; }
.dock-n .v { font-family: var(--font-display); font-size: 1.35rem; font-weight: var(--weight-bold);
             line-height: 1.1; color: var(--count); font-variant-numeric: tabular-nums; }
.dock-n .v.px { color: var(--ink); }
.dock .btn { margin-left: auto; flex-shrink: 0; height: var(--control-h); padding-inline: var(--space-5); }
@media (max-width: 640px) {
  .shell { padding: var(--space-4); }
  .hdr { height: auto; padding-block: var(--space-3); flex-wrap: wrap; gap: var(--space-3); }
  .hdr-l { gap: var(--space-4); width: 100%; }
  .nav { gap: var(--space-4); font-size: var(--text-xs); }
  .who { display: none; }
  .count { padding: var(--space-5); }
  .bignum b { font-size: var(--text-xl); }
  /* once the freshness block wraps under the number it is no longer a right
     rail, so stop right-aligning it into the middle of nowhere */
  .count-top { gap: var(--space-3); }
  .freshness { text-align: left; display: flex; align-items: center; gap: var(--space-3); }
  .stamp { margin-top: 0; }
  /* the prototype bar is scaffolding, not product - keep it to one line */
  .devbar > :nth-child(3) { display: none; }
  .pricegrid { grid-template-columns: minmax(0,1fr); gap: var(--space-5); padding: var(--space-5); }
  .nudge, .ladder { padding-inline: var(--space-5); }
  .btn-count { margin-left: 0; }
  /* six rungs across a phone gives each about 55px and the labels shatter;
     two rows of three keeps every range on one or two comfortable lines */
  .rungs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rung { padding-block: var(--space-3); }
  .qty { max-width: none; }
  .cta-row .btn, .cta-row .btn-2 { flex: 1; }
}
