/* ===========================================================
   PRIORITY FILTER — design system
   Colour has one job each:
     navy   = structure      blue = thinking
     green  = commitment     grey = set aside
   Red is a deliberate, single exception (added 2026-08-07, Lewis's
   explicit call): account deletion specifically, nowhere else. Every
   other destructive action in this app (archive a board, delete a
   board, clear a board) stays on the quiet/blue scale on purpose — see
   those flows for why. Don't reach for red for anything short of
   "destroys the account itself."
   Layout narrows and quietens as the list shrinks.
   =========================================================== */

:root{
  --navy:#16265C;
  --navy-deep:#0F1B45;
  --royal:#2A45C4;
  --blue:#1E56D6;
  --blue-ink:#173F9E;
  --blue-soft:#EAF0FB;
  --blue-soft-2:#F4F8FE;
  --blue-line:#D4E2F7;

  --green:#4CAF50;
  --green-light:#73C177;
  --green-dark:#3D9142;
  --green-soft:#EAF7EB;
  --green-line:#BFE3C1;

  --red-dark:#8C1D1D;
  --red-soft:#FBEAEA;
  --red-line:#EFC6C6;

  --ink:#0F1729;
  --ink-2:#2C3652;
  --grey:#5F6B84;
  --grey-2:#8A94A8;
  --grey-line:#E3E7EF;
  --grey-soft:#F4F5F8;

  --white:#fff;
  --page:#FBFCFE;

  --r-sm:8px; --r:12px; --r-lg:18px; --r-xl:24px;
  --sh-1:0 1px 2px rgba(16,27,69,.05), 0 2px 8px rgba(16,27,69,.05);
  --sh-2:0 2px 6px rgba(16,27,69,.06), 0 10px 30px rgba(16,27,69,.08);
  --sh-3:0 20px 60px rgba(16,27,69,.16);

  --font-h:'Poppins', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-b:'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--page); color:var(--ink);
  font-family:var(--font-b); font-size:16px; line-height:1.55;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  display:flex; flex-direction:column; min-height:100vh; min-height:100dvh;
}
h1,h2,h3,h4{font-family:var(--font-h); margin:0; line-height:1.18; letter-spacing:-.01em}
p{margin:0}
button{font:inherit; color:inherit}
a{color:var(--blue)}
:focus-visible{outline:2.5px solid var(--blue); outline-offset:2px; border-radius:4px}

/* ---------- header (full brand: this is where you arrive) ---------- */
.topbar{background:var(--navy); color:#fff; padding:0 0 2px; position:relative; z-index:5}
.topbar-in{
  max-width:1180px; margin:0 auto; padding:20px 22px;
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
}
.wordmark{display:flex; align-items:center; gap:11px; text-decoration:none; color:#fff; flex:0 0 auto}
.wordmark-mark{color:var(--green); display:flex}
.wordmark-text{display:flex; flex-direction:column; line-height:1}
.wordmark-text strong{font-family:var(--font-h); font-weight:700; font-size:15.5px; letter-spacing:.19em}
.wordmark-text em{font-family:var(--font-h); font-style:normal; font-weight:400; font-size:10.5px; letter-spacing:.42em; color:#A9BCE8; margin-top:4px}

/* Beta tag (2026-09-20): signals this is still early — same reasoning
   Lewis gave for it as Gmail's own long-running "Beta" label once did —
   and buys room to stay free now and figure out pricing later without
   that read as a bait-and-switch once it ends. Quiet by design: a small
   outlined pill, not a banner — it names a fact, it doesn't apologize
   for one. */
.beta-tag{
  font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:#A9BCE8; border:1px solid rgba(169,188,232,.45); border-radius:999px;
  padding:2px 8px; flex:0 0 auto; margin-left:-2px;
}

.topbar-right{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-left:auto}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border:1px solid transparent; border-radius:var(--r-sm); cursor:pointer;
  padding:10px 18px; font-size:14.5px; font-weight:600; font-family:var(--font-b);
  transition:background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease), transform .1s var(--ease), box-shadow .18s var(--ease);
  text-decoration:none; white-space:nowrap;
}
.btn:active{transform:translateY(1px)}
.btn:disabled{opacity:.42; cursor:not-allowed; transform:none}
.btn[hidden]{display:none} /* .btn's own display:inline-flex otherwise outranks the browser's [hidden] default */

/* green = commitment / the way forward. exactly one per screen. */
.btn-go{background:var(--green); color:#fff; box-shadow:0 1px 2px rgba(61,145,66,.35)}
.btn-go:hover:not(:disabled){background:var(--green-dark)}
.btn-ghost-light{background:transparent; color:#C8D5F2; border-color:rgba(255,255,255,.2); padding:8px 13px}
.btn-ghost-light:hover{background:rgba(255,255,255,.1); color:#fff}
.btn-quiet{background:var(--white); color:var(--ink-2); border-color:var(--grey-line); box-shadow:var(--sh-1)}
.btn-quiet:hover:not(:disabled){border-color:#C3CCDC; background:#fff}
.btn-blue{background:var(--blue); color:#fff}
.btn-blue:hover:not(:disabled){background:var(--blue-ink)}
/* Account deletion only — see the design-system note at the top of this
   file for why this is the one place red appears. */
.btn-danger{background:var(--red-dark); color:#fff}
.btn-danger:hover:not(:disabled){background:#711515}
.btn-danger-text{background:var(--white); color:var(--red-dark); border-color:var(--red-line); box-shadow:var(--sh-1)}
.btn-danger-text:hover:not(:disabled){background:var(--red-soft); border-color:#E2A7A7}
.btn-plain{background:transparent; border-color:transparent; color:var(--grey); padding:9px 12px}
.btn-plain:hover:not(:disabled){color:var(--ink); background:var(--grey-soft)}
.btn-sm{padding:7px 13px; font-size:13.5px}
.btn-lg{padding:14px 30px; font-size:16px}
.btn-icon-only{padding:10px 14px}

/* ---------- board switcher (list only now — lives inside the side
   panel's Boards section, Part 2 section B, not its own persistent bar
   anymore) ---------- */
.switcher-list{display:flex; flex-direction:column; gap:6px}
.switcher-opt{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:11px 14px; border:1px solid var(--grey-line); border-radius:var(--r-sm);
  background:#fff; cursor:pointer; text-align:left; font-family:var(--font-b);
  transition:all .14s var(--ease);
}
.switcher-opt:hover{border-color:#C9D4E6; background:var(--blue-soft-2)}
.switcher-opt.is-here{border-color:var(--blue-line); background:var(--blue-soft-2)}
.switcher-opt--new{color:var(--blue-ink); font-weight:600; border-style:dashed}
.switcher-opt-namecol{display:flex; flex-direction:column; gap:2px; min-width:0}
.switcher-opt-name{font-size:14.5px; font-weight:500; color:var(--ink); overflow-wrap:anywhere}
.switcher-opt-date{font-size:12px; color:var(--grey-2)}
.switcher-opt-tag{flex:0 0 auto; font-size:11px; font-weight:700; color:var(--blue-ink); background:var(--blue-soft); padding:2px 8px; border-radius:999px}

/* a board row = the switch button plus its "⋯" actions button, side by side */
.switcher-row{display:flex; align-items:stretch; gap:6px}
.switcher-row .switcher-opt{flex:1; min-width:0}
.switcher-more{
  flex:0 0 auto; width:38px; border:1px solid var(--grey-line); border-radius:var(--r-sm);
  background:#fff; color:var(--grey-2); font-size:16px; cursor:pointer;
  display:grid; place-items:center; transition:all .14s var(--ease);
}
.switcher-more:hover{border-color:#C9D4E6; color:var(--ink-2); background:var(--blue-soft-2)}

/* C.18: archived boards, collapsed by default — the switcher's only way
   to reach them until the Boards page exists (Part 2) */
.switcher-archived{margin-top:10px; padding-top:10px; border-top:1px solid var(--grey-line)}
.switcher-archived summary{
  font-size:12.5px; font-weight:600; color:var(--grey-2); cursor:pointer; list-style:none;
  display:flex; align-items:center; gap:6px;
}
.switcher-archived summary::-webkit-details-marker{display:none}
.switcher-archived summary::before{content:'▸'; font-size:10px}
.switcher-archived[open] summary::before{content:'▾'}
.switcher-opt--archived{
  flex:1; display:flex; align-items:center; padding:11px 14px;
  border:1px solid var(--grey-line); border-radius:var(--r-sm); background:var(--grey-soft);
  cursor:default;
}
.switcher-archived .switcher-row{margin-bottom:6px}

/* Current board's name, in the header (item B.10) — moved here from a
   Capture-only placement (2026-08-07, Lewis's call) because the risk it
   guards against (working in the wrong board) isn't specific to
   Capture; every stage needed the same persistent cue, not just one of
   five. Sits between the wordmark and the header's right-side buttons,
   filling whatever space is left between them (.topbar-right's own
   margin-left:auto is what makes that work without this needing fixed
   positioning). Light text for the navy background — the wordmark's own
   sub-label color, not full white, so it reads as secondary chrome
   rather than competing with the logo. Truncates instead of wrapping or
   pushing the header buttons around on a narrow screen. */
.board-tag{
  font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:#A9BCE8; margin:0 14px; flex:1 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.board-tag[hidden]{display:none}

/* ---------- stage rail ---------- */
.rail{background:#fff; border-bottom:1px solid var(--grey-line); position:sticky; top:0; z-index:4}
/* The only cue that the tab row scrolls, on a viewport too narrow to show
   all five at once. Fades in on whichever side still has more, fades out
   once you've scrolled that direction as far as it goes. */
.rail-fade{
  position:absolute; top:0; bottom:1px; width:28px; pointer-events:none;
  opacity:0; transition:opacity .15s var(--ease); z-index:1;
}
.rail-fade--l{left:0; background:linear-gradient(to right, #fff, rgba(255,255,255,0))}
.rail-fade--r{right:0; background:linear-gradient(to left, #fff, rgba(255,255,255,0))}
.rail-fade.is-visible{opacity:1}
.rail-in{
  max-width:1180px; margin:0 auto; padding:0 22px;
  display:flex; align-items:stretch; gap:2px; overflow-x:auto; scrollbar-width:none;
  transition:max-width .2s var(--ease);
}
/* The rail's own box narrows to match whatever stage is showing beneath it,
   so the first tab's left edge lines up with the content's left edge exactly
   — not just roughly — instead of sitting in a permanently wider box than
   the (deliberately) narrower stage content. */
:root[data-stage="capture"] .rail-in{max-width:820px}
:root[data-stage="gate"] .rail-in{max-width:660px}
:root[data-stage="score"] .rail-in{max-width:680px}
:root[data-stage="focus"] .rail-in{max-width:760px}
:root[data-stage="boards"] .rail-in{max-width:760px}
.rail-in::-webkit-scrollbar{display:none}
.rail-step{
  border:0; background:transparent; cursor:pointer; position:relative;
  padding:14px 4px 13px; margin-right:26px; display:flex; align-items:center; gap:9px;
  font-size:13.5px; font-weight:600; color:var(--grey-2); white-space:nowrap;
  border-bottom:2.5px solid transparent; transition:color .18s var(--ease);
}
.rail-step:hover:not(:disabled){color:var(--ink-2)}
.rail-step:disabled{cursor:not-allowed; opacity:.45}
.rail-step .num{
  width:21px; height:21px; border-radius:50%; display:grid; place-items:center;
  background:var(--grey-soft); color:var(--grey-2); font-size:11.5px; font-weight:700;
  border:1px solid var(--grey-line); transition:all .18s var(--ease);
}
.rail-step[aria-current="true"]{color:var(--navy); border-bottom-color:var(--blue)}
.rail-step[aria-current="true"] .num{background:var(--blue); color:#fff; border-color:var(--blue)}
.rail-step.done .num{background:var(--green-soft); color:var(--green-dark); border-color:var(--green-line)}
.rail-step.done{color:var(--ink-2)}
.rail-count{
  font-size:11px; font-weight:700; color:var(--grey-2);
  background:var(--grey-soft); border-radius:999px; padding:2px 7px;
}
.rail-step[aria-current="true"] .rail-count{background:var(--blue-soft); color:var(--blue-ink)}
.rail-step:last-child{margin-left:10px}

/* ---------- app footer ---------- */
.app-footer{display:flex; justify-content:center; padding:10px 22px 28px}
.app-footer-link{
  background:none; border:0; color:var(--grey-2); font-size:12.5px; font-weight:500; cursor:pointer;
  padding:9px 13px; border-radius:999px; transition:all .16s var(--ease); font-family:var(--font-b);
}
.app-footer-link:hover{color:var(--navy); background:var(--grey-soft)}

/* ---------- stage shell: widths narrow as the list shrinks ---------- */
main{flex:1 0 auto; width:100%}
/* Capture's empty state only: don't stretch main to fill the viewport, so
   the page (and the footer right after it) stays only as tall as the
   centered block actually needs instead of always spanning the full
   screen height. Every other page/state keeps the default above.
   Also drops body's own 100vh/100dvh floor for the same reason — with
   that floor still in place, content height and viewport height are
   fighting a tight, near-equal fit, and small cross-browser rendering
   differences (font metrics render a few px differently in Firefox vs.
   Chromium) can tip it over the edge at some zoom levels and not others.
   Removing the floor entirely removes the tight fit, not just the
   symptom of it. */
html.is-capture-empty main{flex:0 1 auto}
html.is-capture-empty body{min-height:0}
.stage{margin:0 auto; padding:38px 22px 88px; animation:rise .32s var(--ease)}
/* Was 820px — wider than either Screen (660px) or Score (680px), the
   other two single-column stages, with no stated reason to be. A short
   item title in a row that wide left the trash icon stranded far from
   the text with a lot of dead space between them. Brought in line with
   Score's 680px; the empty-state input already narrows further on its
   own (.capture-box, 600px) so this only affects the populated view.
   Caught live 2026-09-20. */
.stage--capture{max-width:680px; display:flex; flex-direction:column; min-height:100%; padding-bottom:32px}
/* Once the list has anything in it, the header block sits at the top and
   doesn't need the same top gap the empty/centered state does. */
.stage--capture.is-anchored{padding-top:18px}
.stage--gate{max-width:660px; padding-top:18px}
.stage--score{max-width:680px; padding-top:18px}
/* Screen, Score, and Capture's anchored state were all deliberately
   matched to an 18px top padding in earlier work (down to a measured
   27px nav-to-content gap) — Choose was never brought into that pass
   and was still sitting on the generic 38px default, 20px more than
   the other three with no stated reason for the difference. Caught
   live 2026-09-20. */
.stage--place{max-width:1180px; padding-top:18px}
.stage--focus{max-width:760px; padding-top:74px}
@keyframes rise{from{opacity:0; transform:translateY(9px)} to{opacity:1; transform:none}}

/* Capture only: while the board is empty, the header block (headline,
   subhead, input, helper line) centers in the space below the nav instead
   of sitting at the top. .cap-shell fills that space (flex:1 inside the
   already-flex-column .stage--capture); while empty, two spacer children
   split the remaining room 45/55 rather than an even 50/50 — dead center
   reads as sitting slightly low, optical centering wants a bit less below
   than above. Once anything's captured, the spacers are gone entirely and
   this is just a normal top-to-bottom stack. */
.cap-shell{display:flex; flex-direction:column; flex:1}
.cap-shell.is-empty{min-height:480px}
.cap-spacer{flex-shrink:0}
.cap-shell.is-empty .cap-spacer--before{flex-grow:45}
.cap-shell.is-empty .cap-spacer--after{flex-grow:55}
/* Short viewport: centering has no room to work with, so fall back to the
   same top-anchored position the non-empty state uses rather than let the
   header block get crushed against the nav. */
@media (max-height:640px){
  .cap-shell.is-empty .cap-spacer{flex-grow:0}
  .cap-shell.is-empty{min-height:0}
}

/* The four elements (headline, subhead, input, helper) read as one group —
   the tightest gaps are between all of them, with the one big gap in the
   whole block landing below the helper line, right before the list. */
.cap-headerblock .capture-box{margin-top:11px}

/* While empty, the block reads as an invitation, not a document — centered
   text, a narrower input so it doesn't stretch edge-to-edge, everything on
   one axis. Once anything's captured this reverts to a normal left-aligned
   working list, which is what you actually want once there's a list to scan. */
.cap-shell.is-empty .cap-headerblock{text-align:center}
.cap-shell.is-empty .cap-headerblock .lede{margin-left:auto; margin-right:auto}
.cap-shell.is-empty .cap-headerblock .capture-box{max-width:600px; margin-left:auto; margin-right:auto}

.stage h1{font-size:clamp(27px,4.3vw,38px); font-weight:600; color:var(--navy); letter-spacing:-.02em}
.stage h1 .accent{color:var(--blue)}
/* Capture's headline is a single longer sentence now (no accent split),
   which read too heavy at the shared size once it wraps to two lines. */
.stage--capture h1{font-size:clamp(22px,3.2vw,29px)}
/* Bigger only while centered/empty — a confident greeting with room to
   breathe — not once anchored, where it sits above a growing list and
   the smaller size above still applies. */
.stage--capture.is-empty h1{font-size:clamp(26px,4vw,35px)}
.lede{margin-top:11px; color:var(--grey); font-size:15.5px; max-width:60ch}
.stage-head{margin-bottom:28px}

/* ---------- capture ---------- */
.capture-box{
  background:#fff; border:1px solid var(--grey-line); border-radius:var(--r-lg);
  box-shadow:var(--sh-2); padding:8px; display:flex; gap:8px; align-items:center;
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.capture-box:focus-within{border-color:var(--blue-line); box-shadow:0 0 0 4px rgba(30,86,214,.09), var(--sh-2)}
.capture-box input{
  flex:1; min-width:0; border:0; outline:0; background:transparent;
  padding:13px 12px; font-size:16.5px; font-family:var(--font-b); color:var(--ink);
}
.capture-box input::placeholder{color:var(--grey-2)}
.capture-hint{margin-top:11px; font-size:13px; color:var(--grey-2); line-height:1.7}
.capture-hint kbd{margin-right:5px}
kbd{
  font-family:var(--font-b); font-size:11px; font-weight:600; background:var(--grey-soft);
  border:1px solid var(--grey-line); border-bottom-width:2px; border-radius:5px; padding:1.5px 6px; color:var(--grey);
}

.cap-list{list-style:none; margin:28px 0 0; padding:0; display:flex; flex-direction:column; border-top:1px solid var(--grey-line)}
.cap-row{
  display:flex; align-items:flex-start; gap:12px; padding:9px 6px 9px 4px;
  border-bottom:1px solid var(--grey-line); animation:rise .22s var(--ease);
}
.cap-row:hover{background:var(--blue-soft-2)}
.cap-idx{
  flex:0 0 26px; text-align:right; font-size:12.5px; font-weight:600;
  color:var(--grey-2); font-variant-numeric:tabular-nums; padding-top:9px;
}
.cap-row .icon-btn{margin-top:1px}
.cap-title{
  flex:1; min-width:0; border:1px solid transparent; background:transparent;
  font-size:16.5px; font-family:var(--font-b); font-weight:500; color:var(--ink);
  padding:6px 9px; border-radius:var(--r-sm); outline:0;
  resize:none; overflow:hidden; line-height:1.45; display:block;
}
.cap-title:hover{border-color:var(--grey-line)}
.cap-title:focus{border-color:var(--blue-line); background:#fff; box-shadow:0 0 0 3px rgba(30,86,214,.08)}
.icon-btn{
  border:1px solid transparent; background:transparent; color:var(--grey-2); cursor:pointer;
  width:32px; height:32px; border-radius:var(--r-sm); display:grid; place-items:center; flex:0 0 auto;
  transition:all .16s var(--ease); opacity:.55;
}
.cap-row:hover .icon-btn, .icon-btn:focus-visible{opacity:1}
.icon-btn:hover{background:var(--grey-soft); color:var(--ink)}
.icon-btn.danger:hover{background:#FDECEC; color:#B4443F}
.icon-btn:disabled{opacity:.2; cursor:not-allowed}

/* ---------- the fork (board-modes spec, section C) ----------
   Two equal green primary actions on one screen is a deliberate exception
   to the "green = commitment, exactly one per screen" rule above — the
   spec calls for it explicitly: two genuinely equal questions, and making
   one visually secondary would smuggle back the effort-framing ("pick the
   short one") the wording is written to avoid. Side by side, never
   stacked, so neither reads as preferred or first. */
.fork{display:flex; gap:20px; margin-top:34px; flex-wrap:wrap}
.fork-col{flex:1 1 220px; display:flex; flex-direction:column; align-items:center}
.fork-caption{
  font-size:13.5px; font-weight:600; line-height:1.3; color:var(--ink-2);
  text-align:center; margin-bottom:9px;
}
.fork-caption b{font-weight:700}
.fork-box{padding:12px 26px; white-space:normal}

.empty{
  border:1.5px dashed var(--blue-line); border-radius:var(--r-lg); background:var(--blue-soft-2);
  padding:38px 26px; text-align:center; color:var(--grey); margin-top:26px;
}
.empty strong{display:block; font-family:var(--font-h); font-size:16.5px; color:var(--navy); margin-bottom:7px; font-weight:600}
.empty p{font-size:14.5px; max-width:44ch; margin:0 auto}

.stage-foot{
  margin-top:34px; padding-top:24px; border-top:1px solid var(--grey-line);
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
}
.stage--capture .stage-foot, .stage--place .stage-foot{border-top:0}
.stage-foot .spacer{flex:1}

/* ---------- stage 2: downside gate ---------- */
.gate-top{margin-bottom:11px}
.gate-subtitle{font-size:13.5px; color:var(--grey); margin-bottom:9px}
.stage--gate .gcard-title{padding-top:18px}
.stage--gate .gcard-body{padding-top:15px}
/* The gate must be fast: the Yes/No has to be reachable without scrolling,
   because you do this once per opportunity, fifty times over. */
.stage--gate .field{margin-bottom:12px}
.stage--gate textarea.inp{min-height:60px}
.stage--gate .field label{margin-bottom:6px}
.stage--gate .field .sub{margin-top:3px; font-size:12.5px}
.gate-prog{display:flex; align-items:center; gap:13px}
.gate-prog-txt{font-size:12.5px; font-weight:600; color:var(--grey-2); white-space:nowrap; font-variant-numeric:tabular-nums}
.gate-bar{flex:1; height:5px; border-radius:999px; background:var(--grey-line); overflow:hidden}
.gate-bar i{display:block; height:100%; background:var(--blue); border-radius:999px; transition:width .3s var(--ease)}

.gcard{
  background:#fff; border:1px solid var(--grey-line); border-radius:var(--r-xl);
  box-shadow:var(--sh-2); overflow:hidden; animation:rise .28s var(--ease);
}
.gcard.is-in{border-color:var(--green-line)}
.gcard.is-out{border-color:var(--grey-line); background:var(--grey-soft)}
.gcard-title{
  font-size:clamp(21px,3.2vw,26px); font-weight:600; color:var(--navy);
  padding:20px 26px 0; letter-spacing:-.02em; overflow-wrap:anywhere;
}
.gcard.is-out .gcard-title{color:var(--grey)}
.gcard-body{padding:17px 26px 20px}

.field .req{
  display:inline-block; margin-left:8px; font-size:10px; font-weight:700; letter-spacing:.1em;
  background:var(--blue-soft); color:var(--blue-ink); padding:2.5px 7px; border-radius:999px; vertical-align:1px;
}
/* optional reads quieter than required — grey, not blue, same "lower
   urgency" language grey already carries everywhere else in the app */
.field .opt{
  display:inline-block; margin-left:8px; font-size:10px; font-weight:700; letter-spacing:.1em;
  background:var(--grey-soft); color:var(--grey); padding:2.5px 7px; border-radius:999px; vertical-align:1px;
}
.binary{display:grid; grid-template-columns:1fr 1fr; gap:11px}
.bin-btn{
  text-align:left; border:1.5px solid var(--grey-line); background:#fff; border-radius:var(--r);
  padding:12px 15px; cursor:pointer; display:flex; flex-direction:column; gap:3px;
  transition:all .16s var(--ease); font-family:var(--font-b);
}
.bin-btn:hover:not(:disabled){border-color:#BFCADB; box-shadow:var(--sh-1)}
.bin-btn:disabled{opacity:.42; cursor:not-allowed}
.bin-title{font-size:14.5px; font-weight:600; color:var(--ink)}
.bin-yes.is-on{border-color:var(--green); background:var(--green-soft); box-shadow:0 0 0 3px rgba(76,175,80,.13)}
.bin-yes.is-on .bin-title{color:var(--green-dark)}
/* ruled out is grey, never red — saying no is the point of the tool, not a failure */
.bin-no.is-on{border-color:#98A3B8; background:#EDEFF4; box-shadow:0 0 0 3px rgba(95,107,132,.13)}
.bin-no.is-on .bin-title{color:var(--ink-2)}

.gate-nav{position:relative; display:flex; align-items:center; gap:10px; margin-top:22px; flex-wrap:wrap}
/* Centered on the row itself — not "between Previous and Next", which
   drifts off-true whenever those two buttons aren't the same width. */
.gate-nav-mid{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); white-space:nowrap}
@media (max-width:560px){
  /* Absolute-centering a nowrap label risks overlapping Previous on a
     narrow screen regardless of how much room it actually needs — so on
     mobile it drops onto its own centered row below instead. */
  .gate-nav > *:nth-child(1){order:1}
  .gate-nav-mid{
    position:static; transform:none; left:auto; top:auto;
    order:4; flex:1 0 100%; text-align:center; margin-top:4px; white-space:normal;
  }
  .gate-nav > .spacer{order:2}
  .gate-nav > *:nth-child(4){order:3}
}
@media (min-width:561px){
  /* .btn:active's press-down transform otherwise overrides the centering
     transform above (same specificity, later rule wins) and yanks this
     button off-center the instant it's clicked — which also made clicks
     miss it, since the target moves out from under the cursor mid-click. */
  .gate-nav-mid:active{transform:translate(-50%,-50%)}
}
.gate-nav .spacer{flex:1}
.gate-tally{margin-top:22px; text-align:center; font-size:13px; color:var(--grey-2)}
.gate-tally b{color:var(--ink-2); font-weight:700}
.notice{
  margin-top:18px; background:var(--blue-soft-2); border:1px solid var(--blue-line);
  border-radius:var(--r); padding:14px 16px; font-size:14px; color:var(--ink-2);
}

/* overview list */
.ov-list{display:flex; flex-direction:column; gap:5px; max-height:52vh; overflow:auto; margin:-4px}
.ov-row{
  display:flex; align-items:center; gap:12px; text-align:left; width:100%;
  border:1px solid var(--grey-line); background:#fff; border-radius:var(--r-sm);
  padding:11px 13px; cursor:pointer; font-family:var(--font-b); transition:all .14s var(--ease);
}
.ov-row:hover{border-color:var(--blue-line); background:var(--blue-soft-2)}
.ov-num{flex:0 0 auto; font-size:12px; font-weight:700; color:var(--grey-2); min-width:18px; font-variant-numeric:tabular-nums}
.ov-title{flex:1; font-size:14.5px; color:var(--ink); overflow-wrap:anywhere}
.ov-tag{flex:0 0 auto; font-size:11px; font-weight:700; letter-spacing:.05em; padding:3px 9px; border-radius:999px; background:var(--grey-soft); color:var(--grey-2); white-space:nowrap}
.ov-in .ov-tag{background:var(--green-soft); color:var(--green-dark)}
.ov-out .ov-tag{background:#E9EBF0; color:var(--grey)}
.ov-out .ov-title{color:var(--grey)}

@media (max-width:560px){
  .binary{grid-template-columns:1fr}
  .gcard-title{padding:22px 18px 0}
  .gcard-body{padding:18px 18px 22px}
}

/* ---------- stage 3: scorecard ---------- */
.scard{
  background:#fff; border:1px solid var(--grey-line); border-radius:var(--r-xl);
  box-shadow:var(--sh-2); overflow:hidden; animation:rise .28s var(--ease);
}
.scard.is-done{border-color:var(--blue-line)}

.sgroup{margin-bottom:26px}
.sgroup-head{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  padding-bottom:9px; margin-bottom:16px; border-bottom:1px solid var(--grey-line);
}
.sgroup-head h3{font-size:14px; font-weight:700; letter-spacing:.11em; text-transform:uppercase}
.sgroup-head span{font-size:12.5px; color:var(--grey-2)}
.sgroup--cost .sgroup-head h3{color:var(--ink-2)}
.sgroup--benefit .sgroup-head h3{color:var(--blue-ink)}

.srow{margin-bottom:20px}
.srow:last-child{margin-bottom:4px}
.srow-top{display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:9px}
.srow-top label{font-size:15px; font-weight:600; color:var(--ink); cursor:pointer}
.sval{
  flex:0 0 auto; min-width:34px; text-align:center; font-family:var(--font-h); font-weight:600;
  font-size:15px; padding:3px 9px; border-radius:var(--r-sm); font-variant-numeric:tabular-nums;
}
.sgroup--cost .sval{background:#EDEFF4; color:var(--ink-2)}
.sgroup--benefit .sval{background:var(--blue-soft); color:var(--blue-ink)}
.sval.is-unset{background:var(--grey-soft); color:var(--grey-2)}
.shint{font-size:12.5px; color:var(--grey-2); margin-top:8px; line-height:1.45}

/* endpoint numbers flank the rail — small enough to read as a scale
   marker, not a second value competing with the chip above. */
.srow-rail{display:flex; align-items:center; gap:9px}
.srow-rail .slider{flex:1}
.srow-end{
  flex:0 0 auto; font-size:11px; font-weight:600; color:var(--grey-2);
  font-variant-numeric:tabular-nums; width:14px; text-align:center;
}

/* range input — costs slate, benefits blue. green stays reserved for commitment.
   Height is well beyond the visible 6px track on purpose: the whole band is
   the click/tap target, not just the thin line, so a grab never has to be
   precise. */
.slider{
  -webkit-appearance:none; appearance:none; width:100%; height:34px; background:transparent;
  cursor:pointer; display:block; margin:0;
}
.slider:focus{outline:none}
.slider::-webkit-slider-runnable-track{
  height:6px; border-radius:999px;
  background:linear-gradient(to right, var(--track-on) 0 var(--fill), var(--grey-line) var(--fill) 100%);
}
.slider::-moz-range-track{height:6px; border-radius:999px; background:var(--grey-line)}
.slider::-moz-range-progress{height:6px; border-radius:999px; background:var(--track-on)}
.slider::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:22px; height:22px; border-radius:50%;
  background:#fff; border:2.5px solid var(--track-on); margin-top:-8px;
  box-shadow:0 1px 4px rgba(16,27,69,.22); transition:transform .12s var(--ease);
}
.slider::-moz-range-thumb{
  width:18px; height:18px; border-radius:50%; background:#fff; border:2.5px solid var(--track-on);
  box-shadow:0 1px 4px rgba(16,27,69,.22);
}
.slider:active::-webkit-slider-thumb{transform:scale(1.14)}
.slider:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px rgba(30,86,214,.22)}
.sgroup--cost .slider{--track-on:#7C89A3}
.sgroup--benefit .slider{--track-on:var(--blue)}

/* unset: a thin dotted line, no handle, until a value is placed */
.slider.is-unset::-webkit-slider-runnable-track{
  height:2px; background:repeating-linear-gradient(to right, var(--grey-2) 0 4px, transparent 4px 9px);
}
.slider.is-unset::-moz-range-track{
  height:2px; background:repeating-linear-gradient(to right, var(--grey-2) 0 4px, transparent 4px 9px);
}
.slider.is-unset::-moz-range-progress{background:transparent}
/* A faint, hollow handle at the midpoint — not the solid filled thumb a
   real value gets — signals "click or drag here" without asserting a
   value that hasn't been chosen yet. Works identically for mouse and
   touch, unlike a hover-only cue. */
.slider.is-unset::-webkit-slider-thumb{
  background:transparent; border-color:var(--grey-2); box-shadow:none;
}
.slider.is-unset::-moz-range-thumb{
  background:transparent; border-color:var(--grey-2); box-shadow:none;
}
.slider.is-unset:hover::-webkit-slider-thumb{border-color:var(--track-on)}
.slider.is-unset:hover::-moz-range-thumb{border-color:var(--track-on)}
.slider.is-unset:focus-visible::-webkit-slider-runnable-track{box-shadow:0 0 0 3px rgba(30,86,214,.22)}
.slider.is-unset:focus-visible::-moz-range-track{box-shadow:0 0 0 3px rgba(30,86,214,.22)}

.netbox{
  display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap;
  border-top:1px solid var(--grey-line); padding-top:18px; margin-top:4px;
}
.netlabel{display:block; font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2)}
.netsum{display:block; font-size:12.5px; color:var(--grey-2); margin-top:4px; font-variant-numeric:tabular-nums}
.netnum{
  font-family:var(--font-h); font-size:38px; font-weight:600; line-height:1;
  letter-spacing:-.02em; font-variant-numeric:tabular-nums;
}
.netnum.is-pos{color:var(--navy)}
.netnum.is-zero{color:var(--grey-2)}
.netnum.is-neg{color:var(--grey)}
.netnum.is-unset{color:var(--grey-2)}

/* ranked preview */
.rankprev{
  margin-top:34px; padding-top:26px; border-top:1px solid var(--grey-line); animation:rise .3s var(--ease);
}
.rankprev h3{font-size:18px; font-weight:600; color:var(--navy)}
.rankprev-note{margin-top:7px; font-size:13.5px; color:var(--grey); max-width:56ch}
.ranklist{list-style:none; margin:18px 0 0; padding:0; counter-reset:r}
.ranklist li{
  display:flex; align-items:center; gap:12px; padding:10px 2px;
  border-bottom:1px solid var(--grey-line);
}
.rank-i{flex:0 0 22px; font-size:12.5px; font-weight:700; color:var(--grey-2); font-variant-numeric:tabular-nums}
.rank-t{flex:1 1 40%; min-width:0; font-size:14.5px; font-weight:500; color:var(--ink); overflow-wrap:anywhere}
.rank-bar{flex:0 0 84px; height:6px; border-radius:999px; background:var(--grey-line); overflow:hidden}
.rank-bar i{display:block; height:100%; border-radius:999px}
.rank-bar i.pos{background:var(--blue)}
.rank-bar i.neg{background:#98A3B8}
.rank-n{
  flex:0 0 auto; min-width:36px; text-align:right; font-family:var(--font-h); font-weight:600;
  font-size:15px; color:var(--navy); font-variant-numeric:tabular-nums;
}
.rank-n.is-neg{color:var(--grey)}

@media (max-width:560px){
  .netnum{font-size:32px}
  .rank-bar{display:none}
}

/* ---------- stage 4: choose / placement ---------- */
/* Centered on purpose (2026-08-07, Lewis's call): the page's own
   headline says what it's for — "where each one lands" — so the title
   reads better presiding over both columns than pinned to the left edge
   of just the Captured/Ranked one. */
.stage--place .stage-head{text-align:center}
.placegrid{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:26px; align-items:start}
/* The tiers are the actual point of this page (its own headline says
   so) — the Ranked/Captured list is source material to work through,
   not the destination. Hiding it (via the toggle in .pcol-head, item
   list built in rankColumn()) re-centers and widens what's left rather
   than leaving it stranded in the grid's original half-width column. */
.placegrid.is-solo{grid-template-columns:minmax(0,1fr); max-width:760px; margin:0 auto}
.pcol-head{margin-bottom:14px; padding-bottom:11px; border-bottom:1px solid var(--grey-line); display:flex; align-items:center; gap:10px}
/* Stacked mode only: the tier column's own header (Stacked/Side by side,
   "Show captured items") used to span the full ~577px column, edge to
   edge — but the cards below it are now capped at 520px and centered
   (see .tierbox), so the header sat wider than everything underneath it,
   poking out past both edges of the cards. Capped and centered to match,
   so the header and the cards read as one aligned block. Reset back to
   full width in row mode just below (.is-row-mode) — that mode's cards
   span a whole horizontally-scrolling row, not a fixed centered column,
   so there's nothing here for the header to match widths with. Caught
   live 2026-09-20. */
.pcol--tiers .pcol-head{max-width:520px; margin-left:auto; margin-right:auto}
.pcol--tiers.is-row-mode .pcol-head{max-width:none; margin-left:0; margin-right:0}
.pcol-head h2{font-size:17px; font-weight:600; color:var(--navy)}

/* Mixed path's two-sub-list column (mixedRankColumn(), stage-place.js).
   Subhead sits smaller than .pcol-head's own h2 — it's one of two
   labels sharing a column that already has its own header controls
   above it, not a page-level heading competing with them. */
.pcol-subhead{font-size:13px; font-weight:700; color:var(--grey-2); text-transform:uppercase; letter-spacing:.06em; margin-bottom:10px}
.pcol-section--stacked{margin-top:24px}
/* margin-left:auto rather than the parent's justify-content:space-between
   — the Direct-path Captured column has no heading text (see rankColumn's
   comment), so this button needs to pin right on its own regardless of
   whether it's the only child or has an h2 sibling before it. */
.pcol-hide{
  background:none; border:0; color:var(--grey-2); font-size:12.5px; font-weight:600; cursor:pointer;
  padding:4px 8px; border-radius:var(--r-sm); transition:all .14s var(--ease); font-family:var(--font-b);
  margin-left:auto;
}
.pcol-hide:hover{color:var(--blue-ink); background:var(--grey-soft)}

/* Stacked / Side by side — only offered once Captured is hidden (solo
   mode, see .placegrid.is-solo above) and only above the 900px breakpoint
   this same page already uses to drop to a single column. Below that,
   both the toggle and the row layout it controls are hard-disabled by
   CSS rather than JS tracking viewport width — .pcol--tiers.is-row's own
   rule is overridden back to a column, and the control itself hides, so
   a state left over from a wider window can't leave the page stuck in a
   layout that doesn't fit. */
.tier-layout{display:flex; gap:4px}
@media (max-width:900px){
  .tier-layout{display:none}
}

/* Row mode: each tierbox becomes a fixed-width column that scrolls its
   own item list internally rather than growing the whole page taller —
   the same reason a kanban board scrolls per-column, since the tiers'
   caps are asymmetric (Committed defaults to 3, In the Running to 10) and
   forcing equal heights would either crop the smaller ones oddly or
   stretch them with dead space. The row itself scrolls horizontally
   if there isn't room for every column at once, rather than shrinking
   them illegibly.
   Applied to .tier-boxes, a dedicated wrapper around just the boxes —
   NOT to .pcol--tiers itself, which also contains .pcol-head (the
   Stacked/Side by side/Show captured controls). A real bug caught live:
   putting .is-row on .pcol--tiers made that header a flex item squeezed
   in alongside the tier boxes instead of a normal full-width row above
   them. */
.tier-boxes.is-row{
  display:flex; flex-direction:row; align-items:flex-start; gap:16px;
  overflow-x:auto; padding-bottom:6px;
}
.tier-boxes.is-row .tierbox{flex:0 0 260px; margin-left:0; margin-right:0}
.tier-boxes.is-row .tierlist{max-height:360px; overflow-y:auto}
/* A 260px column has no room for title + owner chip + buttons on one
   line — they were fighting for space, which forced the title to wrap
   character-by-character into a tall, narrow sliver, with the chip
   ending up vertically centered in the middle of that mess (and the
   rename pencil stranded at the bottom, disconnected from anything).
   Giving the title flex-basis:100% forces it onto its own full-width
   line every time; everything after it (chip, net score, Move, x) wraps
   onto the line(s) below instead of squeezing in beside it. Caught live
   2026-09-20 with a long owner name as the test case. */
.tier-boxes.is-row .tierlist li{flex-wrap:wrap; align-items:flex-start; row-gap:6px}
.tier-boxes.is-row .tl-title{flex:1 1 100%}
@media (max-width:900px){
  .tier-boxes.is-row{display:block; overflow-x:visible}
  .tier-boxes.is-row .tierbox{flex-basis:auto}
  .tier-boxes.is-row .tierlist{max-height:none; overflow-y:visible}
}

/* Row mode needs real width — several fixed columns side by side, not
   one narrow stack — so it gets a wider cap than plain solo mode
   (.placegrid.is-solo's 760px). Below 900px this doesn't matter: the
   toggle that produces .is-row is hidden there, so this class is never
   applied on a viewport narrow enough for the wider cap to cause
   horizontal overflow of the page itself. */
.placegrid.is-row{max-width:1180px}

.placelist{display:flex; flex-direction:column; gap:8px}
.pitem{
  display:flex; align-items:center; gap:12px; background:#fff; border:1px solid var(--grey-line);
  border-radius:var(--r); padding:11px 13px; transition:all .16s var(--ease); cursor:pointer;
}
.pitem:hover{border-color:#C9D4E6; box-shadow:var(--sh-1)}
.pitem:focus-visible{outline:2.5px solid var(--blue); outline-offset:2px}
.pitem.is-placed{border-color:var(--blue-line); background:var(--blue-soft-2)}
.pitem.is-parked{background:var(--grey-soft)}
.pitem.is-parked .pitem-title{color:var(--grey)}
.pitem-rank{
  flex:0 0 auto; min-width:20px; font-size:12.5px; font-weight:700; color:var(--grey-2);
  font-variant-numeric:tabular-nums;
}
.pitem-mid{flex:1; min-width:0; display:flex; flex-direction:column; gap:5px}
.pitem-title{font-size:14.5px; font-weight:500; color:var(--ink); overflow-wrap:anywhere; line-height:1.35}
.pitem-btn{flex:0 0 auto}

/* read-only scorecard view, opened from a Ranked row */
.scoreview-net{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  border-bottom:1px solid var(--grey-line); padding-bottom:16px; margin-bottom:16px;
}
.scoreview-netlabel{font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2)}
.scoreview-netnum{
  font-family:var(--font-h); font-size:30px; font-weight:600; line-height:1;
  letter-spacing:-.02em; font-variant-numeric:tabular-nums; color:var(--navy);
}
.scoreview-netnum.is-neg{color:var(--grey)}
.scoreview-netnum.is-zero{color:var(--grey-2)}
.scoreview-group{margin-bottom:18px}
.scoreview-group:last-child{margin-bottom:0}
.scoreview-group h4{
  font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2);
  margin-bottom:9px; padding-bottom:7px; border-bottom:1px solid var(--grey-line);
}
.scoreview-row{display:flex; align-items:center; justify-content:space-between; gap:12px; padding:6px 0}
.scoreview-rowlabel{font-size:14px; color:var(--ink)}
.scoreview-rowval{
  flex:0 0 auto; min-width:28px; text-align:center; font-family:var(--font-h); font-weight:600;
  font-size:14px; padding:2px 8px; border-radius:var(--r-sm); font-variant-numeric:tabular-nums;
}
.scoreview-rowval--cost{background:#EDEFF4; color:var(--ink-2)}
.scoreview-rowval--benefit{background:var(--blue-soft); color:var(--blue-ink)}

.chip{
  display:inline-block; font-size:10.5px; font-weight:700; letter-spacing:.06em;
  padding:2.5px 8px; border-radius:999px; white-space:nowrap;
}
.chip--parked{background:#E9EBF0; color:var(--grey)}
.chip--shortlist{background:var(--blue-soft); color:var(--blue-ink)}
.chip--contenders{background:#DCE7FA; color:var(--blue-ink)}
/* the Committed tier is the one place green appears here */
.chip--committed{background:var(--green-soft); color:var(--green-dark)}
/* now is committed harder still — solid, not soft */
.chip--now{background:var(--green); color:#fff}
/* Owner: informational, not tied to a tier's meaning — neutral, not
   part of the blue/green tier-color family on purpose. */
/* Owner is free text with no length limit — without a cap, a long name
   forces the whole row wider than its box (in side-by-side mode, wider
   than the fixed-width column itself, dragging the row's own horizontal
   scroll into view). Truncates with an ellipsis instead; the `title`
   attribute on each usage restores the full name on hover for desktop,
   same "supplementary, not the only way to see it" treatment as
   everything else in this app that degrades for touch. Caught live
   2026-09-20 with "Jimmy Jimmy Jimmy" as the test case. */
.chip--owner{background:#EEF1F6; color:var(--ink-2); max-width:120px; overflow:hidden; text-overflow:ellipsis}
/* the gap-flag: a quiet outline, not a fill — visible without reading
   as urgent (this app never uses red). */
.chip--noowner{background:transparent; color:var(--grey-2); border:1px dashed var(--grey-line)}

.tierbox{
  background:#fff; border:1px solid var(--grey-line); border-radius:var(--r-lg);
  padding:16px 17px; margin-bottom:13px; transition:all .2s var(--ease);
  /* Stacked mode's column stretches to ~577px on a wide viewport, which
     left a card holding a couple of short item rows looking sparse and
     over-wide — the content didn't earn that much box. Capped narrower;
     row/side-by-side mode's own flex-basis:260px (see .tier-boxes.is-row
     below) already overrides this there, so this only affects stacked.
     Same class is shared with the public share page's tier boxes, which
     benefits from the same cap. Now narrower than its column, it needs
     to actually center there or it just reads as left-docked with a
     lopsided gap on the right — .tier-boxes.is-row overrides this back
     to 0 below, since a flex row of fixed-width columns has no leftover
     space per-item to center within. Caught live 2026-09-20. */
  max-width:520px; margin-left:auto; margin-right:auto;
}
.tierbox--committed{border-color:var(--green-line); background:var(--green-soft)}
.tierbox--parked{background:var(--grey-soft); border-style:dashed}
/* now is the tightest possible tier — solid green, the boldest thing on the board */
.tierbox--now{background:var(--green); border-color:var(--green-dark)}
.tierbox--now .tierbox-head h3{color:#fff}
.tierbox--now .tierbox-blurb{color:rgba(255,255,255,.82)}
.tierbox--now .tierbox-count{background:rgba(255,255,255,.22); color:#fff; border-color:rgba(255,255,255,.3)}
.tierbox--now .tierdots i{background:rgba(255,255,255,.32)}
.tierbox--now .tierdots i.on{background:#fff}
.tierbox--now .tierlist li{background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.25)}
.tierbox--now .tl-title{color:#fff}
.tierbox--now .tl-net{color:rgba(255,255,255,.85)}
.tierbox--now .icon-btn{color:rgba(255,255,255,.8)}
.tierbox--now .icon-btn:hover{background:rgba(255,255,255,.2); color:#fff}
.tierbox--now .rename-edit-btn{color:rgba(255,255,255,.8)}
.tierbox--now .rename-edit-btn:hover, .tierbox--now .rename-edit-btn:focus-visible{background:rgba(255,255,255,.2); color:#fff}
.tierbox--now.is-full{border-color:#fff; box-shadow:0 0 0 3px rgba(255,255,255,.35)}
.tierbox--now .tierbox-fullnote{background:rgba(255,255,255,.85); color:var(--navy)}
/* a full tier visibly tightens — you see "full" before being told */
.tierbox.is-full{border-width:2px; border-color:var(--navy); box-shadow:0 0 0 3px rgba(22,38,92,.07)}
.tierbox--committed.is-full{border-color:var(--green); box-shadow:0 0 0 3px rgba(76,175,80,.14)}
.tierbox-head{display:flex; align-items:flex-start; justify-content:space-between; gap:12px}
.tierbox-head h3{font-size:15.5px; font-weight:600; color:var(--navy)}
.tierbox-blurb{display:block; font-size:12px; color:var(--grey-2); margin-top:3px}
.tierbox-count{
  flex:0 0 auto; font-size:12px; font-weight:700; color:var(--ink-2); background:rgba(255,255,255,.85);
  border:1px solid var(--grey-line); border-radius:999px; padding:3px 10px; font-variant-numeric:tabular-nums;
}
.tierdots{display:flex; gap:5px; margin:12px 0 4px}
.tierdots i{flex:1; height:4px; border-radius:999px; background:var(--grey-line); transition:background .2s var(--ease)}
.tierdots i.on{background:var(--blue)}
.tierbox--committed .tierdots i.on{background:var(--green)}
.tierbox-fullnote{
  margin-top:11px; font-size:12px; font-weight:600; color:var(--navy);
  background:rgba(255,255,255,.7); border-radius:var(--r-sm); padding:7px 10px;
}
.tierlist{list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:6px}
.tierlist li{
  display:flex; align-items:center; gap:9px; background:rgba(255,255,255,.9);
  border:1px solid rgba(22,38,92,.07); border-radius:var(--r-sm); padding:8px 9px 8px 11px;
  cursor:pointer; transition:border-color .16s var(--ease);
}
.tierlist li:hover{border-color:#C9D4E6}
.tierlist li:focus-visible{outline:2.5px solid var(--blue); outline-offset:1px}
.tierbox--parked .tierlist li{background:#fff}
.tl-title{flex:1; min-width:0; font-size:13.5px; color:var(--ink); overflow-wrap:anywhere; line-height:1.35}
.tl-net{
  flex:0 0 auto; font-size:12.5px; font-weight:700; color:var(--grey); font-variant-numeric:tabular-nums;
}

/* Owner + Notes modal (stage-place.js's openItemDetails) */
.itemdetail-label{
  display:block; font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-2); margin:16px 0 6px;
}
.itemdetail-label:first-child{margin-top:0}
.itemdetail-input, .itemdetail-textarea{
  width:100%; border:1px solid var(--grey-line); background:#fff;
  font-size:15px; font-family:var(--font-b); color:var(--ink);
  padding:9px 11px; border-radius:var(--r-sm); outline:0;
}
.itemdetail-textarea{resize:vertical; line-height:1.45}
.itemdetail-input:focus, .itemdetail-textarea:focus{
  border-color:var(--blue-line); box-shadow:0 0 0 3px rgba(30,86,214,.08);
}

/* ---------- share.html — the public, read-only board view ----------
   Reuses .tierbox/.tierlist/.chip etc. as-is for visual consistency with
   the real Choose page, so this never reads as a second product bolted
   on. The rows here aren't clickable (no edit affordance exists on this
   page at all), so the pointer cursor and hover states .tierlist li
   carries for the real app are turned off within this scope only. */
.share-main{max-width:640px; margin:0 auto; padding:38px 22px 88px}
.share-main.is-row{max-width:1180px}
.share-title{font-family:var(--font-h); font-size:22px; font-weight:700; color:var(--navy)}
.share-sub{margin-top:8px; font-size:14px; color:var(--grey)}
.share-main .tier-layout{margin:26px 0 22px}
.share-tiers{margin-top:0}
.share-tiers .tierlist li{cursor:default}
.share-tiers .tierlist li:hover{border-color:rgba(22,38,92,.07)}
.share-notice{
  max-width:520px; margin:80px auto 0; text-align:center;
  font-size:15px; color:var(--grey); padding:0 22px;
}
.share-cta{
  margin-top:30px; padding-top:20px; border-top:1px solid var(--grey-line);
  text-align:center; font-size:14px; color:var(--grey);
}
.share-cta-link{color:var(--blue); font-weight:600; text-decoration:none}
.share-cta-link:hover{text-decoration:underline}

/* placer modal */
.placer{display:flex; flex-direction:column; gap:9px}
.placer-opt{
  text-align:left; border:1.5px solid var(--grey-line); background:#fff; border-radius:var(--r);
  padding:13px 15px; cursor:pointer; display:flex; flex-direction:column; gap:4px;
  font-family:var(--font-b); transition:all .15s var(--ease);
}
.placer-opt:hover{border-color:var(--blue-line); background:var(--blue-soft-2)}
.placer-opt.is-here{border-color:var(--blue); background:var(--blue-soft)}
.placer-opt.is-full{border-style:dashed}
.placer-opt--park{border-style:dashed; background:var(--grey-soft)}
.placer-name{
  display:flex; align-items:center; gap:9px; font-size:15px; font-weight:600; color:var(--ink);
}
.placer-cap{
  font-size:11px; font-weight:700; color:var(--grey); background:var(--grey-soft);
  border-radius:999px; padding:2px 8px; font-variant-numeric:tabular-nums;
}
.placer-blurb{font-size:12.5px; color:var(--grey-2)}

.swap-in{
  background:var(--blue-soft); border-radius:var(--r); padding:12px 14px; margin-bottom:14px;
  font-size:14px; color:var(--blue-ink);
}
.swap-in span{display:block; font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; opacity:.75; margin-bottom:3px}
.swap-in b{font-weight:600; overflow-wrap:anywhere}
.ov-go{flex:0 0 auto; font-size:11.5px; font-weight:700; color:var(--blue); white-space:nowrap}

@media (max-width:900px){
  .placegrid{grid-template-columns:1fr; gap:30px}
  /* Below this width the grid is one column, so it's read top to
     bottom like any other page — and the tiers, not the ranked list,
     are the actual point of this page (see .placegrid's own comment
     above). Without this, a mobile user has to scroll past the whole
     ranked list just to see what's in Committed. Visual order only
     (not DOM order), so this doesn't touch hideCaptured/tiersSideBySide
     at all — it's correct whether or not Ranked is currently hidden. */
  .pcol--tiers{order:-1}
}
@media (max-width:560px){
  /* stay on one row — a 30-item list must not become an endless scroll */
  .pitem{gap:9px; padding:10px 10px 10px 8px}
  .pitem-rank{min-width:14px; font-size:11.5px}
  .pitem-title{font-size:14px}
  .pitem-btn{padding:6px 11px; font-size:12.5px}
  .chip{font-size:10px; padding:2px 7px}
}

/* ---------- stage 5: focus ----------
   The answer, not a question — no headline, minimal chrome. Composed
   like Capture's empty state: centers in the space below the nav rather
   than sitting hard against it, for the entire normal (capacity-limited)
   range of Focus, not just some special "empty" case. */
.stage--focus{max-width:760px; display:flex; flex-direction:column; min-height:100%; padding-top:18px}
.focus-shell{display:flex; flex-direction:column; flex:1; min-height:480px}
.focus-spacer{flex-shrink:0}
.focus-spacer--before{flex-grow:45}
.focus-spacer--after{flex-grow:55}
@media (max-height:640px){
  .focus-shell{min-height:0}
  .focus-spacer{flex-grow:0}
}

.focusview{text-align:left; animation:rise .4s var(--ease)}
.focuslist{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:30px}
.focuslist li{display:flex; align-items:flex-start; gap:14px}
/* Body-scale, regular weight — this used to render at near-headline size,
   which turned a page holding real item names into a poster. It's still
   the thing you're looking at, just not shouting. */
.fl-t{
  flex:1; font-family:var(--font-b); font-size:19px; font-weight:400;
  color:var(--ink); line-height:1.4; overflow-wrap:anywhere;
}

/* the only checkbox in the app — Committed and Now only. Checking it completes
   the item immediately; there's no lingering "checked" state to render.
   Secondary to the item name now, not the first thing the eye lands on —
   smaller and lighter than it used to be. */
.fl-check{
  flex:0 0 auto; width:20px; height:20px; margin-top:3px; padding:0;
  border:1.5px solid var(--grey-line); border-radius:6px; background:#fff; color:transparent;
  cursor:pointer; display:grid; place-items:center; transition:all .14s var(--ease);
}
.fl-check:hover, .fl-check:focus-visible{border-color:var(--green); background:var(--green-soft); color:var(--green)}
.fl-check:active{transform:scale(.9)}
.fl-check.on-dark{border-color:rgba(255,255,255,.55); background:rgba(255,255,255,.12)}
.fl-check.on-dark:hover, .fl-check.on-dark:focus-visible{border-color:#fff; background:rgba(255,255,255,.28); color:#fff}

/* Now — the single thing, pulled out ahead of the Committed list. Solid, not
   soft: it's meant to read as the boldest thing on the screen. */
.now-banner{
  display:flex; align-items:center; gap:14px; text-align:left;
  background:var(--green); color:#fff; border-radius:var(--r-lg);
  padding:14px 18px; margin-bottom:32px; box-shadow:0 8px 22px rgba(76,175,80,.3);
}
.now-banner-tag{
  flex:0 0 auto; font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  background:rgba(255,255,255,.22); padding:4px 10px; border-radius:999px;
}
.now-banner-title{
  flex:1; font-family:var(--font-h); font-weight:600; font-size:clamp(17px,2.6vw,21px);
  overflow-wrap:anywhere; letter-spacing:-.01em;
}
.now-banner .rename-edit-btn{color:rgba(255,255,255,.75)}
.now-banner .rename-edit-btn:hover, .now-banner .rename-edit-btn:focus-visible{background:rgba(255,255,255,.22); color:#fff}
.now-banner .rename-input{background:rgba(255,255,255,.95); color:var(--ink); border-color:rgba(255,255,255,.7)}

/* The one remaining link — same quiet, centered, muted treatment as the
   site-wide "About" footer link, not left-aligned with the rows above it.
   Sits inside the shell (not as a sibling after it) purely so it isn't
   shoved down to the very bottom of the page by the shell's own flex:1 —
   the extra top margin below is what actually separates it from the
   list, so it still reads as a distinct, secondary thing rather than
   part of the list itself. */
.focus-links{display:flex; justify-content:center; align-items:center; gap:4px; margin-top:56px}
.archive-link{
  background:none; border:0; color:var(--grey-2); font-size:12.5px; font-weight:500; cursor:pointer;
  padding:9px 13px; border-radius:999px; transition:all .16s var(--ease); font-family:var(--font-b);
}
.archive-link:hover{color:var(--navy); background:var(--grey-soft)}

@media (max-width:560px){
  .focuslist{gap:24px}
  .now-banner{padding:12px 14px; gap:11px; margin-bottom:26px}
}

/* ---------- stage: boards page (multi-board Part 2, section C) ----------
   Item 23: must look composed at two rows, its most common early state —
   same centering treatment as Capture's empty state and Focus's list,
   rather than jamming a couple of rows flush under the nav on an
   otherwise empty page. Unlike Capture, this page is never actually
   "empty" (it only exists once a second board does), so the shell
   always centers rather than switching between two layouts. */
.stage--boards{max-width:760px; display:flex; flex-direction:column; min-height:100%; padding-top:18px}
.boards-shell{display:flex; flex-direction:column; flex:1; min-height:480px}
.boards-spacer{flex-shrink:0}
.boards-spacer--before{flex-grow:45}
.boards-spacer--after{flex-grow:55}
@media (max-height:640px){
  .boards-shell{min-height:0}
  .boards-spacer{flex-grow:0}
}

.boards-content{animation:rise .4s var(--ease)}
.boards-head{margin-bottom:18px}
.boards-content h1{margin-bottom:18px}

.boards-sort{display:flex; align-items:center; gap:10px; margin-bottom:20px}
.boards-sort-label{font-size:12.5px; font-weight:600; color:var(--grey-2)}
.boards-sort-opt{
  background:none; border:1px solid transparent; border-radius:999px; cursor:pointer;
  padding:5px 12px; font-size:13px; font-weight:500; color:var(--grey); font-family:var(--font-b);
  transition:all .14s var(--ease);
}
.boards-sort-opt:hover{color:var(--ink-2); background:var(--grey-soft)}
.boards-sort-opt.is-active{color:var(--blue-ink); background:var(--blue-soft); font-weight:600}

/* Rows, not cards (item 15) — modeled on Google Docs: name, last-opened
   date, "⋯" menu. Nothing else per row (item 16 — no counts, no state). */
.boards-rows{display:flex; flex-direction:column; border-top:1px solid var(--grey-line)}
.boards-row{
  display:flex; align-items:center; gap:14px; padding:13px 4px;
  border-bottom:1px solid var(--grey-line);
}
.boards-row-name{
  flex:1; min-width:0; text-align:left; background:none; border:0; cursor:pointer;
  font-size:15px; font-weight:500; color:var(--ink); font-family:var(--font-b);
  padding:6px 8px; border-radius:var(--r-sm); overflow-wrap:anywhere; transition:background .14s var(--ease);
}
.boards-row-name:hover{background:var(--grey-soft)}
.boards-row-date{flex:0 0 auto; font-size:12.5px; color:var(--grey-2)}
.boards-row-more{flex:0 0 auto}

.boards-archived{margin-top:22px; padding-top:14px; border-top:1px solid var(--grey-line)}
.boards-archived summary{
  font-size:12.5px; font-weight:600; color:var(--grey-2); cursor:pointer; list-style:none;
  display:flex; align-items:center; gap:6px;
}
.boards-archived summary::-webkit-details-marker{display:none}
.boards-archived summary::before{content:'▸'; font-size:10px}
.boards-archived[open] summary::before{content:'▾'}
/* Settings' column-label editor specifically — a bigger, darker marker
   than the Boards page's own archived-section arrow, since this one's
   the only cue that there's a whole editor hiding behind "Customize
   column labels" (2026-09-20, Lewis's catch). Scoped so the Boards page
   arrow is untouched. */
.settings-collapse summary::before{font-size:14px; color:var(--ink-2)}
/* Same contrast-not-size logic as the arrow: these eyebrows stay
   smaller than the content they introduce (that subordination IS the
   hierarchy), but get a darker color so they're easier to notice at a
   glance without competing with the field labels below them. */
.settings-eyebrow{color:var(--ink-2); letter-spacing:.08em}
.boards-row--archived{color:var(--grey-2)}
.boards-row--archived .boards-row-name{cursor:default; padding:6px 8px; color:var(--grey-2)}
.boards-row--archived .boards-row-name:hover{background:none}

/* Item 41: desktop-pattern rows (date column + per-row menu) collapse on
   narrow viewports by dropping the date rather than letting the row
   wrap — the "⋯" menu is already a single collapsed action set on every
   viewport, so nothing else needs to change here. */
@media (max-width:720px){
  .boards-row-date{display:none}
}

/* ---------- stage: sort (Mixed path tagging, docs/mixed-path-spec.md) ----------
   Modeled on the Boards page's own layout (narrow single column, a quiet
   "← Back" up top) rather than any of the five main stages — this isn't
   a step in working a board, it's a utility page you dip into. */
.stage--sort{max-width:680px; padding-top:18px}
.sort-head{margin-bottom:18px}
.sort-section-head{font-size:13px; font-weight:700; color:var(--grey-2); text-transform:uppercase; letter-spacing:.06em; margin-bottom:10px}
.sort-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px}
.sort-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  background:#fff; border:1px solid var(--grey-line); border-radius:var(--r); padding:11px 13px;
}
.sort-row-title{flex:1; min-width:0; font-size:14.5px; color:var(--ink); overflow-wrap:anywhere}
.sort-row-opts{flex:0 0 auto; display:flex; gap:6px}

/* ---------- accounts ---------- */
.googlebtn{gap:10px; font-weight:600; padding:12px 18px}
.author{display:flex; align-items:center; gap:12px; margin:18px 0}
.author::before,.author::after{content:""; flex:1; height:1px; background:var(--grey-line)}
.author span{font-size:12px; color:var(--grey-2)}
.autherr{
  background:#FDECEC; border:1px solid #F3C9C7; color:#9E3B37; border-radius:var(--r-sm);
  padding:10px 13px; font-size:13.5px; margin-bottom:14px;
}
.authtoggle{
  display:block; width:100%; margin-top:14px; background:none; border:0; cursor:pointer;
  color:var(--blue); font-size:13.5px; font-weight:600; font-family:var(--font-b); padding:6px;
}
.authtoggle:hover{text-decoration:underline}
.authnote{margin-top:16px; font-size:12.5px; color:var(--grey-2); line-height:1.6}
.accwho{
  background:var(--blue-soft-2); border:1px solid var(--blue-line); border-radius:var(--r); padding:14px 16px;
}
.accwho span{display:block; font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--grey-2)}
.accwho b{display:block; font-size:15.5px; color:var(--navy); margin-top:4px; overflow-wrap:anywhere}
.twoup{display:grid; grid-template-columns:1fr 1fr; gap:11px}
.twoup > div{border:1px solid var(--grey-line); border-radius:var(--r); padding:13px 14px; background:#fff}
.twoup b{display:block; font-size:14px; color:var(--navy)}
.twoup span{display:block; font-size:12.5px; color:var(--grey-2); margin-top:4px}
@media (max-width:480px){ .twoup{grid-template-columns:1fr} }

/* ---------- inline rename ----------
   The pencil trails the text as a normal inline element rather than
   being pinned to a fixed corner. A fixed-position version was tried
   2026-09-20 (to match ClickUp's separate icon-slot convention) but hit
   two real bugs: it got clipped by the Gate/Score cards' overflow:hidden,
   and short titles left a large empty gap before the icon since it was
   positioned against the field's full stretched width, not the text's
   own end. A true separate-slot version (icon as a row sibling, not
   nested in the title) would fix both properly, but touches all eight
   call sites of editableTitle() including two that have no row to put a
   sibling in today (the Gate/Score cards) — reverted to this simpler,
   fully-tested version instead rather than take on that risk for a
   preference, not a functional problem. Revisit only if this keeps
   reading as odd in real use. */
.rename-edit-btn{
  border:0; background:transparent; padding:3px; margin-left:5px;
  border-radius:6px; color:var(--grey-2); opacity:.5; cursor:pointer;
  display:inline-flex; align-items:center; vertical-align:-3px;
  transition:opacity .12s var(--ease), background .12s var(--ease), color .12s var(--ease);
}
.rename-edit-btn:hover, .rename-edit-btn:focus-visible{opacity:1; background:rgba(30,86,214,.09); color:var(--blue)}
.rename-input{
  font:inherit; color:inherit; letter-spacing:inherit; line-height:inherit;
  background:var(--blue-soft-2); border:1.5px solid var(--blue-line); border-radius:6px;
  padding:0 4px; margin:-1px -4px; outline:0; width:100%; box-sizing:border-box; display:block;
}

/* ---------- completed archive ---------- */
.fquiet{font-size:13.5px; color:var(--grey-2); font-style:italic}
.archive-list{display:flex; flex-direction:column; gap:2px; max-height:56vh; overflow:auto; margin:-2px}
.archive-row{
  display:flex; align-items:center; gap:12px; padding:12px 4px;
  border-bottom:1px solid var(--grey-line);
}
.archive-row:last-child{border-bottom:0}
.archive-main{flex:1; min-width:0; display:flex; flex-direction:column; gap:6px}
.archive-title{font-size:14.5px; font-weight:500; color:var(--ink); overflow-wrap:anywhere}
.archive-meta{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.archive-net{font-size:12.5px; font-weight:700; color:var(--navy); font-variant-numeric:tabular-nums}
.archive-net.is-neg{color:var(--grey)}
.archive-when{font-size:12px; color:var(--grey-2)}

/* ---------- toast ---------- */
/* Above .modal-root's 90, not below it — a toast fired from inside an
   open modal (e.g. Settings' "Copy link") must stay visible over that
   modal, not get buried behind its own scrim. Never came up before this
   was the first toast fired while a modal was open (2026-09-20). */
.toast-root{position:fixed; left:50%; bottom:26px; transform:translateX(-50%); z-index:95; display:flex; flex-direction:column; gap:9px; align-items:center; pointer-events:none}
.toast{
  background:var(--navy); color:#fff; padding:11px 18px; border-radius:999px;
  font-size:14px; font-weight:500; box-shadow:var(--sh-3); display:flex; align-items:center; gap:12px;
  animation:toastIn .26s var(--ease); pointer-events:auto; max-width:min(92vw,520px);
}
.toast button{background:none; border:0; color:var(--green); font-weight:700; cursor:pointer; font-size:13.5px; padding:0; white-space:nowrap}
@keyframes toastIn{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}

/* ---------- modal ---------- */
.modal-root{position:fixed; inset:0; z-index:90; display:grid; place-items:center; padding:20px}
.modal-root[hidden]{display:none}
.modal-scrim{position:absolute; inset:0; background:rgba(15,27,69,.44); backdrop-filter:blur(2px); animation:fade .2s var(--ease)}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{
  position:relative; background:#fff; border-radius:var(--r-xl); box-shadow:var(--sh-3);
  width:min(560px,100%); max-height:88vh; overflow:auto; animation:pop .26s var(--ease);
}
@keyframes pop{from{opacity:0; transform:translateY(14px) scale(.985)} to{opacity:1; transform:none}}
.modal-head{padding:26px 28px 0}
.modal-head h2{font-size:21px; font-weight:600; color:var(--navy)}
.modal-head p{margin-top:9px; color:var(--grey); font-size:14.5px}
.modal-body{padding:20px 28px}
.modal-foot{
  padding:18px 28px 24px; display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap;
  border-top:1px solid var(--grey-line); margin-top:6px;
}
.modal-x{position:absolute; top:16px; right:16px}

/* ---------- side panel ----------
   The hamburger menu (Part 2, section B). Slides in from the right,
   rather than the modal's center-pop — this is navigation/account
   chrome, a different kind of interaction than a single decision. Sits
   just below the modal's z-index: a modal opened from inside the panel
   (Board settings, Rename, etc.) must paint on top of it, not behind. */
.panel-root{position:fixed; inset:0; z-index:85}
.panel-root[hidden]{display:none}
.panel-scrim{position:absolute; inset:0; background:rgba(15,27,69,.34); animation:fade .2s var(--ease)}
.panel-box{
  position:absolute; top:0; right:0; height:100%; width:min(360px,100%);
  background:#fff; box-shadow:var(--sh-3); display:flex; flex-direction:column;
  animation:panelIn .24s var(--ease);
}
@keyframes panelIn{from{transform:translateX(100%)} to{transform:translateX(0)}}
.panel-head{padding:16px 16px 4px; display:flex; align-items:center; justify-content:space-between; flex:0 0 auto}
.panel-head h2{font-size:17px; font-weight:600; color:var(--navy)}
.panel-x{position:relative}
.panel-body{padding:6px 20px 24px; overflow-y:auto; flex:1}

.panel-section{display:flex; flex-direction:column; gap:8px}
.panel-eyebrow{
  font-size:11.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  color:var(--grey-2); margin:4px 0 2px;
}
.panel-divider{border-top:1px solid var(--grey-line); margin:20px 0}
/* Every row that actually goes somewhere (as opposed to a static label
   like .panel-board-name) gets the same shape: text on the left, a
   quiet trailing chevron on the right — the chevron is what tells the
   eye "this opens something" at rest, not just on hover, since the
   hover-only background cue this used to rely on is invisible until
   the pointer's already there. */
.panel-link{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  width:100%; text-align:left; background:none; border:0; cursor:pointer;
  padding:11px 8px; font-size:14.5px; font-weight:600; color:var(--ink-2); font-family:var(--font-b);
  border-radius:var(--r-sm); transition:background .14s var(--ease);
}
.panel-link:hover{background:var(--grey-soft)}
.panel-link--sub{font-weight:500; color:var(--grey); padding-left:2px}
.panel-link .chev{color:var(--grey-2); flex:0 0 auto}
/* Static, non-interactive — the current board's name. Reuses the exact
   visual language of .board-tag (same eyebrow treatment on Capture) so
   the same fact reads the same way in both places, and so it stops
   looking like just another clickable row in a list of clickable rows. */
.panel-board-name{
  font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--blue-ink); padding:8px 8px 6px;
}
.panel-quiet-line{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  width:100%; text-align:left; background:none; border:0; cursor:pointer;
  padding:9px 8px; font-size:13px; color:var(--grey-2); font-family:var(--font-b);
  border-radius:var(--r-sm); transition:color .14s var(--ease);
}
.panel-quiet-line:hover{color:var(--blue-ink); background:var(--grey-soft)}
.panel-quiet-line .chev{color:currentColor; opacity:.6; flex:0 0 auto}

/* ---------- form bits ---------- */
.field{margin-bottom:18px}
.field:last-child{margin-bottom:0}
.field label{display:block; font-size:12px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-2); margin-bottom:8px}
.field .sub{display:block; font-size:13px; color:var(--grey-2); font-weight:400; text-transform:none; letter-spacing:0; margin-top:5px; line-height:1.5}
.inp{
  width:100%; border:1px solid var(--grey-line); border-radius:var(--r); background:#fff;
  padding:12px 14px; font-size:15.5px; font-family:var(--font-b); color:var(--ink); outline:0;
  transition:border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.inp:focus{border-color:var(--blue-line); box-shadow:0 0 0 3.5px rgba(30,86,214,.1)}
.inp::placeholder{color:var(--grey-2)}
textarea.inp{resize:vertical; min-height:84px; line-height:1.55}
.num-inp{width:78px; text-align:center}

.switch-row{display:flex; align-items:flex-start; gap:14px; padding:14px 0; border-bottom:1px solid var(--grey-line)}
.switch-row:last-child{border-bottom:0}
.switch-row .txt{flex:1}
.switch-row .txt b{display:block; font-size:14.5px; color:var(--ink); font-weight:600}
.switch-row .txt span{display:block; font-size:13px; color:var(--grey); margin-top:3px}
.switch{
  flex:0 0 auto; position:relative; width:44px; height:25px; border-radius:999px;
  background:var(--grey-line); border:0; cursor:pointer; transition:background .2s var(--ease); margin-top:2px;
}
.switch::after{content:""; position:absolute; top:3px; left:3px; width:19px; height:19px; border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.22); transition:transform .2s var(--ease)}
.switch[aria-checked="true"]{background:var(--green)}
.switch[aria-checked="true"]::after{transform:translateX(19px)}

@media (max-width:860px){
  .btn-label-wide{display:none}
}
@media (max-width:720px){
  .topbar-in{padding:14px 16px 17px; gap:10px 8px; flex-wrap:wrap}
  .wordmark{gap:9px}
  .wordmark-mark svg{width:22px; height:22px}
  .topbar-right{margin-left:auto; flex-wrap:nowrap; gap:7px}
  .btn-ghost-light{padding:8px 10px}
  .rail-in{padding:0 16px}
  .rail-step{margin-right:18px; font-size:12.5px}
  .stage{padding:26px 16px 70px}
  .modal-head{padding:22px 20px 0}
  .modal-body{padding:16px 20px}
  .modal-foot{padding:16px 20px 20px}
  .modal-foot .btn{flex:1}
}
@media (max-width:400px){
  .wordmark-text strong{font-size:13.5px; letter-spacing:.15em}
  .wordmark-text em{font-size:9.5px; letter-spacing:.34em}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important; transition-duration:.001ms !important}
}
