/* TradeDraft TradeDraft — engine styles.
   Extracted from app.html (was 4 inline <style> blocks) into one module.
   Concatenated in the original document order, so the cascade is byte-for-byte
   the same as when these were inline. Linked render-blocking from <head>. */


/* =============================================================
   TRADEdraft — TradeDraft  ·  clean rebuild (v9)
   Brand-locked · mobile-first · cost-only engine · production-grade
   ============================================================= */

:root{
  /* Brand palette, status, structure (--line/--r-*) + the type scale live in css/tokens.css — the
     single source linked FIRST by every surface. APP-ONLY tokens below; don't re-declare a shared
     one here (--line/--line-strong/--green-soft/--amber/--amber-soft/--red-soft moved to tokens.css
     on 16 Jul 2026 — every surface needed them, and duplicated tokens are how they drift apart). */
  --field-line:#948b7b;
  --shadow-sm:0 1px 2px rgba(0,33,71,.06);
  --shadow-md:0 4px 14px rgba(0,33,71,.10);
  --shadow-lg:0 18px 48px rgba(0,33,71,.18);
  --r-lg:14px; --r-xl:20px;   /* app-only radii; --r-sm/--r-md are shared → css/tokens.css */
}
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--prose); color:var(--slate); background:var(--chalk);
  font-size:15px; line-height:1.5;
  -webkit-font-smoothing:antialiased; -webkit-tap-highlight-color:transparent;
}
button{font-family:inherit;cursor:pointer;border:0;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
:focus-visible{outline:2px solid var(--navy);outline-offset:2px;border-radius:3px;box-shadow:0 0 0 4px var(--brass)}  /* two-layer: navy on light + brass halo on navy — WCAG 1.4.11 AA (was brass-only, ~2.2:1 on light) */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}

/* ── TOP BAR ─────────────────────────────────────────────── */
.topbar{position:sticky;top:0;z-index:50;background:var(--ink-navy);color:#fff;
  height:62px;padding:0 52px;display:flex;align-items:center;gap:10px;border-bottom:2px solid var(--brass-soft)}
  /* 62px = 60px content + 2px brass border (border-box). Matches the marketing .nav exactly (60px
     .nav-inner + 2px border OUTSIDE it = 62px) so the bar + logo + nav links sit at the same height
     across pages and don't jump when you navigate to/from TradeDraft. Keep in sync with .nav. */
@media(max-width:620px){.topbar{padding:0 16px}}
.wordmark{font-family:var(--sans);font-size:21px;line-height:1;letter-spacing:.02em;color:#fff;text-decoration:none;display:inline-flex;align-items:baseline}
.wm-trade{font-weight:700;letter-spacing:.02em}
.wm-draft{font-weight:300;color:var(--brass)}
.proto-tag{font-family:var(--sans);font-size:9px;letter-spacing:1.5px;background:var(--brass);
  color:var(--navy);padding:3px 7px;border-radius:3px;font-weight:700}
.tb-spacer{flex:1}
.tb-product{display:inline-flex;align-items:center;margin-left:14px;font-family:var(--sans);font-size:15px;font-weight:500;letter-spacing:.05em;color:rgba(255,255,255,.9)}
.tb-product::before{content:"";width:1px;height:20px;background:rgba(197,160,89,.55);margin-right:14px}
@media(max-width:360px){.tb-product{display:none}}
.tb-nav{display:flex;gap:22px;align-items:center}
.tb-nav a{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.66);text-decoration:none;padding:0 0 3px;border-bottom:1.5px solid transparent;transition:color .12s,border-color .12s}
.tb-nav a:hover{color:#fff;border-bottom-color:var(--brass)}
.tb-nav a.active{color:#fff;border-bottom-color:var(--brass)}
/* "Sign in" link — mirrors the marketing nav's .nav-signin exactly (divider + 32px gap) */
.tb-nav a.tb-signin{position:relative;text-transform:uppercase;letter-spacing:.1em;font-size:11px;font-weight:600;color:rgba(255,255,255,.66);border-bottom:0;margin-left:32px;white-space:nowrap;cursor:pointer}
.tb-nav a.tb-signin::before{content:"";position:absolute;left:-16px;top:50%;transform:translateY(-50%);width:1px;height:15px;background:rgba(255,255,255,.18)}
.tb-nav a.tb-signin:hover{color:rgba(255,255,255,.95);border-bottom:0}
/* Signed-in desktop account chip — mirrors dashboard.html + the marketing pages. The engAcctChip IIFE
   adds .signed-in to .topbar (first paint via the session sniff, then corrected by renderAuth's live
   auth), which swaps the "Sign in" link OUT for the chip. Lives inside .tb-nav → desktop-only for
   free (.tb-nav is display:none below 860px; the burger drawer covers mobile). */
.acct-wrap{display:none}
.topbar.signed-in .tb-signin{display:none}
.topbar.signed-in .acct-wrap{position:relative;display:flex;align-items:center;margin-left:32px}
.topbar.signed-in .acct-wrap::before{content:"";position:absolute;left:-16px;top:50%;transform:translateY(-50%);width:1px;height:15px;background:rgba(255,255,255,.18)}
.acct-chip{display:flex;align-items:center;gap:9px;cursor:pointer;color:#fff;background:none;border:0;font-family:var(--sans);padding:0}
.acct-av{width:30px;height:30px;border-radius:50%;background:var(--brass);color:var(--navy);font-family:var(--sans);font-weight:700;font-size:12px;display:flex;align-items:center;justify-content:center;flex:none;overflow:hidden}
.acct-av img{width:100%;height:100%;object-fit:cover}
.acct-name{font-family:var(--sans);font-size:12.5px;font-weight:500;color:rgba(255,255,255,.92);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acct-name .car{color:rgba(255,255,255,.5);margin-left:6px}
.acct-menu{position:absolute;top:44px;right:0;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 16px 40px rgba(0,33,71,.22);min-width:230px;padding:6px;display:none;z-index:70}
.acct-menu.open{display:block}
.acct-menu a,.acct-menu button{display:flex;align-items:center;gap:11px;width:100%;text-align:left;font-family:var(--prose);font-size:14px;font-weight:500;letter-spacing:normal;text-transform:none;color:var(--navy);background:none;border:0;padding:9px 12px;border-radius:8px;cursor:pointer;text-decoration:none}
.acct-menu a:hover,.acct-menu button:hover{background:rgba(0,33,71,.08);color:var(--navy)}
.acct-menu a svg,.acct-menu button svg{width:18px;height:18px;flex:none;color:var(--steel)}
/* "£" prices icon — via ::before so the glyph isn't in the menu's text (the account-dropdown parity guard reads the label as just "Prices") */
.acct-menu .am-pound{width:18px;height:18px;flex:none;display:inline-flex;align-items:center;justify-content:center;color:var(--steel);font-family:var(--sans);font-size:17px;font-weight:700;line-height:1}
.acct-menu .am-pound::before{content:"£"}
.acct-menu a:hover svg,.acct-menu button:hover svg{color:var(--navy)}
.acct-menu hr{border:0;border-top:1px solid var(--line);margin:5px 4px}
.am-head{display:flex;align-items:center;gap:10px;padding:10px 12px 12px}
.am-av{width:36px;height:36px;border-radius:50%;background:var(--brass);color:var(--navy);font-family:var(--sans);font-weight:700;font-size:13px;display:flex;align-items:center;justify-content:center;flex:none;overflow:hidden}
.am-av img{width:100%;height:100%;object-fit:cover}
.am-id{min-width:0;display:flex;flex-direction:column;line-height:1.3}
.am-id b{font-family:var(--sans);font-size:13.5px;font-weight:600;color:var(--navy);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.am-id span{font-size:11.5px;color:var(--steel);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.am-out{color:#9A3526}
.am-out svg{color:#9A3526!important}
/* Mobile burger + drawer — TradeDraft mirrors the site nav for cross-page consistency */
.tb-burger{display:none;order:5;width:44px;height:44px;align-items:center;justify-content:center;flex-direction:column;gap:5px;background:none;border:0;cursor:pointer;padding:0}
.tb-burger span{width:22px;height:2px;background:#fff;border-radius:2px;transition:.2s}
.tb-burger.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.tb-burger.open span:nth-child(2){opacity:0}
.tb-burger.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.tb-drawer{position:fixed;top:62px;right:22px;left:auto;z-index:55;width:min(300px,calc(100vw - 28px));background:#fff;display:flex;flex-direction:column;padding:8px;border:1px solid rgba(0,33,71,.12);border-radius:14px;box-shadow:0 18px 44px rgba(0,33,71,.22);transform:translateY(-10px);opacity:0;visibility:hidden;transition:transform .2s,opacity .2s,visibility .2s}
.tb-drawer.open{transform:translateY(0);opacity:1;visibility:visible}
.tb-drawer a{font-family:var(--sans);font-size:15px;font-weight:500;color:var(--navy);padding:11px 12px;border-radius:8px;text-decoration:none;cursor:pointer;display:flex;align-items:center;gap:9px;transition:background .12s}
.tb-drawer a:hover{background:rgba(0,33,71,.06)}
.tb-drawer a.active{color:var(--brass-deep);background:rgba(197,160,89,.1)}
.tb-drawer span{color:var(--brass-deep)!important}
.tb-drawer hr{border-top-color:rgba(0,33,71,.12)!important}
#engDrawerInstall{background:rgba(197,160,89,.14);color:var(--brass-deep);font-weight:700;border:1px solid rgba(197,160,89,.4);margin-bottom:4px}
.tb-drawer .dr-in{display:none}
.tb-drawer.signed-in .dr-in{display:block}
@media(min-width:861px){.tb-drawer{display:none!important}}
@media(max-width:860px){.tb-nav{display:none}.tb-burger{display:flex}}
/* Installed app (standalone PWA): hide the marketing links (Home/Pricing/Templates) so it reads as an app, not a webpage. A normal browser tab keeps the full nav. */
@media(display-mode:standalone){.tb-nav a.tb-site,.tb-drawer a.tb-site{display:none}}
.tb-btn{font-family:var(--sans);font-size:11px;letter-spacing:1px;color:rgba(255,255,255,.78);
  background:none;border:0;padding:6px;border-radius:6px;text-transform:uppercase;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;min-height:40px;transition:color .12s,background .12s}
.tb-btn:hover{color:#fff;background:rgba(255,255,255,.08)}
.tb-ico{width:23px;height:23px;color:var(--brass-soft);flex-shrink:0}
/* Signed-out demo bar — reframes the app as a try-it demo until you sign in (toggled in renderAuth) */
.demo-bar{display:none;align-items:center;gap:12px 14px;flex-wrap:wrap;background:var(--amber-soft);border-bottom:1px solid #e8d49a;padding:9px 52px;font-size:13px;color:#5c4310;line-height:1.4}
.demo-bar.show{display:flex}
.demo-bar .demo-dot{font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.12em;background:var(--brass);color:var(--navy);padding:3px 8px;border-radius:4px;flex:none}
.demo-bar .demo-txt{flex:1 1 auto;min-width:150px}
.demo-bar .demo-cta{font-family:var(--sans);font-weight:700;font-size:12px;color:var(--navy);text-decoration:underline;white-space:nowrap;cursor:pointer}
.demo-bar .demo-cta:hover{color:var(--brass-deep)}
@media(max-width:620px){.demo-bar{padding:8px 16px;font-size:12px;gap:8px 10px}.demo-bar .demo-txt{display:none}}

/* ── STEPPER ─────────────────────────────────────────────── */
.stepper-wrap{position:sticky;top:62px;z-index:40;background:var(--chalk);
  border-bottom:2px solid var(--brass-soft);padding:12px 52px;display:flex;align-items:center;justify-content:space-between;gap:32px}
.stepper{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:6px}  /* full width now that My Quotes/Settings left the bar (13 Jun) */
.stepper-wrap .stepper-actions{flex:0 0 auto;display:flex;align-items:center;gap:8px}
@media(max-width:1140px){.stepper-wrap{gap:16px;padding:12px 22px}}
@media(max-width:600px){.tb-btn-label{display:none}.stepper-wrap .stepper-actions .tb-btn{padding:7px 9px}}
/* Mobile: the action icons are lifted into the top header (see relocateStepperActions) */
.topbar .stepper-actions{display:flex;align-items:center;gap:6px}
.topbar .stepper-actions .tb-btn-label{display:none}
.topbar .stepper-actions .tb-btn{padding:7px 9px}
.step{display:flex;align-items:center;gap:8px;flex:0 0 auto;font-family:var(--sans);cursor:pointer}
.step:hover .step-dot{box-shadow:0 0 0 3px rgba(197,160,89,.22)}
.step:focus-visible{outline:2px solid var(--brass);outline-offset:3px;border-radius:6px}
.step-dot{width:26px;height:26px;border-radius:50%;background:rgba(0,33,71,.08);
  color:rgba(0,33,71,.55);display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:700;flex-shrink:0;transition:.2s}
.step-label{font-size:10px;letter-spacing:1.2px;text-transform:uppercase;color:rgba(0,33,71,.45);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:.2s}
.step.is-active .step-dot{background:var(--brass);color:var(--navy)}
.step.is-active .step-label{color:var(--navy)}
.step.is-done .step-dot{background:rgba(197,160,89,.28);font-size:0;position:relative}
.step.is-done .step-dot::after{content:'✓';position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--brass-deep);font-size:13px;font-weight:700}
.step.is-done .step-label{color:rgba(0,33,71,.62)}
/* ── READINESS-DRIVEN STEPPER (18 Jul 2026; quietened 19 Jul 2026) ─────────────────────────────
   .is-done means the step is GENUINELY finished (quoteReadiness/stepReady in app.html), not that
   you walked past it. .is-todo is its counterpart and is DELIBERATELY UNSTYLED (owner, 19 Jul):
   the amber "!" dot and the .step-sub outstanding-note words made a fresh quote open onto a bar of
   warnings; the "Ready to send?" checklist on Review carries the detail, from the same readiness
   facts. The class stays in the DOM as the truth hook the tests read — don't restyle it. */
.step-line{flex:1;height:1px;background:rgba(0,33,71,.14);margin:0 4px}
@media (max-width:760px){.step-label{display:none}.step.is-active .step-label{display:block;font-size:9px}}

/* ── SIMPLE / ADVANCED MODE ──────────────────────────────── */
body.eng-simple .adv-only{display:none!important}      /* hide advanced controls in Simple */
body:not(.eng-simple) .simple-only{display:none!important}  /* hide simple-only notes in Advanced */

/* ── LAYOUT ──────────────────────────────────────────────── */
.app-shell{display:grid;grid-template-columns:1fr;max-width:none;margin:0;min-height:calc(100vh - 132px)}
@media (min-width:980px){.app-shell{grid-template-columns:1fr 1fr;padding:0}}
.builder{background:var(--paper);padding:0 16px 130px;min-width:0}
@media (min-width:980px){.builder{padding:0 52px 96px;border-right:3px solid rgba(197,160,89,.85)}}
/* Won/accepted quote = read-only. The stage content greys out + stops taking clicks; the lock bar
   (outside any .stage) keeps its buttons live so "Add variation" / "Unlock to edit" still work. */
#appShell.is-locked .stage.is-active{opacity:.55;pointer-events:none;animation:none}
/* Job overview — the landing screen when a FINISHED (sent/accepted/…) quote is opened, so you see the
   job before you edit it. Drafts skip it and open straight in the builder. Toggled by body.ov-active. */
.job-ov{display:none;background:#fff;padding:0 0 90px;min-height:calc(100vh - 132px)}/* white body to flow with the de-blued portal (was chalk); flat white cards sit on it (owner, 15 Jul) */
body.ov-active .job-ov{display:block}
/* Hide the builder's step chrome on the overview: the stepper, the appShell, AND the fixed
   Back/Next bar + reactive step hint (both are viewport-fixed siblings of #appShell, so they'd
   otherwise stay pinned to the bottom of the overview and wrongly step you into the builder). */
body.ov-active #appShell,body.ov-active .stepper-wrap,body.ov-active .bottom-bar,body.ov-active .bottom-hint{display:none!important}
/* the builder's split-view preview edge-tab is fixed at the 50% seam — hide it on the overview,
   where there's no split view, so it doesn't float over the card content. */
body.ov-active .pv-toggle{display:none!important}
/* ── Job record (v2, 18 Jul 2026) — context bar → header (identity + money + lifecycle rail +
   actions) → ONE reading column with marginal headings. The old full-bleed 5-node stepper band and
   the three equal "bubble" cards are RETIRED (owner): the stepper borrowed the builder's wayfinder
   look for read-only history, and the boxes gave three different kinds of fact one uniform. Keeps
   the jo- class names the click-handler + tests depend on where semantics survived. ── */
/* context bar — the builder-family chalk strip, doing WAYFINDING (back · ref · status), which is
   what a bar in this position should do. Never pretends to be steps. */
/* 51px + its 1px rule = 52px, the SAME total height as the builder's .stepper-wrap (12px padding
   × 2 + content + a 2px rule). They're the same component in two places — the chalk wayfinding
   strip — so they must not sit a few pixels apart (owner, 19 Jul 2026). Pinned by a test. */
.jo-ctx{background:var(--chalk);border-bottom:1px solid var(--brass);padding:0 26px;height:52px;display:flex;align-items:center;gap:14px}
.jo-ctx-back{font-family:var(--sans);font-size:12.5px;font-weight:600;color:var(--navy);text-decoration:none;display:inline-flex;align-items:center;gap:7px}
.jo-ctx-back:hover{color:var(--brass-deep)}
.jo-ctx-div{width:1px;height:15px;background:rgba(0,33,71,.16)}
.jo-ctx-ref{font-family:var(--mono);font-size:12px;color:var(--steel);letter-spacing:.03em}
/* status = the plain coloured WORD alone (owner, 19 Jul 2026: the dot is gone — don't re-add) */
.jo-ctx-st{font-family:var(--sans);font-size:12.5px;font-weight:600;display:inline-flex;align-items:center;gap:7px;margin-left:auto}
/* one measure: the whole record sits on ~940px; at desktop the section headings move into the
   left gutter (marginal headings) so content rows keep a tight ~650px measure */
.jo-wrap{max-width:940px;margin:0 auto;padding:0 26px}
.jo-band{border-bottom:1px solid var(--line)}
.jo-band .jo-wrap{padding-top:30px;padding-bottom:26px}
.jo-head-row{display:flex;justify-content:space-between;align-items:flex-start;gap:44px;flex-wrap:wrap}
.jo-head-main{min-width:0;flex:1 1 300px}
.jo-meta{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:11px}
.jo-pill{font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:2px 8px;border-radius:3px}
.jo-pill.st-var{color:var(--brass-deep);border:1px solid var(--brass);background:none}
.jo-client{font-family:var(--serif);font-weight:600;color:var(--navy);font-size:clamp(27px,4.4vw,38px);line-height:1.05;margin:0}
.jo-addr{font-size:14px;color:var(--steel);margin:9px 0 0}
.jo-job{font-family:var(--sans);font-size:14px;color:var(--brass-deep);font-weight:500;margin:4px 0 0}
.jo-hero-pay{flex:0 0 auto;min-width:0;text-align:right}
@media(min-width:680px){.jo-hero-pay{padding-left:40px;border-left:1px solid var(--line)}}
.jo-hero-pay .k{font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--steel)}
.jo-hero-pay .v{font-family:var(--mono);font-size:clamp(32px,5.6vw,44px);color:var(--navy);font-weight:600;line-height:1;margin-top:8px;font-variant-numeric:tabular-nums}
.jo-hero-pay .sub{font-size:12px;color:var(--steel);margin-top:9px}

/* lifecycle rail — compact history INSIDE the header, a third the old band's height.
   Completed = solid brass · current = ringed navy · future = hollow hairline. Reads as
   record, never as buttons. Keeps .jo-node/.nlab/.ndate/.cur/.done/.dead (tests). */
.jo-track{margin-top:26px;display:flex;align-items:flex-start;max-width:520px}
.jo-node{flex:1 1 0;position:relative;padding-top:16px;min-width:0}
.jo-node .ln{position:absolute;top:4px;left:0;right:0;height:1px;background:var(--line-strong);opacity:.5}
.jo-node:first-child .ln{left:50%}
.jo-node:last-child .ln{right:50%}
.jo-node .dot{position:absolute;top:0;left:calc(50% - 4.5px);width:9px;height:9px;border-radius:50%;background:#fff;border:1.5px solid var(--line-strong)}
.jo-node.done .dot{background:var(--brass);border-color:var(--brass)}
.jo-node.done .ln{background:var(--brass);opacity:1}
.jo-node.cur .dot{background:var(--navy);border-color:var(--navy);box-shadow:0 0 0 3.5px rgba(0,33,71,.13)}
.jo-node.dead .dot{background:var(--st-bad);border-color:var(--st-bad)}
.jo-node .nlab{display:block;text-align:center;font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:rgba(0,33,71,.34);line-height:1.2}
.jo-node.done .nlab{color:rgba(0,33,71,.58)}
.jo-node.cur .nlab{color:var(--navy)}
.jo-node.dead .nlab{color:var(--st-bad)}
.jo-node .ndate{display:block;text-align:center;font-family:var(--mono);font-size:10px;color:var(--steel);margin-top:3px;line-height:1}

/* actions — ONE primary, honest secondaries, and View quote always present on the far
   right as the constant reference */
.jo-acts{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:28px}
.jo-acts .sp{flex:1 1 auto}
.jo-btn{font-family:var(--sans);font-size:13.5px;font-weight:600;padding:0 20px;min-height:46px;border-radius:8px;border:1.5px solid var(--line);background:#fff;color:var(--navy);cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;justify-content:center;gap:8px}
.jo-btn:hover{border-color:var(--brass)}
.jo-btn.primary{background:var(--navy);color:#fff;border-color:var(--navy)}
.jo-btn.primary:hover{background:var(--navy-2);border-color:var(--navy-2)}
.jo-btn.sm{min-height:38px;padding:8px 16px;font-size:13px}
.jo-btn svg{width:15px;height:15px;flex:none}

/* body — sections separated by air + a full-width rule, not boxes. At ≥880px each section is a
   grid: heading right-aligned in the left margin column, content on the reading column. */
.jo-body{padding:34px 0 100px}
.jo-sec{margin-bottom:44px}
.jo-sec:last-child{margin-bottom:0}
.jo-eyebrow{font-family:var(--sans);font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--steel);margin:0 0 16px;padding-bottom:9px;border-bottom:1px solid var(--line)}
.jo-sc{min-width:0}
@media(min-width:880px){
  .jo-sec{display:grid;grid-template-columns:190px minmax(0,1fr);column-gap:46px;
          border-top:1px solid var(--line);padding-top:20px;margin-bottom:36px}
  .jo-sec:first-child{border-top:none;padding-top:0}   /* the header's own rule serves */
  .jo-eyebrow{border-bottom:none;text-align:right;margin:2px 0 0;padding:0}
}

/* invoice-history table on the job overview — a per-job record of invoices sent + paid */
.jinv{width:100%;border-collapse:collapse;font-size:13.5px}
.jinv th{text-align:left;font-family:var(--sans);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--steel);padding:0 0 8px;border-bottom:1px solid var(--line)}
.jinv td{padding:11px 0;border-bottom:1px solid var(--line);vertical-align:middle}
.jinv tr:last-child td{border-bottom:none}
.jinv th:nth-child(2),.jinv td:nth-child(2){padding-right:16px}
/* AMOUNT is the last column and hard right — it shares the record's one money column, and nothing
   sits to its right to push it out of line (owner, 19 Jul 2026). */
.jinv th:nth-child(4),.jinv td:nth-child(4){text-align:right;padding-right:0}
.jinv .jinv-no,.jinv .jinv-no a{font-family:var(--mono);font-weight:600;color:var(--navy);text-decoration:none}
.jinv .jinv-no a:hover{text-decoration:underline}
.jinv .jinv-amt{font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--navy)}
/* status = plain coloured text, not a filled pill (the no-bubbles rule, 17 Jul) */
.jinv-state{font-family:var(--sans);font-size:12.5px;font-weight:600;white-space:nowrap}
.jinv-state.is-paid{color:#2F6F43}
.jinv-state.is-due{color:var(--steel)}
.jinv-state.is-void{color:#8a8175}
/* settle-by-hand, on the row it belongs to — a quiet text action, not a second primary button */
.jinv-mark{margin-left:10px;font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);
  background:none;border:none;padding:2px 0;cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.jinv-mark:hover{color:var(--brass-deep)}

/* where it stands — a bold plain-English LEAD (the answer) with the status dot, then the
   supporting detail line under it. One glance answers "what's happening with this job". */
/* ("Where it stands" lived here. It has gone — the status is stated ONCE, by the context bar's
   word, with the rail carrying the dates. See .jo-ctx-when and .jo-actnote for the two facts that
   were riding inside it and needed a home: a draft's last-edited, and why "Raise invoice" is
   absent on a fully-invoiced job. Owner, 19 Jul 2026.) */
.jo-ctx-when{font-weight:400;color:var(--steel)}
.jo-ctx-when::before{content:"·";margin:0 6px;color:var(--steel)}
/* the note that stands in for a button that is deliberately not there — it belongs where the
   button was, not in a section further down the page */
.jo-actnote{font-family:var(--sans);font-size:13px;color:var(--steel);margin:14px 0 0}

/* nudge — a brass-ruled inset (the quote document's own emphasis device), not a filled bubble */
.jo-nudge{border-left:2px solid var(--brass);padding:2px 0 2px 16px;margin-top:20px}
.jo-nudge-msg{font-family:var(--sans);font-size:13.5px;line-height:1.5;color:var(--slate);margin:0}
.jo-nudge-msg strong{color:var(--navy)}
.jo-nudge-acts{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-top:12px}
.jo-nudge-done{font-family:var(--sans);font-size:12.5px;font-weight:600;color:var(--steel);background:none;border:none;cursor:pointer;text-decoration:underline;padding:6px 2px}
.jo-nudge-none{font-family:var(--sans);font-size:12.5px;color:var(--steel)}

/* ── THE JOB RECORD'S MONEY SCALE — one size per ROLE, and no role gets two sizes ──────────────
   The record had drifted to eight different money treatments (owner spotted it, 19 Jul 2026): the
   two ledgers ended their sums at DIFFERENT sizes (20px vs 15px) for the same job, and the "Valid"
   row had a 12.5px of its own that matched nothing. The scale below is the whole vocabulary — a new
   figure takes one of these rather than inventing a ninth. Pinned by job-overview.spec.js.
     44px      hero headline (the contract sum, stated once at the top)
     17px/700  a ledger's TERMINAL row — .jo-sum .r.total b AND .jo-pb.grand b, the same because
               they are the same thing: the last figure of a sum. Loud against 13px rows without
               competing with the 44px hero, which already states the client-pays number.
     13px/700  a sub-total landmark inside a ledger (Break-even)
     13px/600  an ordinary ledger row
     12px/400  a MEMO — adds up to nothing, so it's quieter AND smaller (the totals-ledger rule)

   the quote / the contract — plain ruled rows; the MONEY typography still follows the quote
   document's totals standard: tabular mono, ONE terminal figure carrying the heavy navy rule,
   memo rows quieter BELOW it (they sit under the rule, so they can't read as part of the sum) */
.jo-sum .r{display:flex;justify-content:space-between;gap:18px;padding:11px 0;border-bottom:1px solid var(--line);font-family:var(--sans);font-size:13px;color:var(--steel)}
.jo-sum .r b{font-family:var(--mono);font-weight:600;color:var(--slate);font-variant-numeric:tabular-nums}
.jo-sum .r.total{border-bottom:none;border-top:2px solid var(--navy);margin-top:4px;padding-top:15px}
.jo-sum .r:has(+ .r.total){border-bottom:none}   /* the heavy rule IS the divider — no thin line stacked above it */
.jo-sum .r.total span{font-family:var(--sans);color:var(--navy);font-weight:700;font-size:14px}
.jo-sum .r.total b{font-size:17px;font-weight:700;color:var(--navy)}   /* terminal — matches .jo-pb.grand b */
.jo-sum .memo{display:flex;justify-content:space-between;gap:18px;padding:10px 0 0;font-family:var(--sans);font-size:12px;color:var(--steel)}
.jo-sum .memo b{font-family:var(--mono);font-weight:400;color:var(--steel);font-variant-numeric:tabular-nums}
.jo-sum .r.sep{border-bottom:none;margin-top:14px;padding-top:13px;border-top:1px solid var(--line)}   /* a fact row, not money — takes the ordinary 13px, no size of its own */
.jo-sum .r.is-exp b{color:var(--red)}
/* drift note — working copy re-prices away from the accepted contract; a brass-ruled inset
   heads-up in the document's own emphasis language, not a tinted bubble */
.jo-sum .r.jo-drift{display:block;border-bottom:none;margin-top:12px;padding:2px 0 2px 16px;border-left:2px solid var(--brass);
  font-size:12px;line-height:1.5;color:var(--slate)}
.jo-sum .r.jo-drift span{display:block}

/* costs & margin (private) — no chalk panel, no box: the brass label + eye-off mark + the
   "yours only" note carry the privacy, in words rather than a container */
.jo-pm{margin-bottom:14px}
.jo-priv-top{display:flex;align-items:center;gap:7px;margin-bottom:5px}
.jo-priv-lbl{font-family:var(--sans);font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--brass-deep);display:inline-flex;align-items:center;gap:6px}
.jo-priv-lbl svg{width:13px;height:13px}
.jo-priv-note{font-family:var(--sans);font-size:11.5px;color:var(--steel);margin:0;padding-bottom:11px;border-bottom:1px solid var(--line)}
@media(min-width:880px){
  .jo-pm{margin-bottom:0;text-align:right}
  .jo-priv-top{justify-content:flex-end;margin-top:2px}
  .jo-priv-note{border-bottom:none;padding-bottom:0;margin-top:6px;line-height:1.5}
}
/* margin health — a DOT + plain coloured text; no filled lozenge (owner rule) */
.jo-health{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-size:13px;font-weight:600;margin-bottom:13px}
.jo-health .dot{width:8px;height:8px;border-radius:50%;flex:none}
/* (.jo-priv-n / .jo-priv-m — the 27px profit headline — removed 19 Jul 2026. It duplicated the
   "Profit · N%" ledger row a few centimetres below it, figure and percentage both. That drops the
   record's money scale to four sizes; the section-headline 27px no longer has a user here.) */
.jo-build{margin-top:20px;display:flex;flex-direction:column}
.jo-pb{display:flex;justify-content:space-between;gap:16px;padding:11px 0;border-bottom:1px solid var(--line);font-family:var(--sans);font-size:13px;color:var(--steel)}
.jo-pb b{font-family:var(--mono);font-weight:600;color:var(--slate);font-variant-numeric:tabular-nums}
.jo-pb .rsub{font-style:normal;font-weight:400;font-size:11.5px;color:var(--steel)}   /* day-rate maths inline after its label — one line, one row */
.jo-pb.total span,.jo-pb.total b{color:var(--navy);font-weight:700}
.jo-pb.grand{border-bottom:none;border-top:2px solid var(--navy);margin-top:4px;padding-top:15px}
.jo-pb:has(+ .jo-pb.grand){border-bottom:none}   /* same — one rule above the terminal figure, not two */
.jo-pb.grand span{color:var(--navy);font-weight:700;font-size:14px}
.jo-pb.grand b{color:var(--navy);font-size:17px;font-weight:700}   /* terminal — matches .jo-sum .r.total b */
/* the quiet qualifier on the terminal label. Needs to out-rank `.jo-pb.grand span` (which is
   0,2,1) or it inherits that row's 700/14px and shouts as loud as the label it qualifies. */
.jo-pb.grand span .exvat,.jo-pb .exvat{font-weight:400;font-size:11px;color:var(--steel)}

/* details — the same plain ruled list */
.jo-det .r{display:flex;justify-content:space-between;gap:20px;font-family:var(--sans);font-size:13px;padding:11px 0;border-bottom:1px solid var(--line);color:var(--steel)}
.jo-det .r:last-child{border-bottom:none}
.jo-det .r b{color:var(--slate);font-weight:600}

/* read-only quote viewer — the REAL document (the same HTML the PDF/print path snapshots),
   over a navy scrim. "View quote" must show the quote, not a send flow. */
.jo-viewer{display:none;position:fixed;inset:0;z-index:120;background:rgba(0,24,48,.62)}
body.jv-open .jo-viewer{display:block}
body.jv-open{overflow:hidden}
.jv-bar{position:absolute;top:0;left:0;right:0;height:54px;background:var(--navy);display:flex;align-items:center;justify-content:space-between;gap:14px;padding:0 18px}
.jv-ttl{font-family:var(--sans);font-size:13px;font-weight:600;color:#fff;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jv-scroll{position:absolute;top:54px;bottom:0;left:0;right:0;overflow:auto;padding:26px 14px 60px;-webkit-overflow-scrolling:touch}
.jv-doc{max-width:620px;margin:0 auto}

@media(max-width:620px){
  .jo-band .jo-wrap{padding-top:22px;padding-bottom:24px}
  /* Stacked phone layout: the money keeps its desktop RIGHT alignment (owner, 19 Jul 2026 — the
     left-aligned version read as a bug), and the identity block sits centred between the context
     bar's rule above and the money's rule below (the row's 44px desktop gap left it top-heavy). */
  .jo-head-row{gap:20px 44px}
  .jo-hero-pay{text-align:right;width:100%;border-top:1px solid var(--line);padding-top:16px;margin-top:0}
  .jo-track{max-width:none}
  .jo-acts .jo-btn{flex:1 1 auto}
  .jo-acts .sp{display:none}
  .jo-sec{margin-bottom:36px}
}
.eng-lockbar{display:flex;align-items:center;justify-content:space-between;gap:12px 18px;flex-wrap:wrap;background:#fff;border:1px solid var(--line);border-radius:12px;padding:13px 16px;margin:0 0 14px}
.eng-lockbar .lb-main{display:flex;align-items:flex-start;gap:11px;min-width:0}
.eng-lockbar .lb-pad{flex:none;color:var(--brass-deep);margin-top:1px}
.eng-lockbar .lb-pad svg{width:20px;height:20px}
.eng-lockbar strong{display:block;font-family:var(--sans);color:var(--navy);font-size:14px;line-height:1.3}
.eng-lockbar .lb-sub{font-size:12.5px;color:var(--steel);line-height:1.4}
.eng-lockbar .lb-actions{display:flex;gap:8px;flex:none}
.eng-lockbar .lb-btn{font-family:var(--sans);font-size:13px;font-weight:600;border-radius:8px;padding:8px 14px;cursor:pointer;border:1px solid var(--line-strong);background:var(--paper);color:var(--navy);white-space:nowrap}
.eng-lockbar .lb-btn.lb-primary{background:var(--navy);color:#fff;border-color:var(--navy)}
@media(max-width:620px){.eng-lockbar .lb-actions{width:100%}.eng-lockbar .lb-btn{flex:1}}
/* Form content capped + centred in its half so it doesn't stretch on wide screens (homepage-style) */
@media (min-width:980px){.builder>.stage,.builder>.health-bar{max-width:680px;margin-left:auto;margin-right:auto}}
.preview-col{display:none}
@media (min-width:980px){.preview-col{display:block;position:sticky;top:112px;
  height:calc(100vh - 112px);overflow-y:auto;scrollbar-width:none;-ms-overflow-style:none;
  background:
    repeating-linear-gradient(0deg,transparent 0 59px,rgba(197,160,89,.1) 59px 60px),
    repeating-linear-gradient(90deg,transparent 0 59px,rgba(197,160,89,.1) 59px 60px),
    var(--navy);
  padding:24px}}
/* Hide the preview pane's OWN scrollbar so it doesn't stack a second bar beside the window
   scrollbar on the right — the pane still scrolls (wheel/trackpad). Desktop-only (mobile hides .preview-col). */
.preview-col::-webkit-scrollbar{width:0;height:0;display:none}
/* Document fills its half, centred, with slim even navy margins (homepage-style) */
@media (min-width:980px){.preview-col .preview-panel{max-width:600px;margin:0 auto}}
/* Live "Quote summary" rail — shown in place of the full document when the preview is minimised. */
#pvSummary{display:none}
.pv-summary{background:#fff;border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-sm);padding:16px 16px 18px;font-family:var(--sans)}
.pvs-h{font-size:10px;letter-spacing:1.2px;text-transform:uppercase;color:var(--steel);font-weight:700;margin:0 0 12px}
/* Mini-document header (4 Jul redesign): the rail reads as the quote it stands for */
.pv-summary{cursor:pointer}
.pvs-doc{background:#fdfcfa;border-bottom:2px solid var(--brass);margin:-16px -16px 12px;padding:14px 16px 11px;border-radius:var(--r-md) var(--r-md) 0 0}
.pvs-doc-t{font-family:var(--serif,'Newsreader',serif);font-weight:600;font-size:17px;color:var(--navy);margin:0}
.pvs-doc-m{font-family:var(--mono);font-size:11px;color:var(--steel);margin:2px 0 0}
.pvs-doc-addr{font-family:var(--prose,sans-serif);font-size:11px;color:var(--steel);margin:2px 0 0}
.pvs-mine{background:var(--chalk);border-radius:var(--r-sm);padding:11px 13px;margin-top:12px}
.pvs-mine .pvs-health{margin-top:8px;padding:0;background:none}
.pvs-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:5px 0}
.pvs-grp{border-top:1px solid var(--line);margin-top:10px;padding-top:8px}
.pvs-grp:first-of-type{border-top:0;margin-top:0;padding-top:2px}
.pvs-pct{font-weight:500;font-size:11px;color:var(--steel)}
.pvs-sub{padding:2px 0 4px}.pvs-sub .pvs-k,.pvs-sub .pvs-v{font-size:11px;color:var(--steel);font-weight:500}
.pvs-deduct .pvs-v{font-weight:600;color:var(--steel)}
.pvs-health{display:flex;align-items:center;gap:8px;margin-top:14px;padding:9px 11px;background:var(--chalk);border-radius:var(--r-sm);font-size:12px;font-weight:600;color:var(--navy)}
.pvs-dot{width:9px;height:9px;border-radius:50%;flex:none}
.pvs-k{font-size:12px;color:var(--steel)}
.pvs-v{font-size:13px;font-weight:700;color:var(--navy);text-align:right}
.pvs-total .pvs-v{font-size:19px}
.pvs-profit .pvs-v{font-size:16px}
.pvs-empty{font-size:12.5px;color:var(--steel);line-height:1.5;margin:0 0 14px}
.pvs-full{margin-top:14px;width:100%;padding:9px;border:1px solid var(--line-strong);background:var(--paper);border-radius:var(--r-sm);font-family:var(--sans);font-size:12px;font-weight:700;color:var(--navy);cursor:pointer}
.pvs-full:hover{border-color:var(--brass);background:var(--chalk)}
.pvs-gl{font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--steel);font-weight:700;margin:0 0 5px}
.pvs-headline{display:flex;justify-content:space-between;align-items:baseline;margin-top:12px;padding-top:11px;border-top:2px solid var(--navy)}
.pvs-hl-k{font-family:var(--sans);font-size:13px;font-weight:600;color:var(--navy)}
.pvs-hl-v{font-family:var(--sans);font-size:22px;font-weight:700;color:var(--navy)}
/* ── Collapsible live preview (desktop) ──────────────────────
   The slim "Hide" edge-tab toggles .pv-collapsed on #appShell: the navy preview
   half folds away, the form spans the full width and its content cap relaxes
   680→900px to use the room. Choice is remembered per device. Mobile is
   untouched — it already opens the preview from the floating eye button (FAB). */
.pv-toggle{display:none}
@media (min-width:980px){
  /* "Minimise" the preview: it shrinks to a slim live Quote-summary rail (#pvSummary) on the
     right rather than vanishing — so the reclaimed space always shows the headline numbers
     instead of empty grid. The form widens but keeps a readable cap. */
  .app-shell.pv-collapsed{grid-template-columns:minmax(0,1fr) 300px}
  .app-shell.pv-collapsed .builder{border-right:1px solid var(--line)}
  .app-shell.pv-collapsed .builder>.stage,
  .app-shell.pv-collapsed .builder>.health-bar{max-width:820px;margin-left:auto;margin-right:auto}
  .app-shell.pv-collapsed .preview-col{background:var(--chalk);padding:24px 28px;box-shadow:none}
  .app-shell.pv-collapsed .preview-col .preview-panel{display:none}
  .app-shell.pv-collapsed #pvSummary{display:block}
  /* The edge-tab sits on the LEFT edge of the preview pane (the builder/preview seam at 50%),
     not the far-right of the screen. When collapsed it tracks the 300px summary rail's edge. */
  .pv-toggle{position:fixed;right:50%;top:50%;transform:translateY(-50%);z-index:33;
    display:inline-flex;align-items:center;justify-content:center;
    width:22px;height:58px;padding:0;cursor:pointer;color:#fff;
    background:#0c3258;border:0;border-left:1px solid rgba(255,255,255,.16);
    border-radius:9px 0 0 9px;box-shadow:-2px 0 9px rgba(0,33,71,.22);
    transition:background .15s,width .15s}
  .pv-toggle:hover{background:#13406e;width:25px}
  .pv-toggle .pvt-chev{width:14px;height:14px;flex:none}
  #appShell.pv-collapsed ~ .pv-toggle{right:300px}
}

/* ── STAGES ──────────────────────────────────────────────── */
.stage{display:none;padding-top:20px;animation:fadeIn .2s ease}
.stage.is-active{display:block}
/* Work first, pricing after — the order lives in the DOM now (owner, 19 Jul 2026). The old flex
   `order` re-shuffle targeted data-stage="3", which the 4→3 renumber left pointing at Send — a
   silent no-op. Don't reintroduce an order: override; move the markup instead. */
@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.stage-h{margin:8px 0 4px;font-family:var(--serif);font-size:24px;font-weight:600;color:var(--navy);line-height:1.15}
.stage-h:focus{outline:none;box-shadow:none} /* focused only to reposition screen readers on step change — not interactive. box-shadow too: the global :focus-visible ring is TWO layers (navy outline + brass halo); on a ?sample=1 load the programmatic focus counts as keyboard-driven, so the brass halo showed until the first click */
.stage-h em{font-style:italic;color:var(--brass)}
.stage-sub{margin:0 0 22px;font-size:13px;color:var(--steel);line-height:1.5}

/* ── PANEL ───────────────────────────────────────────────── */
/* One spacing rhythm for ALL stages (owner consistency pass, 5 Jul): the step-4 "breathing room"
   values (24px panel padding, 22px card gaps, 12px section headers, airier hints) are now the BASE —
   the owner preferred the roomier Review feel, so steps 1–3 came UP to match rather than keeping a
   second, tighter rhythm and a stack of step-4 overrides. */
.panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:24px;margin-bottom:22px;box-shadow:var(--shadow-sm)}
.panel-h{font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--navy);margin:0 0 14px;display:flex;align-items:center;gap:8px}
.panel-h::before{content:'';width:3px;height:14px;background:var(--brass);border-radius:1px}
.panel-hint{font-size:12.5px;color:var(--steel);margin:-2px 0 16px;line-height:1.55}   /* 12px -> 12.5px so hints match across ALL stages, not just step 4 (owner font-consistency, 5 Jul) */
/* Sub-heading inside a merged card (e.g. Review's "Terms & payment" groups Terms/Payment/Notes) */
.panel-subh{font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--navy);margin:22px 0 11px;padding-top:18px;border-top:1px solid var(--line)}
/* Stage-4 "Advanced options" collapsible (retention / DLP / contingency / quote dates) */
.adv-panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-sm);margin-bottom:22px;overflow:hidden}
.adv-panel>summary{list-style:none;cursor:pointer;padding:20px 24px;font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--navy);display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.adv-panel>summary::-webkit-details-marker{display:none}
.adv-panel>summary::after{content:'›';margin-left:auto;font-size:20px;line-height:1;color:var(--steel);transition:transform .2s}
.adv-panel[open]>summary::after{transform:rotate(90deg)}
.adv-summary-note{flex-basis:100%;font-weight:400;letter-spacing:.01em;text-transform:none;font-size:12px;color:var(--steel);margin-top:3px;line-height:1.45}
.adv-summary-note.is-nudge{color:var(--brass-deep)}
/* Item 17: the contract terms in effect (from your trade's defaults) even when this panel is collapsed. */
.adv-applied{flex-basis:100%;font-weight:600;letter-spacing:.01em;text-transform:none;font-size:12px;color:var(--navy);margin-top:2px;line-height:1.4}
.adv-applied:empty{display:none}
.adv-body{padding:2px 24px 22px}
/* Fold rows (4 Jul redesign v2 — match the approved mock): compact rows, not big empty boxes.
   Label + state stacked on the left, "Change / Add ⌄" affordance vertically centred on the right. */
.fold-panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-sm);margin-bottom:14px;overflow:hidden}
.fold-panel>summary{list-style:none;cursor:pointer;padding:15px 20px;display:flex;align-items:center;gap:16px;justify-content:space-between}
.fold-panel>summary::-webkit-details-marker{display:none}
.fold-panel>summary:hover{background:#faf8f3}
/* Keyboard focus ring INSET (owner, 4 Jul PM): the global :focus-visible outline has a positive
   offset, which the terms-box overflow:hidden clipped into a stray brass line bleeding over the
   buttons below. Pull it inside the summary row so it's a contained, non-bleeding focus indicator. */
.fold-panel>summary:focus-visible{outline:2px solid var(--brass);outline-offset:-3px;border-radius:8px}
.fold-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.fold-title{font-family:var(--sans);font-size:14px;font-weight:600;color:var(--navy)}
.fold-note{font-size:12.5px;color:var(--steel);line-height:1.45}
.fold-note.is-nudge{color:var(--brass-deep)}
.fold-applied{font-size:12.5px;font-weight:600;color:var(--navy);line-height:1.4}
.fold-applied:empty{display:none}
.fold-cta{flex:none;display:flex;align-items:center;gap:5px;font-family:var(--sans);font-size:13px;font-weight:600;color:var(--brass-deep);white-space:nowrap}
.fold-chev{width:15px;height:15px;transition:transform .2s}
.fold-panel[open]>summary .fold-chev{transform:rotate(180deg)}
.fold-body{padding:0 20px 20px}
/* Common-exclusions tick chips (owner item 9, 13 Jul): tick-to-add the usual scope carve-outs. */
.excl-chips{display:flex;flex-wrap:wrap;gap:8px}
.excl-chip{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-size:12.5px;color:var(--navy);background:#fff;border:1.5px solid var(--line);border-radius:8px;padding:8px 12px;cursor:pointer;line-height:1.2;user-select:none}
.excl-chip:hover{border-color:var(--brass)}
.excl-chip input{margin:0;flex:none;cursor:pointer}
.excl-chip.is-on{border-color:var(--brass);background:rgba(197,160,89,.09);font-weight:600}
/* ONE box for the deal terms (owner, 4 Jul PM: "you had all of those in one box earlier"): payment
   open on top, T&C/exclusions/advanced as fold rows within the SAME card. The .panel gives the one
   border+radius; the inner fold-panels lose their own borders/radius/margin and become divided rows. */
.terms-box{padding:0;overflow:hidden}
#appShell[data-step="3"] .panel.terms-box{padding:0}   /* higher-specificity belt-and-braces so no later .panel rule re-pads the merged deal-terms card. Said 4 (the old Review step) until the 4→3 renumber, which left the guard matching nothing; the line above still holds the padding, so this is the safety net doing its job again, not a visual change. */
.tb-pay{padding:22px 24px 20px}   /* bottom room so the boxed Final-balance summary is clearly separated from the Terms fold below (owner, 5 Jul — was 4px, which merged them) */
.terms-box .fold-panel{border:0;border-radius:0;box-shadow:none;margin:0;border-top:1px solid var(--line)}
/* (The old step-4-only breathing-room overrides are gone — those values are the base .panel rhythm
   for every stage now, owner consistency pass 5 Jul.) */
.eng-legal{margin-top:18px;padding-top:14px;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:11px}
.eng-legal a{color:var(--steel);text-decoration:none;letter-spacing:.02em}
.eng-legal a:hover{color:var(--brass)}
.eng-legal .eng-sep{color:var(--line-strong)}
.eng-legal .eng-legal-copy{flex-basis:100%;color:var(--steel);opacity:.75;margin-top:4px}

/* ── TRADE TILES ─────────────────────────────────────────── */
.trade-summary{display:flex;align-items:center;gap:12px;padding:14px;background:var(--chalk);border:1px solid var(--line);border-radius:var(--r-md)}
.ts-icon{width:34px;height:34px;flex-shrink:0;color:var(--navy);display:flex;align-items:center;justify-content:center}
.ts-icon svg{width:28px;height:28px}
.ts-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ts-text strong{font-family:var(--sans);font-size:15px;font-weight:600;color:var(--navy)}
.ts-defaults{font-size:12px;color:var(--steel)}
.ts-change{font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);text-decoration:underline;background:none;padding:6px 4px;white-space:nowrap;cursor:pointer}
.ts-change:hover{color:var(--brass)}
/* Fits its CONTAINER, not the viewport. The old `@media (min-width:540px) → 3 columns` keyed off
   screen width, but this grid lives in the form column, which loses ~600px to the live preview at
   ≥980px — so a wide screen forced three tiles into a narrow column and clipped the third. Latent
   before (the trade picker sat on its own stage); exposed the moment the picker moved onto the job
   step, which is where you land. auto-fit + minmax lets the grid choose its own column count. */
.trade-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:10px}
.trade-tile{background:var(--paper);border:1.5px solid var(--line);border-radius:var(--r-md);
  padding:14px 12px;text-align:left;display:flex;align-items:center;gap:12px;min-height:72px;transition:.15s}
.trade-tile:hover{border-color:var(--brass-soft);transform:translateY(-1px)}
.trade-tile.is-active{border-color:var(--brass);background:linear-gradient(180deg,#fff,#faf6ed);box-shadow:0 0 0 3px rgba(197,160,89,.18)}
.tt-icon{width:34px;height:34px;flex-shrink:0;color:var(--navy);display:flex;align-items:center;justify-content:center}
.trade-tile.is-active .tt-icon{color:var(--brass)}
.tt-icon svg{width:100%;height:100%}
.tt-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.tt-name{font-family:var(--sans);font-size:14px;font-weight:600;color:var(--navy)}
.tt-meta{font-size:11px;color:var(--steel)}

/* ── SEGMENTED ───────────────────────────────────────────── */
.seg{display:flex;gap:10px}
.seg-btn{flex:1;padding:11px 10px;font-family:var(--sans);font-size:13px;font-weight:600;
  color:var(--steel);background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;text-align:center;transition:.15s;min-height:44px}
.seg-btn:hover{border-color:var(--line-strong)}
.seg-meta{font-family:var(--prose);font-size:10px;font-weight:400;color:var(--steel)}
.seg-btn.is-active{background:var(--navy);color:#fff;border-color:var(--navy);box-shadow:0 1px 3px rgba(0,33,71,.25)}
.seg-btn.is-active .seg-meta{color:rgba(255,255,255,.75)}
.mode-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:18px;margin-bottom:16px}
/* Shared stage header — title pinned at the SAME height on every step; contextual control on its row. */
.eng-stagehead{padding-top:20px}
.eng-stagehead-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;min-height:36px}
.eng-stagehead-ctl{display:flex;align-items:center;gap:10px;margin-left:auto}
/* (Removed 18 Jul: a rule for #modeSeg, an element that exists nowhere in site/ — the toggle it hid was
   deleted long ago. It also carried a stale data-step="4" from the old 4-step flow. This is not the
   "dead CSS interleaved on minified lines, leave it for a purge tool" case the house rule protects: the
   ID is provably absent, so the rule could never match anything. Removing it lets the step-number guard
   in tests/send-one-job.spec.js assert that NO selector references a step above STEP.LAST.) */
.mode-bar-label{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.8px;text-transform:uppercase;color:var(--steel)}
.seg-compact{flex:0 0 auto;width:auto;padding:3px}
.seg-compact .seg-btn{flex:0 0 auto;min-height:0;padding:7px 16px;font-size:12px;border-radius:6px;line-height:1}
/* Feedback when switching to Advanced — confirm + highlight the revealed fields */
.mode-hint{margin:-6px 0 14px;font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);display:none}
.mode-hint.show{display:block;animation:modeHintIn .25s ease}
.mode-hint .mh-arrow{color:var(--brass-deep)}
@keyframes modeHintIn{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.adv-flash{animation:advFlash 1.9s ease}
/* Non-subscriber: the send/download/share buttons stay clickable (the click starts the trial)
   but READ as locked — a padlock + slight dim — so the trial ask is honest and up-front. */
.gate-locked{opacity:.78}
.gate-locked::after{content:"";display:inline-block;width:1.05em;height:1.05em;margin-left:7px;vertical-align:-.16em;background-color:currentColor;opacity:.85;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='11' width='14' height='9' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='11' width='14' height='9' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E") center/contain no-repeat}
@keyframes advFlash{0%{box-shadow:0 0 0 0 rgba(197,160,89,0)}12%{box-shadow:0 0 0 3px rgba(197,160,89,.6)}100%{box-shadow:0 0 0 0 rgba(197,160,89,0)}}
@media(prefers-reduced-motion:reduce){.mode-hint.show{animation:none}.adv-flash{animation:none}}

/* ── DEFAULTS STRIP / NUDGE ──────────────────────────────── */
.defaults-strip{display:none;margin-top:14px;padding:12px 14px;background:#f0f5e8;
  border:1px solid #cfe0b6;border-left:3px solid var(--green);border-radius:var(--r-md);
  font-size:13px;color:#2c4a1f;line-height:1.45}
.defaults-strip.is-visible{display:block}
.defaults-strip strong{color:var(--navy);font-weight:600}
.defaults-strip .ds-tweak{display:inline-block;margin-top:4px;font-size:11px;color:var(--steel);font-style:italic}
.company-nudge{display:flex;align-items:center;gap:12px;width:100%;text-align:left;margin-bottom:16px;
  padding:13px 14px;background:#fff;border:1px solid var(--line);border-radius:var(--r-md);cursor:pointer;transition:.15s}
.company-nudge:hover{border-color:var(--brass)}
.company-nudge.is-empty{background:var(--amber-soft);border-color:#e8d49a}
.company-nudge.is-empty:hover{background:#f9e9c4}
.cn-icon{width:30px;height:30px;flex-shrink:0;color:var(--steel);display:flex;align-items:center;justify-content:center}
.company-nudge.is-empty .cn-icon{color:var(--amber)}
.cn-icon svg{width:20px;height:20px}
.cn-text{flex:1;min-width:0;font-size:12px;color:var(--slate);line-height:1.4}
.company-nudge.is-empty .cn-text{color:#5c4310}
.cn-text strong{color:var(--navy);font-family:var(--sans);font-weight:600}
.cn-cta{font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.5px;color:var(--navy);white-space:nowrap}
/* Letterhead treatment (4 Jul redesign): monogram + weighted name + quiet contacts, with
   missing-detail chips for what the printed quote actually needs */
.cn-mono{flex:none;width:40px;height:40px;border-radius:9px;background:var(--navy);color:var(--brass-soft);display:flex;align-items:center;justify-content:center;font-family:var(--serif,'Newsreader',serif);font-weight:600;font-size:16px;letter-spacing:.02em}
.cn-logo{background:#fff;border:1px solid var(--line);padding:3px}
.cn-logo img{width:100%;height:100%;object-fit:contain;display:block}
.company-nudge:not(.is-empty) .cn-text{font-size:14px;color:var(--navy)}
.cn-sub{display:block;margin-top:2px;font-size:12px;color:var(--steel);line-height:1.5}
.cn-miss{display:inline-block;background:var(--amber-soft,#FBEEC9);color:#8a5a10;border-radius:12px;padding:1px 9px;font-family:var(--sans);font-size:11px;font-weight:600;margin-left:6px;white-space:nowrap}
.cn-sub:empty{display:none}

/* ── FIELDS ──────────────────────────────────────────────── */
.field{margin-bottom:12px}
.field label{display:block;font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:.8px;text-transform:uppercase;color:var(--slate);margin-bottom:5px}
.field .hint{font-size:11px;color:var(--steel);margin-top:4px;font-style:italic}
/* Soft, non-blocking format hint — shown only when a field's content looks wrong. Never gates "Next". */
.field-warn{display:none;font-size:11px;color:var(--red);margin-top:4px}
.field-warn.show{display:block}
.field input[aria-invalid="true"]{border-color:var(--red)}
.mic-hint{display:none}
@media (pointer:coarse){.mic-hint{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--steel);margin:-2px 0 14px;line-height:1.4}}
.mic-hint svg{width:14px;height:14px;flex:none;color:var(--brass)}
.field input[type=text],.field input[type=email],.field input[type=tel],.field input[type=number],.field input[type=password],.field input[type=date],
.field select,.field textarea{width:100%;padding:11px 12px;background:#fff;border:1px solid var(--line-strong);
  border-radius:var(--r-md);font-size:16px;color:var(--slate);transition:.15s}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--navy);box-shadow:0 0 0 3px rgba(0,33,71,.08)}
.field textarea{min-height:80px;resize:vertical}
/* Field text sits at 16px on phones ON PURPOSE (below 16px, mobile Safari zooms in on focus — the
   viewport has no user-scalable lock). On wider screens there's no zoom risk, so drop it to 14px to
   match the page copy instead of towering over it (owner, 4 Jul PM). */
@media (min-width:768px){
  .field input[type=text],.field input[type=email],.field input[type=tel],.field input[type=number],.field input[type=password],.field input[type=date],
  .field select,.field textarea{font-size:14px}
}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media (max-width:480px){.field-row{grid-template-columns:1fr}}
.check-label{display:flex;align-items:center;gap:8px;font-weight:500;text-transform:none;letter-spacing:0}
.check-label input{width:18px;height:18px;flex-shrink:0;margin:0}   /* margin:0 so the box centres cleanly on the label text (owner, 5 Jul — UA default margins pushed it off) */
/* Inside a .field the generic ".field label{display:block}" out-ranks .check-label's flex, which
   dropped the tick-box onto the text BASELINE (~4px high of centre) on the Stage-4 terms/retention
   rows and "Skip running costs". Re-assert flex centring at higher specificity (owner, 5 Jul). */
.field label.check-label{display:flex;align-items:center;gap:8px;font-weight:500;text-transform:none;letter-spacing:0}
.inline-note{font-weight:400;text-transform:none;letter-spacing:0;font-size:11px;color:var(--steel)}
/* Settings logo uploader (.logo-field/.logo-preview/.logo-empty/.logo-remove) + day-rate row + .set-acc
   moved to css/settings.css (paired with js/settings.js). The dead .logo-actions/.logo-btn left below. */
.dep-unit-seg{display:inline-flex;border:1.5px solid var(--line-strong);border-radius:8px;overflow:hidden;flex:none}
.dep-unit{padding:9px 13px;font-size:13px;font-weight:700;font-family:var(--sans);background:#fff;color:var(--steel);border:0;cursor:pointer;min-width:42px;transition:.12s}
.dep-unit+.dep-unit{border-left:1.5px solid var(--line-strong)}
.dep-unit.is-active{background:var(--navy);color:#fff}
.logo-actions{display:flex;flex-direction:column;gap:8px}
.logo-btn{display:inline-block;padding:9px 14px;background:var(--navy);color:#fff;border-radius:var(--r-md);font-family:var(--sans);font-size:12px;font-weight:700;letter-spacing:.04em;cursor:pointer;text-align:center}
.logo-btn:hover{background:var(--navy-2)}

/* ── ACCORDION ───────────────────────────────────────────── */
.accordion{border:1px solid var(--line);border-radius:var(--r-md);background:#fbfaf6;overflow:hidden;margin-bottom:14px}
.accordion-head{width:100%;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;
  text-align:left;font-family:var(--sans);font-size:13px;font-weight:600;color:var(--navy);min-height:44px}
.acc-ico{width:13px;height:13px;vertical-align:-2px;color:var(--brass);margin-right:2px}
.acc-chev{font-size:18px;transition:.2s;color:var(--brass)}
.accordion.is-open .acc-chev{transform:rotate(90deg)}
.accordion-body{max-height:0;overflow:hidden;transition:max-height .25s ease}
.accordion.is-open .accordion-body{max-height:600px}
.accordion-inner{padding:0 14px 14px}
/* CIS materials nudge — an amber prompt above the collapsed CIS panel (owner UX review, 4 Jul PM) */
.cis-nudge{display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;margin:0 0 14px;padding:12px 14px;background:var(--amber-soft,#FBEEC9);border:1px solid #e8d49a;border-radius:var(--r-md);cursor:pointer;transition:background .12s}
.cis-nudge:hover{background:#f6e9c4}
.cis-nudge .cn-flag{flex:none;width:20px;height:20px;border-radius:50%;background:#e6c667;color:#5c4310;font-family:var(--sans);font-weight:700;font-size:13px;display:flex;align-items:center;justify-content:center;margin-top:1px}
.cis-nudge .cn-msg{flex:1;min-width:0;font-family:var(--prose);font-size:12.5px;line-height:1.5;color:#5c4310}
.cis-nudge .cn-msg strong{color:#5c4310;font-weight:700}
.cis-nudge .cn-go{flex:none;font-family:var(--sans);font-size:12px;font-weight:700;color:var(--brass-deep);white-space:nowrap;align-self:center}
@media(max-width:520px){.cis-nudge .cn-go{display:none}}

/* ── HEALTH BAR ──────────────────────────────────────────── */
.health-bar{display:none;position:sticky;top:120px;z-index:20;background:#fff;color:var(--navy);
  margin:0 0 10px;border-radius:var(--r-md);border:1px solid var(--line);overflow:hidden;
  box-shadow:var(--shadow-sm);
  transition:max-height .18s ease,padding .18s ease,opacity .15s ease;max-height:58px}
@media (min-width:980px){.health-bar{margin:0 0 12px}}
.health-bar.is-visible{display:block}
.health-bar.is-collapsed{max-height:5px;padding:0;opacity:.9;pointer-events:none}
.hb-inner{display:flex;align-items:center;gap:10px;padding:13px 14px;margin:0 auto;cursor:pointer;min-height:44px}
/* (the traffic-light dot was removed 19 Jul 2026 — owner. The margin fact lives in data-traffic on
   #healthBar + the Detail sheet's message; don't re-add a dot here.) */
.hb-summary{flex:1;min-width:0;font-family:var(--sans);font-size:14px;font-weight:500;
  color:var(--slate);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hb-summary strong{color:var(--navy);font-weight:700}
.hb-summary .hb-net{color:var(--brass-deep);font-weight:600}
.hb-chev{font-family:var(--sans);font-size:13px;font-weight:600;color:var(--brass-deep);flex-shrink:0;white-space:nowrap}

/* ── SCHEDULE / LINES ────────────────────────────────────── */
/* Each line is a light "bubble" card so it's instantly clear which fields belong to which item
   (owner review, 11 Jul 2026 — the 10 Jul flat divided-list blurred one item into the next).
   WHITE surface, hairline border + a whisper of shadow (the earlier chalk fill read dark and
   slab-like once a schedule had a few lines — owner, same day). The border warms slightly while
   a card is being edited. Headings stay flat section labels above the cards. */
.line-item{margin-bottom:0}
.line-item:not(.is-heading){padding:14px 14px 12px;margin-bottom:12px;background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:0 1px 2px rgba(0,33,71,.05)}
.line-item:not(.is-heading):focus-within{border-color:var(--line-strong)}
.line-item:not(.is-heading):last-of-type{margin-bottom:0}
/* Section headings + subtotals in the builder (sections feature, 10 Jul 2026) */
.line-item.is-heading{padding:16px 0 10px;border-bottom:1px solid var(--line)}
/* A heading row announces itself — without the tag an empty or filled section row was just an
   underlined line of text with no clue it groups the items below it (owner, 11 Jul 2026). */
.li-sec-tag{flex:none;margin-top:8px;font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--steel);background:var(--chalk);padding:3px 7px;border-radius:5px}
.li-sec-title{flex:1 1 auto;min-width:0;border:0;border-bottom:1.5px solid var(--field-line);border-radius:0;background:transparent;font-family:var(--sans);font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--navy);padding:6px 2px;min-height:34px}
.li-sec-title:focus{outline:none;border-bottom-color:var(--brass)}
.li-sec-title::placeholder{text-transform:none;letter-spacing:0;font-weight:400;color:#9fb2c2}
/* Per-section "add a line" (owner, 18 Jul). Deliberately QUIET — a dashed, text-weight control that
   reads as part of its section, not a fourth full-width button competing with the three at the foot
   of the list. It is the nearest affordance to the section you just made, which is the whole point. */
.li-addline{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;
  background:none;border:1px dashed var(--line-strong);border-radius:var(--r-md);
  padding:10px 12px;margin:2px 0 16px;cursor:pointer;
  font-family:var(--sans);font-size:13px;font-weight:600;color:var(--steel);min-height:44px}
.li-addline:hover{border-style:solid;border-color:var(--navy);color:var(--navy);background:rgba(0,33,71,.02)}
.li-addline:focus-visible{outline:2px solid var(--brass);outline-offset:2px}
/* An EMPTY section gets the stronger prompt — that blank gap under a new heading IS the dead end. */
.li-addline.is-first{border-color:var(--navy);color:var(--navy);border-style:solid;background:#fff}
.li-secsub{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:8px 2px 14px;font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--steel);border-bottom:1px solid var(--line)}
.li-secsub-val{font-family:var(--mono);font-weight:700;color:var(--navy);font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:0}
.aw-section{margin-top:8px}
.aw-nudge{display:flex;align-items:flex-start;gap:10px;background:var(--chalk);border:1px solid var(--line);border-radius:var(--r-md);padding:11px 13px;margin-bottom:12px;font-family:var(--prose);font-size:13px;color:var(--slate);line-height:1.45}
.aw-nudge strong{color:var(--navy);font-weight:700}
.aw-nudge-x{flex:none;margin-left:auto;background:none;border:0;color:var(--steel);font-size:14px;cursor:pointer;padding:0 2px;line-height:1;min-height:24px}
.aw-nudge-x:hover{color:var(--navy)}
/* Grip drag-to-reorder (Phase 2, 10 Jul 2026) — dedicated handle; arrows stay as fallback */
.li-grip{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;flex:none;color:var(--steel);cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none}
.li-grip svg{width:15px;height:15px;fill:currentColor}
.li-grip:hover{color:var(--navy)}
.li-grip:active{cursor:grabbing}
@media(pointer:coarse){.li-grip{width:38px;height:38px}}
body.li-dragging,body.li-dragging *{cursor:grabbing!important;-webkit-user-select:none;user-select:none}
.line-item.li-drag-src{background:#fff;border-radius:8px;box-shadow:0 10px 24px rgba(0,33,71,.22);position:relative;z-index:5;pointer-events:none;opacity:.97}
.line-item.li-drop-before{box-shadow:inset 0 3px 0 -1px var(--brass)}
.line-item.li-drop-after{box-shadow:inset 0 -3px 0 -1px var(--brass)}
.li-top{display:flex;flex-wrap:wrap;align-items:flex-start;gap:6px;margin-bottom:0}
/* Hanging item number — mirrors the numbered Schedule of Works on the customer document
   (headings skipped there too), so "item 2" means the same thing in both places. */
.li-num{flex:none;min-width:20px;padding-top:8px;font-family:var(--mono);font-size:12.5px;font-weight:600;color:var(--steel);line-height:1.35;font-variant-numeric:tabular-nums}
.li-acts{display:flex;align-items:center;gap:2px;flex:none;margin-left:auto}
/* The description hugs its text: min-height is ONE line and autosizeDesc() grows it only when the
   text really wraps — so a short line no longer shows an empty second line with a floating underline
   below it (owner review, 9 Jul 2026). Focus is a quiet brass underline, no cream fill. */
.li-desc{flex:1 1 auto;min-width:0;padding:6px 2px;background:transparent;border:0;border-bottom:1.5px solid var(--field-line);border-radius:0;font-size:16px;font-weight:400;color:var(--navy);line-height:1.35;min-height:34px;resize:none;overflow:hidden}
.li-desc:focus{border-bottom-color:var(--brass)}
/* Tool row — the optional detail note (left) shares one row with the per-line controls (right),
   so the controls no longer sit on a mostly-empty band of their own (owner review, 11 Jul 2026).
   On narrow screens the two halves wrap into stacked rows and nothing is squeezed. */
.li-toolrow{display:flex;align-items:center;gap:4px 10px;flex-wrap:wrap;margin:3px 0 8px}
.li-toolrow .li-acts{margin-left:auto}
/* Optional per-line note — quiet "+ Add detail" link when empty, tagged sub-note when filled
   (markup built by detailSlot()/detailField() in app.html). */
.li-detail-slot{flex:1 1 220px;min-width:0}
.li-detail-slot .li-detail-wrap{width:100%}
.li-detail-add{display:inline-flex;align-items:center;gap:6px;font-family:var(--prose);font-size:13px;color:var(--brass-deep);background:transparent;border:0;padding:3px 2px;cursor:pointer;min-height:32px}
.li-detail-add:hover{color:var(--navy)}
.li-detail-plus{width:13px;height:13px;stroke:currentColor;stroke-width:1.6;fill:none;stroke-linecap:round}
.li-detail-wrap{display:flex;align-items:center;gap:8px}
.li-detail-tag{font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--brass-deep);background:var(--chalk);padding:3px 7px;border-radius:5px;flex:none}
.li-detail{flex:1;min-width:0;padding:4px 2px;background:transparent;border:0;border-bottom:1.5px solid var(--line);border-radius:0;font-size:13px;line-height:1.3;color:#4A6072;font-family:var(--prose)}
.li-detail:focus{border-bottom-color:var(--brass)}
.li-detail::placeholder{color:#9fb2c2}
.li-dup,.li-remove{width:32px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.li-dup{color:var(--steel)}.li-dup:hover{background:var(--chalk);color:var(--navy)}
.li-remove{color:var(--red);font-size:18px}.li-remove:hover{background:var(--red-soft)}
.li-move{width:26px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--steel);font-size:15px;line-height:1}
.li-move:hover:not(:disabled){background:var(--chalk);color:var(--navy)}
.li-move:disabled{opacity:.28;cursor:default}
/* Touch devices: the per-line controls (grouped in .li-acts on the tool row, right of "+ Add
   detail") get the 44px minimum tap target — 38px was too small to hit reliably (owner report:
   the delete "×" was fiddly to tap). The glyph is enlarged to match. */
@media(pointer:coarse){.li-dup,.li-remove{width:44px;height:44px}.li-remove{font-size:22px}.li-move{width:34px;height:44px}}
.li-ico{width:15px;height:15px}
.li-type{display:inline-flex;background:#f1eee5;border-radius:14px;padding:3px;margin-bottom:10px}
.li-type-btn{font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:.5px;padding:6px 12px;border-radius:11px;color:var(--steel);transition:.12s;min-height:30px}
.li-type-btn.is-active{background:#fff;color:var(--navy);box-shadow:0 1px 2px rgba(0,33,71,.12)}
.li-type-btn.is-active[data-type=materials]{color:#8a6f2c}
/* Four labelled columns — Qty · Unit · Your cost · Line cost — each label sits directly over its
   own field (the old combined "Qty / unit" label floated over two fields and aligned with neither;
   owner, 11 Jul 2026). */
.li-mid{display:grid;grid-template-columns:52px 100px 110px 1fr;gap:10px;align-items:end;padding-bottom:4px}
.li-mini-label{font-family:var(--sans);font-size:10px;letter-spacing:.9px;text-transform:uppercase;color:var(--steel);margin-bottom:4px;display:block}
.li-mid>div:last-child .li-mini-label{text-align:right}
.li-qty,.li-rate{width:100%;padding:7px 2px;background:transparent;border:0;border-bottom:1.75px solid var(--field-line);border-radius:0;font-size:16px;text-align:right;color:var(--navy)}
.li-qty{text-align:left}  /* its label sits top-left; a right-flushed digit under it read misaligned */
.li-qty:focus,.li-rate:focus{border-bottom-color:var(--brass)}
@media(pointer:coarse){.li-qty,.li-rate,.li-unit{min-height:44px}}
.li-rate-wrap{position:relative}
.li-rate-wrap::before{content:'£';position:absolute;left:2px;top:50%;transform:translateY(-50%);color:var(--steel);font-size:13px}
.li-rate{padding-left:13px}
.li-unit{width:100%;min-width:0;padding:7px 2px;background:transparent;border:0;border-bottom:1.75px solid var(--field-line);border-radius:0;font-size:16px;font-family:var(--prose);color:var(--slate);cursor:pointer}  /* 16px: stop iOS auto-zoom on focus */
.li-unit:focus{border-bottom-color:var(--brass)}
@media(max-width:600px){.li-desc{padding:8px 2px;min-height:40px}.li-num{padding-top:10px}}
.li-line-cost{font-family:var(--sans);font-size:16px;font-weight:600;color:var(--slate);text-align:right;padding:7px 0;white-space:nowrap;min-width:84px}
/* Footer of the card — a hairline above the sell price so the card reads top-to-bottom as
   description → note/controls → your numbers → your price (owner review, 11 Jul 2026). */
.li-bot{display:flex;align-items:center;gap:10px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line);font-family:var(--sans);font-size:12px}
.li-arrow{color:var(--brass);font-size:18px;font-weight:700}
.li-sell-label{flex:1;color:var(--steel);font-size:12px;font-family:var(--prose)}
.li-sell-label strong{color:var(--navy);font-weight:600}
.li-pc{font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;padding:7px 11px;border-radius:11px;border:1px solid var(--line-strong);color:var(--steel);background:#fff;cursor:pointer;flex-shrink:0;transition:.12s;min-height:36px}
/* Library matches while typing a line — transient chips under the description; one tap fills the line */
.li-matches{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:2px 0 8px}
.lim-pick{font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);background:var(--chalk);border:1px solid var(--line-strong);border-radius:16px;padding:9px 13px;min-height:40px;cursor:pointer;transition:border-color .12s,background .12s;text-align:left}
.lim-pick:hover{border-color:var(--brass);background:#fff}
.li-pc:hover{border-color:var(--brass);color:var(--navy)}
.li-pc.is-on{background:var(--brass);border-color:var(--brass);color:var(--navy)}
.li-mu{font-size:12px;color:var(--steel);font-weight:400}
.li-sell{font-family:var(--sans);font-size:17px;font-weight:700;color:var(--brass);white-space:nowrap}
/* Narrow phones (placed AFTER the base li-* rules — equal specificity, so order decides): the fixed
   input columns + the 84px cost minimum overflowed the card (~35px bleed on £-thousands lines) — the
   inputs flex down and the cost column sizes to its figure; the qty box slims so the unit select
   keeps room for its word + arrow; and in the footer the pill + price share the row with the
   "Your price incl. …" caption on its own line under the figure (beside the pill it only got
   ~64px and wrapped 4 lines deep). */
@media(max-width:460px){
  .li-mid{grid-template-columns:38px minmax(0,1fr) minmax(0,1.1fr) auto;gap:8px}
  .li-line-cost{min-width:0;font-size:15px}
  .li-bot{flex-wrap:wrap}
  .li-sell{margin-left:auto}
  .li-sell-label{flex:0 0 100%;order:3;text-align:right;margin-top:2px}
}
/* Light result-callout (was solid navy — sat as a second navy block right above the navy
   Add Work button). White with a brass accent so it reads as the total without doubling up. */
.schedule-subtotal{display:flex;align-items:center;gap:12px;margin-top:4px;padding:14px 16px;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);color:var(--navy)}
.ss-left{display:flex;flex-direction:column;flex:1;min-width:0}
.ss-label{font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:1.2px;text-transform:uppercase;color:var(--steel)}
.ss-cost{font-size:13px;color:var(--steel);margin-top:2px}
.ss-arrow{color:var(--brass);font-size:18px;font-weight:700}
.ss-net{font-family:var(--sans);font-size:20px;font-weight:700;color:var(--navy);white-space:nowrap}
.ss-net small{font-size:11px;font-weight:400;color:var(--steel)}
.ss-pricenudge{margin-top:10px;font-family:var(--sans);font-size:12px;font-style:italic;color:var(--steel);text-align:center}

.add-work-btn{width:100%;padding:13px 14px;background:var(--navy);color:#fff;font-family:var(--sans);
  font-size:13px;font-weight:700;letter-spacing:1px;text-transform:uppercase;border-radius:var(--r-md);
  box-shadow:0 2px 10px rgba(0,33,71,.18);transition:.15s;min-height:48px}
.add-work-btn:hover{background:var(--navy-2);transform:translateY(-1px)}
/* Price-list (lib-*) styles moved to css/library.css (linked in <head>), shared with dashboard.html. */
.suggestions{margin-top:10px;padding:0;background:none;border:0}
.suggestions-h{font-family:var(--sans);font-size:10px;letter-spacing:1px;text-transform:uppercase;color:var(--steel);margin-bottom:6px}
.sug-chip{display:inline-block;background:#fff;border:1px solid var(--line-strong);border-radius:14px;
  padding:6px 10px;margin:3px 4px 3px 0;font-family:var(--sans);font-size:11px;color:var(--navy);transition:.15s}
.sug-chip:hover{background:var(--brass);color:var(--navy);border-color:var(--brass)}
/* Learned ("your own") quick-add items — subtly marked, carrying the remembered price. */
.sug-chip.is-mine{border-color:var(--brass);background:#fdfaf3}
.sug-chip .sug-price{color:var(--brass-deep);font-weight:600;margin-left:3px}
.sug-chip:hover .sug-price{color:var(--navy)}

/* ── ADD-WORK BLOCK (library-led hybrid, 20 Jun) ───────────
   On an ESTABLISHED price list the inline search leads, your most-used items sit under it as
   one-tap chips, and typing a fresh line is the quiet fallback. When the list is EMPTY the order
   flips (typing leads) via .is-empty. aw-* names are namespaced off the library MANAGER's lib-*
   surface (js/library.js + css/library.css) so nothing collides. */
.addwork{display:flex;flex-direction:column;gap:12px;margin-top:4px}
.addwork #suggestions{margin-top:0}
.aw-search{display:flex;align-items:center;gap:10px;background:#fff;border:1.5px solid var(--navy);border-radius:var(--r-md);padding:0 12px;transition:box-shadow .15s}
.aw-search:focus-within{box-shadow:0 0 0 3px rgba(0,33,71,.12)}
.aw-search-ico{width:18px;height:18px;flex:0 0 auto;color:var(--navy)}
.aw-search input{flex:1;min-width:0;border:0;outline:none;background:transparent;font-family:var(--sans);font-size:15px;color:var(--navy);padding:12px 0}
.aw-search input::placeholder{color:var(--steel)}
.aw-search-clear{flex:0 0 auto;background:none;border:0;color:var(--steel);font-size:15px;line-height:1;cursor:pointer;padding:6px}
.aw-results{border:1px solid var(--line-strong);border-radius:var(--r-md);background:#fff;overflow:hidden;box-shadow:var(--shadow-sm)}
.aw-res{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;text-align:left;background:#fff;border:0;border-bottom:1px solid var(--line);padding:11px 13px;font-family:var(--sans);font-size:14px;color:var(--navy);cursor:pointer}
.aw-res:last-child{border-bottom:0}
.aw-res:hover{background:var(--chalk)}
.aw-res .awr-price{color:var(--brass-deep);font-weight:600;white-space:nowrap}
.aw-res.aw-res-new{color:var(--steel);font-style:italic}
.aw-new.is-secondary{background:#fff;color:var(--navy);border:1px solid var(--line-strong);box-shadow:none;text-transform:none;letter-spacing:.2px;font-size:13.5px;font-weight:600;min-height:44px}
.aw-new.is-secondary:hover{background:var(--chalk);border-color:var(--brass);transform:none}
.aw-manage{align-self:flex-end;background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-size:12px;font-weight:600;cursor:pointer;padding:4px 2px}
.aw-manage:hover{text-decoration:underline}
/* Stage-3 "Add from library" tick-select picker */
.lp-filter{width:100%;box-sizing:border-box;padding:10px 12px;border:1px solid var(--line-strong);border-radius:10px;font:inherit;margin:0 0 12px}
.lp-list{display:flex;flex-direction:column;gap:6px;max-height:46vh;overflow:auto;-webkit-overflow-scrolling:touch}
.lp-row{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:11px 12px;border:1px solid var(--line-strong);border-radius:10px;cursor:pointer;background:#fff;transition:border-color .12s,background .12s}
.lp-row:hover{border-color:var(--brass)}
.lp-row.is-on{border-color:var(--navy);background:var(--chalk)}
.lp-check{flex:none;width:20px;height:20px;border-radius:5px;border:2px solid var(--steel);display:flex;align-items:center;justify-content:center;color:#fff;background:#fff}
.lp-row.is-on .lp-check{background:var(--navy);border-color:var(--navy)}
.lp-check svg{width:13px;height:13px;visibility:hidden}
.lp-row.is-on .lp-check svg{visibility:visible}
.lp-main{flex:1;min-width:0}
.lp-d{display:block;font-weight:600;color:var(--navy);font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lp-meta{display:block;font-size:12px;color:var(--steel);margin-top:1px}
.lp-empty{font-size:13px;color:var(--steel);line-height:1.55;padding:10px 2px}
.lp-foot{display:flex;align-items:center;gap:12px;justify-content:space-between;margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.lp-manage{background:none;border:0;color:var(--brass-deep);font:inherit;font-weight:600;font-size:13px;cursor:pointer;padding:6px 2px}
.lp-manage:hover{text-decoration:underline}
.lp-add{background:var(--navy);color:#fff;border:0;border-radius:10px;font:inherit;font-weight:600;font-size:14px;padding:11px 18px;cursor:pointer;white-space:nowrap}
.lp-add:disabled{opacity:.5;cursor:default}
.aw-empty{display:flex;gap:9px;align-items:flex-start;background:#fbfaf6;border:1px dashed var(--line-strong);border-radius:var(--r-md);padding:11px 13px;font-size:12.5px;color:var(--steel);line-height:1.45}
.aw-empty svg{width:17px;height:17px;flex:0 0 auto;color:var(--brass-deep);margin-top:1px}
/* ONE STABLE ORDER (owner, 18 Jul): Add section → Type a new line → search the library. Previously
   the order CHANGED between the empty and established states (search led once a library existed) and
   #addSectionBtn carried no order at all, so it defaulted to 0 and floated to the top by accident.
   A control that moves depending on state is itself hard to learn — "where do I click next" is the
   complaint this answers — so the sequence is now identical in both states, structural action first.
   NOTE: this supersedes the 20 Jun "established list → search leads" ordering. */
#addSectionBtn{order:1}#addLineBtn{order:2}#awSearch{order:3}#awResults{order:4}#addFromLibBtn{order:5}.addwork #suggestions{order:6}#awEmptyNote{order:7}
/* Established list (4 Jul redesign): ONE hierarchy — search leads, "type a new line" is a compact
   secondary, "browse your full library" drops to a text link so three add affordances stop
   competing at equal volume. Empty mode keeps the full-size buttons (typing leads). */
.addwork:not(.is-empty) #addFromLibBtn{background:none;border:0;box-shadow:none;color:var(--brass-deep);font-size:13px;font-weight:700;min-height:44px;padding:6px;text-transform:none;letter-spacing:.2px;align-self:center}
.addwork:not(.is-empty) #addFromLibBtn:hover{background:none;border:0;text-decoration:underline;transform:none}

/* ── MARKUP CARD ─────────────────────────────────────────── */
.markup-card{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:18px;margin-bottom:14px}
.markup-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:14px;flex-wrap:wrap;gap:8px}
.mh-label{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:1.2px;text-transform:uppercase;color:var(--navy)}
.mh-readout{font-family:var(--sans);font-size:18px;font-weight:700;color:var(--brass)}
/* touch-action:pan-y lets a vertical swipe that starts on the slider scroll the page instead of
   dragging the thumb — you only move the value with a deliberate horizontal drag. */
.markup-slider{width:100%;-webkit-appearance:none;appearance:none;height:8px;touch-action:pan-y;
  background:linear-gradient(to right,#f0e4c3,var(--brass));border-radius:4px;outline:none}
.markup-slider::-webkit-slider-thumb{-webkit-appearance:none;width:26px;height:26px;border-radius:50%;
  background:var(--navy);border:3px solid #fff;box-shadow:var(--shadow-md);cursor:pointer}
.markup-slider::-moz-range-thumb{width:26px;height:26px;border-radius:50%;background:var(--navy);border:3px solid #fff;box-shadow:var(--shadow-md);cursor:pointer}
.markup-tip{font-size:11px;color:var(--steel);margin-top:8px;font-style:italic;line-height:1.4}
.breakeven-strip{margin-top:12px;padding:11px 14px;border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:13px;
  background:var(--chalk);border-left:3px solid var(--steel);color:var(--slate)}
.breakeven-strip.is-below{background:var(--red-soft);border-left-color:var(--red);color:var(--red)}
.breakeven-strip strong{font-family:var(--sans);font-weight:700}
.sanity-strip{margin-top:10px;padding:11px 14px;border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:13px;line-height:1.45;
  background:#fdf6e3;border-left:3px solid var(--brass);color:#6b5418}
.sanity-strip strong{font-family:var(--sans);font-weight:700}

/* ── YOUR PRICING CARD (overhead + markup, visible at top) ─ */
.pricing-card{margin-bottom:14px}
.pricing-card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
.pricing-card-head .panel-h{margin:0}
.pricing-edit-link{font-family:var(--sans);font-size:11px;font-weight:600;color:var(--navy);text-decoration:underline;background:none;padding:0;white-space:nowrap;cursor:pointer}
.pricing-edit-link:hover{color:var(--brass)}
/* Lightened 19 Jul 2026 (owner: "the navy box is too heavy there") — the running-costs explainer is
   a quiet chalk note with a brass rule now, not a solid navy slab competing with the Final Summary. */
.pricing-loading{background:var(--chalk);color:var(--slate);border-left:3px solid var(--brass);border-radius:0 var(--r-md) var(--r-md) 0;padding:11px 14px;font-family:var(--sans);font-size:13px;line-height:1.5;margin-bottom:16px}
.pricing-loading strong{color:var(--navy);font-weight:700}
.pl-sub{display:block;margin-top:6px;font-size:11.5px;color:var(--steel);font-weight:400}
.pl-sub strong{color:var(--navy);font-weight:700}
.pricing-card .slider-field+.slider-field{margin-top:16px}
.sf-note{font-weight:400;color:var(--steel);letter-spacing:0;text-transform:none}

/* ── OVERHEAD CALCULATOR (baseline wizard) ────────────────── */
.oh-help{margin:4px 0 6px;border:1px solid var(--line);border-radius:var(--r-sm);background:#fbfaf6}
.oh-help summary{cursor:pointer;font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);padding:10px 12px;list-style:none}
.oh-help summary::-webkit-details-marker{display:none}
.oh-help summary::before{content:'＋ ';color:var(--brass)}
.oh-help[open] summary::before{content:'－ '}
.oh-checklist{padding:2px 12px 4px}
.oh-cl-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:5px 0;border-top:1px solid var(--line)}
.oh-cl-row:first-child{border-top:none}
.oh-cl-row label{font-size:12px;color:var(--slate);line-height:1.35;flex:1}
.oh-cl-inp{font-size:13px;color:var(--navy);white-space:nowrap}
.oh-cl-inp input{width:78px;margin-left:4px;padding:4px 6px;border:1px solid var(--line);border-radius:6px;font-family:var(--sans);font-size:16px;text-align:right}  /* 16px: no iOS zoom */
.oh-cl-total{padding:10px 12px;border-top:2px solid var(--line);font-size:12px;color:var(--slate);display:flex;align-items:center;justify-content:space-between;gap:10px}
.oh-cl-total strong{font-family:var(--sans);color:var(--navy)}
.oh-dayrate{margin-top:14px;padding:12px 14px;background:var(--navy);color:rgba(255,255,255,.85);border-radius:var(--r-md);font-family:var(--sans);font-size:14px}
.oh-dayrate strong{color:var(--brass-soft);font-weight:700}
.oh-dayrate.muted{background:var(--chalk);color:var(--steel)}
.oh-dayrate.muted strong{color:var(--slate)}
.hint.warn{color:#b3402f}

/* ── SEND TO CLIENT (Review step) ─────────────────────────── */
.send-panel .panel-hint{margin-bottom:14px}
.send-native{width:100%;margin-bottom:10px;padding:14px;border-radius:var(--r-md);background:var(--navy);color:#fff;border:0;font-family:var(--sans);font-weight:700;font-size:13px;letter-spacing:.4px;cursor:pointer;min-height:50px;display:flex;align-items:center;justify-content:center;gap:8px}
.send-native:hover{background:var(--navy-2)}
.send-btns{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.send-btn{padding:13px 8px;border-radius:var(--r-md);font-family:var(--sans);font-size:12px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;display:flex;align-items:center;justify-content:center;gap:7px;min-height:48px;cursor:pointer;transition:.15s;border:1px solid transparent;background:var(--navy);color:#fff}   /* uppercase to match the Save-as-PDF / Save-quote buttons in the same grid (owner, 5 Jul) */
.send-btn:hover{background:var(--navy-2)}
.send-ico{width:16px;height:16px;flex-shrink:0}
.send-wa{background:#25D366;color:#053d21}
.send-wa:hover{background:#1fbe5b}
.send-email{background:#fff;color:var(--navy);border-color:var(--line-strong)}
.send-email:hover{background:var(--chalk)}
.send-dl{background:var(--navy);color:#fff}
.send-dl:hover{background:var(--navy-2)}
.send-tip{font-size:11px;color:var(--steel);line-height:1.45;margin-top:12px}
/* custom payment terms editor */
.pay-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.pay-label{flex:1;font-size:13px;color:var(--slate)}
.pay-amt-wrap{position:relative;width:130px;flex:none}
.pay-amt-wrap .pay-cur{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--steel);font-size:13px}
.pay-amt{width:100%;padding:8px 9px 8px 19px;background:#fbfaf6;border:1px solid var(--line);border-radius:var(--r-md);font-size:16px;text-align:right}  /* 16px: no iOS zoom; r-md so the £/% boxes read rounded, not square (owner, 6 Jul) */
.pay-amt:focus{outline:2px solid var(--brass);outline-offset:-1px;border-color:var(--brass)}
/* deposit £/% unit toggle (first pay row only) */
.pay-deposit{flex-wrap:wrap;row-gap:8px}
.pay-deposit .pay-label{flex:1 1 100%}
.dep-unit{display:inline-flex;border:1px solid var(--line);border-radius:7px;overflow:hidden;flex:none}
.dep-u{border:0;background:#fbfaf6;color:var(--steel);font-size:13px;font-weight:700;padding:7px 12px;cursor:pointer;line-height:1}
.dep-u.on{background:var(--navy);color:#fff}
.dep-u+.dep-u{border-left:1px solid var(--line)}
.pct-wrap .pay-amt{padding:8px 22px 8px 9px;text-align:right}
.pay-suf{position:absolute;right:9px;top:50%;transform:translateY(-50%);color:var(--steel);font-size:13px}
.pay-conv{font-size:12.5px;font-weight:600;color:var(--navy);white-space:nowrap;flex:none}
.pay-del{width:30px;height:30px;flex:none;border-radius:var(--r-sm);color:var(--steel);font-size:13px;background:none}
.pay-del:hover{background:var(--red-soft);color:var(--red)}
.pay-del-sp{width:30px;flex:none}
/* optional "when is this stage due" note — drops to its own full-width line under the stage row */
.pay-row.has-when{flex-wrap:wrap;row-gap:8px}
.pay-when{flex:1 1 100%;font-size:13px;padding:8px 10px;background:#fbfaf6;border:1px solid var(--line);border-radius:var(--r-sm);color:var(--navy);font-family:var(--sans)}
.pay-when:focus{outline:2px solid var(--brass);outline-offset:-1px;border-color:var(--brass)}
/* The "Final balance on completion" summary is boxed so it anchors to the payment block and
   stops merging into the Terms fold directly below it (owner, 5 Jul). */
.pay-readout{margin-top:12px;background:var(--chalk);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.pay-final{display:flex;justify-content:space-between;font-family:var(--sans);font-weight:700;color:var(--navy);font-size:14px}
.pay-alloc{font-size:12px;color:var(--steel);margin-top:4px}
.pay-alloc.over{color:var(--red);font-weight:600}
/* required-field marker + inline validation */
.req{color:var(--red);font-weight:700}
input.invalid{border-color:var(--red)!important;outline:2px solid rgba(179,64,47,.35);outline-offset:-1px}
.field-err{display:block;color:var(--red);font-size:11px;margin-top:3px}
.send-hint{margin-top:12px;padding:12px 14px;background:var(--amber-soft);border:1px solid #e8d49a;border-radius:var(--r-sm);font-size:12px;color:#5c4310;line-height:1.45}
.send-hint-link{font-family:var(--sans);font-weight:700;color:var(--navy);text-decoration:underline;font-size:12px;white-space:nowrap}
/* Success variant — the WhatsApp/email channels confirm here (stage review, 20 Jul 2026). The base
   .send-hint is AMBER because it only ever carried "you're missing something"; a confirmation in that
   colour reads as a fault. Reuses the positive trio already established by .rts-item.is-done .rts-mark
   and .sp-pill.is-ready, so this is the design system's existing "done", not a new colour. */
.send-hint.is-ok{background:#e6f0e9;border-color:#c2dccb;color:var(--green)}
@media(max-width:420px){.send-btns{grid-template-columns:1fr}}

/* ── REFINE DRAWER ───────────────────────────────────────── */
.refine-drawer{background:#fbfaf6;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;margin-bottom:14px}
.refine-head{width:100%;padding:14px 16px;display:flex;align-items:center;justify-content:space-between;text-align:left;
  font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:.6px;text-transform:uppercase;color:var(--slate);min-height:48px}
.rh-chev{color:var(--brass);transition:.2s}
.refine-drawer.is-open .rh-chev{transform:rotate(90deg)}
.rh-sub{font-family:var(--prose);font-size:11px;letter-spacing:0;text-transform:none;font-weight:400;color:var(--steel);margin-left:8px;font-style:italic}
.refine-body{max-height:0;overflow:hidden;transition:max-height .3s ease}
.refine-drawer.is-open .refine-body{max-height:700px}
.refine-inner{padding:0 16px 16px}
.slider-field{margin-bottom:14px}
.sf-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}
.sf-label{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.6px;text-transform:uppercase;color:var(--slate)}
.sf-val{font-family:var(--sans);font-size:14px;font-weight:700;color:var(--navy)}
/* Fixed-width unit slot (owner, 4 Jul PM) so the day + markup input boxes line up in the same column:
   the input is a fixed width AND the unit ("day"/"days"/"%") occupies a fixed slot to its right, so
   both boxes' right edges align regardless of the unit word. */
.sf-unit{display:inline-block;width:2.6em;text-align:left;margin-left:7px}
.sf-weeks{font-size:12px;font-weight:400;color:var(--steel);margin-left:7px}
.sf-weeks:empty{margin-left:0}
/* Item 16: a VISIBLE box at rest so it's obvious you can tap and type an exact value
   (the slider is the second way in). Was a transparent border that only showed on hover. */
.sf-val-input{width:3.4em;font-family:var(--sans);font-size:16px;font-weight:700;color:var(--navy);text-align:right;
  border:1px solid var(--line-strong);border-radius:5px;background:#fff;padding:3px 7px;-moz-appearance:textfield;cursor:text}
.sf-val-input::-webkit-outer-spin-button,.sf-val-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.sf-val-input:hover{border-color:var(--navy)}
.sf-val-input:focus{border-color:var(--brass);background:#fff;outline:none;box-shadow:0 0 0 2px rgba(197,160,89,.18)}
.slider-field input[type=range]{width:100%;-webkit-appearance:none;appearance:none;height:5px;background:#e4dec8;border-radius:3px}
.slider-field input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;border-radius:50%;background:var(--brass);border:2px solid #fff;box-shadow:var(--shadow-sm)}
.slider-field input[type=range]::-moz-range-thumb{width:20px;height:20px;border-radius:50%;background:var(--brass);border:2px solid #fff}
.sf-hint{font-size:12.5px;color:var(--steel);margin-top:4px;font-style:italic}   /* 11px -> 12.5px so slider hints match the unified hint size across ALL stages (owner font-consistency, 5 Jul) */
.sf-hint a{color:var(--brass-deep);font-weight:600}

/* ── BOTTOM BAR ──────────────────────────────────────────── */
/* No strip: same chalk as the form (so it reads as just-buttons, not a bar) and it
   quietly masks content that scrolls under it. Border + shadow removed deliberately. */
.bottom-bar{position:fixed;bottom:0;left:0;right:0;background:var(--paper);border-top:1px solid var(--line);
  padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px));display:flex;gap:10px;justify-content:space-between;align-items:center;z-index:30;transition:transform .18s ease}
.bottom-bar.is-hidden{transform:translateY(120%)}
@media (min-width:980px){.bottom-bar.is-hidden{transform:none}}
.bb-btn{flex:0 0 auto;padding:11px 22px;font-family:var(--sans);font-size:12px;font-weight:700;letter-spacing:.5px;
  text-transform:uppercase;border-radius:var(--r-md);transition:.15s;min-height:44px;display:flex;align-items:center;justify-content:center;gap:6px}
.bb-back{background:transparent;color:var(--slate);border:1px solid var(--line-strong)}
.bb-back:hover{background:var(--chalk)}
.bb-back:disabled{opacity:.4;cursor:not-allowed}
.bb-next{background:var(--navy);color:#fff}.bb-next:hover{background:var(--navy-2)}
/* In-bar View (preview) button — sits between Back and Next on the builder steps (owner item 2, 13 Jul).
   Ghost styling so Next stays the primary. Shown wherever the old floating eye FAB was (mobile/tablet);
   hidden on desktop, where the live preview is always visible in the split view. */
.bb-view{background:transparent;color:var(--navy);border:1px solid var(--line-strong);padding-left:16px;padding-right:16px}
.bb-view:hover{background:var(--chalk)}
.bb-view .bb-ico{width:15px;height:15px}
@media (min-width:980px){.bb-view{display:none}}
.preview-fab{display:none!important}   /* retired — replaced by the in-bar View button so it no longer overlaps Next */
.bb-next:disabled{background:var(--line-strong);color:#fff;cursor:not-allowed;opacity:.7}
.bb-download{background:var(--navy);color:#fff;box-shadow:0 2px 10px rgba(0,33,71,.25)}
.bb-download:hover{background:var(--navy-2)}
.bb-ico{width:15px;height:15px}
.bottom-hint{display:none;position:fixed;left:0;right:0;bottom:62px;z-index:29;padding:8px 16px;
  background:var(--amber-soft);border-top:1px solid #e8d49a;font-size:12px;color:#5c4310;text-align:center}
.bottom-hint.is-visible{display:block}
.bottom-hint.is-hidden{display:none}
.bottom-hint strong{font-family:var(--sans);color:var(--navy)}
@media (min-width:980px){.bottom-bar{position:fixed;left:0;right:50%;bottom:0;margin:0;border-radius:0;padding:12px max(52px,calc((50vw - 680px)/2))}
  .bottom-hint{position:fixed;left:0;right:50%;bottom:68px;padding:8px max(52px,calc((50vw - 680px)/2))}
  /* 52px floor matches the builder's 52px gutter so BACK/NEXT line up with the panels above
     at every width (the calc takes over once the column is wider than the 680/820px content). */
  #appShell.pv-collapsed ~ .bottom-bar{right:300px;padding:18px max(52px,calc((100vw - 300px - 820px)/2)) 12px;
    background:var(--paper);box-shadow:0 -8px 20px -6px rgba(0,33,71,.12)}
  #appShell.pv-collapsed ~ .bottom-hint{right:300px;padding:8px max(52px,calc((100vw - 300px - 820px)/2))}}

/* ── Bottom section nav + in-page Save (owner items 1, 2, 18) ──────────────────────
   The builder joins the one-app bottom-nav world on mobile: the section nav is the SINGLE
   fixed bottom bar (like the price library), Back/Next + Save flow in the page, and the
   burger retires. Desktop (≥861px) is untouched — nav hidden, top chip + chrome as before. */
/* WHITE tab bar, navy active / steel inactive — byte-for-byte the same treatment as the portal's
   bottom nav (dashboard.html). Both files define .bottomnav independently; the 14 Jul "go lighter at
   the bottom bar" pass lightened the portal's and missed this one, so tapping a quote on a phone made
   the bottom bar jump white -> navy. Keep the two in step. (Owner, 16 Jul.) */
.bottomnav{position:fixed;left:0;right:0;bottom:0;z-index:65;background:#fff;border-top:1px solid var(--line);display:none;padding:8px 4px max(8px,env(safe-area-inset-bottom));box-shadow:0 -6px 20px rgba(0,33,71,.10)}
.bn-item{flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;padding:6px 2px;text-decoration:none;color:var(--steel);transition:color .12s}
.bn-item svg{width:24px;height:24px;stroke:currentColor;stroke-width:1.8;fill:none}
.bn-item:hover{color:var(--navy)}
.bn-label{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.02em}
@media(max-width:360px){.bn-label{font-size:10px;letter-spacing:0}}   /* "My Account" is the widest label — keep it on one line on small phones */
.bn-item.active{color:var(--navy)}
.bn-item.active .bn-label{font-weight:700}
.bn-item.active svg{stroke:var(--navy)}
.bn-pound{font-family:var(--sans);font-size:21px;font-weight:600;line-height:24px;height:24px}
.bn-item.active .bn-pound{color:var(--navy)}
.save-panel .save-actions{display:flex;gap:10px}
.save-panel .save-actions .bb-btn{flex:1}
.bb-save{background:#fff;color:var(--navy);border:1px solid var(--line-strong)}
.bb-save:hover{background:var(--chalk)}

/* ── PREVIEW DOCUMENT (matches home-page sample design) ─── */
/* ── Preview layout toggle (mobile sheet) — "As sent (A4)" | "Easy read" ─────────────────────
   Sits ABOVE the document (owner, 16 Jul). A4 is the default: the preview's job is to show what
   the customer actually receives. Desktop has the roomy .preview-col, so this is phone-only.
   LIGHT SURFACE (owner, 18 Jul): this was styled for a navy backdrop — the track was white-at-10%
   and the UNSELECTED label white-at-72%. The sheet is var(--chalk) (#F5F3EE), so "Easy read" was
   white-on-chalk and effectively invisible; only the selected pill showed, because it carries its
   own white background. Re-cut for chalk: outlined track, --steel label (4.90:1 on chalk, AA), and
   the selected side stays a raised white pill with navy text (14.5:1). Don't reintroduce a
   white/alpha foreground here — nothing behind this control is dark. */
.pv-view{display:none;gap:0;margin:0 0 12px;background:transparent;border:1px solid var(--line-strong);border-radius:var(--r-md);padding:3px}
.pv-view-btn{flex:1;background:none;border:0;border-radius:calc(var(--r-md) - 3px);padding:8px 10px;font-family:var(--sans);font-size:12.5px;font-weight:600;color:var(--steel);cursor:pointer}
.pv-view-btn.is-on{background:#fff;color:var(--navy);box-shadow:0 1px 2px rgba(0,33,71,.14)}
.pv-view-btn:focus-visible{outline:2px solid var(--brass);outline-offset:1px}
@media screen and (max-width:640px){.pv-view{display:flex}}
.preview-panel{background:var(--paper);border:3px solid rgba(255,255,255,.82);border-radius:3px;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.55),0 6px 18px rgba(0,0,0,.32);font-family:var(--prose);color:#001830;font-size:11px;line-height:1.45}
/* On-screen watermark — deters screenshotting the live preview. Scoped to the live
   panels ONLY (#previewDesktop/#previewMobile); the PDF export clones into a separate
   node, so the downloaded/sent document stays clean.
   GATED (4 Jul 2026): only shown to users who CAN'T export a clean copy anyway — i.e. NOT
   subscribed/trialing. app.html's renderAuth() adds body.wm-off once the account is entitled
   (active sub or live trial), so a paying/trial customer sees their own preview unmarked. The
   default (no class) keeps the mark ON, so a non-subscriber never gets a clean frame even briefly. */
#previewDesktop,#previewMobile,#jvDoc{position:relative}
/* Tiled so it repeats down the WHOLE document — a long quote can't be cropped below a single centred
   mark to get a clean copy. An inline SVG "PREVIEW" tile, faint navy, repeated across the panel.
   The tile canvas is deliberately larger than the text so the word is spaced well apart (fewer marks,
   far less cluttered) while still tiling the full length as a screenshot deterrent. */
body:not(.wm-off) #previewDesktop::after,body:not(.wm-off) #previewMobile::after,body:not(.wm-off) #jvDoc::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:6;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='430'%20height='280'%3E%3Ctext%20x='215'%20y='152'%20font-family='Arial,Helvetica,sans-serif'%20font-size='33'%20font-weight='700'%20letter-spacing='3'%20fill='%23002147'%20fill-opacity='0.06'%20text-anchor='middle'%20transform='rotate(-26%20215%20140)'%3EPREVIEW%3C/text%3E%3C/svg%3E");
  background-repeat:repeat;background-position:center}

/* ══ QUOTE DOCUMENT (premium redesign — white, no navy fills; the PDF the customer receives) ══
   The SAME .pv-* markup renders in the compact on-screen preview panel AND is cloned into #printRoot
   for the A4 PDF, so sizes are tuned small (the preview is a scaled A4). Info order: scope → line
   items → total → exclusions → payment → terms → acceptance. Rendered by renderQuoteDocument()
   (engine/src/render/quote-document.ts). Brass is an ACCENT only (rules + the Contract-Sum line). */

/* Letterhead — logo left, doc title + ref right, over a full-width NEUTRAL rule.
   BRAND-NEUTRAL BY DESIGN: the document carries the TRADE's brand (their logo), so it uses no brass
   (TradeDraft's accent) — only navy/slate structure, which flatters any logo. The only colour on the
   page is the trade's own. (A per-trade accent colour is the parked accent-picker feature.) */
.pv-title-band{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;padding:16px 15px 0}
/* Header layout is collision-proof: the logo is hard-capped to its own column (max-width:180px, and
   max-width:100% so it can never spill past that column), while the title column takes the rest and
   wraps if needed. So a long variation title + a wide logo can never overlap. fitDocTitle() (host)
   then shrinks the title to sit on one line where it fits. */
.pv-brandblock{min-width:0;max-width:180px;flex:0 1 auto;overflow:hidden}
.pv-doc-logo{display:block;max-height:44px;max-width:100%;width:auto;object-fit:contain}
.pv-doc-coname{font-family:var(--sans);font-size:13px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--navy);line-height:1.2}
.pv-doc-meta{text-align:right;flex:1 1 auto;min-width:0}
.pv-doctitle{font-family:var(--serif);font-size:19px;font-weight:700;letter-spacing:.2px;color:var(--navy);margin:0;line-height:1.05;overflow-wrap:break-word}
.pv-doc-ref{font-family:var(--mono);font-size:7.5px;letter-spacing:.8px;text-transform:uppercase;color:var(--steel);margin-top:5px}
.pv-brass-rule{height:2px;background:var(--navy);margin:9px 15px 0}

/* Parties — Prepared for | Submitted by, side by side */
.pv-parties{display:grid;grid-template-columns:1fr 1fr;margin:12px 15px 0;border-top:1px solid #E2E8ED}
.pv-party{padding:11px 0;min-width:0}
.pv-parties .pv-party:first-child{padding-right:16px}
.pv-party+.pv-party{padding-left:16px;border-left:1px solid #E2E8ED}
.pv-party-label{font-family:var(--sans);font-size:7px;font-weight:700;letter-spacing:1.2px;color:var(--steel);margin-bottom:4px;text-transform:uppercase}
.pv-party-name{font-weight:700;font-size:11px;color:#001830;line-height:1.25;margin-bottom:1px}
.pv-party-addr{font-size:8.5px;color:#4A6072;line-height:1.45}

/* Project band — scope on the left, issued + valid dates on the right */
.pv-project{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:start;margin:0 15px;padding:8px 0;border-top:1px solid #E2E8ED;border-bottom:1px solid #E2E8ED}
.pv-proj-title{font-weight:700;font-size:10.5px;color:#001830;line-height:1.3}
.pv-proj-desc{font-size:8.5px;color:#4A6072;line-height:1.4;margin-top:2px;max-width:52ch}
.pv-proj-dates{display:flex;gap:16px;text-align:right}
.pv-date-val{font-family:var(--mono);font-weight:500;font-size:9px;color:#001830;white-space:nowrap;font-variant-numeric:tabular-nums;margin-top:1px}

/* Reusable section head — uppercase title + a hairline that fills the row */
.pv-sechead{display:flex;align-items:center;gap:8px;margin:13px 15px 6px}
.pv-sectitle{font-family:var(--sans);font-weight:700;font-size:9px;letter-spacing:1.1px;text-transform:uppercase;color:var(--navy);white-space:nowrap}
.pv-sechead::after{content:"";flex:1;height:1px;background:#E2E8ED}

/* Schedule of Works — per-line Net / VAT / (CIS) / Gross */
.pv-works{width:calc(100% - 30px);margin:8px 15px 0;border-collapse:collapse;table-layout:fixed}  /* 8px top: air between the project band's bottom rule and SCHEDULE OF WORKS (mirrors the homepage hero's .fpd-works gap, scaled) */
.pv-works .pv-works-title{font-family:var(--sans);font-weight:700;font-size:9px;letter-spacing:1.1px;text-transform:uppercase;color:var(--navy);text-align:left;padding:0 0 6px}  /* section title inside the thead so it repeats on every schedule page */
.pv-works .pv-wh{font-family:var(--sans);font-weight:600;font-size:7.5px;letter-spacing:.3px;text-transform:uppercase;color:var(--steel);text-align:right;padding:0 0 5px;border-bottom:1.2px solid var(--navy)}
.pv-works .pv-wh.desc{text-align:left}
.pv-wh-sub{display:block;font-weight:400;font-size:6px;letter-spacing:.2px}
.pv-works .pv-wc{font-family:var(--mono);font-size:9px;color:#001830;text-align:right;padding:6.5px 0;border-bottom:1px solid #EDF0F5;font-variant-numeric:tabular-nums;vertical-align:top;word-break:break-word}
.pv-works .pv-wc.desc{font-family:var(--prose);text-align:left;color:#4A6072;font-weight:500;padding-right:10px}
.pv-works .pv-wc.desc.num{padding-left:18px}  /* room for the hanging item number */
.pv-wc-no{display:inline-block;width:18px;margin-left:-18px;font-family:var(--mono);font-size:8px;font-weight:500;color:var(--steel);font-variant-numeric:tabular-nums}  /* item ref in the gutter — muted slate, keeping the client doc brass-free */
.pv-works .pv-wc.cis-na{color:#9fb2c2;font-weight:400}
.pv-wc-qty{color:var(--steel);font-size:8px;font-family:var(--prose)}
.pv-wc-detail{font-family:var(--prose);font-size:8px;color:var(--steel);line-height:1.4;margin-top:2px;font-weight:400}
.pv-pc{font-family:var(--sans);font-size:6.5px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:#566B89;border:1px solid #b9c4d0;border-radius:2px;padding:0 3px;white-space:nowrap;vertical-align:1px}
.pv-pc-note{padding:4px 15px 0;font-size:8px;color:var(--steel);font-style:italic}
.pv-empty{padding:22px 15px;text-align:center;color:var(--steel);font-style:italic;font-size:10px}
/* Section headings + per-section subtotal inside the Schedule of Works (sections feature, 10 Jul 2026) */
/* padding is 4.5/5.5, NOT the symmetric-looking 6/4 it used to be, and the asymmetry is deliberate:
   the label is UPPERCASE, so there are no descenders, and the font's internal space above the cap line
   is larger than the space below the baseline. With 6/4 the caps sat ~3px low between the two rules
   (measured, not eyeballed: 8.5px above the ink vs 5.5px below). Total height is unchanged. */
.pv-works td.pv-sec-title{font-family:var(--sans);font-weight:700;font-size:8.5px;letter-spacing:1px;text-transform:uppercase;color:var(--navy);text-align:left;padding:4.5px 0 5.5px;border-bottom:1px solid var(--navy)}
/* Bracket every section top AND bottom (owner, 18 Jul). Only the FIRST section looked deliberate,
   and by accident: it sits directly under the column-header rule, so it inherited a line above.
   Later sections had nothing above them but the previous item row and read as drifting. The first
   section is excluded here precisely BECAUSE it already has that rule — giving it one of its own
   would print a double line at the top of every quote. :not(:first-child) also does the right thing
   when un-sectioned items precede the first heading: that heading is no longer first, so it rules. */
/* 1.2px, NOT 1px, and that is load-bearing. This table is border-collapse:collapse, so when two
   cells meet CSS picks ONE border: widest wins, and on an exact tie the border nearer the TOP wins.
   At 1px this rule tied with the preceding item row's own border-bottom (1px solid #EDF0F5) and
   LOST — so on a quote whose sections hold a single line each, the navy rule never drew and the
   owner saw no line above the section. It only appeared in testing because a MULTI-line section
   emits a subtotal row, and subtotal rows carry border-bottom:0, leaving nothing to lose against.
   1.2px matches the column-header rule (.pv-wh) — the same trick, for the same reason.
   19 Jul: this had drifted to 2px with padding-top:11px, against a base of 6px. That made every section
   after the first visibly heavier AND taller than the first, and pushed its title off-centre between its
   own two rules (11px above the caps, 4px below). Back to the 1.2px the note above always specified, and
   the padding-top override dropped so every section heading uses the one base padding. Uniform by
   construction: there is now no per-position padding anywhere in this block. */
.pv-works tbody tr.pv-sec:not(:first-child) td.pv-sec-title{border-top:1.2px solid var(--navy)}
/* "How to pay" bank details (owner, 18 Jul) — was the document's only inline-styled block, at
   13px/1.85 against an 8-9px body, so it sat outside the page's type system. Now on the document's
   own roles: --sans small-caps label, --mono value. MONO is deliberate — the client transcribes all
   three fields into a banking app, and monospaced tabular digits are far harder to misread. */
/* margin:0 15px matches .pv-sechead / .pv-works / .pv-sum — every block on this document insets itself
   by the same 15px. This one had no horizontal margin at all, so the bank details ran to the page edge
   while their own "How to pay" heading sat indented above them (owner, 19 Jul 2026). */
.pv-bank{font-size:8px;line-height:1.5;color:#1E3A52;margin:0 15px}
/* A table so the label and value columns are SHARED. The first cut used a min-width on an
   inline-block label, which only aligns while every label is narrower than that minimum — at the
   larger reading scale "Account number" outgrew it and pushed its own value out of the column. */
.pv-bank-tbl{border-collapse:collapse;margin-top:4px}
.pv-bank-lbl{font-family:var(--sans);font-size:7.5px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;color:#566B89;text-align:left;vertical-align:baseline;white-space:nowrap;padding:2px 14px 2px 0}
.pv-bank-val{font-family:var(--mono);font-size:9px;color:#001830;font-variant-numeric:tabular-nums;text-align:left;vertical-align:baseline;padding:2px 0}
.pv-bank-ref{margin-top:6px;color:#566B89}
/* The online-payment line sits UNDER the bank details, separated by a hairline: bank transfer
   is the primary route (owner), card via the link is the alternative. */
.pv-bank-online{margin-top:7px;padding-top:6px;border-top:1px solid #E2E8ED;color:#1E3A52}
.pv-works tr.pv-sec-sub>td{border-bottom:0;padding:5px 0 2px}
.pv-works td.pv-sec-sub-lbl{font-family:var(--sans);font-size:7.5px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;color:var(--steel);text-align:right}
.pv-works td.pv-sec-sub-val{font-weight:700;color:#001830}

/* £-aligned money cell — £ left / digits right in a fixed slot, so £ signs line up down a column */
.pv-money{display:inline-flex;justify-content:space-between;gap:4px;min-width:56px;margin-left:auto;text-align:left}
.pv-money-sym{color:var(--steel);font-weight:400}
.pv-money-fig{text-align:right;font-variant-numeric:tabular-nums}
.pv-money.muted{color:var(--steel)}

/* Contract Sum ledger (white; value sits under the Gross column via the shared colgroup) */
.pv-sum{width:calc(100% - 30px);margin:3px 15px 0;border-collapse:collapse;table-layout:fixed}
.pv-sum td{padding:3px 0;vertical-align:baseline}
.pv-sum .pv-sum-lbl{font-family:var(--sans);text-align:right;font-size:8.5px;color:var(--steel);padding-right:12px}
.pv-sum .pv-sum-val{font-family:var(--mono);text-align:right;font-size:9.5px;color:#001830;font-variant-numeric:tabular-nums}
.pv-sum tr.sub .pv-sum-lbl{font-size:7.5px;color:#9fb2c2}
.pv-sum tr.sub .pv-sum-val{font-size:8px;color:var(--steel)}
/* MEMO rows (materials excluded from CIS; notional DRC VAT) carry figures that are information only and
   add up to nothing. They are distinguished by TYPE TREATMENT — italic label, smaller quieter figure, and
   a caption that says so in words ("VAT for you to account for to HMRC") — never by brackets, which mean
   NEGATIVE in accounting convention.
   They stay RIGHT-ALIGNED in the money column (owner, 19 Jul 2026). They were previously inset out of it;
   the indent read as a misalignment bug rather than as meaning, and the italic/size/colour/caption
   treatment above already carries the "this is not part of the sum" signal. */
.pv-sum tr.memo .pv-sum-lbl{font-style:italic}
/* A memo row hugs the row it belongs to (1px above) but must CLEAR the rule below it by the same
   amount that rule clears the text beneath it. Measured on the real document, not guessed: 5.25px
   below the memo vs 9.50px above "Contract Sum" — the memo sat visibly cramped against the terminal
   rule. 7.25px equalises them. accept.html mirrors this in LOCKSTEP. */
.pv-sum tr.memo td{padding-top:1px;padding-bottom:7.25px}
.pv-sum tr.gross td{border-top:1px solid #D8DEE7;padding-top:6px}
.pv-sum tr.gross .pv-sum-lbl{font-size:9px;font-weight:700;letter-spacing:.4px;color:var(--navy)}
.pv-sum tr.gross .pv-sum-val{font-size:11px;font-weight:700;color:var(--navy)}
.pv-sum tr.gross .pv-money-sym{color:var(--navy);font-weight:700}
.pv-sum tr.cis .pv-sum-lbl,.pv-sum tr.cis .pv-sum-val{color:#4A6072}  /* neutral slate (was a warm brown-gold — off-brand for a brand-neutral document) */
.pv-sum tr.due .pv-sum-lbl{font-weight:700;color:var(--navy)}
.pv-sum tr.due .pv-sum-val{font-size:11px;font-weight:700;color:var(--navy)}
/* THE TERMINAL ROW — the one figure the customer actually pays (CIS-net when CIS is deducted, otherwise
   the contract sum). Exactly one row carries this; it takes the heavy rule and the largest type so nothing
   competes with it. MUST stay after .gross/.due above — same specificity, later wins. */
.pv-sum tr.terminal td{border-top:2px solid var(--navy);padding-top:8px}
.pv-sum tr.terminal .pv-sum-lbl{font-size:9px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--navy)}
.pv-sum tr.terminal .pv-sum-val{font-size:14px;font-weight:700;color:var(--navy)}
.pv-sum tr.terminal .pv-money{min-width:66px}
.pv-sum tr.terminal .pv-money-sym{color:var(--navy);font-weight:700}
.pv-money-na{color:var(--steel);font-weight:400;justify-content:flex-end}

/* DRC / variation / CIS notes */
.pv-drc{margin:8px 15px;padding:7px 10px;background:#fbeec9;border-left:2px solid #d9b45a;font-size:8.5px;color:#5c4310;line-height:1.5}
.pv-drc strong{color:#3d2c08}
.pv-varline{font-size:9px;color:#4A6072;font-style:italic;margin:6px 15px 0}
.pv-cis-utr{margin:5px 15px 0;font-size:8px;color:#5a6b7a}
/* CIS pending — builder aid in the live preview when CIS is set up but nothing is deducted yet. Print-hidden. */
.pv-cis-pending{margin:6px 15px 0;padding:7px 10px;font-size:8.5px;line-height:1.5;color:#5c4310;background:#fdf6e3;border:1px dashed #d9c389;border-radius:5px;font-style:italic}

/* Exclusions & Assumptions — two columns */
.pv-excl-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin:0 15px}
.pv-excl-col{min-width:0}   /* let each column shrink to its 1fr track so a long line can't push it wide and squash the other (owner, 5 Jul) */
@media (max-width:640px){.pv-excl-grid{grid-template-columns:1fr;gap:8px}}  /* collapse to one column on a narrow (phone) preview; the A4 print stays two-up */
.pv-excl-eyebrow{font-family:var(--sans);font-size:7px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--steel);margin-bottom:5px}
.pv-excl-list{list-style:none;margin:0;padding:0}
.pv-excl-list li{position:relative;padding:0 0 3px 11px;font-size:8.5px;color:#4A6072;line-height:1.45;overflow-wrap:anywhere}
.pv-excl-list li::before{content:"–";position:absolute;left:0;top:0;color:var(--navy);font-weight:600}

/* Free-text prose (notes / the choose-a-pay-plan nudge) */
.pv-prose{font-size:9px;color:#4A6072;line-height:1.5;margin:2px 15px 0;white-space:pre-wrap}
.pv-prose-warn{color:#8a5a10;white-space:normal}

/* Payment Milestones table */
.pv-pay{width:calc(100% - 30px);margin:0 15px;border-collapse:collapse;table-layout:fixed}
.pv-pay .pv-pay-h{font-family:var(--sans);font-weight:600;font-size:7.5px;letter-spacing:.3px;text-transform:uppercase;color:var(--steel);text-align:right;padding:0 0 5px;border-bottom:1.2px solid var(--navy)}
.pv-pay .pv-pay-h:first-child{text-align:left}  /* the Milestone header (NOT a .stage class — that collides with the builder's step-panel .stage{display:none}) */
.pv-pay .pv-pay-stage{font-family:var(--prose);font-size:9px;color:#4A6072;font-weight:500;text-align:left;padding:4px 0;border-bottom:1px solid #EDF0F5}
.pv-pay .pv-pay-amt{font-family:var(--mono);font-size:9px;color:#001830;text-align:right;padding:4px 0;border-bottom:1px solid #EDF0F5;font-variant-numeric:tabular-nums}
.pv-pay-note{font-size:8px;color:var(--steel);line-height:1.5;margin:6px 15px 0;font-style:italic}

/* Terms */
.pv-terms{font-size:8.5px;color:#4A6072;line-height:1.5;margin:2px 15px 0;padding-left:16px}
.pv-terms li{margin-bottom:3px}

/* Standard VAT/CIS legal note — clean muted small print (no tinted box, owner 5 Jul) */
.pv-legal{margin:9px 15px 0;padding:0;font-size:7.5px;color:var(--steel);line-height:1.55}

/* Acceptance — a clean section (heading + thin rule) matching the rest of the document, not a
   tinted box (owner 5 Jul: the blue panels read form-like + eat ink in print). */
.pv-accept{margin:12px 15px 0;padding:0;background:none;border:0}
.pv-accept-h{display:flex;align-items:center;gap:8px;font-family:var(--sans);font-size:9px;font-weight:700;letter-spacing:1.1px;text-transform:uppercase;color:var(--navy);margin-bottom:7px}
.pv-accept-h::after{content:"";flex:1;height:1px;background:#E2E8ED}
.pv-accept-p{font-size:8.5px;color:#4A6072;line-height:1.5}
.pv-accept-list{list-style:none;margin:6px 0 0;padding:0}
.pv-accept-list li{position:relative;padding:0 0 3px 12px;font-size:8.5px;color:#4A6072;line-height:1.5}
.pv-accept-list li::before{content:"–";position:absolute;left:0;top:0;color:var(--navy);font-weight:600}
.pv-accept strong{color:#001830;font-weight:700}
.pv-accept-close{margin-top:6px;font-size:8px;color:var(--steel);line-height:1.5}

/* Signatures + footer */
.pv-sig-note{font-size:7.5px;color:var(--steel);font-style:italic;margin:8px 15px 0}
.pv-sig-row{display:flex;padding:6px 15px 8px;gap:24px}
.pv-sig{flex:1;min-width:0}
.pv-sig-rule{border-top:1px solid rgba(0,33,71,.35);margin-top:13px;margin-bottom:4px}
.pv-sig-label{font-family:var(--sans);font-size:7.5px;letter-spacing:.4px;text-transform:uppercase;color:var(--steel)}
.pv-foot{display:flex;justify-content:space-between;align-items:center;padding:7px 15px;border-top:1px solid #E2E8ED;margin-top:4px;font-family:var(--sans);font-size:7.5px;letter-spacing:.3px;color:var(--steel)}


/* ── H2 reflow (spec: Docs/TradeDraft_Spec_MobileQuoteReflow.md) ──────────────────────────────
   The trade's own phone preview reflows to readable sizes — the same shape their customer sees.

   ⚠️ OPT-IN, NOT THE DEFAULT (owner, 16 Jul 2026): "it doesnt look as it will be on (a4 view all
   items as they shoudl show) — default to the original version of live preview, but then give a
   toggle for mobile friendly above it". The trade's preview exists to answer "what will my customer
   actually receive?", so it defaults to the true A4 layout even though that's small on a phone; the
   "Easy read" toggle above it opts into this reflow. That reasoning does NOT transfer to
   accept.html — the CUSTOMER can't zoom-check a document they've never seen, so their page keeps
   reflow as the default (contract sum was 4.00px before H2). The two are deliberately different.

   Scoped to #previewMobile.is-reflow ON PURPOSE: #printRoot (the PDF clone) and #previewDesktop
   (the print SOURCE) can never match these selectors, so the printed document is untouchable by
   this block even before the media-type guard. MUST stay `@media screen and` —
   tests/mobile-quote-reflow.spec.js trips if `screen` is ever dropped.
   Mirrored (scoped to .doc.is-reflow) inline in accept.html — keep the two in lockstep. */
@media screen and (max-width:640px){/* H2-REFLOW */
#previewMobile.is-reflow .pv-title-band{flex-direction:column-reverse;gap:8px;padding:18px 16px 0}
#previewMobile.is-reflow .pv-doc-meta{text-align:left}
#previewMobile.is-reflow .pv-doctitle{font-size:22px}
#previewMobile.is-reflow .pv-doc-ref{font-size:14px;letter-spacing:.6px;margin-top:6px}
#previewMobile.is-reflow .pv-doc-coname{font-size:15px}
#previewMobile.is-reflow .pv-brandblock{max-width:none}
#previewMobile.is-reflow .pv-brass-rule{margin:12px 16px 0}
#previewMobile.is-reflow .pv-parties{grid-template-columns:1fr;margin:14px 16px 0}
#previewMobile.is-reflow .pv-parties .pv-party:first-child{padding-right:0}
#previewMobile.is-reflow .pv-party{padding:12px 0}
#previewMobile.is-reflow .pv-party+.pv-party{padding-left:0;border-left:0;border-top:1px solid #E2E8ED}
#previewMobile.is-reflow .pv-party-label{font-size:14px;letter-spacing:.8px}
#previewMobile.is-reflow .pv-party-name{font-size:16px}
#previewMobile.is-reflow .pv-party-addr{font-size:14px;line-height:1.5}
#previewMobile.is-reflow .pv-project{grid-template-columns:1fr;gap:10px;margin:0 16px;padding:12px 0}
#previewMobile.is-reflow .pv-proj-title{font-size:16px}
#previewMobile.is-reflow .pv-proj-desc{font-size:14px;max-width:none;margin-top:4px}
#previewMobile.is-reflow .pv-proj-dates{text-align:left}
#previewMobile.is-reflow .pv-date-val{font-size:14px}
#previewMobile.is-reflow .pv-sechead{margin:18px 16px 8px}
#previewMobile.is-reflow .pv-sectitle{font-size:14px}
#previewMobile.is-reflow .pv-works{width:calc(100% - 32px);margin:10px 16px 0}
#previewMobile.is-reflow .pv-works .pv-works-title{font-size:14px;padding:0 0 8px}
#previewMobile.is-reflow .pv-works .pv-wh{font-size:14px;font-weight:600;letter-spacing:.2px;padding:0 0 6px}
#previewMobile.is-reflow .pv-wh-sub{font-size:14px}
#previewMobile.is-reflow .pv-works .pv-wc{font-size:14px;padding:10px 0}
#previewMobile.is-reflow .pv-works .pv-wc.desc{font-size:15px;line-height:1.45;padding-right:12px}
#previewMobile.is-reflow .pv-works .pv-wc.desc.num{padding-left:26px}
#previewMobile.is-reflow .pv-wc-no{width:26px;margin-left:-26px;font-size:14px}
#previewMobile.is-reflow .pv-wc-qty{font-size:14px}
#previewMobile.is-reflow .pv-wc-detail{font-size:14px;margin-top:4px}
#previewMobile.is-reflow .pv-pc{font-size:14px;padding:1px 5px;border-radius:3px}
#previewMobile.is-reflow .pv-pc-note{font-size:14px;padding:6px 16px 0}
#previewMobile.is-reflow .pv-empty{font-size:14px}
#previewMobile.is-reflow .pv-works td.pv-sec-title{font-size:14px;padding:7px 0 9px}
/* Easy read scales the bank block with everything else — the reason it had to stop being inline. */
#previewMobile.is-reflow .pv-bank{font-size:14px;line-height:1.6;margin:0 16px}
#previewMobile.is-reflow .pv-bank-lbl{font-size:13px;padding-right:18px}
#previewMobile.is-reflow .pv-bank-val{font-size:15px}
#previewMobile.is-reflow .pv-works td.pv-sec-sub-lbl{font-size:14px}
#previewMobile.is-reflow .pv-sum{width:calc(100% - 32px);margin:6px 16px 0}
#previewMobile.is-reflow .pv-sum td{padding:5px 0}
#previewMobile.is-reflow .pv-sum .pv-sum-lbl{font-size:14px;padding-right:14px}
#previewMobile.is-reflow .pv-sum .pv-sum-val{font-size:16px}
#previewMobile.is-reflow .pv-sum tr.sub .pv-sum-lbl{font-size:14px}
#previewMobile.is-reflow .pv-sum tr.sub .pv-sum-val{font-size:14px}
#previewMobile.is-reflow .pv-sum tr.gross .pv-sum-lbl{font-size:15px}
#previewMobile.is-reflow .pv-sum tr.gross .pv-sum-val{font-size:16px}
#previewMobile.is-reflow .pv-sum tr.due .pv-sum-val{font-size:16px}
/* the one figure the customer pays stays the biggest thing on the phone too — keep after gross/due */
#previewMobile.is-reflow .pv-sum tr.terminal .pv-sum-lbl{font-size:15px}
#previewMobile.is-reflow .pv-sum tr.terminal .pv-sum-val{font-size:18px}
#previewMobile.is-reflow .pv-drc{font-size:14px;margin:10px 16px;padding:10px 12px}
#previewMobile.is-reflow .pv-varline{font-size:14px;margin:8px 16px 0}
#previewMobile.is-reflow .pv-cis-utr{font-size:14px;margin:8px 16px 0}
#previewMobile.is-reflow .pv-cis-pending{font-size:14px;margin:8px 16px 0;padding:10px 12px}
#previewMobile.is-reflow .pv-excl-grid{grid-template-columns:1fr;gap:12px;margin:0 16px}
#previewMobile.is-reflow .pv-excl-eyebrow{font-size:14px}
#previewMobile.is-reflow .pv-excl-list li{font-size:14px;padding:0 0 5px 14px}
#previewMobile.is-reflow .pv-prose{font-size:14px;margin:4px 16px 0}
#previewMobile.is-reflow .pv-pay{width:calc(100% - 32px);margin:0 16px}
#previewMobile.is-reflow .pv-pay .pv-pay-h{font-size:14px;font-weight:600}
#previewMobile.is-reflow .pv-pay .pv-pay-stage{font-size:14px;padding:8px 8px 8px 0}
#previewMobile.is-reflow .pv-pay .pv-pay-amt{font-size:15px;padding:8px 0}
#previewMobile.is-reflow .pv-pay-note{font-size:14px;margin:8px 16px 0}
#previewMobile.is-reflow .pv-terms{font-size:14px;margin:4px 16px 0;padding-left:18px}
#previewMobile.is-reflow .pv-terms li{margin-bottom:5px}
#previewMobile.is-reflow .pv-legal{font-size:14px;margin:10px 16px;padding:10px 12px}
#previewMobile.is-reflow .pv-accept{margin:12px 16px;padding:12px 14px}
#previewMobile.is-reflow .pv-accept-h{font-size:14px}
#previewMobile.is-reflow .pv-accept-p{font-size:14px}
#previewMobile.is-reflow .pv-accept-list li{font-size:14px;padding:0 0 5px 14px}
#previewMobile.is-reflow .pv-accept-close{font-size:14px;margin-top:8px}
#previewMobile.is-reflow .pv-sig-note{font-size:14px;margin:10px 16px 0}
#previewMobile.is-reflow .pv-sig-row{padding:8px 16px 10px;gap:20px}
#previewMobile.is-reflow .pv-sig-label{font-size:14px}
#previewMobile.is-reflow .pv-foot{font-size:14px;padding:10px 16px;flex-wrap:wrap;gap:4px}
}

/* ── FAB + OVERLAYS ──────────────────────────────────────── */
/* bottom offset is safe-area-aware so it clears the bottom-bar (whose bottom padding includes
   env(safe-area-inset-bottom)) on notched phones — a flat 84px let the taller bar rise under the eye
   and collide with the Next button (the "eye overlaps Next" report). */
.preview-fab{position:fixed;bottom:calc(84px + env(safe-area-inset-bottom,0px));right:14px;width:54px;height:54px;border-radius:50%;background:var(--navy);
  color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-lg);z-index:31}
.preview-fab:hover{transform:scale(1.05);background:var(--navy-2)}
.fab-ico{width:24px;height:24px}
@media (min-width:980px){.preview-fab{display:none}}
.sheet-overlay{position:fixed;inset:0;background:rgba(0,33,71,.85);z-index:60;display:none;align-items:flex-end;backdrop-filter:blur(4px)}
.sheet-overlay.is-open{display:flex}
.sheet{background:var(--chalk);width:100%;max-height:92vh;border-radius:var(--r-xl) var(--r-xl) 0 0;overflow:hidden;display:flex;flex-direction:column;animation:slideUp .3s ease}
@keyframes slideUp{from{transform:translateY(100%)}to{transform:none}}
.sheet-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--line);background:#fff}
.sheet-head h3{margin:0;font-family:var(--serif);font-size:20px;color:var(--navy)}
.sheet-head h3 em{font-style:italic;color:var(--brass)}
.sheet-close{width:36px;height:36px;border-radius:50%;background:var(--chalk);color:var(--slate);font-size:18px;display:flex;align-items:center;justify-content:center}
.sheet-body{flex:1;overflow-y:auto;padding:20px;-webkit-overflow-scrolling:touch}
/* The Settings ".set-acc" Account-&-device accordions moved to css/settings.css (with js/settings.js). */
#previewOverlay .sheet{height:100%}
/* Account / sign-in — full-page SPLIT layout: navy brand panel + form column. */
#accountSheet{align-items:stretch;justify-content:stretch;padding:0;background:var(--chalk);backdrop-filter:none}
#accountSheet .sheet{flex-direction:row;max-width:none;width:100%;height:100%;max-height:none;border-radius:0;box-shadow:none;background:var(--chalk);align-items:stretch;animation:fadeIn .2s ease}
/* left brand panel */
.acct-brand{flex:1 1 46%;position:relative;background:var(--navy);color:#fff;display:flex;align-items:center;overflow:hidden}
.acct-brand::after{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(0deg,transparent 0 59px,rgba(197,160,89,.10) 59px 60px),repeating-linear-gradient(90deg,transparent 0 59px,rgba(197,160,89,.10) 59px 60px);pointer-events:none}
.acct-brand::before{content:"";position:absolute;top:0;bottom:0;right:0;width:3px;background:var(--brass);opacity:.85;z-index:2}
.acct-brand-inner{position:relative;z-index:1;max-width:420px;margin:0 auto;padding:48px 52px}
.acct-wordmark{font-family:var(--sans);font-size:24px;letter-spacing:.02em;display:inline-block;margin-bottom:38px}
.acct-wordmark .wm-trade{font-weight:700;color:#fff}
.acct-wordmark .wm-draft{font-weight:300;color:var(--brass)}
.acct-wordmark .acct-tm{font-size:.46em;font-weight:400;vertical-align:top;margin-left:2px;opacity:.55}
.acct-brand-h{font-family:var(--serif);font-size:clamp(26px,3vw,36px);font-weight:600;line-height:1.15;color:#fff;margin:0 0 30px}
.acct-brand-h em{font-style:italic;color:var(--brass)}
.acct-brand-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:16px}
.acct-brand-list li{position:relative;padding-left:30px;font-family:var(--sans);font-size:15px;color:rgba(255,255,255,.85);line-height:1.4}
.acct-brand-list li::before{content:"✓";position:absolute;left:0;top:0;color:var(--brass);font-weight:700}
/* right form column */
.acct-main{flex:1 1 54%;display:flex;flex-direction:column;background:var(--chalk);min-width:0}
#accountSheet .sheet-head{flex:0 0 auto;justify-content:flex-end;background:transparent;border-bottom:0;padding:18px 20px}
#accountSheet .sheet-head h3{display:none}
#accountSheet .sheet-close{position:static;transform:none;background:rgba(0,33,71,.08);color:var(--slate)}
/* "safe center" centres the panel when it fits but top-aligns the moment content overflows —
   without it, justify-content:center inside this overflow-y:auto column clips the first line
   ("Signed in as") above the scroll area on >760px screens, where it can't be scrolled back to. */
#accountSheet .sheet-body{flex:1 1 auto;width:100%;max-width:420px;margin:0 auto;padding:8px 28px 48px;display:flex;flex-direction:column;justify-content:safe center}
#accountSheet .eng-legal{justify-content:center;text-align:center;margin-top:28px}
@media(max-width:760px){
  #accountSheet .sheet{flex-direction:column}
  /* Hide the navy brand/blueprint panel on phones — the marketing pitch isn't needed when you open
     your own Account & Billing, and dropping it gives the account content the full screen. */
  .acct-brand{display:none}
  #accountSheet .sheet-body{justify-content:flex-start;padding-top:26px;max-width:460px}
}
/* On tablet/desktop, open every panel as a FULL-PAGE screen — NOT a small centred card, which
   feels cramped on a computer (a list / form / preview needs room to work). Mirrors the Account
   panel's full-screen takeover: a full-width white header bar over a chalk body, with the content
   held in a centred column so rows/forms don't stretch edge-to-edge on big monitors. #accountSheet
   keeps its own navy split-panel layout — its #id rules override these. On phones the sheets
   already fill the screen (the max-width:699px rule below). */
@media (min-width:700px){
  .sheet-overlay{align-items:stretch;justify-content:stretch;padding:0;background:var(--chalk);backdrop-filter:none}
  .sheet{max-width:none;width:100%;height:100%;max-height:none;border-radius:0;box-shadow:none;animation:fadeIn .2s ease}
  .sheet-head{padding-left:max(18px,calc((100% - 820px)/2));padding-right:max(18px,calc((100% - 820px)/2))}
  .sheet-body{max-width:820px;width:100%;margin:0 auto}
}
/* Compact sheets (small content — the profit Detail + the Overhead calculator): the full-screen
   takeover suits roomy sheets (library / saved / preview) but strands a few rows in a chalk void
   on a computer (owner, 11 Jul 2026). On desktop these become a centred card over the dimmed navy
   backdrop, sized to their content; on phones they keep the full-screen treatment below. */
@media (min-width:700px){
  .sheet-overlay.sheet-compact{align-items:center;justify-content:center;padding:28px;background:rgba(0,33,71,.85);backdrop-filter:blur(4px)}
  .sheet-compact .sheet{width:100%;max-width:620px;height:auto;max-height:88vh;border-radius:var(--r-xl);box-shadow:0 24px 64px rgba(0,10,30,.35);animation:fadeIn .2s ease}
  .sheet-compact .sheet-head{padding:15px 22px}
  .sheet-compact .sheet-body{max-width:none;padding:22px}
}
/* Phones: sheets fill the WHOLE screen — no half-height "pull-up" panel hugging the bottom. */
@media (max-width:699px){
  .sheet-overlay{align-items:stretch}
  .sheet{height:100%;max-height:100%;border-radius:0}
  #previewOverlay .sheet{height:100%}
}
/* ── Builder bottom-nav mobile layout (owner items 1, 2, 18) — placed AFTER all the .sheet-overlay
   / .preview-fab base + responsive rules so these overrides win (same specificity → source order). */
@media(max-width:860px){
  .bottomnav{display:flex}
  .tb-burger{display:none}
  /* Back/Next FLOW at the bottom of the document (owner, 6 Jul) — they sit just above the floating
     eye when you scroll all the way down, rather than being pinned as a fixed bar. Back stays
     flush-left, Next flush-right (the base flex layout is kept). On a short quote they sit right
     after the content — the owner chose this over the always-fixed bar. */
  .bottom-bar{position:static;left:auto;right:auto;bottom:auto;transform:none;z-index:auto;box-shadow:none;border-top:0;background:transparent;padding:22px 16px 0;margin:10px 0 0}
  .bottom-bar.is-hidden{transform:none}
  .app-shell{min-height:auto}
  body{background:var(--paper);padding-bottom:calc(164px + env(safe-area-inset-bottom))}   /* leaves the flowing Back/Next a small gap above the fixed eye + section nav when scrolled to the bottom */
  .builder{padding-bottom:0}
  /* Sheets sit ABOVE the nav so it stays visible (the crux of the "nav stays put" ask). */
  .sheet-overlay{bottom:calc(78px + env(safe-area-inset-bottom))}
  .bottom-hint{bottom:calc(82px + env(safe-area-inset-bottom))}
  .preview-fab{bottom:calc(92px + env(safe-area-inset-bottom))}
  /* (the floating "＋ Add work" pill was removed 19 Jul 2026 — owner: it hovered over the pricing
     panel as clutter; the in-schedule "＋ Add Work" button is the one add-work door) */
}
.sheet-pv-head{font-family:var(--sans);font-size:13px;letter-spacing:1.2px;text-transform:uppercase;color:var(--navy);font-weight:700}
/* branded confirm / prompt dialog (replaces native confirm/prompt) */
.engd-overlay{position:fixed;inset:0;background:rgba(0,33,71,.85);z-index:80;display:none;align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(4px)}
.engd-overlay.is-open{display:flex}
.engd-box{background:var(--chalk);width:100%;max-width:400px;border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:22px 22px 18px;animation:engdPop .2s ease}
@keyframes engdPop{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
.engd-title{margin:0 0 8px;font-family:var(--serif);font-size:20px;color:var(--navy)}
.engd-msg{margin:0 0 16px;font-size:14px;line-height:1.5;color:var(--slate)}
.engd-input{width:100%;padding:10px 12px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font-size:16px;margin:0 0 16px;background:#fff;color:var(--slate)}  /* 16px: no iOS zoom */
.engd-input:focus{outline:2px solid var(--brass);outline-offset:-1px;border-color:var(--brass)}
.engd-actions{display:flex;gap:10px;justify-content:flex-end}
.engd-btn{font-family:var(--sans);font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:11px 18px;border-radius:var(--r-sm);cursor:pointer}
.engd-cancel{background:none;border:1px solid var(--line-strong);color:var(--slate)}
.engd-cancel:hover{border-color:var(--navy);color:var(--navy)}
.engd-ok{background:var(--navy);border:none;color:#fff}
.engd-ok:hover{background:var(--navy-2)}
.engd-ok.engd-danger{background:var(--red)}
.engd-ok.engd-danger:hover{background:#9a3528}

/* ── SAVED QUOTES (My Quotes sheet) ── */
.sq-bar{display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.sq-savecur,.sq-new{flex:1 1 auto;min-height:42px;border-radius:var(--r-md);font-family:var(--sans);font-size:12px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;padding:10px 14px}
.sq-savecur{background:var(--navy);color:#fff}
.sq-savecur:hover{background:var(--navy-2)}
.sq-new{background:#fff;color:var(--navy);border:1px solid var(--line-strong)}
.sq-new:hover{background:var(--chalk)}
.sq-empty{padding:26px 16px;text-align:center;color:var(--steel);font-size:13px;line-height:1.55;background:#fff;border:1px dashed var(--line-strong);border-radius:var(--r-md)}
.sq-row{display:flex;align-items:center;gap:10px;padding:11px 12px;background:#fff;border:1px solid var(--line);border-radius:var(--r-md);margin-bottom:8px}
.sq-main{flex:1;min-width:0}
.sq-name{font-family:var(--sans);font-weight:600;color:var(--navy);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sq-meta{font-size:10.5px;color:var(--steel);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sq-total{font-family:var(--sans);font-weight:700;color:var(--navy);font-size:13px;flex:0 0 auto}
.sq-actions{display:flex;gap:5px;flex:0 0 auto}
.sq-act{font-family:var(--sans);font-size:11px;font-weight:600;padding:6px 9px;border-radius:6px;border:1px solid var(--line-strong);background:#fff;color:var(--slate);min-height:32px}
.sq-act:hover{background:var(--chalk)}
.sq-del{color:var(--red);border-color:#e0b4ac;font-weight:700}
.sq-del:hover{background:var(--red-soft)}
.bb-save{background:#fff;color:var(--navy);border:1px solid var(--line-strong)}
.bb-save:hover{background:var(--chalk)}
.bb-save.is-saved{background:var(--green-soft);color:var(--green);border-color:var(--green)}

/* Raise-a-payment sheet — the agreed schedule read as a LEDGER: label left, money right, one
   column. "left to invoice" is its terminal row, so its figure sits in the same money column as
   the stages above rather than reading as a sentence (owner, 19 Jul 2026). Every row shares this
   one grid, so the right edge can't drift; don't re-inline these on the rows in JS. */
.rs-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:7px 0;border-bottom:1px solid var(--line);font-family:var(--sans);font-size:13.5px}
.rs-row .rs-amt{font-family:var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
.rs-row.is-paid{opacity:.65;color:#2e7d5b}
.rs-row.is-due{color:var(--navy)}
.rs-row.is-todo{color:var(--steel)}
.rs-remain{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:9px 0 0;
  font-family:var(--sans);font-size:13.5px;color:var(--navy)}
.rs-remain .rs-amt{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:700;white-space:nowrap}
.rs-empty{color:var(--steel);font-size:13px}

/* Detail tiles */
.ms-flow{background:#fff;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.ms-flow-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:12px 14px;font-family:var(--sans);font-size:14px;color:var(--slate);border-bottom:1px solid var(--line)}
.ms-flow-row b{font-weight:700;color:var(--navy);font-size:15px;white-space:nowrap}
.ms-flow-row .inline-note{font-style:normal;color:var(--steel);font-size:11px}
.ms-flow-profit b{color:var(--navy)}  /* neutral ink — green is reserved for the margin-HEALTH signal, not the £ figure (owner, 12 Jun) */
.ms-flow-total{background:var(--navy);border-bottom:0}
.ms-flow-total span,.ms-flow-total b,.ms-flow-total .inline-note{color:#fff;font-size:16px;font-weight:700}
.ms-substats{display:flex;gap:12px;margin-top:14px}
.ms-stat{flex:1;text-align:center;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);padding:11px 8px;font-family:var(--sans)}
.ms-stat b{display:block;font-size:18px;font-weight:700;color:var(--navy);line-height:1.1}
.ms-stat span{display:block;font-size:11px;color:var(--steel);margin-top:3px}
.ms-stat b.green{color:var(--green)}.ms-stat b.amber{color:var(--st-warn)}.ms-stat b.red{color:var(--red)}
.ms-explain{margin-top:16px;padding:14px;background:#fbfaf6;border-left:3px solid var(--brass);border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:13px;color:var(--slate);line-height:1.5}

/* ── VAT / STAGE 4 ───────────────────────────────────────── */
.vat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.vat-grid.cols-3{grid-template-columns:repeat(3,1fr)} /* B2C: DRC hidden, 3 rates fill the row */
.vat-btn{background:#fff;border:1.5px solid var(--line);border-radius:var(--r-md);padding:12px 8px;
  font-family:var(--sans);font-size:11px;font-weight:700;color:var(--slate);text-align:center;transition:.15s;min-height:48px}
.vat-btn.is-active{border-color:var(--brass);background:linear-gradient(180deg,#fff,#faf6ed);color:var(--navy);box-shadow:0 0 0 3px rgba(197,160,89,.18)}
.vat-btn small{display:block;font-weight:400;font-size:9px;color:var(--steel);margin-top:2px}
.vat-note{margin-top:12px;padding:12px 14px;background:var(--chalk);border-left:3px solid var(--brass);border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:12px;color:var(--slate);line-height:1.5}
.vat-note strong{font-family:var(--sans);color:var(--navy);font-weight:700}
.vat-note.drc{background:var(--amber-soft);border-left-color:var(--amber);color:#5c4310}
/* Reverse-Charge guardrail: a gentle, non-blocking nudge when the inputs look like a CIS
   subcontract (B2B + a deducting CIS tier) but a positive VAT rate is still selected. Advisory
   only — it never changes a figure. Slightly stronger amber than the DRC note so it reads as
   "have a think", not an error. */
.vat-guard{margin-top:10px;padding:11px 13px;background:var(--amber-soft);border:1px solid var(--amber);
  border-left:3px solid var(--amber);border-radius:var(--r-sm);font-size:11.5px;color:#5c4310;line-height:1.5}
.vat-guard strong{font-family:var(--sans);color:#5c4310;font-weight:700}
.vat-help-toggle{margin-top:10px;font-family:var(--sans);font-size:12px;font-weight:600;color:var(--navy);background:none;text-decoration:underline;cursor:pointer;padding:4px 0}
.vat-help-toggle:hover{color:var(--brass)}
.vat-help{margin-top:8px;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.vat-help-row{padding:10px 12px;font-size:12px;line-height:1.5;color:var(--slate)}
.vat-help-row+.vat-help-row{border-top:1px solid var(--line)}
.vat-help-row strong{font-family:var(--sans);color:var(--navy);font-weight:700}
/* Slimmed (owner, 4 Jul PM — "is this navy box too heavy"): kept navy (the total is the money hero)
   but flattened the gradient to a flat navy and tightened the padding + row spacing so it reads as a
   lighter card, not a looming slab — most noticeable in the empty/£0 state. */
.final-summary{background:var(--navy);color:#fff;border-radius:var(--r-lg);padding:15px 20px;margin-bottom:14px}
.fs-h{font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:1.5px;text-transform:uppercase;color:rgba(255,255,255,.55);margin:0 0 8px}
.fs-row{display:flex;justify-content:space-between;padding:4px 0;font-size:13px;color:rgba(255,255,255,.85);gap:10px}
.fs-row.cis{color:#f7c873}
.fs-row.gross{margin-top:5px;padding-top:9px;border-top:1px solid rgba(255,255,255,.18);font-family:var(--sans);font-size:18px;font-weight:700;color:#fff}
.fs-row.gross .fs-amt{color:var(--brass)}
.fs-row.client-pays{margin-top:4px;font-family:var(--sans);font-size:14px;font-weight:600;color:#9ed47e}
.fs-row .fs-amt.fs-info{color:rgba(255,255,255,.6);font-weight:600}
/* VAT treatment folded into the summary card as one quiet line (4 Jul redesign) */
.fs-treat{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-top:9px;padding-top:9px;border-top:1px solid rgba(255,255,255,.14);font-size:12.5px;color:rgba(255,255,255,.72);line-height:1.45}
#fsTreat{flex:1;min-width:0}
.fs-treat-edit{flex:none;background:none;border:0;padding:2px 0;font-family:var(--sans);font-size:12.5px;font-weight:700;color:var(--brass-soft);cursor:pointer;white-space:nowrap;min-height:32px}
.fs-treat-edit:hover{text-decoration:underline}
.fst-ok{color:#9ed47e;font-weight:700}   /* the "✓" confidence marker on the treatment line (reads on navy) */
/* "Only you see this" — your profit, fenced at the foot of the navy box (owner, 16 Jul). Full-width
   button (the marginSheet's only door on step 4), styled to read as a quiet footer, NOT a CTA: no fill,
   no border, the same hairline separator as .fs-treat above it. The dot reuses the health bar's traffic
   language; --green/--amber/--red all clear 4.5:1 on --navy, so the same tokens hold on this surface. */
.fs-mine{display:block;width:100%;text-align:left;background:none;border:0;border-top:1px solid rgba(255,255,255,.14);margin-top:9px;padding:9px 0 0;cursor:pointer;font-family:var(--sans)}
/* .55 not .45, and 10px not 9.5px — i.e. exactly .fs-h above it. Same role (a small uppercase label in
   the navy box), so same treatment; .45 measured 4.23:1 on --navy (under AA 4.5), .55 measures 5.66:1. */
.fs-mine-lab{display:block;font-size:10px;font-weight:600;letter-spacing:1.5px;text-transform:uppercase;color:rgba(255,255,255,.55);margin-bottom:5px}
.fs-mine-row{display:flex;justify-content:space-between;align-items:center;gap:10px}
.fs-mine-fig{display:flex;align-items:center;gap:8px;min-width:0;font-size:13.5px;font-weight:600;color:rgba(255,255,255,.9)}
.fs-mine-fig strong{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:600;color:#fff}
.fs-mine-fig .fs-mine-net{font-weight:500;color:rgba(255,255,255,.6)}
.fs-mine-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.fs-mine-dot.green{background:#9ed47e}   /* the navy-surface greens/ambers/reds — brighter than the on-white
.fs-mine-dot.amber{background:#f7c873}      tokens (--green/--amber read muddy on navy), matching the
.fs-mine-dot.red{background:#f08d7a}        .fs-row.cis amber + .fs-row.client-pays green already in this box */
.fs-mine-dot.empty{background:rgba(255,255,255,.3)}
.fs-mine-cta{flex:none;font-size:12.5px;font-weight:700;color:var(--brass-soft);white-space:nowrap}
.fs-mine:hover .fs-mine-cta{text-decoration:underline}
.fst-sub{color:rgba(255,255,255,.5)}     /* the lighter state continuation on the treatment line */
/* Stage-4 VAT treatment as clear one-per-line points instead of a "·"-joined sentence (owner, 6 Jul) */
.fst-points{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}
.fst-points li{position:relative;padding-left:14px;color:rgba(255,255,255,.82)}
.fst-points li::before{content:'';position:absolute;left:1px;top:7px;width:5px;height:5px;border-radius:50%;background:var(--brass-soft)}
.fst-note{display:block;margin-top:6px;font-size:11.5px}

.empty-state{text-align:center;padding:24px 14px;color:var(--steel);font-style:italic;font-size:13px}
.empty-state .mic-hint{justify-content:center;margin:10px 0 0;font-style:normal}
/* Skip-running-costs edge case — a quiet footer under the sliders (4 Jul redesign; ticked = skip) */
.oh-skip{margin:16px 0 0;padding-top:14px;border-top:1px solid var(--line)}
/* The old top:4px nudge here compensated for ".field label{display:block}" killing the flex
   centring; ".field label.check-label" now restores real flex centring, so the nudge is gone
   (it would overshoot 4px low on a flex-centred box). Verified in-browser 5 Jul: delta < 1px. */
.oh-skip .check-label{font-size:13.5px;color:var(--slate);line-height:1.25}
.oh-skip .check-label input{margin:0}
.es-icon{display:block;margin:0 auto 8px;width:32px;height:32px;color:var(--line-strong)}
.muted{color:var(--steel)}

/* ── PRINT (A4 document only) ────────────────────────────── */
/* Dedicated, isolated print container — the live app layout (grid/sticky) made some
   browsers print a blank page, so on "Save as PDF" we clone the finished document into
   #printRoot and print ONLY that, in plain block layout. */
#printRoot{display:none}
@media print{
  @page{size:A4;margin:0}
  html,body{background:#fff!important;margin:0!important;padding:0!important}  /* zero the page box so the document height alone drives pagination (a full 1-page quote stays 1 page) */
  body>*{display:none!important}
  /* Force brand backgrounds (navy bands, brass) to print even when the user hasn't ticked
     "Background graphics", and move the page margin into padding so the browser's header/footer
     chrome (date / title / file URL) is suppressed. */
  #printRoot{display:block!important;padding:8mm 10mm;-webkit-print-color-adjust:exact;print-color-adjust:exact}  /* 14mm -> 9mm (owner) -> 8mm top/bottom so a full single-page quote fits one A4 page */
  #printRoot *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  #printRoot .pv-works tr,#printRoot .pv-pay tr,#printRoot .pv-sum,#printRoot .pv-party,#printRoot .pv-project,#printRoot .pv-excl-grid,#printRoot .pv-accept,#printRoot .pv-sig-row{break-inside:avoid}
  /* Keep the whole agreement block (payment + terms + acceptance + signatures) together — a spilling
     quote drops it to page 2 as ONE unit ("page 1 = quote, page 2 = payment & acceptance"). */
  #printRoot .pv-agreement{break-inside:avoid}
  #printRoot .pv-sechead{break-after:avoid}
  #printRoot thead{display:table-header-group}  /* repeat the schedule header if it spills to a 2nd page */
  #printRoot .pv-cis-pending{display:none!important}  /* builder aid only — never on the document */
}


/* ── next extracted block ── */


  /* (4) Sentence-case form labels — calmer than ALL-CAPS, no new fonts/colours */
  .field label{text-transform:none;letter-spacing:0;font-size:12.5px}
  .sf-label{text-transform:none;letter-spacing:0;font-size:12.5px}
  label.check-label{text-transform:none;letter-spacing:0}

  /* (3) Library-picker results → an informative dropdown */
  #awResults{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:0 10px 28px rgba(0,33,71,.10);margin-top:8px}
  .awr-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--chalk)}
  .awr-head-l{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--steel)}
  .awr-browse{background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-size:12px;font-weight:600;cursor:pointer;padding:2px}
  .awr-browse:hover{text-decoration:underline}
  #awResults .aw-res{display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:#fff;border:0;border-bottom:1px solid var(--line);padding:13px 14px;cursor:pointer;font-family:var(--prose)}
  #awResults .aw-res:last-child{border-bottom:0}
  #awResults .aw-res:hover{background:var(--chalk)}
  .awr-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
  .awr-d{font-family:var(--sans);font-size:14px;font-weight:600;color:var(--navy);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .awr-sub{font-size:12px;color:var(--steel)}
  #awResults .awr-price{font-family:var(--sans);font-size:14px;font-weight:700;color:var(--navy);font-variant-numeric:tabular-nums;flex:none}
  .awr-plus{flex:none;width:30px;height:30px;border-radius:8px;border:1px solid var(--line-strong);color:var(--brass-deep);display:flex;align-items:center;justify-content:center;font-size:18px;line-height:1}
  #awResults .aw-res:hover .awr-plus{border-color:var(--navy);color:var(--navy)}
  #awResults .aw-res-new{display:flex;align-items:center;gap:10px;background:var(--chalk);color:var(--brass-deep);font-family:var(--sans);font-weight:600;font-size:14px;padding:14px}
  .awr-newplus{font-weight:700;font-size:16px}

  /* (1) Ready-to-send checklist (Stage 4) — its own panel again (owner 4 Jul PM). The .panel gives
     the border+radius; kill its padding so the head + rows fill it edge-to-edge like a proper list. */
  .rts-panel{padding:0;overflow:hidden}
  .rts{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;margin-bottom:14px}
  .rts:empty{display:none}
  .rts-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:15px 18px;border-bottom:1px solid var(--line)}
  .rts-h{font-family:var(--serif);font-size:18px;font-weight:600;color:var(--navy)}
  .rts-count{font-family:var(--sans);font-size:12.5px;font-weight:700;color:var(--brass-deep)}
  .rts-count.is-ready{color:var(--green)}
  .rts-item{display:flex;align-items:center;gap:13px;padding:14px 18px;border-bottom:1px solid var(--line)}
  .rts-item:last-child{border-bottom:0}
  .rts-mark{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;font-family:var(--sans)}
  .rts-item.is-done .rts-mark{background:#e6f0e9;color:var(--green);border:1px solid #c2dccb}
  .rts-item.is-todo .rts-mark{background:#f6ecd6;color:var(--brass-deep);border:1px solid #e6d3a6}
  .rts-main{flex:1;min-width:0}
  .rts-t{font-family:var(--sans);font-size:14px;font-weight:600;color:var(--navy)}
  .rts-s{font-family:var(--prose);font-size:12.5px;color:var(--steel);margin-top:2px}
  .rts-item.is-todo .rts-s{color:var(--brass-deep)}
  .rts-act{flex:none;background:none;border:0;font-family:var(--sans);font-size:13px;font-weight:700;color:var(--navy);cursor:pointer;padding:4px;white-space:nowrap}
  .rts-item.is-todo .rts-act{color:var(--brass-deep)}
  .rts-act:hover{text-decoration:underline}
  .panel.rts-flash{box-shadow:0 0 0 3px rgba(197,160,89,.4);transition:box-shadow .3s}
  /* Review-header "to finish" chips — only the OUTSTANDING checklist items, surfaced under the
     subtitle so the last task is one tap away (the full checklist stays by the send actions). */
  /* Merged send card (4 Jul redesign): header pill, in-card checklist, preview button, primary
     accept link, compact save/send row. The ONE navy button in the card is Create accept link —
     the grid's buttons all drop to outline so the hierarchy reads at a glance. */
  .sp-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px}
  .sp-pill{font-family:var(--sans);font-size:12.5px;font-weight:700;border-radius:22px;padding:6px 13px;white-space:nowrap}
  .sp-pill:empty{display:none}
  .sp-pill.is-ready{background:#e6f0e9;color:var(--green);border:1px solid #c2dccb}
  .sp-pill.is-todo{background:#f6ecd6;color:var(--brass-deep);border:1px solid #e6d3a6}
  .sp-rts{border-radius:10px}
  .sp-preview{display:none;width:100%;align-items:center;justify-content:center;gap:8px;margin:0 0 12px;padding:12px 8px;min-height:48px;background:#fff;color:var(--navy);border:1px solid var(--line-strong);border-radius:var(--r-md);font-family:var(--sans);font-size:13px;font-weight:700;cursor:pointer;transition:background .12s}
  .sp-preview:hover{background:var(--chalk)}
  .sp-preview .send-ico{width:16px;height:16px}
  @media(max-width:979px){.sp-preview{display:flex}}
  .sp-pitch{font-size:12px;color:var(--steel);line-height:1.5;text-align:center;margin:10px 0 0}
  .sp-or{display:flex;align-items:center;gap:12px;margin:18px 0 12px;font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--steel);white-space:nowrap}
  .sp-or::before,.sp-or::after{content:'';flex:1;height:1px;background:var(--line)}
  /* THE one primary action (slice 4, 18 Jul). The accept link is the flagship — the client taps once,
     accepts, and the deposit follows — but it was wearing .send-btn, the SAME class as the WhatsApp and
     Email buttons two rows below it. Three identical navy buttons and no focal point, on the one screen
     whose entire job is "send it". It now carries its own weight, and everything else on the card drops
     to outline, so exactly ONE solid navy button appears per screen.
     Sentence case rather than the .send-btn uppercase micro-type: this is an instruction, not a chip.
     The arrow is a real span, NOT a ::after — .gate-locked already owns ::after for the padlock, and a
     second one would leave a doubled glyph (the same trap noted on the stepper marks). */
  .sp-primary{width:100%;min-height:56px;display:flex;align-items:center;justify-content:center;gap:9px;padding:15px 18px;background:var(--navy);color:#fff;border:1px solid var(--navy);border-radius:var(--r-md);font-family:var(--sans);font-size:15px;font-weight:700;cursor:pointer;transition:background .15s}
  .sp-primary:hover{background:var(--navy-2)}
  .sp-arrow{font-size:16px;line-height:1}
  .sp-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px}
  .sp-grid .bb-btn,.sp-grid .send-btn{width:100%;min-height:48px;display:flex;align-items:center;justify-content:center;gap:7px;padding:11px 6px}
  .sp-grid .bb-download{background:#fff;color:var(--navy);border:1px solid var(--line-strong);box-shadow:none}
  .sp-grid .bb-download:hover{background:var(--chalk)}
  /* The block comment above this group already promised "the grid's buttons all drop to outline so the
     hierarchy reads at a glance" — but only bb-download ever did, leaving WhatsApp and Email solid navy
     and competing with the primary. Finishing the job the comment described. */
  .sp-grid .send-btn{background:#fff;color:var(--navy);border:1px solid var(--line-strong)}
  .sp-grid .send-btn:hover{background:var(--chalk)}
  /* Phase two, once the link exists, has its own primary: "Email link to client" is how the quote
     actually reaches them. Copy was equally navy beside it, so the same no-focal-point problem repeated
     one step later. One filled button per screen holds in BOTH phases. */
  #shareResult #shareCopy{background:#fff;color:var(--navy);border:1px solid var(--line-strong)}
  #shareResult #shareCopy:hover{background:var(--chalk)}
  .rts-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:10px 0 2px}
  .rtt-label{font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--steel)}
  .rtt-chip{font-family:var(--sans);font-size:12.5px;font-weight:700;color:var(--navy);background:#fff;border:1.5px solid var(--brass);border-radius:22px;padding:9px 15px;min-height:44px;cursor:pointer;transition:background .12s,border-color .12s}
  .rtt-chip:hover{background:var(--chalk);border-color:var(--brass-deep)}


/* ── next extracted block ── */

@keyframes engspin{to{transform:rotate(360deg)}}#engSplash.is-gone{opacity:0;pointer-events:none}
/* Panel deep-link (?settings/?account) AND ?quote deep-link: keep the splash opaque over the builder
   until the destination is on screen, and hide the builder chrome behind it (panel sheets + the job
   overview are shown by their own boot/showJobOverview code, then the splash lifts). */
html.td-panel-deeplink #engSplash,html.td-quote-deeplink #engSplash{opacity:1!important;pointer-events:auto}
html.td-panel-deeplink #appShell,html.td-panel-deeplink .stepper-wrap,html.td-panel-deeplink .demo-bar,
html.td-quote-deeplink #appShell,html.td-quote-deeplink .stepper-wrap,html.td-quote-deeplink .demo-bar{visibility:hidden}

/* ── next extracted block ── */


        #vatGuidePanel .vg-back{background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-weight:600;font-size:13px;cursor:pointer;padding:2px 0;min-height:32px}
        /* Header row: just the Back button above the title. (The "Question N of N" counter was removed
           5 Jul — it read "Question 2 of 2" when Q1 was pre-answered from the profile, which confused; the
           answered trail of ✓ chips already shows progress.) */
        .vg-q-head{display:flex;align-items:center;gap:10px;margin:0 0 6px}
        .vg-q .vg-qh{font-family:var(--serif,'Newsreader',serif);font-size:21px;color:var(--navy);margin:2px 0 6px;line-height:1.25}
        .vg-q .vg-qhint{margin:0 0 14px;font-size:12.5px;line-height:1.5;color:var(--steel)}   /* 13.5px -> 12.5px to match the other hints (owner, 5 Jul) */
        .vg-opts{display:flex;flex-direction:column;gap:10px}
        .vg-opt{text-align:left;background:#fff;border:1.5px solid var(--line-strong);border-radius:12px;padding:14px 16px;cursor:pointer;font-family:var(--sans);transition:border-color .15s,box-shadow .15s,transform .05s}
        .vg-opt:hover{border-color:var(--navy);box-shadow:0 2px 10px rgba(0,33,71,.08)}
        .vg-opt:active{transform:translateY(1px)}
        .vg-opt b{display:block;font-size:15.5px;color:var(--navy);font-weight:700}
        .vg-opt span{display:block;margin-top:3px;font-size:12.5px;color:#5f6f86;line-height:1.45}
        .vg-step{font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:#6b788c;white-space:nowrap}
        /* "Most jobs" badge — ONLY the rate question's standard-20% card (its hint already says
           "if in doubt, pick the first"); the other questions are genuine either-ways. */
        .vg-opt-most{position:relative;border-color:var(--brass);background:#fffdf8;padding-top:22px}
        /* .vg-opt-most prefix beats ".vg-opt span{color:#5f6f86}" (which was greying the badge text — the real unreadability); navy not brass per the brand rule (owner, 5 Jul) */
        .vg-opt-most .vg-most-tag{position:absolute;top:-9px;left:14px;background:var(--navy);color:#fff;font-size:10px;letter-spacing:1px;font-weight:700;text-transform:uppercase;border-radius:9px;padding:2px 9px;margin:0}
        .vg-opt.vg-opt-most span{margin-top:3px}
        /* Selected state at the RESULT — the last question's options stay visible + re-selectable so you
           can flick between them and read the detail below, instead of them vanishing (owner, 6 Jul). */
        .vg-opt.is-selected{position:relative;border-color:var(--navy);background:#f2f6fb;box-shadow:0 0 0 2px rgba(0,33,71,.14);padding-right:38px}
        .vg-opt.is-selected::after{content:'✓';position:absolute;top:50%;right:15px;transform:translateY(-50%);color:var(--navy);font-weight:800;font-size:15px}
        .vg-opt.is-selected.vg-opt-most{border-color:var(--navy)}
        /* Answered trail — what you've said so far on this path, one-tap editable */
        .vg-done{display:flex;align-items:center;gap:10px;background:var(--chalk);border:1px solid var(--line);border-radius:9px;padding:9px 13px;margin:0 0 8px;font-family:var(--sans);font-size:13px}
        .vg-done-tick{color:var(--green);font-weight:700;flex:none}
        .vg-done-l{flex:1;min-width:0;color:var(--slate);font-weight:600}
        .vg-done-edit{flex:none;background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-size:12.5px;font-weight:700;cursor:pointer;padding:4px;min-height:32px;white-space:nowrap}
        .vg-done-edit:hover{text-decoration:underline}
        /* The result card went LIGHT 19 Jul 2026 (owner: "the box is too heavy") — same chalk-note
           family as the rest of the step, the coloured left rule alone carrying the verdict. The
           WORDING is untouched: the guardrail tests pin it. */
        .vg-card{border-radius:0 14px 14px 0;padding:16px 16px 14px;background:var(--chalk);color:var(--slate);border-left:4px solid var(--brass);margin-top:4px}
        .vg-card.vg-zero,.vg-card.vg-novat{border-left-color:#1f6b43}
        .vg-tag{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--brass-deep);font-weight:700;font-family:var(--sans)}
        .vg-card.vg-zero .vg-tag,.vg-card.vg-novat .vg-tag{color:#1f6b43}
        .vg-head{font-family:var(--serif,'Newsreader',serif);font-size:22px;line-height:1.2;margin:5px 0 9px;color:var(--navy)}
        .vg-reason{margin:0;font-size:14px;line-height:1.55;color:var(--slate)}
        .vg-doc{margin-top:14px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:12px 13px}
        .vg-doc-h{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--brass-deep);font-weight:700}
        .vg-doc-q{margin-top:7px;font-size:13px;line-height:1.5;color:var(--navy);font-style:italic}
        .vg-doc-n{margin-top:8px;font-size:12px;line-height:1.5;color:var(--steel)}
        .vg-toggle{display:flex;gap:10px;align-items:flex-start;margin-top:14px;padding-top:13px;border-top:1px solid var(--line);font-size:12.5px;line-height:1.5;color:var(--slate);cursor:pointer}
        .vg-toggle input{margin-top:3px;flex:0 0 auto}
        .vg-actions{margin-top:12px;display:flex;flex-wrap:wrap;gap:14px;align-items:center}
        .vg-change{background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-weight:600;font-size:13.5px;cursor:pointer;padding:0}
        .vg-note{margin:12px 0 0;font-size:11.5px;line-height:1.5;color:#637085}
        .vg-cis{margin:12px 0 0;background:var(--chalk);border-left:3px solid var(--brass);border-radius:0 10px 10px 0;padding:11px 13px;font-size:12.5px;line-height:1.55;color:var(--navy)}
        .vg-cis b{font-weight:700}
        .vg-mem{margin:0 0 12px;background:#eaf6ef;border-left:3px solid #1f6b43;border-radius:0 10px 10px 0;padding:11px 13px;font-size:13px;line-height:1.55;color:#143a27}
        .vg-memlink{background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-weight:600;font-size:12.5px;cursor:pointer;padding:0;text-decoration:underline}
        .rv-head-row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px}
        .rv-edit{background:none;border:0;color:var(--brass-deep);font-family:var(--sans);font-weight:600;font-size:12.5px;cursor:pointer;padding:0;white-space:nowrap}
        .rv-edit:hover{text-decoration:underline}
        .rv-tag{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--brass-deep);font-weight:700;font-family:var(--sans);margin:0}
        .rv-head{font-family:var(--serif,'Newsreader',serif);font-size:18px;line-height:1.25;margin:4px 0 6px;color:var(--navy)}
        .rv-reason{margin:0;font-size:13px;line-height:1.5;color:var(--steel)}
        .rv-warn{margin:10px 0 0;background:#fdf6e3;border-left:3px solid var(--brass);border-radius:0 8px 8px 0;padding:9px 12px;font-size:12.5px;line-height:1.45;color:#6b5418}
        .rv-ok{margin:10px 0 0;font-size:12.5px;line-height:1.45;color:#1f6b43}
      
/* ── Mono numeric data (IBM Plex Mono) — figures, totals & % in the app UI; labels stay in the UI sans. Mixed label+figure spans (.rts-s, .ss-cost) and prose hints deliberately excluded. ── */
.li-qty,.li-rate,.pay-amt,.li-line-cost,.li-sell,.fs-amt,.sf-val,.pv-row-amt,.pv-tamt,.pvs-v,.pvs-pct,.pvs-hl-v{font-family:var(--mono);font-variant-numeric:tabular-nums}
.pv-trow .pv-tamt{font-family:var(--mono)}
