/* ──────────────────────────────────────────────────────────────────────────
   NoticeDesk — authoritative design tokens + component styles.

   Design system v3 (fable-overhaul): professional UK fintech. Deep emerald
   accent on a cool-light canvas, dark navy-slate sidebar, deliberate radius
   scale (4/8/12/20), layered elevation shadows, larger DM Sans type scale.

   Token contract: every pre-v3 custom property name is preserved — partials
   (batch.html stat cells, extract.html BO column, home demo SVG strokes)
   reference them via inline style/attr. New tokens are additive.

   design_handoff/colors_and_type.css is the stale dark-theme token set —
   DO NOT import it.
   ────────────────────────────────────────────────────────────────────────── */

/* ── SELF-HOSTED FONTS ─────────────────────────────
   DM Sans (variable 300-700) + DM Mono (400/500), woff2 under static/fonts/.
   Self-hosted because the CSP (style-src/font-src 'self') blocks the Google
   Fonts CDN — the <link> approach never loaded in any CSP'd environment.
   Subset ranges copied from Google Fonts css2 output. DM Mono 700 is
   synthesised by the browser (the family has no 700 cut). */
@font-face{font-family:'DM Sans';font-style:normal;font-weight:300 700;font-display:swap;src:url('../fonts/dm-sans-var-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'DM Sans';font-style:normal;font-weight:300 700;font-display:swap;src:url('../fonts/dm-sans-var-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'DM Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/dm-mono-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'DM Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/dm-mono-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'DM Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/dm-mono-500-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'DM Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/dm-mono-500-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root {
  /* Brand — deep emerald. Intentional, not default green.
     D1 (2026-07-12): white-text-on-green components REST on --gh (#047857,
     5.48:1 vs white) and hover --gh2 (#065f46, 7.68:1). --g (3.77:1 vs white)
     stays the accent token — green text/washes/strokes — never a background
     under white text. */
  --g:#059669; --gh:#047857; --gh2:#065f46; --glo:rgba(5,150,105,.08); --gmd:rgba(5,150,105,.16); --gbrd:rgba(5,150,105,.3);

  /* Canvas + surfaces — premium restyle 2026-08-08: canvas one step deeper,
     plus two NEW surface tokens: --card-head (card header strips) and --inset
     (insets / table header rows / quiet fills). Toned, never stark white. */
  --bg:#eef2f7; --white:#fff;
  --card-head:#fafbfd;
  --inset:#f7fafc;

  /* Dark sidebar surface system */
  --sb-bg:#162032;
  --sb-text:#aebccd;
  --sb-text-dim:#8296ad;   /* 5.37:1 on --sb-bg — WCAG AA for the 10.5px labels/badges (was #67788d, 3.61:1) */
  --sb-accent:#34d399;
  --sb-hover:rgba(255,237,213,.07);   /* warm hover tint on navy */
  --sb-active:rgba(52,211,153,.13);
  --sb-brd:rgba(255,255,255,.07);

  /* Borders */
  --brd:#dfe6ee; --brd-md:#c9d3e0; --brd-str:#a9b7c8;

  /* Ink scale — navy-tinted slate.
     --t4 carries real content (.tb-sub, .field-lbl, figcaptions, .price-period)
     so it must clear WCAG AA: #62748c = 4.78:1 on white (was #8b9aac, 2.87:1).
     --t5 (1.59:1) is placeholders/disabled glyphs ONLY — never readable text. */
  --t1:#0e1a28; --t2:#33445a; --t3:#5c6e84; --t4:#62748c; --t5:#c4cedb;

  /* Data + semantic */
  --data:#15619e;
  --ok:#059669; --ok-bg:rgba(5,150,105,.08); --ok-brd:rgba(5,150,105,.25);
  /* --ok is the SAME hex as --g (3.77:1 on white, 3.35:1 on the canvas): fills,
     dots, strokes and borders only. Text that means "ok" uses --ok-text (=
     --gh2, 6.26:1 even on the --ok-bg tint over the canvas, where --gh's
     #047857 measures 4.47:1). tests/test_contrast.py scans every color: use.
     F-40, 2026-09-20. */
  --ok-text:#065f46;
  --warn:#b45309; --warn-bg:rgba(180,83,9,.08); --warn-brd:rgba(180,83,9,.24);
  --fail:#b91c1c; --fail-bg:rgba(185,28,28,.07); --fail-brd:rgba(185,28,28,.24);
  /* Approval-workflow hues (founder call, 2026-07-22): deliberately OFF the
     ok/warn/fail traffic lights — those mean extraction confidence, and an
     amber "awaiting" / red "rejected" pill read as confidence states. Violet
     = in flight, ink-navy = sealed, slate = declined. */
  --appr-wait:#6d28d9; --appr-wait-bg:rgba(109,40,217,.08); --appr-wait-brd:rgba(109,40,217,.26);
  --appr-done:#3b5a80; --appr-done-bg:rgba(59,90,128,.10); --appr-done-brd:rgba(59,90,128,.28);
  --appr-rej:#475569; --appr-rej-bg:rgba(71,85,105,.10); --appr-rej-brd:rgba(71,85,105,.30);
  --info:#15619e; --info-bg:rgba(21,97,158,.08); --info-brd:rgba(21,97,158,.24);

  /* Type */
  --ui:'DM Sans',ui-sans-serif,system-ui,sans-serif;
  --mono:'DM Mono',ui-monospace,monospace;
  --t-hero:clamp(52px,6.2vw,68px);
  --t-display:30px;
  --t-title:22px;

  /* Radius scale: 4 pill-small · 8 inputs · 12 cards · 20 sections */
  --r-xs:4px; --r:8px; --r-lg:12px; --r-xl:20px;

  /* Elevation — layered, navy-tinted */
  --sh-xs:0 1px 2px rgba(13,28,46,.05);
  --sh-sm:0 1px 2px rgba(13,28,46,.04),0 2px 6px rgba(13,28,46,.05);
  --sh:0 1px 2px rgba(13,28,46,.04),0 4px 14px rgba(13,28,46,.07);
  --sh-lg:0 2px 6px rgba(13,28,46,.05),0 14px 36px rgba(13,28,46,.12);
  --sh-xl:0 4px 10px rgba(13,28,46,.06),0 28px 72px rgba(13,28,46,.16);

  --sb-w:248px;
}

*{box-sizing:border-box;margin:0;padding:0}
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* Skip link: off-screen until keyboard-focused, then pinned top-left. */
.skip-link{position:absolute;left:8px;top:-48px;z-index:1000;background:var(--gh);color:#fff;font-size:13px;font-weight:600;padding:9px 16px;border-radius:var(--r);box-shadow:var(--sh-lg);transition:top 140ms ease;text-decoration:none}
.skip-link:focus{top:8px;outline:2px solid #fff;outline-offset:2px}
main:focus{outline:none}
html,body{height:100%;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
/* height pair: 100dvh (where supported) tracks mobile browser chrome as it
   collapses/expands — bare 100vh leaves the bottom of the shell hidden under
   the URL bar on phone Safari/Chrome. Older browsers keep the 100vh line. */
body{background:var(--bg);color:var(--t2);font-family:var(--ui);font-size:14px;display:flex;height:100vh;height:100dvh;overflow:hidden}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-thumb{background:var(--brd-md);border-radius:5px}
input,button,select,textarea{font-family:var(--ui)}
button{cursor:pointer}
button:focus-visible,a:focus-visible,summary:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:2px}

/* ── SIDEBAR — dark navy-slate surface ─────────── */
/* position:relative + z-index:30 gives the sidebar its own stacking context so
   the out-of-process PDF plugin layer (Extract preview iframe) can never paint
   a stale frame OVER it mid width-transition (goTool/goPage animate the width
   on every nav). Also resurrects the intended right-edge shadow, which was
   painting UNDER .main's opaque children. overflow-x:hidden kills the
   horizontal scrollbar sliver from the footer row at narrow widths. */
/* The NAV LIST scrolls (.sb-body below), not the whole rail — the footer is
   the account home since round 5 (identity + switcher + Sign out) and must
   stay pinned in view at short viewport heights now the topbar chip hides on
   desktop. min-height:0 on the body lets the flex item actually shrink. */
.sb{position:relative;z-index:30;width:var(--sb-w);background:var(--sb-bg);border-right:1px solid rgba(10,18,32,.9);display:flex;flex-direction:column;flex-shrink:0;overflow:hidden;box-shadow:2px 0 14px rgba(10,20,36,.10);transition:width 200ms ease}
/* Near-invisible dark scrollbar — RESCOPED from .sb when .sb-body became the
   scroller (round 6: the global light thumb read as a white bar on the navy
   rail). The standard scrollbar-color is FIREFOX-ONLY here by design: Chrome
   ≥121 honours it too but then IGNORES every ::-webkit-scrollbar-* rule on
   the element — including the global 5px width — giving a fat default-width
   bar on classic-scrollbar platforms (round-6 review). @supports not
   selector(::-webkit-scrollbar) is false in Chromium/WebKit, true in
   Firefox — exactly the split we need. */
.sb-body::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14)}
@supports not selector(::-webkit-scrollbar){
  .sb-body{scrollbar-color:rgba(255,255,255,.14) transparent;scrollbar-width:thin}
}
.sb.collapsed{width:52px;overflow:hidden}
.sb.collapsed .wordmark,.sb.collapsed .sb-section-lbl,.sb.collapsed .sb-sep,.sb.collapsed .nav-lbl,.sb.collapsed .tool-badge,.sb.collapsed .sb-foot{display:none}
.sb.collapsed .sb-logo{padding:20px 4px 16px;gap:0;justify-content:space-between}
.sb.collapsed .sb-body{padding:6px 4px}
.sb.collapsed .nav-item,.sb.collapsed .tool-item{justify-content:center;padding:9px 0}
.sb-toggle{margin-left:auto;background:none;border:none;color:var(--sb-text-dim);padding:3px 5px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:color 120ms,background 120ms}
.sb-toggle:hover{color:#f1f5f9;background:var(--sb-hover)}
.sb-toggle svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2;transition:transform 200ms ease}
.sb.collapsed .sb-toggle svg{transform:rotate(180deg)}
.sb-logo{padding:22px 18px 18px;border-bottom:1px solid var(--sb-brd);display:flex;align-items:center;gap:10px;flex-shrink:0}
.sb-logo-img{width:24px;height:24px;flex-shrink:0}
.wordmark{font-family:var(--ui);font-size:19px;font-weight:700;color:#fff;letter-spacing:-.04em}
.wordmark span{color:var(--sb-accent)}
.sb-body{flex:1;min-height:0;padding:12px 10px;overflow-y:auto;overflow-x:hidden}
.sb-section-lbl{font-size:10.5px;font-weight:600;color:var(--sb-text-dim);letter-spacing:.1em;text-transform:uppercase;padding:16px 10px 7px}
#appNav .sb-section-lbl{padding-top:4px}
.nav-item{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:var(--r);color:var(--sb-text);font-size:13.5px;font-weight:500;cursor:pointer;transition:background 120ms,color 120ms;user-select:none;border:none;background:none;width:100%;text-align:left}
a.nav-item{text-decoration:none;box-sizing:border-box} /* the Support Desk entry is a real-route anchor, not a data-page button */
.nav-lbl{white-space:nowrap} /* no multi-line reflow during the 200ms width transition */
.nav-item svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7;flex-shrink:0;opacity:.75}
.nav-item:hover{background:var(--sb-hover);color:#f1f5f9}
.nav-item.active{background:var(--sb-active);color:var(--sb-accent);font-weight:600}
.nav-item.active svg{opacity:1}
.sb-sep{margin:10px 10px;border:none;border-top:1px solid var(--sb-brd)}
/* The footer is a bare container; its divider + padding live on #footUser
   (2026-07-24) so an EMPTY footer (signed-out SPA, or the always-empty static
   shells now the footer Sign-in moved top-right) shows nothing — no bordered
   strip. #footUser carries the visual only when a signed-in account renders. */
.sb-foot{flex-shrink:0}
#footUser{padding:14px 14px 18px;border-top:1px solid var(--sb-brd)}
.btn-signin{width:100%;background:var(--gh);color:#fff;font-size:13.5px;font-weight:600;border:none;border-radius:var(--r);padding:11px;cursor:pointer;transition:background 120ms,box-shadow 120ms;letter-spacing:.01em;box-shadow:0 1px 2px rgba(0,0,0,.25),0 4px 14px rgba(5,150,105,.30)}
.btn-signin:hover{background:var(--gh2);box-shadow:0 1px 2px rgba(0,0,0,.25),0 6px 18px rgba(5,150,105,.38)}
/* (.user-badge / .user-name / .user-plan / .btn-signout retired in round 7 —
   the footer email/plan line is gone by founder call; the workspace chip's
   menu (.org-menu below) carries Sign out.) */
/* (.app-section-divider retired — the workspace group uses .sb-section-lbl like
   every other nav group; the hr.sb-sep above it marks the app boundary.) */
.tool-item{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:var(--r);color:var(--sb-text);font-size:13.5px;font-weight:500;cursor:pointer;transition:background 120ms,color 120ms;border:none;background:none;width:100%;text-align:left}
.tool-item svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7;flex-shrink:0;color:var(--sb-accent);opacity:.8}
.tool-item:hover{background:var(--sb-hover);color:#f1f5f9}
.tool-item.active{background:var(--sb-active);color:var(--sb-accent);font-weight:600}
.tool-item.active svg{opacity:1}
.tool-badge{margin-left:auto;font-size:9.5px;font-weight:600;background:rgba(255,255,255,.10);color:#fff;border:1px solid rgba(255,255,255,.22);padding:2px 7px;border-radius:999px}
/* Tier lock badge (PR-4): a muted/neutral variant of the count pill — the
   dark-sidebar dim-text tokens, NOT the accent treatment (a lock is quiet
   information, not a notification). Keeps .tool-badge, so the
   ".sb.collapsed .tool-badge{display:none}" rule above still hides it. */
.tool-badge-lock{background:transparent;color:var(--sb-text-dim);border-color:var(--sb-brd);font-weight:500}
/* ≤760px: the sidebar drops to its 52px icon rail (mirrors the .sb.collapsed
   state above) — a fixed 248px column left ~127px of content at 375px, which
   no marketing-grid collapse can rescue. Icon nav stays fully usable; the
   expand toggle hides (the media rules would override it, leaving a dead
   control). The in-app screens are separately covered by the <1024px banner.
   PUBLIC-face shells (body.mktd / body.nd-mkt) override this rail into an
   off-canvas drawer — see the MOBILE NAV block at the END of the file, which
   wins by specificity + source order; this block stays the TOOL-screen
   contract and must not grow public-page rules. */
@media (max-width:760px){
  .sb{width:52px;overflow:hidden}
  .sb .wordmark,.sb .sb-section-lbl,.sb .sb-sep,.sb .nav-lbl,.sb .tool-badge,.sb .sb-foot,.sb .sb-toggle{display:none}
  .sb .sb-logo{padding:20px 4px 16px;gap:0;justify-content:center}
  .sb .sb-body{padding:6px 4px}
  .sb .nav-item,.sb .tool-item{justify-content:center;padding:9px 0}
}

/* ── MAIN ──────────────────────────────────────── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden}

/* ── TOP BAR ───────────────────────────────────── */
.topbar{height:56px;background:var(--white);border-bottom:1px solid var(--brd);display:flex;align-items:center;padding:0 28px;gap:14px;flex-shrink:0;box-shadow:var(--sh-xs)}
/* The topbar label is THE screen title now — the in-screen .app-header rows
   were removed in the title-dedup pass, so this is each screen's only name
   and reads at title weight rather than as a breadcrumb echo. */
.tb-title{font-size:14px;font-weight:600;color:var(--t1);letter-spacing:-.01em}
.tb-sub{font-size:12.5px;color:var(--t4)}
.tb-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.tb-signin{color:var(--t1);padding:8px 18px}
/* ≤760px-only Sign out (round 6): the icon rail hides the sidebar footer —
   the ONE account home — and its expand toggle, so the phone shell needs its
   own way out. Desktop never sees it: the !important must beat the inline
   display:'' the shared _show() helper sets when signed in. */
@media (min-width: 761px){.tb-signout-sm{display:none !important}}
.tb-signout-sm{color:var(--t1);padding:8px 14px}
/* Static shells (2026-07-24): the ≤760px icon rail hides .sb-foot — the
   footer chip — and the injected top-right menu is gone, so signed-in MOBILE
   static pages carry the same quiet topbar Sign out the SPA does. Pre-paint
   attribute-gated (the static pages have no JS _show); the show rule (0,3,1)
   must out-specify the hide (0,2,0), and the ≥761px !important hide above
   still wins on any desktop. */
body.mktd .tb-signout-sm{display:none}
html[data-nd-authed] body.mktd .tb-signout-sm{display:inline-flex}
/* (The top-right account-menu block — acct-menu / acct-btn / acct-dropdown /
   acct-dd-* — was REMOVED 2026-07-24 with mktshell's injected menu: the
   static shells now hydrate the SAME sidebar-footer chip (#footUser/#orgPill/
   org-menu, below) the SPA renders, so no acct-menu chrome remains anywhere.
   The Plan & billing body styles further down (acct-plan-* / acct-usage /
   acct-note / acct-actions) are a DIFFERENT, live family — billing.js. */
.tb-icon{width:36px;height:36px;border:1px solid var(--brd);border-radius:var(--r);background:var(--white);color:var(--t3);display:flex;align-items:center;justify-content:center;transition:all 120ms;box-shadow:var(--sh-xs)}
.tb-icon:hover{background:var(--bg);color:var(--t1);border-color:var(--brd-md)}
.tb-icon.active{background:var(--glo);border-color:var(--gbrd);color:var(--gh)}
.tb-icon svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.8}
.tb-badge{font-size:11.5px;font-weight:600;color:var(--gh);background:var(--glo);border:1px solid var(--gbrd);padding:4px 12px;border-radius:999px}

/* ── MOBILE BANNER (dismissible) ───────────────── */
.mobile-banner{display:none;background:var(--warn-bg);border-bottom:1px solid var(--warn-brd);padding:9px 16px;font-size:12.5px;color:var(--warn);align-items:center;gap:10px;flex-shrink:0}
.mobile-banner .mb-close{margin-left:auto;background:none;border:none;color:var(--warn);font-size:17px;cursor:pointer;line-height:1}
@media (max-width: 1023px){
  .mobile-banner.show{display:flex}
}

/* ── CONTENT AREA ──────────────────────────────── */
.content{flex:1;overflow:hidden;display:flex}

/* ── MARKETING PAGES ───────────────────────────── */
/* Round 4 (founder): LEFT-anchored, full-width — no centered measure, no
   narrow reading columns. Every page's content starts at the same left edge
   and runs across the whole screen; the round-3 centering is reverted. */
.mkt-page{display:none;flex:1;overflow-y:auto;padding:64px 72px 96px;container-type:inline-size}
.mkt-page.active{display:block}
/* 2026-09-10 (founder call, site-wide width pass): every STATIC page's content
   sits in the same centred measure the marketing header uses (1120 on
   2026-09-10 AM, 1280 since the founder's first look on a 1917px monitor
   the same afternoon: 400px gutters read as waste), so its h1 lands under
   the wordmark (x=80 at 1440) instead of 88px left of it.
   The round-4 "left-anchored, full width" layout above was drawn for a
   viewport that always had the 248px rail on its left; with the rail parked
   off-canvas for signed-out visitors, a 1,296px lead was unreadable and the
   narrow tools left the right half of the screen empty. Done as PADDING, not
   a wrapper: the page's side gutter grows to centre a 1280px interior and
   never drops below the 72px it always had. 100% resolves against .main
   (viewport minus the rail), so a signed-in shell is unchanged up to a
   1264px viewport with the rail open (1316 collapsed) and centres the same
   1280 on wider monitors, where a full-bleed lead beside the rail was the
   same problem. No element's own margins are touched, and
   the ≤760px block below still wins its 20px gutter on source order. Home has
   its own .mkt-measure wrapper (same 1280). Container queries on .mkt-page
   read the interior, so a two-column page collapses on the width it really
   has, rail open or not. */
.mkt-static{padding-inline:max(72px,calc((100% - 1280px) / 2))}
.mkt-prose{max-width:none}
.mkt-static .lead{max-width:680px} /* was none (round 4: full-width leads beside the rail); 680px is about 75 characters at 17px */
.mkt-static .mkt-prose h1{max-width:880px;text-wrap:balance}
/* Slim end-of-scroll footer (audit A7) — included at the end of every
   marketing partial; tool screens have none. */
.site-footer{margin-top:96px;padding-top:48px;border-top:1px solid var(--brd);color:var(--t3);font-size:13.5px}
.sf-top{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,3fr);gap:40px 48px}
.sf-wordmark{font-size:18px;font-weight:700;letter-spacing:-.04em;color:var(--t1);text-decoration:none}
.sf-wordmark span{color:var(--gh)}
.sf-about p{margin:10px 0 0;max-width:260px;line-height:1.55;color:var(--t3)}
.sf-links{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:28px 24px}
.sf-col{display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.sf-h{margin:0 0 2px;font-size:13px;font-weight:600;color:var(--t1)}
.sf-link{background:none;border:0;padding:0;color:var(--t3);font-size:13.5px;font-weight:400;cursor:pointer;transition:color 120ms}
.sf-link:hover{color:var(--gh)}
a.sf-link{text-decoration:none} /* the footer entries are real-route anchors, never data-page buttons */
.sf-link:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:3px;border-radius:3px}
.sf-bottom{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 24px;margin-top:44px;padding:20px 0 8px;border-top:1px solid var(--brd);font-size:12.5px}
/* Companies Act trading disclosures (reg 24-25, SI 2015/17): quiet small
   print on --t3 (AA). The regulations require the particulars to be
   disclosed, not to be prominent. */
.sf-legal{margin:0;color:var(--t3);font-size:12px;line-height:1.5}
@container (max-width:900px){.sf-top{grid-template-columns:minmax(0,1fr)}.sf-links{grid-template-columns:repeat(2,minmax(0,1fr))}}
h1{font-size:clamp(36px,4.2vw,52px);font-weight:700;color:var(--t1);line-height:1.06;letter-spacing:-.045em;margin-bottom:20px}
h1 em{color:var(--gh);font-style:normal}
h2{font-size:var(--t-display);font-weight:700;color:var(--t1);letter-spacing:-.03em;line-height:1.15;margin-bottom:12px;text-wrap:balance}
/* Section h2s step down one notch so the page h1 + lead outrank section heads
   (the flat 30px-everywhere scale read as five page titles per scroll). */
/* Secondary marketing pages (product/blog/about/etc.) carry a semantic <h1>
   page title for a11y/SEO, but at the display (h2) scale — only the home hero
   gets the oversized treatment (.home-hero h1 below). */
.mkt-prose:not(.home-hero) h1{font-size:var(--t-display);line-height:1.15;letter-spacing:-.03em;margin-bottom:12px}
h3{font-size:16px;font-weight:600;color:var(--t1);margin-bottom:7px}
.lead{font-size:17px;color:var(--t2);line-height:1.75;max-width:560px;margin-bottom:36px;font-weight:300;text-wrap:pretty}
.nowrap{white-space:nowrap}
.btn-row{display:flex;gap:12px;align-items:center;margin-bottom:44px;flex-wrap:wrap}
.btn-primary{background:var(--gh);color:#fff;font-size:14px;font-weight:600;border:none;border-radius:10px;padding:13px 28px;cursor:pointer;transition:background 120ms,box-shadow 120ms;box-shadow:0 1px 2px rgba(5,150,105,.35),0 4px 16px rgba(5,150,105,.25);letter-spacing:.005em}
.btn-primary:hover{background:var(--gh2);box-shadow:0 1px 2px rgba(5,150,105,.4),0 6px 22px rgba(5,150,105,.32)}
.btn-secondary{background:var(--white);color:var(--t2);font-size:14px;font-weight:500;border:1px solid var(--brd-md);border-radius:10px;padding:13px 24px;cursor:pointer;transition:all 120ms;box-shadow:var(--sh-xs)}
.btn-secondary:hover{border-color:var(--g);color:var(--gh)}
/* Trust strip on the navy brand surface (2a hero) — replaced the hairline
   .trust strip 2026-08-05. Sits after the hero CTAs, before "What it checks". */

/* Home canvas: the plain --bg canvas (Direction B, 2026-09-09). The Daylight
   Stage radial wash (2026-08-25: emerald/steel radials + a mint glow behind
   the demo, resolving into --bg by 680px) is RETIRED with the lockup it was
   drawn for — founder call on the running build: it read as off-brand
   against the white hero band and the flat canvas the rest of the site uses. */
/* 2a hero (2026-08-05): the headline goes FULL measure and reads itself.
   Base styles below are the finished state (green em, drawn underline, dot
   shown, no highlight) so reduced-motion and post-play render identically —
   the one-shot animations attach only under no-preference. Font tracks the
   content width (100vw − sidebar 248 − page padding 144) so the single line
   fits the frame like the design's 67px/1312px ratio. */
/* Daylight Stage (2026-08-25): the lockup CENTERS — deliberately breaking the
   left-set prose convention on this one page — and compresses so the demo
   clears an 800px-tall viewport (a design target, not a pinned guarantee —
   real laptop screens lose height to browser chrome). The wordmark stays
   DOMINANT over the headline (founder call): both clamps shrank from the 2a
   sizes, the h1 more. */
/* ── HOME HERO — Direction B "Show the engine" (2026-09-09) ─────────────
   Supersedes the Daylight Stage lockup (2026-08-25: centred wordmark over a
   one-line headline, CTAs below the demo). The promise is the hero: a
   two-column grid, copy left (400px) and the UNCHANGED demo card right, both
   inside the centred 1280px .mkt-measure. The decorative .hh-wordmark is gone
   (the marketing header carries the brand); the h1 em still settles green
   under no-preference (hhGreen), the underline/dot beats retired with the
   spans that carried them. Class names .home-hero / .home-demo are pinned by
   the reduced-motion blanket rule at the end of the file — keep them.
   #page-home's top padding stays scoped >760px on purpose (an ID selector
   outranks .mkt-page unconditionally; below 760px Home follows its siblings). */
@media (min-width:761px){#page-home{padding-top:16px}}
.mkt-measure{max-width:1280px;margin:0 auto}
.home-hero{display:grid;grid-template-columns:380px minmax(0,1fr);gap:40px;align-items:start;padding:24px 0 8px}
.home-hero-copy{padding-top:40px}
.home-hero-copy{display:flex;flex-direction:column;gap:18px}
.home-hero h1{font-size:clamp(36px,3.6vw,52px);line-height:1.04;letter-spacing:-.045em;margin:0;text-wrap:balance}
.home-hero h1 em{color:var(--gh);font-style:normal}
@media (prefers-reduced-motion: no-preference){.home-hero h1 em{animation:hhGreen .35s ease .25s both}}
@keyframes hhGreen{from{color:var(--t1)}to{color:var(--gh)}}
.home-hero-lead{font-size:16px;font-weight:300;line-height:1.7;color:var(--t2);margin:0;max-width:560px;text-wrap:pretty}
.home-cta-row{margin:4px 0 0}
@media (max-width: 760px){.home-cta-row{flex-direction:column;align-items:stretch}.home-cta-row .btn-primary,.home-cta-row .btn-secondary{width:100%}} /* phone: the hero CTAs stack full-width (restored 2026-09-23: this rode the v3 demo's ≤760px block and was deleted with it) */
.home-trust-row{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;font-size:12.5px;color:var(--t3)}
.home-trust-row li{display:flex;align-items:center;gap:8px}
.home-trust-row li::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--g);flex-shrink:0}
.home-hero-demo{min-width:0}
/* The demo card in the hero's right-hand column. Home demo v4 sizes its
   own world from the card's width (the HOME DEMO v4 block). */
.home-hero .home-demo{margin-bottom:0}
.home-hero .home-demo-label{justify-content:flex-start;margin:0 0 10px}
/* Keyed on the CONTENT width, not the viewport (2026-09-10): a signed-in
   visitor with the 248px rail open saw a two-column hero squeezed to ~600px
   and a cropped demo. .mkt-page is the container (inline-size only). */
@container (max-width:1080px){.home-hero{grid-template-columns:1fr;gap:28px}.home-hero-copy{max-width:640px;padding-top:0}}
@media (max-width:760px){.home-hero{padding-top:8px}.home-hero h1{font-size:clamp(32px,8.6vw,40px)}}
.home-demo-cite{text-align:center;font-size:12.5px;color:var(--t3);margin:14px 0 0}
.home-demo-cite strong{color:var(--t1);font-weight:600}

/* The home demo card (v4, the working paper): the kicker above it, the
   card surface and the Replay control. The paper itself is the HOME DEMO
   v4 block further down. */
.home-demo-label{display:flex;align-items:center;justify-content:center;gap:9px;font-size:13px;font-weight:500;color:var(--t3);margin:16px 0 10px}
.hdl-dot{width:7px;height:7px;border-radius:50%;background:var(--g);box-shadow:0 0 0 4px var(--glo);flex-shrink:0}
.home-demo{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xl);overflow:hidden;box-shadow:var(--sh-xl);margin-bottom:22px}
.home-demo-replay{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--t3);background:none;border:1px solid var(--brd);border-radius:var(--r);padding:4px 12px;cursor:pointer;transition:color 100ms,border-color 100ms}
.home-demo-replay:hover{color:var(--gh);border-color:var(--gbrd)}
/* ── Pricing (SITE CALM 2026-09-24) ─────────────────────────────────────
   Four plan cards across, each its own card (the joined hairline 2x2 read as
   one spreadsheet), the plan's button above its list, and the seat and
   top-up lines as quiet extras at the foot of the list. .pr-* is the pricing
   page's namespace. The round-3 "price pop" hover further down stays
   (founder call: do not re-calm). */
.pricing-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-top:24px}
@container (max-width:1120px){.pricing-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container (max-width:620px){.pricing-grid{grid-template-columns:minmax(0,1fr)}}
.price-card{background:var(--white);border:1px solid var(--brd);border-radius:14px;padding:26px 24px 24px;display:flex;flex-direction:column}
.price-card.featured{border-color:var(--g);box-shadow:0 0 0 1px var(--g),0 18px 40px -20px rgba(5,150,105,.35)}
.price-tier{font-size:16px;font-weight:600;color:var(--t1);margin-bottom:4px}
.price-name{font-size:13.5px;font-weight:400;color:var(--t3);margin-bottom:22px;min-height:40px;line-height:1.45;text-wrap:balance}
.price-amt{font-family:var(--mono);font-size:40px;font-weight:500;color:var(--t1);letter-spacing:-.04em;line-height:1}
.price-period{font-size:13px;color:var(--t4);margin-top:6px}
/* "+ VAT" must be unmissable (LAUNCH_PLAN drip-pricing item): darker and
   bold against the muted period line. */
.price-period .price-vat{color:var(--t2);font-weight:600}
.price-incvat{font-size:12px;color:var(--t3);margin:4px 0 20px}
.pr-cta{display:block;width:100%;text-align:center;text-decoration:none;margin:0 0 22px}
.pr-cta:disabled{background:var(--brd-md);color:var(--t3);box-shadow:none;cursor:default}
.price-card:not(.featured) .pr-cta{background:var(--white);color:var(--t1);border:1px solid var(--brd-md);box-shadow:none}
.price-card:not(.featured) .pr-cta:hover{border-color:var(--g);color:var(--gh);background:var(--white)}
.price-feats{list-style:none;display:flex;flex-direction:column;gap:10px;margin:0;padding:18px 0 0;border-top:1px solid var(--brd)}
.price-feats li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;color:var(--t2)}
.price-feats li::before{content:'';width:14px;height:14px;flex-shrink:0;margin-top:1px;background-color:var(--g);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.4 8.7 6.2 12.2 13.6 3.4' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%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 16 16'%3E%3Cpath d='M2.4 8.7 6.2 12.2 13.6 3.4' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
.price-feats li.pr-x{font-size:12.5px;color:var(--t3)}
.price-feats li.pr-x::before{background-color:transparent}
.price-feats li.pr-x:first-of-type,.price-feats li:not(.pr-x) + li.pr-x{margin-top:6px}
.pr-amt-from{font-family:var(--ui);font-size:15px;font-weight:500;color:var(--t3);letter-spacing:0;margin-right:2px}
.pr-lead{margin:10px 0 36px}
.pr-estimator{display:grid;grid-template-columns:minmax(0,1fr);gap:0;background:var(--white);border:1px solid var(--brd);border-radius:14px;padding:20px 24px}
.pr-est-label{display:block;font-size:14px;font-weight:600;color:var(--t1);margin-bottom:12px}
.pr-est-row{display:flex;align-items:center;gap:18px}
.pr-est-out{font-family:var(--mono);font-size:14px;color:var(--t1);white-space:nowrap;min-width:150px;text-align:right}
.pr-slider{flex:1;-webkit-appearance:none;appearance:none;height:6px;border-radius:999px;background:var(--brd-md);cursor:pointer}
.pr-slider:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:4px}
.pr-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:var(--g);border:2px solid var(--white);box-shadow:var(--sh-sm)}
.pr-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--g);border:2px solid var(--white);box-shadow:var(--sh-sm)}
.pr-slider::-moz-range-track{height:6px;border-radius:999px;background:var(--brd-md)}
.pr-slider::-moz-range-progress{height:6px;border-radius:999px;background:var(--g)}
/* The recommendation lives in the estimator row, beside its cause (the
   slider); the recommended card carries only the .featured outline. */
.pr-est-reco{font-size:13px;font-weight:600;color:var(--gh);white-space:nowrap}
.pr-est-cost{margin:14px 0 0;padding-top:14px;border-top:1px solid var(--brd);font-size:13px;color:var(--t3);line-height:1.6}
.pr-est-cost strong{color:var(--t1);font-variant-numeric:tabular-nums}
/* The VAT-status caveat and the credit rule: one quiet line under the grid,
   beside the figures it qualifies. */
.pr-vatnote{margin:18px 0 0;font-size:12.5px;color:var(--t3);line-height:1.6;max-width:880px}
/* The accountancy-practice enquiry: a route to the highest-value segment,
   not a caveat, so it reads as a line of the page. */
.pr-practice{margin-top:14px;font-size:14px;color:var(--t2);line-height:1.6}
.pr-practice a{color:var(--gh);font-weight:600}
.pr-included ul{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 36px}
.pr-included li{display:flex;align-items:flex-start;gap:10px;font-size:14px;line-height:1.5;color:var(--t2)}
.pr-included li::before{content:'';width:15px;height:15px;flex-shrink:0;margin-top:2px;background-color:var(--g);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.4 8.7 6.2 12.2 13.6 3.4' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%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 16 16'%3E%3Cpath d='M2.4 8.7 6.2 12.2 13.6 3.4' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
@container (max-width:980px){.pr-included ul{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container (max-width:600px){.pr-included ul{grid-template-columns:minmax(0,1fr)}}
.pr-penalty,.pr-faq-sec{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:24px 72px;align-items:start}
.pr-penalty > .mk-head,.pr-faq-sec > .mk-head{margin:0}
@container (max-width:900px){.pr-penalty,.pr-faq-sec{grid-template-columns:minmax(0,1fr)}}
.pr-penalty-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.pr-penalty-list li{font-size:15px;line-height:1.6;color:var(--t2);padding:16px 0;border-top:1px solid var(--brd)}
.pr-penalty-list li:first-child{border-top:0;padding-top:0}
.pr-foot{grid-column:2;margin:4px 0 0;font-size:12.5px;line-height:1.6;color:var(--t3)}
.pr-foot a{color:var(--gh)}
@container (max-width:900px){.pr-foot{grid-column:1}}
.pr-faq{border-top:1px solid var(--brd)}
.pr-faq details{border-bottom:1px solid var(--brd)}
.pr-faq summary{font-size:15px;font-weight:600;color:var(--t1);padding:18px 0;cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;gap:12px}
.pr-faq summary::-webkit-details-marker{display:none}
.pr-faq summary::after{content:'+';font-family:var(--mono);font-size:16px;color:var(--t3);flex-shrink:0}
.pr-faq details[open] summary::after{content:'\2212'}
.pr-faq details p{font-size:14.5px;color:var(--t2);line-height:1.65;margin:0;padding:0 40px 20px 0}
.pr-faq details p a{color:var(--gh)}
@media (max-width: 900px){
  .pr-est-row{flex-direction:column;align-items:stretch}
  .pr-est-out{text-align:left;min-width:0}
  .pr-est-reco{white-space:normal}
}
}
.post{padding:24px 0;border-bottom:1px solid var(--brd)}
.post:last-child{border-bottom:none}
.form-row{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:64px;align-items:start}
.fg{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.flbl{font-size:11.5px;font-weight:600;color:var(--t3);letter-spacing:.04em;text-transform:uppercase}
.finput,.ftextarea,.fselect{width:100%;background:var(--white);border:1px solid var(--brd-md);border-radius:var(--r);color:var(--t1);font-size:14px;padding:11px 14px;outline:none;transition:all 120ms;box-shadow:var(--sh-xs)}
.finput:focus,.ftextarea:focus,.fselect:focus{background:var(--white);border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.finput::placeholder,.ftextarea::placeholder{color:var(--t5)}
.ftextarea{height:120px;resize:vertical;line-height:1.6}
.mk-split.about-split{grid-template-columns:minmax(0,7fr) minmax(0,5fr);align-items:start;padding-top:8px}
@container (max-width:960px){.mk-split.about-split{grid-template-columns:minmax(0,1fr)}}
.about-principles{padding:26px 28px}
.about-principles h2{font-size:18px;margin:0 0 4px}
.about-principles dl{margin:0}
.about-principles dl > div{padding:14px 0;border-bottom:1px solid rgba(98,116,140,.16)}
.about-principles dl > div:last-child{border-bottom:0;padding-bottom:0}
.about-principles dt{font-size:14.5px;font-weight:600;color:var(--t1);margin-bottom:4px}
.about-principles dd{margin:0;font-size:14px;line-height:1.6;color:var(--t3)}
/* Contact's form/info rail shares About's column ratio + full-page edge
   (its .form-row is a page-level sibling, not inside the
   880px .mkt-prose). Demo's .form-row keeps the default 1fr 1fr inside prose. */
#page-contact .form-row{grid-template-columns:1.3fr 1fr;gap:44px}
/* Marketing pages: single-column collapse on small screens (the app workspace
   keeps its <1024px banner instead — dense ledger UIs don't translate, but the
   marketing/legal pages must). Mirrors pay.html's / support.css's approach. */
@media (max-width:760px){
  .mkt-page{padding:40px 20px 64px}
  .pricing-grid,.form-row{grid-template-columns:1fr}
  #page-contact .form-row{grid-template-columns:1fr;gap:36px} /* the id rule above outranks the bare .form-row collapse */
  .price-name{min-height:0} /* single column — no two-line-name baseline to reserve */
  .legal-s a{overflow-wrap:anywhere} /* long gov.uk/ICO URLs + emails on the legal pages */
}
.stat-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px}
.stat-cell{padding-top:18px;border-top:1px solid var(--t1)}
.stat-val{font-family:var(--mono);font-size:44px;font-weight:500;color:var(--t1);line-height:1;letter-spacing:-.03em}
.stat-lbl{font-size:14px;line-height:1.5;color:var(--t3);margin-top:10px;max-width:280px}
.legal-s{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);column-gap:72px;padding:28px 0;margin:0;border-top:1px solid var(--brd)}
.legal-s > :not(h3){grid-column:2}
@container (max-width:860px){.legal-s{grid-template-columns:minmax(0,1fr)}.legal-s > :not(h3){grid-column:1}}
.legal-s h3{grid-column:1;font-size:16px;font-weight:600;color:var(--t1);margin:0 0 10px;line-height:1.4}
.legal-s p,.legal-s li{font-size:15px;color:var(--t2);line-height:1.7;margin-bottom:10px}
.legal-s ul{padding-left:20px;margin-bottom:10px}
.legal-s a{color:var(--gh);font-weight:500;text-decoration:none}
.legal-s a:hover{text-decoration:underline}
/* A reading page gets a reading measure — 880px prose ran the 13.5px body to
   ~130 characters a line. */
/* (round 4: the privacy 680px reading cap is retired — founder call: text runs the full screen, left-anchored) */
/* Terms is the page's second DOCUMENT — a part-level break, not a peer h3. */
.legal-part{margin-top:44px;padding-top:28px;border-top:1px solid var(--brd)}
.legal-part h2{font-size:18px;font-weight:600;letter-spacing:-.01em;margin-bottom:12px;text-wrap:balance}
.info-box{background:var(--white);border:1px solid var(--brd);border-radius:14px;padding:26px 28px}
.ib-h{font-size:18px;margin:0 0 6px}

/* ── APP SCREENS ───────────────────────────────── */
.app-screen{display:none;flex:1;flex-direction:column;overflow:hidden}
.app-screen.active{display:flex}
/* Content-flow screens (History / VAT Check / Admin / Plan & billing / Access
   requests / Leads / Team / Security — everything on the .history-screen
   wrapper) own the scroll at the SCREEN level, not in a fixed-height inner box.
   The old `.history-screen{flex:1;overflow-y:auto}` made a trapped scroll
   region: a wheel event over the topbar or any gutter was swallowed (everything
   above is overflow:hidden) with no page-scroll fallback, so a tall list or a
   full detail+timeline read as "stuck halfway". Scrolling the whole screen
   makes the wheel work anywhere over it. Extract/Manual keep their
   overflow:hidden two-panel layouts, and Batch keeps its own .batch-screen
   scroll (its drag-drop overlay pins to #tool-batch and its empty-state
   dropzone needs the flex:1 box) — neither uses .history-screen.
   EVERY .history-screen tool screen MUST be listed here: a new one that isn't
   inherits .app-screen{overflow:hidden} and its content is CLIPPED with no
   scrollbar (the MFA-enrol Confirm button fell below the fold, unreachable —
   founder UAT 2026-07-21; Team had the same latent omission). Pinned by
   tests/test_tool_screen_scroll.py. */
#tool-history.app-screen,#tool-vatcheck.app-screen,#tool-admin.app-screen,
#tool-account.app-screen,#tool-access.app-screen,#tool-leads.app-screen,
#tool-team.app-screen,#tool-security.app-screen,#tool-email.app-screen{overflow-y:auto}
/* (.app-header/.app-title retired — every tool screen's title + actions live in
   the shared topbar now; see topbar.html + app.js _syncAuditChrome.) */
.batch-back{background:var(--glo);color:var(--gh);border:1px solid var(--gbrd);font-size:12px;font-weight:600;padding:7px 14px;border-radius:var(--r);display:inline-flex;align-items:center;gap:6px;transition:all 120ms}
.batch-back:hover{background:var(--gh);color:#fff}
.batch-back svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2}
/* (.status-pill retired 2026-09-04 — the indicator is the .status-strip band, §2 below.) */

/* Extract screen layout — v5 "the whole screen is the intake" (2026-09-10).
   .extract-layout is a ROW: the working column (intake or stage) + the
   companion drawer as an inline sibling (>1400px) or an overlay (≤1400px —
   see the audit-sidebar block). Inside the column: a notices strip, the
   full-stage dropzone (#xrIdle) OR the three-panel stage (#xrStage). */
.extract-layout{flex:1;display:flex;overflow:hidden;min-height:0}
.xr-column{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden;background:var(--bg)}
.xr-notices{flex-shrink:0}
.xr-notices #limitBanner:not(:empty){padding:14px 20px 0}
/* Idle intake: 20px gutter, dashed hairline, 20px radius, emerald wash on hover/drag. */
.xr-idle{flex:1;min-height:0;display:flex;flex-direction:column;padding:20px 20px 18px;gap:14px}
.xr-drop{flex:1;min-height:0;margin:0;border:1.5px dashed var(--brd-md);border-radius:var(--r-xl);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:28px;cursor:pointer;transition:border-color 150ms,background-color 150ms;text-align:center;overflow:hidden;position:relative;background:transparent}
.xr-drop:hover,.xr-drop.ready{border-color:var(--g);background:rgba(5,150,105,.04)}
.xr-drop:focus-visible{outline:none;border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.xr-drop .dz-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:6px}
.xr-drop .dz-icon{width:64px;height:64px;background:var(--glo);border:1px solid var(--gbrd);border-radius:16px;display:flex;align-items:center;justify-content:center;margin-bottom:18px;box-shadow:0 2px 10px rgba(5,150,105,.14)}
.xr-drop .dz-icon svg{width:28px;height:28px;stroke:var(--g);fill:none;stroke-width:2}
.xr-drop .dz-t{font-size:17px;font-weight:600;color:var(--t1);margin-bottom:5px;overflow-wrap:anywhere;letter-spacing:-.02em}
.xr-drop .dz-sub{font-size:13px;color:var(--t3);line-height:1.55;margin-bottom:22px;max-width:56ch}
.xr-chips{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:center}
.xr-chip{font-size:11px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd);border-radius:6px;padding:4px 11px}
.dz-list{width:100%;text-align:left;padding:6px;max-height:260px;overflow-y:auto}
.dz-list-item{font-size:12px;color:var(--t3);padding:2px 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dz-list-more{font-size:12px;color:var(--t4);padding:2px 0}
.dz-list-count{font-size:12.5px;font-weight:600;color:var(--gh);margin-top:8px}
.xr-idle-foot{display:flex;justify-content:center;flex-shrink:0}
.btn-change{font-size:12px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd-md);border-radius:var(--r);padding:8px 16px;white-space:nowrap;display:inline-flex;align-items:center;gap:6px;transition:all 120ms;cursor:pointer}
.btn-change:hover{border-color:var(--g);color:var(--gh)}
.btn-change svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2}
/* Record / Document segmented tabs at EVERY width (founder, 2026-09-11: the
   prototype tabs the two panes; the record gets the whole stage). extract.js
   _setStageTab flips #xrStage[data-stage-tab]; the CSS below shows one pane. */
.xr-tabs{display:flex;gap:4px;background:var(--bg);border-bottom:1px solid var(--brd);padding:8px 20px;flex-shrink:0}
.xr-tab{flex:1;font-size:11.5px;font-weight:600;border-radius:6px;padding:6px 0;cursor:pointer;transition:all 120ms;color:var(--t3);background:transparent;border:1px solid transparent}
.xr-tab.is-on{color:var(--gh);background:var(--white);border-color:var(--gbrd);box-shadow:0 1px 2px rgba(13,28,46,.05)}
/* The stage: document · record · drawer. */
.xr-stage{flex:1;display:flex;overflow:hidden;min-height:0;position:relative}
.xr-doc{flex:1;min-width:0;min-height:0;overflow-y:auto;padding:20px;background:var(--bg);position:relative}
.xr-stage[data-stage-tab="record"] .xr-doc{display:none}
.xr-stage[data-stage-tab="document"] .xr-record{display:none}
.xr-doc-host{position:relative;max-width:1000px;min-height:100%;margin:0 auto;display:flex;flex-direction:column}
/* Rendered pages (pdf.js → canvas): one sheet per page, the host itself is
   unpainted so the sheets sit on the canvas-coloured pane. */
.xr-doc-pages{display:flex;flex-direction:column;gap:14px;width:100%}
.xr-doc-page{display:block;width:100%;background:var(--white);border-radius:var(--r-xs);box-shadow:var(--sh)}
.xr-doc-more{font-size:12px;color:var(--t4);text-align:center;padding:6px 0 2px}
/* The iframe fallback and the image preview keep the white sheet. */
.xr-doc-host iframe,.xr-doc-host img.dz-preview-img,.xr-doc-host .dz-preview-note{background:var(--white);border-radius:var(--r-xs);box-shadow:var(--sh)}
.xr-doc-host iframe{width:100%;min-height:620px;border:none;border-radius:0;flex:1}
.xr-doc-host img.dz-preview-img{width:100%;height:100%;object-fit:contain;background:var(--white)}
.xr-doc-host .dz-preview-note{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;padding:28px;background:var(--white);text-align:center}
.xr-doc-host .dz-preview-note .dz-sub{max-width:38ch}
.dz-drop-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;background:rgba(236,250,244,.95);border:2px dashed var(--g);border-radius:inherit;z-index:20;font-size:14px;font-weight:600;color:var(--gh);opacity:0;visibility:hidden;pointer-events:none;transition:opacity 100ms}
.dz-drop-overlay svg{width:30px;height:30px;stroke:currentColor;fill:none;stroke-width:2}
.xr-stage.has-files.drag-active .dz-drop-overlay{opacity:1;visibility:visible;pointer-events:auto}
.xr-record{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;background:var(--white);overflow:hidden}
.xr-status{flex-shrink:0}
.xr-read-meta{display:none;gap:10px;padding:0 30px 8px;font-family:var(--mono);font-size:10.5px;color:var(--t4);background:var(--info-bg);border-bottom:1px solid var(--info-brd)}
.xr-read-meta .ls-meta + .ls-meta::before{content:'·';margin-right:10px;color:var(--brd-str)}
.xr-status:has(.sp-proc) .xr-read-meta{display:flex}
.xr-status:has(.sp-proc) .status-strip{border-bottom:none}
/* min-width:0 — without it the min-content width forces the layout past the
   viewport at laptop width + expanded sidebar. */
.output-scroll{flex:1;min-width:0;overflow-y:auto;padding:18px 24px 30px;transition:background 60ms}
.output-scroll.flash-success{background:rgba(5,150,105,.08)}
.output-scroll.flash-warn{background:rgba(180,83,9,.08)}
/* Record rows: caption · rows (label 94px + dot · mono editable value · verdict). */
.xr-group{margin-bottom:16px}
.xr-group-lbl{font-size:10px;font-weight:600;color:var(--t4);letter-spacing:.08em;text-transform:uppercase;margin:0 0 3px;display:flex;align-items:center;gap:8px}
.xr-group-lbl::after{content:'';flex:1;height:1px;background:#eef2f7}
.xr-rows{display:flex;flex-direction:column}
.xr-row{display:flex;align-items:center;gap:10px;padding:7px 10px;margin:0 -10px;border-radius:var(--r);transition:background 100ms;animation:xrIn 240ms ease both}
.xr-row:hover{background:#f7fafd}
.xr-row:focus-within{background:#f7fafd}
.xr-lbl{width:108px;flex-shrink:0;font-size:10px;font-weight:600;color:var(--t4);letter-spacing:.06em;text-transform:uppercase;display:flex;align-items:center;gap:5px;line-height:1.25}
.xr-row .field-val{flex:1;min-width:0;width:auto;font-size:12.5px}
.xr-verdict{flex-shrink:0;font-family:var(--mono);font-size:10px;text-align:right;white-space:nowrap;letter-spacing:0;text-transform:none;color:var(--t4)}
.xr-val-hint{font-family:var(--mono);font-size:11px;color:var(--t3);margin-top:2px;white-space:nowrap}
.xr-verdict--ok{color:var(--gh)}
.xr-verdict--warn{color:var(--warn)}
.xr-verdict--edit{color:var(--info)}
.xr-lines-hdr{display:flex;align-items:center;gap:8px;margin:0 0 8px}
.xr-lines-hdr .xr-group-lbl{flex:1;margin:0}
.xr-help{font-size:10.5px;color:var(--t4);margin:6px 0 16px}
/* ── Record ledger layout (2026-09-11) — the Xero / QuickBooks bill-detail
   shape. Paper cards on the canvas; a 3-column header grid (label above
   value); closed <details> cards for the rest; totals right-aligned inside
   the line-items card with the grand total the heaviest figure on the page.
   Founder: the flat list read as "white with text". */
.output-scroll{background:var(--bg)}
.xr-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);box-shadow:var(--sh-sm);margin-bottom:12px}
.xr-head{padding:14px 18px 10px}
.xr-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:24px;row-gap:6px}
.xr-cell{flex-direction:column;align-items:stretch;gap:3px;padding:6px 8px;margin:0;border-radius:var(--r)}
.xr-cell .xr-lbl{width:auto}
.xr-cell .field-val{font-size:13.5px;width:100%}
.xr-cell .xr-verdict{text-align:left;margin-top:1px}
.xr-details{padding:0}
.xr-details-sum{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;padding:10px 18px;font-size:11px;font-weight:600;color:var(--t3);letter-spacing:.06em;text-transform:uppercase;user-select:none}
.xr-details-sum::-webkit-details-marker{display:none}
.xr-details-sum:hover{color:var(--t1)}
.xr-details-sum:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:-2px;border-radius:var(--r-lg)}
.xr-details-title{flex-shrink:0}
.xr-details-peek{flex:1;min-width:0;font-family:var(--mono);font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--t4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.xr-details-att{flex-shrink:0;font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-border);border-radius:999px;padding:1px 8px}
.xr-details-chev{flex-shrink:0;width:8px;height:8px;border-right:1.5px solid var(--t4);border-bottom:1.5px solid var(--t4);transform:rotate(-45deg);transition:transform 120ms;margin-right:2px}
.xr-details[open] > .xr-details-sum{border-bottom:1px solid var(--brd)}
.xr-details[open] > .xr-details-sum .xr-details-chev{transform:rotate(45deg)}
.xr-details[open] > .xr-details-sum .xr-details-peek{visibility:hidden}
.xr-details > .xr-rows{padding:8px 18px 10px}
.xr-details .xr-row{margin:0;padding:6px 8px;border-bottom:1px solid #eef2f7}
.xr-details .xr-row:last-child{border-bottom:none}
.xr-details .xr-lbl{width:130px}
.xr-lines-hdr{margin-top:6px}
.xr-totals{display:flex;flex-direction:column;align-items:flex-end;gap:2px;padding:10px 18px 12px;border-top:1px solid var(--brd);background:var(--card-head)}
.xr-total-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;width:min(100%,360px);padding:3px 0;animation:xrIn 240ms ease both}
.xr-total-row .xr-lbl{width:auto;flex:1;justify-content:flex-end;text-align:right}
.xr-total-row .field-val{flex:0 0 130px;width:130px;text-align:right}
.xr-total-row .xr-verdict{flex-basis:100%;text-align:right}
.xr-total-row--grand{border-top:1px solid var(--brd);margin-top:4px;padding-top:8px}
.xr-total-row--grand .xr-lbl{color:var(--t2)}
.xr-total-row--grand .field-val{font-size:16px;font-weight:500}
/* Round 2 (2026-09-11): quiet dots — a confident or empty field paints no
   dot (the accessible name inside stays), so colour means "look here". */
.conf-dot.conf-high,.conf-dot.conf-none{width:0;height:0;margin:0;border:0;background:transparent}
.xr-key{display:flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10px;color:var(--t4);margin:-4px 0 12px 8px}
.xr-key .conf-dot{margin-left:8px}
.xr-key .conf-dot:first-child{margin-left:0}
.xr-row--none{font-size:12px;color:var(--t4);font-style:italic;padding:6px 8px}
.xr-total-mirror{flex:0 0 auto;font-family:var(--mono);font-size:16px;font-weight:500;color:var(--t1);text-align:right;min-width:130px}
/* The strip is the Guardian header: its toggle sits inside .xr-status and the
   headless card shows body only, nothing at all while collapsed. */
.xr-status{position:relative}
.sp-toggle{position:absolute;right:16px;top:50%;transform:translateY(-50%);font-size:11px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd);border-radius:999px;padding:3px 10px;cursor:pointer;transition:all 120ms}
.sp-toggle:hover{border-color:var(--g);color:var(--gh)}
.sp-toggle:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:1px}
.xr-status:has(.sp-hidden) .sp-toggle,.xr-status:has(.sp-proc) .sp-toggle{display:none}
/* The toggle floats over the strip's right edge: its sentence stops short of
   it, and on a narrow screen the strip grows to the lines its sentence needs
   rather than clipping them under the toggle (audit 2026-09-26, PR-K2:
   stray fragments at 390px under the mobile banner and the worked-out bar). */
.xr-status:has(.sp-toggle:not([hidden])) .status-strip:not(.sp-hidden):not(.sp-proc){padding-right:118px}
@media (max-width:760px){.xr-status .status-strip:not(.sp-hidden){height:auto;min-height:40px;padding-top:8px;padding-bottom:8px;line-height:1.35}}
.guardian-score.gsc-headless:not(.open){display:none}
.guardian-score.gsc-headless .gsc-body{border-top:none}
@media (max-width:760px){.xr-grid{grid-template-columns:1fr;row-gap:2px}.xr-total-row{width:100%}}
.xr-table{margin-bottom:6px}
/* Eleven columns: keep readable cells and let the card scroll sideways
   (overflow-x:auto on .table-card) instead of squeezing SKU/description. */
.xr-table table{min-width:820px}
/* Entrance (rows, line rows, the Guardian card) + the reveal's hidden state.
   xr-pending is removed by extract.js in read order; reduced motion shows
   everything at once (extract.js reads the same media query). */
@keyframes xrIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.xr-pending{display:none!important}
#lineBody tr{animation:xrIn 260ms ease both}
@media (prefers-reduced-motion:reduce){.xr-row,.xr-total-row,#lineBody tr{animation:none}}
/* The Guardian card leads the record but reveals LAST: hold its collapsed
   height while pending so the record does not jump when it lands. */
#guardianBanner.xr-pending{display:block!important;visibility:hidden;min-height:90px}
@media (max-width:760px){
  .xr-idle{padding:14px 14px 12px}
  .xr-drop .dz-t{font-size:15.5px}
  .output-scroll{padding:14px 16px 24px}
  .xr-lbl,.xr-details .xr-lbl{width:88px}
}
/* Batch chip strip (Extract v5, PR3): under the topbar, above the stage. */
.batch-chip[aria-disabled="true"]{cursor:default;opacity:.7}
.batch-chip-strip{display:flex;gap:8px;padding:9px 20px;background:var(--white);border-bottom:1px solid var(--brd);flex-shrink:0;overflow-x:auto}
.batch-chip-strip[hidden]{display:none}
.batch-chip{display:flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;white-space:nowrap;border:1px solid var(--brd);background:var(--white);color:var(--t2);cursor:pointer;font:inherit;transition:border-color 120ms,background 120ms}
.batch-chip:hover{border-color:var(--g)}
.batch-chip--queued{background:var(--bg);color:var(--t4)}
.batch-chip--reading{border-color:rgba(21,97,158,.30);background:rgba(21,97,158,.05);color:var(--info)}
.batch-chip.is-current{border-color:var(--gbrd);background:var(--glo);color:var(--gh)}
.batch-chip-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0;background:var(--t5)}
.batch-chip-dot--done{background:var(--ok)} .batch-chip-dot--reading{background:var(--info)} .batch-chip-dot--manual{background:var(--warn)} .batch-chip-dot--error{background:var(--fail)}
.batch-chip-name{font-family:var(--mono);font-size:10.5px;max-width:22ch;overflow:hidden;text-overflow:ellipsis}
.batch-chip-st{font-size:9.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;opacity:.75}

/* Topbar file chip (Extract v5). */
.file-chip{display:flex;align-items:center;gap:8px;background:var(--bg);border:1px solid var(--brd);border-radius:999px;padding:8px 12px;min-width:0}
.file-chip-name{font-family:var(--mono);font-size:11.5px;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:28ch}
.file-chip-meta{font-family:var(--mono);font-size:10px;color:var(--t4);white-space:nowrap}
.file-chip-meta:empty{display:none}
@media (max-width:1100px){.file-chip-meta{display:none}}
/* "New extraction" is a first-class topbar action (2026-09-11): the shared .exp-btn
   anatomy, plus a tinted plus so it reads as "start the next one" rather than
   as a tag on the file name. */
.new-extraction-btn svg{stroke:var(--g);stroke-width:2.4}
.new-extraction-btn:hover svg{stroke:currentColor}
/* The companion feed (Extract v5, PR2). */
.audit-list.feed{padding:10px 14px}
.feed-entry{display:flex;gap:9px;padding:5px 0;animation:xrIn 200ms ease both}
.feed-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;margin-top:4px;background:var(--t5)}
.feed-dot--ok{background:var(--ok)} .feed-dot--warn{background:var(--warn)} .feed-dot--fail{background:var(--fail)} .feed-dot--info,.feed-dot--edit{background:var(--info)}
.feed-body{flex:1;min-width:0}
.feed-text{font-size:11.5px;color:var(--t2);line-height:1.45}
.feed-text .comp-badge-ok,.feed-text .comp-badge-warn{margin-left:4px;vertical-align:middle}
.feed-meta{font-family:var(--mono);font-size:10px;color:var(--t4);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.feed-block{margin:2px 0 6px;padding:8px 10px;background:var(--warn-bg);border:1px solid var(--warn-brd);border-radius:var(--r)}
.feed-block-hdr{display:flex;align-items:center;justify-content:space-between;font-size:11.5px;font-weight:600;color:var(--t1);margin-bottom:2px}
.feed-block .feed-entry{padding:4px 0}
.feed-block .chip-remedy{margin-top:6px}
.feed-chips{margin-top:6px;display:flex;gap:6px;flex-wrap:wrap}
.chip-dup{font-size:11px;font-weight:600;color:var(--t2);background:var(--white);border:1px solid var(--brd-md);border-radius:999px;padding:5px 12px;cursor:pointer;transition:all 120ms}
.chip-dup:hover{border-color:var(--g);color:var(--gh)}
.chip-dup--compare{color:var(--info);background:rgba(21,97,158,.06);border-color:rgba(21,97,158,.25)}
.chip-dup--compare:hover{background:rgba(21,97,158,.12);color:var(--info);border-color:rgba(21,97,158,.4)}
.feed-dup-table{margin-top:6px;background:var(--card-head);border:1px solid var(--brd);border-radius:var(--r);padding:8px 10px;font-size:10.5px}
.feed-dup-grid{display:grid;grid-template-columns:56px 1fr 1fr;gap:3px 8px;font-family:var(--mono);color:var(--t1)}
.feed-dup-hdr{font-family:var(--ui);font-weight:600;color:var(--t3)}
.feed-dup-lbl{font-family:var(--ui);color:var(--t4)}
.feed-dup-total{color:var(--warn);font-weight:500}
.feed-dup-note{color:var(--t4);margin-top:5px;font-size:10px}
.feed-diff{margin-top:5px}
.feed-kbd{font-size:10px;color:var(--t4);margin-bottom:8px;display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.feed-kbd kbd{font-family:var(--mono);font-size:9px;background:var(--bg);border:1px solid var(--brd);border-radius:4px;padding:1px 5px;color:var(--t3)}
.feed-kbd[hidden]{display:none}
/* Foot row: the advanced prompt (a <details>) takes the full width and Undo
   is pinned to the top right of the row, on the summary line (the
   prototype's "↩ Undo last change"). Pinned rather than a flex sibling so
   the OPEN details can use the whole width instead of a left column. */
.feed-foot-row{position:relative}
.feed-foot-row>.companion-prompt{margin:0}
.feed-foot-row>.btn-undo{position:absolute;top:0;right:0}
#feedFoot .companion-prompt{border-top:none;background:transparent;padding:0}
#feedFoot .companion-prompt>summary{padding:8px 132px 8px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
#feedFoot .companion-prompt[open]{padding-bottom:0}
@media (prefers-reduced-motion:reduce){.feed-entry{animation:none}}

/* Placeholder / loading */
.ph-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:11px;color:var(--t4)}
.ph-state:not(:empty):has(> :not(:empty)){padding:14px 20px 0}
.ph-ico{width:60px;height:60px;border:1.5px dashed var(--brd-md);border-radius:14px;display:flex;align-items:center;justify-content:center}
.ph-ico svg{width:26px;height:26px;stroke:var(--t5);fill:none;stroke-width:1.5}
.ph-t{font-size:15px;font-weight:500;color:var(--t3)}
.ph-s{font-size:12.5px;color:var(--t3)}
/* Warn-state placeholder variants (built by JS — e.g. an unreadable-file /
   gated empty state). --warn variants swap the dashed neutral chrome for the
   semantic amber wash; --wide gives a longer explanatory sub line room. */
.ph-card--warn{border-style:solid;border-color:var(--warn-brd);background:var(--warn-bg)}
.ph-ico--warn svg{stroke:var(--warn)}
.ph-t--strong{color:var(--t1)}
.ph-sub--wide{max-width:340px;text-align:center;line-height:1.55}
/* Wave-1 onboarding — "Audit your last VAT quarter" card (T5). Sits inside
   #phState (the Extract empty state); reuses .field-card as its base so it
   matches the rest of the app's card language instead of inventing a new one. */
.qa-card{margin-top:8px;max-width:380px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 22px}
.qa-t{font-size:14.5px;font-weight:600;color:var(--t1)}
.qa-s{font-size:12.5px;color:var(--t3);line-height:1.55}
.qa-actions{display:flex;gap:10px;margin-top:6px;flex-wrap:wrap;justify-content:center}
.qa-actions .btn-primary,.qa-actions .btn-secondary{padding:10px 18px;font-size:13px}
/* (The staged loading card — .loading-state/.load-* — was retired 2026-09-10:
   Extract v5 reveals the real response in read order instead.) */

/* Batch progress band — live run header: spinner + k-of-n + determinate bar
   with a travelling sheen while work is in flight. */
.batch-progress{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:18px 22px;margin-bottom:20px;box-shadow:var(--sh-sm)}
.batch-progress-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.batch-progress-lbl{font-size:13.5px;font-weight:600;color:var(--t1);font-family:var(--mono)}
.batch-progress-file{font-size:12px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:right;font-family:var(--mono)}
.batch-progress-track{width:100%;height:6px;background:var(--brd);border-radius:999px;overflow:hidden}
.batch-progress-fill{height:100%;background:var(--g);border-radius:999px;transition:width 240ms ease;position:relative;overflow:hidden}
.batch-progress-fill::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);animation:bpSheen 1.3s ease-in-out infinite}
@keyframes bpSheen{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
.bp-spin{width:13px;height:13px;border:2px solid var(--gmd);border-top-color:var(--g);border-radius:50%;animation:bpSpin 700ms linear infinite;flex-shrink:0}
@keyframes bpSpin{to{transform:rotate(360deg)}}
@keyframes batchRowPulse{0%,100%{background:rgba(217,119,6,.05)}50%{background:rgba(217,119,6,.14)}}
.batch-row-active{animation:batchRowPulse 1.4s ease-in-out infinite}
.batch-row-queued td{color:var(--t4)}
@keyframes statPulse{0%{transform:scale(1)}40%{transform:scale(1.18)}100%{transform:scale(1)}}
.stat-pulse{animation:statPulse 280ms ease}

/* Per-row status chips (queued → processing → done/flagged) */
.batch-st{display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:11px;font-weight:600;padding:3px 11px;border-radius:999px;border:1px solid transparent;white-space:nowrap}
.batch-st svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2.2;flex-shrink:0}
.bst-pass{color:var(--ok-text);background:var(--ok-bg);border-color:var(--ok-brd)}
.bst-review{color:var(--warn);background:var(--warn-bg);border-color:var(--warn-brd)}
.bst-error{color:var(--fail);background:var(--fail-bg);border-color:var(--fail-brd)}
.bst-manual{color:var(--t3);background:var(--bg);border-color:var(--brd)}
.bst-queued{color:var(--t4);background:var(--bg);border-color:var(--brd)}
.bst-processing{color:var(--info);background:var(--info-bg)}
.bst-spin{width:10px;height:10px;border:2px solid rgba(21,97,158,.25);border-top-color:var(--info);border-radius:50%;animation:bpSpin 700ms linear infinite;flex-shrink:0}
.batch-file{font-size:12px;color:var(--t3);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.batch-row-reason{font-size:11px;color:var(--t3);max-width:340px;margin-top:2px;line-height:1.4;white-space:normal;overflow-wrap:anywhere}
.batch-noact{color:var(--t4);font-size:11px}
.batch-view{font-size:11px;padding:4px 12px;opacity:1}
@media (prefers-reduced-motion: reduce){
  .batch-progress-fill::after{animation:none}
  .bp-spin,.bst-spin{animation:none;border-top-color:currentColor;opacity:.6}
  .batch-row-active{animation:none;background:rgba(217,119,6,.1)}
  .stat-pulse{animation:none}
  .batch-stat-cell,.bi-stat{transition:none}
}

/* Duplicate-invoice banner (advisory) — sits above the Guardian card on the
   Extract surface when /upload returns a prior matching extraction. */
.dup-banner{display:flex;align-items:flex-start;gap:12px;background:var(--warn-bg);border:1px solid var(--warn-brd);border-radius:var(--r-lg);padding:14px 18px;margin-bottom:16px;box-shadow:var(--sh-sm)}
.dup-ico{font-size:16px;line-height:1.3;flex-shrink:0}
.dup-body{flex:1;min-width:0}
.dup-t{font-size:13px;font-weight:600;color:var(--warn);margin-bottom:3px}
.dup-msg{font-size:12.5px;color:var(--t2);line-height:1.5}
.dup-msg strong{color:var(--t1);font-weight:600}
.dup-view{flex-shrink:0;align-self:center;background:var(--warn);color:#fff;border:none;font-size:12px;font-weight:600;padding:7px 14px;border-radius:var(--r);cursor:pointer;white-space:nowrap;transition:opacity 120ms}
/* Re-upload of the SAME FILE (2026-07-26). Deliberately NOT amber: nothing is
   wrong and nothing needs the user's attention — we are telling them we
   recognised the file, charged nothing and are showing the record they already
   have. Amber here (the old behaviour, borrowed from the same-invoice warning)
   read as an error for a completely benign, common action. Informational blue,
   with the same geometry so the two banners never jump the layout. */
.dup-banner--info{background:var(--info-bg);border-color:var(--info-brd)}
.dup-banner--info .dup-t{color:var(--info)}
.dup-banner--info .dup-view{background:var(--info)}
.dup-view:hover{opacity:.88}
/* Dismiss × — only the credit-headroom strip carries one (a payment failure
   is not dismissible; it is the one thing the user must act on). Quiet by
   design: a nudge you can wave away must not compete with the CTA beside it.
   No outline:none anywhere here — the global button:focus-visible ring (:108)
   is inherited untouched, per the site-wide keyboard rule; these rules only
   add the colour shift that makes the low-contrast glyph legible on focus. */
.dup-dismiss{flex-shrink:0;align-self:flex-start;background:none;border:none;color:var(--t4);font-size:17px;line-height:1;padding:2px 4px;margin:-2px -4px 0 4px;cursor:pointer;border-radius:var(--r-xs);transition:color 120ms}
.dup-dismiss:hover,.dup-dismiss:focus-visible{color:var(--t2)}
/* Dunning strip (global slot under the topbar, topbar.html #dunningBanner) —
   reuses the .dup-banner advisory anatomy; these rules only position the
   slot in the content column. */
.dunning-slot{padding:12px 24px 0}
.dunning-slot .dup-banner{margin-bottom:0}
/* Batch summary: duplicate row tint + inline pill (the at-a-glance flag). */
.batch-row-dup{background:var(--warn-bg)}
.dup-pill{display:inline-block;font-size:11.5px;font-weight:600;color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-brd);padding:3px 11px;border-radius:999px;margin-left:6px;white-space:nowrap;vertical-align:middle}
/* "↻ Already processed" — the batch row's re-upload flag (2026-07-26). Same
   footprint as .dup-pill so a row carrying both keeps its rhythm, but the INFO
   tokens (identical to .cn-pill's, the other informational pill in this cell):
   a recognised re-upload cost nothing and broke nothing, so it must not wear
   the duplicate warning's amber. Overrides only the three colour properties. */
.dup-pill--info{color:var(--info);background:var(--info-bg);border-color:var(--info-brd)}
/* Credit-note flag (Wave 1.5) — neutral/informational pill (info tokens), the
   at-a-glance "this document is a credit note" marker. Same footprint as .dup-pill. */
.cn-pill{display:inline-block;font-size:11.5px;font-weight:600;color:var(--info);background:var(--info-bg);border:1px solid rgba(21,97,158,.24);padding:3px 11px;border-radius:999px;margin-left:6px;white-space:nowrap;vertical-align:middle}
/* Credit-note detail strip (History detail): pill + "View original →" link. */
.cn-detail-strip{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.cn-detail-strip .cn-pill{margin-left:0}
/* Receipt (AP-48) History-detail note — the one-line "which rules applied"
   beside the pill; same quiet tokens as .gsc-note. */
.cn-detail-note{font-size:12px;color:var(--t4)}
.cn-view-original{font-size:12px;font-weight:600;color:var(--info);background:transparent;border:none;padding:2px 4px;cursor:pointer;border-radius:var(--r)}
.cn-view-original:hover{background:var(--info-bg)}

/* Approval workflow — list pill (same footprint as .dup-pill/.cn-pill) +
   the History-detail inline action strip. Status colours use the DEDICATED
   --appr-* tokens (violet/ink/slate — founder call 2026-07-22): approval
   states must never read as the ok/warn/fail extraction-confidence lights.
   The slate is #475569, darkened from slate-500 to clear WCAG AA (4.5:1)
   at 11.5px/600 even over a duplicate-tinted row. */
.appr-pill{display:inline-block;font-size:11.5px;font-weight:600;padding:3px 11px;border-radius:999px;margin-left:6px;white-space:nowrap;vertical-align:middle;border:1px solid transparent}
.appr-pill--pending{color:var(--appr-wait);background:var(--appr-wait-bg);border-color:var(--appr-wait-brd)}
.appr-pill--approved{color:var(--appr-done);background:var(--appr-done-bg);border-color:var(--appr-done-brd)}
.appr-pill--rejected{color:var(--appr-rej);background:var(--appr-rej-bg);border-color:var(--appr-rej-brd)}
.appr-strip{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:10px 14px;margin-bottom:12px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r)}
.appr-copy{font-size:13px;color:var(--t3)}
.appr-copy strong{color:var(--t2);font-weight:600}
/* Tier-gate variant (Gold+, 2026-08-11): a quieter ground than a working
   strip, so a stranded row reads as a NOTICE rather than a live control. */
.appr-gate{background:var(--bg)}
.appr-gate-note{flex-basis:100%}
.appr-select{max-width:280px}
.appr-btn{white-space:nowrap}
.appr-link{font-size:12px;font-weight:600;color:var(--t4);background:transparent;border:none;padding:2px 4px;cursor:pointer;border-radius:var(--r)}
.appr-link:hover{color:var(--t2);background:var(--bg)}
.appr-reject-form{display:flex;align-items:flex-start;flex-wrap:wrap;gap:8px;width:100%}
/* State-pair rule (the #165 class): the form ships with the `hidden`
   attribute and is revealed by the Reject click. The display:flex above is
   author CSS, so it BEATS the browser's own [hidden]{display:none} — without
   this pair rule the reject form rendered permanently for everyone (requester
   included) and the Reject button read as dead (prod UAT, 2026-07-22). */
.appr-reject-form[hidden]{display:none}
.appr-reason{flex:1 1 260px;min-height:44px;resize:vertical}
.appr-err{width:100%}

/* Guardian */
/* Legacy fallback banner — used only by extract.js error path
   (guardianBanner.innerHTML on /upload failure). Main compliance UI is
   .guardian-score below. */
.guardian{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:16px 18px;margin-bottom:16px;box-shadow:var(--sh-sm)}
.guardian.issues{border-color:var(--warn-brd);background:var(--warn-bg)}
.guardian-hdr{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.guardian-lbl{font-size:12px;font-weight:600;color:var(--t3)}

/* Guardian score card — compliance-report treatment (fable-overhaul).
   Default-collapsed when all-pass; auto-opens on warn/fail/checking.
   Per-row gov.uk ↗ preserved (Phase 2.1). A 3px state-coloured left edge
   makes the card read as a filed compliance report, not a debug panel. */
.guardian-score{background:var(--white);border:1px solid var(--brd);border-left-width:3px;border-left-color:var(--brd-md);border-radius:var(--r-lg);margin-bottom:16px;box-shadow:var(--sh-sm);overflow:hidden}
.guardian-score.has-fail{border-color:var(--fail-brd);border-left-color:var(--fail)}
.guardian-score.has-warn{border-color:var(--warn-brd);border-left-color:var(--warn)}
.guardian-score.has-checking{border-color:rgba(21,97,158,.28);border-left-color:var(--info)}
.guardian-score.all-pass{border-color:var(--ok-brd);border-left-color:var(--ok)}
.gsc-header{display:flex;align-items:center;gap:14px;padding:14px 18px;cursor:pointer;user-select:none}
.gsc-header:hover{background:#f8fafc}
.gsc-dial{width:44px;height:44px;flex-shrink:0}
.gsc-summary{flex:1;min-width:0}
.gsc-title{font-size:13.5px;font-weight:600;color:var(--t1);letter-spacing:-.005em;display:flex;align-items:center;gap:6px}
.gsc-shield{width:14px;height:14px;fill:none;stroke-width:2;flex-shrink:0}
.gsc-sub{font-size:12px;color:var(--t3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gsc-chev{width:15px;height:15px;stroke:var(--t4);fill:none;stroke-width:2;flex-shrink:0;transition:transform 180ms ease}
.guardian-score.open .gsc-chev{transform:rotate(180deg)}
.gsc-body{display:none;border-top:1px solid var(--brd);padding:14px 18px 16px;flex-direction:column;gap:18px;background:#fcfdfe}
.guardian-score.open .gsc-body{display:flex}
.gsc-note{font-size:12px;color:var(--t4);border-top:1px dashed var(--brd);padding-top:10px;margin-top:-6px}
.gsc-section-hdr{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.gsc-section-lbl{font-size:10.5px;font-weight:600;color:var(--t4);letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}
.gsc-section-bar{flex:1;height:3px;background:var(--brd);border-radius:999px;overflow:hidden}
.gsc-section-fill{height:100%;background:var(--ok);border-radius:999px;transition:width 240ms ease}
.gsc-section-count{font-family:var(--mono);font-size:10.5px;color:var(--t3);white-space:nowrap}
.gsc-rows{display:flex;flex-direction:column;gap:1px}
.gsc-row{display:flex;align-items:center;gap:9px;padding:6px 0;font-size:12.5px;flex-wrap:wrap}
/* The AI remedy chip (companion.js) is a sentence, not a button label. On a
   failing VAT Registration row it sat on the same flex line as the label +
   "Edit field →" and the label collapsed under it (site walkthrough
   2026-09-05). The chip now wraps in its own full-width track below the
   label/link/actions line, indented like the detail line. */
.gsc-row-remedy{flex-basis:100%;padding-left:16px;display:flex}
.gsc-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.gsc-pass .gsc-dot{background:var(--ok)}
.gsc-warn .gsc-dot{background:var(--warn)}
.gsc-fail .gsc-dot{background:var(--fail)}
.gsc-skip .gsc-dot{background:var(--t5)}
.gsc-checking .gsc-dot{background:transparent;width:9px;height:9px;border:1.5px solid var(--info);border-right-color:transparent;border-radius:50%;animation:gscSpin 700ms linear infinite}
.gsc-spin{display:none}
@keyframes gscSpin{to{transform:rotate(360deg)}}
/* Pulse the score dial while a recheck is in flight so the user sees
   activity even with the body collapsed. Reduced-motion fallback below. */
.guardian-score.has-checking .gsc-dial{animation:gscDialPulse 1.4s ease-in-out infinite}
@keyframes gscDialPulse{0%,100%{opacity:1}50%{opacity:.55}}
.gsc-row-lbl{flex:1 1 auto;color:var(--t2);min-width:0;font-weight:500}
.gsc-skip .gsc-row-lbl{color:var(--t4);font-weight:400}
.gsc-row-detail{font-size:12px;color:var(--t3);line-height:1.55;flex-basis:100%;padding-left:16px}
.gsc-edit-btn{font-size:11px;font-weight:600;color:var(--gh);background:var(--glo);border:1px solid var(--gbrd);border-radius:var(--r-xs);padding:3px 10px;cursor:pointer;white-space:nowrap;transition:background 100ms,color 100ms;margin-left:auto;flex-shrink:0}
.gsc-row-remedy .gsc-edit-btn{margin-left:0;flex:0 1 auto;min-width:0}
.gsc-edit-btn:hover{background:var(--gmd);color:var(--gh)}
/* Citation ↗ arrow: brand-green at full opacity so it reads as an
   interactive link, not background decoration. Hover underlines to
   reinforce the affordance. */
.cite-arrow{display:inline-flex;align-items:center;font-size:12.5px;font-weight:600;margin-left:5px;color:var(--gh);text-decoration:none;transition:color 100ms,text-decoration-color 100ms;border-radius:var(--r-xs)}
.cite-arrow:hover{color:var(--gh);text-decoration:underline;text-underline-offset:2px}
/* --glo is an 8%-alpha tint — as the ONLY indicator it made these the one
   near-invisible focus stop in the app, and it overrode the global
   a:focus-visible outline. Keep the halo, restore the ring. */
.cite-arrow:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:2px;box-shadow:0 0 0 2px var(--glo)}
@keyframes gscFlash{0%{box-shadow:0 0 0 3px var(--gbrd)}100%{box-shadow:0 0 0 3px transparent}}
.gsc-flash{animation:gscFlash 700ms ease forwards}
@media (prefers-reduced-motion: reduce){
  .gsc-section-fill,.gsc-chev,.cite-arrow{transition:none}
  .gsc-flash{animation:none;box-shadow:0 0 0 3px var(--gbrd)}
  .gsc-checking .gsc-dot{animation:none;border-right-color:var(--info);opacity:.6}
  .guardian-score.has-checking .gsc-dial{animation:none;opacity:.85}
}

/* Section label */
.slbl{font-size:11.5px;font-weight:600;color:var(--t3);letter-spacing:.04em;margin-bottom:10px;margin-top:6px;display:flex;align-items:center;gap:8px;text-transform:uppercase}
.slbl::after{content:'';flex:1;height:1px;background:var(--brd)}

/* Field grid */
.field-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:24px}
.field-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:13px 16px;transition:border-color 120ms,box-shadow 120ms;box-shadow:var(--sh-xs)}
.field-card--wide{grid-column:span 2}
.field-card:focus-within{border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.field-lbl{font-size:10px;font-weight:600;color:var(--t4);letter-spacing:.07em;text-transform:uppercase;margin-bottom:5px;display:flex;align-items:center;gap:5px}
.conf-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
.conf-high{background:var(--ok)}
.conf-med{background:var(--warn)}
.conf-low{background:var(--fail)}
.conf-user{background:var(--info)}
.conf-none{background:var(--brd-md)}
.fi-none{color:var(--t3)}
.field-val{width:100%;border:none;border-bottom:1.5px solid transparent;font-family:var(--mono);font-size:13px;color:var(--t1);background:transparent;outline:none;padding:1px 0;transition:border-color 120ms;letter-spacing:-.01em;text-overflow:ellipsis}
.field-val:focus{border-bottom-color:var(--g)}
/* Keyboard focus needs more than the 1.5px underline — the same 3px halo as
   .finput:focus (mouse focus keeps just the underline via :focus above). */
.field-val:focus-visible{box-shadow:0 0 0 3px var(--glo);border-radius:2px;outline:none}
.fi-high{color:var(--t1)}
.fi-med{color:var(--warn)}
.fi-low{color:var(--fail);font-weight:600}
.fi-user{color:var(--info)}

/* Table */
/* overflow-x:auto, NOT hidden — the line-items table is ~722px wide and the
   output panel can be ~500px at laptop widths; hidden made the money columns
   (VAT %, Unit price, Line total) unreachable. */
.table-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);overflow-x:auto;overflow-y:hidden;box-shadow:var(--sh-sm);margin-bottom:20px}
table{width:100%;border-collapse:collapse;font-size:12.5px}
thead{background:#f6f9fc}
th{font-size:10.5px;font-weight:600;color:var(--t3);letter-spacing:.07em;text-transform:uppercase;padding:11px 14px;text-align:left;border-bottom:1px solid var(--brd);white-space:nowrap}
th.r{text-align:right} th.c{text-align:center}
tbody tr{border-bottom:1px solid var(--brd);transition:background 80ms}
tbody tr:last-child{border-bottom:none}
tbody tr:hover{background:#f7fafd}
td{padding:10px 14px;vertical-align:middle}
td.num{color:var(--t4);font-family:var(--mono);font-size:10.5px;text-align:center;width:30px}
td.sku{font-family:var(--mono);font-size:12.5px;color:var(--data);white-space:nowrap}
td.desc{color:var(--t2);max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
td.c{text-align:center}
td.r{text-align:right}
td.mono{font-family:var(--mono);font-size:12.5px}
td.bold{font-weight:600;color:var(--t1)}
.tbl-inp{width:100%;background:transparent;border:none;border-bottom:1.5px solid transparent;font-family:var(--mono);font-size:12.5px;outline:none;padding:1px 0;transition:border-color 120ms;color:inherit;text-overflow:ellipsis}
.tbl-inp:focus{border-bottom-color:var(--g)}
/* Keyboard-focus halo — mirrors .field-val:focus-visible above. */
.tbl-inp:focus-visible{box-shadow:0 0 0 3px var(--glo);border-radius:2px;outline:none}
/* Alignment variants — an input never inherits its <td>'s text-align, so the
   numeric/centred cells set it explicitly via these classes (extract.js). */
.tbl-inp--r{text-align:right}
.tbl-inp--c{text-align:center}
/* F18 — per-row "Remove line" control (extract.js buildLineRowsHtml, editable
   only). A .btn-secondary shrunk to table scale: it keeps the token border /
   hover colours and the global button:focus-visible ring, so the keyboard
   affordance is the same one every other button has. Hover/focus recolour to
   --fail because the action is destructive (Undo restores it). */
.line-rm{padding:0;width:22px;height:22px;line-height:1;border-radius:6px;font-size:12px;box-shadow:none}
.line-rm:hover,.line-rm:focus-visible{color:var(--fail);border-color:var(--fail);background:var(--fail-bg)}

/* (The bottom fix bar — .bottom-bar/.adj-input — was removed 2026-09-04; the
   AI prompt lives in the companion drawer, see .companion-prompt below.) */
@media (max-width:1280px){.upload-panel{width:clamp(380px,36%,520px)}}
/* AI Act Art 50(1)/50(5) notice above the drawer's fix input
   (docs/legal/AI_ACT_POSITION.md §5). A real token rule, never an inline
   style; margin:0 so it sits as the input's label. Sized on the
   .dz-sub/.load-s sub-label scale. */
.adj-note{margin:0;font-size:12.5px;color:var(--t3);line-height:1.55}
.btn-fix{background:var(--gh);color:#fff;font-size:13px;font-weight:600;border:none;border-radius:var(--r);padding:10px 20px;letter-spacing:.01em;transition:background 120ms;white-space:nowrap;box-shadow:0 1px 2px rgba(5,150,105,.3)}
.btn-fix:hover:not(:disabled){background:var(--gh2)}
.btn-fix:disabled{background:var(--brd-md);color:var(--t3);cursor:not-allowed;box-shadow:none}
.bb-sep{width:1px;height:26px;background:var(--brd)}
.exp-btn{font-size:12px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd-md);border-radius:var(--r);padding:8px 14px;white-space:nowrap;display:flex;align-items:center;gap:6px;transition:all 120ms;box-shadow:var(--sh-xs)}
.exp-btn:hover{border-color:var(--g);color:var(--gh);background:var(--glo)}
.exp-btn svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2}

/* Export dropdown (bottom-bar declutter) — collapses CSV/Sage/Xero into one
   "Export ▾" toggle. Opens upward (the bar is screen-bottom). */
.export-menu{position:relative;display:inline-flex;flex-shrink:0}
.export-caret{margin-left:1px}
.export-dropdown{position:absolute;bottom:calc(100% + 8px);right:0;min-width:184px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);box-shadow:var(--sh-lg);padding:6px;display:flex;flex-direction:column;gap:2px;z-index:30}
.export-dropdown[hidden]{display:none}
.export-opt{text-align:left;font-size:13px;font-weight:600;color:var(--t3);background:transparent;border:none;border-radius:var(--r);padding:10px 12px;white-space:nowrap;cursor:pointer;transition:all 100ms}
.export-opt:hover{background:var(--glo);color:var(--gh)}
/* Downward variant — the batch Export ▾ sits in the screen-TOP header, so its menu
   must open below the toggle (the default opens upward for the bottom bar).
   left:0 anchors it under the left-aligned toggle so it can't clip off-screen. */
.export-dropdown-down{top:calc(100% + 8px);bottom:auto;left:0;right:auto}
/* Credit-note export caveat (Wave 1.5) — a small factual note inside the Export ▾
   dropdown, shown only when the current document is a credit note. */
.export-caveat{font-size:11px;line-height:1.4;color:var(--t2);padding:8px 12px 4px;border-top:1px solid var(--brd);margin-top:2px;white-space:normal;max-width:220px}
.export-caveat[hidden]{display:none}
/* The pending caveat is AMBER (the prototype's red-ish warning). It must sit
   AFTER the base rule above and outrank it: a same-specificity rule earlier
   in the file lost the cascade and the line rendered grey (founder
   click-through, 2026-09-11). */
.export-caveat.export-caveat--pending{color:var(--warn);font-weight:600}

/* Audit sidebar */
/* A width:0 + overflow:hidden panel is INVISIBLE BUT STILL FOCUSABLE — a
   keyboard user on Extract tabbed into the closed panel's Close button and
   its Undo button, and activating the first one opened a panel they never
   asked for (keyboard audit 2026-07-25). visibility:hidden takes the whole
   subtree out of the tab order; the delayed transition keeps the slide-out
   (visibility flips only after the 180ms collapse, and instantly on open). */
/* The drawer OVERLAYS the stage at EVERY width (founder, 2026-09-11: "the AI
   companion hovers over, not a block"). Until then it was an inline flex
   sibling above 1400px, with the document pane yielding width to it, and an
   overlay only below. Now one posture: position:absolute over the record,
   the scrim dims the stage, and it is dismissed by the scrim, Escape, or its
   own ✕ — the same shape as the mobile nav rail (.sb-scrim). The width
   transition is unchanged so the prefers-reduced-motion rule still covers
   it. The 1400px auto-open floor (companion.js DRAWER_AUTO_MIN_WIDTH) is a
   separate decision and stays. */
.audit-sidebar{width:400px;background:var(--white);border-left:1px solid var(--brd);display:flex;flex-direction:column;flex-shrink:0;transition:width 180ms ease,visibility 0s;overflow:hidden;
               position:absolute;top:0;right:0;bottom:0;z-index:56;box-shadow:-8px 0 28px rgba(10,20,36,.16)}
.audit-sidebar.closed{width:0;visibility:hidden;transition:width 180ms ease,visibility 0s linear 180ms;box-shadow:none}
/* The layout is the positioning context; without this the drawer would pin
   to the viewport and slide under the topbar. */
.extract-layout{position:relative}
.extract-layout:has(.audit-sidebar:not(.closed)) .audit-scrim{opacity:1;visibility:visible}
/* Sits just under the drawer (56) and above the page, mirroring .sb-scrim's
   z-index:55. Inert and invisible until the rule above reveals it. */
/* position:absolute inside .extract-layout (position:relative), NOT fixed:
   the scrim covers exactly what is inerted (the stage), and the topbar +
   nav rail stay visible, clickable and honestly focusable (pre-merge
   review 2026-09-11: a fixed scrim dimmed Save/Export/nav while leaving
   them in the tab order). */
.audit-scrim{position:absolute;inset:0;background:rgba(10,20,36,.38);z-index:55;
             opacity:0;visibility:hidden;transition:opacity 180ms ease,visibility 0s linear 180ms}
@media (prefers-reduced-motion:reduce){.audit-scrim{transition:none}}
.audit-hdr{padding:16px 18px 13px;border-bottom:1px solid var(--brd);display:flex;justify-content:space-between;align-items:center;flex-shrink:0}
.audit-t{font-size:13.5px;font-weight:600;color:var(--t1)}
.audit-close{background:none;border:none;color:var(--t4);font-size:19px;line-height:1;padding:2px 5px;border-radius:var(--r-xs)}
.audit-close:hover{color:var(--t1)}
.audit-list{flex:1;overflow-y:auto;padding:10px}
.audit-item{padding:10px 12px;background:var(--bg);border:1px solid var(--brd);border-radius:var(--r);margin-bottom:6px}
.audit-instr{font-size:12.5px;color:var(--t2);line-height:1.45}
.audit-time{font-family:var(--mono);font-size:9.5px;color:var(--t4);margin-top:3px}
.audit-empty{font-size:12.5px;color:var(--t4);padding:8px 4px}
.audit-foot{padding:11px;border-top:1px solid var(--brd);flex-shrink:0}
.btn-undo{width:auto;flex-shrink:0;background:transparent;border:1px solid transparent;color:var(--fail);font-size:12px;font-weight:600;border-radius:var(--r);padding:8px 10px;display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:all 120ms;white-space:nowrap}
.btn-undo:hover:not(:disabled){background:var(--fail-bg);border-color:var(--fail-brd)}
.btn-undo:disabled{opacity:.3;cursor:not-allowed}
.btn-undo[aria-disabled="true"]{opacity:.5;cursor:not-allowed}
.btn-undo[aria-disabled="true"]:hover{background:transparent;border-color:transparent}
.btn-undo svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2}

/* Batch screen */
/* #tool-batch is the positioning context for the full-screen drag-drop overlay
   below (the base .app-screen rule sets no position). */
#tool-batch{position:relative}
.batch-screen{flex:1;overflow-y:auto;padding:28px 32px}

/* Drag-drop overlay — fades in while a drag is over the Batch page, mirroring the
   Extract .dz-drop-overlay. Covers the whole screen (inset:0); pointer-events stays
   none so the underlying #tool-batch drop handler still fires. Tokens only. */
.batch-drop-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;background:rgba(236,250,244,.95);border:2px dashed var(--g);border-radius:inherit;z-index:30;font-size:15px;font-weight:600;color:var(--gh);opacity:0;visibility:hidden;pointer-events:none;transition:opacity 120ms}
.batch-drop-overlay svg{width:34px;height:34px;stroke:currentColor;fill:none;stroke-width:2}
#tool-batch.batch-drag-active .batch-drop-overlay{opacity:1;visibility:visible}
.page-title{font-size:var(--t-title);font-weight:700;color:var(--t1);letter-spacing:-.03em;margin-bottom:5px}
.page-sub{font-size:14px;color:var(--t3);margin-bottom:20px;max-width:680px;line-height:1.55}

/* Empty-state Batch dropzone — drop OR click to start a fresh batch here (no
   detour to Extract). Mirrors the Extract .dropzone look (dashed border, centred
   icon+text, green hover) using tokens only. The .batch-drag-active class on
   #tool-batch lights it up while a file is dragged anywhere over the screen. */
.batch-dropzone{border:1.5px dashed var(--brd-md);border-radius:var(--r-xl);display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:56px 28px;margin-bottom:20px;cursor:pointer;background:transparent;transition:border-color 150ms,background-color 150ms}
/* Empty state: the drop target owns the working area it was leaving dead —
   and the 'Batch results / No batch in progress' labels stand down (the
   dropzone says what this screen is). Toggled by _toggleBatchEmptyChrome. */
.batch-screen.batch-empty{display:flex;flex-direction:column}
.batch-empty .batch-dropzone{flex:1;margin-bottom:0;min-height:320px}
.batch-empty .page-title,.batch-empty .page-sub{display:none}
.batch-dropzone:hover,#tool-batch.batch-drag-active .batch-dropzone{border-color:var(--g);background:var(--glo)}
.bdz-icon{width:56px;height:56px;background:var(--glo);border:1px solid var(--gbrd);border-radius:14px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 10px rgba(5,150,105,.14)}
.bdz-icon svg{width:24px;height:24px;stroke:var(--g);fill:none;stroke-width:2}
.bdz-t{font-size:14.5px;font-weight:600;color:var(--t1);margin-bottom:4px;letter-spacing:-.01em}
.bdz-sub{font-size:12.5px;color:var(--t3);line-height:1.55}
/* "← Back to results" — subtle text link above the New-batch dropzone; returns to
   the kept results without replacing them. Tokens only (no inline styles). */
.batch-back-to-results{background:none;border:none;font-size:12.5px;font-weight:600;color:var(--t3);padding:0;margin-bottom:14px;cursor:pointer;transition:color 120ms}
.batch-back-to-results:hover{color:var(--gh)}

/* Batch header stat cards — 3px status accent, live pulse during a run */
.batch-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:14px;margin-bottom:18px}   /* six cells since "Already in History" (2026-09-05) */
.batch-stat-cell{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:17px 20px;box-shadow:var(--sh-xs);position:relative;overflow:hidden;min-width:0;transition:box-shadow 160ms,transform 160ms}
.batch-stat-cell:hover{box-shadow:var(--sh-sm);transform:translateY(-1px)}
.batch-stat-cell::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--brd-md)}
.batch-stat-cell.bsc-ok::before{background:var(--ok)}
.batch-stat-cell.bsc-warn::before{background:var(--warn)}
.batch-stat-cell.bsc-fail::before{background:var(--fail)}
/* Skipped (unreadable input set aside) — muted slate, echoing the row chip's
   .bst-manual neutral token: needs attention, but not an alarm-red error. */
.batch-stat-cell.bsc-skip::before{background:var(--brd-str)}
/* Already in History (re-upload, nothing charged) — the info blue the row pill uses. */
.batch-stat-cell.bsc-info::before{background:var(--info)}
.bsc-info .stat-ic{color:var(--info)}
.batch-stat-val{font-family:var(--mono);font-size:26px;font-weight:500;color:var(--t1);line-height:1;letter-spacing:-.02em}
.bsv-ok{color:var(--ok-text)} .bsv-warn{color:var(--warn)} .bsv-fail{color:var(--fail)} .bsv-skip{color:var(--t3)}
.batch-stat-lbl{font-size:11px;color:var(--t3);margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (max-width: 1000px){.batch-stats{grid-template-columns:repeat(3,1fr)}}
@media (max-width: 620px){.batch-stats{grid-template-columns:repeat(2,1fr)}}

/* Batch insights — the post-run dashboard (count-up stats, currency mix,
   spend-by-supplier bars that grow on completion) */
.batch-insights{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xl);padding:24px 26px;margin-top:20px;box-shadow:var(--sh-sm)}
.bi-header{display:flex;align-items:baseline;gap:10px;margin-bottom:16px}
.bi-title{font-size:15px;font-weight:600;color:var(--t1);letter-spacing:-.01em}
.bi-sub{font-size:12px;color:var(--t4)}
/* ── Stat-tile icon chip (shared: .hist-stat / .bi-stat / .batch-stat-cell) ──
   A quiet 28px rounded chip anchored BOTTOM-right — on the label line, not
   the value line, so a wide money value (£119,772.78) keeps its full width
   and only the short ellipsis-safe label yields (padding via the sibling
   selector ONLY when a chip is present — chipless tiles like the sparkline
   card are untouched). Neutral by default; the batch status cells tint the
   glyph to match their keyline. */
.stat-ic{position:absolute;bottom:12px;right:12px;width:28px;height:28px;border-radius:8px;background:var(--bg);border:1px solid var(--brd);display:flex;align-items:center;justify-content:center;color:var(--t4);pointer-events:none}
.stat-ic svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8}
.stat-ic~.hist-stat-lbl,.stat-ic~.bi-stat-lbl,.stat-ic~.batch-stat-lbl{padding-right:34px}
.bsc-ok .stat-ic{color:var(--ok-text)}
.bsc-warn .stat-ic{color:var(--warn)}
.bsc-fail .stat-ic{color:var(--fail)}
.bi-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:14px}
/* Admin's 6-tile KPI band — an even row, not a ragged 4+2. */
.bi-stats-6{grid-template-columns:repeat(6,1fr)}
.bi-stat{position:relative;background:#f8fafc;border:1px solid var(--brd);border-radius:var(--r-lg);padding:16px 18px;min-width:0;transition:box-shadow 160ms,transform 160ms}
.bi-stat:hover{box-shadow:var(--sh-sm);transform:translateY(-1px)}
.bi-stat-val{font-family:var(--mono);font-size:24px;font-weight:500;color:var(--t1);line-height:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:-.02em}
.bi-stat-val-warn{color:var(--warn)}
/* Wraps at word boundaries, never an ellipsis and never mid-word (audit 2026-09-26, PR-H; only #adminStats may break a token, below): the spend label carries notes such as
   "· 2 duplicates left out", and an ellipsis hid exactly that note. */
.bi-stat-lbl{font-size:11.5px;color:var(--t3);margin-top:6px;line-height:1.35;white-space:normal;overflow-wrap:normal}
/* A tile's extra line (the admin "Refund changes owed" date, PR-A round 4):
   it WRAPS, never clips, so a date is never cut off at phone width. */
.bi-stat-sub{font-size:11px;color:var(--t3);margin-top:4px;line-height:1.35;white-space:normal;overflow-wrap:anywhere}
.bi-stat-sub-warn{color:var(--warn)}
.bi-meta{font-size:12px;color:var(--t3);margin-bottom:18px;line-height:1.6}
.bi-meta strong{color:var(--warn);font-weight:600}
.bi-chart-label{font-size:10.5px;font-weight:600;color:var(--t4);letter-spacing:.08em;text-transform:uppercase;margin-bottom:12px}
/* The amount column is as wide as its amount and the name and track give way (audit 2026-09-26,
   PR-H round 4, 6b): a fixed 160px + 1fr + 90px row was wider than a phone's panel, so the amount
   sat past the panel's edge. */
.bi-bar-row{display:grid;grid-template-columns:minmax(0,160px) minmax(24px,1fr) max-content;align-items:center;gap:12px;margin-bottom:8px}
.bi-bar-label{font-size:12px;color:var(--t2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bi-bar-track{height:7px;background:var(--brd);border-radius:999px;overflow:hidden}
.bi-bar-fill{height:100%;background:var(--g);border-radius:999px;transition:width 400ms ease}
.bi-bar-val{font-family:var(--mono);font-size:11.5px;color:var(--t3);text-align:right}
@media (max-width: 900px){.bi-stats{grid-template-columns:repeat(2,1fr)}.bi-stats-6{grid-template-columns:repeat(3,1fr)}}

/* Currency-mix strip — proportional stacked bar by invoice count + legend */
.bi-ccy-label{font-size:10.5px;font-weight:600;color:var(--t4);letter-spacing:.08em;text-transform:uppercase;margin:0 0 8px}
.bi-ccy-bar{display:flex;height:10px;border-radius:999px;overflow:hidden;background:var(--brd);gap:2px}
.bi-ccy-seg{height:100%;min-width:6px}
.bi-ccy-0{background:var(--g)}
.bi-ccy-1{background:var(--data)}
.bi-ccy-2{background:#7c3aed}
.bi-ccy-3{background:var(--warn)}
.bi-ccy-legend{margin:8px 0 16px}
.bi-ccy-key{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--t3);margin-right:16px}
.bi-ccy-dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0}

/* Manual review */
.manual-screen{flex:1;padding:24px 28px;display:flex;flex-direction:column;gap:12px;overflow:hidden}
.warn-banner{background:var(--warn-bg);border:1px solid var(--warn-brd);border-radius:var(--r-lg);padding:15px 19px;flex-shrink:0}
.wb-t{font-size:14px;font-weight:600;color:var(--warn);margin-bottom:4px}
.wb-b{font-size:12.5px;color:var(--warn);opacity:.85;line-height:1.55}
.wb-meta{font-size:11.5px;color:var(--warn);opacity:.6;margin-top:5px;font-family:var(--mono)}
.manual-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px;flex:1;overflow:hidden;min-height:0}
.manual-panel{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--sh-sm)}
.manual-lbl{font-size:11.5px;font-weight:600;color:var(--t3);padding:11px 14px;border-bottom:1px solid var(--brd);background:#f6f9fc;flex-shrink:0;letter-spacing:.04em;text-transform:uppercase}
.manual-ph{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;color:var(--t4)}
.manual-ph svg{width:38px;height:38px;stroke:var(--t5);fill:none;stroke-width:1.2}
.manual-ph p{font-size:12.5px}
.manual-pdf{flex:1;width:100%;border:none}
.manual-json{flex:1;padding:14px;font-family:var(--mono);font-size:12.5px;color:var(--t1);line-height:1.75;overflow-y:auto;resize:none;background:transparent;border:none;outline:none;width:100%}
/* This textarea is the ONLY editable control on the 422 manual-review screen
   and had outline:none with no replacement — zero confirmation of where focus
   was, on a recovery screen (keyboard audit 2026-07-25). */
.manual-json:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:-2px}
.manual-foot{padding:11px 13px;border-top:1px solid var(--brd);display:flex;flex-wrap:wrap;gap:8px;flex-shrink:0}
/* A row with no shown button takes no room (PR-B1 round 7): Parse & continue
   hides after a save that would repeat, and its row stayed as an empty
   bordered strip under the editor. */
.manual-foot:not(:has(> :not([hidden]))){display:none}
.btn-parse{background:var(--gh);color:#fff;font-size:13px;font-weight:600;border:none;border-radius:var(--r);padding:9px 18px;transition:background 120ms}
.btn-parse:hover{background:var(--gh2)}
.btn-cancel{background:none;border:1px solid var(--brd-md);color:var(--t3);font-size:13px;border-radius:var(--r);padding:9px 14px;transition:all 100ms}
.btn-cancel:hover{border-color:var(--brd-str);color:var(--t1)}
/* Manual-review UX reframe (PR-3): retry-primary bar at the TOP of the right
   panel (border flipped to the bottom edge), the raw-JSON editor demoted into
   a collapsed advanced <details> that flex-fills only when opened. */
.manual-foot-primary{border-top:none;border-bottom:1px solid var(--brd)}
.btn-parse:disabled{opacity:.45;cursor:not-allowed}
.manual-foot .btn-parse.manual-secondary{background:var(--white);color:var(--t2);border:1px solid var(--brd-md)}
.manual-foot .btn-parse.manual-secondary:hover{background:var(--white);border-color:var(--g);color:var(--gh)}
.btn-parse:disabled:hover{background:var(--gh)}
/* `.manual-cols` is a grid, so its items stretch to the row height by default.
   That was right while the raw-JSON editor filled the right panel; after the
   PR-3 reframe collapsed it, the panel holds ~100px of content (retry bar +
   closed summary) inside a ~670px box — ~570px of dead white beside the
   document. Size the panel to its content while the editor is CLOSED, and let
   it stretch again the moment it opens and actually needs the height.
   `:has()` is universally supported (older than `::details-content` above); an
   engine without it simply keeps the previous stretched-but-empty look, which
   is cosmetic, never broken. */
.manual-panel:has(.manual-advanced:not([open])){align-self:start;max-height:100%}
.manual-advanced{flex-shrink:0;display:block;min-height:0}
.manual-advanced[open]{display:flex;flex-direction:column;flex:1}
/* Current engines wrap details content in ::details-content — without this
   rule the flex chain stops at the wrapper and the textarea collapses to its
   two-row intrinsic height (adversarial-review HIGH). Older engines ignore
   the pseudo and use the [open] rule above directly. */
.manual-advanced[open]::details-content{display:flex;flex-direction:column;flex:1;min-height:0}
/* Belt-and-braces: a usable editor even if a future engine breaks the
   pseudo-element flex chain again. */
.manual-advanced .manual-json{min-height:180px}
.manual-advanced summary{list-style:none;cursor:pointer;user-select:none;font-size:12.5px;font-weight:600;color:var(--t3);padding:12px 14px;flex-shrink:0}
.manual-advanced summary::-webkit-details-marker{display:none}
.manual-advanced summary::before{content:'▸';font-size:10px;margin-right:7px;color:var(--t4);display:inline-block;transition:transform 120ms}
.manual-advanced[open] summary::before{transform:rotate(90deg)}
.manual-advanced summary:hover{color:var(--t1)}

/* Modals */
.modal-backdrop{position:fixed;inset:0;background:rgba(10,20,36,.45);backdrop-filter:blur(5px);z-index:200;display:flex;align-items:center;justify-content:center;padding:20px}
.modal{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xl);padding:36px;width:100%;max-width:440px;box-shadow:var(--sh-xl);max-height:calc(100vh - 40px);max-height:calc(100dvh - 40px);overflow-y:auto}
.modal-t{font-size:var(--t-title);font-weight:700;color:var(--t1);letter-spacing:-.025em;margin-bottom:6px}
.modal-sub{font-size:14px;color:var(--t4);margin-bottom:26px;line-height:1.55}

/* Tax code segmented control */
.tax-seg{display:flex;gap:8px;flex-wrap:wrap}
.tax-seg-opt{flex:1 1 calc(50% - 4px);min-width:0;font-size:12.5px;font-weight:500;padding:10px 12px;border-radius:var(--r);border:1px solid var(--brd-md);color:var(--t3);background:var(--white);transition:all 120ms;text-align:left;display:flex;flex-direction:column;gap:3px}
.tax-seg-opt:hover{border-color:var(--brd-str);color:var(--t2)}
.tax-seg-opt.sel{background:var(--glo);border-color:var(--gbrd);color:var(--gh);font-weight:600;box-shadow:0 0 0 1px var(--gbrd)}
.tax-seg-opt .tso-code{font-size:13.5px;font-family:var(--mono);letter-spacing:.02em}
.tax-seg-opt .tso-lbl{font-size:10.5px;color:var(--t4)}
.tax-seg-opt.sel .tso-lbl{color:var(--gh);opacity:.75}

/* Toast */
/* Line-item header abbreviations (SKU / UOM / B/O, 2026-09-05): the tooltip is the point, not the UA's dotted underline */
th abbr[title]{text-decoration:none;border-bottom:1px dotted currentColor;cursor:help}
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#101c2b;color:#fff;font-size:13px;font-weight:500;padding:11px 20px;border-radius:var(--r-lg);z-index:1000;pointer-events:none;box-shadow:var(--sh-lg);animation:toastIn 180ms ease;max-width:90vw}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%,0)}}

/* Auth modal (PR A — login two-step) */
.auth-error{background:var(--fail-bg);border:1px solid var(--fail-brd);color:var(--fail);font-size:12.5px;line-height:1.55;padding:11px 14px;border-radius:var(--r);margin-bottom:18px}
.auth-otp-hint{font-size:13.5px;color:var(--t3);line-height:1.55;margin-bottom:20px}
.auth-otp-hint strong{color:var(--t2);font-weight:600}
/* "Resend code" — a link-styled button inline in the OTP hint (a real link
   would imply navigation; this re-fires the send). Disabled = the 30s client
   cooldown in auth.js authResendCode. */
.auth-resend{background:none;border:none;padding:0;font:inherit;font-weight:600;color:var(--gh);cursor:pointer}
.auth-resend:hover{text-decoration:underline}
.auth-resend:disabled{color:var(--t4);cursor:default;text-decoration:none}
.auth-foot{font-size:11.5px;color:var(--t4);margin-top:16px;text-align:center;line-height:1.55}
.auth-foot a{color:var(--gh);text-decoration:none;font-weight:600}
.auth-foot a:hover{text-decoration:underline}
.auth-terms{font-size:11.5px;color:var(--t4);margin-top:14px;text-align:center;line-height:1.55}
.auth-terms a{color:var(--gh);text-decoration:none;font-weight:600}
.auth-terms a:hover{text-decoration:underline}
.flbl-opt{color:var(--t4);font-weight:400}
.mkt-static .flbl{font-size:13.5px;font-weight:500;color:var(--t2);letter-spacing:0;text-transform:none}

/* Owner-only access-request review modal (Wave 0b) */
.ar-error{background:var(--fail-bg);border:1px solid var(--fail-brd);color:var(--fail);font-size:12.5px;line-height:1.55;padding:11px 14px;border-radius:var(--r);margin-bottom:16px}
.ar-empty{padding:24px;text-align:center;color:var(--t4);font-size:13px}
.ar-list{display:flex;flex-direction:column;gap:10px}
.ar-list-decided{margin-top:8px}
.ar-decided-h{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--t4);font-weight:600;margin:20px 0 4px}
.ar-row{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:14px 16px;border:1px solid var(--brd-md);border-radius:var(--r);background:var(--white)}
.ar-row-done{opacity:.7}
.ar-row-main{min-width:0;flex:1}
.ar-row-who{font-size:13.5px;color:var(--t2);font-weight:500;word-break:break-word}
.ar-row-note{font-size:12.5px;color:var(--t3);line-height:1.5;margin-top:4px;word-break:break-word}
.ar-row-date{font-size:11.5px;color:var(--t4);margin-top:6px}
.ar-row-actions{display:flex;flex-direction:column;gap:8px;flex-shrink:0}
.ar-row-actions .btn-primary,.ar-row-actions .btn-secondary{padding:7px 16px;font-size:12.5px;width:auto}
.ar-row-status{font-size:12px;font-weight:600;text-transform:capitalize;flex-shrink:0}
.ar-status-approved{color:var(--ok-text)}
.ar-status-declined{color:var(--t4)}

/* ── Lead forms (Contact + Book-a-demo): inline field errors + honeypot ── */
.field-err{color:var(--fail);font-size:12px;line-height:1.45;margin-top:5px}
.finput-invalid{border-color:var(--fail-brd)}
.finput-invalid:focus{border-color:var(--fail);box-shadow:0 0 0 3px var(--fail-bg)}
/* A money cell whose text is not a figure (extract.js A.invalidMoneyFields,
   F-10): the underline goes red and stays red on focus, and Save is blocked
   until it reads as a figure. Same tokens as .finput-invalid. */
.field-val--invalid,.tbl-inp--invalid{border-bottom-color:var(--fail);background:var(--fail-bg);color:var(--fail)}
.field-val--invalid:focus,.tbl-inp--invalid:focus{border-bottom-color:var(--fail)}
/* Honeypot: visually hidden off-screen (not display:none — some bots skip
   display:none fields). No inline styles; design-token file owns this. */
.lead-hp{position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}

/* ── Leads owner-review surface (.ld-*, cloned from the .ar-* family) ──── */
.ld-error{background:var(--fail-bg);border:1px solid var(--fail-brd);color:var(--fail);font-size:12.5px;line-height:1.55;padding:11px 14px;border-radius:var(--r);margin-bottom:16px}
.ld-empty{padding:24px;text-align:center;color:var(--t4);font-size:13px}
.ld-list{display:flex;flex-direction:column;gap:10px}
.ld-list-done{margin-top:8px}
.ld-done-h{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--t4);font-weight:600;margin:20px 0 4px}
.ld-row{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:14px 16px;border:1px solid var(--brd-md);border-radius:var(--r);background:var(--white)}
.ld-row-handled{opacity:.7}
.ld-row-main{min-width:0;flex:1}
.ld-row-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.ld-row-email{font-size:13.5px;color:var(--t2);font-weight:500;word-break:break-word}
.ld-kind{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:2px 8px;border-radius:var(--r-xs);flex-shrink:0}
.ld-kind-demo{color:var(--gh);background:var(--glo);border:1px solid var(--ok-brd)}
.ld-kind-contact{color:var(--t3);background:var(--bg);border:1px solid var(--brd)}
.ld-row-detail{font-size:12.5px;color:var(--t3);line-height:1.5;margin-top:4px;word-break:break-word}
.ld-row-k{color:var(--t4);font-weight:600}
.ld-row-msg{font-size:12.5px;color:var(--t3);line-height:1.5;margin-top:6px;word-break:break-word}
.ld-row-date{font-size:11.5px;color:var(--t4);margin-top:6px}
.ld-row-actions{display:flex;flex-direction:column;gap:8px;flex-shrink:0}
.ld-row-actions .btn-secondary{padding:7px 16px;font-size:12.5px;width:auto}
.ld-row-status{font-size:12px;font-weight:600;color:var(--t4);flex-shrink:0}

/* ── Team screen (.tm-*, PR-4 — cloned from the .ar-* family) ──────────── */
.tm-seats{margin-bottom:16px}
.tm-seats-line{font-size:13px;color:var(--t2);font-weight:600}
.tm-seats-limit{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:10px;background:var(--warn-bg);border:1px solid var(--warn-brd);color:var(--warn);font-size:12.5px;line-height:1.55;padding:11px 14px;border-radius:var(--r)}
.tm-seats-limit .btn-primary{padding:7px 16px;font-size:12.5px;width:auto;flex-shrink:0}
.tm-form{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}
.tm-form .finput{flex:1;min-width:200px}
.tm-form .fselect{width:auto;flex-shrink:0}
.tm-form .btn-primary{padding:10px 20px;flex-shrink:0}
.tm-section-h{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--t4);font-weight:600;margin:20px 0 8px}
.tm-row .ar-row-actions{flex-direction:row;align-items:center}
.tm-role-select{width:auto;padding:7px 10px;font-size:12.5px}
.tm-role-lbl{font-size:12px;font-weight:600;color:var(--t4);text-transform:capitalize}
.tm-you{color:var(--t4);font-weight:400}
.tm-row-invite{border-style:dashed}

/* ── Security screen (MFA enrolment UI) — two small tokens; everything else
   reuses the owner-card/team/modal families. The QR is an <img> over a
   data: URI (never inline SVG markup — see security.js's QR rule). */
.mfa-qr{width:180px;height:180px;max-width:100%;border:1px solid var(--brd);border-radius:8px;background:#fff;display:block;margin:10px 0}
.mfa-secret{font-family:var(--mono);font-size:12.5px;color:var(--t2);background:var(--bg);border:1px solid var(--brd);border-radius:var(--r);padding:8px 12px;margin:6px 0;user-select:all;word-break:break-all}

/* ── Workspace chip + account menu (PR-4; sidebar-footer home since round 5;
   chip-pill restyle round 6; CUSTOM panel round 7) — the founder liked the
   prod account chip's anatomy (avatar initials + name + caret in a rounded
   pill) but called the native <select> popup "basic", so the chip is now a
   real <button> opening a styled panel ABOVE it: workspaces with a check on
   the active one, a divider, then Sign out (in-menu by founder call, round
   7 — the email/plan line below is gone). orgswitcher.js owns fill/open/
   close/Esc/outside-click in the SPA; mktshell.js hydrates the SAME chip on
   the static shells (2026-07-24 — the injected top-right acct-menu is gone
   with its CSS: one account surface, every shell). ── */
.org-menu-wrap{position:relative}
.org-pill{display:flex;align-items:center;width:100%;box-sizing:border-box;gap:8px;background:rgba(255,255,255,.04);border:1px solid var(--sb-brd);border-radius:999px;padding:5px 10px 5px 6px;cursor:pointer;transition:border-color 120ms,background 120ms;font:inherit;text-align:left;color:inherit}
.org-pill:hover{background:var(--sb-hover)}
/* var(--sb-active) is a ~13%-alpha wash against the dark rail — too faint to
   be the sole focus signal on the control that opens the workspace switcher
   AND Sign out (T2.21). The halo stays; a real outline goes back on top. */
.org-pill:focus-visible{outline:2px solid var(--sb-accent);outline-offset:2px;border-color:var(--sb-accent);box-shadow:0 0 0 3px var(--sb-active)}
.org-pill[aria-expanded="true"]{border-color:var(--sb-accent);background:var(--sb-hover)}
.org-pill-avatar{flex:0 0 auto;width:24px;height:24px;border-radius:50%;background:var(--sb-active);color:var(--sb-accent);display:inline-flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:700;letter-spacing:.02em}
.org-pill-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:600;color:#f1f5f9}
.org-pill-caret{width:14px;height:14px;stroke:var(--sb-text-dim);fill:none;stroke-width:2;flex:0 0 auto;pointer-events:none}
/* The panel: anchored ABOVE the chip (the footer sits at the viewport
   bottom), same dark-navy family as the rail, elevated. */
/* max-height + own scroll (review HIGH): .sb clips overflow, so an unbounded
   panel would silently CUT OFF the top workspaces for a many-org practice —
   the feature's own target user. Same near-invisible thumb as .sb-body. */
.org-menu{position:absolute;bottom:calc(100% + 8px);left:0;right:0;background:#1b2740;border:1px solid rgba(255,255,255,.12);border-radius:12px;padding:6px;box-shadow:0 10px 30px rgba(5,12,25,.55),0 2px 8px rgba(5,12,25,.4);z-index:40;max-height:min(320px,55vh);overflow-y:auto}
.org-menu::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14)}
@supports not selector(::-webkit-scrollbar){
  .org-menu{scrollbar-color:rgba(255,255,255,.14) transparent;scrollbar-width:thin}
}
.org-menu-item{display:flex;align-items:center;gap:9px;width:100%;box-sizing:border-box;background:none;border:none;border-radius:8px;padding:8px 10px;cursor:pointer;font:inherit;font-size:12.5px;font-weight:500;color:var(--sb-text);text-align:left;transition:background 120ms,color 120ms}
.org-menu-item:hover{background:var(--sb-hover);color:#f1f5f9}
/* Keyboard focus needs its OWN mark here: the hover tint is a 7%-alpha wash
   on navy, and this menu is the one place in the app where arrow keys are the
   intended way to move (orgswitcher/menukeys roving focus) — an indicator
   identical to hover left that motion invisible (keyboard audit 2026-07-25). */
.org-menu-item:focus-visible{outline:2px solid var(--sb-accent);outline-offset:-2px;background:var(--sb-hover);color:#f1f5f9}
.org-menu-item.active{color:#f1f5f9;font-weight:600}
.org-menu-check{flex:0 0 auto;width:15px;height:15px;display:inline-flex;align-items:center;justify-content:center}
.org-menu-check svg{width:14px;height:14px;stroke:var(--sb-accent);fill:none;stroke-width:2.4}
.org-menu-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.org-menu-sep{margin:6px 4px;border-top:1px solid rgba(255,255,255,.10)}
.org-menu-signout{color:var(--sb-text-dim)}
.org-menu-signout:hover,.org-menu-signout:focus-visible{color:#fff}

/* ── APP CALM (2026-09-24): the light rail ───────────────────────────────
   One rule for the workspace (founder, 2026-09-24): white is for the thing
   you are working on, and everything else sits on the tint. So the rail
   and, on tool screens, the topbar take the canvas's own --bg: only the
   record, the tables and the cards are white. The --sb-* tokens are
   re-declared ON .sb,
   so the rail, its workspace chip and the chip's menu read light, while
   anything outside .sb that borrows :root's navy keeps it. The literal
   near-white colours overridden below were written for the navy rail. It
   sits after the chip and menu rules so it wins their ties by source order;
   the public drawer (MOBILE NAV, end of file) sets layout only, so it
   inherits the light rail too. */
.sb{--sb-bg:var(--bg);--sb-text:#33445a;--sb-text-dim:#5c6e84;--sb-accent:#047857;--sb-hover:rgba(14,26,40,.05);--sb-active:rgba(5,150,105,.09);--sb-brd:var(--brd);border-right:1px solid var(--brd);box-shadow:none}
/* The active entry's green on the green wash over the tint is 4.42:1, under
   AA for 14px text; one step darker is 6.19:1. */
.sb .nav-item.active,.sb .tool-item.active{color:#065f46}
:is(html[data-nd-deeplink], body:not(.nd-mkt):not(.mktd)) .topbar{background:var(--bg);box-shadow:none}
/* On that tint: the chip naming the open document is the thing you are
   working on, so it is white (its 10px meta line is 4.78:1 there, 4.25:1 on
   the tint); and the save line's amber, 4.47:1 on the tint, takes the status
   strip's deeper amber. */
.topbar .file-chip{background:var(--white)}
:is(html[data-nd-deeplink], body:not(.nd-mkt):not(.mktd)) .topbar .save-indicator.save-dirty{color:#92400e}
.sb .sb-body::-webkit-scrollbar-thumb,.sb .org-menu::-webkit-scrollbar-thumb{background:rgba(14,26,40,.16)}
@supports not selector(::-webkit-scrollbar){.sb .sb-body,.sb .org-menu{scrollbar-color:rgba(14,26,40,.16) transparent}}
.sb .wordmark{color:var(--t1)}
.sb .sb-toggle:hover,.sb .nav-item:hover,.sb .tool-item:hover{color:var(--t1)}
.sb .sb-section-lbl{font-size:12px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--t3)}
.sb .tool-item svg{color:currentColor;opacity:.7}
.sb .tool-item.active svg,.sb .nav-item.active svg{opacity:1}
.sb .tool-badge{background:var(--white);color:var(--t2);border-color:var(--brd)}
.sb .tool-badge-lock{background:transparent;color:var(--t3)}
.sb .org-pill{background:var(--white)}
.sb .org-pill-name{color:var(--t1)}
.sb .org-menu{background:var(--white);border-color:var(--brd);box-shadow:0 10px 30px rgba(13,28,46,.14),0 2px 8px rgba(13,28,46,.08)}
.sb .org-menu-item:hover,.sb .org-menu-item:focus-visible,.sb .org-menu-item.active{color:var(--t1)}
.sb .org-menu-sep{border-top-color:var(--brd)}
.sb .org-menu-signout:hover,.sb .org-menu-signout:focus-visible{color:var(--t1)}

/* ── Credit-estimate note (E5, PR-4) — quiet, advisory-only ────────────── */
.credit-est{font-size:11.5px;color:var(--t4)}
#creditEstNote{margin-right:auto;align-self:center}

/* ── Owner screens (Plan & billing / Access requests / Leads) ─────────────
   The three surfaces converted from modals to real tool screens (2026-07-07).
   .owner-pane caps the content width so review cards don't stretch across a
   full-bleed screen; .owner-card is the white body card the account screen
   renders into (the .ar-row/.ld-row lists are cards of their own). */
.owner-pane{max-width:760px}
.owner-pane-narrow{max-width:560px}
.owner-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:20px 22px;box-shadow:var(--sh-xs)}
.owner-card .ar-empty{padding:12px 0}

/* ── Plan & billing body (.acct-*, PR-3 Task 12) ──────────────────────────
   Reuses .history-pill (status), .bi-bar-* (usage meter) and the button
   tokens; these classes only handle the screen-body layout. */
.acct-plan-row{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.acct-plan-name{font-size:15px;font-weight:700;color:var(--t1);letter-spacing:-.01em}
.acct-usage{margin:4px 0 14px}
.acct-usage .bi-bar-row{margin-bottom:6px}
.acct-usage-lbl{font-size:12.5px;color:var(--t3);line-height:1.5}
.acct-usage-avail{font-size:14px;font-weight:600;color:var(--t1);line-height:1.4;margin-bottom:6px}
.acct-usage-lbl strong{color:var(--t1);font-weight:600}
.acct-note{font-size:12px;color:var(--t4);line-height:1.55;margin-top:10px}
.acct-actions{display:flex;flex-direction:column;gap:8px;margin-top:16px}
/* Auto top-up (2026-08-11) — a SETTING on the Plan & billing screen, so it
   reads as a quiet block below the actions rather than another CTA. Divider
   above, no tint: nothing here is a warning. */
.acct-autotopup{margin-top:20px;padding-top:16px;border-top:1px solid var(--brd)}
.acct-at-head{font-size:13px;font-weight:600;color:var(--t1);margin-bottom:6px}
.acct-at-form{margin-top:14px;display:flex;flex-direction:column;gap:6px}
.acct-at-lbl{font-size:12.5px;color:var(--t2);margin-top:8px}
.acct-at-form .finput{max-width:110px;display:inline-block;margin-right:6px}
/* [hidden] must win over the author display above — the .appr-reject-form
   lesson (#165): an author display rule beats the UA [hidden] rule, so the
   form would render for everyone the moment it gained a flex display. */
.acct-at-form[hidden],#autoTopupForm[hidden]{display:none}

/* In-app plan picker (billing.js, 2026-09-20, audit F-5): one .modal over
   the four tiers. Radio + name + meta per option; the current tier is
   marked and inert; the sentence under the list is the server's real
   preview figure. Reuses the .modal shell + the modal-actions grammar. */
.plan-picker{max-width:480px}
.pp-list{display:flex;flex-direction:column;gap:8px;margin:4px 0 14px}
.pp-opt{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border:1px solid var(--brd);border-radius:var(--r-lg);cursor:pointer;background:var(--white)}
.pp-opt:hover{border-color:var(--brd-md)}
.pp-opt:has(input:checked){border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.pp-opt:has(input:focus-visible){outline:2px solid var(--g);outline-offset:2px}
.pp-opt.is-current{cursor:default;background:var(--bg);color:var(--t3)}
/* F-5 round 2: the current plan is a LIVE choice while a change is scheduled (the revert) */
.pp-opt.is-current.is-revertable{cursor:pointer}
.pp-opt.is-current.is-revertable .pp-name{color:var(--t1)}
.pp-opt input{margin-top:3px;accent-color:var(--g);flex:none}
.pp-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.pp-name{font-size:14px;font-weight:700;color:var(--t1);letter-spacing:-.01em}
.pp-opt.is-current .pp-name{color:var(--t3)}
.pp-tag{display:inline-block;font-size:11px;font-weight:600;color:var(--t3);background:var(--bg);border:1px solid var(--brd);border-radius:999px;padding:1px 8px;margin-left:6px;vertical-align:middle}
.pp-meta{font-size:12.5px;color:var(--t3);line-height:1.45}
.pp-line{font-size:13px;color:var(--t2);line-height:1.5;min-height:1.5em}
.pp-line:empty{display:none}
#planPickerErr{margin-top:8px}

/* One modal footer grammar (replaces the six hand-rolled inline-style rows):
   stacked full-width by default, --row for side-by-side equal pairs. */
/* Notice/confirm modal (notice.js) — the action-outcome layer. Reuses the
   .modal shell; the tone bar is the one new element. Message text preserves
   the \n\n paragraphing the old native confirm() copy carried. */
.notice-modal{max-width:420px}
.notice-msg{white-space:pre-line;margin-bottom:0}
.notice-tone{height:3px;border-radius:999px;margin-bottom:18px}
.notice-tone--ok{background:var(--g)}
.notice-tone--warn{background:var(--warn)}
.notice-tone--error{background:var(--fail)}
/* Danger confirm button — red in EVERY state. The rest rule alone lost the
   cascade on hover (.btn-secondary:hover's green, one pseudo-class higher —
   the #165 state-pair class), so hover and focus are doubled-selector pinned:
   a destructive action never shows the brand green (prod UAT round 5). */
.btn-secondary.notice-danger{color:var(--fail);border-color:var(--fail)}
.btn-secondary.notice-danger:hover{color:var(--fail);border-color:var(--fail);background:var(--fail-bg)}
.btn-secondary.notice-danger:focus-visible{outline:2px solid var(--fail);outline-offset:2px}
.modal-actions{display:flex;flex-direction:column;gap:8px;margin-top:16px}
.modal-actions .btn-primary,.modal-actions .btn-secondary{width:100%}
.modal-actions--row{flex-direction:row}
.modal-actions--row .btn-primary,.modal-actions--row .btn-secondary{flex:1;width:auto}
/* Quiet under-field hint (the .acct-note scale) — one component for the
   Sage/Xero per-supplier memory notes. */
.fhint{font-size:11px;color:var(--t4);margin-top:4px;line-height:1.55}
/* Advisory note inside a modal field group: softer than .field-err (which is
   a validation failure), louder than .fhint. Used by the export modals to
   flag a tax code the document disagrees with (G12e). */
.fnote{font-size:11.5px;color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-brd);border-radius:var(--r);padding:7px 9px;margin-top:6px;line-height:1.5}
.acct-actions .btn-primary,.acct-actions .btn-secondary{width:100%}
.acct-plans-link{align-self:flex-start;font-size:12.5px;font-weight:600;color:var(--gh);background:transparent;border:none;padding:4px 0;cursor:pointer;border-radius:var(--r)}
.acct-plans-link:hover{color:var(--gh);text-decoration:underline}
.acct-plans-link:hover{text-decoration:underline}

/* Extraction history (PR B) — flows naturally; the parent .app-screen owns the
   scroll now (see the #tool-*{overflow-y:auto} block), so a wheel anywhere over
   the screen scrolls it instead of only inside a fixed-height box. min-height
   keeps a short list/detail filling the viewport (footer band stays at bottom). */
.history-screen{padding:28px 32px;min-height:100%;box-sizing:border-box}
.history-empty{padding:32px;text-align:center;color:var(--t4);font-size:13px}
.history-truncated{font-size:11.5px;color:var(--t4);text-align:center;margin-top:4px}
.history-date{color:var(--t3);white-space:nowrap}
.history-supplier{color:var(--t2);font-weight:500;max-width:280px}
.hist-sup-wrap{display:flex;align-items:center;gap:10px;min-width:0}
.hist-sup-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* Supplier initial-avatars — deterministic tint per supplier (hist-av-0..5) */
.hist-av{width:28px;height:28px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:700;letter-spacing:.02em;flex-shrink:0}
.hist-av-0{background:rgba(5,150,105,.10);color:#047857;border:1px solid rgba(5,150,105,.22)}
.hist-av-1{background:rgba(21,97,158,.10);color:#15619e;border:1px solid rgba(21,97,158,.22)}
.hist-av-2{background:rgba(124,58,237,.08);color:#6d28d9;border:1px solid rgba(124,58,237,.2)}
.hist-av-3{background:rgba(180,83,9,.09);color:#b45309;border:1px solid rgba(180,83,9,.2)}
.hist-av-4{background:rgba(13,148,136,.09);color:#0f766e;border:1px solid rgba(13,148,136,.22)}
.hist-av-5{background:rgba(190,24,93,.07);color:#be185d;border:1px solid rgba(190,24,93,.18)}
.history-pill{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;font-family:var(--mono);padding:3px 11px;border-radius:999px;border:1px solid transparent}
.history-pill-dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex-shrink:0;background:currentColor}
.history-pill--ok{color:var(--ok-text);background:var(--ok-bg);border-color:var(--ok-brd)}
.history-pill--warn{color:var(--warn);background:var(--warn-bg);border-color:var(--warn-brd)}
.history-pill--fail{color:var(--fail);background:var(--fail-bg);border-color:var(--fail-brd)}
/* Neutral/informational pill (beta/comp/paused/no-subscription states on the
   Plan & billing modal + Admin screen — PR-3/PR-5). Same anatomy, muted tokens. */
.history-pill--muted{color:var(--t4);background:var(--bg);border-color:var(--brd)}
.history-pill--ui{font-family:var(--ui)}
/* Per-row View/Delete buttons removed 2026-08-08 (row-as-affordance) —
   their .history-actions/.history-act/.history-del rules went with them. */
.hist-row-nav{cursor:pointer}
.hist-unreadable{color:var(--t3);font-style:italic;font-weight:400}
.batch-row-nav{cursor:pointer}

/* ── History filter toolbar — a toggleable <thead> row-group so the search
   controls are REAL table cells sharing the column solver with the labels and
   data. With auto-sized columns, same-table cells are the ONLY robust way to
   land a search box truly centred over its column (a detached flex/grid row
   drifts the instant the widest supplier name / total changes). Row 1 =
   controls (full-width colspan cell: chips left, scope tabs right); row 2 =
   searches aligned per column. ── */

/* #historyFilterRow is a <thead> now — display:none/'' still toggles the whole
   group as one unit. It must NOT inherit any flex/block display or the UA
   table-header-group is lost and the column sharing collapses; keep it a plain
   row group and only paint it white (the label thead keeps the tint). */
.hist-toolbar{background:var(--white);border-radius:var(--r-lg) var(--r-lg) 0 0}
.hist-toolbar > tr > td,
.hist-toolbar > tr > th{background:var(--white);border-bottom:none}
.hist-toolbar-spacer{flex:1}

/* Row 1 — controls bar inside the full-width colspan cell. Reset the uppercase
   label treatment the shared th/td rules could impose; chips left, tabs right. */
.hist-tb-controls-cell{padding:10px 12px;text-transform:none;letter-spacing:normal}
.hist-tb-controls-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.hist-chip-row{display:inline-flex;gap:6px}
.hist-chip{font-size:11.5px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd-md);border-radius:999px;padding:5px 11px;cursor:pointer;transition:all 120ms;white-space:nowrap}
.hist-chip:hover{border-color:var(--g);color:var(--gh)}
/* The chip cluster may wrap once the Clear button joins it at narrow widths —
   without this the inline-flex run overflows its table cell (review NIT). */
.hist-chip-row{flex-wrap:wrap}
/* "Clear filters (N)" — deliberately QUIETER than the chips (text-only, no
   border/fill): its presence is the signal, not its weight. history.js shows
   it only while ≥1 filter is active (founder UAT 2026-07-24). */
.hist-clear-btn{font-size:11.5px;font-weight:600;color:var(--t3);background:none;border:none;border-radius:var(--r-xs);padding:5px 8px;cursor:pointer;transition:color 120ms,background 120ms;white-space:nowrap;text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--brd-str)}
.hist-clear-btn:hover{color:var(--t1);background:var(--bg);text-decoration-color:var(--t3)}
.hist-chip-active{color:var(--gh);background:var(--glo);border-color:var(--gbrd)}

/* Row 2 — search cells. These hold form controls, not labels: strip the shared
   th uppercase/letter-spacing/weight, and carry the divider under the toolbar. */
.hist-tb-search-cell{padding:8px 12px;text-transform:none;letter-spacing:normal;font-weight:400;vertical-align:middle;text-align:center;border-bottom:1px solid var(--brd)}

/* Search inputs — the auto-sized COLUMN drives the width; the box tracks it (no
   px floor that would inflate the column) and centres within its cell so it
   reads as sitting cleanly above the column, not shoved to one edge. */
.hist-search{width:100%;padding:6px 10px;font-size:12.5px;text-align:left}

/* Compact date-range preset dropdown above the narrow Invoice-date column. The
   trigger fills the cell; the panel opens absolutely-positioned (the export-menu
   idiom) so its width never widens the column. */
.hist-daterange-menu{position:relative;display:block;width:100%}
/* The Approval ▾ facet reuses this dropdown shell INSIDE the chip row —
   there it sizes to content like a chip, and the pill radius matches its
   neighbours (the 100%-width/rect look belongs to the date column only). */
.hist-chip-row .hist-daterange-menu{width:auto}
.hist-chip-row .hist-dd-toggle{width:auto;border-radius:999px;font-size:11.5px;padding:5px 11px;color:var(--t3);font-weight:600;box-shadow:none}
.hist-dd-toggle{width:100%;display:inline-flex;align-items:center;justify-content:space-between;gap:6px;background:var(--white);border:1px solid var(--brd-md);border-radius:var(--r);color:var(--t2);font-size:12.5px;font-weight:600;padding:6px 10px;cursor:pointer;transition:all 120ms;box-shadow:var(--sh-xs);white-space:nowrap}
.hist-dd-toggle:hover{border-color:var(--g);color:var(--gh)}
.hist-dd-toggle[aria-expanded="true"]{border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.hist-dd-lbl{overflow:hidden;text-overflow:ellipsis}
.hist-dd-caret{width:12px;height:12px;flex:none;stroke:currentColor;fill:none;stroke-width:2;transition:transform 120ms}
.hist-dd-toggle[aria-expanded="true"] .hist-dd-caret{transform:rotate(180deg)}
.hist-dd-panel{position:absolute;top:calc(100% + 6px);left:0;z-index:40;min-width:200px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);box-shadow:var(--sh-lg);padding:6px;display:flex;flex-direction:column;gap:2px;text-align:left}
.hist-dd-panel[hidden]{display:none}
.hist-dd-opt{text-align:left;font-size:13px;font-weight:600;color:var(--t3);background:transparent;border:1px solid transparent;border-radius:var(--r);padding:9px 12px;white-space:nowrap;cursor:pointer;transition:all 100ms}
.hist-dd-opt:hover{background:var(--bg);color:var(--t1)}
.hist-dd-opt.vc-tab-active{background:var(--glo);color:var(--gh);border-color:var(--gbrd)}
/* Custom From–To pair lives INSIDE the panel — stacked under the presets with a
   hairline separator (no margin-left:auto flex-row trick any more). */
.hist-dd-panel .hist-date-range{display:flex;align-items:center;gap:6px;margin:4px 2px 2px;padding-top:8px;border-top:1px solid var(--brd)}
.hist-date{width:130px;padding:6px 8px;font-size:12.5px}
.hist-date-sep{color:var(--t4);font-size:12px}

/* Two theads now — only the label group carries the header tint. */
.hist-head-labels{background:#f6f9fc}

/* Below ~720px per-column alignment would crush the narrow columns — so DROP
   the alignment (not the controls): the search row's cells stop being table
   cells and flow inline-block, letting the three filters wrap as a normal bar.
   The controls stay fully usable on a phone; only the wide-screen "above its
   column" affordance is sacrificed. Page body never scrolls sideways. */
@media (max-width:720px){
  .hist-toolbar .hist-tb-search{display:block}
  .hist-tb-search .hist-tb-search-cell{display:inline-block;padding:6px 12px;border-bottom:none;vertical-align:top}
  .hist-tb-search .hist-tb-search-cell:empty{display:none}
  .hist-daterange-menu,.hist-search{max-width:200px}
}
.hist-more-row{display:flex;justify-content:center;margin:14px 0 0;padding-bottom:32px} /* padding, not margin: guarantees scroll clearance under the button (it sat flush at the viewport edge — round 4) */
/* Per-invoice audit timeline (WS-C) — History detail */
.tl-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xl);padding:18px 22px;margin-top:20px;box-shadow:var(--sh-sm)}
.tl-hdr{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.tl-count{font-size:11px;font-weight:600;color:var(--t4);background:var(--bg);border:1px solid var(--brd);border-radius:999px;padding:2px 10px}
.tl-row{display:flex;gap:12px;padding:9px 0;border-top:1px solid var(--brd)}
.tl-dot{flex:none;width:9px;height:9px;border-radius:50%;margin-top:5px;background:var(--t5)}
.tl-dot.tl-ok{background:var(--g)}
.tl-dot.tl-warn{background:#d97706}
.tl-dot.tl-fail{background:#dc2626}
.tl-dot.tl-edit{background:#2563eb}
.tl-main{min-width:0;flex:1}
.tl-head{display:flex;align-items:center;gap:8px}
.tl-when{font-family:var(--mono);font-size:11px;color:var(--t4)}
.tl-badge{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;border-radius:999px;padding:1.5px 8px;background:var(--bg);color:var(--t3)}
.tl-badge.tl-ok{color:var(--gh)}
.tl-badge.tl-warn{color:#b06a08}
.tl-badge.tl-fail{color:#c2352b}
.tl-badge.tl-edit{color:#2563eb}
.tl-title{font-size:13px;font-weight:600;color:var(--t1);margin-top:2px}
.tl-body{font-size:12px;color:var(--t3);margin-top:2px;line-height:1.5}
.tl-change{font-size:12px;color:var(--t3);margin-top:2px}
.tl-change s{color:var(--t4)}
.tl-change b{font-family:var(--mono);font-weight:600;color:var(--t1)}
.tl-trunc{font-size:11.5px;color:var(--t4);border-top:1px dashed var(--brd);margin-top:10px;padding-top:8px}
.tl-field{font-weight:600;color:var(--t2)}
.tl-more{color:var(--t4);font-style:italic}

/* History LIST card opts out of the shared .table-card clipping so the per-group
   Export ▾ dropdown (an absolutely-positioned child of a row cell) isn't cut off
   by overflow-y:hidden. The 6-column list fits without the x-scroll the wide
   line-items detail table needs, so visible is safe here only. */
.hist-list-card{overflow:visible}

/* Batch grouping (Note C) — a collapsible cluster styled as one distinct unit
   with NEUTRAL chrome (a slate spine, a soft grey band, top/bottom hairlines).
   Deliberately not emerald: green reads as "all-clean", a status the cluster
   itself must not imply — colour is reserved for the compliance pills. */
.hist-group-head>td{padding:0;background:var(--bg);border-top:1px solid var(--brd-md)}
.hist-group-head>td:first-child{box-shadow:inset 4px 0 0 var(--brd-str)}
.hist-group{display:flex;align-items:center;gap:10px;padding:13px 16px;flex-wrap:wrap}
.hist-group-toggle{display:inline-flex;align-items:center;gap:9px;background:none;border:none;cursor:pointer;color:var(--t1);font-size:13.5px;font-weight:600;padding:2px;min-width:0;flex:0 1 auto}
.hist-group-caret{width:15px;height:15px;color:var(--t3);transition:transform 140ms;flex-shrink:0}
.hist-group-open .hist-group-caret{transform:rotate(90deg)}
.hist-group-ic{width:16px;height:16px;color:var(--t3);flex-shrink:0}
.hist-group-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Neutral, factual count pill — the SPLIT lives in the coloured status pill next to it. */
.hist-group-count{font-family:var(--ui);font-size:11.5px;font-weight:600;color:var(--t2);background:var(--white);border:1px solid var(--brd-md);border-radius:999px;padding:3px 10px;white-space:nowrap;flex-shrink:0}
.hist-group-sub{font-size:11px;color:var(--t3)}
/* Export ▾ sits in the Actions column, aligned with the rows' View/Delete. */
.hist-group-actions{vertical-align:middle;text-align:center;padding:8px 12px}
.hist-group-exp-toggle{padding:6px 12px;font-size:11.5px}
/* Right-align the group Export ▾ menu so it opens leftward and can't clip past
   the table-card's right edge (the bottom-bar default opens left → off-screen). */
.hist-group-exp-menu{left:auto;right:0}
/* Every down-opening dropdown inside the topbar right-anchors for the same
   reason — the toggles sit near the viewport's right edge (round 5: Extract's
   Export ▾ + the History-detail Export ▾ moved up here; Batch's benefits too). */
#topbar .export-dropdown-down{left:auto;right:0}
.hist-group-member>td{background:var(--white)}
.hist-group-member>td:first-child{box-shadow:inset 4px 0 0 var(--brd-str)}
.hist-group-member-last>td{border-bottom:1px solid var(--brd-md)}
.hist-group-member[hidden]{display:none}
/* Duplicate-flagged member keeps its amber tint even with the slate spine. */
.hist-group-member.batch-row-dup>td{background:var(--warn-bg)}

/* History summary band (round 2) — count-up stats + 8-week sparkline */
.hist-stats{display:grid;grid-template-columns:repeat(4,1fr) 1.35fr;gap:14px;margin:4px 0 18px}
.hist-stats:empty{display:none}
.hist-stat{position:relative;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:16px 18px;box-shadow:var(--sh-xs);min-width:0;transition:box-shadow 160ms,transform 160ms}
.hist-stat:hover{box-shadow:var(--sh-sm);transform:translateY(-1px)}
/* (hover lift lives with each tile family — .hist-stat/.bi-stat/.batch-stat-cell) */
.hist-stat-val{font-family:var(--mono);font-size:24px;font-weight:500;color:var(--t1);letter-spacing:-.02em;line-height:1.1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Wraps, never an ellipsis (audit 2026-09-26, PR-H): the Total label carries notes such as
   "· 1 other currency · 2 duplicates left out · shown so far" (measured 331px of text in a
   174px label at 1440px wide). */
.hist-stat-lbl{font-size:11px;color:var(--t3);margin-top:6px;line-height:1.35;white-space:normal}
/* Phones (audit 2026-09-26, PR-H round 2): three tiles to a row left the money tile's label 54px
   wide at 390px, nine lines tall, and its value clipped. Labels wrap at word boundaries only; the
   money tile's own row is in the <= 1100px block below the band (round 4: from 561 to 1100px the
   band had an empty grey cell beside it). Scoped to #batchInsights: the admin overview shares
   .bi-stats.
   Money readable at every width (audit 2026-09-26, PR-H round 4, measured 320 to 1440px in
   tests/e2e/test_stat_labels_wrap.py). A seven-figure value and a sign ("−£1,234,567.89", 195px at
   24px) was clipped even at 1440 (a 174px box). A money value now scales with its tile through
   container query units, never below 15px and never above the 24px it always had; the other values
   keep 24px. Batch insights run two columns wherever the band would be too narrow for four, one on a
   phone. Phones trim the screen, panel and tile padding (the History tiles sit three to a 236px row at
   320px), and the History labels step down a size at <= 360px so "Extractions" fits its tile whole.
   The admin overview's labels may break a token that has no break of its own (a follow-up's error
   code, "PaddleError:subscription_update_when_past_due"). */
/* 11cqi, not 12: the History Total subtracts credit notes, so it can carry a minus sign, and at 12cqi
   "-" plus seven figures ran 2px over its 1440px tile. */
.hist-stat,#batchInsights .bi-stat{container-type:inline-size}
.hist-stat-val[data-cu-fmt="money"],#biTotalSpend,#biVatTotal{font-size:clamp(15px,11cqi,24px)}
#adminStats .bi-stat-lbl{overflow-wrap:anywhere}
/* The admin overview's VALUES too (PR-H round 5): counts and seven-figure money scale with their
   tile like the History and batch money values, the band runs three columns above a phone, three
   rows of three (six were 82px wide at 1024 and left three empty cells above 1180px), and two on a phone, where the MRR and revenue tiles take a row each, and so does
   so the ten fill it with no empty cell (rounds 6 and 8). */
#adminStats .bi-stat{container-type:inline-size}
#adminStats .bi-stat-money .bi-stat-val{font-size:clamp(13px,12cqi,24px)}   /* money only: counts keep 24px (round 6) */
#adminStats{grid-template-columns:repeat(3,1fr);grid-auto-flow:dense}   /* three columns at every width above a phone. Ten tiles since #439's Refund-changes-owed tile: the two money tiles span two columns, so the twelve cells fill four rows of three with no empty cell (nine tiles in three columns and six in six left holes before; six clipped seven figures at 1104 to 1118px, round 6) */
#adminStats .bi-stat-money{grid-column:span 2}
@media (max-width:560px){#adminStats{grid-template-columns:repeat(2,1fr)}#adminStats .bi-stat-money{grid-column:1/-1}#adminStats .bi-stat{padding:14px 10px}}
@media (max-width:1100px){#batchInsights .bi-stats{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){#batchInsights .bi-stats{grid-template-columns:1fr}.history-screen,.batch-screen{padding-left:16px;padding-right:16px}.batch-insights{padding:18px 14px}.hist-stat{padding:14px 10px}}
@media (max-width:360px){.hist-stat-lbl{font-size:10.5px}}
.hist-stat-spark{display:flex;flex-direction:column;justify-content:flex-end}
.hist-spark{width:100%;height:32px;display:block}
.hist-spark-bar{fill:var(--g);opacity:.85;transform-box:fill-box;transform-origin:bottom;animation:sparkGrow 480ms cubic-bezier(.25,.8,.35,1) both;animation-delay:calc(var(--st,0)*45ms)}
.hist-spark-bar-zero{fill:var(--brd-md)}
@keyframes sparkGrow{from{transform:scaleY(0)}}
/* 1180px, not 1100 (PR-H round 6, the refuter's sweep): from 1101 to 1160px the five-column band
   clipped a seven-figure Total (122px in a 110 to 121px box). */
@media (max-width: 1180px){.hist-stats{grid-template-columns:repeat(3,1fr)}.hist-stat-spark{grid-column:span 3}.hist-stats>.hist-stat:nth-child(4){grid-column:1/-1}}
@media (prefers-reduced-motion: reduce){.hist-spark-bar{animation:none}.hist-stat{transition:none}}

/* Polished empty state (inside the colspan cell) */
.hist-empty-wrap{display:flex;flex-direction:column;align-items:center;gap:7px;padding:36px 16px}
.hist-empty-wrap svg{width:32px;height:32px;stroke:var(--t5);fill:none;stroke-width:1.4;margin-bottom:3px}
.hist-empty-t{font-size:14.5px;font-weight:600;color:var(--t2)}
.hist-empty-s{font-size:12.5px;color:var(--t4);max-width:380px;line-height:1.6}
/* Read-only History detail (PR B-rework) — dedicated panel, never the Extract surface */
/* (.history-view-banner retired — the detail view opens on an object header.) */
.history-detail-head{margin-bottom:14px}
.history-detail-head .hdd-title{display:flex;align-items:center;gap:10px;margin-bottom:3px}
.history-detail-head .hdd-sub{margin-bottom:0}
.ro-pill{font-size:10.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--t4);background:var(--bg);border:1px solid var(--brd);border-radius:999px;padding:3px 10px;flex-shrink:0}
/* Read-only field/line inputs: same look as editable, minus the edit affordance */
.field-val--readonly{cursor:default}
/* Mouse focus stays mark-free — a read-only field must not grow the green
   "you can type here" underline. */
.field-val--readonly:focus{border-bottom-color:transparent}
/* KEYBOARD focus must still be visible. These inputs became tab-reachable on
   2026-07-25 (their text truncates, so unfocusable put the tail out of reach)
   — and the rule above meant the only remaining mark was the --glo halo at
   1.10:1 against the card, i.e. ~200 invisible tab stops on the History
   detail. Measured, review 2026-07-25. Later in the file than
   .field-val:focus-visible / .tbl-inp:focus-visible (same specificity), so it
   wins on order; covers the read-only line-item cells too. */
.field-val--readonly:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:1px;box-shadow:none;border-radius:2px}
.history-detail-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.history-legend{display:inline-flex;align-items:center;gap:14px;font-size:11.5px;color:var(--t4)}
.history-legend-item{display:inline-flex;align-items:center;gap:5px}
.history-detail-actions{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}
.history-detail-exports{display:inline-flex;align-items:center;gap:8px}
.history-pdf-note{font-size:12px;color:var(--t4);line-height:1.55;margin-top:16px;padding:11px 15px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r)}

/* Edit persistence — Save button + indicator in the Extract bottom bar (PR B-rework) */
.save-indicator{font-size:11.5px;font-weight:600;white-space:nowrap}
.save-indicator.save-dirty{color:var(--warn)}
.save-indicator.save-busy{color:var(--t3)}
.save-indicator.save-ok{color:var(--ok-text)}
/* F-10: "Fix the highlighted figure first" while a money cell is not a figure. */
.save-indicator.save-blocked{color:var(--fail)}
.save-btn:not(:disabled){border-color:var(--g);color:var(--gh);background:var(--glo)}
.save-btn:disabled{opacity:.5;cursor:default}

/* ── SHARED MOTION UTILITIES (design overhaul round 2) ─────────────────────
   Compositor-friendly (transform/opacity only). Every animation collapses to
   its instant end-state under prefers-reduced-motion. --st is a per-element
   stagger index set inline by the renderers (data, not styling — no token
   equivalent exists for a list position). */
@keyframes riseIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.anim-rise{animation:riseIn 340ms cubic-bezier(.2,.7,.3,1) both;animation-delay:calc(var(--st,0)*28ms)}
/* Re-renders of a list the user is already reading (append/filter/delete)
   must not replay the entrance — rows blink out mid-stagger (round 4). */
.hist-still .anim-rise{animation:none}
@keyframes barGrow{from{width:0}}
.bar-animate{animation:barGrow 700ms cubic-bezier(.25,.8,.35,1) both;animation-delay:calc(var(--st,0)*60ms)}
@keyframes skelShimmer{0%{background-position:-200px 0}100%{background-position:calc(200px + 100%) 0}}
@media (prefers-reduced-motion: reduce){
  .anim-rise,.bar-animate{animation:none}
}

/* ── VAT INVOICE CHECK — compliance command centre (round 2) ───────────────
   The differentiator screen. Hero band (count-up £ headlines + self-drawing
   clean/flagged ring) → metric cards → quiet info strips → rich invoice rows
   with per-defect chips → collapsible clean list → standing Notice-700
   caveat. Everything scopes via #tool-vatcheck / .vc-*. */

#tool-vatcheck .history-detail-toolbar{margin-bottom:18px}

/* Period selector — segmented tabs with a persistent active state */
.vc-period-tabs{display:inline-flex;align-items:center;gap:2px;background:var(--white);border:1px solid var(--brd);border-radius:10px;padding:3px;box-shadow:var(--sh-xs)}
.vc-tab{font-size:13px;font-weight:600;color:var(--t3);background:transparent;border:1px solid transparent;border-radius:var(--r);padding:8px 16px;display:inline-flex;align-items:center;gap:6px;transition:background 120ms,color 120ms,box-shadow 120ms;box-shadow:none;white-space:nowrap}
.vc-tab:hover{background:var(--bg);color:var(--t1)}
.vc-tab.vc-tab-active{background:var(--glo);color:var(--gh);border-color:var(--gbrd);box-shadow:0 1px 2px rgba(5,150,105,.12)}

/* Custom range group — dates + Apply in one quiet control bar */
.vc-range{display:inline-flex;align-items:center;gap:6px;background:var(--white);border:1px solid var(--brd);border-radius:10px;padding:3px 3px 3px 12px;box-shadow:var(--sh-xs);font-size:12.5px;color:var(--t4);transition:border-color 120ms}
.vc-range.vc-range-active{border-color:var(--gbrd);box-shadow:0 0 0 1px var(--gbrd)}
.vc-range .vc-date{border:none;background:transparent;font-family:var(--ui);font-size:13px;color:var(--t2);padding:7px 4px;outline:none;border-radius:var(--r-xs)}
.vc-range .vc-date:focus{color:var(--t1);background:var(--glo)}
/* The :focus tint alone is an 8%-alpha wash — fine as a mouse-click echo, too
   faint as the only keyboard indicator (keyboard audit 2026-07-25). */
.vc-range .vc-date:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:1px}
/* Tinted secondary (the .batch-back recipe) — a filter refresh must not
   outrank the page's actual deliverable (Audit pack). */
.vc-range .vc-apply{font-size:12.5px;font-weight:600;color:var(--gh);background:var(--glo);border:1px solid var(--gbrd);border-radius:var(--r);padding:8px 16px;box-shadow:none;display:inline-flex;white-space:nowrap;transition:all 120ms}
.vc-range .vc-apply:hover{background:var(--gh);color:#fff}
/* Muted disabled state for the tinted pills (e.g. Audit pack over an empty period). */
.batch-back:disabled{color:var(--t5);background:var(--bg);border-color:var(--brd);cursor:default}
.batch-back:disabled:hover{color:var(--t5);background:var(--bg)}

/* Metric cards (#vcMetrics) — 3px status accent along the top edge */
.vc-metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin:4px 0 18px}
.vc-metrics:empty{display:none}
.vc-metric-card{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:20px 22px;box-shadow:var(--sh-sm);position:relative;overflow:hidden;min-width:0;transition:box-shadow 160ms,transform 160ms}
.vc-metric-card:hover{box-shadow:var(--sh);transform:translateY(-1px)}
.vc-metric-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--brd-md)}
.vc-metric-card.vc-ok::before{background:var(--ok)}
.vc-metric-card.vc-warn::before{background:var(--warn)}
.vc-metric-val{font-family:var(--mono);font-size:30px;font-weight:500;color:var(--t1);letter-spacing:-.03em;line-height:1.05;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vc-metric-denom{font-size:17px;color:var(--t4);font-weight:600}
.vc-metric-lbl{font-size:12px;font-weight:500;color:var(--t3);margin-top:8px;letter-spacing:.01em}
@media (max-width: 1100px){.vc-metrics{grid-template-columns:repeat(2,1fr)}}

/* Hero band — the headline £ split + the self-drawing ring */
.vc-hero{display:flex;align-items:center;gap:36px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xl);padding:28px 34px;margin-bottom:16px;box-shadow:var(--sh);position:relative;overflow:hidden}
.vc-hero::before{content:'';position:absolute;inset:0;background:radial-gradient(640px 200px at 88% -60px,rgba(5,150,105,.06),transparent 60%);pointer-events:none}
.vc-hero-stats{display:grid;grid-template-columns:1fr 1fr;gap:36px;flex:1;min-width:0}
.vc-hero-block{min-width:0;position:relative}
.vc-hero-block + .vc-hero-block{padding-left:36px;border-left:1px solid var(--brd)}
.vc-hero-val{font-family:var(--mono);font-size:clamp(30px,3.2vw,40px);font-weight:500;color:var(--ok);letter-spacing:-.035em;line-height:1.05;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vc-hero-val-warn,.vc-hero-val.vc-hero-val-warn{color:var(--warn)}
.vc-hero-lbl{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;color:var(--t1);margin-top:9px;letter-spacing:-.005em}
.vc-hero-sub{font-size:11.5px;color:var(--t4);margin-top:3px;line-height:1.5}
.vc-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.vc-dot-ok{background:var(--ok)}
.vc-dot-warn{background:var(--warn)}
@media (max-width: 1100px){
  .vc-hero{gap:24px;padding:22px 24px}
  .vc-hero-stats{gap:24px}
  .vc-hero-block + .vc-hero-block{padding-left:24px}
}

/* Registration coverage bar + a single compressed caveat line */
.vc-strips{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:14px 18px 12px;margin-bottom:18px;box-shadow:var(--sh-xs)}
.vc-reg-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:9px}
.vc-reg-title{font-size:12.5px;font-weight:600;color:var(--t2);letter-spacing:-.005em}
.vc-reg-sub{font-size:11px;color:var(--t4)}
.vc-reg-bar{display:flex;height:10px;border-radius:999px;overflow:hidden;background:var(--brd);transform-origin:left;animation:vcBarWipe 620ms cubic-bezier(.2,.7,.3,1) both}
.vc-reg-seg{height:100%;width:var(--w);min-width:3px}
.vc-reg-seg + .vc-reg-seg{box-shadow:-1.5px 0 0 var(--white)}
.vc-reg-verified{background:var(--ok)}
.vc-reg-mismatch{background:var(--warn)}
.vc-reg-unverified{background:var(--brd-str)}
.vc-reg-notreg{background:var(--fail)}
.vc-reg-legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:11px}
.vc-reg-key{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--t3)}
.vc-reg-dot{width:8px;height:8px;border-radius:2px;flex-shrink:0}
.vc-coverage-note{font-size:11.5px;color:var(--t4);line-height:1.6;margin-top:12px;padding-top:11px;border-top:1px solid var(--brd)}
.vc-coverage-note strong{color:var(--warn);font-weight:600}
.vc-composition{font-size:11.5px;color:var(--t4);line-height:1.6;margin-top:12px;padding-top:11px;border-top:1px solid var(--brd)}
.vc-composition strong{color:var(--warn);font-weight:600}
@keyframes vcBarWipe{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.vc-caveat{font-size:11.5px;color:var(--t3);line-height:1.65;margin-top:18px;padding:12px 16px;background:transparent;border:1px dashed var(--brd-md);border-radius:var(--r-lg);max-width:78ch}
.vc-more-note{font-size:11.5px;color:var(--t3);padding:8px 2px}
/* Round-3 list paging: .vc-hid must OUTRANK .vc-inv-row's display:flex (the
   [hidden] attribute wouldn't — same lesson as the home-demo handover). */
.vc-inv-row.vc-hid{display:none}
.vc-show-more{display:block;width:100%;margin:2px 0 8px;padding:9px 14px;font-size:12.5px;font-weight:600;color:var(--t3);background:var(--bg);border:1px dashed var(--brd-md);border-radius:var(--r-lg);cursor:pointer;transition:color 120ms,border-color 120ms,background 120ms}
.vc-show-more:hover{color:var(--gh);border-color:var(--gbrd);background:var(--white)}

/* Sections + rich invoice rows */
.vc-section{margin-top:4px}
.vc-section-hdr{display:flex;align-items:center;gap:9px;padding:8px 2px;margin-bottom:8px}
.vc-section-title{font-size:11.5px;font-weight:600;color:var(--t3);letter-spacing:.04em;text-transform:uppercase}
.vc-section-count{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-brd);padding:1px 9px;border-radius:999px}
.vc-section-hdr::after{content:'';flex:1;height:1px;background:var(--brd)}
.vc-rows{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}
.vc-inv-row{display:flex;align-items:center;gap:14px;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:13px 18px;box-shadow:var(--sh-xs);transition:box-shadow 140ms,transform 140ms,border-color 140ms}
.vc-inv-row:hover{box-shadow:var(--sh);transform:translateY(-1px);border-color:var(--brd-md)}
.vc-inv-main{flex:1;min-width:0}
.vc-inv-top{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.vc-inv-supplier{font-size:13.5px;font-weight:600;color:var(--t1);letter-spacing:-.005em;min-width:0;overflow-wrap:anywhere}
.vc-inv-num{font-family:var(--mono);font-size:12px;color:var(--data)}
.vc-inv-date{font-size:12px;color:var(--t4)}
.vc-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
.vc-chip{font-size:10.5px;font-weight:600;color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-brd);padding:2px 9px;border-radius:999px;white-space:nowrap;cursor:default}
.vc-inv-issues{font-size:12px;color:var(--t3);line-height:1.55;margin-top:6px}
.vc-inv-side{text-align:right;flex-shrink:0}
.vc-inv-vat{font-family:var(--mono);font-size:14.5px;font-weight:500;color:var(--t1);letter-spacing:-.01em}
.vc-inv-vat-lbl{font-size:9.5px;font-weight:600;color:var(--t4);letter-spacing:.08em;text-transform:uppercase;margin-top:1px}
/* .vc-view-btn removed 2026-08-08 — the whole .vc-inv-row is the affordance
   now (data-vc-view on the row; rules in the restyle layer, section 11). */

/* All-clear banner (no defects in the period) */
.vc-allclear{display:flex;align-items:center;gap:11px;background:var(--ok-bg);border:1px solid var(--ok-brd);color:var(--ok-text);font-size:13.5px;font-weight:600;line-height:1.5;padding:14px 18px;border-radius:var(--r-lg);margin-bottom:14px}
.vc-allclear svg{width:19px;height:19px;stroke:var(--ok);fill:none;stroke-width:2;flex-shrink:0}

/* Collapsible clean-invoice list */
#tool-vatcheck details{margin-top:14px}
#tool-vatcheck summary{list-style:none;cursor:pointer;user-select:none}
#tool-vatcheck summary::-webkit-details-marker{display:none}
.vc-clean-summary{display:flex;align-items:center;gap:9px;padding:10px 2px;border-radius:var(--r);margin-bottom:6px}
.vc-clean-summary:hover .vc-section-title{color:var(--t1)}
.vc-clean-summary::after{content:'';flex:1;height:1px;background:var(--brd);order:3}
.vc-chev{width:8px;height:8px;border-right:2px solid var(--t4);border-bottom:2px solid var(--t4);transform:rotate(45deg) translateY(-2px);transition:transform 160ms ease;flex-shrink:0;margin:0 6px 0 4px;order:4}
#tool-vatcheck details[open] .vc-chev{transform:rotate(225deg) translateY(-1px)}
@media (prefers-reduced-motion: reduce){
  .vc-reg-bar{animation:none}
  .vc-metric-card,.vc-inv-row,.vc-chev{transition:none}
}

/* Empty + skeleton states */
.vc-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:56px 24px;background:var(--white);border:1px dashed var(--brd-md);border-radius:var(--r-xl);text-align:center}
.vc-empty svg{width:34px;height:34px;stroke:var(--t5);fill:none;stroke-width:1.4;margin-bottom:4px}
.vc-empty-t{font-size:14.5px;font-weight:600;color:var(--t2)}
.vc-empty-s{font-size:12.5px;color:var(--t4);max-width:420px;line-height:1.6}
.vc-skeleton{display:flex;flex-direction:column;gap:12px}
.vc-skel{border-radius:var(--r-lg);background:linear-gradient(90deg,#eef2f7 0%,#f7fafd 40%,#eef2f7 80%);background-size:200px 100%;animation:skelShimmer 1.1s linear infinite}
.vc-skel-hero{height:150px;border-radius:var(--r-xl)}
.vc-skel-line{height:64px}
.vc-skel-row{height:58px}
@media (prefers-reduced-motion: reduce){.vc-skel{animation:none}}

/* ══════════════════════════════════════════════════════════════════════════
   PUBLIC FACE — design overhaul round 2.
   Home demo v2 (cinematic ghost extraction), credibility strip, rollup teaser,
   CTA band, and the marketing-page component set (product vignettes, article
   cards, changelog timeline, shared kickers). All additive — nothing above
   this line is modified. Animations are transform/opacity-only and collapse
   to their end-state under prefers-reduced-motion.
   ══════════════════════════════════════════════════════════════════════════ */

/* Shared marketing kicker (replaces the repeated inline-style label) */
.mkt-kicker{font-size:13px;font-weight:500;color:var(--t3);margin-bottom:10px}

/* ── HOME DEMO v4 — the working paper (2026-09-23) ──────────────────────
   Built by static/js/homedemo.js. Every verdict, figure and gov.uk
   reference on the paper is the engine's (runClientSideCompliance), none is
   written here. Two layouts, chosen by the CARD's width (named container):
   DESK (card >= 760px): a world laid out at the card's own width, one design
     unit = card width / 1400 (--u), holding the invoice, the register slip
     and the working paper; the camera zooms by transform, text re-rasters
     crisp whenever it rests (homedemo.js drops will-change at rest).
   COMPACT (card < 760px): the paper alone, in px, no camera.
   homedemo.js reads --hd-mode, so THIS file decides which layout is live. */
.home-demo-v4{position:relative;container:hddemo / inline-size}
.hd-head{display:flex;align-items:center;gap:10px;min-height:46px;padding:8px 14px 8px 18px;border-bottom:1px solid var(--brd)}
.hd-status{display:inline-flex;align-items:center;gap:9px;font-size:12px;font-weight:600;color:var(--t2)}
.hd-status::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--data);box-shadow:0 0 0 3px var(--info-bg);flex-shrink:0}
.hd-status:not(.done)::before{animation:ndBlink 1.4s ease-in-out infinite}
/* Idle until the demo starts: laid out, not yet checking (review, 2026-09-23). */
.hd-status.idle::before{animation:none;background:var(--brd-str);box-shadow:0 0 0 3px var(--bg)}
/* The engine did not load: a plain note, not an empty paper. */
.hd-unavailable .hd-stage{aspect-ratio:auto;min-height:0}
.hd-unavailable .hd-caption,.hd-unavailable .hd-foot{display:none}
.hd-unavailable-note{margin:28px 24px;color:var(--t2);font-size:13.5px}
.hd-status.done{color:var(--ok-text)}
.hd-status.done::before{background:var(--ok);box-shadow:0 0 0 3px var(--ok-bg)}
.hd-stage{position:relative;overflow:hidden;aspect-ratio:1400 / 1080;background:#e8edf3}
.hd-stage::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:6;background:radial-gradient(130% 100% at 50% 38%,transparent 62%,rgba(14,26,40,.06) 100%)}
.hd-world{--u:calc(100cqw / 1400);--hd-mode:desk;position:absolute;left:0;top:0;width:100%;height:100%;transform-origin:0 0}
.hd-ink{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:5}
.hd-foot{display:flex;align-items:center;gap:14px;min-height:58px;padding:8px 14px 8px 18px;border-top:1px solid var(--brd)}
.hd-caption{flex:1;min-width:0;margin:0;font-size:12px;line-height:1.5;color:var(--t3)}
.home-demo-v4 .demo-handover{flex:0 0 auto;margin:0;animation:none}
.home-demo-v4 .demo-handover-btn{padding:11px 18px}
.home-demo-v4 .demo-sandbox{margin:0;padding:16px 18px 18px;border-top:0}
.home-demo-v4.sbx-mode{overflow:visible}
.home-demo-v4.sbx-mode .hd-stage,.home-demo-v4.sbx-mode .hd-foot{display:none}
.hd-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* Paper, desk mode: sizes in design units */
.hd-inv,.hd-slip,.hd-wp{position:absolute;background:#fff;color:var(--t1);box-shadow:0 calc(2*var(--u)) calc(6*var(--u)) rgba(14,26,40,.08),0 calc(16*var(--u)) calc(42*var(--u)) rgba(14,26,40,.13)}

/* The invoice: a typeset A4 sheet */
.hd-inv{left:calc(30*var(--u));top:calc(34*var(--u));width:calc(500*var(--u));height:calc(707*var(--u));padding:calc(36*var(--u)) calc(36*var(--u)) calc(26*var(--u));display:flex;flex-direction:column;font-size:calc(15*var(--u));border-radius:calc(2*var(--u))}
.hd-inv-head{display:flex;justify-content:space-between;align-items:flex-start;gap:calc(14*var(--u));border-bottom:calc(3*var(--u)) solid var(--t1);padding-bottom:calc(16*var(--u))}
.hd-inv-brand{font-size:calc(16.5*var(--u));font-weight:700;letter-spacing:.05em;text-transform:uppercase;margin-bottom:calc(6*var(--u))}
.hd-inv-sub{font-size:calc(14*var(--u));line-height:1.55;color:var(--t3)}
.hd-inv-title{font-size:calc(24*var(--u));font-weight:300;letter-spacing:.22em;color:var(--t2)}
.hd-inv-mid{display:flex;justify-content:space-between;gap:calc(20*var(--u));margin:calc(20*var(--u)) 0 calc(10*var(--u))}
.hd-inv-kick{font-size:calc(12.5*var(--u));font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--t3);margin-bottom:calc(4*var(--u))}
.hd-inv-cust{font-size:calc(16*var(--u));font-weight:600}
.hd-inv-meta{display:flex;flex-direction:column;align-items:flex-end;flex:none}
.hd-inv-mrow{display:flex;justify-content:flex-end;align-items:baseline;gap:calc(12*var(--u));font-size:calc(14*var(--u));line-height:1.75}
.hd-inv-mrow span{color:var(--t3);white-space:nowrap}
.hd-inv-mrow b{font-family:var(--mono);font-weight:400;white-space:nowrap}
.hd-inv-bill{min-width:0}
.hd-inv-blank{display:inline-block;width:calc(96*var(--u));height:calc(15*var(--u));border-bottom:calc(1.5*var(--u)) dashed var(--brd-str)}
.hd-inv-lines{width:100%;border-collapse:collapse;margin-top:calc(14*var(--u));font-size:calc(14*var(--u))}
.hd-inv-lines th{font-size:calc(11.5*var(--u));font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--t3);text-align:right;padding:0 0 calc(7*var(--u)) calc(10*var(--u));border-bottom:calc(2*var(--u)) solid var(--t1)}
.hd-inv-lines th:first-child,.hd-inv-lines td:first-child{text-align:left;padding-left:0}
.hd-inv-lines td{padding:calc(8*var(--u)) 0 calc(8*var(--u)) calc(10*var(--u));text-align:right;font-family:var(--mono);color:var(--t2);border-bottom:1px solid var(--brd)}
.hd-inv-lines td:first-child{font-family:var(--ui);color:var(--t2)}
.hd-inv-lines td:last-child{color:var(--t1)}
.hd-inv-totals{margin:calc(14*var(--u)) 0 0 auto;width:62%;border-top:calc(1.5*var(--u)) solid var(--t1);padding-top:calc(8*var(--u))}
.hd-inv-trow{display:flex;justify-content:space-between;align-items:baseline;font-size:calc(14.5*var(--u));padding:calc(3*var(--u)) 0}
.hd-inv-trow span{color:var(--t3)}
.hd-inv-trow b{font-family:var(--mono);font-weight:400}
.hd-inv-grand{border-top:calc(3*var(--u)) solid var(--t1);margin-top:calc(6*var(--u));padding-top:calc(8*var(--u))}
.hd-inv-grand span{color:var(--t1);font-weight:700}
.hd-inv-grand b{font-size:calc(18*var(--u));font-weight:500}
.hd-inv-foot{margin-top:auto;padding-top:calc(14*var(--u));border-top:1px solid var(--brd);font-size:calc(12*var(--u));line-height:1.6;color:var(--t3)}

/* The register slip: the lookup that runs on the server, never here */
.hd-slip{left:calc(36*var(--u));top:calc(752*var(--u));width:calc(500*var(--u));height:calc(268*var(--u));padding:calc(22*var(--u)) calc(28*var(--u)) calc(18*var(--u));transform:rotate(.7deg);border-radius:calc(4*var(--u));display:flex;flex-direction:column}
.hd-slip-top{display:flex;align-items:center;gap:calc(10*var(--u));margin-bottom:calc(10*var(--u))}
.hd-slip-kick{flex:1;font-family:var(--mono);font-size:calc(12.5*var(--u));letter-spacing:.2em;text-transform:uppercase;color:var(--t3)}
.hd-tab{font-family:var(--mono);font-size:calc(11.5*var(--u));letter-spacing:.06em;color:var(--t3);border:1px solid var(--brd-md);border-radius:999px;padding:calc(3*var(--u)) calc(11*var(--u))}
.hd-tab.on{color:var(--ok-text);border-color:var(--gbrd);background:var(--glo)}
.hd-slip-title{font-size:calc(20*var(--u));font-weight:600;letter-spacing:-.01em;margin-bottom:calc(12*var(--u))}
.hd-slip-row{display:grid;grid-template-columns:calc(112*var(--u)) minmax(0,1fr);gap:calc(10*var(--u));font-size:calc(14.5*var(--u));line-height:1.45;margin-bottom:calc(6*var(--u))}
.hd-slip-row span{font-family:var(--mono);color:var(--t3)}
.hd-slip-row b{font-family:var(--mono);font-weight:400;color:var(--t1)}
/* The stamp owns the slip's last row, so it can never sit on the text above it */
.hd-slip-foot{margin-top:auto;display:flex;justify-content:flex-end}
.hd-stamp{font-family:var(--mono);font-weight:500;font-size:calc(19*var(--u));line-height:1.2;letter-spacing:.16em;text-transform:uppercase;color:var(--t3);border:calc(3*var(--u)) solid var(--t3);border-radius:calc(6*var(--u));padding:calc(5*var(--u)) calc(12*var(--u));opacity:0;transform:rotate(-4deg)}
.hd-slip-note{position:absolute;right:calc(28*var(--u));bottom:calc(-34*var(--u));font-size:calc(15*var(--u));font-weight:500;color:var(--t2)}

/* The working paper: a green-ruled analysis pad */
.hd-wp{left:calc(546*var(--u));top:calc(22*var(--u));width:calc(830*var(--u));height:calc(1036*var(--u));padding:calc(28*var(--u)) calc(32*var(--u)) calc(24*var(--u)) calc(98*var(--u));border-radius:calc(2*var(--u))}
.hd-wp::before{content:'';position:absolute;top:0;bottom:0;left:calc(64*var(--u));width:calc(7*var(--u));border-left:calc(1.5*var(--u)) solid rgba(5,150,105,.34);border-right:calc(1.5*var(--u)) solid rgba(5,150,105,.34)}
.hd-wp-kicker{font-family:var(--mono);font-size:calc(14*var(--u));letter-spacing:.22em;text-transform:uppercase;color:var(--ok-text);margin-bottom:calc(10*var(--u))}
.hd-wp-meta{display:flex;align-items:baseline;gap:calc(14*var(--u));min-height:calc(30*var(--u))}
.hd-wp-k{flex:0 0 calc(200*var(--u));font-size:calc(15.5*var(--u));color:var(--t3)}
.hd-wp-v{flex:1;min-width:0;font-family:var(--mono);font-size:calc(16.5*var(--u));color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hd-tbl{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:calc(12*var(--u));background-image:linear-gradient(rgba(5,150,105,.24),rgba(5,150,105,.24)),linear-gradient(rgba(5,150,105,.24),rgba(5,150,105,.24)),linear-gradient(rgba(5,150,105,.24),rgba(5,150,105,.24));background-size:1px 100%;background-repeat:no-repeat;background-position:calc(202*var(--u)) 0,calc(564*var(--u)) 0,calc(608*var(--u)) 0}
/* the site's global th is small caps-and-tracking; the paper's labels are sentence case */
.hd-tbl th{text-transform:none;letter-spacing:0;color:inherit}
.hd-c-lbl{width:calc(202*var(--u))}
.hd-c-mark{width:calc(44*var(--u))}
.hd-c-ref{width:calc(92*var(--u))}
.hd-tbl thead th{height:calc(34*var(--u));font-family:var(--mono);font-size:calc(12.5*var(--u));font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--t3);text-align:left;vertical-align:bottom;padding:0 0 calc(7*var(--u)) calc(10*var(--u));border-bottom:calc(2*var(--u)) solid rgba(51,68,90,.7)}
.hd-tbl thead th:first-child{padding-left:0}
.hd-tbl thead th.hd-th-mark{text-align:center;padding-left:0}
.hd-sec-row th{height:calc(42*var(--u));vertical-align:bottom;text-align:left;padding:0 0 calc(7*var(--u));font-weight:400;white-space:nowrap;background:#fff}
.hd-sec-t{font-size:calc(15*var(--u));font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--t1)}
.hd-sec-s{font-size:calc(14*var(--u));color:var(--t3);margin-left:calc(14*var(--u))}
.hd-row th,.hd-row td{height:calc(34*var(--u));padding:0 calc(10*var(--u));border-bottom:1px solid rgba(98,116,140,.2);vertical-align:middle;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hd-row th{padding-left:0;text-align:left;font-weight:400}
.hd-row td.hd-mark{position:relative}
.hd-lbl{font-size:calc(18.5*var(--u));color:var(--t2)}
.hd-lbl-soft{color:var(--t3);font-size:calc(17*var(--u))}
.hd-lbl-strong{color:var(--t1);font-weight:600 !important}
.hd-val{font-size:calc(18.5*var(--u))}
.hd-txt{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}
.hd-val .hd-txt,.hd-amt{font-family:var(--mono);color:var(--t1)}
.hd-val .hd-txt.hd-prose{font-family:var(--ui)}
.hd-row th .hd-txt{font-family:var(--ui)}
.hd-txt.hd-s-fail,.hd-sub.hd-s-fail,.hd-sumnote.hd-s-fail{color:var(--fail)}
.hd-txt.hd-s-warn,.hd-sub.hd-s-warn,.hd-sumnote.hd-s-warn{color:var(--warn)}
.hd-row td.hd-val .hd-txt.hd-s-fail,.hd-row td.hd-val .hd-txt.hd-s-warn{font-family:var(--ui);font-size:calc(16*var(--u))}
.hd-multi{font-family:var(--ui)}
.hd-sub{display:inline-flex;align-items:center;margin-right:calc(14*var(--u));font-size:calc(15.5*var(--u));color:var(--t2)}
.hd-subslot{display:inline-block;width:calc(22*var(--u));height:calc(22*var(--u));margin-left:calc(4*var(--u))}
.hd-num{text-align:right}
.hd-amt{font-size:calc(18.5*var(--u))}
.hd-amt-strong{font-weight:500;font-size:calc(19.5*var(--u))}
.hd-sumnote{float:left;font-family:var(--ui);font-size:calc(14.5*var(--u));color:var(--ok-text);line-height:calc(34*var(--u))}
.hd-row-note td{height:calc(31*var(--u));background:#fff}
.hd-notetxt{display:inline-block;font-size:calc(14.5*var(--u));color:var(--t3);font-style:italic;white-space:normal}
.hd-ref{font-family:var(--mono);font-size:calc(14.5*var(--u))}
.hd-reflink{color:var(--t3);text-decoration:none;border-bottom:1px dotted var(--brd-str);opacity:0}
.hd-reflink:hover{color:var(--gh);border-bottom-color:var(--gh)}
.hd-reflink:focus-visible{outline:2px solid var(--g);outline-offset:2px;opacity:1}
.hd-signoff{margin-top:calc(12*var(--u));padding-top:calc(10*var(--u));border-top:calc(4*var(--u)) double rgba(51,68,90,.6)}
.hd-so-1{font-size:calc(22*var(--u));font-weight:600;color:var(--t1);letter-spacing:-.01em}
.hd-so-2{font-size:calc(16.5*var(--u));color:var(--t2);margin-top:calc(4*var(--u))}
.hd-so-3{font-size:calc(14*var(--u));color:var(--t3);margin-top:calc(4*var(--u))}
.hd-signoff span{display:inline-block}

/* COMPACT: the paper alone, in px (phones, narrow columns). */
@container hddemo (max-width: 759px){
  /* min-height: the paper's height at a phone's width, reserved before
     homedemo.js lays it out (it does so at load, below the fold) */
  .hd-stage{aspect-ratio:auto;min-height:900px;background:var(--white)}
  .hd-stage::after{display:none}
  .hd-world{--hd-mode:compact;position:relative;height:auto}
  .hd-inv,.hd-slip{display:none}
  .hd-wp{position:relative;left:auto;top:auto;width:auto;height:auto;padding:16px 12px 16px 30px;box-shadow:none;border-radius:0}
  .hd-wp::before{left:12px;width:4px;border-left-width:1px;border-right-width:1px}
  .hd-wp-kicker{font-size:10.5px;margin-bottom:6px}
  .hd-wp-meta{min-height:20px;gap:8px}
  .hd-wp-k{flex-basis:92px;font-size:11px}
  .hd-wp-v{font-size:11.5px;white-space:normal}
  .hd-tbl{margin-top:8px;background-image:none}
  .hd-c-lbl{width:31%}
  .hd-c-mark{width:30px}
  .hd-c-ref{width:44px}
  .hd-tbl thead th{height:24px;font-size:9.5px;padding:0 0 5px 6px;border-bottom-width:1.5px}
  .hd-sec-row th{height:32px;padding-bottom:5px;white-space:normal}
  .hd-sec-t{font-size:10.5px}
  .hd-sec-s{font-size:10.5px;margin-left:8px}
  .hd-row th,.hd-row td{height:auto;min-height:30px;padding:6px 6px;white-space:normal;overflow:visible;word-break:break-word}
  .hd-row th{padding-left:0}
  .hd-lbl,.hd-val{font-size:11.5px}
  .hd-txt{display:inline;max-width:none;overflow:visible}
  .hd-row td.hd-val .hd-txt.hd-s-fail,.hd-row td.hd-val .hd-txt.hd-s-warn{font-size:11px}
  .hd-sub{display:inline-flex;font-size:11px;margin-right:6px;white-space:nowrap}
  .hd-subslot{width:13px;height:13px;margin-left:2px}
  .hd-amt,.hd-amt-strong{font-size:11.5px}
  .hd-sumnote{float:none;display:block;line-height:1.4;font-size:10.5px;text-align:left}
  .hd-row-note td{height:auto;padding:6px 0}
  .hd-notetxt{font-size:10.5px}
  .hd-ref{font-size:10px}
  .hd-signoff{margin-top:12px;padding-top:9px;border-top-width:3px}
  .hd-so-1{font-size:14px}
  .hd-so-2{font-size:12px;margin-top:2px}
  .hd-so-3{font-size:11px;margin-top:2px}
  .hd-foot{flex-direction:column;align-items:stretch;gap:10px}
  .home-demo-v4 .demo-handover-btn{width:100%}
}

/* Handover CTA: the finished paper holds for inspection; this button is
   the only door into the sandbox. display:flex would beat the [hidden] UA
   default, so the override is explicit. */
.demo-handover{display:flex;flex-shrink:0}
.demo-handover[hidden]{display:none}
.demo-handover-btn{flex:1;text-align:center;padding:12px 20px}

/* ── SITE CALM (2026-09-24) ─────────────────────────────────────────────
   The public pages' pass after the working-paper demo and the film. One
   rule (founder, 2026-09-24): white is for the thing you are working on,
   and everything else sits on a tint. So the page ground is --page, one
   step lighter than the workspace canvas (--bg), and the objects on it are
   white: the demo, a plan, a paper illustration, a panel you fill in. A
   section sits ON the ground, not in a card. The long pages alternate:
   a section whose visual carries its own frame (a table, the product
   screenshot) may sit on a white .mk-band; paper always sits on the tint,
   where it reads as paper. One idea per section: a headline, a
   sentence or two, then the visual. The illustrations borrow the demo's
   ink (a tick for passed, an amber ring for worth a second look, a slate
   ring for unverified, a crimson cross for broken) and, like the demo, show
   only what the engine returns for the input they show. The glyphs are CSS
   masks filled with background-color, so no rule here sets text colour to
   the brand green (tests/test_contrast.py). */
:root{--page:#f4f7fa}
#page-home,.mkt-static{background:var(--page)}
/* A white band, edge to edge whatever the page's gutter. The white is a
   spread shadow trimmed to the band's height by clip-path: neither is
   layout, so nothing reaches past the page (no sideways scroll on a phone,
   tests/e2e/test_home_phone.py). The band is a wrapper, so a section's
   scroll reveal (.story-sec) moves the content, never the band. */
.mk-band{background:var(--white);box-shadow:0 0 0 100vmax var(--white);clip-path:inset(0 -100vmax);margin-top:96px;padding-bottom:96px}
/* A plain link in running copy is the site green, never the browser blue. */
.mkt-page a:not([class]){color:var(--gh)}
.mk-sec{padding-top:96px}
.mk-head{max-width:640px;margin:0 0 44px}
.mk-head h2{font-size:clamp(26px,2.5vw,34px);line-height:1.14;letter-spacing:-.032em;margin:0 0 14px}
.mk-sub{font-size:17px;line-height:1.6;color:var(--t2);margin:0;text-wrap:pretty}
.mk-sub + .mk-sub{margin-top:12px}
.mk-small{font-size:13px;line-height:1.55;color:var(--t3);margin:14px 0 0}
.mk-link{display:inline-block;margin-top:22px;font-size:15px;font-weight:600;color:var(--gh);text-decoration:none;border-bottom:1px solid var(--gbrd);padding-bottom:1px;transition:border-color 120ms}
.mk-link:hover{border-bottom-color:var(--gh)}
.mk-split{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:72px;align-items:center}
.mk-split > .mk-head{margin:0}
@container (max-width:960px){.mk-split{grid-template-columns:minmax(0,1fr);gap:36px}}
.mk-paper{background:var(--white);border:1px solid var(--brd);border-radius:10px;box-shadow:0 1px 2px rgba(13,28,46,.04),0 16px 36px -16px rgba(13,28,46,.18)}
.mk-tk,.mk-rg,.mk-ra,.mk-cx{display:inline-block;flex:none;width:15px;height:15px;-webkit-mask:var(--mk-m) center/contain no-repeat;mask:var(--mk-m) center/contain no-repeat}
.mk-tk{background-color:var(--g);--mk-m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.4 8.7 6.2 12.2 13.6 3.4' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.mk-rg{background-color:var(--t3);--mk-m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='5.4' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E")}
.mk-ra{background-color:var(--warn);--mk-m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='5.4' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E")}
.mk-cx{background-color:var(--fail);--mk-m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4 12 12M12 4 4 12' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E")}
.mk-fig{font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--t1)}
/* The names a visitor already uses, said once under the hero: a quiet line
   between two hairlines, not a navy band of dots. */
.mk-works{display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:12px 48px;margin-top:56px;padding:24px 0;border-top:1px solid var(--brd);border-bottom:1px solid var(--brd)}
.mk-works-g{display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:6px 22px}
.mk-works-l{font-size:13px;color:var(--t3)}
.mk-works-i{font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--t2)}
/* The four kinds of check, each a scrap of working paper. */
.mk-checks{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 32px}
/* Each column is paper, heading, sentence: a subgrid lines the four up row
   by row, so the scraps share one height whatever their row count. */
.mk-check{display:grid;grid-template-rows:subgrid;grid-row:span 3}
@container (max-width:1040px){.mk-checks{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:0}.mk-check:nth-child(n+3) .mk-swatch{margin-top:48px}}
@container (max-width:560px){.mk-checks{grid-template-columns:minmax(0,1fr)}.mk-check:nth-child(n+2) .mk-swatch{margin-top:40px}}
.mk-swatch{padding:14px 16px;font-size:12.5px;color:var(--t2)}
.mk-sw-row{display:flex;align-items:center;gap:10px;min-height:30px;border-bottom:1px solid rgba(98,116,140,.16)}
.mk-sw-row:last-child{border-bottom:0}
.mk-sw-row > :first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-sw-row .mk-fig{font-size:12px}
.mk-sw-row.mk-sw-sum{border-top:1px solid var(--t1);border-bottom:0;font-weight:600;color:var(--t1)}
.mk-sw-more{min-height:30px;display:flex;align-items:center;color:var(--t3);font-size:12px}
.mk-check h3{font-size:16px;margin:22px 0 6px}
.mk-check p{font-size:14px;line-height:1.55;color:var(--t3);margin:0}
/* How it works: a real sequence, so it keeps its numbers, small. */
.mk-steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px;list-style:none;margin:0;padding:0}
@container (max-width:760px){.mk-steps{grid-template-columns:minmax(0,1fr);gap:24px}}
.mk-steps li{border-top:1px solid var(--brd);padding-top:18px}
.mk-step-n{font-family:var(--mono);font-size:12px;color:var(--t3)}
.mk-steps h3{font-size:16px;margin:8px 0 6px}
.mk-steps p{font-size:14px;line-height:1.55;color:var(--t3);margin:0}
/* A cropped piece of the real product, shown at its own size. */
.mk-shot{margin:0;max-width:1162px;border:1px solid var(--brd);border-radius:12px;overflow:hidden;background:var(--bg);box-shadow:0 1px 2px rgba(13,28,46,.04),0 24px 48px -24px rgba(13,28,46,.22)}
.mk-shot img{display:block;width:100%;height:auto}
.mk-shot figcaption{font-size:12.5px;color:var(--t3);padding:10px 16px;background:var(--white);border-top:1px solid var(--brd)}

/* ── HOME — VAT-period rollup (SITE CALM 2026-09-24: no card; the section's
   words, then the real screen cropped to its summary at its own size) ── */
.rollup-band{padding-top:96px}
.rollup-band .mk-head{margin-bottom:36px}
/* ── HOME — "Extraction is the easy half" + Pricing at a glance (2026-09-09;
   SITE CALM 2026-09-24: no card around the section, the table is the object) ── */
.easy-half{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:72px;align-items:center;padding-top:96px}
.easy-half-copy .mk-head{margin:0}
.easy-half-table{width:100%;border-collapse:separate;border-spacing:0;border:1px solid var(--brd);border-radius:12px;overflow:hidden;font-size:14px;background:var(--white);box-shadow:0 1px 2px rgba(13,28,46,.04),0 16px 36px -16px rgba(13,28,46,.14)}
.easy-half-table th{padding:12px 16px;background:var(--card-head);font-size:12px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--t3);text-align:center}
.easy-half-table th:first-child{text-align:left}
.easy-half-table td{padding:12px 16px;border-top:1px solid var(--brd);color:var(--t1);text-align:center}
.easy-half-table td:first-child{text-align:left}
.easy-half-table .eh-ours{color:var(--gh);background:rgba(5,150,105,.04)}
.easy-half-table th.eh-ours{color:var(--gh)}
.easy-half-table .eh-yes{color:var(--gh);font-weight:600}
.easy-half-table .eh-no{color:var(--t5)}
@container (max-width:960px){.easy-half{grid-template-columns:minmax(0,1fr);gap:32px}}
/* A phone: the three-column table fits 320px (it ran 35px past the screen;
   review, 2026-09-23). The header word Extraction sets the table's minimum
   width, so the cells tighten. */
@media (max-width:420px){.easy-half-table th,.easy-half-table td{padding:9px 6px}.easy-half-table th{font-size:11px}}
.price-glance{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
.pg-card{display:flex;flex-direction:column;gap:6px;background:var(--white);border:1px solid var(--brd);border-radius:12px;padding:22px 22px 20px;text-decoration:none;color:inherit;transition:border-color 140ms,box-shadow 140ms}
.pg-card:hover{border-color:var(--brd-str);box-shadow:var(--sh-sm)}
.pg-tier{font-size:14px;font-weight:600;color:var(--t1);letter-spacing:-.01em}
.pg-amt{font-family:var(--mono);font-size:30px;font-weight:500;color:var(--t1);letter-spacing:-.025em;line-height:1.1}
.pg-amt span{font-family:var(--ui);font-size:12px;font-weight:500;color:var(--t3);margin-left:6px;letter-spacing:0}
.pg-meta{font-size:13px;color:var(--t3)}
.pg-trial,.pg-day-one{font-size:12.5px;font-weight:600;color:var(--gh);margin-top:6px}
.pg-day-one{color:var(--t3);font-weight:500}
@container (max-width:900px){.price-glance{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container (max-width:480px){.price-glance{grid-template-columns:minmax(0,1fr)}}

/* ── Closing CTA band (home, product, the two free tools). SITE CALM
   2026-09-24: a white panel on the tinted page, words left and buttons right;
   the navy block and its green glow are retired with the rest of the
   gradients. .btn-cta-ghost keeps its name and reads as a secondary button. */
.cta-band{margin-top:96px;background:var(--white);border:1px solid var(--brd);border-radius:16px;padding:44px 48px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 48px;align-items:center}
.cta-band h2{font-size:clamp(24px,2.3vw,30px);letter-spacing:-.03em;margin:0 0 8px;grid-column:1}
.cta-band p{font-size:15.5px;line-height:1.6;color:var(--t2);margin:0;max-width:620px;grid-column:1}
.cta-btns{grid-column:2;grid-row:1 / span 2;justify-content:flex-end;margin-bottom:0}
@container (max-width:860px){.cta-band{grid-template-columns:minmax(0,1fr);padding:32px 28px}.cta-btns{grid-column:1;grid-row:auto;justify-content:flex-start}}
.btn-cta-ghost{background:var(--white);color:var(--t2);font-size:14px;font-weight:500;border:1px solid var(--brd-md);border-radius:10px;padding:13px 24px;cursor:pointer;text-decoration:none;transition:border-color 120ms,color 120ms}
.btn-cta-ghost:hover{border-color:var(--g);color:var(--gh)}

/* ── PRODUCT PAGE (SITE CALM 2026-09-24) ─────────────────────────────────
   pd-* is the product page's namespace (pr-* stays the pricing page's). The
   read, the check index and the register outcomes are paper; the period
   rollup is the real screen; the exports are one table, not five cards. */
.tour-video + .mk-sec{padding-top:56px}
.pd-read{padding:18px 22px 14px;font-size:13.5px;width:100%;max-width:560px;justify-self:end}
.pd-read-h{display:flex;justify-content:space-between;align-items:baseline;padding-bottom:12px;margin-bottom:2px;border-bottom:1px solid var(--t1);font-size:12.5px;color:var(--t3)}
.pd-read-h .mk-fig{font-size:12px;color:var(--t2)}
.pd-read-row{display:grid;grid-template-columns:120px minmax(0,1fr) auto;gap:14px;align-items:center;min-height:44px;border-bottom:1px solid rgba(98,116,140,.16);color:var(--t1)}
.pd-read-row > :first-child{color:var(--t3);font-size:13px}
.pd-read-row i{font-style:normal;font-size:12px;color:var(--warn);white-space:nowrap}
.pd-read-row.is-doubt i::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--warn);margin-right:7px;vertical-align:1px}
.pd-read-note{margin:12px 0 0;font-size:11.5px;color:var(--t3)}
.pd-index{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.pd-index-col{padding:28px 32px}
.pd-index-col + .pd-index-col{border-left:1px solid var(--brd)}
.pd-index-t{display:flex;justify-content:space-between;align-items:baseline;margin:0 0 4px;padding-bottom:12px;border-bottom:1px solid var(--t1);font-size:14px;font-weight:600;color:var(--t1)}
.pd-index-t .mk-fig{font-size:13px;color:var(--t3)}
.pd-index-dl{margin:0}
.pd-index-dl > div{padding:13px 0;border-bottom:1px solid rgba(98,116,140,.16)}
.pd-index-dl > div:last-child{border-bottom:0}
.pd-index-dl dt{font-size:14px;font-weight:600;color:var(--t1);margin-bottom:3px}
.pd-index-dl dd{margin:0;font-size:13.5px;line-height:1.55;color:var(--t3)}
.pd-index-names{list-style:none;margin:0 0 16px;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:28px}
.pd-index-names li{display:flex;align-items:center;gap:10px;min-height:40px;border-bottom:1px solid rgba(98,116,140,.16);font-size:14px;color:var(--t1)}
.pd-index-names li::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--brd-str);flex:none}
.pd-index-plus{font-size:13.5px;line-height:1.55;color:var(--t3);margin:10px 0 0}
.pd-index-plus strong{color:var(--t1);font-weight:600}
@container (max-width:900px){.pd-index{grid-template-columns:minmax(0,1fr)}.pd-index-col + .pd-index-col{border-left:0;border-top:1px solid var(--brd)}}
@container (max-width:480px){.pd-index-col{padding:22px 18px}.pd-index-names{grid-template-columns:minmax(0,1fr)}}
.pd-reg{padding:8px 22px;font-size:14px;width:100%;max-width:560px;justify-self:end}
.pd-reg .mk-sw-row{min-height:50px}
.pd-reg-v{font-size:12.5px;color:var(--t3);white-space:nowrap}
.pd-tier{display:inline-block;margin:0 0 16px;font-size:12.5px;font-weight:500;color:var(--t2);background:var(--white);border:1px solid var(--brd);border-radius:999px;padding:4px 12px}
.pd-feats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:44px 40px}
.pd-feat{border-top:1px solid var(--brd);padding-top:20px}
.pd-feat h3{font-size:16px;margin:0 0 8px}
.pd-feat p{font-size:14px;line-height:1.6;color:var(--t3);margin:0}
@container (max-width:1000px){.pd-feats{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container (max-width:600px){.pd-feats{grid-template-columns:minmax(0,1fr)}}
.pd-fmt-wrap{overflow-x:auto;border:1px solid var(--brd);border-radius:12px;background:var(--white);box-shadow:0 1px 2px rgba(13,28,46,.04),0 16px 36px -16px rgba(13,28,46,.14)}
.pd-fmt{width:100%;border-collapse:collapse;font-size:14px;min-width:560px}
.pd-fmt th,.pd-fmt td{padding:16px 22px;text-align:left;vertical-align:top;border-top:1px solid var(--brd);letter-spacing:0;text-transform:none}
.pd-fmt thead th{border-top:0;background:var(--card-head);font-size:12px;font-weight:600;color:var(--t3);padding-block:12px}
.pd-fmt tbody th{font-size:14px;font-weight:600;color:var(--t1);white-space:nowrap;background:none;width:26%}
.pd-fmt td.mk-fig{width:9%}
.pd-fmt td{color:var(--t2);line-height:1.55}
.pd-fmt td.mk-fig{color:var(--t1)}
/* Third-party trademark attribution (Intuit brand terms, AP-46; FreeAgent,
   AP-47): required on a page that names them, quiet by design. */
.brand-attrib{font-size:11.5px;color:var(--t3);line-height:1.55;margin:20px 0 0}

/* ── BLOG (SITE CALM 2026-09-24) ──────────────────────────────────────────
   The index is a dated list read top to bottom (founder, 2026-08-04: not a
   grid), with no cards and no tag pills. An article is a centred reading
   column at 17px, reversing the 2026-08-04 full-width text: the dead space
   that call fixed was a LEFT-aligned narrow column, and centring removes it
   without a 1,280px line. */
.bl-list{margin-top:8px;border-top:1px solid var(--brd)}
.bl-row{display:grid;grid-template-columns:160px minmax(0,1fr);gap:8px 40px;padding:26px 0;border-bottom:1px solid var(--brd);text-decoration:none;color:inherit}
.bl-meta{display:flex;flex-direction:column;font-size:13px;line-height:1.6;color:var(--t3)}
.bl-main{display:flex;flex-direction:column;gap:6px;max-width:760px}
.bl-t{font-size:19px;font-weight:600;letter-spacing:-.02em;line-height:1.3;color:var(--t1);transition:color 120ms}
.bl-s{font-size:15px;line-height:1.6;color:var(--t3)}
.bl-row:hover .bl-t{color:var(--gh)}
.bl-row:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:4px;border-radius:4px}
@container (max-width:640px){.bl-row{grid-template-columns:minmax(0,1fr)}.bl-meta{flex-direction:row;gap:14px}}
.mk-crumbs{font-size:13.5px;margin:0 0 14px}
.mk-crumbs a{color:var(--t3);text-decoration:none}
.mk-crumbs a::before{content:"\2190";margin-right:6px}
.mk-crumbs a:hover{color:var(--gh)}
.mk-reading{max-width:760px;margin-inline:auto}
.mkt-static .mk-reading h1{font-size:clamp(30px,3.3vw,42px);line-height:1.12;letter-spacing:-.035em;margin-bottom:16px}
.mk-reading .lead{font-size:19px;line-height:1.6;font-weight:400;color:var(--t2);max-width:none;margin-bottom:16px}
.mk-reading .legal-updated{margin:0 0 8px;padding-bottom:24px;border-bottom:1px solid var(--brd)}
.article-backline{margin-top:36px;font-size:15px}
.article-backline a{color:var(--gh);text-decoration:none}
.article-backline a:hover{text-decoration:underline}
.article-body{padding:0}
/* Founder round 2026-08-04: article text FILLS THE SCREEN like every other
   page (the round-4 "no narrow reading columns" rule) — the 680px caps left
   two-thirds of the article card as dead white space on a wide monitor.
   That was the dead-space complaint; the index list layout was fine. */
.article-body p{font-size:17px;color:var(--t2);line-height:1.75;margin:18px 0 0}
.article-body h4{font-size:21px;font-weight:700;color:var(--t1);margin:40px 0 0;letter-spacing:-.02em;line-height:1.3}
.article-body ul,.article-body ol{margin:14px 0 0;padding-left:22px}
.article-body li{font-size:17px;color:var(--t2);line-height:1.7;margin-bottom:8px}
.article-body strong{color:var(--t1)}
.article-note{font-size:13.5px;color:var(--t3);margin-top:36px;padding:16px 18px;background:var(--white);border-radius:10px;line-height:1.65}

/* ── CHANGELOG — month index + entries ─────────────────────────────────
   Relaid 2026-09-10 (founder call). Was a 640px left-anchored timeline rail
   drawn to sit beside the sidebar; with the rail parked for signed-out
   visitors the right half of the screen was empty. Now a sticky month index
   on the left and the entries on the right, together spanning the 1280
   measure; each entry is a [kind | title + body] grid so the tag chips line
   up as a column. No per-entry dates: the page names only the month by
   design (the 2026-07-12 founder call in the template), so none is printed.
   The index sticks inside the scrolling .mkt-page; align-self:start gives it
   the whole grid row to travel in. Collapses on the page's OWN width
   (container queries), so the signed-in shell with the rail open stacks
   exactly like a narrow window. */
.cl-layout{display:grid;grid-template-columns:200px minmax(0,1fr);gap:64px;align-items:start;margin-top:8px}
/* top:0 reads as ~64px below the visible edge in Chromium/WebKit, which measure sticky offsets from the scroll container's CONTENT box (the page's 64px top padding); Firefox uses the padding box. Both land it readably; a negative top to "correct" Chromium would push it off-screen in Firefox. */
.cl-index{position:sticky;top:0;align-self:start;display:flex;flex-direction:column;gap:2px;padding-top:6px}
.cl-index-lbl{font-size:13px;font-weight:600;color:var(--t1);margin-bottom:8px;padding-left:12px}
.cl-index a{font-size:13.5px;font-weight:500;color:var(--t3);text-decoration:none;padding:7px 12px;border-radius:var(--r);transition:color 120ms,background 120ms}
.cl-index a:hover{color:var(--t1);background:var(--white)}
.cl-index a:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:2px}
.cl-list{margin:0}
/* Month subhead — emitted once per month run (not on every entry). */
.cl-anchor{scroll-margin-top:24px} /* the index target: an empty sibling before each month header, so the header line itself stays verbatim (append-only page) */
.cl-month{font-size:21px;font-weight:700;color:var(--t1);letter-spacing:-.02em;display:flex;align-items:center;gap:16px;margin:0 0 4px;padding-top:6px}
.cl-month::after{content:'';flex:1;height:1px;background:var(--brd)}
.cl-item + .cl-anchor{margin-top:40px} /* the month gap sits on the anchor, so a jump lands on the header, not 40px above it */
.cl-item{display:grid;grid-template-columns:132px minmax(0,1fr);column-gap:28px;padding:24px 0;border-bottom:1px solid var(--brd)}
.cl-item:last-child{border-bottom:0}
.cl-t{grid-column:2;font-size:17px;font-weight:600;color:var(--t1);letter-spacing:-.015em;margin-bottom:8px}
.cl-b{grid-column:2;font-size:15px;color:var(--t2);line-height:1.7;max-width:760px}
.cl-tags{grid-column:1;grid-row:1 / span 2;display:flex;flex-direction:column;align-items:flex-start;gap:6px;margin:2px 0 0}
@container (max-width:900px){
  .cl-layout{grid-template-columns:1fr;gap:28px}
  .cl-index{position:static;flex-direction:row;flex-wrap:wrap;gap:6px;padding-top:0}
  .cl-index-lbl{flex-basis:100%;padding-left:0}
  .cl-index a{border:1px solid var(--brd);background:var(--white)}
}
@container (max-width:600px){
  .cl-item{grid-template-columns:1fr;column-gap:0}
  .cl-t,.cl-b{grid-column:1}
  .cl-tags{grid-column:1;grid-row:auto;order:3;flex-direction:row;flex-wrap:wrap;margin-top:10px}
}
/* The entry's kind, said quietly (SITE CALM 2026-09-24: were tinted pills). */
.cl-tag{display:inline-block;font-size:12.5px;font-weight:500;color:var(--t3)}
.cl-tag-improve{color:var(--t3)}
.cl-tag-compliance{color:var(--t3)}

/* ── ABOUT / DEMO / CONTACT shared bits ───────────────────────────────── */
.about-quote{border-left:3px solid var(--g);padding:2px 0 2px 20px;margin:0 0 28px;font-size:21px;line-height:1.5;color:var(--t1);font-weight:500;letter-spacing:-.01em;max-width:600px}
.about-body p{font-size:16px;color:var(--t2);line-height:1.75;margin-bottom:16px;max-width:600px}
.about-body p strong{color:var(--t1)}
.ib-stack{display:flex;flex-direction:column}
.ib-stack > div{padding:14px 0;border-bottom:1px solid var(--brd)}
.ib-stack > div:last-child{border-bottom:0;padding-bottom:0}
.principle-t{font-size:14.5px;font-weight:600;color:var(--t1);margin-bottom:4px}
.principle-b{font-size:14px;color:var(--t3);line-height:1.6}
.expect-item{display:flex;gap:12px}
.expect-n{font-family:var(--mono);font-size:13px;color:var(--t3);flex-shrink:0;padding-top:1px}
.expect-t{font-size:14.5px;font-weight:600;color:var(--t1);margin-bottom:4px}
.expect-b{font-size:14px;color:var(--t3);line-height:1.55}
.principle-b a{color:var(--gh);font-weight:500;text-decoration:none}
.principle-b a:hover{text-decoration:underline}
.form-note{font-size:12.5px;color:var(--t3);margin-top:10px;line-height:1.55}
.legal-updated{font-family:var(--mono);font-size:12px;color:var(--t3);letter-spacing:.02em;margin:-8px 0 36px}

/* ── PUBLIC FACE — ≤760px mobile pass (2026-07-12) ─────────────────────────
   Completes the marketing single-column collapse for the round-2 components.
   MUST stay AFTER those components' ≤1100px tablet rules, which live above
   and share specificity —
   source order is what lets these win at ≤760px. (Historically "end of the
   file"; the Site v4 section and the MOBILE NAV shell block now follow — the
   tail order is: component rules → this block → Site v4 → MOBILE NAV last.)
   The classic marketing grids (.pricing-grid/.form-row) collapse in the
   ≤760px block next to their base rules. */
@media (max-width:760px){
  /* About's stat band lives here (not in the block by its base rule — the
     base .stat-grid rule follows that block in source and would win the
     specificity tie). */
  .stat-grid{grid-template-columns:1fr}
  /* SITE CALM rhythm on a phone: 96px between sections is most of a screen. */
  .mk-sec,.easy-half,.rollup-band{padding-top:72px}
  .mk-band{margin-top:72px;padding-bottom:72px}
  .cta-band{margin-top:72px;padding:28px 22px}
}

/* ══════════════════════════════════════════════════════════════════════════
   Site v4 — standalone marketing/utility pages (templates/marketing/*).
   They wear the SAME shell as the app: flex body → dark sidebar (the shared
   partial in sb_static mode) + .main → slim topbar + scrolling .content — a
   visitor moving between the app and the marketing pages never loses the
   navigation rail. Auth-aware chrome keys off the pre-paint
   html[data-nd-authed] attribute (stored token, or the local dev shim),
   scoped to body.mktd so the SPA's JS-driven data-auth-* toggling is
   untouched.
   ══════════════════════════════════════════════════════════════════════════ */
/* Anchor-mode nav entries (the static sidebar renders anchors where the SPA
   renders buttons) — keep the button visuals. */
a.nav-item,a.tool-item{text-decoration:none;box-sizing:border-box}
/* Static app-nav: hidden until the pre-paint check finds a session. */
.appnav-static{display:none}
html[data-nd-authed] .appnav-static{display:block}
/* Role-gated static entries (Plan & billing / Team / Access / Leads / Admin):
   hidden until mktshell.js confirms the session's role and adds .granted. The
   descendant selectors are (0,2,0)/(0,3,0) to out-specify .tool-item{display:
   flex} (0,1,0) — the #165 specificity lesson (a bare .appnav-role would tie
   and depend on source order). */
.appnav-static .appnav-role{display:none}
.appnav-static .appnav-role.granted{display:flex}
/* Anon control on static pages (sidebar foot + topbar "Sign in"): hidden
   once the pre-paint authed attribute lands. (The authed sbf workspace CTAs
   — and their #165 specificity pair — were REMOVED in round 7 by founder
   call: the hydrated workspace nav covers signed-in visitors, so no authed
   anchor remains to show/hide.) */
html[data-nd-authed] .sbf-anon{display:none}
/* SPA analog (2026-07-24): the top-right #tbSignIn is the ONE signed-out
   control (the footer #footGuest was removed). It defaults visible (.exp-btn
   display:flex) so a signed-out visitor sees it FROM FIRST PAINT — the pre-paint
   data-nd-deeplink attribute (index.html sets it iff a token exists) hides it
   for a token-holder so they never flash it; _syncAuditChrome's inline display
   is authoritative once the async session resolves. Mirrors the static-shell
   `html[data-nd-authed] .sbf-anon` hide. */
html[data-nd-deeplink] #tbSignIn{display:none}
a.btn-signin{display:block;text-align:center;text-decoration:none}
/* In-page auth-aware CTAs on the ported pages (cta-bands etc.). */
.mktd [data-auth-user]{display:none}
html[data-nd-authed] .mktd [data-auth-user]{display:inline-flex}
html[data-nd-authed] .mktd [data-auth-anon]{display:none}
/* CTA anchors: the ported partials swapped onclick <button>s for real-route
   <a>s — keep the button visuals on the anchor form. */
a.btn-primary,a.btn-cta-ghost,a.btn-secondary{display:inline-flex;align-items:center;justify-content:center;text-decoration:none;box-sizing:border-box}

/* ── Site v4 §2.2 — home scroll-story + sandbox ─────────────────────────────
   Reveals are OPT-IN via html.motion-ok (story.js stamps it only when the
   visitor has not asked for reduced motion AND IntersectionObserver exists):
   the default state — no JS, reduced motion, old browser — is fully visible
   with zero movement. One quiet move per section; the sandbox is the page's
   one loud element. */
html.motion-ok .story-sec{opacity:0;transform:translateY(18px);transition:opacity 480ms ease,transform 480ms ease}
html.motion-ok .story-sec.story-vis{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  html.motion-ok .story-sec{opacity:1;transform:none;transition:none}
}

/* The sandbox — phase 2 of the home-demo artifact: mounts INSIDE the demo
   card's result panel when the cinematic finishes (one artifact, founder
   call 2026-07-14). */
.demo-sandbox{margin-top:14px;padding-top:14px;border-top:1px solid var(--brd)}

/* Handover mode: mounting the sandbox flips .home-demo into .sbx-mode — the
   PDF facsimile retires (the editable fields ARE the document now) and the
   result panel takes the whole card, with the invoice paper on the left and
   the live verdict on the right. Without this the A4 sheet column stretched
   to the sandbox's height as dead whitespace (founder feedback 2026-07-14). */
/* overflow:visible — the card's overflow:hidden exists to clip the PDF
   panel's dark background against the rounded corners; with the PDF retired
   it only kills position:sticky (an ancestor clip box becomes the sticky
   container). Sandbox content is padding-inset, so nothing pokes the corners. */
.home-demo.sbx-mode{overflow:visible}
.home-demo.sbx-mode .demo-sbx-s{max-width:none}
@media (min-width:901px){
  .home-demo.sbx-mode .sbx-root{grid-template-columns:1.04fr .96fr;gap:20px}
  /* The verdict column is the taller one — sticking the invoice paper keeps
     the fields in view while the reader scrolls the check list, so an edit
     and the check it flips stay on screen together. */
  .home-demo.sbx-mode .sbx-fields{position:sticky;top:14px}
}
/* The fields column reads as the document itself — a bounded sheet of paper,
   not a loose grid floating in the panel. */
.sbx-fields{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);padding:16px 18px 12px;box-shadow:var(--sh)}
.demo-sbx-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}
.demo-sbx-t{font-size:14px;font-weight:600;color:var(--t1);letter-spacing:-.01em}
.demo-sbx-s{font-size:12.5px;color:var(--t3);line-height:1.55;margin-top:2px;max-width:340px}
.sbx-reset{padding:7px 14px;font-size:12.5px;flex-shrink:0}
.sbx-root{display:grid;grid-template-columns:1fr;gap:16px;align-items:start}
.sbx-foot{margin-top:12px;font-size:11.5px;color:var(--t3)}

/* Field grid (left panel) */
.sbx-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px}
.sbx-field{background:var(--bg);border:1px solid var(--brd);border-radius:var(--r-lg);padding:9px 12px}
.sbx-wide{grid-column:1 / -1}
.sbx-lbl{font-size:9.5px;font-weight:600;color:var(--t3);letter-spacing:.07em;text-transform:uppercase;margin-bottom:3px}
.sbx-inp{width:100%;border:0;background:transparent;font:inherit;font-size:13.5px;color:var(--t1);padding:2px 0;border-bottom:1px dashed transparent;transition:border-color 120ms}
.sbx-inp:hover{border-bottom-color:var(--brd-md)}
.sbx-inp:focus{outline:none;border-bottom-color:var(--g)}
/* The dashed underline is the same colour :hover already paints, so keyboard
   focus was indistinguishable from a mouse hovering elsewhere (T2.21). */
.sbx-inp:focus-visible{outline:2px solid var(--g);outline-offset:1px}
.sbx-lines{width:100%;border-collapse:collapse;margin-bottom:14px;font-size:13px}
.sbx-lines th{text-align:left;font-size:9.5px;font-weight:600;color:var(--t3);letter-spacing:.07em;text-transform:uppercase;padding:6px 8px;border-bottom:1px solid var(--brd)}
.sbx-lines td{padding:4px 8px;border-bottom:1px solid var(--brd)}
.sbx-lines .sbx-inp{font-family:'DM Mono',monospace}
.sbx-lines td:first-child .sbx-inp{font-family:inherit}
.sbx-num{text-align:right}
.sbx-lines th:nth-child(n+2),.sbx-lines td:nth-child(n+2){width:88px;text-align:right}
.sbx-totals{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
.sbx-totals .sbx-inp{font-family:'DM Mono',monospace;font-size:14.5px;font-weight:500}

/* Verdict panel — the REAL .guardian-score card renders here; only the
   sandbox-specific note needs styling. */
.sbx-verdict{position:static}
.sbx-note{margin-top:10px;font-size:12px;color:var(--t3);line-height:1.6;background:var(--bg);border:1px solid var(--brd);border-radius:var(--r-lg);padding:10px 12px}

@media (max-width:900px){
  .sbx-grid{grid-template-columns:1fr}
}
/* ≤760px (site walkthrough 2026-09-05): at 375px the three 88px numeric
   columns squeezed the DM Mono line totals to "174.…". Fixed layout gives the
   numeric columns a width that fits "1,234.00" and hands whatever is left to
   the description — the description is the column that can wrap, a figure is
   not. */
@media (max-width:760px){
  .sbx-lines{table-layout:fixed}
  .sbx-lines th:first-child,.sbx-lines td:first-child{width:auto}
  .sbx-lines th:nth-child(n+2),.sbx-lines td:nth-child(n+2){width:70px;padding-left:4px;padding-right:4px}
  .sbx-lines .sbx-inp{min-width:0;font-size:12.5px}
}
/* Sandbox at true phone widths (≤430px): three 88px numeric columns + the
   description column overflow the ~310px sheet interior at 390px — narrow
   the numeric columns and stack the totals trio so nothing scrolls sideways. */
@media (max-width:430px){
  .sbx-lines th:nth-child(n+2),.sbx-lines td:nth-child(n+2){width:66px}
  .sbx-totals{grid-template-columns:1fr}
}

/* ── Site v4 §2.4 — utility pages (/vat-number-checker, /time-saved-calculator)
   Relaid 2026-09-10 (founder call) for the centred 1280 measure: the checker
   is a tool CARD beside its explanation column; the calculator is one
   full-measure card, inputs on the left half and the live result on the
   right, with the assumptions as a three-column strip beneath. Both collapse
   on the PAGE's own width (container queries on .mkt-page), so the signed-in
   shell with the rail open stacks like a narrow window would. */
.util-card{background:var(--white);border:1px solid var(--brd);border-radius:14px;box-shadow:0 1px 2px rgba(13,28,46,.04),0 16px 36px -16px rgba(13,28,46,.16);padding:28px}
.util-split{display:grid;grid-template-columns:minmax(0,520px) minmax(0,1fr);gap:48px;align-items:start;margin:8px 0 64px}
.util-aside{display:flex;flex-direction:column;gap:26px;padding-top:4px}
.util-aside-item{padding-top:18px;border-top:1px solid var(--brd)}
.util-aside h3{margin-bottom:6px}
.util-aside p{font-size:15px;color:var(--t2);line-height:1.7}
.vc-tool{margin:0}
.vc-input{font-family:'DM Mono',monospace;font-size:16px;letter-spacing:.04em;text-transform:uppercase}
.vc-result{display:block;margin-top:14px;padding:14px 16px;border-radius:var(--r-lg);border:1px solid var(--brd);background:var(--bg);font-size:14px;line-height:1.6}
.vc-result p{margin:0 0 6px}
.vc-mono{font-family:'DM Mono',monospace}
/* SCOPED to the public checker's result box (T2.21). Unscoped, this second
   `.vc-dot` won on source order and silently re-styled the VAT-Check TOOL's
   dot too (defined at the .vc-hero-lbl rule above): it added an 8px margin
   the flex `gap:7px` already supplies, and dropped `flex-shrink:0`, so the
   dot could be squashed by a long label. Two surfaces, two owners, one class
   name — the rule that does not own the token gets the scope. */
.vc-result .vc-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:8px;vertical-align:1px}
.vc-dot-ok{background:var(--ok)}
.vc-dot-warn{background:var(--warn)}
.vc-dot-fail{background:var(--fail)}
.vc-pass{border-color:rgba(5,150,105,.35)}
.vc-fail{border-color:rgba(220,38,38,.3)}
.vc-note{font-size:12.5px;color:var(--t3);margin-top:8px}
/* Calculator: one card, two halves. The result half carries a quiet inset
   ground so the headline figures read as the OUTPUT of the inputs beside
   them rather than a second form. */
.tc-tool{margin:8px 0 28px;padding:0;overflow:hidden}
.tc-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.tc-inputs{display:grid;grid-template-columns:1fr;gap:18px;padding:32px}
.tc-output{background:var(--inset);border-left:1px solid var(--brd);padding:32px;display:flex;flex-direction:column;justify-content:center;min-width:0}
.tc-output-lbl{font-size:14px;font-weight:600;color:var(--t2);margin-bottom:18px}
.tc-figures{display:flex;flex-direction:column;gap:22px}
.tc-fig .tc-val{font-family:'DM Mono',monospace;font-size:44px;font-weight:500;color:var(--t1);letter-spacing:-.03em;line-height:1.05;overflow-wrap:anywhere}
.tc-fig .tc-lbl{font-size:12.5px;color:var(--t3);margin-top:4px}
.tc-plan{margin-top:22px;padding-top:18px;border-top:1px solid var(--brd);font-size:14px;color:var(--t2);line-height:1.6}
.tc-assumptions{padding-top:40px}
.tc-assumptions h2{font-size:22px;margin-bottom:18px}
.tc-assumptions-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.tc-assumption{padding-top:18px;border-top:1px solid var(--brd)}
.tc-assumption > strong{display:block;font-size:15px;font-weight:600;color:var(--t1);margin-bottom:6px} /* the heading only; a <strong> inside the body stays inline */ /* the card's heading only; a <strong> inside the body stays inline */
.tc-assumption p{font-size:14.5px;color:var(--t2);line-height:1.65}
@container (max-width:1000px){
  .util-split{grid-template-columns:1fr;gap:32px}
  .tc-assumptions-grid{grid-template-columns:1fr}
}
@container (max-width:820px){
  .tc-grid{grid-template-columns:1fr}
  .tc-output{border-left:0;border-top:1px solid var(--brd)}
}
@media (max-width:760px){
  .util-card{padding:22px 20px}
  .tc-tool{padding:0} /* the calculator card pads its two halves, not itself; without this the .util-card rule above (same specificity, later than .tc-tool's padding:0) double-padded it on phones */
  .tc-inputs,.tc-output{padding:22px 20px}
  .tc-fig .tc-val{font-size:36px}
}

/* ── Site v4 §2.5 — product-tour video embed (conditional on the asset).
   The player lives ONLY on /product, under the lead (moved from /demo
   2026-08-07). The .tour-video-link pointer that /product used to carry went
   with it — a link to a page that no longer hosts the tour is a dead promise. */
.tour-video{max-width:1280px;margin:8px 0 48px} /* the page measure (2026-09-10 width pass); 880 left the right fifth of the measure empty */
.tour-video video{width:100%;height:auto;border-radius:14px;border:1px solid var(--brd-md);box-shadow:var(--sh-sm);background:#0b1220}
.tour-video-note{margin-top:8px;font-size:12.5px;color:var(--t3)}
/* Silent expect-item micro-loops on /demo (Hyperframes cuts from the tour).
   Conditional on static/video/loops/ existing; degrade to text alone when
   absent. They no longer gate on the tour player — it moved to /product. */
.expect-loop{display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;
  border-radius:9px;border:1px solid var(--brd);background:var(--bg);margin-bottom:9px}
@media (prefers-reduced-motion:reduce){.expect-loop{display:none}}

/* ── Round-3 hover life (founder: the site reads too static — "wiggle when
   moused over"). Two tiers, one personality: divider-grid cells (cred /
   price / stat share 1px grid seams, so they must NOT translate) get
   edge-safe life — a background wash, an emerald baseline sweeping in, and
   their icon or number springing; standalone bordered cards lift STRAIGHT
   (round 4: the earlier rotate read as skew — no tilt anywhere, boxes move
   exactly like the other interactive cards). The overshoot curve gives the
   life. Hover-capable pointers only; reduced-motion loses all movement. */
/* Restyle round 5 (2026-08-08): this block is BACK to main's exact hover
   grammar — the round-1 "calmed" rewrite flattened the price-pop the founder
   explicitly liked on the live site ("the price jumped out at you when you
   hovered"). Founder call beats the anti-slop rule here; do not re-calm. */
@media (hover:hover) and (prefers-reduced-motion:no-preference){
  .price-card{transition:background 160ms ease,box-shadow 220ms ease}
  .price-card:hover{background:#fafcfe;box-shadow:inset 0 -2px 0 var(--g)}
  .price-card.featured:hover{box-shadow:0 0 0 1px var(--g),inset 0 -2px 0 var(--g),0 18px 40px -20px rgba(5,150,105,.35)}
  .price-amt{transition:transform 340ms cubic-bezier(.34,1.56,.64,1),color 160ms ease}
  .price-card:hover .price-amt{transform:translateY(-2px) scale(1.03);color:var(--gh)}
}

/* ── Extract: document scan-in-progress (2026-08-06) ──────────────────────
   While a single-upload extraction runs, a thin emerald line sweeps down and
   back up the source-document preview — the document is visibly "being read".
   Host is the existing .dropzone (already position:relative + overflow:hidden);
   extract.js startDocScan/stopDocScan own the element's lifecycle, bounded by
   the request (finally) — the loop never outlives the extraction. Batch has no
   per-document preview, so it never mounts one. Reduced motion hides the line
   entirely; the results-panel loader still communicates progress. */
@keyframes nd-scan {
  0%   { top: 2%; }
  50%  { top: 96%; }
  100% { top: 2%; }
}
.nd-scanline {
  position: absolute;
  left: 0;
  right: 0;
  top: 2%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--g) 50%, transparent);
  box-shadow: 0 0 12px rgba(5, 150, 105, .5);
  animation: nd-scan 3s ease-in-out infinite;
  pointer-events: none;
  z-index: 2;
}
@media (prefers-reduced-motion: reduce) {
  .nd-scanline { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PREMIUM RESTYLE — 2026-08-08 founder brief ("high-end product, clean
   finishes, premium loading states, less colours everywhere").

   The system in one paragraph: colour is demoted to 6px dots and small mono
   figures — no tinted chip backgrounds, no amber-bordered cards, no blue SKU
   columns. Ink and hairlines carry hierarchy. Emerald keeps its five jobs
   (primary action, focus, active nav, confidence-high, brand). Surfaces are
   toned, not stark: canvas deepened one step (--bg #eef2f7), every card gets
   a quiet --card-head header strip and hairline-divided cells. Loading is
   staged and quiet — checklist + one thin sweep, never a spinner. Type goes
   editorial: mono uppercase eyebrows over light-300 titles.

   This layer is an APPENDED override pass — source order wins the ties, so
   the recipes above keep their anatomy and this file's tail owns the look.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Shared loop keyframes (the ONLY allowed loops: sweep / shimmer / blink) */
@keyframes ndBlink{0%,100%{opacity:1}50%{opacity:.3}}
@keyframes ndSweep{from{transform:translateX(-110%)}to{transform:translateX(360%)}}
@keyframes ndRowShimmer{from{background-position:200% 0}to{background-position:-200% 0}}

/* ── 1 · Ledger cards ─────────────────────────────────────────────────────
   One white card, hairline border, 12px radius, quiet shadow; header strips
   on --card-head; stat bands + field grids become 1px-gap hairline cells. */

/* Card header strips */
thead{background:var(--card-head)}
th{font-size:9.5px;letter-spacing:.12em;color:var(--t4);padding:10px 14px}
.hist-head-labels{background:var(--card-head)}
.manual-lbl{background:var(--card-head);font-size:9.5px;letter-spacing:.12em;color:var(--t4);padding:10px 14px;border-bottom:1px solid #eef2f7}
.panel-hdr{padding:13px 20px 11px;border-bottom:1px solid var(--brd);background:var(--card-head)}
.panel-t{font-size:9.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--t4)}
.audit-hdr{background:var(--card-head);padding:13px 18px 11px}
.audit-t{font-size:9.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--t4)}
.slbl{font-size:9.5px;letter-spacing:.12em;color:var(--t4);font-weight:600}
.slbl::after{background:transparent}

/* (Field-grid ledger rules retired 2026-09-10 — Extract v5 renders .xr-row rows.) */
/* Confidence dot leads the label, both LEFT-aligned (founder review row 4:
   margin-left:auto here shoved the whole dot+label cluster to the right
   edge — the dot precedes the text in the DOM, so the auto margin moved
   both). Only the dot shrinks to 5px; alignment stays the base flex. */
.field-lbl .conf-dot{width:5px;height:5px}

/* Stat bands (Batch header · History summary · insights · VAT metrics ·
   Admin KPIs) → hairline-divided cells inside one bordered band. */
.batch-stats,.hist-stats,.bi-stats,.vc-metrics{gap:1px;background:#eef2f7;border:1px solid var(--brd);border-radius:var(--r-lg);overflow:hidden;box-shadow:0 1px 3px rgba(13,28,46,.05)}
.batch-stat-cell,.hist-stat,.bi-stat,.vc-metric-card{border:none;border-radius:0;box-shadow:none;background:var(--white)}
.batch-stat-cell:hover,.hist-stat:hover,.bi-stat:hover,.vc-metric-card:hover{box-shadow:none;transform:none}
/* Kill the coloured top keylines — the label dot (below) carries the state. */
.batch-stat-cell::before,.vc-metric-card::before{display:none}
/* Numbers are ink; colour rides a 6px dot beside the label. */
.batch-stat-val,.bsv-ok,.bsv-warn,.bsv-fail{color:var(--t1)}
.bsv-skip{color:var(--t3)}
.batch-stat-cell .batch-stat-lbl::before,.vc-metric-card .vc-metric-lbl::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--brd-str);margin-right:6px;vertical-align:1px}
.batch-stat-cell.bsc-ok .batch-stat-lbl::before,.vc-metric-card.vc-ok .vc-metric-lbl::before{background:var(--ok)}
.batch-stat-cell.bsc-warn .batch-stat-lbl::before,.vc-metric-card.vc-warn .vc-metric-lbl::before{background:var(--warn)}
.batch-stat-cell.bsc-fail .batch-stat-lbl::before{background:var(--fail)}
.batch-stat-cell.bsc-skip .batch-stat-lbl::before{background:var(--brd-str)}
/* Neutral cells keep no dot — only stat cells that CARRY a state get one. */
.batch-stats > .batch-stat-cell:first-child .batch-stat-lbl::before{content:none}
.stat-ic{background:var(--inset)}

/* Guardian score card: white ledger card — no coloured left spine, no tinted
   border. State lives in the dial, the row dots, and the header strip. */
.guardian-score{border-left-width:1px;border-left-color:var(--brd);position:relative}
.guardian-score.has-fail,.guardian-score.has-warn,.guardian-score.has-checking,.guardian-score.all-pass{border-color:var(--brd);border-left-color:var(--brd)}
.gsc-header{background:var(--card-head);border-bottom:1px solid #eef2f7}
.gsc-header:hover{background:var(--inset)}
.gsc-body{background:var(--white);border-top:none}
.gsc-title{font-size:12.5px}
/* While a recheck is in flight: a thin emerald sweep along the card's top
   edge replaces the old dial opacity pulse (pulse washes are banned). */
.guardian-score.has-checking .gsc-dial{animation:none}
.guardian-score.has-checking::after{content:'';position:absolute;top:0;left:0;width:40%;height:2px;background:linear-gradient(90deg,transparent,var(--g),transparent);animation:ndSweep 1.6s ease-in-out infinite}
/* Checking rows: blinking dot, not a spinner. */
.gsc-checking .gsc-dot{width:7px;height:7px;border:none;background:var(--info);animation:ndBlink 1.4s ease-in-out infinite;border-radius:50%}
/* Citation right-aligned in mono; edit action stays a quiet text action. */
.cite-arrow{font-family:var(--mono);font-weight:500}
.gsc-edit-btn{background:none;border:none;padding:3px 4px;font-weight:600}
.gsc-edit-btn:hover{background:var(--glo)}
/* Legacy fallback banner: white, never amber-washed. */
.guardian.issues{border-color:var(--brd);background:var(--white)}

/* Cards that stay standalone get the standard quiet chrome. */
.batch-insights,.tl-card,.owner-card,.vc-strips,.batch-progress,.table-card{box-shadow:0 1px 3px rgba(13,28,46,.05)}
.bi-header{padding-bottom:10px;border-bottom:1px solid #eef2f7;margin-bottom:14px}
.bi-title{font-size:9.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--t4)}
.tl-hdr{padding-bottom:10px;border-bottom:1px solid #eef2f7}
.bi-stat{background:var(--white)}

/* ── 2 · Status strip: "what is the system doing", where the user is looking ─ */
/* A full-width band at the top of the Extract output pane (above the fields),
   replacing the topbar pill — founder 2026-09-04: a pill, however tinted,
   "still gets lost with everything going on". Tone-filled: working = info
   tint + pulsing dot + an indeterminate progress line along the bottom edge;
   ok / warn / err = the confidence-light tints. sp-idle is never shown. */
.status-strip{display:flex;align-items:center;gap:10px;position:relative;flex-shrink:0;box-sizing:border-box;height:40px;padding:0 30px;overflow:hidden;font-size:13px;font-weight:600;letter-spacing:.01em;border-bottom:1px solid var(--brd);background:var(--card-head);color:var(--t2);transition:background 160ms,color 160ms,border-color 160ms,height 160ms ease}
/* Collapsed, not display:none — the aria-live region stays in the tree. */
.status-strip.sp-hidden{height:0;border-bottom-width:0}
.status-strip::before{content:'';width:9px;height:9px;border-radius:50%;background:var(--brd-str);flex-shrink:0}
.status-strip::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:2px;background:currentColor;opacity:0;transform-origin:left;transform:scaleX(0)}
.sp-idle{background:var(--card-head);color:var(--t4);border-bottom-color:var(--brd)}
.sp-proc{background:var(--info-bg);color:var(--info);border-bottom-color:var(--info-brd)}
/* The strip's own text colours, NOT the shared --ok/--warn tokens: on their
   own tinted grounds those measure 3.43:1 and 4.39:1, both under WCAG AA's
   4.5:1 (audit 2026-09-04). This is the component made deliberately prominent
   so people could read it. Scoped here rather than changed at the token level,
   because --ok/--warn are used as text in 47 other places on their own
   backgrounds. --gh2 is the existing deep green (7.00:1 here); #92400e is the
   amber one step darker (6.20:1). Dots and borders keep the original hues, so
   the traffic-light reads identically. */
.sp-ok{background:var(--ok-bg);color:var(--gh2);border-bottom-color:var(--ok-brd)}
.sp-warn{background:var(--warn-bg);color:#92400e;border-bottom-color:var(--warn-brd)}
.sp-err{background:var(--fail-bg);color:var(--fail);border-bottom-color:var(--fail-brd)}
.sp-proc::before{background:var(--info);animation:ndBlink 1.4s ease-in-out infinite}
.sp-proc::after{opacity:.55;animation:ndStripRun 1.4s ease-in-out infinite}
.sp-ok::before{background:var(--ok)}
.sp-warn::before{background:var(--warn)}
.sp-err::before{background:var(--fail)}
@keyframes ndStripRun{0%{transform:scaleX(0);transform-origin:left}45%{transform:scaleX(1);transform-origin:left}55%{transform:scaleX(1);transform-origin:right}100%{transform:scaleX(0);transform-origin:right}}
@media (prefers-reduced-motion:reduce){.sp-proc::after{animation:none;transform:scaleX(1)}.status-strip{transition:none}}

/* Batch per-row chips: same capsule; the icon/dot carries the colour. */
.batch-st{background:var(--card-head);border-color:var(--brd);color:var(--t2)}
.bst-pass,.bst-review,.bst-error,.bst-manual,.bst-queued,.bst-processing{background:var(--card-head);border-color:var(--brd);color:var(--t2)}
.bst-pass svg{stroke:var(--ok)}
.bst-review svg{stroke:var(--warn)}
.bst-error svg{stroke:var(--fail)}
.bst-queued{color:var(--t4)}
/* Processing dot: blink, never spin. */
.bst-spin{width:6px;height:6px;border:none;background:var(--info);border-radius:50%;animation:ndBlink 1.4s ease-in-out infinite}
.bp-spin{width:7px;height:7px;border:none;background:var(--g);border-radius:50%;animation:ndBlink 1.4s ease-in-out infinite}

/* History compliance pills (dot element already in the anatomy). */
.history-pill--ok,.history-pill--warn,.history-pill--fail{color:var(--t2);background:var(--card-head);border-color:var(--brd)}
.history-pill--ok .history-pill-dot{background:var(--ok)}
.history-pill--warn .history-pill-dot{background:var(--warn)}
.history-pill--fail .history-pill-dot{background:var(--fail)}
.history-pill--muted{background:var(--card-head)}

/* Approval pills: capsule + dot (the --appr hues live in the dot only). */
.appr-pill{display:inline-flex;align-items:center;gap:6px}
.appr-pill::before{content:'';width:6px;height:6px;border-radius:50%;flex-shrink:0;background:var(--brd-str)}
.appr-pill--pending,.appr-pill--approved,.appr-pill--rejected{color:var(--t2);background:var(--card-head);border-color:var(--brd)}
.appr-pill--pending::before{background:var(--appr-wait);animation:ndBlink 1.8s ease-in-out infinite}
.appr-pill--approved::before{background:var(--appr-done)}
.appr-pill--rejected::before{background:var(--appr-rej)}

/* Informational pills (duplicate / re-upload / credit note / VAT defects). */
.dup-pill,.dup-pill--info,.cn-pill{color:var(--t2);background:var(--card-head);border-color:var(--brd);display:inline-flex;align-items:center;gap:6px}
.dup-pill::before,.cn-pill::before{content:'';width:6px;height:6px;border-radius:50%;flex-shrink:0}
.dup-pill::before{background:var(--warn)}
.dup-pill--info::before,.cn-pill::before{background:var(--info)}
/* Receipt pill (AP-48): a neutral slate dot, so a receipt and a credit note
   are told apart at a glance without a second colour family. */
.cn-pill--receipt::before{background:var(--t3)}
.vc-chip{color:var(--t2);background:var(--card-head);border-color:var(--brd);display:inline-flex;align-items:center;gap:6px}
.vc-chip::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--warn);flex-shrink:0}
.vc-section-count{color:var(--t2);background:var(--card-head);border-color:var(--brd)}
.tb-badge{color:var(--t2);background:var(--card-head);border:1px solid var(--brd);display:inline-flex;align-items:center;gap:6px}
.tb-badge::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--g);flex-shrink:0}
.ld-kind-demo,.ld-kind-contact{color:var(--t3);background:var(--card-head);border:1px solid var(--brd)}
.ro-pill{background:var(--card-head)}

/* ── 3 · Advisory banners: white cards, dot-marked — never a tinted wash ── */
.dup-banner{background:var(--white);border-color:var(--brd)}
.dup-banner--info{background:var(--white);border-color:var(--brd)}
.dup-view{background:var(--white);color:var(--warn);border:1px solid var(--brd-md)}
.dup-banner--info .dup-view{background:var(--white);color:var(--info)}
.dup-view:hover{opacity:1;border-color:var(--brd-str)}
.warn-banner{background:var(--white);border-color:var(--brd)}
.wb-b{color:var(--t2);opacity:1}
.wb-meta{color:var(--t4);opacity:1}
.vc-allclear{background:var(--white);border-color:var(--brd);color:var(--t1)}
.vc-allclear svg{stroke:var(--ok)}
.tm-seats-limit{background:var(--white);border-color:var(--brd);color:var(--t2)}
.mobile-banner{background:var(--card-head);border-bottom-color:var(--brd);color:var(--warn)}
.ph-card--warn{border-color:var(--brd-md);background:var(--white)}
.auth-error,.ar-error,.ld-error{background:var(--white);border-color:var(--fail-brd)}
.batch-row-dup{background:var(--inset)}
.hist-group-member.batch-row-dup>td{background:var(--inset)}

/* ── 4 · Confidence + semantics = dots only ──────────────────────────────── */
td.sku{color:var(--t3)}
.fi-med{color:var(--t1)}
.fi-user{color:var(--t1)}
.fi-low{color:var(--fail);font-weight:500}
/* Supplier avatars: one ink, not a rainbow — the initials are the signal. */
.hist-av-0,.hist-av-1,.hist-av-2,.hist-av-3,.hist-av-4,.hist-av-5{background:var(--inset);color:var(--t3);border:1px solid var(--brd)}
/* Audit timeline dots keep semantics; badges go quiet. */
.tl-badge{background:var(--card-head);border:1px solid var(--brd)}

/* ── 5 · Premium loading: shimmer rows (the staged checklist card was retired
   2026-09-10 with Extract v5 — the record reveals in read order instead) ── */
/* Batch working row: quiet white shimmer + blinking chip dot — the amber
   pulse is gone. Queued rows stay grey text, no chrome. */
.batch-row-active{animation:ndRowShimmer 2s linear infinite;background:linear-gradient(90deg,#fff 25%,#f4f9f7 50%,#fff 75%);background-size:200% 100%}
.batch-progress-track{background:#eef2f7}
.stat-pulse{animation:none}

/* Skeletons: keep (already shimmer); tone the base to the new canvas. */
.vc-skel{background:linear-gradient(90deg,#eef2f7 0%,#f7fafc 40%,#eef2f7 80%);background-size:200px 100%}

/* ── 6 · OTP boxes (login + MFA step-up) ─────────────────────────────────── */
.otp-row{display:flex;align-items:center;gap:8px;margin:2px 0 4px}
.otp-box{flex:1;min-width:0;height:48px;border-radius:9px;border:1px solid #eef2f7;background:var(--inset);font-family:var(--mono);font-size:17px;text-align:center;color:var(--t1);outline:none;caret-color:transparent;transition:border-color 120ms,background 120ms,box-shadow 120ms;padding:0}
.otp-box.filled{background:var(--white);border-color:var(--brd)}
.otp-box:focus{background:var(--white);border-color:var(--g);box-shadow:0 0 0 3px rgba(5,150,105,.08)}
/* A FULL-STRENGTH keyboard focus mark on the sign-in row. `outline:none` is
   set above for the mouse aesthetic, and the 8%-alpha halo that replaced it
   is not a replacement — measured in a real browser: outline "none 0px",
   box-shadow alpha 0.08, caret-color transparent. Three separate signals
   removed, on the one control every single user must operate, with nothing
   put back. The project's own rule (CLAUDE.md, menukeys.js): "outline:none
   needs a full-strength replacement." :focus-visible is keyboard-only, so
   the pointer look is unchanged. 2026-09-06 sweep, T2.21. */
.otp-box:focus-visible{outline:2px solid var(--g);outline-offset:2px;caret-color:var(--g)}
/* Blinking caret bar on the active empty box. */
.otp-box:focus:placeholder-shown{background-image:linear-gradient(var(--g),var(--g));background-repeat:no-repeat;background-size:1.5px 18px;background-position:center;animation:ndBlink 1.1s step-end infinite}
.otp-dash{width:10px;height:1.5px;background:var(--brd-str);border-radius:2px;flex-shrink:0}
.otp-hidden{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;border:0;padding:0}
.otp-resend-row{display:flex;align-items:center;gap:8px}
.otp-countdown{font-family:var(--mono);font-size:11.5px;color:var(--t4)}

/* ── 7 · History filters → underline tabs; segments stay hairline ────────── */
.hist-chip{background:none;border:none;border-radius:0;padding:9px 2px;font-size:12px;font-weight:600;color:var(--t3);border-bottom:2px solid transparent;transition:color 120ms,border-color 120ms}
.hist-chip:hover{color:var(--t1);border-bottom-color:var(--brd-str)}
.hist-chip-active{color:var(--t1);background:none;border-bottom-color:var(--g)}
.hist-chip-row{gap:14px;align-items:center}
/* Segmented controls (History scope + VAT period): inset track, raised
   white active cell — ink, not a green wash. */
.vc-period-tabs{background:var(--inset)}
.vc-tab.vc-tab-active{background:var(--white);color:var(--t1);border-color:var(--brd-md);box-shadow:var(--sh-xs)}
.hist-dd-opt.vc-tab-active{background:var(--inset);color:var(--t1);border-color:transparent}
.hist-search,.hist-date{border-radius:8px}

/* ── 8 · Charts: one ink, single-hue series + grey ───────────────────────── */
.gsc-section-bar,.bi-bar-track{background:#eef2f7}
.bi-ccy-0{background:var(--g)}
.bi-ccy-1{background:rgba(5,150,105,.7)}
.bi-ccy-2{background:rgba(5,150,105,.45)}
.bi-ccy-3{background:var(--brd-str)}
.bi-ccy-bar{background:#eef2f7}
.vc-reg-bar{background:#eef2f7}

/* ── 9 · Page headers: editorial — light titles under mono eyebrows ─────── */
.page-title{font-weight:300;font-size:23px;letter-spacing:-.02em}
/* The tool titles became h2 on 2026-09-08 (the SPA root served TEN h1s; a
   crawler reading the document saw nine app-screen titles competing with the
   marketing hero). The two element defaults that differ have to be restated
   or the demotion silently changes rendering: h1 is line-height 1.06 and sets
   no text-wrap, h2 is 1.15 and sets balance.

   ELEMENT-SCOPED, not on the bare class, because `.page-title` is NOT only
   worn by headings — history.js:1423 builds the History-detail title as
   `<div class="page-title hdd-title">`, which never had an h1 line-height to
   restate. Putting these on `.page-title` changed that div's rendering too,
   making the "the rendering is unchanged" claim false on a screen this work
   never touched (adversarial review, 2026-09-08).

   `text-wrap:wrap` is the initial value and the correct way to cancel h2's
   balance. `normal` belongs to white-space, is invalid on text-wrap, and is
   dropped by the parser — which leaves balance applying and the fix silently
   absent. The first cut shipped exactly that, and the pin that "guarded" it
   only asserted the string was present. */
h2.page-title{line-height:1.06;text-wrap:wrap}

/* ── 10 · Marketing (home) ───────────────────────────────────────────────── */
/* Pricing cards deliberately carry NO overrides in this layer (founder
   call 2026-08-08 round 4): the original card grammar — 42px popped
   prices, soft green featured tint — stays as-is. */
/* Hero demo card shadow per the approved mock. */
.home-demo{box-shadow:0 14px 44px rgba(13,28,46,.10)}

/* ── 11 · Row-as-affordance (founder call 2026-08-08) ─────────────────────
   The per-row View/Delete buttons are gone: History, Batch and VAT Check
   rows navigate on click, and carry tabindex + role="link" so Enter/Space
   works — these rules give that keyboard stop a visible ring. */
.hist-row-nav:focus-visible,tr.batch-row-nav:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:-2px}
.vc-inv-row[data-vc-view]{cursor:pointer}
.vc-inv-row[data-vc-view]:focus-visible{outline:2px solid rgba(5,150,105,.55);outline-offset:2px}

/* ── 12 · Founder mock round (2026-08-08 evening) ─────────────────────────
   Brand topbar on marketing shells; VAT-checker result as a ledger card;
   Plan & billing / owner screens get the card-strip + quiet-action grammar;
   History detail gets its eyebrow header. (Pricing cards were restyled here
   too, then reverted the same evening — the original card grammar won.) */

/* Brand cluster — wordmark + mono tagline at the top of every marketing
   page (SPA #tbBrand, static base.html .tb-brand). App tool screens keep
   the screen title: the sidebar rail already carries the wordmark there. */
.tb-brand{display:flex;align-items:baseline;gap:16px;min-width:0}
.tb-wordmark{font-family:var(--ui);font-size:17px;font-weight:700;letter-spacing:-.04em;color:var(--t1);white-space:nowrap}
.tb-wordmark span{color:var(--g)}
.tb-tagline{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--t4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:1100px){.tb-tagline{display:none}}

/* VAT-checker (free tool): result renders as a small ledger card. */
.vc-result{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);box-shadow:0 1px 3px rgba(13,28,46,.05)}
.vc-result.vc-pass{border-color:var(--brd)}
.vc-result.vc-fail{border-color:var(--brd)}

/* Plan & billing: the plan row reads as the card's header strip; actions
   collapse into ONE quiet horizontal row under a hairline (the mock's
   Update-payment / Change-plan / Cancel grammar — same handlers). */
#tool-account .owner-card{padding-top:0}
#tool-account .acct-plan-row{margin:0 -22px 16px;padding:12px 22px;background:var(--card-head);border-bottom:1px solid #eef2f7;border-radius:var(--r-lg) var(--r-lg) 0 0}
#tool-account .acct-actions{flex-direction:row;flex-wrap:wrap;align-items:center;gap:8px 10px;margin-top:18px;padding-top:14px;border-top:1px solid #eef2f7}
#tool-account .acct-actions .btn-primary,#tool-account .acct-actions .btn-secondary{width:auto;padding:9px 16px;font-size:12.5px}
#tool-account .acct-actions .acct-plans-link{margin-left:auto}

/* Owner-family section heads (Team / Access / Leads / Email-in) align to
   the mono-eyebrow grammar. */
.tm-section-h,.ar-decided-h,.ld-done-h{font-family:var(--mono);font-size:9.5px;font-weight:500;letter-spacing:.14em;color:var(--t3)}
.tm-seats-line{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}

/* History detail header: mono eyebrow ABOVE a light display title (the
   builder emits sub under title; order flips it visually, markup untouched). */
.history-detail-head{display:flex;flex-direction:column;position:relative}
.history-detail-head .hdd-sub{order:-1;font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--t4);margin-bottom:7px}
.history-detail-head .hdd-title{font-size:26px}
/* Owner-only Delete (round 5): quiet until hovered — a rare, deliberate act,
   not a workflow button. Sits clear of the eyebrow/title stack. */
.hdd-del{position:absolute;top:2px;right:0;font-size:11.5px;font-weight:600;color:var(--t3);background:none;border:1px solid var(--brd);border-radius:var(--r);padding:6px 13px;cursor:pointer;transition:color 120ms,border-color 120ms,background 120ms}
.hdd-del:hover,.hdd-del:focus-visible{border-color:var(--fail-brd);color:var(--fail);background:var(--fail-bg)}

/* ── Reduced motion: every restyle loop collapses to its end state ───────── */
@media (prefers-reduced-motion: reduce){
  .load-card::before,.guardian-score.has-checking::after{animation:none;display:none}
  .load-step-1 .ls-dot,.load-step-2 .ls-dot,.load-step-3 .ls-dot{animation:lsDone 1ms linear forwards}
  .batch-row-active{animation:none;background:var(--inset)}
  /* .hd-status's working pulse is unreachable under reduced motion today
     (homedemo.js's reduceMotion() gate renders the finished paper) and the
     blanket .home-demo rule covers it too; listed anyway as the CSS-level
     backstop should that JS gate ever be refactored. */
  .sp-proc::before,.sp-proc::after,.bst-spin,.bp-spin,.gsc-checking .gsc-dot,.appr-pill--pending::before,.hd-status:not(.done)::before{animation:none;opacity:.7}
  .otp-box:focus:placeholder-shown{animation:none}
  .otp-box{transition:none}
}

/* ── TOUCH — coarse-pointer hit-target pass (2026-08-26) ──────────────────
   Pointer-gated, not width-gated: a phone in landscape can be >760px wide
   and is still a finger. Only the smallest chrome gets a bump — the banner
   dismiss (visually ~17px) grows a 44px hit area via padding + negative
   margin so the visual weight is unchanged. */
@media (pointer:coarse){
  .mobile-banner .mb-close{padding:13px 14px;margin:-13px -14px;margin-left:auto}
}

/* ── APP CALM (2026-09-24): the workspace screens ────────────────────────
   The signed-in screens take the public site's calm: labels in sentence
   case in the UI face (mono stays for figures, IDs, VAT numbers and dates as
   data), no decorative icon squares or initial avatars, one card radius, no
   emerald washes. Every rule is scoped to .app-screen (the wrapper of every
   tool screen) or to a modal, so the home page's sandbox and demo, the
   public forms and the public tables are untouched. CSS only: the label text
   is already written in sentence case (or Title Case, for the field names
   the record and the audit trail share) in the markup; only the transform,
   the tracking and the face change here. Nothing a test or a script reads
   moves. */
/* Labels and table headers */
.app-screen th{font-family:var(--ui);font-size:12px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--t3)}
.app-screen :is(.slbl,.xr-group-lbl,.gsc-section-lbl,.manual-lbl,.bi-title,.vc-section-title,.tm-section-h,.ar-decided-h,.ld-done-h),.audit-t{font-family:var(--ui);font-size:13px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--t2)}
.app-screen .xr-lbl{font-size:12.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--t3)}
.app-screen .xr-details-sum{font-size:13px;letter-spacing:0;text-transform:none;color:var(--t2)}
.app-screen :is(.bi-chart-label,.bi-ccy-label,.vc-inv-vat-lbl){font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--t3)}
.app-screen .batch-chip-st{font-size:11px;letter-spacing:0;text-transform:none}
.app-screen .tm-seats-line{font-family:var(--ui);font-size:13px;font-weight:600;letter-spacing:0;text-transform:none}
.app-screen :is(.tl-badge,.ro-pill,.ld-kind){font-size:11.5px;font-weight:600;letter-spacing:0;text-transform:none}
.app-screen .history-detail-head .hdd-sub{font-family:var(--ui);font-size:13px;letter-spacing:0;text-transform:none;color:var(--t3)}
.app-screen :is(.history-pill,.cn-pill,.dup-pill){font-family:var(--ui);letter-spacing:0}
.app-screen .xr-key{font-family:var(--ui);font-size:12px;color:var(--t3)}
.app-screen .xr-verdict{font-family:var(--ui);font-size:11.5px}
.app-screen .flbl,.modal-backdrop .flbl{font-size:13px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--t2)}
.app-screen .page-title{font-weight:600;letter-spacing:-.02em}
/* Words read in the UI face, figures in mono: a name, an address or the
   payment terms is text, not data to compare digit by digit. Keyed on the
   field's own data-doc (read-only and editable cells both carry it) and on
   the editable line description. IDs, VAT numbers, dates and money keep mono. */
.app-screen :is([data-doc="supplier_name"],[data-doc="supplier_email"],[data-doc="supplier_address"],[data-doc="supplier_city"],[data-doc="supplier_region"],[data-doc="supplier_country"],[data-doc="customer_name"],[data-doc="payment_terms"],[data-doc="ship_to_address"],[data-doc="ship_to_city"],[data-doc="ship_to_region"],[data-doc="ship_to_country"]) .field-val,
.app-screen .tbl-inp[data-field-key="description"],
.app-screen .xr-details-peek{font-family:var(--ui)}
.app-screen .xr-details-peek{color:var(--t3)}
@media (min-width:761px){.app-screen .xr-details .xr-lbl{width:140px}}
/* Decoration that carried no information */
.app-screen .stat-ic,.app-screen .hist-av{display:none}
.app-screen .stat-ic~:is(.hist-stat-lbl,.bi-stat-lbl,.batch-stat-lbl){padding-right:0}
.app-screen .vc-hero::before{content:none}
.app-screen :is(.xr-drop .dz-icon,.bdz-icon){background:var(--white);border-color:var(--brd);box-shadow:none}
/* One card radius on the working screens */
.app-screen :is(.batch-insights,.tl-card,.xr-drop,.batch-dropzone){border-radius:var(--r-lg)}

/* ── APP CALM (2026-09-25): VAT Check ────────────────────────────────────
   The period screen in the site's calm. One white summary panel on the
   tint: the two VAT totals as plain figures (mono, like the site's prices,
   in ink rather than green and amber), a thin share bar with its percentage
   written out, and the registration line under a rule. The invoices are
   rows of one white list, not a floating card each. No dial, no coloured
   headline figures, no dot in front of every label: a status dot stays only
   where it keys a colour (beside the two totals, which the share bar
   colours, and in the registration legend). Everything the screen said
   before, it still says; nothing a test or a script reads moves. */
#tool-vatcheck .vc-metric-card .vc-metric-lbl::before{content:none}
#tool-vatcheck .vc-metric-denom{font-weight:500}
#tool-vatcheck .vc-summary{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);box-shadow:0 1px 3px rgba(13,28,46,.05);margin-bottom:28px}
#tool-vatcheck .vc-hero{display:block;background:none;border:none;border-radius:0;box-shadow:none;padding:24px 28px 22px;margin:0;overflow:visible}
#tool-vatcheck .vc-hero-stats{gap:32px}
#tool-vatcheck .vc-hero-block + .vc-hero-block{padding-left:32px}
#tool-vatcheck .vc-hero-val,#tool-vatcheck .vc-hero-val.vc-hero-val-warn{font-size:30px;color:var(--t1);letter-spacing:-.04em}
#tool-vatcheck .vc-hero-lbl{font-size:13.5px;color:var(--t2);margin-top:8px}
#tool-vatcheck .vc-hero-sub{font-size:12.5px;color:var(--t3);margin-top:2px}
#tool-vatcheck .vc-share{margin-top:22px}
#tool-vatcheck .vc-share-bar{display:flex;height:6px;border-radius:999px;overflow:hidden;background:var(--bg);transform-origin:left;animation:vcBarWipe 620ms cubic-bezier(.2,.7,.3,1) both}
#tool-vatcheck .vc-share-seg{height:100%;width:var(--w);min-width:3px}
#tool-vatcheck .vc-share-seg + .vc-share-seg{box-shadow:-2px 0 0 var(--white)}
#tool-vatcheck .vc-share-ok{background:var(--ok)}
#tool-vatcheck .vc-share-warn{background:var(--warn)}
#tool-vatcheck .vc-share-cap{font-size:12.5px;color:var(--t3);margin-top:9px}
#tool-vatcheck .vc-share-cap > span{color:var(--t1);font-weight:600}
#tool-vatcheck .vc-strips{background:none;border:none;border-top:1px solid var(--brd);border-radius:0;box-shadow:none;padding:18px 28px;margin:0}
#tool-vatcheck .vc-reg-title{font-size:13px;color:var(--t2)}
#tool-vatcheck .vc-reg-sub{font-size:12px;color:var(--t3)}
#tool-vatcheck .vc-reg-bar{height:6px;background:var(--bg)}
#tool-vatcheck .vc-reg-legend{margin-top:10px}
#tool-vatcheck .vc-reg-key{font-size:12.5px;color:var(--t3)}
#tool-vatcheck .vc-reg-key > span{color:var(--t1);font-weight:600}
#tool-vatcheck .vc-composition{font-size:12.5px;color:var(--t3);margin-top:14px;padding-top:12px}
/* The invoices: one white list, a rule between rows */
#tool-vatcheck :is(.vc-section-hdr,.vc-clean-summary,.vc-inv-row) > .vc-dot{display:none}
#tool-vatcheck :is(.vc-section-hdr,.vc-clean-summary)::after{content:none}
#tool-vatcheck .vc-section-hdr{padding:0 2px;margin-bottom:10px}
#tool-vatcheck .vc-clean-summary{padding:6px 2px;margin:4px 0 10px}
#tool-vatcheck .vc-rows{gap:0;background:var(--white);border:1px solid var(--brd);border-radius:var(--r-lg);overflow:hidden;box-shadow:0 1px 3px rgba(13,28,46,.05);margin-bottom:14px}
#tool-vatcheck .vc-inv-row{border:none;border-radius:0;box-shadow:none;background:transparent;padding:14px 20px;animation:none;transition:background 120ms}
#tool-vatcheck .vc-inv-row + .vc-inv-row{border-top:1px solid var(--brd)}
#tool-vatcheck .vc-inv-row:hover{background:var(--inset);box-shadow:none;transform:none;border-color:var(--brd)}
#tool-vatcheck .vc-inv-row:focus-visible{outline-offset:-2px}
#tool-vatcheck .vc-inv-num{color:var(--t2)}
#tool-vatcheck .vc-inv-date{color:var(--t3)}
#tool-vatcheck .vc-inv-issues{font-size:12.5px}
#tool-vatcheck .vc-inv-vat{font-weight:600}
#tool-vatcheck .vc-show-more{background:none;border:none;border-radius:var(--r);width:auto;margin:0 0 10px;padding:6px 2px;color:var(--gh);text-align:left}
#tool-vatcheck .vc-show-more:hover{background:none;color:var(--gh);text-decoration:underline}
#tool-vatcheck .vc-empty{background:transparent}
#tool-vatcheck .vc-caveat{border:none;border-radius:0;padding:0 2px;margin-top:26px;font-size:12.5px;color:var(--t3)}
@media (max-width:760px){
  #tool-vatcheck .vc-hero{padding:18px 18px 16px}
  #tool-vatcheck .vc-strips{padding:16px 18px}
  #tool-vatcheck .vc-inv-row{padding:12px 14px}
}
@media (max-width:560px){
  #tool-vatcheck .vc-hero-stats{grid-template-columns:1fr;gap:16px}
  #tool-vatcheck .vc-hero-block + .vc-hero-block{padding-left:0;border-left:none;padding-top:16px;border-top:1px solid var(--brd)}
  /* The period toolbar: on a phone the three tabs and the date range were
     each wider than the column and ran off the right edge (on main too).
     Each takes the full width: the tabs share it equally (a label wraps
     rather than overlap its neighbour), the two dates get the first row of
     the range and Apply the second, so every date shows in full and nothing
     scrolls sideways. */
  #tool-vatcheck .vc-period-tabs,#tool-vatcheck .vc-range{display:flex;width:100%;min-width:0;box-sizing:border-box}
  #tool-vatcheck .vc-tab{flex:1 1 0;min-width:0;justify-content:center;text-align:center;white-space:normal;line-height:1.25;padding:8px 4px;font-size:12.5px}
  #tool-vatcheck .vc-range{flex-wrap:wrap;row-gap:6px;padding:3px 3px 3px 10px}
  #tool-vatcheck .vc-range .vc-date{flex:1 1 0;min-width:0;padding:7px 2px;font-size:12.5px}
  #tool-vatcheck .vc-range .vc-date::-webkit-calendar-picker-indicator{margin-left:2px;padding:0}
  #tool-vatcheck .vc-range .vc-apply{flex:1 0 100%;justify-content:center;margin-left:-7px}
}
@media (prefers-reduced-motion: reduce){#tool-vatcheck .vc-share-bar{animation:none}}
@media (max-width:380px){
  /* Below 380px two dates and an arrow no longer fit one row: the start date
     takes the first row, the arrow and end date the second, Apply the third. */
  #tool-vatcheck .vc-range #vcFrom{flex:1 0 100%}
}

/* ── MARKETING HEADER — horizontal nav for the PUBLIC pages (2026-09-09;
   signed-in too since 2026-09-10) ──
   The public face at >760px: chevron, wordmark, five links, then Sign in +
   See pricing (anonymous) or one Open NoticeDesk button (signed in). Engages
   on the public-shell bodies (body.mktd static pages, body.nd-mkt the SPA on
   Home) for BOTH auth states — the founder liked the chevron drawer signed
   out and asked for the same signed in (2026-09-10). html[data-nd-authed]
   no longer gates the header; it only swaps the right-hand controls. The
   ONE remaining gate is html[data-nd-deeplink] (the SPA's pre-paint tool
   frame): a signed-in landing on a TOOL keeps the rail + topbar, since the
   tools are rail territory (goTool strips body.nd-mkt). At ≤760px the header
   is display:none and the MOBILE NAV drawer below is the one navigation. The
   sidebar stays in the DOM for both of those reasons. Placed before the
   MOBILE NAV block on purpose: that block's END-of-file contract stands. */
.mkt-header{display:none;position:relative;background:var(--page);border-bottom:1px solid var(--brd);flex-shrink:0}
/* A phone's public pages use the app's topbar instead: the same tint. */
html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .topbar{background:var(--page);box-shadow:none}
.mkt-header-in{box-sizing:content-box;max-width:1280px;margin:0 auto;padding:0 72px;height:64px;display:flex;align-items:center;gap:36px}
.mkt-brand{font-family:var(--ui);font-size:19px;font-weight:700;letter-spacing:-.04em;color:var(--t1);text-decoration:none;white-space:nowrap}
.mkt-brand span{color:var(--g)}
.mkt-nav{display:flex;gap:26px}
.mkt-nav-link{font-size:14px;font-weight:500;color:var(--t2);text-decoration:none;padding:6px 0;border-bottom:2px solid transparent;transition:color 120ms,border-color 120ms}
.mkt-nav-link:hover{color:var(--t1)}
.mkt-nav-link.active{color:var(--t1);border-bottom-color:var(--g)}
.mkt-header-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.mkt-signin{font-family:var(--ui);font-size:14px;font-weight:500;color:var(--t2);background:none;border:none;padding:8px 10px;border-radius:var(--r);cursor:pointer;text-decoration:none;transition:background 120ms,color 120ms}
.mkt-signin:hover{background:var(--bg);color:var(--t1)}
.mkt-cta.btn-primary{padding:10px 18px;border-radius:var(--r)}
/* Signed-in swap (2026-09-10): Sign in + See pricing carry .sbf-anon (hidden
   by the html[data-nd-authed] rule above); the Open NoticeDesk button is the
   inverse pair. (0,2,0) hide beats a.btn-primary's (0,1,1) inline-flex; the
   (0,3,0) attribute show sits after it — the #165 cascade shape. */
.mkt-header-right .mkt-open{display:none}
html[data-nd-authed] .mkt-header-right .mkt-open{display:inline-flex}
.mkt-nav-link:focus-visible,.mkt-signin:focus-visible,.mkt-brand:focus-visible{outline:2px solid var(--g);outline-offset:3px}
/* The header's chevron: a 32px emerald control that opens the sidebar as an
   off-canvas drawer (founder call 2026-09-10 — the full sidebar comes BACK,
   hidden by default). PINNED TO THE VIEWPORT'S LEFT EDGE, outside the
   centred measure (founder's second look, same day, on a 1917px monitor:
   inside the measure it sat 400px in and "floated nowhere"); at the edge it
   reads as the handle of the rail that slides out from there, at every
   width. While the drawer is open the 248px rail covers it (z-index 60
   over an unpositioned header) and .main is inert, so the drawer closes
   from the scrim or Escape, never from the chevron; the old
   "flip to point left while open" rule was removed for that reason
   (pre-merge review 2026-09-10 PM: it rendered to a hidden control at
   every width). Absolute against .mkt-header (position:relative above);
   32px tall on a 64px bar, so top:16px centres it. */
.mkt-nav-toggle{position:absolute;left:24px;top:16px;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;background:var(--glo);border:1px solid var(--gbrd);border-radius:var(--r);color:var(--gh);cursor:pointer;padding:0;flex-shrink:0;transition:background 120ms,border-color 120ms}
.mkt-nav-toggle:hover{background:var(--gmd);border-color:var(--g)}
.mkt-nav-toggle:focus-visible{outline:2px solid var(--g);outline-offset:3px}
.mkt-nav-toggle svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.2}
@media (min-width:761px){
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .mkt-header{display:block}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .topbar{display:none}
  /* DESKTOP DRAWER (2026-09-10): on the public shell the sidebar is not
     removed — it is parked off-canvas and slides in from the chevron, the
     same .mob-open / #sbScrim / inert mechanics as the ≤760px drawer below.
     Signed-in visitors get it too (same day): a persisted .sb.collapsed
     (the tool screens' 52px rail preference) must not narrow the drawer or
     hide its labels, hence the width re-assert and the display:revert set
     mirrored from the ≤760px block. */
  /* No transition on the PARKED rule: a signed-in tool→Home switch (goPage adds body.nd-mkt) flips .sb from the in-flow rail to this parked state, and a transform transition here animated that flip as a 248px ghost sliding off over the reflowed Home (pre-merge review 2026-09-10). Opening still animates (the .mob-open rule below); closing snaps. */
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb{position:fixed;top:0;bottom:0;left:0;width:var(--sb-w);transform:translateX(-102%);visibility:hidden;z-index:60;box-shadow:8px 0 32px rgba(10,20,36,.35);transition:none}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb.mob-open{transform:none;visibility:visible;transition:transform 200ms ease}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-toggle{display:none}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .wordmark,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-section-lbl,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-sep,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .nav-lbl,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .tool-badge,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-foot{display:revert}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-logo{padding:22px 18px 18px;gap:10px;justify-content:flex-start}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .sb-body{padding:12px 10px}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .nav-item,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb .tool-item{justify-content:flex-start;padding:9px 11px}
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb-scrim:not([hidden]){display:block}
}
@media (min-width:761px) and (prefers-reduced-motion:reduce){
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb,
  html:not([data-nd-deeplink]) :is(body.mktd, body.nd-mkt) .sb.mob-open{transition:none}
}

/* ── MOBILE NAV — ≤760px off-canvas drawer for the PUBLIC face (2026-08-26) ─
   On marketing/support surfaces the ≤760px icon rail (line ~187) is replaced
   by a hamburger-opened drawer: the rail solved "248px column ate the phone",
   but 52px of permanent chrome is still ~15% of a 390px screen and its
   icon-only nav hid the footer account chip. Drawer mode engages ONLY on:
     body.mktd            — the static marketing/support shells, and
     body.nd-mkt          — the SPA on a MARKETING page (goPage adds it,
                            goTool removes it; index.html ships it so the
                            anonymous home boot paints drawer-first), guarded
                            by html:not([data-nd-deeplink]) so a signed-in
                            phone deep-link's pre-paint tool frame keeps the
                            rail with zero drawer flash.
   Tool screens never match either selector — the rail block above is their
   contract and stays byte-identical. :is() carries (0,2,2) specificity, so
   every re-assert here beats both the rail's (0,2,0) hides and a persisted
   .sb.collapsed (0,3,0 with one class deeper) via source order + weight; a
   browser without :is() drops these rules and degrades to today's rail.
   MUST stay at the END of the file (same source-order contract as the
   PUBLIC FACE block at ~2117). */
.tb-menu{display:none;width:44px;height:44px;align-items:center;justify-content:center;background:none;border:none;color:var(--t1);border-radius:var(--r);flex-shrink:0;margin-left:-12px;transition:background 120ms}
.tb-menu:hover{background:var(--bg)}
.tb-menu svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2}
.sb-scrim{display:none;position:fixed;inset:0;background:rgba(10,20,36,.45);z-index:55}

@media (max-width:760px){
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .tb-menu{display:flex}
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb-scrim:not([hidden]){display:block}

  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb{position:fixed;top:0;bottom:0;left:0;width:min(300px,84vw);transform:translateX(-102%);visibility:hidden;z-index:60;box-shadow:8px 0 32px rgba(10,20,36,.35);transition:transform 200ms ease,visibility 0s 200ms}
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb.mob-open{transform:none;visibility:visible;transition:transform 200ms ease}

  /* Inside the drawer: undo the icon-rail hides/compactions AND a persisted
     .sb.collapsed (the desktop toggle's localStorage choice must not shrink
     a fixed-width drawer). display:revert = each element's own base display.
     .sb-toggle stays hidden — collapsing a drawer is meaningless. */
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .wordmark,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .sb-section-lbl,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .sb-sep,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .nav-lbl,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .tool-badge,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .sb-foot{display:revert}
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .sb-logo{padding:22px 18px 18px;gap:10px;justify-content:flex-start}
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .sb-body{padding:12px 10px}
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .nav-item,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb .tool-item{justify-content:flex-start;padding:9px 11px}

  /* One signal in one place: the quiet ≤760px topbar Sign out existed
     because the icon rail hid the footer chip — in drawer mode the chip is
     BACK (the drawer restores .sb-foot), so the topbar twin retires on
     drawer-mode bodies only. TOOL screens keep it: the rail still hides
     their footer. !important mirrors the ≥761px hide — it must beat both
     the html[data-nd-authed] show rule and the SPA's inline display swap. */
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .tb-signout-sm{display:none !important}
}
@media (max-width:760px) and (prefers-reduced-motion:reduce){
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb,
  :is(body.mktd, html:not([data-nd-deeplink]) body.nd-mkt) .sb.mob-open{transition:none}
}

/* ── AI companion: remedy chips, drawer cards, prompt ─────────────────────
   (2026-09-03; the dock + ⌘K palette were removed 2026-09-04) Additive only. The drawer REUSES .audit-sidebar/.closed above
   — deliberately no second width declaration: the upstream proposal added a
   .companion-drawer rule at 320px fighting .audit-sidebar's 280px on the same
   element. Tokens only; --sh-md and --r-pill do NOT exist in this file (the
   proposal used both), so shadows use --sh/--sh-lg and pills use 999px like
   every other pill here. */
.chip-remedy,.gsc-remedy-btn{background:var(--white);border:1px solid var(--gh);color:var(--gh);font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:var(--r);display:inline-flex;align-items:center;gap:5px;cursor:pointer;transition:background 120ms ease,color 120ms ease;white-space:normal;text-align:left;line-height:1.3}
.chip-remedy:hover,.gsc-remedy-btn:hover{background:var(--gh);color:#fff}
.chip-remedy:focus-visible,.gsc-remedy-btn:focus-visible{outline:2px solid var(--gh);outline-offset:2px}
.companion-scroll{flex:1;overflow-y:auto;display:flex;flex-direction:column;min-height:0}
.comp-card{background:var(--inset);border:1px solid var(--brd);border-radius:var(--r);padding:11px 12px;font-size:12px;margin:12px 12px 0}
.comp-card-hdr{font-weight:600;color:var(--t1);margin-bottom:6px}
.comp-card-sub{color:var(--t3);line-height:1.45;margin-bottom:8px}
.comp-recs-list{display:flex;flex-direction:column;gap:6px}
.comp-recs-list .chip-remedy{width:100%;justify-content:flex-start}
.diff-container{background:var(--white);border:1px solid var(--brd);border-radius:var(--r-xs);padding:8px 10px;font-family:var(--mono);font-size:11px;line-height:1.6}
.comp-diff-instr{font-family:inherit;font-weight:600;color:var(--t1);margin-bottom:4px}
.comp-diff-row{display:flex;gap:6px;align-items:baseline;flex-wrap:wrap}
.comp-diff-lbl{color:var(--t3)}
.diff-del{color:var(--fail);text-decoration:line-through}
.diff-arrow{color:var(--t4)}
.diff-add{color:var(--gh2);font-weight:600}
/* The prompt is the ONE place to type an AI instruction since 2026-09-04, so
   it gets real room: a 3-row auto-growing textarea (companion.js grows it up
   to 8 rows), the Apply button on its own row with the keyboard hint, and the
   drawer itself widened 280→320px. Founder feedback: "such small real estate". */
/* Demoted to a collapsed <details> 2026-09-04 — the star + chips are the
   primary path. Summary anatomy mirrors .manual-advanced (one demotion
   pattern in the product); the Art 50 notice lives inside, above the input. */
.companion-prompt>summary{list-style:none;cursor:pointer;user-select:none;font-size:12px;font-weight:600;color:var(--t3);padding:11px 16px;display:flex;align-items:center}
.companion-prompt>summary::-webkit-details-marker{display:none}
.companion-prompt>summary::before{content:'▸';font-size:10px;margin-right:7px;color:var(--t4);display:inline-block;transition:transform 120ms}
.companion-prompt[open]>summary::before{transform:rotate(90deg)}
.companion-prompt>summary:hover{color:var(--t1)}
.companion-prompt>summary:focus-visible{outline:2px solid var(--g);outline-offset:-2px;border-radius:var(--r)}
.companion-prompt[open]{padding-bottom:14px}
.companion-prompt{padding:14px 16px 12px;border-top:1px solid var(--brd);flex-shrink:0;background:var(--inset)}
.companion-prompt .adj-note{margin:0 0 8px}
.companion-input{display:block;width:100%;min-height:78px;max-height:220px;resize:none;padding:10px 12px;font-size:13.5px;line-height:1.5;font-family:inherit;border:1px solid var(--brd-md);border-radius:var(--r);outline:none;background:var(--white);color:var(--t1);transition:border-color 120ms,box-shadow 120ms}
.companion-input:focus{border-color:var(--g);box-shadow:0 0 0 3px var(--glo)}
.companion-input::placeholder{color:var(--t4)}
.companion-input:disabled{background:var(--bg);color:var(--t4)}
.companion-chat-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:8px}
.companion-hint{font-size:11px;color:var(--t4);line-height:1.4;white-space:nowrap}
.companion-hint kbd{font-family:var(--mono);font-size:10px;color:var(--t3);background:var(--white);border:1px solid var(--brd);border-radius:3px;padding:1px 4px}
.companion-chat-row .btn-fix{padding:9px 22px}
/* ── Precision star (spec item 2) + topbar companion toggle ─────────── */
.ico-precision-star{width:14px;height:14px;fill:currentColor;flex-shrink:0}
.in-situ-star-btn{background:var(--white);border:1px solid var(--brd-md);color:var(--t3);width:auto;min-width:30px;height:22px;padding:0 8px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:border-color 120ms,color 120ms,background 120ms,transform 120ms;position:relative;margin-left:auto;flex-shrink:0}
.in-situ-star-btn:hover{border-color:var(--g);color:var(--gh);background:var(--glo);transform:scale(1.06)}
/* Focus is NOT hover. Sharing the selector meant a keyboard user reached the
   ✦ star and saw exactly what a mouse pointer resting elsewhere on the row
   produced — and the shared rule then set `outline:none`, removing the only
   thing that distinguished them (T2.21). */
.in-situ-star-btn:focus-visible{border-color:var(--g);color:var(--gh);background:var(--glo);transform:scale(1.06);outline:2px solid var(--g);outline-offset:2px}
/* (The ✦ star's CSS tooltip was REMOVED 2026-09-04: it was authored with
   `content:none`, so it could never render, and its :hover/:focus-visible
   partner was unreachable with it. The star's disclosure lives in its title
   AND its aria-label, which reach mouse, keyboard and screen-reader users —
   a CSS tooltip would have reached only the first.) */
.field-lbl{display:flex;align-items:center;gap:6px}
.tbl-cell{display:flex;align-items:center;gap:4px;min-width:0}
.tbl-cell .tbl-inp{flex:1;min-width:0}
.tbl-cell--star .in-situ-star-btn{min-width:28px;height:20px;padding:0 7px}
.tbl-cell--star .ico-precision-star{width:12px;height:12px}
/* Emerald flash on the field a star just re-read. */
.star-flash{animation:starFlash 900ms ease-out}
@keyframes starFlash{0%{box-shadow:0 0 0 0 rgba(5,150,105,.55);background:rgba(5,150,105,.18)}100%{box-shadow:0 0 0 6px rgba(5,150,105,0);background:transparent}}
@media (prefers-reduced-motion:reduce){.star-flash{animation:none;box-shadow:0 0 0 3px var(--gbrd)}}
.companion-toggle-btn{display:inline-flex;align-items:center;gap:6px}
.companion-toggle-btn .ico-precision-star{color:var(--gh)}
.companion-toggle-btn.active{border-color:var(--g);color:var(--gh2);background:var(--glo)}
.badge-count{background:var(--gh);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:999px;line-height:1.4}
.audit-t{display:flex;align-items:center;gap:6px}
.audit-t .ico-precision-star{color:var(--gh);width:13px;height:13px}
.comp-card-hdr{display:flex;align-items:center;justify-content:space-between}
.comp-badge-warn{font-size:10px;font-weight:700;color:var(--warn);font-family:var(--mono)}
.comp-badge-ok{font-size:10px;font-weight:700;color:var(--ok-text);font-family:var(--mono)}

/* ── Gate + zero-state panels (site walkthrough 2026-09-05) ──────────────
   buildBatchGateHtml / buildVatCheckGateHtml / buildPlanZeroHtml share this.
   The premium restyle turned .bi-title into a 9.5px small-caps eyebrow
   (correct for the insight tiles it was written for), which left these
   panels as a two-line small-caps whisper at the top of an empty screen.
   Here the title is a normal-case heading and the panel sits centred. */
.history-empty.gate-panel{max-width:540px;margin:48px auto;padding:36px 28px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center}
.gate-panel .bi-title{font-size:17px;font-weight:600;letter-spacing:-.01em;text-transform:none;color:var(--t1);line-height:1.3}
.gate-panel .bi-sub{font-size:13px;line-height:1.55;color:var(--t3);max-width:440px}
.gate-panel .btn-primary{margin-top:6px}

/* ── Home hero + demo under prefers-reduced-motion (site walkthrough
   2026-09-05, item 46) ──────────────────────────────────────────────────
   The demo's JS gate renders its end state and each animated piece carries
   its own reduce override above, but the walkthrough still observed
   animations running with the preference on. One blanket rule for the two
   regions closes every remaining gap — a new keyframe added to the demo
   later inherits it instead of needing its own line. Measured in headless
   Chromium: zero running animations in either region with reduce on. */
@media (prefers-reduced-motion: reduce){
  .home-hero,.home-hero *,.home-hero *::before,.home-hero *::after,
  .home-demo,.home-demo *,.home-demo *::before,.home-demo *::after{animation:none !important;transition:none !important}
}

/* ── Worked-out figures (spec 2026-09-24): VAT Invoice Check lines ─────────
   Appended at the end of the sheet on purpose (a parallel branch rewrites
   sections above). The waiting list names each document whose VAT is
   worked out but not accepted; each name opens the record. */
.vc-waiting{margin-top:12px;padding-top:11px;border-top:1px solid var(--brd);font-size:12px;color:var(--t3);line-height:1.6}
.vc-waiting p{margin:0 0 6px}
.vc-waiting ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px 14px}
.vc-waiting-link{color:var(--t2);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.vc-waiting-link:hover{color:var(--t1)}
.vc-waiting-link:focus-visible{outline:2px solid var(--t2);outline-offset:2px;border-radius:3px}

/* ── Worked-out figures on the record (spec 2026-09-24, section 6) ─────────
   Appended at the end of the sheet on purpose (a parallel branch rewrites
   sections above). A note under a field says where its value stands against
   the document: the "Worked out" tag, the working and its basis, and the
   person's buttons. Info blue, deliberately off the confidence lights and
   the approval violet: a worked-out figure is neither. */
.wo-note{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;margin-top:6px;font-size:11.5px;line-height:1.5;color:var(--t3)}
.wo-note .wo-text{min-width:0}
.wo-tag{display:inline-block;padding:0 6px;border-radius:var(--r-xs);background:var(--info-bg);border:1px solid var(--info-brd);color:var(--info);font-size:10.5px;font-weight:600;white-space:nowrap}
.wo-tag--quiet{background:transparent;border-color:var(--brd);color:var(--t3)}
.wo-limit{flex-basis:100%;padding-left:8px;border-left:2px solid var(--warn-brd);color:var(--t2)}
.wo-actions{display:inline-flex;flex-wrap:wrap;gap:6px}
.wo-btn{padding:3px 10px;font-size:11.5px;line-height:1.4}
.wo-bar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 14px;margin:0 0 12px;padding:10px 14px;border:1px solid var(--info-brd);border-radius:var(--r-lg);background:var(--info-bg);font-size:13px;line-height:1.5;color:var(--t2)}
.wo-bar .wo-btn{padding:5px 14px;font-size:12.5px}
.wo-line-notes td{padding-top:0;border-top:0}
.wo-line-list{display:flex;flex-direction:column;gap:4px;padding:0 0 8px}
.wo-line-item{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px}
.wo-line-lbl{min-width:80px;font-size:11px;font-weight:600;color:var(--t2)}
.wo-line-item .wo-note{margin-top:0}
.wo-pill{display:inline-block;margin-left:6px;padding:0 6px;border-radius:var(--r-xs);border:1px solid var(--info-brd);background:var(--info-bg);color:var(--info);font-family:var(--ui);font-size:10.5px;font-weight:600;white-space:nowrap}
.wo-strip-list{display:flex;flex-direction:column;gap:6px;margin:-4px 0 14px;padding:0 14px}
.wo-strip-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;font-size:12px;line-height:1.5;color:var(--t3)}

/* ── WORKSPACE DASHBOARD (2026-09-30, v2) ──────────────────────────────────
   The landing screen (static/js/dashboard.js). One memorable element: the
   hero, on the rail's own navy with faint ledger ruling, carrying the
   quarter as a ruler (quarter start, quarter end, the return deadline,
   today) and the three answers a clerk needs before anything else. Below
   it everything is quiet: white cards, sentence-case headings, figures set
   large and tabular. Colour is meaning, never decoration: emerald is
   progress and money in, crimson blocks filing, amber is time pressure, the
   approval hues are approval states. Every entrance collapses under
   prefers-reduced-motion; .db-still stops the minute refresh replaying it. */
#tool-dashboard{overflow-y:auto}
.db-screen{padding:24px 32px 56px;max-width:1320px;width:100%;margin:0 auto;box-sizing:border-box;container-type:inline-size}
.db-note{font-size:12.5px;color:var(--t3);line-height:1.5;margin:12px 0 0}
.db-empty-line{font-size:14px;color:var(--t3);margin:4px 0}
.db-link{background:none;border:none;padding:0;color:var(--gh);font-weight:600;font-size:13px;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.db-link:hover{color:var(--gh2)}

/* The hero */
.db-hero{position:relative;color:#fff;border-radius:22px;padding:30px 34px 48px;overflow:hidden;
  background-color:var(--sb-bg);
  background-image:repeating-linear-gradient(180deg,transparent 0 31px,rgba(255,255,255,.035) 31px 32px),
    linear-gradient(135deg,#162032 0%,#1b2b42 100%);
  box-shadow:0 18px 40px rgba(13,28,46,.22)}
.db-hero-top{display:flex;justify-content:space-between;align-items:flex-start;gap:24px;flex-wrap:wrap}
.db-hello{font-size:clamp(24px,3.2vw,34px);line-height:1.15;letter-spacing:-.03em;font-weight:700;margin:0;color:#fff;max-width:760px}
.db-hello-n{color:#a7f3d0}
.db-brief{margin:8px 0 0;font-size:15px;line-height:1.5;color:#c9d6e5;max-width:680px}
.db-hero-actions{display:flex;gap:10px;flex-wrap:wrap}
.db-btn-light{font:inherit;font-size:14px;font-weight:600;color:var(--sb-bg);background:#fff;border:none;border-radius:10px;padding:11px 18px;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.2)}
.db-btn-light:hover{background:#ecfdf5}
.db-btn-ghost{font:inherit;font-size:14px;font-weight:600;color:#fff;background:transparent;border:1px solid rgba(255,255,255,.3);border-radius:10px;padding:10px 16px;cursor:pointer}
.db-btn-ghost:hover{border-color:#fff;background:rgba(255,255,255,.06)}
.db-btn-light:focus-visible,.db-btn-ghost:focus-visible{outline:2px solid #a7f3d0;outline-offset:2px}

/* The quarter ruler */
.db-ruler{margin:46px 8px 0;padding:0 0 58px}
.db-ruler-track{position:relative;height:10px;border-radius:999px;background:rgba(255,255,255,.08)}
.db-ruler-q{position:absolute;left:0;top:0;bottom:0;border-radius:999px 0 0 999px;background:rgba(255,255,255,.14)}
.db-ruler-w{position:absolute;right:0;top:0;bottom:0;border-radius:0 999px 999px 0;
  background:repeating-linear-gradient(135deg,rgba(251,191,36,.35) 0 4px,rgba(251,191,36,.08) 4px 8px)}
.db-ruler-fill{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:linear-gradient(90deg,#10b981,#34d399);
  animation:dbGrow 1100ms cubic-bezier(.3,.7,.2,1) both;transform-origin:left}
.db-ruler-due .db-ruler-fill{background:linear-gradient(90deg,#10b981 0%,#10b981 70%,#fbbf24 100%)}
@keyframes dbGrow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.db-tick{position:absolute;top:14px;transform:translateX(-50%);font-size:11px;color:#8296ad;text-align:center}
.db-tick i{display:block;width:1px;height:6px;background:rgba(255,255,255,.25);margin:0 auto 3px}
.db-tick b{font-weight:500}
.db-ruler-end,.db-ruler-due-pin{position:absolute;top:36px;transform:translateX(-50%);font-size:12px;color:#fff;white-space:nowrap;text-align:center;line-height:1.25}
.db-ruler-due-pin{transform:translateX(-100%);text-align:right}
.db-ruler-end b,.db-ruler-due-pin b{display:block;font-size:11px;font-weight:500;color:#8296ad}
.db-ruler-due-pin{color:#fcd34d}
.db-ruler-today{position:absolute;top:-7px;width:0;height:24px}
.db-ruler-today::before{content:"";position:absolute;left:-10px;top:0;width:20px;height:20px;border-radius:50%;background:#fff;border:5px solid #10b981;box-shadow:0 0 0 6px rgba(16,185,129,.25)}
.db-ruler-due .db-ruler-today::before{border-color:#fbbf24;box-shadow:0 0 0 6px rgba(251,191,36,.25)}
.db-ruler-today b{position:absolute;top:30px;left:0;transform:translateX(-50%);font-size:12px;font-weight:700;color:#fff;background:rgba(0,0,0,.25);border-radius:6px;padding:1px 7px}
.db-ruler .db-ruler-today b{top:-30px}

/* The three answers */
.db-figs{display:flex;gap:0;margin-top:26px;flex-wrap:wrap;align-items:stretch}
.db-fig{display:flex;flex-direction:column;gap:6px;padding:4px 32px 4px 0;margin-right:32px;border-right:1px solid rgba(255,255,255,.12);min-width:0}
.db-fig-v{font-size:clamp(34px,4.4vw,52px);font-weight:700;letter-spacing:-.045em;line-height:1;font-variant-numeric:tabular-nums;color:#fff;white-space:nowrap}
.db-fig-v small{font-size:.45em;font-weight:500;letter-spacing:-.01em;color:#c9d6e5}
.db-fig-l{font-size:13.5px;color:#c9d6e5}
.db-fig-urgent .db-fig-v{color:#fcd34d}
.db-fig-note{font-size:13px;color:#8296ad;max-width:220px;line-height:1.45}
.db-fig-locked{justify-content:flex-end}
.db-fig-bar{display:flex;height:6px;width:180px;border-radius:999px;overflow:hidden;background:rgba(255,255,255,.1);margin-top:2px}
.db-fig-bar i{display:block;height:100%}
.db-fig-bar-ok{background:#34d399}.db-fig-bar-fail{background:#f87171}
.db-stagger{margin-left:auto;align-self:flex-end;font-size:12px;color:#8296ad;display:flex;flex-direction:column;gap:5px}
.db-stagger select{font:inherit;font-size:13px;color:#fff;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.2);border-radius:8px;padding:7px 10px}
.db-stagger select option{color:var(--t1)}
.db-stagger select:focus-visible{outline:2px solid #a7f3d0;outline-offset:2px}
.db-hero-skel span{display:block;height:18px;width:40%;border-radius:6px;background:rgba(255,255,255,.1);margin-bottom:14px}
.db-hero-skel span:first-child{height:32px;width:55%}

/* The grid of cards */
.db-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:20px;margin-top:22px}
.db-card{background:var(--white);border:1px solid var(--brd);border-radius:16px;box-shadow:var(--sh-xs);padding:20px 22px;min-width:0}
.db-span-5{grid-column:span 5}.db-span-7{grid-column:span 7}.db-span-12{grid-column:span 12}
.db-card-head{display:flex;justify-content:space-between;align-items:center;gap:14px;margin-bottom:14px;flex-wrap:wrap}
.db-card-head-sub{margin-top:22px;padding-top:18px;border-top:1px solid var(--brd)}
.db-h{font-size:16px;font-weight:700;letter-spacing:-.015em;color:var(--t1);margin:0}
.db-period-wrap{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.db-range{font-size:12.5px;color:var(--t4);font-variant-numeric:tabular-nums}

/* Needs you */
.db-att-grid{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.db-att-grid li + li{border-top:1px solid var(--brd)}
.db-att{display:grid;grid-template-columns:56px minmax(0,1fr) 20px;align-items:center;gap:14px;width:100%;text-align:left;background:none;border:none;padding:12px 6px;cursor:pointer;font:inherit;color:inherit;border-radius:10px}
.db-att:hover{background:var(--inset)}
.db-att:focus-visible{outline:2px solid var(--db-tone,var(--g));outline-offset:-2px}
.db-att-fail{--db-tone:var(--fail);--db-bg:var(--fail-bg)}
.db-att-warn{--db-tone:var(--warn);--db-bg:var(--warn-bg)}
.db-att-info{--db-tone:var(--info);--db-bg:var(--info-bg)}
.db-att-wait{--db-tone:var(--appr-wait);--db-bg:var(--appr-wait-bg)}
.db-att-rej{--db-tone:var(--appr-rej);--db-bg:var(--appr-rej-bg)}
.db-att-n{font-size:28px;font-weight:700;letter-spacing:-.04em;color:var(--db-tone);font-variant-numeric:tabular-nums;text-align:center;background:var(--db-bg);border-radius:12px;padding:6px 0}
.db-att-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.db-att-title{font-size:15px;font-weight:600;color:var(--t1)}
.db-att-sub{font-size:13px;color:var(--t3)}
.db-att-go{width:18px;height:18px;fill:none;stroke:var(--t4);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.db-att:hover .db-att-go{stroke:var(--db-tone)}
.db-calm{display:flex;align-items:center;gap:14px;padding:18px;border-radius:12px;background:var(--ok-bg);border:1px solid var(--ok-brd)}
.db-calm svg{width:32px;height:32px;flex:none;fill:none;stroke:var(--ok);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.db-calm strong{display:block;font-size:16px;color:var(--ok-text)}
.db-calm span{font-size:13px;color:var(--ok-text)}

/* Payments by due date */
.db-pay-figs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.db-pay-fig{border-radius:12px;padding:12px 12px 10px;background:var(--inset);border:1px solid var(--brd);min-width:0}
.db-pay-v{display:block;font-size:20px;font-weight:700;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--t1);overflow-wrap:anywhere}
.db-pay-l{display:block;font-size:12px;color:var(--t3);margin-top:3px}
.db-pay-fig-soon{background:var(--warn-bg);border-color:var(--warn-brd)}.db-pay-fig-soon .db-pay-v{color:var(--warn)}
.db-pay-fig-zero .db-pay-v{color:var(--t4)}
.db-pay-none{padding:18px;border-radius:12px;background:var(--inset);border:1px solid var(--brd)}
.db-pay-none strong{display:block;font-size:16px;color:var(--t1)}
.db-pay-none span{font-size:13px;color:var(--t3)}
.db-pay-list{list-style:none;margin:14px 0 0;padding:0}
.db-pay-row{display:grid;grid-template-columns:118px minmax(0,1fr) max-content;gap:10px;align-items:center;width:100%;background:none;border:none;border-top:1px solid var(--brd);padding:9px 4px;font:inherit;text-align:left;cursor:pointer;color:var(--t2)}
.db-pay-row:hover{background:var(--inset)}
.db-pay-row:focus-visible{outline:2px solid var(--g);outline-offset:-2px}
.db-pay-when{font-size:12px;font-weight:600;border-radius:999px;padding:2px 9px;justify-self:start}
.db-pay-past{color:var(--fail);background:var(--fail-bg)}.db-pay-soon{color:var(--warn);background:var(--warn-bg)}
.db-pay-who{font-size:13.5px;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.db-pay-no{color:var(--t4);font-size:12.5px}
.db-pay-amt{font-size:13.5px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--t1)}

/* Spend: figures with their own lines, then the chart */
.db-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;margin-bottom:22px;border:1px solid var(--brd);border-radius:14px;overflow:hidden}
.db-tile{padding:16px 18px;min-width:0;display:flex;flex-direction:column;gap:4px}
.db-tile + .db-tile{border-left:1px solid var(--brd)}
.db-tile-lbl{font-size:13px;color:var(--t3);font-weight:600}
.db-tile-val{font-size:28px;font-weight:700;color:var(--t1);letter-spacing:-.04em;font-variant-numeric:tabular-nums;overflow-wrap:anywhere;line-height:1.1}
.db-delta{display:block;font-size:12px;color:var(--t3);font-variant-numeric:tabular-nums}
.db-delta-vs{color:var(--t4)}
.db-delta-up,.db-delta-down{color:var(--t1);font-weight:600}
.db-delta-up .db-delta-vs,.db-delta-down .db-delta-vs{font-weight:400}
.db-tile-foot{display:block;font-size:11.5px;color:var(--t4)}
.db-legend-line{display:flex;gap:18px;font-size:12.5px;color:var(--t3);margin:0 0 8px 52px}
.db-legend-line span{display:inline-flex;align-items:center;gap:7px}
.db-key-now{display:inline-block;width:12px;height:12px;border-radius:3px;background:var(--g)}
.db-key-ghost{display:inline-block;width:12px;height:12px;border-radius:3px;background:var(--brd-md);opacity:.8}
.db-area{position:relative;margin:0}
.db-area-plot{position:relative;margin-left:52px}
.db-area-svg{width:100%;height:220px;display:block;overflow:visible}
.db-area-svg:focus-visible{outline:2px solid var(--g);outline-offset:4px;border-radius:6px}
.db-area-grid line{stroke:var(--brd);stroke-width:1;vector-effect:non-scaling-stroke}
.db-area-grid line.db-zero{stroke:var(--brd-str)}
.db-ax-y{position:absolute;left:-52px;width:44px;text-align:right;transform:translateY(-50%);font-size:11.5px;color:var(--t4);font-variant-numeric:tabular-nums}
.db-ax-xs{position:relative;margin-left:52px;height:18px;margin-top:6px}
.db-ax-x{position:absolute;font-size:11.5px;color:var(--t4);white-space:nowrap}
.db-ax-x0{left:0}.db-ax-x1{left:50%;transform:translateX(-50%)}.db-ax-x2{right:0}
.db-bars path{fill:var(--g)}
.db-bars path.db-bar-neg{fill:#6ee7b7}
.db-bars-ghost path{fill:var(--brd-md);opacity:.55}
.db-area-svg .db-bars{animation:dbRise 800ms cubic-bezier(.3,.7,.2,1) both;transform-origin:50% 100%}
@keyframes dbRise{from{transform:scaleY(0)}to{transform:scaleY(1)}}
.db-area-cursor{fill:rgba(14,26,40,.05);display:none}
.db-area-on .db-area-cursor{display:inline}
.db-area-tip{position:absolute;top:-8px;transform:translate(-50%,-100%);background:var(--t1);color:#fff;font-size:12.5px;padding:5px 9px;border-radius:8px;pointer-events:none;white-space:nowrap;box-shadow:var(--sh);font-variant-numeric:tabular-nums}

/* Top suppliers */
.db-sup{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.db-sup-row{display:grid;grid-template-columns:20px minmax(0,1fr) minmax(60px,26%) max-content;grid-template-areas:"rank name bar val";gap:4px 14px;align-items:center}
.db-sup-rank{grid-area:rank;font-size:13px;font-weight:700;color:var(--t4);font-variant-numeric:tabular-nums}
.db-sup-name{background:none;border:none;padding:0;text-align:left;font:inherit;font-size:14.5px;color:var(--t1);font-weight:600;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.db-sup-name:hover{color:var(--gh);text-decoration:underline;text-underline-offset:3px}
.db-sup-val{grid-area:val;font-size:14.5px;font-weight:700;color:var(--t1);font-variant-numeric:tabular-nums}
.db-sup-track{grid-area:bar;height:8px;background:var(--inset);border-radius:999px;overflow:hidden}
.db-sup-fill{display:block;height:100%;background:var(--g);border-radius:999px}
.db-sup-row:first-child .db-sup-fill{background:var(--gh2)}
.db-sup-n{display:block;font-size:11.5px;font-weight:500;color:var(--t4);text-align:right}
.db-sup-main{grid-area:name;display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.db-sup-main .db-sup-name{flex:0 1 auto}
.db-sup-val{text-align:right}

/* Ready for your ledger + credits */
.db-ledger{display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.db-ledger-v{font-size:34px;font-weight:700;letter-spacing:-.04em;color:var(--t1);font-variant-numeric:tabular-nums;line-height:1}
.db-ledger-v small{font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--t3)}
.db-ledger-l{font-size:13.5px;color:var(--t3);line-height:1.5}
.db-ledger-done .db-ledger-v{font-size:22px;color:var(--ok-text)}
.db-ledger-go{padding:9px 16px;font-size:13px;margin-top:6px}
.db-credit-big{font-size:26px;font-weight:700;letter-spacing:-.03em;color:var(--t1);font-variant-numeric:tabular-nums}
.db-credit-of{font-size:14px;font-weight:500;color:var(--t3);letter-spacing:0}
.db-meter{height:8px;border-radius:999px;background:var(--inset);overflow:hidden;margin:10px 0 0}
.db-meter-fill{display:block;height:100%;background:var(--g);border-radius:999px}
.db-credits-warn .db-meter-fill{background:var(--warn)}
.db-credits-fail .db-meter-fill{background:var(--fail)}
.db-credit-cta{display:flex;gap:14px;align-items:center;margin-top:12px;flex-wrap:wrap}
.db-credit-cta .btn-secondary{padding:9px 16px;font-size:13px}

/* Activity */
.db-act-list{list-style:none;margin:0;padding:0;position:relative}
.db-act-list::before{content:"";position:absolute;left:15px;top:8px;bottom:8px;width:2px;background:var(--brd)}
.db-act{position:relative;display:grid;grid-template-columns:32px minmax(0,1fr) max-content;gap:12px;align-items:start;padding:8px 0}
.db-avatar{width:32px;height:32px;border-radius:50%;background:var(--white);border:2px solid var(--brd-md);display:inline-flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:var(--t2);position:relative;z-index:1}
.db-act-ic{position:absolute;left:20px;top:28px;width:16px;height:16px;border-radius:50%;background:var(--white);border:1px solid var(--brd);display:inline-flex;align-items:center;justify-content:center;z-index:2}
.db-act-ic svg{width:10px;height:10px;fill:none;stroke:var(--t3);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.db-act-extracted .db-act-ic svg{stroke:var(--g)}
.db-act-approval .db-act-ic svg{stroke:var(--appr-wait)}
.db-act-deleted .db-act-ic svg{stroke:var(--fail)}
.db-act-body{font-size:14px;color:var(--t2);line-height:1.5;padding-top:5px;min-width:0;overflow-wrap:anywhere}
.db-act-body strong{color:var(--t1);font-weight:600}
.db-act-time{font-size:12.5px;color:var(--t4);padding-top:6px;white-space:nowrap}
.db-doc{background:none;border:none;padding:0;font:inherit;color:var(--gh);font-weight:600;cursor:pointer;text-align:left}
.db-doc:hover{text-decoration:underline;text-underline-offset:3px}
.db-doc-gone{color:var(--t3);font-weight:500;cursor:default}
.db-act-more summary{cursor:pointer}
.db-act-more ul{margin:6px 0 0;padding-left:18px;display:flex;flex-direction:column;gap:3px}
.db-act-load{margin:10px 0 0 44px}

/* Welcome (an empty workspace) */
.db-welcome{text-align:center;background:var(--white);border:1px dashed var(--gbrd);border-radius:18px;padding:36px 24px;margin:22px 0 0}
.db-welcome h3{font-size:20px;color:var(--t1);margin:10px 0 6px;letter-spacing:-.02em}
.db-welcome p{font-size:14px;color:var(--t3);max-width:520px;margin:0 auto;line-height:1.55}
.db-welcome-art svg{width:64px;height:64px;fill:none;stroke:var(--g);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.db-welcome-cta{display:flex;gap:12px;justify-content:center;margin-top:18px;flex-wrap:wrap}
.db-is-empty .db-grid{opacity:.55}

/* Skeletons */
.db-skel{display:flex;flex-direction:column;gap:10px}
.db-skel span{display:block;height:14px;border-radius:6px;background:linear-gradient(90deg,var(--inset) 0,var(--brd) 50%,var(--inset) 100%);background-size:200px 100%;animation:skelShimmer 1.2s linear infinite}
.db-skel span:nth-child(2){width:80%}.db-skel span:nth-child(3){width:55%}

/* A repaint the user did not ask for keeps still. */
.db-still .bar-animate,.db-still .db-bars,.db-still .db-ruler-fill{animation:none}
@media (prefers-reduced-motion: reduce){
  .db-bars,.db-ruler-fill,.db-skel span{animation:none}
}

/* Narrower: the grid folds (container queries, so the sidebar decides). */
@container (max-width: 1040px){
  .db-span-5,.db-span-7,.db-col{grid-column:span 12}
}
@container (max-width: 860px){
  .db-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}
  .db-tile:nth-child(3){border-left:none}
  .db-tile:nth-child(n+3){border-top:1px solid var(--brd)}
  .db-fig{border-right:none;margin-right:0;padding-right:0;width:100%;padding-bottom:14px}
  .db-figs{flex-direction:column;gap:6px}
  .db-stagger{margin-left:0;align-self:flex-start}
}
@container (max-width: 560px){
  .db-hero{padding:22px 18px 40px;border-radius:18px}
  .db-hero-actions{width:100%}
  .db-hero-actions button{flex:1 1 0;padding:10px 8px}
  .db-figs{display:grid;grid-template-columns:1fr 1fr;gap:14px 16px}
  .db-fig{padding:0}
  .db-fig-v{font-size:clamp(22px,8.5cqw,32px)}
  .db-fig:nth-child(3),.db-stagger{grid-column:1 / -1}
  .db-ruler{margin-top:40px}
  .db-ruler-end{display:none}
  .db-tick b{font-size:10px}
  .db-pay-figs{grid-template-columns:minmax(0,1fr)}
  .db-pay-row{grid-template-columns:minmax(0,1fr) max-content}
  .db-pay-when{grid-column:1 / -1}
  .db-tiles{grid-template-columns:minmax(0,1fr)}
  .db-tile + .db-tile{border-left:none;border-top:1px solid var(--brd)}
  .db-area-plot,.db-ax-xs{margin-left:40px}
  .db-ax-y{left:-40px;width:34px;font-size:10.5px}
  .db-legend-line{margin-left:40px}
  .db-periods{display:flex;width:100%}
  .db-periods .vc-tab{flex:1 1 0;justify-content:center;white-space:normal;padding:8px 4px;font-size:12.5px;text-align:center}
}
@media (max-width: 760px){
  .db-screen{padding:14px 12px 40px}
  .db-card{padding:16px}
  .db-act{grid-template-columns:32px minmax(0,1fr)}
  .db-act-time{grid-column:2;padding-top:0}
}

/* Dashboard search: a combobox with grouped results. */
.db-search{position:relative;margin:-28px 28px 0;z-index:5}
.db-search-box{position:relative;display:flex;align-items:center}
.db-search-ic{position:absolute;left:16px;width:18px;height:18px;fill:none;stroke:var(--t4);stroke-width:2;stroke-linecap:round;pointer-events:none}
.db-search-input{width:100%;box-sizing:border-box;font:inherit;font-size:15.5px;color:var(--t1);background:var(--white);border:1px solid var(--brd);border-radius:14px;padding:16px 52px 16px 48px;box-shadow:0 10px 30px rgba(13,28,46,.14);transition:border-color 140ms,box-shadow 140ms}
.db-search-input::placeholder{color:var(--t4)}
.db-search-input:focus{outline:none;border-color:var(--g);box-shadow:0 0 0 4px var(--gmd),var(--sh)}
.db-kbd{position:absolute;right:14px;font-family:var(--mono);font-size:12px;color:var(--t3);border:1px solid var(--brd-md);border-bottom-width:2px;border-radius:6px;padding:1px 7px;background:var(--inset)}
.db-search-input:focus + .db-kbd{opacity:0}
.db-chips{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 0;align-items:center}
.db-chip{font:inherit;font-size:12.5px;font-weight:600;color:var(--t3);background:var(--white);border:1px solid var(--brd);border-radius:999px;padding:5px 12px;cursor:pointer;transition:all 120ms}
.db-chip:hover{color:var(--t1);border-color:var(--brd-md)}
.db-chip[aria-pressed="true"]{background:var(--glo);color:var(--gh);border-color:var(--gbrd)}
.db-chip:focus-visible{outline:2px solid var(--g);outline-offset:2px}
.db-chip-sep{width:1px;height:18px;background:var(--brd);margin:0 4px}
.db-search-panel{position:absolute;left:0;right:0;top:56px;background:var(--white);border:1px solid var(--brd);border-radius:14px;box-shadow:var(--sh-xl);max-height:min(460px,60vh);overflow:auto;padding:6px;animation:dbPanel 160ms cubic-bezier(.2,.7,.3,1) both}
@keyframes dbPanel{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.db-search-list{list-style:none;margin:0;padding:0}
.db-grp{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--t4);padding:10px 12px 4px}
.db-opt{display:grid;grid-template-columns:minmax(0,1fr) max-content;grid-template-areas:"main meta" "pills pills";gap:2px 12px;padding:9px 12px;border-radius:10px;cursor:pointer;align-items:center}
.db-opt:hover,.db-opt-on{background:var(--glo)}
.db-opt-on{box-shadow:inset 3px 0 0 var(--g)}
.db-opt-main{grid-area:main;font-size:14px;color:var(--t1);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.db-opt-no{font-family:var(--mono);font-size:12.5px;color:var(--t3);font-weight:400}
.db-opt-meta{grid-area:meta;font-size:12.5px;color:var(--t3);font-variant-numeric:tabular-nums;white-space:nowrap}
.db-opt-pills{grid-area:pills;display:flex;gap:4px;flex-wrap:wrap}
.db-opt-pills:empty{display:none}
.db-opt-act .db-opt-main{color:var(--gh);font-weight:600}
.db-opt mark{background:rgba(5,150,105,.16);color:inherit;border-radius:3px;padding:0 1px}
.db-pill{font-size:11px;font-weight:600;border-radius:999px;padding:1px 8px;border:1px solid var(--brd-md);color:var(--t3);background:var(--inset)}
.db-pill-fail{color:var(--fail);border-color:var(--fail-brd);background:var(--fail-bg)}
.db-pill-warn{color:var(--warn);border-color:var(--warn-brd);background:var(--warn-bg)}
.db-pill-wait{color:var(--appr-wait);border-color:var(--appr-wait-brd);background:var(--appr-wait-bg)}
.db-pill-done{color:var(--appr-done);border-color:var(--appr-done-brd);background:var(--appr-done-bg)}
.db-pill-rej{color:var(--appr-rej);border-color:var(--appr-rej-brd);background:var(--appr-rej-bg)}
.db-search-status{font-size:12.5px;color:var(--t3);margin:0;padding:8px 12px}
.db-search-status:empty{display:none}
@media (prefers-reduced-motion: reduce){.db-search-panel{animation:none}.db-search-input{transition:none}}
@media (max-width: 760px){
  .db-search{margin:-22px 10px 0}
  .db-search-input{font-size:16px;padding:13px 16px 13px 44px}
  .db-kbd{display:none}
  .db-opt{grid-template-columns:minmax(0,1fr);grid-template-areas:"main" "meta" "pills"}
}

/* Dashboard v3: the email-in address in the hero, and "waiting on someone
   else" under Needs you. */
.db-hero-side{display:flex;flex-direction:column;align-items:flex-end;gap:12px}
.db-mail{display:flex;align-items:center;gap:10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:12px;padding:8px 8px 8px 12px;max-width:100%;min-width:0}
.db-mail svg{width:18px;height:18px;flex:none;fill:none;stroke:#a7f3d0;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.db-mail-txt{display:flex;flex-direction:column;min-width:0}
.db-mail-l{font-size:11.5px;color:#8296ad}
.db-mail-a{font-size:13.5px;color:#fff;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}
.db-mail-copy{font:inherit;font-size:12.5px;font-weight:600;color:var(--sb-bg);background:#a7f3d0;border:none;border-radius:8px;padding:6px 12px;cursor:pointer;flex:none}
.db-mail-copy:hover{background:#d1fae5}
.db-mail-copy:focus-visible{outline:2px solid #fff;outline-offset:2px}
.db-mail-copied{background:#fff}
.db-mail-setup{font:inherit;font-size:13px;font-weight:600;color:#a7f3d0;cursor:pointer;padding:8px 12px}
.db-mail-setup:hover{border-color:#a7f3d0}
.db-waiting{display:flex;align-items:center;gap:10px;width:100%;margin-top:10px;padding:10px 12px;border-radius:10px;background:var(--appr-wait-bg);border:1px solid var(--appr-wait-brd);color:var(--appr-wait);font:inherit;font-size:13.5px;font-weight:600;text-align:left;cursor:pointer}
.db-waiting:hover{background:rgba(109,40,217,.13)}
.db-waiting:focus-visible{outline:2px solid var(--appr-wait);outline-offset:2px}
.db-waiting-dot{width:8px;height:8px;border-radius:50%;background:var(--appr-wait);flex:none}
@container (max-width: 560px){
  .db-hero-side{align-items:stretch;width:100%}
  .db-mail-a{font-size:12.5px}
}
/* Dashboard: the plan and billing notice in the hero (no plan, payment
   failed, out of credits, a scheduled end, a trial ending). */
.db-notice{display:inline-flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:14px;padding:10px 12px 10px 14px;border-radius:12px;font-size:14px;line-height:1.4;border:1px solid}
.db-notice-plan{color:#fff;background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.22)}
.db-notice-fail{color:#fecaca;background:rgba(248,113,113,.14);border-color:rgba(248,113,113,.45)}
.db-notice-warn{color:#fde68a;background:rgba(251,191,36,.12);border-color:rgba(251,191,36,.4)}
.db-notice-info{color:#d1fae5;background:rgba(52,211,153,.1);border-color:rgba(52,211,153,.35)}
.db-notice-act{font:inherit;font-size:13px;font-weight:600;color:var(--sb-bg);background:#fff;border:none;border-radius:8px;padding:6px 12px;cursor:pointer}
.db-notice-act:focus-visible{outline:2px solid #a7f3d0;outline-offset:2px}

/* Dashboard v4 (the design review, 2026-09-30): the working half (Needs you
   beside the ledger, bills and quarter completeness), then Insights. */
.db-col{display:flex;flex-direction:column;gap:20px;min-width:0}
.db-col > .db-card{grid-column:auto}
.db-band{margin:14px 0 -6px;font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--t3);display:flex;align-items:center;gap:14px}
.db-band::after{content:"";flex:1;height:1px;background:var(--brd)}
.db-arrivals{margin:-4px 0 14px;padding:9px 12px;border-radius:10px;background:var(--inset);font-size:13.5px;color:var(--t2);line-height:1.45}
.db-arrivals b{color:var(--t1)}
.db-arrivals-none{color:var(--t3)}
.db-att-why{display:flex;flex-wrap:wrap;gap:4px 12px;margin-top:6px;font-size:12.5px;color:var(--t3)}
.db-att-why b{color:var(--fail);font-variant-numeric:tabular-nums}
.db-att-why em{font-style:normal;color:var(--t4)}
.db-fig-sub{font-size:12px;color:#fca5a5}
.db-quarter-edit[hidden]{display:none}
.db-quarter-form{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.db-quarter-change{font:inherit;font-size:12px;font-weight:600;color:#a7f3d0;background:none;border:none;padding:0;cursor:pointer;align-self:flex-start;text-decoration:underline;text-underline-offset:3px}
.db-quarter-change[hidden]{display:none}
.db-quarter-change:focus-visible{outline:2px solid #a7f3d0;outline-offset:2px}
.db-btn-locked{display:inline-flex;align-items:center;gap:8px;color:#c7d2de;border-style:dashed}
.db-lock-badge{font-size:11px;font-weight:700;color:var(--sb-bg);background:#a7f3d0;border-radius:999px;padding:2px 7px}
.db-ledger-split{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:5px;font-size:13.5px;color:var(--t2)}
.db-ledger-split li{display:flex;gap:8px;align-items:baseline}
.db-ledger-split b{font-variant-numeric:tabular-nums;min-width:2ch;text-align:right}
.db-ledger-ok b{color:var(--ok-text)}.db-ledger-fix b{color:var(--fail)}
.db-quiet-lead{margin:0 0 8px;font-size:13.5px;color:var(--t2)}
.db-quiet{list-style:none;margin:0 0 8px;padding:0;display:flex;flex-direction:column;gap:8px}
.db-quiet li{display:flex;flex-direction:column;gap:1px;padding:8px 10px;border-radius:10px;background:var(--warn-bg);border:1px solid var(--warn-brd)}
.db-quiet li span{font-size:12.5px;color:var(--t3)}
.db-mark{font-size:11px;font-weight:600;border-radius:999px;padding:1px 8px;white-space:nowrap;border:1px solid}
.db-mark-fail{color:var(--fail);background:var(--fail-bg);border-color:var(--fail-brd)}
.db-mark-new{color:var(--info);background:var(--info-bg);border-color:var(--info-brd)}
@container (max-width: 1040px){
  .db-col{grid-column:span 12}
}
@container (max-width: 560px){
  .db-sup-row{grid-template-columns:20px minmax(0,1fr) max-content;grid-template-areas:"rank name val" ". bar bar"}
}
/* The unsaved-quarter question is a row of its own under the figures, so
   the form never crowds the figures or the search bar that overlaps the
   hero's foot. */
.db-stagger-ask{flex-basis:100%;flex-direction:row;align-items:center;flex-wrap:wrap;gap:12px;margin:22px 0 0;align-self:auto;font-size:13.5px;color:#c7d2de;padding-top:18px;border-top:1px solid rgba(255,255,255,.1)}
