/* VA order calculator — phone first.
   Plain CSS, no framework and no build step, matching the other VA portals. */

:root {
  --brand: #c8102e;
  --brand-dark: #a30d26;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --bg: #f1f5f9;
  --card: #fff;
  --ok-bg: #d1fae5; --ok-fg: #065f46;
  --warn-bg: #fef3c7; --warn-fg: #78350f;
  --bad-bg: #ffe4e6; --bad-fg: #9f1239;
  /* Navbar height on tablet and up, where it collapses to a single fixed-height row. The
     desktop quote rail offsets its `top` by exactly this, so the two must move together. */
  --nav-h: 3.5rem;
}

* { box-sizing: border-box; }

/* The browser's default is `[hidden] { display: none }`, which any explicit `display` rule
   silently overrides. Every panel below sets one (.prompt and .sheet are flex, .modal is
   flex), so without this they stay on screen no matter what the JS sets `hidden` to — the
   customer prompt showed with a customer selected, and both sheets sat in the flow. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

/* iOS zooms the page when a focused input is under 16px. Search is the most-used control
   in the app, so this is functional, not cosmetic. */
input, button, select { font-size: 16px; font-family: inherit; }

h1 { font-size: 1.5rem; margin: 0.75rem 0 0; letter-spacing: -0.01em; }
h2 { font-size: 1rem; margin: 0; }
h3 { font-size: 1rem; margin: 0; }
p { margin: 0; }

.muted { color: var(--muted); }
.small { font-size: 0.875rem; }
.fine { color: #94a3b8; font-size: 0.75rem; margin-top: 0.75rem; }
.strong { font-weight: 600; }
.strong-inline { font-weight: 600; color: var(--ink); }
.accent { color: var(--brand); }
.warn { color: var(--warn-fg); }
.nums { font-variant-numeric: tabular-nums; }
.error { color: #e11d48; font-size: 0.875rem; margin-top: 0.75rem; }

/* ── sign in ───────────────────────────────────────────────────────────── */
.centre-page { min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: 2rem 1.25rem; }
.signin { width: 100%; max-width: 24rem; }
.brand-rule { width: 3rem; height: 4px; border-radius: 2px; background: var(--brand); }
.sub { color: var(--muted); font-size: 0.875rem; margin-top: 0.25rem; }

.card {
  background: var(--card); border-radius: 0.75rem; padding: 1.5rem;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.05); border: 1px solid var(--line);
  margin-top: 2rem;
}
.card-warn { border-color: #fcd34d; }
.card label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.5rem; }
.code {
  margin-top: 0.75rem; padding: 0.5rem 0.75rem; background: #f8fafc;
  border-radius: 0.5rem; font: 0.75rem/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted); overflow-wrap: anywhere;
}

/* type=password was missing from this list, so the password box on the sign-in form fell
   back to the UA default: visibly shorter than the email box above it and with tighter
   padding (Mirza, 2026-08-20). Adding the selector is the whole fix. Listing types
   explicitly rather than using a bare `input` keeps checkboxes and radios out of it. */
input[type=email], input[type=search], input[type=text], input[type=password],
input[type=tel], input[type=number] {
  width: 100%; padding: 0.75rem; border: 1px solid #cbd5e1; border-radius: 0.5rem;
  background: #fff; color: inherit; outline: none;
}
input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px rgb(200 16 46 / 0.15); }

/* One field per row, with the label sitting on its input. The form previously relied on
   `.card label { margin-bottom }` alone, so the gap between a field and the NEXT label was
   the same as the gap between a label and its own input, and the pairs did not read as
   pairs. */
.field + .field { margin-top: 1rem; }
.field label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.375rem; }
.signin-head { margin-bottom: 0.5rem; }

.btn {
  border: 0; border-radius: 0.5rem; padding: 0.85rem 1.25rem; font-weight: 600;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
}
.btn-block { display: flex; width: 100%; margin-top: 1.25rem; }
.btn-brand { background: var(--brand); color: #fff; }
.btn-brand:hover { background: var(--brand-dark); }
.btn-brand:disabled { opacity: 0.4; cursor: default; }
.btn-ghost { background: #fff; color: #334155; border: 1px solid #cbd5e1; }
.btn-dark { background: #334155; color: #fff; }
.linkish { background: none; border: 0; color: var(--brand); font-weight: 500; font-size: 0.875rem; cursor: pointer; padding: 0; margin-top: 1.25rem; }

/* ── navbar ────────────────────────────────────────────────────────────────
   Full-bleed chrome. z-index 30 keeps it BELOW the sheets at 40, which is load-bearing on
   a phone: #cart and #picker are full-screen takeovers there, and chrome painted over them
   covers their close buttons. Raising this to 60 (2026-08-24) did exactly that and trapped
   reps inside the cart with no way back. The desktop rail is handled by lowering the rail
   instead, in the 1100px block, because there the rail is a docked panel rather than an
   overlay. Do not raise this number to solve a desktop stacking problem. */
.navbar { position: sticky; top: 0; z-index: 30; background: rgb(255 255 255 / 0.96); backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); }
.navbar-inner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; padding: 0.75rem 1rem; }
.brand-tick { width: 4px; height: 1.25rem; border-radius: 2px; background: var(--brand); }
.brand-logo { height: 1.5rem; width: auto; display: block; flex: none; }
.cust-hint { padding: 0.5rem 1rem; color: #64748b; font-size: 0.75rem; border-bottom: 1px solid var(--line); }
.navbar-title { font-size: 0.875rem; font-weight: 600; }
/* Phone: logo/title/sign-out on line one, the customer button wrapping to line two on
   its own (flex-basis 100%). Desktop pulls it back up into the single row. */
.navbar-signout { margin: 0 0 0 auto; color: #94a3b8; font-size: 0.75rem; }

.customer-btn { display: flex; flex: 1 1 100%; width: 100%; align-items: center; gap: 0.5rem; padding: 0.25rem 0 0; background: none; border: 0; text-align: left; cursor: pointer; }
.customer-text { flex: 1; min-width: 0; }
.customer-name { display: block; font-size: 0.875rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.customer-meta { display: block; font-size: 0.75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill { flex-shrink: 0; border: 1px solid #cbd5e1; background: #fff; border-radius: 0.5rem; padding: 0.35rem 0.65rem; font-size: 0.75rem; font-weight: 500; color: #475569; cursor: pointer; }

/* No border-top now that this is the first block of the working column rather than the
   last row of the header — the navbar's own border already draws that line. */
.searchbar { position: relative; padding: 1rem; }
.search-icon { position: absolute; left: 1.75rem; top: 50%; transform: translateY(-50%); color: #94a3b8; pointer-events: none; }
.searchbar input { padding-left: 2.5rem; padding-right: 2.5rem; }
.search-clear { position: absolute; right: 1.25rem; top: 50%; transform: translateY(-50%); background: none; border: 0; color: #94a3b8; padding: 0.5rem; cursor: pointer; }

/* ── prompts and banners ───────────────────────────────────────────────── */
.banner { margin: 0.75rem 1rem; padding: 0.6rem 0.75rem; border-radius: 0.5rem; background: var(--bad-bg); color: var(--bad-fg); font-size: 0.875rem; }
.prompt { display: flex; width: calc(100% - 2rem); margin: 0.75rem 1rem 0; gap: 0.75rem; align-items: center; text-align: left; padding: 0.6rem 0.75rem; border-radius: 0.5rem; background: #fffbeb; border: 1px solid #fde68a; color: var(--warn-fg); font-size: 0.875rem; cursor: pointer; }
.prompt span:first-child { flex: 1; }
.prompt-cta { font-weight: 600; flex-shrink: 0; }

/* ── browse ────────────────────────────────────────────────────────────── */
#browse { padding: 1.5rem 1rem; }
.section { font-size: 0.875rem; font-weight: 600; color: var(--muted); }
.section + * { margin-top: 0.75rem; }
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 0.625rem; margin-top: 0.75rem; }
.tile { background: #fff; border: 1px solid var(--line); border-radius: 0.75rem; padding: 0.75rem 0.875rem; text-align: left; cursor: pointer; box-shadow: 0 1px 2px rgb(0 0 0 / 0.04); }
.tile b { display: block; font-weight: 500; }
.tile i { display: block; font-style: normal; font-size: 0.75rem; color: var(--muted); margin-top: 0.125rem; }
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.chip { background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 0.5rem 0.875rem; font-size: 0.875rem; color: #334155; cursor: pointer; }
h2.section:nth-of-type(2) { margin-top: 2rem; }

/* ── results and cart lines ────────────────────────────────────────────── */
/* The match count above the list. Sits tight to the results so it reads as a caption on
   them rather than as another line of page furniture. */
.result-count { margin: 0.75rem 0 -0.25rem; }
.results { list-style: none; margin: 0.75rem 0 0; padding: 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.results li { background: #fff; padding: 1rem; border-bottom: 1px solid var(--line); }
.results li:last-child { border-bottom: 0; }
.row { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.row-main { flex: 1; min-width: 0; }
.item-desc { font-weight: 500; line-height: 1.35; }
.item-sku { margin-top: 0.25rem; font: 0.75rem ui-monospace, SFMono-Regular, Menlo, monospace; color: #94a3b8; }
.price { font-size: 1.125rem; font-weight: 600; }
.price-tag { font-size: 0.75rem; color: #94a3b8; }
.price-tag.contract { color: #047857; font-weight: 500; }
.needs-customer { font-size: 0.75rem; color: #94a3b8; line-height: 1.25; text-align: right; }
.line-actions { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-top: 0.75rem; }
.line-actions .btn { flex: 1; }
.pack-hint { font-size: 0.75rem; color: var(--muted); white-space: nowrap; flex-shrink: 0; }
.note-inline { margin-top: 0.75rem; font-size: 0.875rem; color: var(--warn-fg); }

/* Previously-bought marker on a search row. Green, quiet, and never a call to action:
   it explains why the row is where it is, nothing more. */
.bought { margin-top: 0.25rem; font-size: 0.75rem; font-weight: 500; color: var(--ok-fg); }

.badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.badge { display: inline-flex; align-items: center; gap: 0.375rem; border-radius: 999px; padding: 0.25rem 0.625rem; font-size: 0.75rem; font-weight: 500; border: 1px solid; }
.badge .dot { width: 6px; height: 6px; border-radius: 50%; }
.badge-in { background: var(--ok-bg); color: var(--ok-fg); border-color: #a7f3d0; }
.badge-in .dot { background: #10b981; }
.badge-short { background: var(--warn-bg); color: var(--warn-fg); border-color: #fde68a; }
.badge-short .dot { background: #f59e0b; }
.badge-out { background: var(--bad-bg); color: var(--bad-fg); border-color: #fecdd3; }
.badge-out .dot { background: #f43f5e; }
.badge-unknown { background: #f1f5f9; color: var(--muted); border-color: var(--line); }
.badge-unknown .dot { background: #94a3b8; }
.badge .detail { font-weight: 400; opacity: 0.75; }
.badge-status { background: #f1f5f9; color: #475569; border-color: var(--line); }

/* quantity stepper */
.qty { display: inline-flex; align-items: center; border: 1px solid #cbd5e1; border-radius: 0.5rem; overflow: hidden; background: #fff; }
.qty button { width: 2.75rem; height: 2.75rem; border: 0; background: none; font-size: 1.25rem; color: #475569; cursor: pointer; }
.qty button:disabled { opacity: 0.3; cursor: default; }
.qty input { width: 4rem; height: 2.75rem; border: 0; border-left: 1px solid #cbd5e1; border-right: 1px solid #cbd5e1; text-align: center; outline: none; border-radius: 0; }
.qty.sm button { width: 2.25rem; height: 2.25rem; font-size: 1.125rem; }
.qty.sm input { width: 3.5rem; height: 2.25rem; font-size: 0.875rem; }

.trash { background: none; border: 0; color: #94a3b8; padding: 0.375rem; cursor: pointer; flex-shrink: 0; }
.trash:hover { color: #e11d48; }


.empty { padding: 4rem 1.5rem; text-align: center; }

/* ── bottom cart bar ───────────────────────────────────────────────────── */
.cartbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; background: #fff; border-top: 1px solid var(--line); padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px)); }
.cartbar-btn { margin-top: 0; justify-content: space-between; }
#app { padding-bottom: 6rem; }

/* ── sheets (picker, cart) ─────────────────────────────────────────────── */
.sheet { position: fixed; inset: 0; z-index: 40; background: var(--bg); display: flex; flex-direction: column; }
.sheet-head { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; background: #fff; border-bottom: 1px solid var(--line); }
.sheet-title { flex: 1; min-width: 0; }
.icon-btn { background: none; border: 0; color: var(--muted); padding: 0.25rem; cursor: pointer; }
.sheet-search { padding: 1rem; background: #fff; border-bottom: 1px solid var(--line); }
.cust-list { list-style: none; margin: 0; padding: 0; flex: 1; overflow-y: auto; overscroll-behavior: contain; }
.cust-list li { border-bottom: 1px solid #f1f5f9; }
.cust-list button { display: flex; width: 100%; gap: 0.75rem; align-items: flex-start; padding: 0.875rem 1rem; background: #fff; border: 0; text-align: left; cursor: pointer; }
.cust-name { font-weight: 500; }
.cust-meta { font-size: 0.875rem; color: var(--muted); margin-top: 0.125rem; }
.cust-no { font: 0.75rem ui-monospace, SFMono-Regular, Menlo, monospace; color: #94a3b8; margin-top: 0.125rem; }
.tag-current { background: rgb(200 16 46 / 0.1); color: var(--brand); border-radius: 999px; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; }

#cart-lines { flex: 1; overflow-y: auto; overscroll-behavior: contain; border: 0; margin: 0; }
.cart-foot { background: #fff; border-top: 1px solid var(--line); padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom, 0px)); }
.totals { display: flex; align-items: baseline; justify-content: space-between; }
.total { font-size: 1.5rem; font-weight: 600; }
.note { border-radius: 0.5rem; padding: 0.5rem 0.75rem; font-size: 0.875rem; margin-bottom: 0.75rem; }
.note-warn { background: #fffbeb; color: var(--warn-fg); }
.note-ok { background: #ecfdf5; color: var(--ok-fg); }
.note-bad { background: #fff1f2; color: var(--bad-fg); }

/* ── modal ─────────────────────────────────────────────────────────────── */
.modal { position: fixed; inset: 0; z-index: 50; background: rgb(0 0 0 / 0.4); display: flex; align-items: flex-end; justify-content: center; }
.modal-card { background: #fff; width: 100%; max-width: 28rem; border-radius: 1rem 1rem 0 0; padding: 1.25rem; }
.modal-row { display: flex; gap: 0.75rem; align-items: flex-start; }
.warn-badge { flex-shrink: 0; width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--warn-bg); color: var(--warn-fg); display: flex; align-items: center; justify-content: center; font-weight: 700; }
.modal-actions { display: flex; gap: 0.75rem; margin-top: 1.25rem; }
.modal-actions .btn { flex: 1; }

@media (min-width: 640px) {
  .modal { align-items: center; }
  .modal-card { border-radius: 1rem; }
}

/* ── desktop ───────────────────────────────────────────────────────────────
   The app is phone-first, and on a laptop the phone layout read as "very hard to
   navigate" (Tadd Duvendack, 2026-08-18): full-screen takeover sheets, a stretched
   single column, a cart you could not see while picking items. On a wide screen the
   quote becomes a permanently visible right rail, the picker becomes a floating
   dialog, and the working column holds a readable width. */
@media (min-width: 700px) {
  /* The customer picker floats instead of taking the whole screen. */
  #picker { left: 50%; right: auto; top: 7vh; bottom: auto; transform: translateX(-50%);
            width: min(34rem, calc(100vw - 4rem)); max-height: 82vh;
            border-radius: 0.75rem; border: 1px solid var(--line); overflow: hidden;
            box-shadow: 0 25px 60px rgb(15 23 42 / 0.35); }

  .tiles { grid-template-columns: repeat(4, 1fr); }

  /* One row, fixed height: the customer button comes up off its own line and the height
     becomes a known quantity, which is what --nav-h below can then offset against. */
  .navbar-inner { flex-wrap: nowrap; height: var(--nav-h); padding: 0 1.25rem; }
  .customer-btn { order: 1; flex: 0 1 26rem; width: auto; min-width: 0; margin-left: auto; padding: 0; }
  .navbar-signout { order: 2; margin: 0; }
}

@media (min-width: 1100px) {
  /* The quote is always on screen: no bottom bar, no sheet, no lost context. */
  #app { margin-right: 26rem; }
  .cartbar { display: none !important; }
  /* `top` overrides .sheet's `inset: 0`. Without it the rail starts at the very top of the
     viewport, level with the navbar, which is what made the bar look severed at 26rem and
     the page read as two panes rather than one app under one header. */
  /* +1px for the navbar's own bottom border: --nav-h is the height of .navbar-inner and the
     border sits outside it. Without the offset the rail starts one pixel high and clips that
     border, leaving the header's underline visibly broken across the rail's width. */
  /* z-index 20 puts the rail under the navbar (30). On this breakpoint the rail is docked
     furniture, not a takeover, and its own close button is hidden just below, so nothing
     here needs to sit above the chrome. The phone keeps the sheet at 40, above the navbar,
     which is what makes its back button tappable. */
  #cart { display: flex !important; left: auto; top: calc(var(--nav-h) + 1px); width: 26rem;
          z-index: 20; border-left: 1px solid var(--line); }
  #cart [data-close-cart] { display: none; }

  /* The working column holds a readable width instead of stretching wall to wall. The
     navbar is deliberately NOT in this list: it spans the viewport. */
  .searchbar { max-width: 46rem; margin-left: auto; margin-right: auto; }
  #banner, #customer-prompt { width: 100%; max-width: 44rem; margin-left: auto; margin-right: auto; }
  #browse, #results, #searching, #no-results { max-width: 46rem; margin-left: auto; margin-right: auto; }
  #results { border: 1px solid var(--line); border-radius: 0.75rem; overflow: hidden; margin-top: 0.75rem; }
  #app { padding-bottom: 2rem; }
}
