/* CONFIG PLACEHOLDER — brand palette + skin tokens. A client build
   drops its brand colors into these variables (the config seam owns
   them); the tile/bg values below are a neutral default theme, not any
   client's brand. The skin tokens (--radius, --radius-sm, --shadow,
   --font) after them carry matching stock values as the pre-boot
   fallback — app.js re-applies every one from client-config.js at boot.
   The --tier-* colors further down are functional signals, not brand. */
:root {
  --tile: #437D8D;
  --tile-2: #57808B;
  --tile-dark: #2E5561;
  --bg: #1C2B30;
  --text: #FFFFFF;
  --accent: #F5A623; /* amber: qualified-plan markers, blocked/needs-attention */
  --radius: 14px;    /* skin token: main-surface corner radius */
  --radius-sm: 10px; /* skin token: inner-control corner radius */
  --shadow: none;    /* skin token: card shading depth — flat by default */
  --sheen: none;     /* skin token: light-from-above gradient on raised surfaces — flat by default */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; /* skin token */
  --flag: #4EA72E;   /* green: items highlighted on the price sheet — never amber */
  --tier-12: #4EA72E;   /* green: price still holds the 12% tier */
  --tier-10: #F5D033;   /* yellow: price holds the 10% tier */
  --tier-5:  #E5484D;   /* red: price is down to the 5% tier */
  --tier-flat: #000000; /* black: below 5% — flat $250 */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Screens, panels and the modal are display:flex/grid, which beats the UA's
   [hidden] rule — without this, hiding them by attribute does nothing. */
[hidden] { display: none !important; }

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-text-size-adjust: 100%;
}

main {
  max-width: 480px;
  margin: 0 auto;
  padding: 12px 10px 40px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.85;
}

.label-sub {
  text-transform: none;
  font-weight: 400;
  opacity: 0.8;
}

.section-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 8px;
  opacity: 0.9;
}

/* ---- Client branding --------------------------------------------------
   The brand header (top of the app) and the lockup on the gating
   screens (sign-in, locked). The logo sits on a plain white plate:
   client logos are designed for light grounds more often than not,
   and the plate keeps every logo legible on the app's dark theme
   without restyling the logo itself. The company name is real text
   under the logo, so the build is identified even at sizes where the
   wordmark inside the logo art is too small to read. */
.brand-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}

.brand-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

.brand-logo {
  display: block;
  width: auto;
  height: auto;
  object-fit: contain;
  background: #FFFFFF;
  border-radius: var(--radius-sm);
  padding: 8px 12px;
}

/* A round badge logo can declare skin.logoPlate "ring": the white
   plate becomes a disc, leaving a thin white ring around the badge
   as separation instead of a rectangle (Jeff, 2026-10-29). */
body[data-logo-plate="ring"] .brand-logo {
  border-radius: 50%;
  padding: 3px;
}

.brand-logo-main { max-width: min(280px, 86vw); max-height: 84px; }

.brand-logo-gate { max-width: min(320px, 82vw); max-height: 132px; }

.brand-company {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.03em;
}

.brand-company-gate { font-size: 19px; }

/* ---- Rates: the Change Price screen's alert surface -------------------
   This screen changes live money, so it wears an alert background the
   rest of the app never uses — the manager should feel the difference
   before reading a word. The colour is a fixed functional red, not a
   brand colour; the accent border and the note borrow the client's
   accent so it still belongs to the build. */
#screen-rates-change {
  background: #571E1E;
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  padding: 12px 10px;
}

.rates-alert-note {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}

/* The price field is the whole point of this screen, so it stands as
   tall as the screen's other controls instead of shrinking to a
   one-line strip: roughly double the stock input height, with the
   type and the $ sized to match. */
#screen-rates-change .money-input input {
  min-height: 72px;
  font-size: 26px;
  font-weight: 700;
}

#screen-rates-change .money-input .dollar-prefix { font-size: 40px; }

/* ---- Customer bar + name gate -----------------------------------------
   The bar is the appointment's identity: always visible on the QUOTE
   and PRICING screens. While it is empty, both screens' working areas
   are locked (dimmed + inert, applied by app.js) — the panels that
   load or export existing jobs stay live, because loading a job is
   one of the ways a name gets set. */
.customer-bar {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.customer-bar input {
  min-height: 48px;
  padding: 0 12px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile);
  color: var(--text);
  font-size: 16px;
}

.customer-bar input::placeholder { color: rgba(255, 255, 255, 0.5); }

.gate-note {
  background: var(--tile-dark);
  border-left: 5px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 12px;
  font-size: 15px;
  font-weight: 700;
}

.gate-locked { opacity: 0.45; pointer-events: none; }

/* ---- Screens ---- */
/* Each screen reproduces main's column layout so the pricing sections keep
   the exact spacing they had before they were wrapped. */
.screen {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.screen-tabs {
  display: grid;
  /* However many tabs the build shows (Home made three, a manager
     sees four) they share the row equally. */
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 8px;
}

.screen-tabs button {
  min-height: 56px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-dark);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.05em;
}

.screen-tabs button.active {
  background: var(--tile);
  outline: 2px solid var(--accent);
}

/* ---- Quote / Estimate toggle (2026-11-01): compact, top-right ---- */
.pricing-topbar {
  display: flex;
  justify-content: flex-end;
}
.mode-toggle {
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--tile-dark);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
.mode-toggle button {
  min-height: 36px;
  padding: 0 16px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.mode-toggle button.active {
  background: var(--tile);
  background-image: var(--sheen);
  outline: 2px solid var(--accent);
}
.mode-note {
  margin: 8px 2px 0;
  font-size: 13px;
  opacity: 0.75;
}
#estimate-save { margin-top: 10px; }

/* The red estimate frame: fixed to the viewport, always in the rep's
   peripheral vision while he estimates, never in the way. */
#estimate-frame {
  position: fixed;
  inset: 0;
  border: 4px solid #d92b1f;
  pointer-events: none;
  z-index: 850;
}
#estimate-frame[hidden] { display: none; }

/* ---- Home screen (2026-11-01) ---- */
.home-section {
  background: var(--tile-dark);
  background-image: var(--sheen);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.home-note {
  margin: 0;
  font-size: 13px;
  opacity: 0.75;
}
.quote-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* ---- Price inputs ---- */
.input-section {
  background: var(--tile-dark);
  border-radius: var(--radius);
  padding: 10px 14px;
}

.input-section input {
  width: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-size: 34px;
  font-weight: 800;
  text-align: center;
  min-height: 56px;
}

.input-section input::placeholder { color: rgba(255,255,255,0.4); }

/* $ prefix on List Price / Proposed / Target Pmt — the input keeps text-align:
   center for its own value; the prefix just sits fixed-width to its left. */
.money-input {
  display: flex;
  align-items: center;
  gap: 2px;
}

.money-input .dollar-prefix {
  flex: none;
  font-size: 28px;
  font-weight: 800;
  opacity: 0.7;
}

.money-input input { flex: 1 1 auto; min-width: 0; }

/* Proposed price sits beside the payment-to-price solver; two 34px inputs will
   not fit an iPhone side by side, so this row runs a size down. */
.price-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  align-items: start;
}

.price-row .input-section input { font-size: 26px; min-height: 48px; }
.price-row .money-input .dollar-prefix { font-size: 22px; }

.solved-price {
  font-size: 20px;
  font-weight: 800;
  text-align: center;
  font-variant-numeric: tabular-nums;
  padding-bottom: 4px;
  color: var(--accent);
}

/* ---- Cards ---- */
.headline-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.card {
  background: var(--tile);
  background-image: var(--sheen);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px 12px;
  min-height: 84px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 2px;
}

.big {
  font-size: 28px;
  font-weight: 800;
  line-height: 1.1;
}

.small {
  font-size: 13px;
  font-weight: 600;
  opacity: 0.85;
}

/* ---- Drop table ---- */
.drop-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--tile-dark);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: 15px;
}

.drop-table th {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 8px 6px;
  background: rgba(0,0,0,0.25);
  text-align: right;
}

.drop-table th:first-child { text-align: left; }

.drop-table td {
  padding: 10px 6px;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-top: 1px solid rgba(255,255,255,0.08);
}

.drop-table td:first-child {
  text-align: left;
  font-weight: 700;
  /* Always reserve the stripe so tier color never shifts the layout. */
  border-left: 4px solid transparent;
}

/* Which commission tier this row's price falls in. */
.drop-table tr.tier-t12 td:first-child { border-left-color: var(--tier-12); }
.drop-table tr.tier-t10 td:first-child { border-left-color: var(--tier-10); }
.drop-table tr.tier-t5 td:first-child { border-left-color: var(--tier-5); }
.drop-table tr.tier-flat td:first-child { border-left-color: var(--tier-flat); }

/* ---- Lender toggle + plan select ---- */
.plan-picker {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lender-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.lender-toggle button {
  min-height: 56px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-dark);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.05em;
}

.lender-toggle button.active {
  background: var(--tile);
  outline: 2px solid var(--accent);
}

/* iOS Safari ignores CSS on <option>, so mark a qualified selection on the
   select itself: amber text whenever the chosen plan qualifies. */
#plan-select.qualified { color: var(--accent); }

#plan-select {
  width: 100%;
  min-height: 56px;
  border: none;
  border-radius: var(--radius);
  /* The same shading as every other tile (Jeff, 2026-10-31): the
     flat tile-2 fill made the finance bar glow next to its cards. */
  background: var(--tile);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 17px;
  font-weight: 700;
  padding: 0 14px;
  appearance: none;
  -webkit-appearance: none;
}

/* ---- Effect cards ---- */
.effect-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 10px;
}

.effect-card {
  align-items: flex-start;
  text-align: left;
}

.effect-lines {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
}

.effect-lines .hl { color: var(--accent); }

/* ---- Tiles / steppers ---- */
.tile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.tile {
  background: var(--tile);
  background-image: var(--sheen);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  min-height: 84px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 2px;
}

.tile .label { font-size: 12px; }

.tile.stepper {
  display: grid;
  grid-template-columns: 44px 1fr 44px;
  grid-template-rows: auto 1fr;
  align-items: center;
}

.tile.stepper .label {
  grid-column: 1 / -1;
  padding-top: 2px;
}

.tile.stepper output {
  font-size: 28px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tile.stepper output input {
  width: 100%;
  background: rgba(0,0,0,0.25);
  border: none;
  border-radius: 8px;
  outline: 2px solid var(--accent);
  color: var(--text);
  font-size: 24px;
  font-weight: 800;
  text-align: center;
  min-height: 48px;
}

.tile.stepper .minus,
.tile.stepper .plus {
  min-height: 56px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile-dark);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 26px;
  font-weight: 800;
}

.tile.stepper .minus:active,
.tile.stepper .plus:active { background: var(--tile-2); }

/* ---- Quick grid ---- */
.quick-grid .tile { background: var(--tile-2); background-image: var(--sheen); outline: 2px solid transparent; }

/* Which commission tier this tile's price holds. */
.quick-grid .tile.tier-t12 { outline-color: var(--tier-12); }
.quick-grid .tile.tier-t10 { outline-color: var(--tier-10); }
.quick-grid .tile.tier-t5 { outline-color: var(--tier-5); }
.quick-grid .tile.tier-flat { outline-color: var(--tier-flat); }

.quick-grid .tile .small {
  font-size: 12px;
  opacity: 0.9;
}

/* ---- Reset ---- */
.reset-btn {
  width: 100%;
  min-height: 56px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-dark);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.reset-btn:disabled { opacity: 0.4; }

/* Press feel: tappable controls answer the tap with a slight settle.
   Purely cosmetic — no layout depends on it. */
button { transition: transform 0.07s ease; }
button:active { transform: scale(0.98); }

/* The Manager section's two actions are separate decisions: a real
   gap between them, and Call reads as the secondary action (outline),
   Send as the primary (filled). Without the gap the two pills merged
   into one shape on the phone (Jeff, 2026-10-29). */
section[data-section="dropCall"] {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* The Call / Text / Email row (2026-10-31): three equal buttons,
   same reset-btn shading as Send above them. */
.mgmt-row {
  display: flex;
  gap: 10px;
}
.mgmt-row .reset-btn {
  flex: 1 1 0;
  min-width: 0;
  padding-left: 6px;
  padding-right: 6px;
}

/* The Change Price screen's lead-highlight toggle (2026-10-31). */
.flag-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 4px;
  font-size: 15px;
  line-height: 1.4;
  cursor: pointer;
}
.flag-toggle input {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  accent-color: var(--flag);
}

/* ---- Misc charges (quote screen, 2026-10-31) ---- */
.misc-section { margin: 4px 0 14px; }
.misc-note {
  margin: 0 0 10px;
  font-size: 13.5px;
  line-height: 1.45;
  opacity: 0.75;
}
.misc-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
  margin-bottom: 8px;
}
.misc-desc,
.misc-amount {
  border: none;
  border-radius: var(--radius);
  background: var(--tile);
  color: var(--text);
  min-height: 48px;
  padding: 0 12px;
  font-size: 16px;
}
.misc-desc { flex: 1 1 auto; min-width: 0; }
.misc-amount { flex: 0 0 96px; width: 96px; text-align: right; }
.misc-remove {
  flex: 0 0 44px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-dark);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 20px;
  cursor: pointer;
}

/* Section dividers (Jeff, 2026-10-31): a hairline and air above the
   pricing screen's working groups — manager buttons, the money
   questions, the setup knobs, the grid, the drops, reset — so the
   screen reads as groups instead of one long scroll. The line rides
   on the section itself, so it travels wherever a layout variant
   moves the group. */
#screen-pricing > section[data-section="dropCall"],
#screen-pricing > section[data-section="planPicker"],
#screen-pricing > section[data-section="knobs"],
#screen-pricing > section[data-section="quickGrid"],
#screen-pricing > section[data-section="drops"],
#screen-pricing > section[data-section="reset"] {
  border-top: 1px solid rgba(128, 128, 128, 0.35);
  border-top: 1px solid color-mix(in srgb, var(--text) 16%, transparent);
  padding-top: 14px;
  margin-top: 14px;
}

/* The Call/Text/Email buttons are plain reset-btns like Send —
   an earlier single-button outline style for Call was removed
   2026-10-31 (Jeff: it should be the same color as the others). */

/* ---- Privacy veil (2026-10-31): the floating eye + the cover ---- */
.privacy-btn {
  position: fixed;
  right: 14px;
  bottom: calc(18px + env(safe-area-inset-bottom));
  z-index: 900;
  width: 46px;
  height: 46px;
  border: none;
  border-radius: 50%;
  background: var(--tile);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
/* In the dock layout the tab bar owns the bottom edge — float above it. */
body.layout-dock .privacy-btn { bottom: calc(84px + env(safe-area-inset-bottom)); }

#privacy-veil {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 24px;
  cursor: pointer;
}
#privacy-veil[hidden] { display: none; }
.veil-company { font-size: 24px; font-weight: 800; }
.veil-hint { opacity: 0.65; font-size: 15px; margin: 0; }
body.veil-on { overflow: hidden; }

/* ==================== Quote screen ==================== */

/* ---- Collapsible headers (groups + saved jobs) ---- */
.panel-toggle,
.group-header {
  width: 100%;
  min-height: 56px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-dark);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  color: var(--text);
  text-align: left;
}

.panel-toggle .section-title,
.group-header .group-name { margin-bottom: 0; }

.group-header .group-name {
  flex: 1;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.03em;
}

.group-count {
  min-width: 26px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--bg);
  font-size: 13px;
  font-weight: 800;
  text-align: center;
}

.group-chev {
  display: inline-block;
  margin-left: auto;
  font-size: 22px;
  font-weight: 800;
  opacity: 0.7;
  transition: transform 0.12s ease-out;
}

.group-header .group-chev { margin-left: 0; }

[aria-expanded="true"] > .group-chev { transform: rotate(90deg); }

/* ---- Sections > subsections > items ---- */
.quote-section { margin-bottom: 10px; }

/* The section band outranks its subsections by size and type only —
   it keeps the shared group-header shading (tile-dark + sheen +
   shadow). An earlier background override here made the quote
   screen's section bands a different, flatter green than every
   other bar in the app (Jeff, 2026-10-31: matching, everywhere). */
.section-header {
  min-height: 60px;
}

.section-header .group-name {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.06em;
}

.section-groups {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 0 0 10px;      /* indent marks the nesting */
  border-left: 2px solid rgba(255,255,255,0.12);
  margin-left: 6px;
}

.quote-group { margin-bottom: 0; }

.group-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 8px;
}

.quote-item {
  background: var(--tile);
  border-radius: var(--radius);
  padding: 8px 10px;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px 8px;
  /* Always reserve the stripe so flagging an item never shifts the layout. */
  border-left: 5px solid transparent;
}

/* Green-highlighted on the price sheet. Amber is taken — it means blocked. */
.quote-item.flagged { border-left-color: var(--flag); }

.qi-name {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.25;
}

.qi-price {
  font-size: 13px;
  font-weight: 600;
  opacity: 0.75;
  white-space: nowrap;
}

.qi-note {
  grid-column: 1;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--accent);
}

.qi-details {
  grid-column: 1 / -1;
  margin: 0;
  padding-left: 18px;
  font-size: 12px;
  line-height: 1.4;
  opacity: 0.8;
}

.qi-stepper {
  grid-row: 1 / span 2;
  grid-column: 2;
  display: grid;
  grid-template-columns: 48px 46px 48px;
  align-items: center;
}

.qi-stepper button {
  min-height: 56px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile-dark);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 26px;
  font-weight: 800;
}

.qi-stepper button:active { background: var(--tile-2); }

.qi-stepper output {
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.qi-stepper output input {
  width: 100%;
  min-height: 48px;
  background: rgba(0,0,0,0.25);
  border: none;
  border-radius: 8px;
  outline: 2px solid var(--accent);
  color: var(--text);
  font-size: 18px;
  font-weight: 800;
  text-align: center;
}

.quote-item.selected { outline: 2px solid var(--accent); }

.quote-item.blocked { opacity: 0.5; }
.quote-item.blocked .qi-stepper { pointer-events: none; }

/* ---- Bundle inclusion checklist ---- */
.qi-inclusions {
  grid-column: 1 / -1;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 2px;
}

.qi-inclusions label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
}

.qi-inclusions input {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  accent-color: var(--accent);
}

/* ---- Cascade-removal notice ---- */
.quote-notice {
  background: var(--tile-dark);
  border-radius: var(--radius);
  border-left: 4px solid var(--accent);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--accent);
}

/* ---- Total bar ---- */
/* No trailing room under the groups (Jeff, 2026-11-02): the old 75vh
   of padding existed so an opened subsection could scroll flush to
   the top, but it left a screenful of desert between the price book
   and Misc Charges. Groups near the end now expand in place, and
   Misc Charges follows the groups at the screen's normal gap. */
#quote-groups { padding-bottom: 0; }

.quote-total-bar {
  /* In flow at the end of the quote screen — NOT sticky (Jeff,
     2026-11-02). As a sticky bar it rode up over the Misc Charges
     card and covered its Add button while the screen scrolled; in
     flow it can never cover anything, and main's bottom padding
     (the dock layout's taller one) leaves it clear of the dock and
     the floating eye at rest. */
  z-index: 2;
  background: var(--tile-dark);
  border-radius: var(--radius);
  padding: 10px 14px;
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  align-items: center;
  gap: 12px;
  box-shadow: 0 -6px 16px rgba(0,0,0,0.35);
}

.qt-figure { text-align: left; }
.qt-figure .big { font-size: 26px; }

/* ---- Saved jobs ---- */
.jobs-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 8px;
}

#job-name {
  width: 100%;
  min-height: 56px;
  padding: 0 14px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-2);
  color: var(--text);
  font-size: 17px;
  font-weight: 700;
}

#job-name::placeholder { color: rgba(255,255,255,0.5); }

.jobs-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.job-row {
  background: var(--tile);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 10px;
}

/* A saved job's Delete wraps below Load/Send: it takes the full width
   of its own row instead of sitting orphaned under the job name, so
   the card's vertical rhythm matches its padding. */
#jobs-list .job-row > button:last-of-type {
  grid-column: 1 / -1;
}

.job-meta { min-width: 0; }

.job-name {
  font-size: 15px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.job-date { font-size: 12px; font-weight: 600; opacity: 0.75; }

.job-row button {
  min-height: 56px;
  padding: 0 14px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile-dark);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
}

.jobs-empty { font-size: 13px; font-weight: 600; opacity: 0.7; }

/* Destructive actions read differently from the teal buttons around them, but
   stay inside the collapsed panel so colour is the second line of defence. */
.reset-btn.danger {
  background: transparent;
  border: 2px solid var(--accent);
  color: var(--accent);
}

.reset-btn.danger:disabled { opacity: 0.35; }

/* ---- Export & backup ---- */
.restore-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-top: 4px;
}

#restore-input {
  width: 100%;
  min-height: 56px;
  padding: 14px;
  border: none;
  border-radius: var(--radius);
  background: var(--tile-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
}

/* The file button is the tap target, so it gets the 56px, not the input box. */
#restore-input::-webkit-file-upload-button {
  min-height: 44px;
  margin-right: 12px;
  padding: 0 14px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile-dark);
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
}

.export-status {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--tile);
}

.export-status.error { color: var(--accent); }

/* ---- Scope modal ---- */
.scope-modal {
  position: fixed;
  inset: 0;
  z-index: 10;
  /* Fully opaque on purpose: at 95% the pricing screen's dollar figures read
     straight through the sheet the customer is being shown. */
  background: var(--bg);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 16px 10px;
}

.scope-sheet {
  width: 100%;
  max-width: 480px;
  max-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--tile-dark);
  border-radius: var(--radius);
  padding: 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.scope-sheet h2 {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.scope-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.scope-item {
  background: var(--tile);
  border-radius: var(--radius);
  padding: 10px 12px;
  border-left: 5px solid transparent;
}

.scope-item.flagged { border-left-color: var(--flag); }

.scope-name {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
}

.scope-qty { font-weight: 800; opacity: 0.85; }

.scope-bullets {
  margin: 6px 0 0;
  padding-left: 20px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  opacity: 0.9;
}

/* ---- Calculator ---- */
/* Fixed to the right edge, ~1/3 down the viewport. Sits below the (opaque,
   full-screen) scope modal so it's never visible over the customer view. */
.calc-toggle {
  position: fixed;
  right: 0;
  top: 33vh;
  z-index: 5;
  min-width: 32px;
  min-height: 56px;
  border: none;
  border-radius: 10px 0 0 10px;
  background: var(--tile);
  color: var(--text);
  font-size: 22px;
  font-weight: 800;
  box-shadow: -2px 2px 8px rgba(0,0,0,0.35);
}

/* Sits BELOW the toggle, never over it — the toggle must stay reachable to
   close the panel again (it was getting covered before, with no way back). */
.calc-panel {
  position: fixed;
  right: 0;
  top: calc(33vh + 60px);
  z-index: 5;
  width: 240px;
  max-width: calc(100vw - 40px);
  background: var(--tile-dark);
  border-radius: 14px 0 0 14px;
  padding: 12px;
  box-shadow: -2px 2px 12px rgba(0,0,0,0.45);
  /* Never slide under the privacy eye (fixed bottom-right; its top
     edge sits 64px + safe-area above the viewport bottom). Cap the
     height and scroll rather than bury the bottom key row under it. */
  max-height: calc(100vh - (33vh + 60px) - 82px - env(safe-area-inset-bottom));
  overflow-y: auto;
}
/* Dock layout floats the eye above the tab bar — more clearance. */
body.layout-dock .calc-panel {
  max-height: calc(100vh - (33vh + 60px) - 148px - env(safe-area-inset-bottom));
}

/* Full width on phones (this app's own phone breakpoint — main content caps
   at 480px too); iPad and larger keep the narrow floating panel. */
@media (max-width: 480px) {
  .calc-panel {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    border-radius: var(--radius);
    /* Jeff (2026-10-31): top-anchored, the full-width keypad ran to
       the bottom of the screen and the privacy eye landed on the =
       key. Anchor by the bottom edge instead — the panel ends right
       above the eye and grows upward; the cap + scroll is only a
       safety valve for very short viewports. */
    top: auto;
    bottom: calc(82px + env(safe-area-inset-bottom));
    max-height: calc(100vh - 82px - env(safe-area-inset-bottom) - 8px);
  }
  body.layout-dock .calc-panel {
    bottom: calc(148px + env(safe-area-inset-bottom));
    max-height: calc(100vh - 148px - env(safe-area-inset-bottom) - 8px);
  }
}

.calc-topline {
  display: flex;
  align-items: stretch;
  gap: 6px;
  margin-bottom: 10px;
}

.calc-display {
  flex: 1 1 auto;
  min-width: 0;
  background: rgba(0,0,0,0.3);
  border-radius: var(--radius-sm);
  padding: 13px 12px;
  text-align: right;
  font-size: 30px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  overflow-x: auto;
  white-space: nowrap;
}

.calc-close {
  flex: none;
  min-width: 40px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 16px;
  font-weight: 800;
}

/* The history toggle: a clock button mirroring the close button on
   the display's left. Dimmed while the tape is empty, outlined while
   the tape is open. */
.calc-history-btn svg { display: block; margin: 0 auto; }
.calc-history-btn:disabled { opacity: 0.35; }
.calc-history-btn[aria-expanded="true"] { outline: 2px solid var(--accent); }

/* The history tape: finished calculations, newest at the bottom,
   small and quiet. Tapping a row recalls its result and closes the
   tape. Hidden (truly gone, no reserved space) until the clock
   button opens it. */
.calc-history {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 66px;
  overflow-y: auto;
  margin-bottom: 8px;
}

.calc-history[hidden] { display: none; }

.calc-history-row {
  border: none;
  background: none;
  color: var(--text);
  opacity: 0.6;
  text-align: right;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding: 2px 4px;
  cursor: pointer;
}

/* Keys grew ~30% taller overall (44px -> 58px rows, wider gaps, a
   larger display) at Jeff's word, 2026-10-29: the pad was fiddly at
   glove-and-kitchen-table size. */
.calc-keys {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.calc-key {
  min-height: 58px;
  border: none;
  border-radius: 10px;
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 20px;
  font-weight: 700;
}

.calc-key.op { background: var(--accent); color: var(--bg); }
.calc-key:active { filter: brightness(1.15); }

/* ---- Gating (Step 4): account bar, call links, manager screen -----------
   Same components and skin variables as the rest of the shell — the
   gating adds structure, never a second visual language. */

.account-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  /* It renders as the Home screen's footer (its last element): a
     rule sets it apart from the section above it. */
  border-top: 1px solid var(--tile-dark);
  padding-top: 10px;
}

.account-label { font-size: 13px; font-weight: 600; opacity: 0.85; }

/* Privacy saver picker (2026-11-01): sits in the account bar next to
   Help — a device-local choice, in the same small print as the name. */
.saver-setting {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  opacity: 0.85;
  white-space: nowrap;
}
.saver-setting select {
  font: inherit;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--tile-dark);
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
}

.call-links {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.call-link { text-align: center; text-decoration: none; }

.stack-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stack-form input {
  min-height: 48px;
  padding: 0 12px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 15px;
}

/* The roster list and the add form are one stack (now inside their
   own roll-up panels): a little air above the form inside its panel. */
#team-panel, #add-panel, #deleted-panel, #settings-panel { padding-top: 10px; }

.stack-form input::placeholder { color: rgba(255,255,255,0.5); }

.manager-jobs {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.manager-job {
  background: var(--tile);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* The rolled-up manager card: header is the whole tap target, body
   carries the detail when opened. */
.manager-job-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border: none;
  background: none;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.manager-job-title { flex: 1; font-size: 14px; font-weight: 700; }

.manager-job-stamp { font-size: 12px; font-weight: 600; opacity: 0.75; }

/* The two-line minimized header (Jeff's layout, 2026-10-30): money on
   line 1; rep left and date–time right on line 2. */
.manager-job-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.manager-job-main .manager-job-title { flex: none; }

.manager-job-sub {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  opacity: 0.75;
}

/* Team-card contact actions: a quiet row of handoff links under the
   person's details. */
.row-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.row-action {
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  padding: 0 16px;
  border-radius: var(--radius-sm);
  background: var(--tile-dark);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

/* Boot splash: a branded breath while the app loads. The fade-out
   animation is also the fail-safe — if the script dies, the splash
   still retires itself and can never trap the user. */
.splash {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  animation: splash-out 0.6s ease 2.6s forwards;
}

.splash.gone { opacity: 0; visibility: hidden; transition: opacity 0.45s ease, visibility 0.45s; }

@keyframes splash-out {
  to { opacity: 0; visibility: hidden; }
}

.splash-card { text-align: center; padding: 24px; }

.splash-name { font-size: 30px; font-weight: 800; letter-spacing: 0.01em; }

.splash-sub { margin-top: 4px; font-size: 15px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; opacity: 0.7; }

/* "What's new": a quiet panel under the tab bar, once per release. */
.whatsnew {
  margin: 10px 0;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--panel);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
}

.whatsnew-list { margin: 0 0 10px; padding-left: 18px; font-size: 14px; line-height: 1.45; }

/* Manager-screen select rows (rep filter, settings, edit sheet). */
.mgr-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 10px;
}

.mgr-filter select {
  min-height: 44px;
  padding: 0 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}

.stack-form select {
  min-height: 48px;
  padding: 0 12px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--tile);
  background-image: var(--sheen);
  color: var(--text);
  font-size: 15px;
}

.manager-job-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 12px 12px;
}

.manager-job-body[hidden] { display: none; }

/* A lead's event log on its card: small, quiet, one line per stamp. */
.job-events {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 600;
  opacity: 0.75;
  display: flex;
  flex-direction: column;
  gap: 2px;
  list-style: none;
}

/* The manager's new-lead popup: sits at the top of the manager screen
   until dismissed. */
.mgr-alert {
  background: var(--tile);
  background-image: var(--sheen);
  box-shadow: var(--shadow);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.mgr-alert[hidden] { display: none; }



.manager-line { font-size: 13px; font-weight: 600; }

.manager-line.dim { opacity: 0.75; }

.manager-job ul {
  list-style: none;
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sync-note { font-size: 12px; font-weight: 600; color: var(--accent); }

/* ---- Layout variants (Step 7) ------------------------------------------
   The variant is a body class (layout-classic / layout-rail /
   layout-dock) that app.js applies at boot from the client config's
   library choice (layout.js). ARRANGEMENT ONLY: the rules below move,
   restyle and respacing the SAME elements — no variant adds, removes
   or renames a component, and the gating screens (login, locked,
   manager, rates) are deliberately untouched: they inherit the body
   class but no rule here reaches them. Section ORDER is not CSS's
   job — app.js sets it from the plan (inline `order`), so a variant's
   signature here is its nav, its headline arrangement and its density.

   Classic is the shell as it shipped; its single rule restates the
   base value so all three signatures live in one place and a porter
   can diff a variant against it. */

body.layout-classic .headline-grid { grid-template-columns: 1fr 1fr; }

/* Rail — a slim segmented control instead of the big tab buttons, and
   the rollout card leading full-width with the remaining headline
   cards on a rail beneath it. */
body.layout-rail .screen-tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--tile-dark);
  border-radius: 999px;
}

body.layout-rail .screen-tabs button {
  flex: 1 1 0;
  min-height: 44px;
  border-radius: 999px;
  background: transparent;
  font-size: 15px;
}

body.layout-rail .screen-tabs button.active {
  background: var(--tile);
  outline: none;
}

body.layout-rail .headline-grid {
  display: flex;
  flex-wrap: wrap;
}

body.layout-rail .headline-grid .card { flex: 1 1 0; }

body.layout-rail .headline-grid .card:first-child {
  flex-basis: 100%;
  min-height: 96px;
}

body.layout-rail .headline-grid .card:first-child .big { font-size: 34px; }

/* Dock — the tab bar fixed to the bottom of the screen (below the
   modals' z-index, so sign-in and the scope sheet still cover it),
   headline cards stacked as full-width rows, and compact density:
   tighter gaps, shorter cards and tiles, a smaller table. */
body.layout-dock main { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }

body.layout-dock .screen-tabs {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  z-index: 5;
  width: min(480px, 100%);
  display: flex;
  gap: 6px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  background: var(--tile-dark);
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.35);
}

body.layout-dock .screen-tabs button {
  flex: 1 1 0;
  min-height: 48px;
  font-size: 15px;
}

/* The quote screen's total bar is in flow (see .quote-total-bar),
   so there is no sticky offset to park above the dock: main's
   bottom padding (above) is what leaves it clear of the dock. */

body.layout-dock .headline-grid {
  display: flex;
  flex-direction: column;
}

body.layout-dock .headline-grid .card { min-height: 60px; }

body.layout-dock main,
body.layout-dock .screen { gap: 8px; }

body.layout-dock .card { min-height: 64px; padding: 8px 10px; }

body.layout-dock .tile { min-height: 64px; }

body.layout-dock .big { font-size: 24px; }

body.layout-dock .input-section input { min-height: 48px; font-size: 30px; }

body.layout-dock .drop-table { font-size: 14px; }

body.layout-dock .drop-table td { padding: 7px 6px; }

/* =====================================================================
   DEMO F POLISH LAYER — Fairhaven Kitchen Co. (appended override block;
   the shared base above is untouched, the same arrangement Demo D uses
   for its light-build overrides).

   The design system the stock shell lacks, in one layer:
   - FLAT: no gradients, no sheen, no bevels. Solid fills, 1px borders,
     and a soft shadow reserved for primary actions and raised sheets.
   - A NEUTRAL SURFACE RAMP carries the app: warm off-white ground,
     white cards, a warm sand fill for quiet controls. Ink text, muted
     warm grey for secondary print. Brass is an ACCENT — active states,
     badges, key-number labels, links — never a surface.
   - A TYPE SCALE: price numerals are the heroes (34–38px, weight 650,
     tabular figures), section labels are small, letterspaced and
     muted, body copy sits at 15px.
   - ONE GEOMETRY: cards 14px radius, controls 10px, card padding
     16px, 12px vertical rhythm everywhere.
   The flavour tokens a manager picks at onboarding map onto this
   layer: palette (the --f-* variables below), button shape (the
   radius tokens), and arrangement (the layout variant). Restyling a
   client is re-declaring these variables, never new code.
   ===================================================================== */

body {
  --f-bg: #F6F4EF;          /* app ground — warm off-white */
  --f-surface: #FFFFFF;     /* cards, sheets, inputs */
  --f-soft: #FBFAF6;        /* quiet inset surface */
  --f-fill: #F1EDE3;        /* quiet control fill (steppers, row actions) */
  --f-line: #E4DED1;        /* 1px borders */
  --f-line-strong: #D8D0BE; /* button borders, dashed empty states */
  --f-ink: #23201B;         /* text, primary actions, active dock pill */
  --f-muted: #6E675C;       /* secondary print */
  --f-brass: #A97B1F;       /* the accent */
  --f-brass-dark: #8A651A;  /* accent where small text must hold contrast */
  --f-tint: #FBF6E9;        /* brass-tinted notice ground */
  --f-danger: #B3402A;
  --f-shadow: 0 1px 2px rgba(35, 32, 27, 0.06), 0 12px 32px rgba(35, 32, 27, 0.09);
}

/* ---- Type scale + rhythm ---- */
main { gap: 12px; }
body.layout-dock main, body.layout-dock .screen { gap: 12px; }

.label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--f-muted);
  opacity: 1;
}
.section-title {
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--f-ink);
  opacity: 1;
}
.big {
  font-size: 36px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
body.layout-dock .big { font-size: 34px; }
.small { color: var(--f-muted); font-weight: 500; opacity: 1; }
body { font-size: 15px; }

/* ---- Brand header: the logo sits on the ground, not on a plate ---- */
.brand-header { padding: 8px 0 2px; gap: 8px; }
.brand-logo {
  background: transparent;
  padding: 0;
  border-radius: 0;
}
.brand-logo-main { max-height: 76px; }
.brand-company { font-size: 17px; font-weight: 700; letter-spacing: 0.01em; color: var(--f-ink); }

/* ---- Customer bar + name gate ---- */
.customer-bar input {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-radius: 10px;
  color: var(--f-ink);
  min-height: 50px;
  box-shadow: none;
}
.customer-bar input::placeholder { color: rgba(35, 32, 27, 0.38); }
.gate-note {
  background: var(--f-tint);
  border: 1px solid var(--f-line);
  border-left: 3px solid var(--f-brass);
  border-radius: 10px;
  color: var(--f-ink);
  font-weight: 600;
}

/* ---- Tabs: the dock is a light bar; the active tab is an ink pill ---- */
.screen-tabs button {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  box-shadow: none;
  color: var(--f-muted);
  border-radius: 10px;
  white-space: nowrap;
}
.screen-tabs button.active {
  background: var(--f-ink);
  border-color: var(--f-ink);
  color: #FFFFFF;
  outline: none;
}
body.layout-dock .screen-tabs {
  background: rgba(255, 255, 255, 0.94);
  border-top: 1px solid var(--f-line);
  box-shadow: 0 -8px 24px rgba(35, 32, 27, 0.06);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
body.layout-dock .screen-tabs button {
  background: transparent;
  border: none;
  border-radius: 999px;
  color: var(--f-muted);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  min-height: 48px;
}
body.layout-dock .screen-tabs button.active {
  background: var(--f-ink);
  color: #FFFFFF;
  outline: none;
}

/* ---- Quote / Estimate toggle ---- */
.mode-toggle {
  background: var(--f-fill);
  border: 1px solid var(--f-line);
  box-shadow: none;
}
.mode-toggle button { color: var(--f-muted); }
.mode-toggle button.active {
  background: var(--f-surface);
  color: var(--f-ink);
  outline: none;
  box-shadow: 0 1px 3px rgba(35, 32, 27, 0.14);
}
.mode-note { color: var(--f-muted); opacity: 1; }

/* ---- Home: white sections, designed empty states ---- */
.home-section {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
  padding: 16px;
}
.home-note { color: var(--f-muted); font-size: 13.5px; line-height: 1.45; opacity: 1; }
.jobs-empty {
  display: block;
  border: 1.5px dashed var(--f-line-strong);
  background: var(--f-soft);
  border-radius: 10px;
  padding: 16px 14px;
  text-align: center;
  color: var(--f-muted);
  font-size: 13.5px;
  font-weight: 500;
  opacity: 1;
}
#manager-jobs > .manager-line {
  border: 1.5px dashed var(--f-line-strong);
  background: var(--f-soft);
  border-radius: 10px;
  padding: 16px 14px;
  text-align: center;
  color: var(--f-muted);
}

/* ---- Inputs: white fields, hairline borders, hero numerals ---- */
.input-section {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
  padding: 14px 16px;
}
.input-section input {
  color: var(--f-ink);
  font-size: 38px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.input-section input::placeholder { color: rgba(35, 32, 27, 0.35); }
body.layout-dock .input-section input { font-size: 34px; min-height: 52px; }
.money-input .dollar-prefix { color: var(--f-muted); font-weight: 600; opacity: 1; }
.price-row .input-section input { font-size: 27px; }
.solved-price { color: var(--f-brass-dark); }

.stack-form input, .stack-form select,
.mgr-filter select, .saver-setting select {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 10px;
  box-shadow: none;
  color: var(--f-ink);
}
.stack-form input::placeholder { color: rgba(35, 32, 27, 0.38); }
#job-name {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
#job-name::placeholder { color: rgba(35, 32, 27, 0.38); }
#restore-input {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
#restore-input::-webkit-file-upload-button {
  background: var(--f-ink);
  color: #FFFFFF;
  border: none;
  border-radius: 8px;
}
.restore-label { color: var(--f-muted); opacity: 1; }

/* ---- Headline + effect cards ---- */
.card {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
  padding: 16px 14px;
}
body.layout-dock .card { min-height: 68px; padding: 14px; }
.card .label, .tile .label { color: var(--f-brass-dark); }
.effect-lines .hl { color: var(--f-brass-dark); }

/* ---- Drop table ---- */
.drop-table {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
}
.drop-table th {
  background: var(--f-soft);
  color: var(--f-muted);
  border-bottom: 1px solid var(--f-line);
}
.drop-table td { color: var(--f-ink); border-top: 1px solid #EFEAE0; }

/* ---- Buttons: quiet white by default, ink for the primary action ---- */
.reset-btn {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line-strong);
  border-radius: 10px;
  box-shadow: none;
  color: var(--f-ink);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: normal;
  line-height: 1.25;
  padding: 10px 12px;
}
#send-manager-btn, #use-as-list, #job-save,
.gate-sheet button[type="submit"] {
  background: var(--f-ink);
  border-color: var(--f-ink);
  color: #FFFFFF;
  box-shadow: var(--f-shadow);
}
.reset-btn.danger {
  background: transparent;
  border: 1.5px solid var(--f-danger);
  color: var(--f-danger);
}
.quote-total-bar .reset-btn { font-size: 15px; padding: 8px 10px; }
.job-row button, .row-action {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  box-shadow: none;
  color: var(--f-ink);
  text-decoration: none;
}

/* ---- Quote screen ---- */
.panel-toggle, .group-header {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 12px;
  box-shadow: none;
  color: var(--f-ink);
}
.group-count { background: var(--f-brass); color: var(--f-ink); }
.group-chev { color: var(--f-muted); opacity: 1; }
.section-groups { border-left-color: var(--f-line); }
.quote-item {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-left: 5px solid transparent;
  border-radius: 14px;
  box-shadow: none;
  padding: 12px;
}
.quote-item.flagged { border-left-color: var(--flag); }
.quote-item.selected { outline: 2px solid var(--f-brass); }
.qi-price { color: var(--f-muted); opacity: 1; }
.qi-note { color: var(--f-brass-dark); }
.qi-stepper button {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
.qi-stepper button:active { background: #E9E3D3; }
.qi-stepper output input, .tile.stepper output input {
  background: var(--f-soft);
  color: var(--f-ink);
  outline: 2px solid var(--f-brass);
}
.qi-inclusions input { accent-color: var(--f-brass); }
.quote-notice {
  background: var(--f-tint);
  border: 1px solid var(--f-line);
  border-left: 3px solid var(--f-brass);
  border-radius: 10px;
  color: var(--f-ink);
}
.quote-total-bar {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: 0 -10px 28px rgba(35, 32, 27, 0.08);
  /* The floating privacy eye parks over the bar's bottom-right corner;
     ending the bar short of it keeps "Use as List Price" fully
     readable instead of clipped underneath the button. */
  margin-right: 66px;
}
.qt-figure .big { font-size: 30px; }
.misc-desc, .misc-amount {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-radius: 10px;
  color: var(--f-ink);
}
.misc-remove {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 10px;
  box-shadow: none;
  color: var(--f-ink);
}
.misc-note { color: var(--f-muted); opacity: 1; }

/* ---- Pricing tiles, plan picker ---- */
.tile {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
}
body.layout-dock .tile { min-height: 68px; }
.tile.stepper .minus, .tile.stepper .plus {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
.tile.stepper .minus:active, .tile.stepper .plus:active { background: #E9E3D3; }
.quick-grid .tile { background: var(--f-soft); background-image: none; }
.lender-toggle button {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  box-shadow: none;
  color: var(--f-muted);
}
.lender-toggle button.active {
  background: var(--f-ink);
  border-color: var(--f-ink);
  color: #FFFFFF;
  outline: none;
}
#plan-select {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  box-shadow: none;
  color: var(--f-ink);
}
#plan-select.qualified { color: var(--f-brass-dark); }
.export-status {
  background: var(--f-soft);
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
.export-status.error { color: var(--f-danger); }

/* ---- Job rows, manager cards, alerts ---- */
.job-row {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
}
.job-date, .manager-job-stamp, .manager-job-sub { color: var(--f-muted); opacity: 1; }
.manager-job {
  background: var(--f-surface);
  background-image: none;
  border: 1px solid var(--f-line);
  border-radius: 14px;
  box-shadow: none;
}
.manager-job-head { color: var(--f-ink); }
.mgr-alert {
  background: var(--f-tint);
  background-image: none;
  border: 1px solid var(--f-brass);
  box-shadow: none;
  color: var(--f-ink);
}
.manager-line.dim { color: var(--f-muted); opacity: 1; }
.sync-note { color: var(--f-brass-dark); }

/* ---- Sheets: raised white cards; the gate is a composed sign-in ---- */
.scope-sheet {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  border-radius: 16px;
  box-shadow: var(--f-shadow);
}
.scope-item {
  background: var(--f-soft);
  border: 1px solid var(--f-line);
  border-left: 5px solid transparent;
  border-radius: 12px;
}
.scope-item.flagged { border-left-color: var(--flag); }
.scope-modal:has(> .scope-sheet.gate-sheet) { align-items: center; }
.gate-sheet { padding: 30px 24px 22px; gap: 16px; }
.gate-sheet .brand-lockup { gap: 10px; }
.gate-sheet .brand-logo-gate { max-height: 118px; }
.gate-sheet .brand-company-gate { font-size: 20px; }
.gate-sheet h2 {
  text-align: center;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: none;
}
.gate-sheet .stack-form input { min-height: 52px; font-size: 16px; }
.gate-foot { text-align: center; font-size: 12.5px; color: var(--f-muted); }

/* ---- Veil, splash, account bar, calculator ---- */
#privacy-veil { background: var(--f-bg); }
.veil-company { color: var(--f-ink); }
.veil-hint { color: var(--f-muted); opacity: 1; }
.privacy-btn {
  background: var(--f-ink);
  background-image: none;
  border: 1px solid var(--f-ink);
  box-shadow: var(--f-shadow);
  color: #FFFFFF;
}
.splash { background: var(--f-bg); }
.splash-name { color: var(--f-ink); }
.splash-sub { color: var(--f-brass-dark); opacity: 1; }
.account-bar { border-top-color: var(--f-line); }
.account-label { color: var(--f-muted); opacity: 1; }
.whatsnew {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  box-shadow: none;
}
.calc-toggle { background: var(--f-ink); color: #FFFFFF; box-shadow: var(--f-shadow); }
.calc-panel {
  background: var(--f-surface);
  border: 1px solid var(--f-line);
  box-shadow: var(--f-shadow);
}
.calc-display { background: var(--f-soft); color: var(--f-ink); }
.calc-key {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
.calc-key.op { background: var(--f-brass); border-color: var(--f-brass); color: #FFFFFF; }
.calc-close {
  background: var(--f-fill);
  background-image: none;
  border: 1px solid var(--f-line);
  color: var(--f-ink);
}
.calc-history-row { color: var(--f-muted); opacity: 1; }

/* ---- The Change Price alert surface, in the light system ---- */
#screen-rates-change {
  background: #FBEEE9;
  border: 1px solid #D9A08E;
  border-radius: 14px;
}
.rates-alert-note { color: var(--f-danger); }
