/* ============================================================
   Foundry Webtools: order page
   Page styles; app rules are scoped to .fop-app. Lexend Deca throughout.
   Dark theme: ProfitPad Foundry's navy and blue (the tokens below, from
   profitpad_foundry/public/css/foundry.bundle.css); light theme: the
   HubSpot look (html[data-theme="light"], further down). Desktop: dense
   order grid. Phone (<768px): cards per line, sticky action bar.
   ============================================================ */

html, body { margin: 0; min-height: 100%; }
body {
  min-height: 100vh;
  background: var(--page-bg);
}

/* Colour tokens sit on :root (not .fop-app) because the Flatpickr calendar
   is appended to <body>, outside the app. These are the dark values; the light
   theme overrides them under html[data-theme="light"] at the end of this
   file (theme picked in the page <head>, toggled from the user menu). */
:root {
  /* Foundry dark: page navy-900, cards navy-850, dialogs and inputs
     navy-800, text #f2f5f7, muted #97a7c6, accent #0062ff, links #6aa3ff.
     The token names are the original ones: --gold is the accent (blue
     here), --gold-lt the accent as text (links, totals). */
  --page-bg:   #011028;
  --navy:      #0b2042;
  --navy-mid:  #10294f;
  --navy-dark: #011028;
  --gold:      #0062ff;
  --gold-lt:   #6aa3ff;
  --white:     #ffffff;
  --text:      #f2f5f7;
  --muted:     #97a7c6;
  /* The accent is reserved for the primary action, focus / active states
     and the order total. Card, grid and button borders are navy lines. */
  --steel:     #213a66;
  --border:    #18305a;
  --line:      #18305a;
  --card-bg:   #061834;
  --input-bg:  #0b2042;
  --row-hover: rgba(0, 98, 255, 0.08);
  --success:   #3ecf8e;
  --warning:   #f0c46a;
  --error:     #ff5f5f;
  /* Theme-dependent surfaces and text. --white is the heading / strong text
     colour (dark slate in light); --on-gold is text on accent buttons and
     badges. --accent-rgb and --deep-rgb feed the translucent tints. */
  --accent-rgb:   0, 98, 255;
  --deep-rgb:     1, 16, 40;
  --on-gold:      #ffffff;
  --panel:        #0b2042;
  --panel-hi:     #0b2042;
  --surface:      #061834;
  --surface-head: #0b2042;
  --chip-bg:      #011028;
  --alt-row:      rgba(255, 255, 255, .025);
  --tint-bg:      rgba(0, 98, 255, .08);
  --tint-text:    #d3dbeb;
  --tint-label:   #b3c0da;
  --shadow:       rgba(0, 0, 0, .5);
  --overlay:      rgba(1, 9, 22, .75);
  --err-text:     #ffd2d2;
  --warn-text:    #fbe7bd;
  --ok-text:      #c9f5e2;
  --danger-text:  #ffb3b3;
  color-scheme: dark;
}

.fop-app {
  font-family: 'Lexend Deca', sans-serif;
  font-size: 15px;
  color: var(--text);
  padding: 24px 16px 96px;
}

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

.fop-wrap { max-width: 1280px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; }
.fop-wrap--narrow { max-width: 640px; }
/* Orders list: wider so the Bill to / Ship to cards have room for the
   address beside Terms and Credit limit (2026-10-19, on request). */
.fop-wrap--orders { max-width: 960px; }

.fop-kicker {
  font-family: 'Lexend Deca', sans-serif;
  font-size: 13px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted);
}
.fop-h1 {
  margin: 2px 0 0;
  font-family: 'Lexend Deca', sans-serif;
  font-size: 34px; font-weight: 700; letter-spacing: .02em;
  color: var(--white);
}
.fop-h2 {
  margin: 0 0 12px;
  font-family: 'Lexend Deca', sans-serif;
  font-size: 24px; font-weight: 700; color: var(--white);
}

.fop-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.fop-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.fop-row--end { justify-content: flex-end; }
.fop-muted { color: var(--muted); }
.fop-block { display: block; }
.fop-num { text-align: right; font-variant-numeric: tabular-nums; }
.fop-warn-text { color: var(--warning); font-size: 13px; }

.fop-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px;
}

.fop-hint { margin-top: 10px; font-size: 13px; color: var(--muted); }

/* ── Badges, keys ── */
.fop-badge {
  display: inline-block; padding: 1px 7px;
  font-family: 'Lexend Deca', sans-serif; font-size: 13px; font-weight: 600; letter-spacing: .04em;
  color: var(--text); background: rgba(143, 164, 194, 0.12);
  border: 1px solid var(--border); border-radius: 4px;
}
.fop-key {
  display: inline-block; min-width: 20px; padding: 0 5px; margin-left: 4px;
  font: 600 11px/18px 'Lexend Deca', sans-serif; text-align: center;
  color: var(--muted); border: 1px solid var(--line); border-radius: 4px;
}
.fop-key--dark { color: var(--on-gold); border-color: rgba(var(--deep-rgb), .35); }

/* ── Buttons ── */
.fop-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 18px;
  font-family: 'Lexend Deca', sans-serif; font-size: 17px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; text-decoration: none;
  color: var(--on-gold); background: var(--gold);
  border: 1px solid var(--gold); border-radius: 6px;
  cursor: pointer;
}
/* Hover only where there is a real pointer: on a phone a tap leaves :hover
   stuck, so after Exit the button drawn in its place (Change customer) stayed
   lit. */
@media (hover: hover) {
  .fop-btn:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--gold-lt); }
}
/* Secondary buttons: steel outline, gold only on hover / focus. */
.fop-btn--ghost { color: var(--text); background: transparent; border-color: var(--steel); }
/* Same :not()s as the .fop-btn hover rule, so this one wins; with fewer, the
   solid gold background won and hid the gold label. */
@media (hover: hover) {
  .fop-btn--ghost:hover:not([disabled]):not([aria-disabled="true"]) { color: var(--gold-lt); border-color: var(--gold); background: rgba(var(--accent-rgb), 0.08); }
}
.fop-btn--sm { padding: 6px 12px; font-size: 14px; }
/* External-link icon after links that open a new tab (EXT_ICON in app.js). */
.fop-ext { width: .9em; height: .9em; flex: none; fill: currentColor; vertical-align: -.1em; }
.fop-btn[disabled], .fop-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.fop-app :focus-visible { outline: 2px solid var(--gold-lt); outline-offset: 2px; }

.fop-icon-btn {
  width: 28px; height: 28px; font-size: 18px; line-height: 1;
  color: var(--muted); background: none; border: 0; border-radius: 4px; cursor: pointer;
}
.fop-icon-btn:hover { color: var(--error); background: rgba(255, 95, 95, .1); }

/* ── Inputs ── */
.fop-label {
  display: block; margin-bottom: 5px;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
}
.fop-input {
  width: 100%; padding: 8px 10px;
  font: inherit; color: var(--white);
  background: var(--input-bg);
  border: 1px solid var(--line); border-radius: 5px;
}
.fop-input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .25); }
.fop-input--err { border-color: var(--error); }
.fop-input--override { color: var(--gold-lt); }
/* Custom chevron instead of the native arrow: a little further from the
   edge than the native one (8px), slightly bolder, same muted colour as the date fields' calendar
   icon (gold when focused). */
select.fop-input {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 38px;
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 14px 14px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fa4c2' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
select.fop-input:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236aa3ff' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
select.fop-input option, select.fop-input optgroup { color: #000; }
/* Notes start at about 1.5 lines (the half line hints there is room for
   more) and grow with their text (autosize() in app.js). */
textarea.fop-notes { display: block; min-height: calc(2.1em + 18px); line-height: 1.4; resize: none; overflow: hidden; }

/* ── Alerts ── */
.fop-alert { padding: 12px 14px; border-radius: 8px; border: 1px solid; font-size: 14px; }
.fop-alert--error   { color: var(--err-text); background: rgba(255, 95, 95, .12);  border-color: rgba(255, 95, 95, .45); }
.fop-alert--warning { color: var(--warn-text); background: rgba(240, 196, 106, .1); border-color: rgba(240, 196, 106, .45); }
.fop-alert--success { color: var(--ok-text); background: rgba(62, 207, 142, .1);  border-color: rgba(62, 207, 142, .45); }

/* ── Loading ── */
.fop-center { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 80px 0; color: var(--muted); }
.fop-spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(var(--accent-rgb), .2); border-top-color: var(--gold);
  animation: fop-spin .8s linear infinite;
}
.fop-dots { color: var(--muted); animation: fop-pulse 1s ease-in-out infinite; }
@keyframes fop-spin { to { transform: rotate(360deg); } }
@keyframes fop-pulse { 50% { opacity: .3; } }

/* ── Autocomplete ── */
.fop-ac { position: relative; }
.fop-ac__list {
  display: none; position: absolute; z-index: 50; left: 0; top: calc(100% + 4px);
  min-width: 100%; width: max-content; max-width: min(560px, 92vw); max-height: 300px; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 14px 40px var(--shadow);
}
.fop-ac__list--open { display: block; }
.fop-ac__item { padding: 8px 12px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fop-ac__item--active, .fop-ac__item:hover { background: rgba(var(--accent-rgb), .15); }
.fop-ac__msg { padding: 10px 12px; color: var(--muted); }

/* ── Customer summary + ship-to picker ── */
.fop-parties { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.fop-party {
  padding: 12px 16px 14px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.fop-party__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; margin-bottom: 6px; }
.fop-party__lbl {
  font-family: 'Lexend Deca', sans-serif; font-size: 13px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.fop-party__name { font-size: 17px; font-weight: 600; color: var(--white); margin-bottom: 4px; }
/* Top right of each card: the customer id tile (after the ship-to's
   "Change" link); the bill-to's price level follows the name. */
.fop-party__topr { display: flex; align-items: center; gap: 10px; }
/* Same size as the product id tile on phone line cards. */
.fop-party__topr .fop-badge { font-size: 14px; }
.fop-party__name .fop-level { margin-left: 2px; vertical-align: 1px; }
/* The address keeps at least 150px; when the corner (credit limit) does
   not fit beside it, the corner wraps below, still
   right-aligned, instead of squeezing the address or spilling out. */
.fop-party__addr { flex: 1 1 150px; min-width: 0; font-size: 14px; line-height: 1.45; color: var(--muted); }
.fop-party__body { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 8px 12px; }
.fop-party__body > .fop-party__corner, .fop-party__body > .fop-party__corners { margin-left: auto; }
.fop-party__corners { display: flex; align-items: flex-end; gap: 16px; }
.fop-party__corner { display: flex; flex-direction: column; align-items: flex-end; text-align: right; white-space: nowrap; }
/* Secondary labels are sentence case; caps are kept for section titles and
   grid column headers only. */
.fop-party__lbl2 { font-size: 13px; font-weight: 500; color: var(--muted); }
.fop-party__amt { font-family: 'Lexend Deca', sans-serif; font-size: 20px; font-weight: 700; color: var(--white); line-height: 1.1; font-variant-numeric: tabular-nums; }
.fop-linkbtn {
  padding: 0; font: 600 13px 'Lexend Deca', sans-serif; color: var(--gold-lt);
  background: none; border: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.fop-level {
  display: inline-block; padding: 1px 8px;
  font-family: 'Lexend Deca', sans-serif; font-size: 15px; font-weight: 700; letter-spacing: .04em;
  color: var(--on-gold); background: var(--gold); border-radius: 4px;
}

.fop-picklist { display: flex; flex-direction: column; gap: 6px; }
.fop-pick {
  display: flex; gap: 12px; align-items: flex-start; width: 100%; padding: 10px 12px;
  font: inherit; text-align: left; color: var(--text);
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.fop-pick:hover, .fop-pick:focus { border-color: var(--gold); background: var(--row-hover); outline: none; }
.fop-pick__num { width: 18px; color: var(--gold); font-weight: 700; }
/* A ship-to that isn't a HubSpot Ship-to Location: shown, not pickable. */
.fop-pick--off, .fop-pick--off:hover { opacity: .6; cursor: not-allowed; border-color: var(--line); background: var(--surface); }
/* place-order answered "still syncing": the note and its "Open it now" button. */
.fop-pending { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.fop-wait { font-size: 13px; }
.fop-pick__main { flex: 1; }

/* ── Order header ── */
.fop-head { background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px; }
.fop-head__sum {
  padding: 12px 16px;
  font-family: 'Lexend Deca', sans-serif; font-size: 17px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.fop-head__grid {
  display: grid; gap: 12px 14px; padding: 0 16px 16px;
  grid-template-columns: repeat(6, minmax(0, 1fr));
}
/* Header fields sit three to a row (each spans 2 of the 6 columns);
   --row starts a new row, so a short row leaves the rest empty. */
.fop-head__grid > .fop-field { grid-column: span 2; }
.fop-head__grid > .fop-field--row { grid-column: 1 / span 2; }
.fop-head__grid > .fop-field--end { grid-column: 5 / span 2; }
.fop-field--half, .fop-head__grid > .fop-field--half { grid-column: span 3; }
.fop-field--full, .fop-head__grid > .fop-field--full { grid-column: 1 / -1; }
/* A half-width field that starts its row (shipping instructions). */
.fop-head__grid > .fop-field--half.fop-field--row { grid-column: 1 / span 3; }

/* ── Line chart ── */
.fop-grid { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); font-variant-numeric: tabular-nums; }
.fop-line {
  display: grid; align-items: center;
  grid-template-columns: 36px 150px minmax(160px, 1fr) 120px 110px 100px 110px 64px 64px 36px;
  border-top: 1px solid var(--line);
}
.fop-line:first-child, .fop-lines-lbl + .fop-line { border-top: 0; }
/* "Lines" title: phones on a locked order only (see the phone pass). */
.fop-lines-lbl { display: none; }
/* Alternating line shading (every second line). */
.fop-line--alt { background: var(--alt-row); }
.fop-line:not(.fop-line--head):focus-within { background: var(--row-hover); box-shadow: inset 3px 0 0 var(--gold); }
.fop-line--head {
  font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  background: var(--surface-head); border-radius: 10px 10px 0 0;
}
.fop-line--head .fop-cell--qty,
.fop-line--head .fop-cell--price,
.fop-line--head .fop-cell--cost,
.fop-line--head .fop-cell--ext,
.fop-line--head .fop-cell--stock { text-align: right; }
.fop-cell { padding: 6px 8px; min-width: 0; }
.fop-cell--num { color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.fop-cell--desc { font-size: 14px; overflow: hidden; text-overflow: ellipsis; }
.fop-line--head .fop-cell--desc { font-size: inherit; }
.fop-cell--del { text-align: center; }
/* Read-only columns are muted; the editable ones (qty, unit price) stay white. */
.fop-cell--cost, .fop-cell--ext { color: var(--muted); }
.fop-grid .fop-input { padding: 6px 8px; border-color: transparent; background: transparent; }
.fop-grid .fop-input:hover { border-color: var(--line); }
.fop-grid .fop-input:focus { background: var(--input-bg); border-color: var(--gold); }
.fop-grid .fop-num { text-align: right; }
/* Desktop: the editable cells (product, qty, unit price) drop their own
   padding so the input text sits 8px from the cell edge, the same as the
   plain cells and the column headers. Digits then line up down each column. */
@media (min-width: 768px) {
  .fop-grid .fop-cell--product { padding-left: 0; }
  .fop-grid .fop-cell--qty,
  .fop-grid .fop-cell--price { padding-left: 0; padding-right: 0; }
  .fop-grid .fop-input { padding-left: 7px; padding-right: 7px; }
}
.fop-mlabel { display: none; }
/* Product id tile on read-only lines: phones only (desktop has the column). */
.fop-line__id { display: none; }
/* Product id tile on editable lines with a product (fop-cell--tiled). The
   product box stays focusable but out of sight, so arrows and Tab still
   reach it; focusing it removes the tile (tileProduct in app.js). */
.fop-pid { display: none; margin: 4px 0 4px 7px; font-size: 14px; cursor: pointer; }
.fop-pid:hover { border-color: var(--gold); }
/* inline-flex, not inline-block: a wrapped id (two lines) then aligns on its
   first line, so the desktop baseline row doesn't push the other cells down. */
.fop-cell--tiled .fop-pid { display: inline-flex; }
.fop-cell--tiled .fop-ac {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
/* "No lines on this order." on a locked order with no lines (every width). */
.fop-grid .fop-line--empty { display: block; }
.fop-line--empty .fop-cell { padding: 14px 12px; }
/* "Add line comment" (inline strip): phones only, while the box is folded. */
.fop-addcmt { display: none; }

.fop-qty { display: flex; align-items: center; }
.fop-step { display: none; }

.fop-stock { display: inline-block; min-width: 30px; padding: 1px 6px; border-radius: 4px; font-weight: 600; text-align: center; }
.fop-stock--ok   { color: var(--success); background: rgba(62, 207, 142, .12); }
.fop-stock--low  { color: var(--warning); background: rgba(240, 196, 106, .12); }
.fop-stock--none { color: var(--error);   background: rgba(255, 95, 95, .12); }

.fop-gridtools { gap: 8px; }
/* Under the lines: grid buttons left, totals summary box right. */
/* 8px under the lines (the column's 16px gap less 8). */
.fop-gridfoot { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-top: -8px; }
.fop-sum {
  width: 340px; max-width: 100%; margin-left: auto;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  font-variant-numeric: tabular-nums;
}
.fop-sum__row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 14px; border-top: 1px solid var(--line); }
.fop-sum__row:first-child { border-top: 0; }
.fop-sum__lbl { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.fop-sum__val { text-align: right; }
.fop-confirm-freight { font-size: 15px; color: var(--muted); }
.fop-sum__row--total { border-top: 2px solid var(--steel); padding: 10px 14px; }
.fop-sum__row--total .fop-sum__lbl { font-size: 13px; color: var(--text); }
.fop-sum__row--total .fop-sum__val { font-family: 'Lexend Deca', sans-serif; font-size: 22px; font-weight: 700; color: var(--gold-lt); }
.fop-sum__cost { display: block; font-family: 'Lexend Deca', sans-serif; font-size: 13px; font-weight: 400; color: var(--muted); }
@media (max-width: 767px) { .fop-sum { width: 100%; } }
.fop-btn--on { background: rgba(143, 164, 194, 0.16); }

/* Stock + qty breaks sit together in one slightly tinted panel under the
   focused line: stock strip is the top half, breaks the bottom. */
.fop-stockstrip {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 12px 0 44px;
  padding: 6px 12px;
  font-size: 13px;
  color: var(--tint-text);
  background: var(--tint-bg);
}
.fop-stockstrip[data-cell="strip"] { border-radius: 8px 8px 0 0; padding-top: 8px; }
.fop-stockstrip[data-cell="breaks"] { border-radius: 0 0 8px 8px; padding-bottom: 8px; margin-bottom: 10px; }
.fop-stockstrip[hidden] { display: none; }
.fop-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 4px 2px 8px; border: 1px solid var(--line); border-radius: 999px;
}
.fop-chip__br { color: var(--muted); }
/* Qty break chips end in plain text (no stock badge), so even padding. */
.fop-chip--break { padding-right: 8px; }
.fop-strip__lbl {
  align-self: center; min-width: 76px;
  font-size: 13px; font-weight: 600; color: var(--muted);
}
.fop-stockstrip .fop-chip { border-color: var(--steel); background: var(--chip-bg); }
.fop-stockstrip .fop-chip--ship { border-color: var(--gold); }
.fop-stockstrip .fop-strip__lbl { color: var(--tint-label); }
.fop-chip--ship { border-color: var(--gold); }
.fop-chip--ship .fop-chip__br { color: var(--gold-lt); }

/* ── Action bar ── */
.fop-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  font-variant-numeric: tabular-nums;
}
.fop-total { font-family: 'Lexend Deca', sans-serif; font-size: 22px; color: var(--gold-lt); }
.fop-legend { margin-top: -6px; padding: 0 4px; font-size: 12px; color: var(--muted); }
.fop-legend .fop-key { margin: 0 2px 0 8px; }
.fop-bar__actions { display: flex; gap: 10px; }

/* ── Confirm dialog ── */
.fop-modal {
  /* Above the sign-in chip (auth.js, z-index 9000), below the gate (9999).
     safe center: a box taller than the screen starts at the top instead of
     being cut off above it. */
  position: fixed; inset: 0; z-index: 9500; display: flex; align-items: safe center; justify-content: center;
  padding: 16px; background: var(--overlay);
}
.fop-modal__box {
  box-sizing: border-box; /* max-height includes the padding, so the bottom stays on screen */
  width: 100%; max-width: 640px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto;
  padding: 22px; background: var(--panel-hi); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 30px 80px var(--shadow);
  display: flex; flex-direction: column; gap: 14px;
}
.fop-confirm-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 18px; font-size: 14px; }
.fop-confirm-meta span { display: inline-block; min-width: 76px; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; }
.fop-confirm-total { text-align: right; font-family: 'Lexend Deca', sans-serif; font-size: 22px; color: var(--gold-lt); }
.fop-table-wrap { overflow-x: auto; }
.fop-table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.fop-table th { padding: 6px 8px; text-align: left; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--line); }
.fop-table td { padding: 6px 8px; border-bottom: 1px solid var(--line); }

/* ── Phone ── */
@media (max-width: 767px) {
  .fop-app { padding: 16px 16px 120px; font-size: 16px; }
  .fop-h1 { font-size: 28px; }
  .fop-head__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fop-parties { grid-template-columns: 1fr; }
  .fop-head__grid > .fop-field, .fop-head__grid > .fop-field--row, .fop-head__grid > .fop-field--end { grid-column: auto; }
  .fop-field--half, .fop-head__grid > .fop-field--half { grid-column: span 2; }
  .fop-head__grid > .fop-field--full { grid-column: 1 / -1; }

  .fop-grid { border: 0; background: none; display: flex; flex-direction: column; gap: 10px; }
  .fop-line--head { display: none; }
  .fop-line {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "product product"
      "desc    desc"
      "qty     price"
      "cost    ext"
      "avail   total"
      "del     del";
    gap: 2px 10px; padding: 10px 6px 8px;
    background: var(--card-bg); border: 1px solid var(--border); border-radius: 10px;
  }
  .fop-line:first-child { border-top: 1px solid var(--border); }
  .fop-cell--num { display: none; }
  .fop-cell--product { grid-area: product; }
  .fop-cell--desc { grid-area: desc; white-space: normal; color: var(--white); }
  .fop-cell--qty { grid-area: qty; }
  .fop-cell--price { grid-area: price; }
  .fop-cell--cost { grid-area: cost; text-align: left; }
  .fop-cell--ext { grid-area: ext; text-align: right; }
  .fop-line [data-cell="avail"] { grid-area: avail; text-align: left; }
  .fop-line [data-cell="total"] { grid-area: total; text-align: right; color: var(--muted); font-size: 13px; }
  .fop-cell--del { grid-area: del; text-align: right; }
  .fop-stockstrip { margin: 0 2px; padding: 6px 8px; }
  .fop-stockstrip[data-cell="strip"] { margin-top: 6px; }
  .fop-stockstrip[data-cell="breaks"] { margin-bottom: 2px; }

  .fop-mlabel { display: inline; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
  label.fop-mlabel { display: block; margin-bottom: 3px; }
  .fop-grid .fop-input { padding: 10px; font-size: 16px; background: var(--input-bg); border-color: var(--line); }
  .fop-grid .fop-cell--price .fop-num { text-align: left; }

  .fop-step {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 44px; height: 44px; font-size: 22px; color: var(--gold-lt);
    background: rgba(var(--accent-rgb), .12); border: 1px solid var(--border); cursor: pointer;
  }
  .fop-step:first-child { border-radius: 6px 0 0 6px; }
  .fop-step:last-child { border-radius: 0 6px 6px 0; }
  .fop-qty .fop-input { border-radius: 0; text-align: center; height: 44px; }

  /* Product search drops down right under the product box, as wide as the
     box (it was a bottom sheet, which opened far from the box and covered
     the action bar). Above the action bar (z-index 50 vs 40). */
  .fop-grid .fop-ac__list {
    width: 100%; max-width: none; max-height: 45vh;
  }
  .fop-ac__item { padding: 12px 14px; white-space: normal; }

  .fop-legend { display: none; }
  .fop-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    border-radius: 0; border-width: 1px 0 0; padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  }
  .fop-bar__totals { width: 100%; }
  .fop-bar__actions { width: 100%; }
  .fop-bar__actions .fop-btn { flex: 1; justify-content: center; }
  .fop-bar .fop-key, .fop-gridtools .fop-key, .fop-modal .fop-key { display: none; }
  .fop-confirm-meta { grid-template-columns: 1fr; }
}

/* ── Flatpickr calendar (ship / required date) ──
   Ported from the camo-cpq quote expiration picker and re-themed navy and
   gold. Loaded after vendor/flatpickr.min.css so these rules win. The
   calendar is appended to <body>, outside .fop-app, which is why the colour
   tokens live on :root. */
/* Calendar icon on the right of the date fields (the native date input
   had one; Flatpickr's text input doesn't). Muted by default, gold on focus. */
.fop-date-alt {
  cursor: pointer;
  padding-right: 38px;
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fa4c2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M3 9.5h18M8 2.5v4M16 2.5v4'/%3E%3C/svg%3E");
}
.fop-date-alt[readonly] { background-color: var(--input-bg); }
.fop-date-alt:focus,
.fop-date-alt.active {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236aa3ff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M3 9.5h18M8 2.5v4M16 2.5v4'/%3E%3C/svg%3E");
}

/* No padding or border on the outer box: when flatpickr opens the
   calendar above the field it positions it by the summed height of its
   children only, so outer padding/border made it overlap the input. The
   spacing lives on .flatpickr-months / .flatpickr-innerContainer instead,
   and the outline is a box-shadow, which takes no space. */
.flatpickr-calendar {
  font-family: 'Lexend Deca', sans-serif;
  background: var(--panel-hi);
  border: 0;
  border-radius: 0.75rem;
  box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.35), 0 18px 50px var(--shadow);
  padding: 0;
}
.flatpickr-innerContainer { padding-bottom: 0.75rem; }
.flatpickr-calendar.arrowTop:before { border-bottom-color: rgba(var(--accent-rgb), 0.35); }
.flatpickr-calendar.arrowTop:after  { border-bottom-color: var(--panel-hi); }
.flatpickr-calendar.arrowBottom:before { border-top-color: rgba(var(--accent-rgb), 0.35); }
.flatpickr-calendar.arrowBottom:after  { border-top-color: var(--panel-hi); }

/* Padding without touching widths (flatpickr sizes the calendar from the
   fixed .dayContainer width; see the camo-cpq notes). */
.flatpickr-weekdays,
.dayContainer { padding: 0 0.75rem; box-sizing: border-box; }
.flatpickr-months { padding: 0.75rem 0.75rem 0; box-sizing: border-box; }
/* The prev/next arrows are absolutely positioned at top: 0 of
   .flatpickr-months; shift them down by the new top padding. */
.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month { top: 0.75rem; }

.flatpickr-months .flatpickr-month,
.flatpickr-current-month .flatpickr-monthDropdown-months,
.flatpickr-current-month input.cur-year {
  color: var(--white);
  fill: var(--white);
  font-family: 'Lexend Deca', sans-serif;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.flatpickr-current-month .flatpickr-monthDropdown-months { background: var(--panel-hi); }
.flatpickr-current-month .flatpickr-monthDropdown-months option { background: var(--panel); color: var(--white); }
.flatpickr-current-month .flatpickr-monthDropdown-months:hover,
.numInputWrapper:hover { background: rgba(var(--accent-rgb), 0.12); }
.numInputWrapper span.arrowUp:after { border-bottom-color: var(--gold-lt); }
.numInputWrapper span.arrowDown:after { border-top-color: var(--gold-lt); }

.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month { color: var(--muted); fill: var(--muted); }
.flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-months .flatpickr-next-month:hover svg { fill: var(--gold-lt); }

span.flatpickr-weekday {
  color: var(--muted);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.flatpickr-day {
  color: var(--text);
  border-radius: 9999px;
}
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay { color: rgba(143, 164, 194, 0.45); }
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.flatpickr-disabled:hover { color: rgba(143, 164, 194, 0.3); background: none; border-color: transparent; }
.flatpickr-day:hover,
.flatpickr-day:focus {
  background: rgba(var(--accent-rgb), 0.15);
  border-color: rgba(var(--accent-rgb), 0.15);
}
.flatpickr-day.today { border-color: var(--gold); color: var(--gold-lt); }
.flatpickr-day.today:hover,
.flatpickr-day.today:focus { background: rgba(var(--accent-rgb), 0.2); border-color: var(--gold); color: var(--white); }
.flatpickr-day.selected,
.flatpickr-day.selected:hover,
.flatpickr-day.selected:focus,
.flatpickr-day.selected.prevMonthDay,
.flatpickr-day.selected.nextMonthDay {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-gold);
  font-weight: 600;
  box-shadow: none;
}

/* ── Side layout (index.html, default): stock + qty breaks box right of the lines ── */
.fop-wrap--sideopen { max-width: 1640px; }
.fop-split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.fop-split--closed { grid-template-columns: minmax(0, 1fr); }
.fop-split__main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.fop-side {
  position: sticky; top: 16px;
  max-height: calc(100vh - 32px); overflow-y: auto;
  /* Scrolls on its own: reaching the end does not hand the scroll to the page. */
  overscroll-behavior: contain;
  padding: 12px 14px 14px;
  background: var(--tint-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--tint-text); font-size: 15px; font-variant-numeric: tabular-nums;
}
.fop-side__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.fop-side__line { position: relative; padding: 12px 10px 2px; margin: 0 -10px; border: 1px solid transparent; border-radius: 8px; }
/* Divider above each product's name (between products in the card).
   It sits on the line's top border: 14px above it (4 section padding +
   2 line padding + 1 border + 7 margin), 12px below (line padding-top). */
.fop-side__line::before {
  content: ""; position: absolute; left: 10px; right: 10px; top: -1px;
  border-top: 1px solid var(--line);
}
.fop-side__line + .fop-side__line { margin-top: 7px; }
/* No divider above the first product (the card title is already there). */
.fop-side__head + .fop-side__line::before { display: none; }
.fop-side__line--active { border-color: var(--gold); background: rgba(var(--accent-rgb), 0.06); }
.fop-side__item { font-weight: 600; color: var(--white); margin-bottom: 2px; }
.fop-side__desc { font-weight: 400; color: var(--white); }
.fop-side__empty { padding: 4px 0 2px; }
/* No "All" column in the side layout. */
.fop-grid--noall .fop-line { grid-template-columns: 36px 150px minmax(160px, 1fr) 120px 110px 100px 110px 64px 36px; }
@media (max-width: 767px) {
  .fop-grid--noall .fop-line { grid-template-columns: 1fr 1fr; }
}
.fop-side__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 2px; }
.fop-side__sec { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px 0 4px; min-width: 0; }
.fop-side__sec .fop-chip { max-width: 100%; }
.fop-side__sec .fop-strip__lbl { width: 100%; font-size: 14px; }
.fop-side .fop-chip { border-color: var(--steel); background: var(--chip-bg); }
.fop-side .fop-chip--ship { border-color: var(--gold); }
@media (max-width: 1199px) {
  .fop-split { grid-template-columns: minmax(0, 1fr); }
  .fop-side { position: static; }
}

/* ── Existing order (?order) or quote (?deal) ──
   Status badge beside the name, an info note, read-only header (and lines
   once picking starts), the red Cancel button and its dialog. */
.fop-status {
  display: inline-block; margin-left: 8px; padding: 2px 9px; vertical-align: middle;
  font-family: 'Lexend Deca', sans-serif; font-size: 15px; font-weight: 700; letter-spacing: .04em;
  color: var(--text); background: rgba(143, 164, 194, 0.16); border: 1px solid var(--steel); border-radius: 4px;
}
/* Status colours (statusClass() in app.js): Delivered / Completed green,
   Closed red, Partly Picked / Partly Shipped orange, Quote in the accent;
   the rest (To Pick, Picked, To Deliver) stay neutral. */
.fop-status--done    { color: var(--ok-text); border-color: rgba(62, 207, 142, .45); background: rgba(62, 207, 142, .1); }
.fop-status--cancel  { color: var(--err-text); border-color: rgba(255, 95, 95, .45); background: rgba(255, 95, 95, .12); }
.fop-status--quote   { color: var(--gold-lt); border-color: var(--gold); background: rgba(var(--accent-rgb), .1); }
.fop-status--partial { color: #f7b27a; border-color: rgba(245, 150, 70, .5); background: rgba(245, 150, 70, .12); }
html[data-theme="light"] .fop-status--partial { color: #a14d00; border-color: rgba(214, 110, 20, .5); background: rgba(245, 150, 70, .12); }
.fop-alert--info { color: var(--text); background: rgba(143, 164, 194, 0.08); border-color: var(--steel); }
/* Locked header (existing order): every box (selects, date fields, text
   inputs, notes, the read-only order info) looks the same: the normal
   input background and text colour, icons kept (background-color only, so
   the chevron / calendar images stay), with a not-allowed cursor. */
.fop-input:disabled { cursor: not-allowed; }
.fop-head--locked .fop-input,
.fop-head .fop-input:disabled,
.fop-head--locked .fop-date-alt[readonly] {
  color: var(--text); background-color: var(--input-bg);
  opacity: 1; -webkit-text-fill-color: var(--text); cursor: not-allowed;
}
/* Locked header: no dropdown chevron on Ship via and no calendar icon on
   the date, since neither opens. */
.fop-head--locked select.fop-input,
.fop-head--locked select.fop-input:focus,
.fop-head--locked .fop-date-alt,
.fop-head--locked .fop-date-alt:focus,
.fop-head--locked .fop-date-alt.active { background-image: none; padding-right: 10px; }
.fop-grid-in[readonly] { color: var(--text); background: transparent; border-color: transparent; }
.fop-grid-in[readonly]:focus { border-color: var(--steel); box-shadow: none; }
.fop-btn--danger { color: var(--danger-text); background: transparent; border-color: rgba(255, 95, 95, .45); }
@media (hover: hover) {
  .fop-btn--danger:hover:not([disabled]):not([aria-disabled="true"]) { color: var(--err-text); background: rgba(255, 95, 95, .12); border-color: var(--error); }
}
.fop-btn--danger-solid { color: #ffffff; background: #c43c3c; border-color: #c43c3c; }
@media (hover: hover) {
  .fop-btn--danger-solid:hover:not([disabled]):not([aria-disabled="true"]) { background: #d94b4b; }
}
.fop-modal__box--sm { max-width: 460px; }
.fop-cancel-desc { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text); }
.fop-row--removed td { color: var(--muted); text-decoration: line-through; }
.fop-row--removed td:last-child { text-decoration: none; }
.fop-bar__actions { align-items: center; }
.fop-lastmod { font-size: 13px; color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.fop-lastmod__lbl { margin-right: 6px; color: var(--muted); }
@media (max-width: 767px) { .fop-lastmod { width: 100%; } .fop-bar__actions { flex-wrap: wrap; } }

/* ── Title row of an existing order or quote: Exit beside the title, a
   rule under it. ── */
.fop-top--rule { border-bottom: 1px solid var(--steel); padding-bottom: 12px; }
/* Wide dialog box (the quote). */
.fop-modal__box--wide { max-width: 1100px; }
.fop-tools__end { gap: 8px; }

/* ── Orders list ── */
/* Thin steel scrollbar in its own gutter, 8px clear of the order cards'
   right edge, so it never sits on their borders. */
.fop-orders {
  display: flex; flex-direction: column; gap: 6px; max-height: 60vh; overflow-y: auto;
  padding-right: 8px; scrollbar-gutter: stable; scrollbar-width: thin; scrollbar-color: var(--steel) transparent;
}
.fop-order {
  display: flex; flex-direction: column; gap: 4px; width: 100%; padding: 10px 12px;
  font: inherit; text-align: left; color: var(--text);
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.fop-order:hover, .fop-order:focus { border-color: var(--gold); background: var(--row-hover); outline: none; }
.fop-order--open { border-color: var(--steel); }
.fop-order__top, .fop-order__mid { display: flex; align-items: baseline; gap: 6px; }
.fop-order__date, .fop-order__total { margin-left: auto; font-variant-numeric: tabular-nums; }
.fop-order__mid { font-size: 13px; }
.fop-order__total { color: var(--text); }
.fop-order__stage { display: flex; gap: 6px; flex-wrap: wrap; }
.fop-status--sm { margin-left: 0; padding: 0 6px; font-size: 13px; }
.fop-center--sm { padding: 24px 0; }

/* Delivery notes on an existing order: one small card per note, linking to
   Foundry. */
.fop-dns { display: flex; flex-wrap: wrap; gap: 8px; }
.fop-dn {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; font-size: 14px;
  color: var(--text); text-decoration: none;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 6px;
}
.fop-dn:hover { border-color: var(--gold); }
.fop-dn__name { display: inline-flex; align-items: center; gap: .3em; color: var(--gold-lt); font-weight: 600; }


.fop-cell--desc .fop-block { font-size: 13px; overflow: hidden; text-overflow: ellipsis; }

/* ── Line comments and the details layout (2026-10-19) ── */
/* Inline layout: stock, qty breaks and the comment form one panel under the
   focused line; the comment strip is its bottom half now. */
.fop-stockstrip[data-cell="breaks"] { border-radius: 0; padding-bottom: 6px; margin-bottom: 0; }
.fop-stockstrip--comment { align-items: flex-start; border-radius: 0 0 8px 8px; padding-bottom: 8px; margin-bottom: 10px; }
.fop-stockstrip--solo { border-radius: 8px; padding-top: 8px; }
/* Line comments off (LINE_COMMENTS in app.js): the breaks strip ends the panel. */
.fop-stockstrip[data-cell="breaks"].fop-stockstrip--last { border-radius: 0 0 8px 8px; padding-bottom: 8px; margin-bottom: 10px; }
@media (max-width: 767px) { .fop-stockstrip[data-cell="breaks"].fop-stockstrip--last { margin-bottom: 2px; } }
.fop-stockstrip--comment .fop-strip__lbl { align-self: flex-start; padding-top: 6px; }
/* Inline layout: clicking a description jumps to that line's comment. */
.fop-grid:not(.fop-grid--noall) .fop-line[data-row] .fop-cell--desc { cursor: text; }
.fop-stockstrip--comment > .fop-muted { align-self: center; }
.fop-line-comment {
  display: block; flex: 1; min-width: 200px; min-height: calc(1.4em + 14px);
  padding: 6px 8px; font-size: 14px; line-height: 1.4; resize: none; overflow: hidden;
}
.fop-grid .fop-stockstrip .fop-line-comment { background: var(--input-bg); border-color: var(--line); }
.fop-grid .fop-stockstrip .fop-line-comment:focus { border-color: var(--gold); }
@media (max-width: 767px) {
  .fop-stockstrip[data-cell="breaks"] { margin-bottom: 0; }
  .fop-stockstrip--comment { margin-bottom: 2px; }
  .fop-line-comment { min-width: 0; width: 100%; font-size: 16px; }
}

/* Details layout: no All column; the last column holds the Details button
   and the × side by side. */
.fop-grid--details .fop-line { grid-template-columns: 36px 150px minmax(160px, 1fr) 120px 110px 100px 110px 64px 64px; }
.fop-grid--details .fop-cell--del { display: flex; justify-content: flex-end; align-items: center; gap: 2px; padding-left: 0; padding-right: 4px; }
@media (max-width: 767px) {
  .fop-grid--details .fop-line { grid-template-columns: 1fr 1fr; }
}
.fop-detail-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.fop-detail-btn svg { width: 16px; height: 16px; }
.fop-detail-btn:hover { color: var(--gold-lt); background: rgba(var(--accent-rgb), .12); }
/* A line with a comment: gold icon with a small dot. */
.fop-detail-btn--has { color: var(--gold-lt); }
.fop-detail-btn--has::after {
  content: ""; position: absolute; top: 4px; right: 3px; width: 6px; height: 6px; border-radius: 50%; background: var(--gold);
}

/* Line details dialog: stock (left) and qty breaks (right), then the comment. */
.fop-details__desc { margin-top: -6px; color: var(--white); }
.fop-details__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.fop-details .fop-chip { border-color: var(--steel); background: var(--chip-bg); }
.fop-details .fop-chip--ship { border-color: var(--gold); }
.fop-details__comment .fop-line-comment { width: 100%; min-height: calc(4.2em + 14px); }
/* Qty, unit price, unit cost, ext in one row (two per row on phones). Stock
   and qty breaks stay side by side at every width. */
.fop-details__nums { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; font-variant-numeric: tabular-nums; }
.fop-details__nums .fop-input { text-align: right; }
.fop-details__val { padding: 9px 11px 9px 0; text-align: right; color: var(--muted); }
.fop-details .fop-mlabel { display: none; }
@media (max-width: 767px) {
  .fop-details__nums { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.fop-confirm-comment { font-size: 13px; white-space: pre-wrap; }
/* A saved line's comment under its description. */
.fop-line-notes { display: block; margin-top: 2px; }
.fop-line-note { display: block; font-size: 13px; line-height: 1.35; color: var(--muted); white-space: pre-line; overflow-wrap: anywhere; }

/* Inline strip: every label (Inventory, Quantity breaks, Line comment) in one
   fixed-width column and every value left-aligned in a second column. The
   strip's left padding makes room for the label, which sits in it with a
   negative margin, so chips that wrap line up under the first chip. */
.fop-stockstrip { --lbl: 128px; padding-left: calc(12px + var(--lbl) + 6px); }
.fop-stockstrip .fop-strip__lbl { flex: 0 0 var(--lbl); min-width: 0; margin-left: calc(-1 * (var(--lbl) + 6px)); }
@media (max-width: 767px) {
  .fop-stockstrip { --lbl: 112px; padding-left: calc(8px + var(--lbl) + 6px); }
}

/* Desktop: a line that grows (a saved comment or an error under the
   description) keeps every cell at the top: cells share the first text
   baseline, so the product, qty and price input text sits on the same line
   as the description's first line and the plain number cells. */
@media (min-width: 768px) {
  .fop-line:not(.fop-line--head) { align-items: baseline; }
}

/* Place Order clicked with no ship via, or with no order status in the
   confirm dialog: that box flashes yellow twice (flashField() in app.js). background-color only, so the select keeps
   its chevron. */
@keyframes fop-flash {
  0%, 100% { border-color: var(--line); box-shadow: none; background-color: var(--input-bg); }
  50% { border-color: var(--warning); box-shadow: 0 0 0 3px rgba(240, 196, 106, .45); background-color: rgba(240, 196, 106, .18); }
}
.fop-input.fop-flash { animation: fop-flash .4s ease-in-out 2; }

/* Invoiced / cancelled orders: no Br / All stock columns at all, so qty,
   prices and ext move right instead of leaving empty columns (desktop; phones
   use the card layout). */
@media (min-width: 768px) {
  .fop-grid--nostock .fop-line { grid-template-columns: 36px 150px minmax(160px, 1fr) 120px 110px 100px 110px 36px; }
  .fop-grid--nostock.fop-grid--details .fop-line { grid-template-columns: 36px 150px minmax(160px, 1fr) 120px 110px 100px 110px 64px; }
}

/* ── Phone pass (2026-10-19): tighter, less chunky ──
   Less padding on the page, cards and header; the line card puts its ×
   (and the Details button) beside the product box instead of on a row of
   its own; unit cost / ext / stock sit left and right in one row each; the
   orders list grows with the page instead of scrolling inside its card; the
   action bar is one row (total left, buttons right). Desktop is unchanged. */
@media (max-width: 767px) {
  /* The sign-in chip (auth.js, absolute top right, about 28px tall at top
     12px) gets the top strip to itself, so the title and status badge start
     below it instead of running into it. */
  .fop-app { padding: 50px 12px 96px; }
  .fop-wrap { gap: 12px; }
  .fop-h1 { font-size: 26px; }
  /* Title, then its buttons on their own row (the sign-in chip sits top right). */
  .fop-top { flex-direction: column; align-items: flex-start; gap: 8px; }
  .fop-top > .fop-row { gap: 8px; align-self: flex-end; justify-content: flex-end; }
  .fop-top .fop-key { display: none; }
  .fop-card { padding: 14px 12px; }
  .fop-btn { padding: 9px 14px; font-size: 16px; }
  .fop-btn--sm { padding: 6px 10px; font-size: 14px; }

  /* Bill-to / ship-to cards. */
  /* Bill-to and ship-to read as one card: one border and background on
     the pair, a thin divider between them. */
  .fop-parties {
    gap: 0; background: var(--card-bg);
    border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  }
  .fop-party { padding: 10px 12px 12px; background: none; border: 0; border-radius: 0; }
  .fop-party + .fop-party { border-top: 1px solid var(--line); }
  /* Read-only orders (picking started): the line cards merge into
     one card the same way, a thin divider between lines. */
  .fop-grid.fop-grid--locked {
    gap: 0; background: var(--card-bg);
    border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  }
  .fop-grid--locked .fop-line { background: none; border: 0; border-radius: 0; }
  .fop-grid--locked .fop-line:not(.fop-line--head) ~ .fop-line { border-top: 1px solid var(--line); }
  /* "Lines" title at the top of that card, set like Bill to / Ship to. */
  .fop-grid--locked .fop-lines-lbl { display: flex; align-items: center; min-height: 24px; padding: 10px 12px 0; }
  .fop-party__top { margin-bottom: 4px; }
  .fop-party__name { font-size: 16px; margin-bottom: 2px; }
  .fop-party__amt { font-size: 18px; }

  /* Header: same two fields per row, less inset. */
  .fop-head__sum { padding: 10px 12px; }
  .fop-head__grid { gap: 10px; padding: 0 12px 12px; }
  /* Ship via on a row of its own. */
  .fop-head__grid > .fop-field--mfull { grid-column: 1 / -1; }

  /* Line cards. The × (and the Details button) sit at the end of the
     product row: they share its grid area, and the product cell leaves
     room for them, so qty and price stay half and half on every card.
     Unit price sits left and qty right (on request), with unit cost under
     the price and ext. under the qty. */
  .fop-grid { gap: 8px; }
  .fop-grid .fop-line,
  .fop-grid--noall .fop-line,
  .fop-grid--details .fop-line {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "product product"
      "desc    desc"
      "price   qty"
      "cost    ext"
      "avail   total";
    gap: 0 8px; padding: 8px 8px 10px;
  }
  .fop-cell { padding: 4px; }
  .fop-cell--desc { padding-top: 2px; padding-bottom: 6px; font-size: 14px; }
  .fop-grid .fop-cell--product { padding-right: 44px; }
  .fop-grid .fop-line:has(.fop-detail-btn) .fop-cell--product { padding-right: 80px; }
  .fop-grid .fop-line:not(:has(.fop-cell--del button)) .fop-cell--product { padding-right: 4px; }
  .fop-grid .fop-cell--del,
  .fop-grid--details .fop-cell--del {
    grid-area: product; justify-self: end; align-self: end;
    display: flex; gap: 0; padding: 4px 0 7px;
  }
  .fop-grid .fop-cell--del .fop-icon-btn { width: 36px; height: 36px; font-size: 22px; }
  /* Read-only lines (invoiced / cancelled orders): the product id is a tile
     in the card's top right and the description starts the card. */
  .fop-grid .fop-line--ro { position: relative; }
  /* Same spot as the customer id tile on the bill-to / ship-to cards (12px
     in from the right, centred in a 24px row under 10px of padding). The
     extra classes beat the product cell's padding rules above. grid-area:
     auto, because an absolute item that keeps a grid area is placed inside
     that area (the card's 8px padding in), not against the card's edge. */
  .fop-grid .fop-line.fop-line--ro .fop-cell.fop-cell--product {
    grid-area: auto; position: absolute; top: 10px; right: 12px; display: flex; align-items: center; min-height: 24px; padding: 0;
  }
  .fop-grid .fop-line--ro .fop-cell--product .fop-mlabel,
  .fop-grid .fop-line--ro .fop-cell--product .fop-ac { display: none; }
  .fop-grid .fop-line--ro .fop-line__id { display: inline-block; font-size: 14px; }
  .fop-grid .fop-line--ro .fop-cell--desc { padding-top: 4px; padding-right: 84px; }
  /* Read-only lines: qty, unit price, unit cost and ext in one row, each
     label above its value (editable lines keep the stepper and price box). */
  .fop-grid .fop-line.fop-line--ro {
    grid-template-columns: minmax(0, .8fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr);
    grid-template-areas:
      "desc  desc  desc  desc"
      "qty   price cost  ext"
      "avail avail total total";
  }
  .fop-grid .fop-line--ro .fop-cell--qty,
  .fop-grid .fop-line--ro .fop-cell--price,
  .fop-grid .fop-line--ro .fop-cell--cost,
  .fop-grid .fop-line--ro .fop-cell--ext { padding-top: 4px; font-size: 15px; }
  .fop-grid .fop-line--ro .fop-cell--cost .fop-mlabel,
  .fop-grid .fop-line--ro .fop-cell--ext .fop-mlabel { display: block; margin-bottom: 3px; }
  .fop-grid .fop-line--ro .fop-grid-in[readonly] { padding-top: 0; padding-bottom: 0; font-size: 15px; }
  /* No × on a read-only line: drop the empty cell. A Details button (details
     layout, open order) sits top right and the tile moves left of it. */
  .fop-grid .fop-line--ro .fop-cell--del:not(:has(button)) { display: none; }
  .fop-grid .fop-line--ro .fop-cell--del:has(button) { grid-area: auto; position: absolute; top: 4px; right: 6px; padding: 0; }
  .fop-grid .fop-line.fop-line--ro:has(.fop-cell--del button) .fop-cell.fop-cell--product { right: 48px; }
  .fop-grid .fop-line--ro:has(.fop-cell--del button) .fop-cell--desc { padding-right: 124px; }
  .fop-grid .fop-cell--cost.fop-num { text-align: left; }
  .fop-grid .fop-cell--ext.fop-num { text-align: right; }
  .fop-grid .fop-cell--cost, .fop-grid .fop-cell--ext { font-size: 14px; padding-top: 6px; }
  .fop-grid .fop-input { padding: 9px 10px; }
  /* Read-only lines (existing orders): values sit flush left, no box. */
  .fop-grid .fop-grid-in[readonly] { padding-left: 0; padding-right: 0; height: auto; text-align: left; }
  .fop-step { flex-basis: 40px; height: 42px; }
  .fop-qty .fop-input { height: 42px; }

  /* Inline strip: each label (Inventory, Quantity breaks, Line comment) on
     its own line above its chips, so the chips get the full width. */
  .fop-stockstrip { padding-left: 8px; }
  .fop-stockstrip .fop-strip__lbl { flex: 0 0 100%; margin-left: 0; padding-top: 0; }
  .fop-stockstrip--comment .fop-strip__lbl { padding-top: 0; }

  /* Totals box and the buttons beside it. */
  /* 6px under the lines (the column's 12px gap less 6), half the gap
     between the other sections. An empty button row (locked orders) is
     dropped, or its row gap would add 8px. */
  .fop-gridfoot { margin-top: -6px; gap: 8px; }
  .fop-gridtools:empty { display: none; }
  .fop-sum__row { padding: 7px 12px; }

  /* Orders list: "New order" floats fixed in the bottom right of the
     screen, above the list (the page's 96px bottom padding keeps the last
     order clear of it). */
  .fop-fab {
    position: fixed; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 40;
    padding: 14px 20px; border-radius: 6px; /* same corners as every other button */
    box-shadow: 0 10px 28px var(--shadow), 0 0 0 1px rgba(var(--deep-rgb), .4);
  }
  .fop-fab .fop-key { display: none; }
  /* Keyboard-only hints (orders list, ship-to picker): no keyboard on a phone. */
  .fop-hint--keys { display: none; }
  /* Its row holds nothing else when there is no ship-to checkbox: no gap. */
  .fop-row:has(> .fop-fab:only-child) { display: contents; }
  /* Orders list: no scroll box inside the card, the page scrolls instead. */
  .fop-orders { max-height: none; overflow: visible; padding-right: 0; scrollbar-gutter: auto; }
  .fop-order { padding: 9px 10px; }

  /* Stock & qty breaks box (side layout) under the header. */
  /* It grows with the page (no scroll area of its own), and stock and qty
     breaks stack, chips flowing in rows, so chip labels stay on one line. */
  .fop-side { padding: 10px 12px 12px; font-size: 14px; max-height: none; overflow: visible; }
  .fop-side__cols { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .fop-side__sec { flex-direction: row; flex-wrap: wrap; }
  .fop-side__sec .fop-chip { white-space: nowrap; }

  /* Action bar: one row, total left and buttons right. On an existing order
     "Last modified" takes its own line above the buttons. */
  .fop-bar {
    flex-wrap: nowrap; align-items: flex-end; gap: 10px;
    padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
  }
  .fop-bar__totals { width: auto; flex: none; align-self: center; }
  .fop-bar__totals .fop-muted { display: block; font-size: 12px; }
  .fop-bar__actions { width: auto; flex: 1; min-width: 0; gap: 8px; justify-content: flex-end; }
  .fop-bar__actions .fop-btn { padding: 10px 8px; font-size: 15px; letter-spacing: .03em; }
  .fop-lastmod { font-size: 12px; text-align: right; white-space: normal; }

  /* Dialogs: a little more room for content. */
  .fop-modal { padding: 10px; }
  /* 100dvh: on iPhone 100vh is the height with the toolbars hidden, so the
     box outgrew the visible screen and its top (title, checkbox) was cut off. */
  .fop-modal__box { padding: 16px 14px; gap: 12px; max-height: calc(100vh - 20px); max-height: calc(100dvh - 20px); }

}

/* Phone line cards, calmer (2026-10-19): no stock count on the card (the
   strip and the stock box show the stock); strip labels
   in the same small caps as Qty / Unit price; smaller chips; the line
   comment folded behind an "Add line comment" button until it is used. */
@media (max-width: 767px) {
  .fop-grid .fop-line [data-cell="avail"],
  .fop-grid .fop-line [data-cell="total"] { display: none; }

  .fop-stockstrip { gap: 6px; padding-top: 8px; padding-bottom: 8px; }
  .fop-stockstrip[data-cell="strip"] { margin-top: 8px; }
  .fop-stockstrip .fop-strip__lbl,
  .fop-side__sec .fop-strip__lbl {
    font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
  }
  .fop-stockstrip .fop-chip { gap: 5px; padding: 1px 3px 1px 7px; font-size: 13px; }
  .fop-stockstrip .fop-chip--break { padding-right: 7px; }
  .fop-stockstrip .fop-stock { min-width: 24px; padding: 0 5px; }

  .fop-stockstrip--cmt-closed .fop-strip__lbl,
  .fop-stockstrip--cmt-closed .fop-line-comment { display: none; }
  .fop-stockstrip--cmt-closed .fop-addcmt { display: inline-flex; }
  .fop-addcmt { padding: 5px 10px; font-size: 13px; }
}

/* ── Light theme: HubSpot look (2026-10-19, on request: "for light mode,
   just make it look like HubSpot", from a HubSpot company record
   screenshot) ──
   Pale gray page, white cards with thin gray borders and rounded corners,
   dark slate text, Lexend Deca in sentence case (no condensed caps),
   teal links / focus / active states, dark teal pill primary buttons
   (HubSpot's Create colour), white outlined pill secondary buttons, gray tab boxes with a white active tab and
   gray tag-style id badges. Dark mode uses Foundry's navy and blue. Picked
   in each page's <head> (saved choice, else the system setting) and toggled from the
   user menu (bindThemeBtn() in app.js). */
html[data-theme="light"] {
  color-scheme: light;
  --accent-rgb:   200, 150, 42;
  --deep-rgb:     9, 21, 41;
  --page-bg:      #f5f8fa;
  --navy:         #ffffff;
  --navy-mid:     #f5f8fa;
  --navy-dark:    #eaf0f6;
  /* --gold / --gold-lt carry the teal accent here (links, focus, active
     tab, chips); primary buttons use --hs-primary below. */
  --gold:         #0091ae;
  --gold-lt:      #007a8c;
  --hs-primary:    #1c484a;
  --hs-primary-hi: #275f61;
  --white:        #213343;
  --text:         #33475b;
  --muted:        #516f90;
  --steel:        #cbd6e2;
  --border:       #dfe3eb;
  --line:         #dfe3eb;
  --card-bg:      #ffffff;
  --input-bg:     #ffffff;
  --row-hover:    #f5f8fa;
  --success:      #00a38d;
  --warning:      #b36b00;
  --error:        #d9363e;
  --on-gold:      #ffffff;
  --panel:        #ffffff;
  --panel-hi:     #ffffff;
  --surface:      #ffffff;
  --surface-head: #f5f8fa;
  --chip-bg:      #ffffff;
  --alt-row:      #fbfcfd;
  --tint-bg:      #f5f8fa;
  --tint-text:    #33475b;
  --tint-label:   #516f90;
  --shadow:       rgba(45, 62, 80, .18);
  --overlay:      rgba(45, 62, 80, .45);
  --err-text:     #9b1c22;
  --warn-text:    #7a4a00;
  --ok-text:      #006b5c;
  --danger-text:  #c0282f;
}

/* Type, both themes (dark too since 2026-10-19, on request): Lexend Deca
   everywhere, sentence case, no tracking. Colours stay per theme. */
html .fop-app,
html .fop-app *:not(svg):not(path),
html .flatpickr-calendar,
html .flatpickr-calendar *,
html .fop-header,
html .fop-header * {
  font-family: 'Lexend Deca', sans-serif !important;
  letter-spacing: normal !important;
  text-transform: none !important;
}
html .fop-app { font-size: 14px; }
html .fop-kicker { font-size: 14px; font-weight: 500; }
html .fop-h1 { font-size: 26px; font-weight: 600; }
html .fop-h2,
html .fop-head__sum { font-size: 18px; font-weight: 600; }
html .fop-party__lbl { font-size: 16px; font-weight: 600; }
html .fop-party__name { font-size: 15px; font-weight: 500; }
html .fop-party__addr { font-size: 14px; }
html .fop-party__amt,
html .fop-sum__row--total .fop-sum__val,
html .fop-total,
html .fop-confirm-total { font-size: 18px; font-weight: 600; }
/* Freight and HST above the confirm dialog's total: smaller, muted. */
html .fop-confirm-total.fop-confirm-freight { font-size: 14px; font-weight: 400; color: var(--muted); }
html .fop-sum__lbl,
html .fop-table th,
html .fop-mlabel { font-size: 13px; font-weight: 500; }
html .fop-sum__row--total .fop-sum__lbl { font-size: 14px; font-weight: 600; }
html .fop-label { font-size: 14px; font-weight: 400; }

html .fop-btn { font-size: 14px; font-weight: 600; }
html .fop-btn--sm { font-size: 13px; }
html .fop-line--head > * { font-size: 13px; font-weight: 600; }
/* Light-only text colours for the type rules above (dark keeps its gold
   totals and muted labels). */
html[data-theme="light"] .fop-h2,
html[data-theme="light"] .fop-head__sum,
html[data-theme="light"] .fop-party__lbl,
html[data-theme="light"] .fop-party__amt,
html[data-theme="light"] .fop-sum__row--total .fop-sum__val,
html[data-theme="light"] .fop-total,
html[data-theme="light"] .fop-confirm-total,
html[data-theme="light"] .fop-sum__row--total .fop-sum__lbl { color: var(--white); }

/* Cards: white, thin gray border, rounded, a faint shadow. */
html[data-theme="light"] .fop-card,
html[data-theme="light"] .fop-party,
html[data-theme="light"] .fop-head,
html[data-theme="light"] .fop-sum,
html[data-theme="light"] .fop-grid,
html[data-theme="light"] .fop-bar {
  border-color: var(--border); border-radius: 12px;
  box-shadow: 0 1px 2px rgba(45, 62, 80, .06);
}
html[data-theme="light"] .fop-line--head { --muted: #33475b; background: #f5f8fa; border-radius: 12px 12px 0 0; }
@media (max-width: 767px) {
  html[data-theme="light"] .fop-bar { border-radius: 0; box-shadow: 0 -2px 8px rgba(45, 62, 80, .08); }
  /* Bill-to / ship-to share one card on phones: the pair gets the card look. */
  html[data-theme="light"] .fop-party { border: 0; border-radius: 0; box-shadow: none; }
  html[data-theme="light"] .fop-party + .fop-party { border-top: 1px solid var(--line); }
  html[data-theme="light"] .fop-parties { border-color: var(--border); border-radius: 12px; box-shadow: 0 1px 2px rgba(45, 62, 80, .06); }
}

/* Buttons: pills, dark teal primary (sampled from HubSpot's Create
   button), white outlined secondary. */
html[data-theme="light"] .fop-btn {
  font-size: 14px; font-weight: 600; padding: 9px 18px; border-radius: 999px;
  color: #ffffff; background: var(--hs-primary); border-color: var(--hs-primary);
}
html[data-theme="light"] .fop-btn--sm { padding: 6px 12px; font-size: 13px; }
html[data-theme="light"] .fop-btn--ghost { color: var(--white); background: #ffffff; border-color: var(--steel); }
html[data-theme="light"] .fop-btn--on { background: #eaf0f6; }
@media (hover: hover) {
  html[data-theme="light"] .fop-btn:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--hs-primary-hi); border-color: var(--hs-primary-hi); }
  html[data-theme="light"] .fop-btn--ghost:hover:not([disabled]):not([aria-disabled="true"]) { color: var(--white); background: #f5f8fa; border-color: #7c98b6; }
  /* Cancel order: the general hover above gave red text on
     the dark teal (hard to read). Hover now turns the button the danger
     red with white text (2026-10-19, on request). */
  html[data-theme="light"] .fop-btn--danger:hover:not([disabled]):not([aria-disabled="true"]) { color: #ffffff; background: var(--danger-text); border-color: var(--danger-text); }
}
html[data-theme="light"] .fop-key { color: inherit; border-color: currentColor; opacity: .7; }

/* Inputs and focus: gray border, teal ring. */
html[data-theme="light"] .fop-input { border-color: var(--steel); border-radius: 6px; }
/* Read-only line values (locked orders, readonly grid cells) stay plain
   text, as in dark mode. */
html[data-theme="light"] .fop-grid--locked .fop-input,
html[data-theme="light"] .fop-grid-in[readonly] { border-color: transparent; }
/* Desktop: with visible boxes, the qty and unit price inputs touched (the
   base rule drops those cells' side padding so digits line up). A 4px gap
   each side splits them by 8px; the column headers move in to match. */
@media (min-width: 768px) {
  html[data-theme="light"] .fop-grid .fop-cell--qty,
  html[data-theme="light"] .fop-grid .fop-cell--price { padding-left: 4px; padding-right: 4px; }
  html[data-theme="light"] .fop-grid .fop-line--head .fop-cell--qty,
  html[data-theme="light"] .fop-grid .fop-line--head .fop-cell--price { padding-right: 12px; }
}
html[data-theme="light"] .fop-input:focus,
html[data-theme="light"] .fop-grid .fop-input:focus { border-color: #00bda5; box-shadow: 0 0 0 3px rgba(0, 189, 165, .2); }
html[data-theme="light"] .fop-app :focus-visible { outline-color: #00bda5; }

/* Links: teal, no underline until hover. */
html[data-theme="light"] .fop-linkbtn { font-weight: 600; text-decoration: none; }
html[data-theme="light"] .fop-linkbtn:hover { text-decoration: underline; }

/* Order header as HubSpot properties (2026-10-19, on request, both
   themes): label over value. Fields that can't be edited (a locked header,
   the order date, the order info fields) are plain text with no box, the
   text lined up under its label (the box is pulled 10px left). Editable
   fields keep a permanent input box (on request the same day, after a
   hover-only box), sized normally. Empty read-only values read "--"
   (placeholder set in afterRender()). Colours come from the theme tokens; light swaps in
   its own border, focus and icon colours. */
html .fop-head .fop-input::placeholder { color: var(--muted); -webkit-text-fill-color: var(--muted); opacity: 1; }
/* "--" is for read-only values; an empty editable box stays empty. */
html .fop-head:not(.fop-head--locked) .fop-input:not(:disabled)::placeholder { color: transparent; -webkit-text-fill-color: transparent; }
html .fop-head .fop-label { margin-bottom: 2px; }
html .fop-head .fop-input {
  width: calc(100% + 10px); margin-left: -10px; padding-left: 10px;
  font-size: 15px; color: var(--white); -webkit-text-fill-color: var(--white);
  border-color: transparent; background-color: transparent; background-image: none;
}
html .fop-head:not(.fop-head--locked) .fop-input:not(:disabled) { width: 100%; margin-left: 0; border-color: rgba(143, 164, 194, .35); background-color: var(--input-bg); }
html .fop-head:not(.fop-head--locked) .fop-input:not(:disabled):hover { border-color: rgba(143, 164, 194, .6); }
html .fop-head:not(.fop-head--locked) .fop-input:not(:disabled):focus,
html .fop-head:not(.fop-head--locked) .fop-date-alt.active { border-color: var(--gold); }
html .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fa4c2' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }
html .fop-head:not(.fop-head--locked) .fop-date-alt { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fa4c2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M3 9.5h18M8 2.5v4M16 2.5v4'/%3E%3C/svg%3E"); }
html[data-theme="light"] .fop-head:not(.fop-head--locked) .fop-input:not(:disabled) { border-color: var(--steel); background-color: #ffffff; }
html[data-theme="light"] .fop-head:not(.fop-head--locked) .fop-input:not(:disabled):hover { border-color: #a9bbcf; }
html[data-theme="light"] .fop-head:not(.fop-head--locked) .fop-input:not(:disabled):focus,
html[data-theme="light"] .fop-head:not(.fop-head--locked) .fop-date-alt.active { border-color: #00bda5; }
html[data-theme="light"] .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23516f90' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }
html[data-theme="light"] .fop-head:not(.fop-head--locked) .fop-date-alt { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23516f90' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M3 9.5h18M8 2.5v4M16 2.5v4'/%3E%3C/svg%3E"); }
/* Beats the locked-header rules' input background (more specific). */
html .fop-head--locked .fop-input,
html .fop-head .fop-input:disabled,
html .fop-head--locked .fop-date-alt[readonly] { background-color: transparent; cursor: default; }
@media (max-width: 767px) {
  /* Phones: HubSpot's mobile property list, a thin line under each
     property (two per row where they fit). */
  html .fop-head__grid { row-gap: 0; column-gap: 16px; padding-bottom: 4px; }
  html .fop-head__grid > .fop-field { padding: 10px 0; border-bottom: 1px solid var(--line); }

  /* Phones, HubSpot app's Edit Deal list (2026-10-19, on request, both
     themes): one property per row with a line across the card, small label
     over the value, no input boxes (editable or not), a calendar icon on
     editable dates, a filled caret on dropdowns. An empty property shows only its label, at
     value size (like HubSpot's empty "Deal Type"); tapping it (focus) puts
     the label back on top. Values are 16px so iOS doesn't zoom on focus. */
  html .fop-head__grid { display: block; padding: 0; }
  html .fop-head__grid > .fop-field {
    position: relative; display: flex; flex-direction: column; justify-content: center;
    min-height: 66px; padding: 9px 12px; border-bottom: 1px solid var(--line);
  }
  html .fop-head__grid > .fop-field:last-child { border-bottom: 0; }
  html .fop-head .fop-label { margin-bottom: 1px; font-size: 13px; transition: font-size .12s ease; }
  html .fop-head input.fop-input,
  html .fop-head select.fop-input,
  html .fop-head textarea.fop-input,
  html .fop-head:not(.fop-head--locked) input.fop-input:not(:disabled),
  html .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled),
  html .fop-head:not(.fop-head--locked) textarea.fop-input:not(:disabled) {
    width: 100%; margin: 0; padding: 0; min-height: 0; height: auto;
    font-size: 16px; line-height: 1.35;
    border: 0; border-radius: 0; box-shadow: none; background-color: transparent;
  }
  html .fop-head textarea.fop-notes { min-height: 0; }
  /* Editable dates keep their calendar icon (locked ones have none). */
  html .fop-head:not(.fop-head--locked) input.fop-date-alt:not(:disabled) { padding-right: 28px; background-position: right 2px center; }
  html .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) {
    padding-right: 28px; background-position: right 2px center; background-size: 12px 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 3.5h10L6 9z' fill='%23f0f4fa'/%3E%3C/svg%3E");
  }
  html[data-theme="light"] .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 3.5h10L6 9z' fill='%23213343'/%3E%3C/svg%3E");
  }
  /* Focus: the label takes the accent colour instead of a box. */
  html .fop-head__grid > .fop-field:focus-within .fop-label,
  html .fop-head__grid > .fop-field:has(.fop-date-alt.active) .fop-label { color: var(--gold); }
  /* Empty and not focused: label only, at value size; the (invisible)
     control covers the row so a tap still lands on it. */
  html .fop-head__grid > .fop-field:has(> .fop-input:placeholder-shown):not(:focus-within):not(:has(.fop-date-alt.active)) .fop-label,
  html .fop-head__grid > .fop-field:has(> select.fop-input option[value=""]:checked):not(:focus-within) .fop-label { margin: 0; font-size: 16px; }
  html .fop-head__grid > .fop-field:has(> .fop-input:placeholder-shown):not(:focus-within):not(:has(.fop-date-alt.active)) > .fop-input,
  html .fop-head__grid > .fop-field:has(> select.fop-input option[value=""]:checked):not(:focus-within) > select.fop-input {
    position: absolute; inset: 0; width: 100%; height: 100%; padding: 0 12px; opacity: 0;
  }
  /* The caret stays visible on an empty dropdown. */
  html .fop-head__grid > .fop-field:has(> select.fop-input:not(:disabled) option[value=""]:checked):not(:focus-within)::after {
    content: ""; position: absolute; right: 14px; top: 50%; width: 12px; height: 12px; margin-top: -6px;
    pointer-events: none; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 3.5h10L6 9z' fill='%23f0f4fa'/%3E%3C/svg%3E") no-repeat center / 12px 12px;
  }
  html[data-theme="light"] .fop-head__grid > .fop-field:has(> select.fop-input:not(:disabled) option[value=""]:checked):not(:focus-within)::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 3.5h10L6 9z' fill='%23213343'/%3E%3C/svg%3E");
  }
}

/* Tags: id badges gray, price level a filled teal pill. */
html[data-theme="light"] .fop-badge { font-size: 13px; font-weight: 500; color: var(--text); background: #eaf0f6; border-color: var(--steel); border-radius: 4px; }
html[data-theme="light"] .fop-level { font-size: 13px; font-weight: 500; padding: 2px 9px; color: #ffffff; background: #0b7a85; border-radius: 4px; }

/* Stock / qty-break panel and side panel: pale gray. */
html[data-theme="light"] .fop-stockstrip,
html[data-theme="light"] .fop-side { background: #f5f8fa; }
html[data-theme="light"] .fop-side__line--active { background: rgba(0, 145, 174, .06); }
html[data-theme="light"] .fop-detail-btn:hover { background: rgba(0, 145, 174, .1); }
html[data-theme="light"] .flatpickr-day.today:focus { background: rgba(0, 145, 174, .15); }
/* Remaining gold tints in the base rules, turned teal / gray. */
html[data-theme="light"] .fop-step { background: #f5f8fa; border-color: var(--steel); color: var(--gold-lt); }
html[data-theme="light"] .fop-ac__item--active,
html[data-theme="light"] .fop-ac__item:hover,
html[data-theme="light"] .flatpickr-day:hover,
html[data-theme="light"] .flatpickr-day:focus,
html[data-theme="light"] .numInputWrapper:hover { background: rgba(0, 145, 174, .1); border-color: transparent; }
html[data-theme="light"] .fop-spinner { border-color: rgba(0, 145, 174, .2); border-top-color: var(--gold); }
html[data-theme="light"] .flatpickr-calendar { box-shadow: 0 0 0 1px var(--border), 0 10px 30px var(--shadow); }
html[data-theme="light"] .flatpickr-calendar.arrowTop:before { border-bottom-color: var(--border); }
html[data-theme="light"] .flatpickr-calendar.arrowBottom:before { border-top-color: var(--border); }

/* Dialogs: white, rounded, soft shadow. */
html[data-theme="light"] .fop-modal__box { border-radius: 12px; box-shadow: 0 10px 40px var(--shadow); }

/* ── Page header (2026-10-19), both themes ──
   Bar built by initHeader() in app.js: the Foundry mark left; Open in
   Foundry, HS Deal, HS Company and the user menu (name; opens the email,
   the theme toggle and Sign out) right. #333 in light, Foundry's
   navy-950 in dark (the override at the end of this file). Sticky on
   desktop; on phones app.js adds --hidden while scrolling down (slides up
   out of view) and drops it on any scroll up. It replaces auth.js's
   sign-in chip on these pages. */
#fw-user-chip { display: none !important; }
.fop-header {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  height: 40px; padding: 0 20px;
  font-size: 14px; font-weight: 500; color: #f2f2f2; background: #333333;
  transition: transform .2s ease;
}
.fop-header__logo { display: flex; align-items: center; flex: none; }
.fop-header__logo img { display: block; height: 28px; width: auto; }
.fop-header__end { display: flex; align-items: center; gap: 18px; min-width: 0; }
.fop-header__links { display: flex; align-items: center; gap: 18px; }
.fop-header__links:not(:empty) { padding-right: 18px; border-right: 1px solid #555555; }
.fop-header__link { display: inline-flex; align-items: center; gap: 6px; color: #f2f2f2; text-decoration: none; white-space: nowrap; }
.fop-header__link:hover { color: #ffffff; text-decoration: underline; text-underline-offset: 3px; }
.fop-umenu { position: relative; min-width: 0; }
.fop-umenu__btn {
  display: flex; align-items: center; gap: 8px; max-width: 100%; height: 30px; padding: 0 12px 0 14px;
  font: inherit; color: #ffffff; background: rgba(255, 255, 255, .1); border: 0; border-radius: 999px; cursor: pointer;
}
.fop-umenu__btn:hover, .fop-umenu__btn[aria-expanded="true"] { background: rgba(255, 255, 255, .18); }
.fop-umenu__name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fop-umenu__caret { flex: none; width: 10px; height: 6px; }
.fop-umenu__name--first { display: none; }
.fop-hl__short { display: none; }
/* Same colour as the bar: the email, a divider, the theme row, Sign out. */
.fop-umenu__panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 70; width: max-content; min-width: 140px;
  color: #f2f2f2; background: #333333; border: 1px solid #555555; border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35); overflow: hidden;
}
.fop-umenu__panel[hidden] { display: none; }
.fop-umenu__row { padding: 12px 16px; white-space: nowrap; border-bottom: 1px solid #555555; }
.fop-umenu__lbl { display: block; margin-bottom: 2px; font-size: 12px; color: #b5b5b5; }
.fop-umenu__out {
  display: block; width: 100%; padding: 12px 16px; text-align: left;
  font: inherit; color: #ffffff; background: none; border: 0; cursor: pointer;
}
.fop-umenu__out:hover,
.fop-umenu__theme:hover { background: rgba(255, 255, 255, .08); }
/* Theme row, above Sign out. */
.fop-umenu__theme {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 12px 16px; text-align: left;
  font: inherit; color: #ffffff; background: none; border: 0; border-bottom: 1px solid #555555; cursor: pointer;
}
.fop-umenu__theme svg { width: 17px; height: 17px; flex: none; }
.fop-header :focus-visible { outline: 2px solid #ffffff; outline-offset: 3px; border-radius: 3px; }
@media (max-width: 767px) {
  .fop-header { height: 40px; padding: 0 12px; gap: 10px; font-size: 13px; }
  .fop-header--hidden { transform: translateY(-100%); }
  /* Narrow screens: first name only, still shortened with an ellipsis if
     it does not fit. */
  .fop-header__end, .fop-header__links { gap: 12px; }
  .fop-header__links:not(:empty) { padding-right: 12px; }
  .fop-header__link { gap: 4px; }
  .fop-umenu__btn { padding: 0 10px 0 12px; gap: 6px; }
  .fop-umenu__name--full { display: none; }
  .fop-umenu__name--first { display: inline; }
  .fop-hl__full { display: none; }
  .fop-hl__short { display: inline; }
  .fop-header__end { min-width: 0; }
}

/* ── View Quote dialog (2026-10-19) ──
   Header (title, Open in new tab, ×), the HubSpot quote page in an iframe
   taking all the height left, then the "Send to" email box with Send Quote
   beside it. The email box is a .fop-input wrapper holding the address
   chips and a borderless input, so it outlines (and flashes, .fop-flash)
   as one box. Esc, × or a backdrop click closes (no Close button). */
.fop-modal.fop-modal--quote { padding: 8px 16px; }   /* little space above and below */
.fop-modal--quote .fop-quote { height: 100%; max-height: none; overflow: hidden; }
.fop-quote__head { display: flex; align-items: center; gap: 12px; }
.fop-quote__titles { flex: 1 1 auto; min-width: 0; }
.fop-quote__head .fop-btn { flex: none; }
.fop-quote__x {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 36px; font-size: 26px; line-height: 1;
}
/* The iframe sits in a clipping box; fitQuoteFrame() scales it down when
   the box is narrower than the 816px quote sheet. */
.fop-quote__viewport {
  position: relative; overflow: hidden; flex: 1 1 auto; min-height: 0;
  background: #ffffff; border: 1px solid var(--line); border-radius: 8px;
}
.fop-quote__frame { position: absolute; top: 0; left: 0; display: block; width: 100%; height: 100%; border: 0; transform-origin: 0 0; }
/* Touch screens: catches pinch / pan / double tap for the quote under it
   (app.js, quoteTouchStart). touch-action none: the browser leaves the
   gestures to the page. */
.fop-quote__touch { position: absolute; inset: 0; z-index: 1; touch-action: none; }
/* Send row: the email box grows, Send sits to its right on the box's
   line (the footer row's button joins this flex row through
   display: contents); the sent / error note goes under both. */
.fop-quote__foot { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 6px 10px; }
.fop-quote__foot > .fop-field { flex: 1 1 0; min-width: 0; }
.fop-quote__foot .fop-row { display: contents; }
.fop-quote__foot [data-action="send-quote"] { flex: none; height: 40px; }
.fop-quote__note { order: 9; flex: 1 0 100%; }
.fop-quote__note:empty { display: none; }
.fop-emails { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 4px 8px; min-height: 40px; cursor: text; }
.fop-emails:focus-within { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .25); }
.fop-emails.fop-input--err { border-color: var(--error); }
.fop-emails__in {
  flex: 1 1 180px; min-width: 120px; padding: 2px 2px;
  font: inherit; color: var(--white); background: transparent; border: 0; outline: none;
}
/* The box (.fop-emails:focus-within) shows the focus ring; the input inside
   gets none, or .fop-app :focus-visible draws a second ring inside it. */
.fop-app .fop-emails__in:focus, .fop-app .fop-emails__in:focus-visible { outline: none; }
.fop-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 9px;
  font-size: 14px; color: var(--text); background: rgba(143, 164, 194, 0.14);
  border: 1px solid var(--steel); border-radius: 999px;
}
.fop-chip__x {
  display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; padding: 0;
  font-family: inherit; font-size: 16px; line-height: 1; color: var(--muted); background: none; border: 0; border-radius: 50%; cursor: pointer;
}
.fop-chip__x:hover { color: var(--error); background: rgba(255, 95, 95, .1); }
html[data-theme="light"] .fop-emails:focus-within { border-color: #00bda5; box-shadow: 0 0 0 3px rgba(0, 189, 165, .2); }
html[data-theme="light"] .fop-chip { background: #eaf0f6; }
/* Phones: the dialog nearly fills the screen with little padding,
   "Open in new tab" is just its icon, the send hint is hidden and Send
   Quote reads "Send". */
@media (max-width: 767px) {
  /* 12px of the page shows above and below (so it reads as a dialog over
     the order), 6px at the sides. */
  .fop-modal.fop-modal--quote { padding: 12px 6px max(12px, env(safe-area-inset-bottom)); }
  .fop-modal--quote .fop-quote { width: 100%; max-width: none; padding: 8px 2px; gap: 8px; }
  /* Only the quote runs to 2px from the edge; the header and the send row
     keep 8px. */
  .fop-modal--quote .fop-quote__head, .fop-modal--quote .fop-quote__foot { padding: 0 6px; }
  .fop-quote__head { gap: 8px; }
  .fop-quote .fop-h2 { font-size: 17px; line-height: 1.2; }
  .fop-quote__newtab { padding: 7px 9px; }
  .fop-quote__newtab-txt, .fop-quote__hint, .fop-quote__q { display: none; }
  .fop-quote__viewport { border-radius: 4px; }
  .fop-quote__foot { gap: 6px 8px; }
  .fop-quote__foot .fop-label { margin-bottom: 3px; }
  .fop-quote__foot [data-action="send-quote"] { padding: 0 16px; }
  .fop-emails__in { font-size: 16px; } /* no iOS zoom on focus */
}

/* ── Foundry dark: what the tokens can't reach (dark theme only) ──
   Button hover in Foundry's darker blue (the light accent as a background
   would wash out the white label), header icons in the dark muted and text
   colours, and the page header bar in navy-950 with navy lines. */
@media (hover: hover) {
  html:not([data-theme="light"]) .fop-btn:hover:not([disabled]):not([aria-disabled="true"]) { background: #0050d4; border-color: #0050d4; }
  html:not([data-theme="light"]) .fop-btn--ghost:hover:not([disabled]):not([aria-disabled="true"]) { color: var(--gold-lt); border-color: var(--gold); background: rgba(var(--accent-rgb), 0.12); }
  html:not([data-theme="light"]) .fop-btn--danger:hover:not([disabled]):not([aria-disabled="true"]) { color: var(--err-text); background: rgba(255, 95, 95, .12); border-color: var(--error); }
  html:not([data-theme="light"]) .fop-btn--danger-solid:hover:not([disabled]):not([aria-disabled="true"]) { background: #d94b4b; border-color: #d94b4b; }
}
html:not([data-theme="light"]) .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2397a7c6' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }
html:not([data-theme="light"]) .fop-head:not(.fop-head--locked) .fop-date-alt { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2397a7c6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M3 9.5h18M8 2.5v4M16 2.5v4'/%3E%3C/svg%3E"); }
@media (max-width: 767px) {
  html:not([data-theme="light"]) .fop-head:not(.fop-head--locked) select.fop-input:not(:disabled) {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 3.5h10L6 9z' fill='%23f2f5f7'/%3E%3C/svg%3E");
  }
}
html:not([data-theme="light"]) .fop-header,
html:not([data-theme="light"]) .fop-umenu__panel { color: #f2f5f7; background: #010916; }
html:not([data-theme="light"]) .fop-header { box-shadow: 0 1px 0 #18305a; }
html:not([data-theme="light"]) .fop-umenu__panel,
html:not([data-theme="light"]) .fop-umenu__row,
html:not([data-theme="light"]) .fop-umenu__theme { border-color: #18305a; }
html:not([data-theme="light"]) .fop-header__links:not(:empty) { border-right-color: #18305a; }
html:not([data-theme="light"]) .fop-header__link { color: #f2f5f7; }
html:not([data-theme="light"]) .fop-umenu__lbl { color: #97a7c6; }
