/* Self-hosted Inter (latin, variable weight) — the UI typeface. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Inter.var.woff2") format("woff2");
}

:root {
  --navy: #1f3a5f;
  --green: #3d6b35;
  --burgundy: #6e1e2c;
  --ink: #20242b;
  --muted: #6b7280;
  --rule: #dfe2e7;
  --bg: #eef1f5;
  --card: #ffffff;
  /* spacing scale */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 36px;
  /* radii + elevation — give surfaces a raised "dashboard panel" feel */
  --radius: 12px; --radius-sm: 8px;
  --shadow-card: 0 1px 2px rgba(20, 36, 60, .05), 0 6px 22px rgba(20, 36, 60, .07);
  --shadow-sm: 0 1px 2px rgba(20, 36, 60, .08);
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ---- top bar ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--card); border-bottom: 2px solid var(--navy);
  padding: 12px 28px; box-shadow: var(--shadow-sm);
}
.topbar .brand { display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--navy); font-weight: 600; }
.topbar .brand img { height: 34px; }
.topbar nav { display: flex; align-items: center; gap: 16px; }
.topbar nav a { text-decoration: none; color: var(--navy); }
.topbar nav .current-user { font-size: 13px; color: #555; padding: 2px 8px; background: #eef1f5; border-radius: 12px; }
.edited-by { font-size: 11px; color: #888; }
/* modal (presence + save-conflict popups) */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.45); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.modal { background: #fff; border-radius: 10px; padding: 22px 26px; max-width: 600px; width: 92%; box-shadow: 0 12px 48px rgba(0,0,0,.3); }
.modal h3 { margin: 0 0 14px; color: var(--navy); }
.modal-body { font-size: 14px; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; flex-wrap: wrap; }
.btn-secondary { background: #eef1f5; color: var(--navy); border: none; border-radius: 6px; padding: 9px 16px; cursor: pointer; font-size: 14px; }
.btn-overwrite { background: var(--burgundy); color: #fff; border: none; border-radius: 6px; padding: 9px 16px; cursor: pointer; font-size: 14px; }
.btn-overwrite:hover { background: #571723; }
.diff-cols { display: flex; gap: 24px; margin-top: 8px; }
.diff-cols > div { flex: 1; min-width: 0; }
.diff-cols h4 { margin: 0 0 6px; font-size: 13px; color: #555; }
.diff-list { margin: 0; padding-left: 16px; font-size: 13px; }
.diff-list li { margin-bottom: 3px; word-break: break-word; }
.diff-list .old { color: var(--burgundy); text-decoration: line-through; }
.diff-list .new { color: #1a7a3a; }

main { max-width: min(95vw, 1500px); margin: var(--s5) auto; padding: 0 28px; }

/* ---- buttons ---- */
button, .btn-primary {
  font: inherit; cursor: pointer; border: 1px solid var(--navy);
  background: var(--card); color: var(--navy); border-radius: 6px;
  padding: 8px 14px;
}
.btn-primary { background: var(--navy); color: #fff; }
.btn-primary:hover { background: #16304f; }
.topbar nav a.btn-primary, .topbar nav a.btn-primary:hover { color: #fff; }
.btn-danger { border-color: var(--burgundy); color: var(--burgundy); }
.btn-add { margin-top: 8px; border-style: dashed; }
.btn-del { border: none; color: var(--burgundy); background: none;
  font-size: 18px; line-height: 1; padding: 2px 6px; }

/* ---- cards ---- */
.card {
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: var(--s5) var(--s5); margin-bottom: var(--s4); box-shadow: var(--shadow-card);
}
.card h2 { margin: 0 0 var(--s4); font-size: 13px; text-transform: uppercase;
  letter-spacing: 0.8px; color: var(--navy); font-weight: 700; }

/* ---- login ---- */
.login-card {
  max-width: 360px; margin: 60px auto; background: var(--card);
  border: 1px solid var(--rule); border-radius: 10px; padding: 30px;
  text-align: center;
}
.login-logo { height: 70px; margin-bottom: 10px; }
.login-card h1 { font-size: 18px; margin: 6px 0; }
.login-card form { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.login-card input { padding: 10px; border: 1px solid var(--rule); border-radius: 6px; font: inherit; }

/* ---- list ---- */
.page-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--s5); gap: var(--s4); flex-wrap: wrap; }
.page-head h1 { font-size: 26px; margin: 0; font-weight: 700; letter-spacing: -0.2px; }

.list-table { width: 100%; border-collapse: separate; border-spacing: 0;
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow-card); }
.list-table th, .list-table td { padding: 13px 14px; text-align: left;
  border-bottom: 1px solid var(--rule); vertical-align: middle; }
.list-table .col-updated { white-space: nowrap; }
.list-table .row-actions { white-space: nowrap; }
.list-table th { background: var(--navy); color: #fff; font-size: 12.5px;
  text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600; }
.list-table tbody tr:nth-child(even) { background: #fafbfd; }
.list-table tbody tr:hover { background: #eef3fb; }
.list-table tbody tr:last-child td { border-bottom: none; }
.list-table .num { text-align: right; font-variant-numeric: tabular-nums; }
/* keep this a normal table cell (not flex) so it vertical-aligns with the row
   and its bottom border spans the full row height; space the links inline. */
.row-actions a { color: var(--navy); text-decoration: none; }
.row-actions a + a { margin-left: 14px; }

.pill { display: inline-block; padding: 2px 9px; border-radius: 9px;
  color: #fff; font-size: 12px; text-transform: capitalize; background: var(--muted); }
.pill-ocean { background: var(--navy); }
.pill-air { background: var(--green); }
/* #15: Air-Direct gets a bolder, brighter pill (vermilion + thicker outline)
   so the case visually pops out of an otherwise muted list. */
.pill-air-direct { background: #d2492a; outline: 2px solid #efb96c;
  outline-offset: -3px; font-weight: 700; }
.pill-single { background: #5b6b7a; }   /* slate — one retailer */
.pill-multi { background: #8a5a2b; }    /* amber-brown — multiple retailers */

/* ---- list status + paid flags (inline edit) ---- */
.col-status .flag { flex-direction: row; align-items: center; gap: 6px;
  cursor: pointer; color: var(--ink); }
.col-status input { width: auto; cursor: pointer; }
.status-pill { display: inline-block; padding: 1px 8px; border-radius: 9px;
  font-size: 11px; font-weight: 600; background: #e6e8ec; color: var(--muted); }
.status-pill.is-final { background: var(--green); color: #fff; }
.col-paid { white-space: nowrap; }
/* Paid pill — derived from BDD billing flags (engine.paid_status), not ticked
   by hand. Green = fully paid, gold = partial, burgundy = not paid. */
.pill-paid-paid { background: var(--green); }
.pill-paid-partial { background: #c9a227; }
.pill-paid-unpaid { background: var(--burgundy); }
/* subtle marker: BDD explicitly says the warehouse assignment is NOT verified */
.wh-unverified { color: #c9a227; font-size: 13px; cursor: help; }

/* ---- BDD change detection (sync) ---- */
/* "BDD changed" pill: gold-outlined so it reads as needs-review, not error */
.pill-bdd-changed { background: #a06a00; outline: 2px solid #ecd190;
  outline-offset: -3px; font-weight: 700; text-transform: none; cursor: help; }
/* subtle row tint for changed orders; hover keeps precedence */
.list-table tbody tr.row-bdd-changed { background: #fdf6e4; }
.list-table tbody tr.row-bdd-changed:hover { background: #f8eecd; }
/* toolbar next to the page title: last-synced line + manual check button */
.sync-bar { display: flex; align-items: center; gap: 12px; }
.sync-last { font-size: 13px; }
.sync-bar button { font: inherit; font-size: 13px; font-weight: 600;
  padding: 7px 14px; border: 1px solid var(--navy); border-radius: 6px;
  color: var(--navy); background: #fff; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px; }
.sync-bar button:hover { background: var(--navy); color: #fff; }
.sync-bar button:disabled { opacity: 0.6; cursor: wait; }
.sync-spinner { width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: sync-spin 0.8s linear infinite; }
@keyframes sync-spin { to { transform: rotate(360deg); } }
/* daily exchange-rate widget under the page head: set by hand, prefills
   drafts; the stale note fires when the UTC day passed the stored date */
.daily-rate-bar { display: flex; align-items: center; gap: 10px;
  margin: 0 0 14px; font-size: 13px; flex-wrap: wrap; }
.daily-rate-bar .drb-label { font-weight: 600; color: var(--navy); }
.daily-rate-bar input[name="rate"] { width: 90px; }
.daily-rate-bar input { font: inherit; font-size: 13px; padding: 6px 8px;
  border: 1px solid var(--rule); border-radius: 6px; }
.daily-rate-bar button { font: inherit; font-size: 13px; font-weight: 600;
  padding: 6px 14px; border: 1px solid var(--navy); border-radius: 6px;
  color: var(--navy); background: #fff; cursor: pointer; }
.daily-rate-bar button:hover { background: var(--navy); color: #fff; }
.daily-rate-bar .drb-stale, .daily-rate-bar .drb-err { color: #8a6d1e;
  background: #fdf6e3; border: 1px solid #c9a227; border-radius: 6px;
  padding: 4px 10px; }
.daily-rate-bar .drb-err { color: #a33; background: #fdeaea;
  border-color: #d99; }
/* the on-open popup (reuses .modal): change rows + conflict checkboxes */
.sync-changes { margin: 8px 0 0; padding-left: 0; list-style: none;
  font-size: 13px; max-height: 300px; overflow-y: auto; }
.sync-changes li { margin: 5px 0; padding: 6px 8px; background: #f6f7fa;
  border-radius: 6px; }
.sync-changes .old { color: var(--burgundy); text-decoration: line-through; }
.sync-changes .new { color: var(--green); font-weight: 600; }
.sync-changes li.conflict { background: #fdf2f2;
  border-left: 3px solid var(--burgundy); }
.sync-changes li.conflict label { display: flex; gap: 8px; cursor: pointer;
  align-items: baseline; }
.sync-changes li.conflict input { width: auto; }
.sync-conflict-note { font-size: 12.5px; color: var(--burgundy); margin: 10px 0 0; }
.sync-status-note { font-size: 12.5px; color: var(--muted); margin: 10px 0 0; }

/* Version history — promoted to the top of the order form (section 1 header)
   so it's findable; reads as a real button, not a buried link. */
.btn-versions { float: right; font-size: 13px; font-weight: 600;
  padding: 6px 12px; border: 1px solid var(--navy); border-radius: 6px;
  color: var(--navy); background: #fff; text-decoration: none;
  text-transform: none; letter-spacing: 0; }
.btn-versions:hover { background: var(--navy); color: #fff; }

.typo-warn { border-left: 4px solid var(--burgundy); }
.typo-warn h2 { color: var(--burgundy); }
.typo-list { margin: 8px 0 0; padding-left: 18px; font-size: 13px; }
.typo-list li { margin: 3px 0; }

.empty { text-align: center; padding: 50px; color: var(--muted); }
.empty .btn-primary { display: inline-block; margin-top: 12px; text-decoration: none; }

/* ---- form layout ---- */
.form-layout { display: grid; grid-template-columns: 1fr 440px;
  gap: var(--s5); align-items: start; }
/* Single column of cards — sections have very different heights, so any 2-up
   packing looks lopsided. A clean stacked column reads as organized; the sticky
   totals panel keeps the action buttons in view so scroll length isn't a problem.
   (.card-wide is a harmless no-op here, kept for clarity.) */
.order-form > .card { margin-bottom: var(--s4); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.grid-2 .span-2 { grid-column: 1 / -1; }
/* 3-up field grid for field-heavy cards (Customer) — uses the wide form column
   to cut vertical height. .span-2 still spans the full row. */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); }
.grid-3 .span-2 { grid-column: 1 / -1; }
/* A field is: one-line caption, control, optional hint UNDER the control.
   Captions are locked to a single line height so that two fields sitting side
   by side in a grid row always put their inputs on the same baseline — a
   caption that wrapped (or a required marker on its own line) used to knock
   its neighbour out of alignment. */
label { display: flex; flex-direction: column; gap: var(--s1); font-size: 14px;
  color: var(--muted); }
label > .lbl {
  display: block; min-height: 20px; line-height: 20px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
label > .lbl .muted { font-weight: 400; }
.req { color: var(--burgundy); font-weight: 700; font-style: normal; }
label input, label select, label textarea {
  font: inherit; color: var(--ink); padding: 8px 10px;
  border: 1px solid var(--rule); border-radius: 6px; background: #fff;
  width: 100%;
}
label input:focus, label select:focus, label textarea:focus {
  outline: 2px solid var(--navy); outline-offset: -1px; border-color: var(--navy);
}
.field-hint { font-size: 11.5px; color: var(--muted); line-height: 1.35; }
.hidden { display: none !important; }

/* Grid rows align their fields from the top; the hint hangs below without
   stretching the control. */
.grid-2, .grid-3 { align-items: start; }

.checkline { flex-direction: row; align-items: center; gap: 8px; margin: 0;
  color: var(--ink); }
.checkline input { width: auto; }
.checkline input[type="text"], .checkline input[type="date"] { width: auto; flex: 0 1 200px; }
/* Checkbox/radio stacks: even spacing instead of ad-hoc margins per line. */
.check-grid { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; }
.check-grid.inline { flex-direction: row; flex-wrap: wrap; gap: 18px; align-items: center; }

/* ---- row tables ---- */
.rows-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
.rows-table th { font-size: 11px; text-transform: uppercase; color: var(--muted);
  text-align: left; padding: 4px 6px; letter-spacing: 0.4px; }
.rows-table th.num { text-align: right; }
.rows-table td { padding: 3px 6px; }
.rows-table input { width: 100%; padding: 6px 8px; border: 1px solid var(--rule);
  border-radius: 5px; font: inherit; }
.rows-table td.num input { text-align: right; }
.rows-table .num { text-align: right; }
.rows-table th.col-pending, .rows-table td.col-pending { text-align: center; width: 110px; }
.rows-table td.col-pending input { width: auto; padding: 0; }

/* ---- totals panel ---- */
.hint { font-size: 13px; color: var(--muted); margin: -4px 0 12px; }
.advanced { margin-top: 10px; }
.advanced summary { cursor: pointer; font-size: 13px; color: var(--navy); }
.advanced .grid-2 { margin-top: 10px; }
.reprice-row { display: flex; align-items: center; gap: 16px; margin-top: 14px;
  padding-top: 12px; border-top: 1px solid var(--rule); }
.reprice-row a { color: var(--navy); text-decoration: none; font-size: 13px; }

/* Stretch the totals column to the form's full height so its sticky card has
   room to travel — otherwise (align-items:start) the column is only as tall as
   the card and it scrolls away almost immediately. */
.totals-panel { align-self: stretch; }
.totals-panel .sticky { position: sticky; top: var(--s4);
  max-height: calc(100vh - 2 * var(--s4)); overflow-y: auto; }
.totals-basis { font-size: 11px; color: var(--navy); background: #eef2f8;
  border-radius: 5px; padding: 5px 8px; margin-bottom: 8px; text-align: center; }
.totals-counts { display: flex; justify-content: space-between; font-size: 12px;
  color: var(--muted); border-bottom: 1px solid var(--rule); padding-bottom: 8px; }
.totals-lines { margin: 8px 0; }
.tline { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0;
  font-size: 13px; }
/* The label column keeps a consistent minimum width so short labels ("US
   tariff") align with longer ones ("Insurance & processing"), but long labels
   (small-batch handling + its detail) WRAP instead of pushing the amount out
   of the panel. The amount span can never shrink or wrap, so it can't clip. */
.tline > span:first-child { flex: 1 1 auto; min-width: 9.5em;
  white-space: normal; overflow-wrap: anywhere; }
.tline > span:last-child { flex-shrink: 0; white-space: nowrap; text-align: right; }
.tline em { color: var(--muted); font-style: normal; font-size: 11px; }
.tline.credit { color: var(--green); }
.tline.review { background: #fdf6e3; border-left: 3px solid #c9a227;  /* brand gold = "verify this" */
  padding-left: 6px; }
.tline .review-note { color: #8a6d1e; font-weight: 600; font-size: 11px; }
/* Provisional cells (#6/#7/#8): when a line's amount is pending, the form
   renders an italic note instead of the figure — muted to read "to be
   determined" without competing with the real numbers. */
.tline.pending { color: var(--muted); }
.tline .tpending { font-style: italic; color: var(--muted); font-size: 12px; }
/* "Totals not final" banner (#9): mirrors the PDF banner; gold-on-cream to
   match the verify-this idiom. */
.provisional-banner { background: #fdf6e3; border: 1px solid #c9a227;
  border-radius: 4px; padding: 6px 10px; color: #8a6d1e; font-weight: 600;
  font-size: 12px; margin-bottom: 6px; }

/* #11: gold border on the Additional Fees section when destination is
   AK/HI/NH or a summer-upgrade / wooden-box fee is set. Matches the
   verify-this idiom so the eye lands here before sending. */
.card.fees-attention { border: 2px solid #c9a227; background: #fdf6e3; }
.card.fees-attention h2 { color: #8a6d1e; }

/* #14: optional per-row label column. Hidden by default to avoid
   cluttering typical orders; "Show labels" toggle reveals it, and
   loading a saved order with any labels auto-reveals (see app.js). */
#purchases .col-label { display: none; }
#purchases.show-labels .col-label { display: table-cell; }

/* Catch-all "Other >3L" formats column — same hidden-by-default idiom as the
   label column; auto-revealed when an order already carries >3L items. */
#purchases .col-lv { display: none; }
#purchases.show-lv .col-lv { display: table-cell; }
#purchases td.col-lv { min-width: 110px; }
#purchases td.col-lv input.lv-desc { margin-top: 3px; font-size: 11px; }
.purchases-controls { display: flex; align-items: center; gap: 14px;
  margin-top: 6px; }
.show-labels-toggle { display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--muted); cursor: pointer; }

/* #13: pending-BDD purchase rows — gold-highlighted with a small pill so
   the row stands out before sending. The pill itself is hidden by default
   and revealed by the is-pending-bdd class. */
.pending-bdd-pill { display: none; margin-top: 4px; padding: 2px 6px;
  background: #c9a227; color: #fff; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.4px; border-radius: 3px;
  width: fit-content; }
tr.is-pending-bdd { background: #fdf6e3 !important; }
tr.is-pending-bdd > td:first-child { border-left: 3px solid #c9a227; }
tr.is-pending-bdd .pending-bdd-pill { display: inline-block; }
/* High-value order (#25): the insurance-override menu opens + goes gold to prompt a rate check. */
details.advanced.insurance-review { border: 2px solid #c9a227; background: #fdf6e3;
  border-radius: 6px; padding: 4px 8px; }
details.advanced.insurance-review > summary { color: #8a6d1e; font-weight: 600; }
.totals-grand { display: flex; justify-content: space-between; align-items: baseline;
  border-top: 2px solid var(--navy); padding-top: 8px; margin-top: 6px; }
.totals-grand strong { font-size: 20px; color: var(--burgundy);
  font-variant-numeric: tabular-nums; }
.totals-payment { margin-top: 8px; }
.tpay { display: flex; justify-content: space-between; align-items: baseline;
  padding: 3px 0; font-size: 13px; }
.tpay strong { font-variant-numeric: tabular-nums; color: var(--burgundy); }
.tpay.zelle strong { color: #2e7d32; }
.tpay-rate { font-size: 11px; color: var(--muted); text-align: right; }

.warnings { margin-top: 10px; }
.warn { background: #fff6f6; border-left: 3px solid var(--burgundy);
  padding: 6px 8px; font-size: 12px; margin-bottom: 6px; color: #7a2531; }
.actions { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.actions button { width: 100%; }
.btn-finalize { border-color: var(--green); color: #fff; background: var(--green); }
.btn-finalize:hover { background: #335c2c; }
.finalized-state { font-size: 12px; font-weight: 600; color: var(--muted);
  margin-top: 14px; }
.finalized-state.is-final { color: var(--green); }
.save-status { margin-top: 8px; font-size: 12px; min-height: 16px; }

.muted { color: var(--muted); }
.error { background: #fff6f6; border: 1px solid var(--burgundy);
  color: var(--burgundy); padding: 8px; border-radius: 6px; font-size: 13px; }

/* ---- list sorting + filters ----
   The filters sit in a second <thead> row, each control directly above the
   column it filters (inputs bind to the #list-filters form via form=). */
.filter-row th { background: #f4f6fa; padding: 6px 8px;
  text-transform: none; letter-spacing: 0; }
.filter-row input, .filter-row select { width: 100%; min-width: 0;
  padding: 6px 8px; border: 1px solid var(--rule); border-radius: 6px;
  font: inherit; font-size: 12px; background: #fff; color: var(--ink);
  box-sizing: border-box; }
.filter-row .filter-dates label { display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--muted); font-weight: 600; }
.filter-row .filter-dates label + label { margin-top: 4px; }
.filter-row .filter-actions { white-space: nowrap; }
.filter-row .filter-actions button { padding: 6px 12px; border: 1px solid var(--navy);
  border-radius: 6px; background: var(--navy); color: #fff; font: inherit;
  font-size: 12px; cursor: pointer; }
.filter-row .filter-actions .clear { color: var(--muted); text-decoration: none;
  font-size: 12px; margin-left: 8px; }
.list-table th .sort-link { color: #fff; text-decoration: none; white-space: nowrap; }
.list-table th .sort-link:hover,
.list-table th .sort-link.active { text-decoration: underline; }

@media (max-width: 860px) {
  .form-layout { grid-template-columns: 1fr; }
  .totals-panel .sticky { position: static; max-height: none; }
}

/* "Load from BDD" — order# field inline button + status line */
.bdd-load { display: flex; gap: 6px; }
.bdd-load input { flex: 1; }
#btn-bdd-load { white-space: nowrap; flex: 0 0 auto; }
.bdd-status { display: block; margin-top: 4px; font-size: 12px; min-height: 1em; }
.bdd-status.ok { color: var(--green); }
.bdd-status.err { color: var(--burgundy); }

/* ---- "Start here" order-number card (step 1) ---- */
.card-start { border: 2px solid var(--navy); }
.card-start h2 { display: flex; align-items: center; gap: 8px; }
.step-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--navy); color: #fff; font-size: 13px; font-weight: 700;
}
.order-ref { display: block; font-weight: 600; }
.order-ref input { font-size: 18px; padding: 8px 10px; }
.caption {
  margin: 8px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted);
  border-left: 3px solid var(--navy); padding-left: 10px;
}

/* ---- required fields + validation visuals ---- */
.req > :first-child::after,
label.req::after { content: " *"; color: var(--burgundy); font-weight: 700; }
/* labels are flex-column, so a bare ::after lands BELOW the input — pin the
   required asterisk to the caption's top-right corner instead. */
label.req { position: relative; }
label.req::after { position: absolute; top: 0; right: 2px; content: "*"; }
.field-invalid,
input.field-invalid {
  border: 2px solid var(--burgundy) !important;
  background: #fcebed !important;
  outline: none;
  box-shadow: 0 0 0 3px rgba(110, 30, 44, 0.15);
}
label.has-error { color: var(--burgundy); font-weight: 600; }
#payment-card.bypassed { opacity: 0.55; }
#payment-card.bypassed .req::after { content: ""; }
.bypass-toggle {
  display: flex; flex-direction: row; align-items: center; gap: 6px;
  margin: 6px 0; font-size: 13px; color: var(--navy); cursor: pointer;
}
.bypass-toggle input { width: auto; }

/* ---- new-supplier-name highlight (verify, not an error) ---- */
input.supplier-new {
  border: 2px solid #c9a227 !important;   /* brand gold = "verify this" */
  background: #fdf6e3 !important;
  box-shadow: 0 0 0 3px rgba(201, 162, 39, 0.18);
}
.bdd-status.warn-status { color: #8a6d1e; font-weight: 600; }

/* purchases table: fixed layout -> exact, equal columns + top-aligned grid */
#purchases { table-layout: fixed; }
#purchases td { vertical-align: top; }              /* inputs line up at the top, regardless of the BDD subtext height */
#purchases th { white-space: nowrap; font-size: 10px; letter-spacing: 0.3px;
  vertical-align: bottom; padding-bottom: 5px; }    /* headers on one line, sitting just above the inputs */
#purchases th:nth-child(1), #purchases td:nth-child(1) { width: 30%; }   /* retailer */
#purchases th:nth-child(2), #purchases td:nth-child(2),
#purchases th:nth-child(3), #purchases td:nth-child(3),
#purchases th:nth-child(4), #purchases td:nth-child(4) { width: 72px; text-align: center; }  /* bottles/magnums/jeroboams — equal, centered */
#purchases td:nth-child(2) input, #purchases td:nth-child(3) input,
#purchases td:nth-child(4) input { width: 60px; text-align: center; }  /* narrow box, centered in its column */
#purchases th:nth-child(5), #purchases td:nth-child(5) { width: 18%; }   /* wine value HT — readable */

/* BDD ground-truth reference under a retailer field (which supplier this row is) */
.bdd-ref { font-size: 10.5px; color: var(--muted); margin-top: 3px; line-height: 1.3; }
/* supplier-alias edit form (inline name + save) */
.alias-edit { display: flex; gap: 6px; align-items: center; }
.alias-edit input[type="text"] { flex: 1; min-width: 180px; padding: 5px 7px;
  border: 1px solid var(--rule); border-radius: 5px; }

/* ==========================================================================
   Quotes-platform additions (appended to the copied gos2 stylesheet)
   ========================================================================== */

/* quote + option status pills */
.qstatus-new        { background: #a06a00; color: #fff; }
.qstatus-in_progress{ background: var(--navy); color: #fff; }
.qstatus-quoted     { background: #5b6b7a; color: #fff; }
.qstatus-finalized  { background: var(--green); color: #fff; }
.qstatus-cancelled  { background: #999; color: #fff; }
.qstatus-draft      { background: #5b6b7a; color: #fff; }
.qstatus-sent       { background: var(--navy); color: #fff; }
.qstatus-approved   { background: var(--green); color: #fff; }
.qstatus-archived   { background: #999; color: #fff; }

.quote-workspace h3 { display: flex; align-items: center; gap: 8px; margin: 0; }
.quote-workspace h4 { margin: var(--s4) 0 var(--s2); font-size: 12px;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.option-card { margin-bottom: var(--s4); }
.caption { font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); }

/* bottle rows + line-item tables */
.rows-table { width: 100%; border-collapse: collapse; margin: var(--s2) 0; }
.rows-table th { text-align: left; font-size: 11px; text-transform: uppercase;
  color: var(--muted); padding: 4px 6px; }
.rows-table td { padding: 3px 6px; vertical-align: middle; }
.rows-table input { width: 100%; box-sizing: border-box; }
.rows-table td:first-child { width: 30px; }
.li-table .li-amount { text-align: right; white-space: nowrap; min-width: 8em; }
.li-table .li-pct { padding: 2px 8px; margin-left: 4px; }
.li-table tfoot td { border-top: 2px solid var(--rule); padding-top: 8px; }
.o-total { text-align: right; white-space: nowrap; }

/* terms editor */
.terms-para { border-left: 3px solid var(--rule); padding: var(--s2) var(--s3);
  margin: var(--s2) 0; }
.terms-para.overridden { border-left-color: #c9a227; background: #fdf9ee; }
.terms-para-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.terms-text { white-space: pre-wrap; margin: var(--s1) 0 0; }
.inactive-term { opacity: .55; }

/* misc */
fieldset { border: 1px solid var(--rule); border-radius: var(--radius);
  margin: var(--s2) 0; }
fieldset legend { font-size: 12px; color: var(--muted); padding: 0 6px; }
.bdd-load { display: flex; gap: var(--s2); align-items: center; }
.bdd-load input { max-width: 240px; }

/* sortable list headers are plain <a> tags — force them white on the navy th
   (the default browser link blue was unreadable on the banner) */
.list-table th a { color: #fff; text-decoration: none; }
.list-table th a:hover { text-decoration: underline; }

/* ---- role chrome: make quoter vs requester mode unmistakable ----
   Quoter = burgundy frame; requester = green frame + tinted page background.
   The badge next to the user name names the role explicitly. */
body.role-quoter .topbar { border-bottom: 4px solid var(--burgundy); }
body.role-requester .topbar { border-bottom: 4px solid var(--green); }
body.role-requester { background: #edf3ec; }
.role-badge { padding: 2px 10px; border-radius: 10px; font-size: 11px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: #fff; cursor: help; }
.role-badge.quoter { background: var(--burgundy); }
.role-badge.requester { background: var(--green); }

/* ---- suppliers table (intake form + workspace recap) ----
   Fixed layout so the header sits square over its column and the last column
   can't be squeezed against the card edge: count columns are equal and narrow,
   the name column takes the slack, wine value gets real room. */
.table-scroll { overflow-x: auto; margin: 0 -4px; padding: 0 4px; }
.suppliers-table { table-layout: fixed; min-width: 720px; }
.suppliers-table th, .suppliers-table td { padding: 5px 6px; }
.suppliers-table .col-del { width: 32px; }
/* Four volume columns now (2026-08-25): the name column no longer hogs the
   row — counts get real width and the headers can say what they mean. */
.suppliers-table .col-name { width: 26%; min-width: 150px; }
.suppliers-table th.num { width: auto; text-align: center; }
.suppliers-table th[data-tip] { cursor: help; text-decoration: underline dotted; }
.suppliers-table td.num input { text-align: right; }
.suppliers-table .col-value { width: 130px; }
.suppliers-table th.col-value { text-align: right; padding-right: 12px; }
.suppliers-table td.col-value { padding-right: 6px; }
.suppliers-table .s-value { text-align: right; }
.suppliers-table tfoot .totals-row td {
  border-top: 2px solid var(--rule); padding-top: 9px; font-weight: 700;
  color: var(--ink); font-variant-numeric: tabular-nums; text-align: right;
}
.suppliers-table tfoot .totals-row td.col-name { text-align: left; }
.counts-recap { font-size: 13px; color: var(--navy); margin: 8px 0 0;
  font-weight: 600; }

/* "Just the totals" mode: one unnamed line, so the name and delete columns
   (and the separate totals row that would just repeat it) come off. */
#suppliers-card.mode-totals .col-del,
#suppliers-card.mode-totals .col-name,
#suppliers-card.mode-totals tfoot,
#suppliers-card.mode-totals #btn-add-supplier { display: none; }
#suppliers-card.mode-totals .suppliers-table { min-width: 560px; }

/* two-way switch for how the counts get entered */
.mode-switch { display: inline-flex; border: 1px solid var(--rule);
  border-radius: 8px; overflow: hidden; background: #fff; margin-bottom: 10px; }
.mode-switch button { border: none; border-radius: 0; background: #fff;
  color: var(--muted); padding: 8px 16px; font-size: 13.5px; font-weight: 600; }
.mode-switch button + button { border-left: 1px solid var(--rule); }
.mode-switch button.active { background: var(--navy); color: #fff; }

.suppliers-recap { margin-bottom: var(--s4); font-size: 13.5px; }
.suppliers-recap th, .suppliers-recap td { padding: 7px 10px; }
.suppliers-recap .num { text-align: right; font-variant-numeric: tabular-nums; }
.suppliers-recap tfoot td { border-top: 2px solid var(--rule);
  background: #f7f9fc; }

/* ---- stage tabs (Request → Shipping prices → Final quote) ---- */
.stage-tabs {
  display: flex; gap: var(--s2);
  margin: var(--s5) 0 var(--s4);
  border-bottom: 2px solid var(--rule);
}
.stage-tab {
  appearance: none; border: none; background: none; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--muted);
  padding: var(--s2) var(--s4) var(--s3);
  margin-bottom: -2px;
  border-bottom: 3px solid transparent;
  display: inline-flex; align-items: center; gap: var(--s2);
}
.stage-tab:hover { color: var(--ink); }
.stage-tab.active { color: var(--navy); border-bottom-color: var(--navy); }
.stage-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--rule); color: var(--ink);
  font-size: 12px; font-weight: 700;
}
.stage-tab.active .stage-num { background: var(--navy); color: #fff; }
.stage-tab.done .stage-num { background: var(--green); color: #fff; }
/* a completed stage shows a check instead of its number */
.stage-tab.done .stage-num { font-size: 0; }
.stage-tab.done .stage-num::after { content: "✓"; font-size: 12px; }
.stage-panel { display: none; }
.stage-panel.active { display: block; }

.pricing-row .grid-2, .pricing-row .grid-3 { margin-top: var(--s2); }

/* ---- stage 2: what this row will produce ---- */
.pricing-preview { margin-top: var(--s4); padding-top: var(--s3);
  border-top: 1px solid var(--rule); }
.preview-table { width: 100%; max-width: 460px; border-collapse: collapse;
  font-size: 13.5px; }
.preview-table td { padding: 4px 0; }
.preview-table .num { text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.preview-table tfoot td { border-top: 2px solid var(--navy); padding-top: 7px;
  font-weight: 700; color: var(--navy); font-size: 15px; }
.warn-note { font-size: 12.5px; color: #8a6d1e; background: #fdf6e3;
  border-left: 3px solid #c9a227; padding: 6px 10px; border-radius: 4px;
  margin: 8px 0; max-width: 560px; }

/* ---- stage 3: option card ---- */
.option-head { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); margin-bottom: var(--s3); }
.option-head h3 { font-size: 19px; font-weight: 700; }

/* Where this option stands — informative, deliberately NOT button-shaped. */
.lifecycle { display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-bottom: var(--s3); font-size: 13px; }
.lc-steps { display: flex; align-items: center; gap: 6px; }
.lc-step { padding: 3px 10px; border-radius: 11px; font-weight: 600;
  background: #eef1f5; color: var(--muted); }
.lc-step.done { background: #dfe7dd; color: var(--green); }
.lc-step.current { background: var(--navy); color: #fff; }
.lc-arrow { color: var(--rule); }
.lc-note { color: var(--muted); }
.lifecycle.archived { color: var(--muted); font-style: italic; }

/* Actions grouped by purpose, each group captioned, with one shared strip
   underneath that explains whatever the pointer is on. */
.action-bar { display: flex; flex-wrap: wrap; gap: var(--s5);
  padding: var(--s3) 0; border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule); }
.act-group { display: flex; flex-direction: column; gap: 6px; }
.act-group + .act-group { padding-left: var(--s5); border-left: 1px solid var(--rule); }
.act-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 700; }
.act-buttons { display: flex; gap: var(--s2); flex-wrap: wrap; }
.act-buttons a { text-decoration: none; display: inline-block; }
.act-explain { min-height: 34px; margin: var(--s2) 0 var(--s4);
  font-size: 13px; color: var(--navy); background: #f2f6fb;
  border-radius: 6px; padding: 8px 12px; }

.opt-section { margin-top: var(--s5); }
.opt-section > h4:first-child { margin-top: 0; }

/* Internal routing strip: cost first, then the journey in the order it
   happens — crossing → warehouse → final delivery. Team-facing only; none of
   this wording goes near the customer document. */
.routing-summary { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s3) var(--s5); margin: var(--s3) 0 0; padding: 10px 14px;
  background: #f7f9fc; border: 1px solid var(--rule); border-radius: var(--radius-sm);
  font-size: 13px; }
.routing-summary.empty { color: var(--muted); display: block; }
.rs-costs, .rs-route { display: flex; align-items: center; gap: var(--s3); }
.rs-route { gap: var(--s2); }
.rs-costs { padding-right: var(--s4); border-right: 1px solid var(--rule); }
.rs-cell { display: flex; flex-direction: column; line-height: 1.3; }
.rs-label { font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 700; }
.rs-value { font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.rs-step .rs-value { color: var(--navy); }
.rs-todo .rs-value { color: #a06a00; font-style: italic; font-weight: 500; }
.rs-arrow { color: var(--rule); font-size: 16px; }
.routing-summary a { color: var(--navy); font-size: 12.5px; margin-left: auto; }

/* the headline preview, so "title fragment" stops being a guess */
.title-preview { margin: 0 0 var(--s3); padding: 10px 14px;
  background: #f7f9fc; border-left: 3px solid var(--navy); border-radius: 4px;
  font-size: 16px; font-weight: 600; color: var(--ink); }
.override-wrap { margin-top: var(--s2); }

/* price table: one straight rule across the footer. (The old markup reused
   .totals-grand, a flex rule meant for the sidebar panel, on two <td>s — which
   turned them into flex boxes with their own offset borders and broke the
   line into steps.) */
.li-table { table-layout: fixed; }
.li-table .col-del { width: 32px; }
.li-table .col-qty { width: 70px; }
.li-table .col-price { width: 170px; }
.li-table .col-amount { width: 120px; }
.li-table th { padding-bottom: 6px; border-bottom: 1px solid var(--rule); }
.li-table td { padding: 4px 6px; }
.li-table .col-price input { width: calc(100% - 42px); }
.li-table .li-amount { text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.li-table .li-pct { padding: 4px 9px; margin-left: 4px; vertical-align: middle; }
.li-table tfoot .li-total-row td {
  border-top: 2px solid var(--navy); padding-top: 10px;
  font-weight: 700; color: var(--ink); font-size: 15px;
}
.li-table tfoot .li-total-row .o-total { color: var(--burgundy);
  font-variant-numeric: tabular-nums; }
.price-source { margin-bottom: var(--s2); }

/* the comments block, as a document rather than a column of inputs */
.doc-block { border: 1px solid var(--rule); border-radius: var(--radius-sm);
  background: #fff; overflow: hidden; }
.doc-line { display: grid; grid-template-columns: 190px 1fr; gap: var(--s4);
  padding: 12px 14px; border-bottom: 1px solid var(--rule); align-items: start; }
.doc-line:last-child { border-bottom: none; }
/* The chip lives with the label, not stacked under the field — it used to
   take the row the field needed to grow into. */
.doc-label { display: flex; flex-direction: column; align-items: flex-start;
  gap: 5px; font-size: 12px; font-weight: 700; color: var(--navy);
  text-transform: uppercase; letter-spacing: .04em; padding-top: 9px; }
.doc-value { position: relative; }
/* Visibly a field: the whole point of the block is that it can be edited, so
   it must not look like printed text (Louis, 2026-08-24). */
.doc-text {
  display: block; width: 100%; font: inherit; font-size: 14.5px;
  line-height: 1.55; min-height: 44px;
  color: var(--ink); border: 1px solid var(--rule); border-radius: 5px;
  background: #fff; padding: 9px 12px; resize: vertical; overflow: hidden;
}
.doc-text:hover:not(:disabled) { border-color: #b9c3d1; }
.doc-text:focus { outline: 2px solid var(--navy); outline-offset: -1px;
  border-color: var(--navy); }
.doc-text:disabled { background: #f4f5f7; color: var(--muted); }
.doc-line.is-auto { background: #f4f8fd; }
.auto-chip { display: none; margin-top: 2px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: #16304f;
  background: #dbe7f6; border-radius: 3px; padding: 1px 6px; cursor: help; }
.doc-line.is-auto .auto-chip { display: inline-block; }
.auto-chip.inline { display: inline-block; margin: 0; }

/* Terms: ONE editable block. A textarea can't colour its own text, so a
   transparent textarea sits exactly on top of a backdrop that renders the
   same string with the quote's own values marked. Both MUST keep identical
   font, padding, border and wrapping or the highlight drifts off the words. */
.terms-editor { position: relative; }
.terms-backdrop, .terms-full {
  font: inherit; font-size: 14px; line-height: 1.6;
  padding: 12px 14px; border: 1px solid var(--rule); border-radius: 6px;
  white-space: pre-wrap; overflow-wrap: break-word; word-break: normal;
  margin: 0; letter-spacing: normal;
}
.terms-backdrop {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  background: #fff; color: transparent; pointer-events: none;
}
.terms-full {
  position: relative; z-index: 1; display: block; width: 100%;
  background: transparent; color: var(--ink); caret-color: var(--navy);
  resize: none; overflow: hidden;
}
.terms-full:focus { outline: 2px solid var(--navy); outline-offset: -1px; }
.terms-full:disabled { color: var(--muted); }
.terms-editor.locked .terms-backdrop { background: #f4f5f7; }
mark.tok { background: #fdf0c8; color: transparent; border-radius: 3px; }
mark.tok.missing { background: #f8d7da; }
.terms-foot { display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-top: var(--s3); font-size: 13px; }
.terms-foot .t-apply { margin-left: auto; }
.terms-foot .t-apply:disabled { opacity: .45; cursor: default; }

/* ---- services & vocabulary admin ---- */
.wide-hint { max-width: 70ch; margin-bottom: var(--s5); }
.vocab-row { padding: var(--s4) 0; border-top: 1px solid var(--rule); }
.vocab-row:first-of-type { border-top: none; }
.vocab-row .grid-2 { margin-bottom: var(--s3); }
.vocab-head { display: flex; align-items: center; gap: var(--s4);
  flex-wrap: wrap; margin-bottom: var(--s3); }
.vocab-head .row-actions { margin-left: auto; display: flex; gap: var(--s2); }
.vocab-code { background: #eef1f5; color: var(--navy); border-radius: 4px;
  padding: 3px 9px; font-size: 13px; font-weight: 700; }
.vocab-table { table-layout: auto; }
.vocab-table th { border-bottom: 1px solid var(--rule); padding-bottom: 6px; }
.vocab-table td { padding: 5px 6px; vertical-align: middle; }
.vocab-table td code { font-size: 12.5px; font-weight: 700; color: var(--navy); }
.vocab-table .col-ord { width: 78px; }
.vocab-table .col-on { width: 72px; text-align: center; }
.vocab-table .col-on input { width: auto; }
.vocab-table .nowrap { white-space: nowrap; display: flex; gap: 4px;
  align-items: center; }
.vocab-table .add-row { background: #f7f9fc; }
.vocab-table .add-row td { padding-top: 10px; }
.sentence-samples { list-style: none; padding: 0; margin: var(--s3) 0 0; }
.sentence-samples li { padding: 8px 0; border-top: 1px dashed var(--rule);
  font-size: 14px; }
.sentence-samples .caption { color: var(--navy); }

/* ---- who-gets-notified card (/notifications) ---- */
.recip-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s4); }
.recip-block { border: 1px solid var(--rule); border-radius: var(--radius-sm);
  padding: var(--s3) var(--s4); background: #fff; }
.recip-block h4 { margin: 0 0 var(--s2); font-size: 13px; color: var(--navy); }
.recip-list { list-style: none; margin: 0 0 var(--s2); padding: 0; }
.recip-list li { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s2); padding: 3px 0; font-size: 13.5px; border-bottom: 1px dashed var(--rule); }
.recip-list li:last-child { border-bottom: none; }
.recip-add { display: flex; gap: var(--s2); }
.recip-add input { flex: 1; min-width: 0; font: inherit; padding: 6px 9px;
  border: 1px solid var(--rule); border-radius: 5px; }
.recip-add .btn-add { margin-top: 0; }
.log-head { font-size: 13px; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--navy); margin: var(--s5) 0 var(--s2); }

/* 4-up field row (customer city/state/zip/phone) */
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s3);
  align-items: start; }


/* ---- instant tooltips ([data-tip]) ----
   Native title= tooltips need a second of a perfectly still pointer and are
   clipped inside scroll containers — these show immediately, positioned by
   JS (request_form.js) with position:fixed so no overflow box can cut them. */
.tip-bubble {
  position: fixed; z-index: 2000; max-width: 320px;
  background: var(--ink); color: #fff; font-size: 12.5px; line-height: 1.45;
  padding: 8px 11px; border-radius: 6px; box-shadow: 0 6px 24px rgba(0,0,0,.25);
  pointer-events: none; text-transform: none; letter-spacing: normal;
  font-weight: 400; white-space: normal;
}


/* Kat's pricing-complete signal at the foot of stage 2 */
.pricing-done-bar { display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-top: var(--s4); padding-top: var(--s4);
  border-top: 2px solid var(--rule); }
.pricing-done-bar button:disabled { opacity: .5; cursor: default; }
