/* Inter — the one family (UI rulebook V5), loaded once here so no page
   imports its own copy. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400..700&display=swap');

/* shell.css — the design system. One file, loaded by every screen.
 *
 * The rule that makes this work: components are styled ONLY through the tokens
 * below. Nothing hard-codes a hex value. That is what lets the whole system
 * change from one place — and what will let dark mode be switched on later by
 * redefining tokens rather than hunting through five stylesheets.
 *
 * Deliberately small: six type sizes, one spacing scale, one accent. Most of
 * what reads as "designed" is consistency, not decoration. Things group because
 * they are near each other, not because they are fenced in a box — so borders
 * are rare here and space does the work.
 *
 * Typeface is Inter over the system stack (Tech-Indigo, 2026-09-19: the UI
 * rulebook's one family), loaded once by the @import at the top of this file.
 */

:root{
  /* ground + surfaces */
  --ground:#F8FAFC;
  --surface:#ffffff;

  /* THE NAVIGATION RAIL HAS ITS OWN GROUND, and this is why it is a separate
     token rather than a darker --ground. `--ground` has 42 consumers doing FOUR
     unrelated jobs: the page ground (2), a knocked-out LIGHT foreground on top
     of --ink (16 — .btn.primary's label, the brand mark, the scorer's bulk bar),
     a subtle shaded inset ON white surfaces (21), and three translucent sticky
     bars. Darkening the token would turn white button text grey on six screens
     and repaint every hover state in the app. Audited 2026-09-04 before the
     change; nothing else may read these two.
     --nav-hover is deliberately DARKER than the rail. The sidebar's hover used
     --line-2 (#f1f3f7), which against a grey rail is a colour difference of
     about one unit — the hover would have silently stopped existing. */
  --nav-ground:#f0f1f5;
  --nav-hover:#e4e7ef;

  /* ink. Neutrals carry a slight blue bias so they read as chosen rather than
     as the default mid-grey every unconsidered interface uses. */
  --ink:#0F172A;
  --ink-2:#334155;
  --ink-3:#64748B;
  --line:#E2E8F0;
  --line-2:#F1F5F9;

  /* one accent, spent on the primary action, "this is the current step" and
     the active nav */
  --accent:#4F46E5;
  --accent-soft:#EEF2FF;

  /* semantic state — deliberately separate from the accent, so "needs
     attention" never has to compete with "you are here" */
  --good:#0f7b4f;
  --warn:#a2551f;
  --warn-soft:#fdf4ec;
  --alert:#ab3226;
  --alert-soft:#fdeeec;

  --grade-a:#0f7b4f;
  --grade-b:#4F46E5;

  --shadow:0 4px 6px -1px rgba(79,70,229,.05), 0 2px 4px -1px rgba(15,23,42,.03);
  --shadow-lift:0 2px 6px rgba(16,24,40,.06), 0 18px 44px -18px rgba(16,24,40,.22);

  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:72px;
  --r:14px; --r-sm:12px;

  /* Six named type roles (L1-01). Mid-gear: a 22px title against 13–14px
     meta/headers, not 26px against whisper-grey 11–12px. Same names the three
     Golden Workflow surfaces apply as classes. */
  --type-page-title:22px;
  --type-section-heading:16px;
  --type-body:15px;
  --type-table-cell:14px;
  --type-supporting-meta:14px;
  --type-table-header:13px;

  /* The sidebar's width, and the page's indent, are the SAME token. They can
     never disagree, which is the only way a fixed sidebar and the content
     beside it stay honest across four breakpoints. */
  --sidebar-w:212px;

  /* A CLIENT'S MARK, until logos are read off the LinkedIn page. Six tints, all
     dark enough to carry white initials, all desaturated enough to sit in a
     table without shouting — this is an identifier, not a highlight. Chosen by
     hashing the client's name, so a client is the same colour on every screen
     forever, and the palette is tokens so the "nothing hard-codes a colour"
     rule at the top of this file still holds. */
  --mark-0:#3c4d70;
  --mark-1:#1f6f4a;
  --mark-2:#8a4230;
  --mark-3:#4b4577;
  --mark-4:#1f5f70;
  --mark-5:#7a5320;
}

/* The mark itself. Used by the clients table, the client header, and anywhere a
   company needs to be recognisable at a glance. */
.mono-mark{
  /* --surface is #ffffff, byte-identical to the #fff this replaced, so the
     no-hex-outside-:root rule is satisfied with zero pixels changed. NOT
     --ground: the six tints above are chosen to carry WHITE initials, and
     --ground is the token that would move first if this file ever gains a
     dark mode. */
  /* 32px, up from 26 (2026-09-04). A logo is the fastest thing on the row to
     recognise and at 26 it was smaller than the text beside it. The radius
     goes up with it so the corner stays the same visual softness rather than
     tightening as the square grows — the record head's 40px size (.head >
     .mono-mark, below) keeps its own pairing for the same reason. Nothing else
     on the row changed: the mark got bigger, the design did not get busier. */
  width:32px;height:32px;border-radius:8px;flex:none;color:var(--surface);
  display:grid;place-items:center;font-size:11.5px;font-weight:700;letter-spacing:.01em;
  overflow:hidden;
}
/* A real logo sits on WHITE inside the same box, never on a tint: most company
   PNGs carry their own background, and painting one onto a coloured square
   draws a visible rectangle around it. The hairline keeps a white-on-white
   logo from dissolving into the row. `contain` because these are square-ish
   but not square, and a cropped logo is worse than a letterboxed one. */
.mono-mark.has-logo{background:var(--surface);box-shadow:inset 0 0 0 1px var(--line)}
.mono-mark img{width:100%;height:100%;object-fit:contain;display:block}

*{box-sizing:border-box}
html{-webkit-font-smoothing:antialiased}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:var(--type-body); line-height:1.6;
}
/* Named type roles. One class per job so Clients, Overview and Candidates
   cannot pick three different sizes for the same role. */
.type-page-title{
  margin:0;font-size:var(--type-page-title);font-weight:620;letter-spacing:-.02em;
  line-height:1.2;color:var(--ink);text-wrap:balance
}
.type-supporting-meta{
  font-size:var(--type-supporting-meta);font-weight:400;color:var(--ink-2);line-height:1.4
}
/* A missing fact in a table or header (L1-03). Same job as .about.none for a
   panel: a muted phrase that says what would fill it, never a blank cell or a
   bare em-dash (those read as a failed load). supportingMeta size; ink-3 so it
   is unset, not a guess (.guess italic) and not an error (.err). */
.empty-placeholder{
  font-size:var(--type-supporting-meta);font-weight:400;color:var(--ink-3);
  font-style:normal;line-height:1.4
}
.type-section-heading{
  margin:0;font-size:var(--type-section-heading);font-weight:600;letter-spacing:-.014em;
  line-height:1.3;color:var(--ink)
}
.type-body{font-size:var(--type-body);color:var(--ink)}
.type-table-header{
  font-size:var(--type-table-header);font-weight:550;color:var(--ink-2);
  letter-spacing:0;text-transform:none
}
.type-table-cell{font-size:var(--type-table-cell)}
/* ---------- page widths: three, not six ----------
   Every screen used to pick its own number (720, 900, 1060, 1180, 1360, 1800)
   and the client page sat at 1060 while the board it opens from sat at 1360.
   One default, which is the board's — working screens are full-width
   application layout, not a reading column — and two named departures:
   `narrow` for a form or a settings page, `full` for the scorer's twelve
   columns. A page sets one word on <main>, never a pixel. */
:root{--page-w:1360px}
.wrap{max-width:var(--page-w);margin:0 auto;padding:0 var(--s5)}
.wrap.narrow{--page-w:900px}
.wrap.full{--page-w:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}

/* ---------- the shell ----------
   A fixed sidebar on the left, and the page indented by exactly its width.
   Written once in shell.js and injected by every screen, so the board, the
   builder, the market map, the forms and the scorer stop being five products
   that share a login.

   It REPLACED seven hand-written copies of a top bar (2026-09-04). Fixed
   positioning rather than a flex/grid parent was the deliberate choice: no
   page's DOM had to be restructured to sit beside it, so converting a screen
   is deleting a header and adding two static attributes — and every existing
   `.wrap` keeps centring, just inside a narrower column. */
.app-shell{padding-left:var(--sidebar-w)}

.sidebar{
  position:fixed;inset:0 auto 0 0;width:var(--sidebar-w);z-index:30;
  display:flex;flex-direction:column;
  padding:var(--s5) var(--s3) var(--s4);
  border-right:1px solid var(--line);background:var(--nav-ground);
  overflow-y:auto;overscroll-behavior:contain;
  /* The sidebar measures ITSELF, so the rail below styles itself from its own
     width rather than from the viewport's. That matters because there are two
     different reasons it goes narrow — a small screen, and a screen whose
     content needs the room back (the scorer) — and a viewport rule can only
     see the first. One rule, both reasons, no duplicated breakpoint. */
  container-type:inline-size;
}

/* THE RAIL. Not a separate mode: the same sidebar, told that it is too narrow
   to carry words. Reuben, 2026-09-04: "I want it to be on the left, in the
   sidebar" — so it loses its labels, never its position. */
@container (max-width:120px){
  .sidebar{padding-left:var(--s2);padding-right:var(--s2);align-items:center}
  .sb-brand{padding:0 0 var(--s5);justify-content:center}
  .sb-item span,.sb-who{display:none}
  /* L1-21: keep the word on the rail. Hiding it left only a filled "K"
     square — a mystery FAB with no job. 11px KESST fits the 60px rail. */
  .sb-word{font-size:11px;letter-spacing:.02em}
  .sb-group{width:100%}
  .sb-item{justify-content:center;padding:9px 0}
  .sb-foot{width:100%;align-items:center}
  .sb-me:not(:empty){padding:var(--s3) 0 0;justify-content:center}
}

.sb-brand{
  display:flex;align-items:center;gap:9px;text-decoration:none;color:var(--ink);
  padding:0 var(--s3) var(--s6);
}
/* One line, same size as nav labels. Not a stacked ALL-CAPS lockup. */
.sb-word{font-weight:620;font-size:13.5px;letter-spacing:0;line-height:1.2}

.sb-group{display:flex;flex-direction:column;gap:1px}
.sb-item{
  display:flex;align-items:center;gap:10px;
  padding:7px 11px;border-radius:var(--r-sm);text-decoration:none;
  color:var(--ink-2);font-size:13.5px;font-weight:500;white-space:nowrap;
}
.sb-item:hover{color:var(--ink);background:var(--nav-hover)}
.sb-item[aria-current]{background:var(--surface);color:var(--ink);font-weight:560;box-shadow:var(--shadow)}
.sb-item svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.sb-item span{overflow:hidden;text-overflow:ellipsis}

.sb-foot{margin-top:auto;display:flex;flex-direction:column;gap:var(--s3);padding-top:var(--s5)}
/* auth.js fills this. Empty until it does, so it must not draw a border of its
   own — an empty bordered box on every page load is a broken-looking page. */
.sb-me:not(:empty){
  display:flex;align-items:center;gap:9px;
  padding:var(--s3) 11px 0;border-top:1px solid var(--line);
}
.sb-av{
  width:26px;height:26px;border-radius:7px;flex:none;background:var(--ink);color:var(--ground);
  display:grid;place-items:center;font-size:10px;font-weight:650;
}
.sb-who{min-width:0;flex:1;line-height:1.3}
.sb-who b{display:block;font-size:12.5px;font-weight:550;color:var(--ink);
  overflow-wrap:anywhere}
.sb-who span{display:block;font-size:11px;color:var(--ink-3);
  overflow-wrap:anywhere}
.sb-out{
  border:0;background:none;padding:5px;border-radius:6px;cursor:pointer;
  color:var(--ink-3);flex:none;display:grid;place-items:center;
}
.sb-out:hover{color:var(--ink);background:var(--nav-hover)}
.sb-out svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}

/* ---------- where you are, and what part of it you are looking at ----------
   ONE DEFINITION, four callers: the client, the role, the territory and the
   scoring page. It was three copies inline in three files and they had already
   drifted — client.html's crumb was missing the `flex-wrap:wrap` the other two
   had, so a long client name would not wrap there and would nowhere else. A
   fourth copy for the scorer would have made that two disagreements.

   ⚠ SCOPED TO `nav` ON PURPOSE, AND THAT IS NOT FUSSINESS. `.crumb` was once
   also used elsewhere in the app for `<span class="crumb">`, a bold inline
   "Client › Role › Territory" run inside a sentence. An unscoped
   `.crumb{display:flex;font-size:12.5px}` here would have reached across and
   quietly restyled it — the exact failure this project keeps shipping, a
   shared thing taught to only some of its callers. `nav.crumb` cannot match a
   span. */
nav.crumb{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-3);
  padding:var(--s5) 0 0;flex-wrap:wrap}
nav.crumb a{color:var(--ink-3);text-decoration:none}
nav.crumb a:hover{color:var(--ink);text-decoration:underline}
nav.crumb b{color:var(--ink-2);font-weight:400}

/* The tab strip under a record's title. Tabs are BUTTONS where they switch the
   page in place and LINKS where they leave it; one rule covers both so they
   cannot read as two different kinds of control — which means resetting the
   button's own chrome explicitly rather than hoping the cascade does it. */
.tabs{display:flex;gap:var(--s5);border-bottom:1px solid var(--line);
  margin-bottom:var(--s5);overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
/* A strip with no tabs in it draws nothing. Measured 2026-09-08 at 1440×900: an
   empty <nav class="tabs"> is still a 1px-tall flex box with its bottom border,
   so a stray rule sat under the head on every record page before its data
   arrived — and stayed on an archived client and on a client with no market
   map, both of which clear their tabs on purpose. `:empty` is the quietest
   device: no page changes, and the rule comes back the moment a tab does. */
.tabs:empty{display:none}
/* An inactive tab is ink-2, not ink-3: 13.5px text at ink-3 measures ~3.3:1 on
   white — grey-on-grey and below readable. Hover keeps a real step, to ink. */
.tab{padding:0 0 11px;margin-bottom:-1px;color:var(--ink-2);font-size:13.5px;
  font-weight:520;text-decoration:none;white-space:nowrap;
  border:0;border-bottom:1.5px solid transparent;background:none;
  font-family:inherit;cursor:pointer}
.tab:hover{color:var(--ink)}
.tab[aria-current]{color:var(--ink);font-weight:580;border-bottom-color:var(--ink)}
.tab i{font-style:normal;color:var(--ink-3);font-weight:400;margin-left:3px}
/* A tab with nothing behind it yet says so and does not pretend to be a link —
   a control wired to nothing is a named failure class here. */
.tab.off{color:var(--line);cursor:default}

/* ---------- page head ----------
   ONE head for every screen. The board, the list pages and the three record
   pages each had their own: 25px, 26px and 30px titles, three paddings, and
   three copies of the actions-top-right row (.tools, .ch-acts, .head-actions).
   The board is the measured standard, so its numbers are the rule: a
   pageTitle, the first thing on the page at 48px, actions on the same line to
   the right. A record page puts its breadcrumb in that 48px instead, so the
   title sits under the crumb rather than a second 48px down. */
.head{padding:var(--s7) 0 var(--s4);display:flex;align-items:flex-start;gap:var(--s4);flex-wrap:wrap}
nav.crumb + .head,.head.rec{padding-top:var(--s4)}
.head-main{flex:1;min-width:min(100%,340px)}
h1{margin:0;font-size:var(--type-page-title);font-weight:620;letter-spacing:-.02em;line-height:1.2;text-wrap:balance}
.sub{margin:8px 0 0;color:var(--ink-2);max-width:62ch}
/* Rule 1: a title, then ONE line of counts separated by "·". */
.count{margin:6px 0 0;font-size:var(--type-supporting-meta);color:var(--ink-2);font-variant-numeric:tabular-nums}
.count b{color:var(--ink);font-weight:600}
.count .money{color:var(--good)}
/* The record's identity line and the one note that may sit under it: the
   territory's state, "needs a JD", "closed". A note is drawn only when there is
   one — a row of dashes reads as a broken screen. */
.head-sub{margin:3px 0 0;font-size:var(--type-supporting-meta);color:var(--ink-2)}
.head-note{margin:6px 0 0;font-size:12.5px;color:var(--ink-2)}
.head-note.warn{color:var(--warn)}
.head-note b{color:var(--ink);font-weight:600}
/* Rule 2: actions top-right, short, priced when they cost money. */
.head-acts{margin-left:auto;display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;justify-content:flex-end}
.head-acts .btn[disabled]{opacity:.55}
/* The mark beside a record's title. One size for the client, the role and the
   territory — it was 44px on one page and 38px on the next. */
.head>.mono-mark{width:40px;height:40px;border-radius:10px;font-size:14px;margin-top:1px}
/* The tab strip sits directly under a record head. */
.head + .tabs{margin-top:var(--s2)}

/* ---------- record shell (L1-02)
   One chrome for a client or territory record: breadcrumb, client identity
   (mark + name), tabs slot, header actions. Overview, Roles, Market map and
   territory Candidates wrap their existing crumb/head/tabs in this so they
   cannot drift into three products. Left nav is still shell.js's labelled
   sidebar — Candidates does not opt into the icon rail. Type roles stay
   L1-01's; this block adds layout grouping, not a second type scale. */
.record-shell{display:block}
.record-shell > nav.crumb{padding-top:var(--s5)}
.record-shell > .head{padding-top:var(--s4)}
.record-shell > .head + .tabs{margin-top:var(--s2)}
.record-shell [data-shell-mark]:empty{display:none}

/* The find box: a real input that filters rows as you type. Used by the board
   and the market map, and was written out in both. */
.find{display:flex;align-items:center;gap:7px;border:1px solid var(--line);
  background:var(--surface);border-radius:var(--r-sm);padding:0 11px;width:230px}
.find:focus-within{border-color:var(--accent)}
.find svg{width:13px;height:13px;flex:none;fill:none;stroke:var(--ink-3);stroke-width:1.7}
.find input{border:0;background:none;font:inherit;font-size:13.5px;color:var(--ink);
  padding:8px 0;width:100%}
.find input:focus{outline:none}
.find input::placeholder{color:var(--ink-3)}

/* ---------- numbers. Money first: it is why the work exists. ---------- */
.ledger{display:flex;align-items:flex-end;gap:var(--s7);flex-wrap:wrap;
  padding:var(--s5) 0 var(--s6);border-bottom:1px solid var(--line)}
.num{font-variant-numeric:tabular-nums;letter-spacing:-.028em;line-height:1;font-weight:660;display:block}
.num.money{font-size:40px;color:var(--good)}
.num.plain{font-size:21px}
.num.zero{color:var(--ink-3)}
.lab{display:block;margin-top:7px;font-size:12.5px;color:var(--ink-3)}

.eyebrow{font-size:11px;font-weight:660;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3);margin:var(--s7) 0 var(--s3)}

/* ---------- surfaces ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
  box-shadow:var(--shadow);overflow:hidden}
.card + .card{margin-top:var(--s4)}

/* ---------- controls ----------
   THE LADDER, and it is the whole action hierarchy of the app:

     .btn.primary   the ONE action that commits or spends on this screen —
                    Run the searches, Save & Rescore, Generate, Build the map.
                    Accent-filled. At most one per screen or dialog.
     .btn           looks, previews, edits, opens — reversible, free. Outlined.
     .btn.quiet     secondary and navigational — Cancel, Advanced…, Back.
                    Borderless until hovered.
     .btn.danger    destructive. Alert-coloured text, never filled, so it can
                    sit beside the others without shouting until it is meant.

   A price rides ON the button (`.p`) — a control that spends money says so on
   its face, and the confirmation says what it will do. The scorer's older
   names (.btn-primary, .btn-ghost, .btn-danger) and the builder's .ghost map
   onto the same four rungs here, so a screen cannot draw a fifth kind. */
.btn{
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  padding:7px 14px;border-radius:var(--r);font:inherit;font-size:13.5px;font-weight:550;
  cursor:pointer;text-decoration:none;white-space:nowrap;display:inline-block;
}
.btn:hover{border-color:var(--ink-3)}
.btn.primary,.btn-primary{background:var(--accent);border-color:var(--accent);color:var(--ground)}
.btn.primary:hover,.btn-primary:hover{opacity:.88}
.btn.quiet,.btn.ghost,.btn-ghost{border-color:transparent;color:var(--ink-2);padding:7px 10px;background:transparent}
.btn.quiet:hover,.btn.ghost:hover,.btn-ghost:hover{color:var(--ink);background:var(--line-2)}
.btn.danger,.btn-danger{color:var(--alert);border-color:transparent;background:transparent}
.btn.danger:hover,.btn-danger:hover{background:var(--alert-soft)}
.btn[disabled],.btn.off{opacity:.4;cursor:not-allowed;pointer-events:none}
.btn .p{color:var(--ink-3);font-weight:400;font-size:11.5px;margin-left:5px}
.btn.primary .p{color:var(--ground);opacity:.7}
/* A row of actions. `.commit` is the rung that separates "look" from "do":
   the committing button stands apart from the preview beside it by a hairline
   and a gap, so Preview effect and Save & Rescore never read as one pair. */
.btn-row{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap}
.btn-row .grow{flex:1}
.btn-row .commit{display:flex;gap:var(--s2);align-items:center;margin-left:var(--s2);
  padding-left:var(--s3);border-left:1px solid var(--line)}
.linkish{background:none;border:none;color:var(--ink-2);padding:4px 6px;font:inherit;
  font-size:13px;cursor:pointer;text-decoration:none;border-radius:6px}
.linkish:hover{color:var(--ink);background:var(--line-2)}

/* ---------- state ---------- */
.dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--accent);display:inline-block}
.dot.warn{background:var(--warn)}
.dot.alert{background:var(--alert)}

/* Four milestones: onboarding · hiring manager · run sheet · sent to sourcing.
   A rail, not arrows — these are a checklist, not a journey, and a flat bar
   survives being 3px tall on a phone in a way clip-path chevrons do not. */
.rail{display:flex;gap:3px;margin-bottom:7px;max-width:210px}
.rail i{height:3px;border-radius:2px;background:var(--line);flex:1}
.rail i.done{background:var(--ink)}
.rail i.now{background:var(--accent)}
.rail i.hold{background:var(--warn)}
.rail i.dead{background:var(--line)}
.stage{display:block;font-size:12.5px;color:var(--ink-2)}
.stage.now{color:var(--accent);font-weight:550}
.stage.done{color:var(--good);font-weight:550}
.stage.urgent{color:var(--alert);font-weight:550}

/* ---------- dialogs ---------- */
dialog{border:1px solid var(--line);border-radius:var(--r-sm);padding:0;max-width:460px;width:92%;
  box-shadow:var(--shadow-lift);background:var(--surface);color:var(--ink)}
dialog::backdrop{background:rgba(11,13,18,.32);backdrop-filter:blur(2px)}
.dlg{padding:var(--s5) var(--s5) var(--s4)}
.dlg h2{margin:0 0 var(--s4);font-size:18px;font-weight:620;letter-spacing:-.014em}
.dlg label{display:block;font-size:12.5px;font-weight:600;margin:14px 0 5px;color:var(--ink-2)}
.dlg input,.dlg select,.dlg textarea{
  width:100%;padding:12px 16px;border:1px solid var(--line);border-radius:var(--r-sm);
  font:inherit;font-size:14px;background:var(--surface);color:var(--ink);
  transition:border-color 100ms
}
.dlg input:focus,.dlg select:focus,.dlg textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.dlg textarea{min-height:76px;resize:vertical}
.dlg .row{display:flex;gap:var(--s2);justify-content:flex-end;align-items:center;margin-top:var(--s5)}
.dlg .hint{font-weight:400;color:var(--ink-3);font-size:11.5px;margin-left:6px}
/* The shared dialog builder (jobs-ui.js showDialog) emits its field hint as
   `.fhint`, and until 2026-09-08 nothing styled it: every New/Edit client,
   role and territory dialog drew the hint in the label's own bold, run
   straight on from the label text ("Industrywhat you would call them"). It is
   the quiet line under the label now — the form rule from DESIGN.md. */
.dlg .fhint{display:block;font-weight:400;color:var(--ink-3);font-size:11.5px;margin-top:2px;line-height:1.45}
/* Cancel is emitted without a class by the shared dialog builder. It is the
   quiet rung, not the browser's default grey button. */
.dlg .row button:not(.btn){border:1px solid transparent;background:transparent;color:var(--ink-2);
  padding:7px 10px;border-radius:var(--r-sm);font:inherit;font-size:13.5px;font-weight:550;cursor:pointer}
.dlg .row button:not(.btn):hover{color:var(--ink);background:var(--line-2)}
/* Create Client (jobs-ui.js openCreateClient). The three identity fields carry
   a quiet required mark; a refusal sits under its own box, or at the top of the
   dialog — never on the page behind the modal; the optional details fold under
   one line; and the actions stay in view when those details are open. */
.dlg .cc-req{color:var(--ink-3);font-weight:600}
.dlg .cc-ferr:not([hidden]){display:block;margin-top:5px;font-size:12px;line-height:1.4;color:var(--alert)}
.dlg .cc-err:not([hidden]){margin:0 0 var(--s3);padding:8px 10px;border-radius:var(--r-sm);
  background:var(--alert-soft);color:var(--alert);font-size:13px;line-height:1.4}
.dlg input[aria-invalid="true"]{border-color:var(--alert)}
.dlg .cc-more{margin-top:var(--s4);border-top:1px solid var(--line-2);padding-top:var(--s3)}
.dlg .cc-more summary{cursor:pointer;width:max-content;font-size:12.5px;font-weight:600;color:var(--ink-2)}
.dlg .row.cc-acts{position:sticky;bottom:0;background:var(--surface);
  margin:var(--s4) 0 calc(-1 * var(--s4));padding:var(--s3) 0 var(--s4)}
/* The currency input: a "$" the field wears. Opened from the board AND the
   client page, and was styled by only one of them. */
.curwrap{display:flex;align-items:center;border:1px solid var(--line);
  border-radius:var(--r-sm);overflow:hidden}
.curwrap:focus-within{border-color:var(--accent)}
.curwrap .cur{padding:9px 3px 9px 11px;color:var(--ink-3);font-size:14px}
.curwrap input{border:none !important;border-radius:0 !important;padding-left:2px !important}
.curwrap input:focus{outline:none}

/* ---------- messages ---------- */
.err{display:none;background:var(--alert-soft);color:var(--alert);border:1px solid var(--alert);
  border-color:color-mix(in srgb,var(--alert) 30%,transparent);
  padding:11px 14px;border-radius:var(--r-sm);font-size:13.5px;margin:var(--s4) 0}
.empty{text-align:center;color:var(--ink-3);padding:var(--s8) var(--s5)}
/* Waiting, said quietly. The spinner was written out in the builder and the
   form page; one definition, and reduced-motion honoured once. */
.loading{text-align:center;color:var(--ink-3);padding:var(--s6) var(--s5);font-size:13.5px}
.spin{display:inline-block;width:14px;height:14px;border:2px solid var(--line);
  border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite;
  vertical-align:middle;margin-right:6px}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spin{animation:none}}
/* Set fee (L1-04). The fee gap is a normal next step, so it is a quiet chip in
   the secondary rung's colours — never --warn. One definition for the Clients
   table and the Roles summary. */
.setfee{border:1px solid var(--line);background:var(--surface);color:var(--ink-2);
  padding:1px 9px;border-radius:9999px;font:inherit;font-size:var(--type-supporting-meta);
  font-weight:400;line-height:1.4;cursor:pointer;white-space:nowrap}
.setfee:hover{border-color:var(--ink-3);color:var(--ink)}

.foot{margin:var(--s7) 0 var(--s8);color:var(--ink-3);font-size:12.5px;
  border-top:1px solid var(--line);padding-top:var(--s4)}

/* ---------- the JD-vs-form line (T1-7) ----------
   Sits under a years-of-experience field on three screens and says what the JOB
   DESCRIPTION asked for. It never filters and never scores — it prints a
   question and stops.

   Quiet by default because most of the time it is only context. `.ask` is the
   one that earns colour: the posted floor and the person filling the form in
   front of you disagree, and that gap is the most useful question on the call.
   Warn, not alert — nothing is broken, there is something to decide. */
.jd-gap{margin:7px 0 0;padding:9px 11px;border:1px solid var(--line);
  border-radius:var(--r-sm);background:var(--surface);
  font-size:12.5px;line-height:1.55;color:var(--ink-2)}
.jd-gap .say{display:block;font-weight:600;color:var(--ink)}
.jd-gap .why{display:block;margin-top:3px}
/* The sentence the number was read out of. This is what makes a bad parse
   visible: a person recognises the wrong line instantly, and no regex would
   ever have told them. */
.jd-gap .quote{display:block;margin-top:5px;color:var(--ink-3);
  border-left:2px solid var(--line);padding-left:8px}
.jd-gap.ask{background:var(--warn-soft);
  border-color:color-mix(in srgb,var(--warn) 28%,transparent)}
.jd-gap.ask .say{color:var(--warn)}
.jd-gap.ask .quote{border-left-color:color-mix(in srgb,var(--warn) 30%,transparent)}
.jd-gap.ok{background:transparent;border-color:var(--line-2)}
.jd-gap.ok .say{font-weight:550;color:var(--ink-2)}

/* ======================================================================
   THE RECORD-PAGE AND COLLECTION VOCABULARY — written once (2026-09-08).

   Until now the client, role and territory pages each carried their own copy
   of every rule below, pasted from the page before, and the copies had drifted:
   a panel head aligned to the baseline on one page and the centre on the next,
   a `.state` colour that existed on two pages and not the third, a stat
   separator that rendered as a block because `.stat span{display:block}`
   caught it. The board's table was a fourth copy under a different name.
   A page may add to these. It may not redefine them.
   ====================================================================== */

/* ---------- tables for collections ----------
   Rule 3: a real table, one object per row, aligned columns, numbers right.
   Rule 4: a `···` per row; everything else hides there. The row itself is the
   link, so only a row that IS one gets the pointer and the hover. */
.tbl{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.tbl table{width:100%;border-collapse:collapse;font-size:var(--type-table-cell)}
/* A short collection (the Clients table, a client's Roles) is as wide as what
   it holds, not as wide as the page. At 100% the browser hands every column a
   share of the empty space, so a `1` ends up a hand's width from the name it
   belongs to and a one-role table stretches edge to edge. `.fit` lets the
   columns take their content's width and the frame close around them; it still
   stops at the page's edge, and past that cells wrap exactly as they always did. */
.tbl.fit{width:fit-content;max-width:100%}
.tbl.fit table{width:auto}
.tbl th{text-align:left;font-size:var(--type-table-header);font-weight:550;color:var(--ink-2);
  padding:10px var(--s4);border-bottom:1px solid var(--line);white-space:nowrap}
.tbl td{padding:12px var(--s4);border-top:1px solid var(--line-2);color:var(--ink-2);vertical-align:middle}
.tbl tbody tr:first-child td{border-top:0}
.tbl tbody tr:is([role="link"],[role="button"],[tabindex]){cursor:pointer;transition:background 150ms}
.tbl tbody tr:is([role="link"],[role="button"],[tabindex]):hover{background:var(--line-2)}
.tbl tbody tr:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.tbl b{color:var(--ink);font-weight:560;display:block}
.tbl .sub{display:block;font-size:12px;color:var(--ink-3);margin-top:2px;max-width:none}
.tbl .n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.tbl .dim{color:var(--ink-3)}
.tbl .when{white-space:nowrap;color:var(--ink-3)}
.tbl .go{text-align:center;color:var(--ink-3);font-size:16px;width:44px}
.tbl td.more{width:44px;padding:0}
.rowmenu{border:0;background:none;color:var(--ink-3);font-size:15px;line-height:1;
  padding:10px 14px;cursor:pointer;border-radius:var(--r-sm);letter-spacing:1px}
.rowmenu:hover{color:var(--ink);background:var(--line-2)}
/* Nothing in the table yet. Inside the frame, so the table keeps its edges. */
.tbl .empty{padding:var(--s7) var(--s5);font-size:13.5px}
.stat b .empty-placeholder{font-size:var(--type-supporting-meta);font-weight:400;color:var(--ink-3)}

/* State as small words, not a coloured pill. Colour is spent only where it
   means something: warn is the one that says a search stopped part way. */
.state{font-size:12.5px;color:var(--ink-2)}
.state.done,.state.hold{color:var(--ink-3)}
.state.now{color:var(--good);font-weight:550}
.state.warn{color:var(--warn);font-weight:550;cursor:help}

/* ---------- a section head: a title or a count line, an action to the right ---------- */
.pnl-h{display:flex;align-items:center;gap:var(--s3);margin:0 0 var(--s3);flex-wrap:wrap}
.pnl-h h4{margin:0}
.pnl-h .count{margin:0}
.pnl-h .btn{margin-left:auto}

/* ---------- panels for detail ----------
   A record's Overview is two columns that become one on a narrow screen; a
   panel is the quietest frame that keeps a group of facts together. */
.ov{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:var(--s4);align-items:start}
.ov .span{grid-column:1/-1}
.pnl{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:var(--s5)}
.pnl h4{margin:0 0 var(--s3);font-size:var(--type-section-heading);font-weight:600;color:var(--ink)}
.about{margin:0;font-size:13.5px;color:var(--ink-2);line-height:1.55}
/* A panel with nothing in it says what would fill it and how. An empty box
   with no explanation is what makes a screen feel broken rather than new. */
.about.none{color:var(--ink-3)}
.about.none b{color:var(--ink-2);font-weight:600}
.about + .dl{margin-top:var(--s4)}
.dl{display:grid;grid-template-columns:auto minmax(0,1fr);gap:9px var(--s5);font-size:13px;margin:0}
.dl dt{color:var(--ink-3);white-space:nowrap}
.dl dd{margin:0;color:var(--ink);min-width:0;overflow-wrap:anywhere}
.dl a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line)}
.dl a:hover{color:var(--accent);border-color:var(--accent)}
.stats{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5) var(--s4)}
.stat b{display:block;font-size:23px;font-weight:640;letter-spacing:-.024em;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--ink)}
.stat b.dim{color:var(--ink-3)}
.stat span{display:block;margin-top:6px;font-size:12px;color:var(--ink-3)}
/* A number that is really two — "9 of 13", "43 / 58". The separator is muted
   so the figures read as figures. It is INLINE, said explicitly: the label
   rule above is `.stat span{display:block}` and used to catch this too, which
   drew "1 / 4" as three lines. */
.stat b .sl{display:inline;margin:0;color:var(--ink-3);font-weight:400;font-size:15px}
/* The log for one record: one rule per row, the time on the right. */
.actlog{display:flex;flex-direction:column}
.act{display:flex;gap:var(--s3);align-items:baseline;padding:8px 0;
  border-top:1px solid var(--line-2);font-size:13px;color:var(--ink-2)}
.act:first-child{border-top:0}
.act time{margin-left:auto;flex:none;color:var(--ink-3);font-size:12px;white-space:nowrap}
.act .times{font-style:normal;color:var(--ink-3);font-size:12px}
.ov-note{margin:var(--s4) 0 0;font-size:12.5px;color:var(--ink-2);line-height:1.55;
  border-left:2px solid var(--line);padding-left:var(--s3)}
.ov-note.dim{color:var(--ink-3);border-color:var(--line-2)}
.ov-note a{color:var(--ink-2);text-decoration:none}
.ov-note a:hover{color:var(--accent)}
@media (max-width:900px){ .ov{grid-template-columns:1fr} }

/* ---------- what is finished folds ----------
   Rule 5: finished work folds at the bottom with a count and a reassurance.
   One chevron, one summary, and it was drawn seven different ways. */
.fold>summary{list-style:none;cursor:pointer;font-size:12.5px;color:var(--ink-3);
  padding:var(--s3) 2px;display:flex;align-items:baseline;gap:6px}
.fold>summary::-webkit-details-marker{display:none}
.fold>summary::before{content:"\203A";display:inline-block;transition:transform .12s ease}
.fold[open]>summary::before{transform:rotate(90deg)}
.fold>summary:hover{color:var(--ink-2)}
.fold>summary b{color:var(--ink-2);font-weight:600}
.fold>summary i{font-style:normal;color:var(--ink-3);font-weight:400}
/* A fold that opens INSIDE a panel — the job description, the screening
   guide — carries a firmer label, because it is the panel's own content. */
.fold.strong>summary{font-size:13px;font-weight:550;color:var(--ink-2);padding:0}
.fold.strong>summary:hover{color:var(--ink)}
.fold.strong>summary::before{color:var(--ink-3)}
/* The job description, folded. Never summarised — a summary of a JD is a new
   judgment, and the JD is the input everything downstream is built from. */
.jd{margin-top:var(--s5);border-top:1px solid var(--line-2);padding-top:var(--s4)}
.jd pre{margin:var(--s3) 0 0;white-space:pre-wrap;font:inherit;font-size:13px;
  line-height:1.6;color:var(--ink-2);max-height:420px;overflow:auto;
  border-left:2px solid var(--line);padding-left:var(--s4)}

/* ---------- the occasional actions, behind a `···` ----------
   A menu, because they are real and rare — putting them on the face of the
   page is how the old rows ended up carrying five controls each. */
.menu{position:relative}
.menu>summary{list-style:none;cursor:pointer;border:1px solid var(--line);
  background:var(--surface);border-radius:var(--r-sm);padding:7px 12px;
  color:var(--ink-3);font-size:13.5px;letter-spacing:1px;line-height:1.2}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary:hover{border-color:var(--ink-3);color:var(--ink)}
.menu-list{position:absolute;right:0;top:calc(100% + 6px);z-index:20;min-width:250px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
  box-shadow:var(--shadow-lift);padding:var(--s1);display:flex;flex-direction:column}
.mi{display:block;width:100%;text-align:left;background:none;border:0;
  padding:8px 11px;border-radius:6px;font:inherit;font-size:13px;color:var(--ink-2);
  text-decoration:none;cursor:pointer}
.mi:hover{background:var(--line-2);color:var(--ink)}
.mi.off{color:var(--ink-3);cursor:default}
.mi.danger{color:var(--alert)}
.mi.danger:hover{background:var(--alert-soft)}

/* ---------- forms ----------
   Top-aligned labels, single column, the help UNDER the input. Three form
   vocabularies existed (the dialog's, the builder's `label.f`, the scorer's
   `.field`); this is the one they now share. */
.field{display:block;margin:0 0 var(--s4)}
.field>label,.field>.l,label.f{display:block;font-size:12.5px;font-weight:600;color:var(--ink-2);margin:0 0 5px}
.field .help{display:block;font-size:12px;color:var(--ink-3);margin-top:5px;line-height:1.5}
.field input:not([type=checkbox]):not([type=radio]):not([type=file]),.field select,.field textarea{
  width:100%;padding:12px 16px;border:1px solid var(--line);border-radius:var(--r-sm);
  font:inherit;font-size:14px;background:var(--surface);color:var(--ink);
  transition:border-color 100ms}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.field textarea{min-height:86px;resize:vertical}
.fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:0 var(--s4)}
/* A group of fields under one heading, ruled off from the group above. The
   heading's hint goes on its own line, not run on in grey after the title. */
.fieldset{border-top:1px solid var(--line);padding-top:var(--s4);margin-top:var(--s5)}
.fieldset>h3{margin:0 0 var(--s3);font-size:13px;font-weight:640;letter-spacing:-.006em;color:var(--ink)}
.fieldset>h3 .hint{display:block;font-weight:400;font-size:12.5px;color:var(--ink-3);
  letter-spacing:0;margin-top:3px;max-width:78ch}
/* People filters on the territory. Same field rules as the market map form. */
.rs-form .rs-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:0 var(--s5)}
.rs-form .rs-wide{grid-column:1 / -1}
.rs-form .field.rs-wide>label{
  display:inline-flex;align-items:center;gap:var(--s2);
  font-size:14px;font-weight:400;color:var(--ink);line-height:1.4;margin:0
}
.rs-form .rs-picker{position:relative}
.rs-form .rs-picker-control{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s2)}
.rs-form .rs-picker-pills{display:flex;flex-wrap:wrap;gap:var(--s2)}
.rs-form .rs-picker-pills:empty{display:none}
.rs-form .rs-picker-pill{display:inline-flex;align-items:center;gap:var(--s1);max-width:100%;
  padding:5px 9px;border-radius:9999px;background:var(--accent-soft);color:var(--ink);font-size:13px;line-height:1.4}
.rs-form .rs-picker-pill button{border:0;background:none;color:var(--ink-2);padding:0;cursor:pointer;font:inherit;line-height:1}
.rs-form .rs-picker-control .rs-picker-search{flex:1 1 190px;min-width:0}
.rs-form .rs-picker-menu{position:absolute;top:calc(100% + var(--s1));left:0;right:0;z-index:20;
  max-height:260px;overflow-y:auto;border:1px solid var(--line);border-radius:var(--r-sm);
  padding:var(--s2);background:var(--surface);box-shadow:var(--shadow)}
.rs-form .rs-picker-option{display:flex;align-items:center;gap:var(--s2);padding:8px 10px;
  border-radius:var(--r-sm);font-size:14px;font-weight:400;color:var(--ink);line-height:1.4;
  cursor:pointer;transition:background 150ms}
.rs-form .rs-picker-option[hidden]{display:none}
.rs-form .rs-picker-option:hover{background:var(--accent-soft)}
.rs-form .rs-picker-empty{margin:0;padding:8px 10px;color:var(--ink-3);font-size:14px}
.rs-form .rs-max{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}
.rs-form .rs-max select{width:auto;flex:none}
.rs-form .rs-price{color:var(--ink-2);font-size:14px;line-height:1.6}
.rs-form .rs-line,.rs-form .rs-msg{margin:var(--s2) 0 0;font-size:14px;line-height:1.6;color:var(--ink)}
.rs-form .rs-msg.bad{color:var(--alert)}
.rs-form .rs-line:empty,.rs-form .rs-msg:empty{display:none;margin:0}
.rs-form .rs-cap{margin:var(--s3) 0 0;font-size:14px;line-height:1.6;color:var(--ink)}
.rs-form .rs-cap label{display:inline-flex;align-items:center;gap:var(--s2);font-weight:400;color:var(--ink);margin:var(--s2) 0 0}
.rs-form .btn-row{margin-top:var(--s3)}
@media (max-width:860px){
  .rs-form .rs-grid{grid-template-columns:minmax(0,1fr)}
}

/* ---------- responsive. None of these screens had a single rule before. ----------
   THE SIDEBAR NEVER FOLDS TO THE TOP. It narrows, then becomes an icon rail,
   and it stays on the left at every width. Reuben, 2026-09-04, on a draft that
   did fold it: "I want it to be on the left, in the sidebar." Desktop is the
   primary case; the rail is what "collapse the sidebar" means here. Because the
   width and the indent are one token, each step is a single line. */
@media (max-width:1100px){
  :root{--sidebar-w:184px}
}
@media (max-width:860px){
  .wrap{padding:0 var(--s4)}
  .head{padding:var(--s6) 0 var(--s4)}
  h1{font-size:24px}
  .ledger{gap:var(--s5) var(--s6);padding-bottom:var(--s5)}
  .num.money{font-size:32px}
}
@media (max-width:820px){
  :root{--sidebar-w:60px}
}

/* A SCREEN THAT NEEDS THE ROOM BACK asks for the rail itself, at whatever width
   its own content stops fitting. The scorer's candidate table is 11 columns and
   wants about 1,410px: on a 1,920 desktop the full sidebar leaves it exactly
   enough and nothing over. L1-02: Candidates dropped `rail-wide` so its left
   nav matches Overview / Roles / Market map (labelled sidebar, not the icon
   rail). The class remains for a future screen that truly cannot fit labels. */
@media (max-width:1670px){
  .rail-wide{--sidebar-w:60px}
}

/* A run sheet that never finished. Sits beside "N found" because the number is
   true and the warning is about what it is a fraction OF — the same contract as
   the export button, which may never promise a count without saying what it
   counts. Warn, not alert: nothing is broken and one click fixes it. */
.unfinished{display:inline-block;margin-left:var(--s2);padding:1px 7px;border-radius:9999px;
  background:var(--warn-soft);color:var(--warn);font-size:11.5px;font-weight:600;
  border:1px solid color-mix(in srgb,var(--warn) 25%,transparent);cursor:help}

/* ---------- Candidate Fit (A08) ----------
   The Role's approved assessment, the guided review of a proposal, what a
   Cycle inherits, and a candidate's explanation. Same tokens, same chrome as
   every other record page; the accent marks only the current step. */
.fit-dl dd .sub{display:block;font-size:12px;color:var(--ink-3);margin-top:2px;line-height:1.45}
.fit-list{margin:0;padding:0;list-style:none}
.fit-list li{padding:3px 0;line-height:1.45}
.fit-list li+li{border-top:1px solid var(--line-2)}
.fit-list .sub{display:block;font-size:12px;color:var(--ink-3);margin-top:1px}
.fit-origin,.fit-treat{font-style:normal;font-size:11.5px;color:var(--ink-3);margin-left:5px}
.fit-review{display:grid;grid-template-columns:200px minmax(0,1fr);gap:var(--s5);align-items:start}
.fit-rail{display:flex;flex-direction:column;gap:2px;position:sticky;top:var(--s5)}
.fit-step{display:grid;grid-template-columns:20px minmax(0,1fr);gap:2px 8px;align-items:baseline;text-align:left;
  background:none;border:0;border-left:2px solid transparent;padding:6px 10px;font:inherit;font-size:13px;color:var(--ink-3);cursor:pointer;border-radius:0 6px 6px 0}
.fit-step:hover{color:var(--ink-2);background:var(--line-2)}
.fit-step b{font-weight:600;font-variant-numeric:tabular-nums;color:inherit}
.fit-step span{color:inherit}
.fit-step i{grid-column:2;font-style:normal;font-size:11.5px;color:var(--ink-3)}
.fit-step.done{color:var(--ink-2)}
.fit-step.now{color:var(--ink);border-left-color:var(--accent);font-weight:580}
.fit-step:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.fit-body{min-width:0;max-width:720px}
.fit-body .fit-settled{margin-top:var(--s4)}
.fit-eyebrow{margin:0 0 var(--s3);font-size:12px;color:var(--ink-3)}
.fit-question{margin:0 0 var(--s4);font-size:19px;font-weight:620;letter-spacing:-.014em;line-height:1.3}
.fit-q .about{margin:0 0 var(--s4)}
.fit-conflict{display:grid;gap:var(--s2);margin:0 0 var(--s4);font-size:13px;color:var(--ink-2)}
.fit-conflict b{display:block;font-size:11.5px;font-weight:600;color:var(--ink-3);letter-spacing:.02em}
.fit-answers{display:grid;gap:var(--s2);margin:0 0 var(--s4)}
.fit-answer{display:block;width:100%;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:10px 12px;font:inherit;color:var(--ink);cursor:pointer;line-height:1.4}
.fit-answer:hover{border-color:var(--ink-3)}
.fit-answer:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.fit-answer b{display:block;font-weight:580}
.fit-answer span{display:block;font-size:12.5px;color:var(--ink-2);margin-top:2px}
.fit-answer i{display:block;font-style:normal;font-size:11.5px;color:var(--ink-3);margin-top:3px}
.fit-answer[aria-pressed="true"]{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.fit-evidence{margin:0 0 var(--s4)}
.fit-quotes{margin:10px 0 0;padding:0;list-style:none;font-size:13px;color:var(--ink-2);line-height:1.5}
.fit-quotes li{padding:6px 0 6px 12px;border-left:2px solid var(--line)}
.fit-quotes li+li{margin-top:6px}
.fit-quotes b{display:block;font-size:11.5px;font-weight:600;color:var(--ink-3)}
.fit-conf{margin:0 0 var(--s4);font-size:12.5px}
.fit-acts{margin-top:var(--s2)}
.fit-stale{margin:0 0 var(--s4)}
.fit-retry{padding:2px 8px;font-size:12px;margin-left:4px}
.fit-pool-line{font-size:12.5px;color:var(--ink-2)}
.fit-explain .fit-dl{margin-top:var(--s3);font-size:12.5px}
@media (max-width:900px){ .fit-review{grid-template-columns:1fr} .fit-rail{position:static;flex-direction:row;flex-wrap:wrap} }

/* ---------- paid consent (paid.js) ----------
   The one dialog every spend goes through: the facts as a .dl, an add-on
   only ever unchecked, one primary carrying the price, Cancel the quiet rung.
   No page redraws it; a screen that spends money asks here. */
dialog.pay{max-width:520px}
.pay-dl{margin:0}
.dlg label.pay-addon{display:flex;gap:8px;align-items:flex-start;margin:var(--s4) 0 0;font-size:13px;font-weight:400;color:var(--ink-2);line-height:1.45}
.pay-addon input{margin:3px 0 0;flex:none;width:auto}
.pay-addon .p{color:var(--ink-3);font-style:normal;font-size:11.5px}
