/* Unfussed — the app shell. One place you stay: a persistent sidebar (new
   chat, history, projects) beside one main surface that is either the module
   gallery (picking what to do) or a conversation (the thing itself).

   Design system lifted deliberately from design/direction/current-vs-recommended.html
   surface 4 panel B ("the transcript, done properly") and surface 3 ("Kind
   Form" intake) — the same tokens, the same class shapes, so this reads as
   one continuous decision rather than a fifth redesign. Chat semiotics are
   the thing that was rejected (bubbles, You/Unfussed ping-pong, a letter
   boxed in turn chrome, an always-open composer) — not the thread. So there
   are no ".turn"/".bubble" classes here at all: a delivered document is
   ".mdoc", full width, paper-quality; the buyer's own words are a quiet
   ".you-block" note, never a speech bubble; the composer is priced labelled
   actions first, a text box only after a choice.
*/
:root {
  color-scheme: light dark;
  --ink: #162019;
  --paper: #f7f3ea; --paper: light-dark(#f7f3ea, #12180f);
  --card: #fffdf8;  --card: light-dark(#fffdf8, #1b2717);
  --line: #d8d5c9;  --line: light-dark(#d8d5c9, rgba(243, 240, 230, .16));
  --acid: #d9ff57;
  --coral: #ff7657;
  --green: #163d29;
  /* Fixed, not light-dark(): the sidebar itself stays forest green in both
     themes (protected item 5), so its own text stays this off-white in both
     themes too — never var(--text), which flips to near-black ink in light
     mode and reads at 1.38:1 on #163d29 (measured, UX_REVIEW_FABLE.md). */
  --sidebar-ink: #f2f5ef;
  --muted: #667064; --muted: light-dark(#667064, #a6b0a3);
  --text: #162019;  --text: light-dark(#162019, #f3f0e6);
  --green-ink: #163d29; --green-ink: light-dark(#163d29, #8fe0af);
  --orange-ink: #b03d20; --orange-ink: light-dark(#b03d20, #ffab8f);
  --well: rgba(22, 32, 25, .05); --well: light-dark(rgba(22, 32, 25, .05), rgba(243, 240, 230, .06));
  --rust: #8c2f13; --rust: light-dark(#8c2f13, #f0a08a);
  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif: Georgia, "Iowan Old Style", "Times New Roman", serif;
  --shadow: 0 16px 40px rgba(32, 38, 28, .10); --shadow: 0 16px 40px light-dark(rgba(32, 38, 28, .10), rgba(0, 0, 0, .45));
  /* T-336 — spacing rhythm scale. The only vertical gaps empty-state and
     interview chrome may use; no other rule in those flows invents a gap. */
  --space-1: 8px;
  --space-2: 12px;
  --space-3: 16px;
  --space-4: 24px;
}
:root[data-theme="light"] { color-scheme: only light; }
:root[data-theme="dark"] { color-scheme: only dark; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--paper); color: var(--text); font: 15.5px/1.55 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid var(--text); outline-offset: 2px; border-radius: 4px; }
.hidden { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------------------------------------------------------------- shell -- */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  flex: 0 0 272px;
  display: flex;
  flex-direction: column;
  /* Always-olive rail — NEVER borrow paper --line / --muted / --text.
     Those light-dark() tokens flip to beige/ink in light and paint 1.38:1
     ghosts on #163d29 (pixel-audit-2026-09-07 HIGH). Local tokens only. */
  --sidebar-fg: #f2f5ef;
  --sidebar-fg-muted: rgba(242, 245, 239, .68);
  --sidebar-stroke: rgba(242, 245, 239, .32);
  --sidebar-stroke-strong: rgba(242, 245, 239, .5);
  --sidebar-fill: rgba(255, 255, 255, .08);
  --sidebar-fill-strong: rgba(255, 255, 255, .12);
  --sidebar-ink: var(--sidebar-fg); /* keep legacy name for history rows */
  border-right: 2px solid rgba(10, 28, 18, .55);
  background: #163d29;
  color: var(--sidebar-fg);
  height: 100vh;
  position: sticky;
  top: 0;
  overflow-y: auto;
}
/* Force cream on brand + controls — beat global `a { color: inherit }` and
   any paper --text that leaked through light-dark in light mode. */
.sidebar a.sidebar-brand,
.sidebar a.sidebar-brand span,
.sidebar .side-row,
.sidebar .sidebar-section h2,
.sidebar .sidebar-empty,
.sidebar .sidebar-foot .account-link,
.sidebar .sidebar-foot .account-link .label {
  color: var(--sidebar-fg);
}
.sidebar a.sidebar-brand,
.sidebar a.sidebar-brand > span:not(.mark) {
  color: #fff;
}
.sidebar .side-row:hover { background: var(--sidebar-fill); }
.sidebar .side-row.active { background: var(--sidebar-fill-strong); color: var(--acid); }
.sidebar .side-row .chev { color: var(--sidebar-fg-muted); }
.sidebar .project-convos { border-left-color: var(--sidebar-stroke); }
.sidebar .sidebar-section h2 { color: var(--sidebar-fg-muted); }
.sidebar .sidebar-foot { border-top-color: var(--sidebar-stroke); }
/* Theme pill: hug glyphs, olive stroke — not a full-width hollow field. */
.sidebar .theme-switch {
  width: max-content;
  max-width: 100%;
  align-self: start;
  border: 2px solid var(--sidebar-stroke);
  background: rgba(0, 0, 0, .18);
}
.sidebar .theme-switch label { color: var(--sidebar-fg-muted); min-width: 36px; min-height: 36px; }
.sidebar .theme-switch label:hover { color: #fff; }
/* Wallet — filled chunk, not 1px wireframe. */
.sidebar-wallet {
  margin: 0 14px 10px;
  padding: 10px 12px;
  border: 2px solid var(--sidebar-stroke);
  border-radius: 12px;
  background: var(--sidebar-fill);
  font-size: 12.5px;
  font-weight: 750;
  color: var(--sidebar-fg-muted);
}
.sidebar-wallet b { color: var(--acid); font-weight: 850; }
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 10px;
  text-decoration: none;
  font-weight: 870;
  letter-spacing: -.03em;
  color: #fff;
}
.sidebar-brand .mark {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 2.5px solid #0a1c12;
  border-radius: 11px;
  background: var(--acid);
  box-shadow: 3px 3px 0 #0a1c12;
  flex: none;
  transform: rotate(-3deg);
}
.sidebar-brand .mark img { display: block; width: 20px; height: 20px; }

.newchat {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  margin: 6px 12px 14px;
  padding: 11px 14px;
  border: 2.5px solid #0a1c12;
  border-radius: 14px;
  background: var(--acid);
  color: #162019;
  font-weight: 850;
  font-size: 14px;
  text-decoration: none;
  box-shadow: 3px 3px 0 #0a1c12;
}
.newchat:hover { background: #c9f13f; }
.newchat .plus { font-size: 17px; line-height: 1; font-weight: 800; }

.sidebar-section { padding: 4px 14px; }
.sidebar-section h2 {
  margin: 14px 4px 6px;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--sidebar-fg-muted);
}
.sidebar nav.projects, .sidebar nav.history { display: grid; gap: 2px; }
.sidebar .side-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--sidebar-fg);
  font-size: 13.5px;
  font-weight: 700;
  text-align: left;
  text-decoration: none;
  overflow: hidden;
}
.side-row .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-row .chev { flex: none; font-size: 10px; color: var(--sidebar-fg-muted); transition: transform .15s; }
.side-row.open .chev { transform: rotate(90deg); }
.sidebar .project-convos {
  display: grid;
  gap: 1px;
  margin: 2px 0 4px 14px;
  padding-left: 10px;
  border-left: 2px solid var(--sidebar-stroke);
}
.project-convos .side-row { font-weight: 650; font-size: 13px; padding: 6px 10px; }
/* Empty gate — olive-safe dashed, never paper --line / --muted. */
.sidebar .sidebar-empty {
  margin: 4px 10px;
  padding: 10px 12px;
  border: 2px dashed var(--sidebar-stroke);
  border-radius: 12px;
  background: rgba(0, 0, 0, .12);
  color: var(--sidebar-fg-muted);
  font-size: 12.5px;
  line-height: 1.5;
}
.sidebar .sidebar-empty a {
  color: var(--acid);
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* History rows (T-LU-288) — the sidebar's flat, primary list of every paid
   conversation. renameControl() (shared with the convo-bar title) is reused
   here with the label swapped for a real <a>, so the row stays a normal
   link (ctrl/cmd-click, right-click) rather than a div faking one. Its own
   wrap div has no layout of its own, so .history-rename supplies the flex
   row .side-row otherwise gives a single text label. */
.history-rename { display: flex; align-items: center; gap: 4px; width: 100%; min-width: 0; }
.history-rename .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; color: inherit; }
.history-row .rename-btn { flex: none; opacity: 0; color: var(--sidebar-fg); }
.history-row:hover .rename-btn, .history-row:focus-within .rename-btn { opacity: .75; }
.history-row .rename-btn:hover { opacity: 1 !important; background: var(--sidebar-fill-strong); }
.history-row .rename-form { flex: 1; min-width: 0; }
.history-row .rename-form input { color: var(--ink); font-size: 13px; padding: 5px 8px; min-width: 0; }

.sidebar-foot {
  margin-top: auto;
  padding: 14px 14px; /* equal — was 12/16 hairline asymmetry */
  border-top: 2px solid var(--sidebar-stroke);
  display: grid;
  gap: 8px;
}
/* Account — chunky filled row, NOT a hollow 1px field (Luke hate).
   Soft fill + 2px olive stroke + lime hover edge; cream label always. */
.sidebar-foot .account-link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 12px;
  border: 2px solid var(--sidebar-stroke);
  border-radius: 14px;
  background: var(--sidebar-fill);
  text-decoration: none;
  color: var(--sidebar-fg);
  font-size: 13px;
  font-weight: 800;
  box-shadow: 2px 2px 0 rgba(10, 28, 18, .45);
}
.sidebar-foot .account-link .label { color: inherit; }
.sidebar-foot .account-link:hover {
  background: var(--sidebar-fill-strong);
  border-color: var(--acid);
  color: #fff;
}
.sidebar-foot .account-link:focus-visible {
  outline: 3px solid var(--acid);
  outline-offset: 2px;
}
.footlinks { display: flex; gap: 12px; padding: 0 2px; }
.footlinks a { color: var(--sidebar-fg-muted); font-size: 12px; font-weight: 700; text-decoration: none; }
.footlinks a:hover { color: #fff; text-decoration: underline; }

/* ---- mobile: sidebar collapses behind a menu button ---- */
.menu-toggle { display: none; position: fixed; top: 12px; left: 12px; z-index: 20; width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 11px; background: var(--card); align-items: center; justify-content: center; box-shadow: var(--shadow); }
.menu-toggle span, .menu-toggle span::before, .menu-toggle span::after { content: ""; display: block; width: 18px; height: 2px; background: var(--text); position: relative; }
.menu-toggle span::before { position: absolute; top: -6px; }
.menu-toggle span::after { position: absolute; top: 6px; }
.sidebar-scrim { display: none; position: fixed; inset: 0; background: rgba(10, 14, 10, .4); z-index: 15; }
@media (max-width: 860px) {
  .menu-toggle { display: flex; }
  .sidebar { position: fixed; z-index: 16; left: 0; top: 0; transform: translateX(-100%); transition: transform .16s ease; box-shadow: var(--shadow); }
  .shell.sidebar-open .sidebar { transform: translateX(0); }
  .shell.sidebar-open .sidebar-scrim { display: block; }
  .scrollarea { padding-top: 58px; }
}

/* ----------------------------------------------------------------- main -- */
.main { flex: 1; min-width: 0; height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
.scrollarea { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; align-items: center; padding: 0 24px 40px; }
.composer { flex: none; border-top: 1px solid var(--line); background: var(--card); padding: 5px 24px; }
.composer.hidden { display: none; }
.composer-inner { width: min(880px, 100%); margin: 0 auto; }

/* ---- picker (gallery) state ---- */
.picker { width: min(920px, 100%); margin: 40px auto 0; }
.picker-head { max-width: 62ch; }
.picker-head .hp-h { margin: 0; font-size: clamp(30px, 4vw, 44px); line-height: .98; letter-spacing: -.05em; font-weight: 900; }
.picker-head .hl { background: linear-gradient(transparent 64%, var(--acid) 64%, var(--acid) 92%, transparent 92%); padding: 0 .04em; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.picker-head .hp-lead { max-width: 60ch; margin: 12px 0 0; color: var(--muted); font-size: 15.5px; line-height: 1.55; }

.area-head { display: flex; align-items: baseline; gap: 10px; margin: 36px 0 12px; }
.area-head:first-of-type { margin-top: 30px; }
.area-head h2 { margin: 0; font-size: 18px; font-weight: 860; letter-spacing: -.03em; }
.area-head .count { color: var(--muted); font-size: 12.5px; font-weight: 700; }
.mod-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.mod-card { display: flex; flex-direction: column; gap: 8px; padding: var(--space-3); border: 2px solid var(--ink); border-color: light-dark(var(--ink), rgba(243, 240, 230, .22)); border-radius: 15px; background: var(--card); box-shadow: 4px 4px 0 var(--mod, var(--ink)); text-decoration: none; color: inherit; transition: transform .12s ease; }
.mod-card:hover { transform: translate(-1px, -1px); box-shadow: 5px 5px 0 var(--mod, var(--ink)); }
.mod-card .name { font-weight: 850; letter-spacing: -.024em; font-size: 16px; line-height: 1.22; }
.mod-card .what { color: var(--muted); font-size: 12.5px; line-height: 1.42; flex: 1; }
.mod-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; background: var(--card); }
.chip { font-size: 11px; font-weight: 780; letter-spacing: .02em; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
.chip.points { border-color: transparent; background: var(--well); color: var(--text); }
.chip.tier1 { border-color: transparent; background: var(--coral); color: #1d0d08; }
.chip.engine { border-style: dashed; background: var(--card); }

.skeleton { display: grid; gap: 12px; margin: 18px 0; }
.skeleton .bar { height: 68px; border-radius: 14px; background: linear-gradient(90deg, var(--card) 25%, var(--line) 50%, var(--card) 75%); background-size: 200% 100%; animation: shimmer 1.3s ease-in-out infinite; }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .skeleton .bar { animation: none; }
  .mod-card, .mbtn, .newchat { transition: none; }
  .mod-card:hover { transform: none; }
}
.empty { padding: 22px; border: 2px dashed var(--line); border-radius: 15px; color: var(--muted); margin: 16px 0; }
.msg { margin: 16px 0; padding: var(--space-3); border-radius: 12px; font-size: 14.5px; border: 2px solid; }
.msg.bad { border-color: var(--rust); background: #fdeeea; background: light-dark(#fdeeea, #2b1a15); color: #6d240f; color: light-dark(#6d240f, #f7cfc2); }
.msg.good { border-color: var(--green-ink); background: #eaf6ee; background: light-dark(#eaf6ee, #1a2317); color: #123322; color: light-dark(#123322, #e6f7d2); }

/* ---- conversation (thread) state ---- */
/* T-LU-286: the delivered document owns a pane of its own (§4.3). `.reading`
   is the two-column row — `.thread-rail` (the conversation, narrower once a
   document exists) and `.artifact-panel` (the document, full width of its
   own column, own scroll). `.scrollarea` stops being the single scroller
   for this state — each column scrolls independently instead, so a long
   document does not drag the thread's own scroll position with it. */
.scrollarea:has(.reading) { align-items: stretch; padding: 0; overflow: hidden; }
.reading { display: flex; align-items: stretch; width: 100%; height: 100%; min-height: 0; }
.thread-rail { flex: 1 1 480px; max-width: 620px; min-width: 300px; height: 100%; overflow-y: auto; padding: 0 24px 40px; }
/* No document yet (still generating, or every run failed) — the rail
   reclaims the full width exactly as the old single-column `.convo` did. */
.reading:not(:has(.artifact-panel)) .thread-rail { flex: 1 1 auto; max-width: none; }
.doc-scrim { display: none; }

.convo { width: min(72ch, 100%); margin: 28px auto 0; }
.convo-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 4px 16px; position: sticky; top: 0; z-index: 2; background: var(--paper); }
.convo-bar .crumb { color: var(--muted); font-size: 12.5px; font-weight: 700; text-decoration: none; }
.convo-bar .crumb:hover { text-decoration: underline; }
.convo-bar .title { font-weight: 870; letter-spacing: -.03em; font-size: 17px; }
.convo-bar .rename-btn { border: 0; background: none; padding: 3px 7px; margin: -3px -2px; border-radius: 7px; color: var(--muted); font-size: 12px; font-weight: 800; text-decoration: underline; text-underline-offset: 3px; }
.convo-bar .rename-btn:hover { color: var(--text); background: var(--well); }
.convo-bar .sp { flex: 1; }
.convo-bar .wallet { color: var(--muted); font-size: 12.5px; font-weight: 750; font-variant-numeric: tabular-nums; white-space: nowrap; }
.convo-bar .wallet b { color: var(--green-ink); }
/* .convo-bar is sticky top:0 within .scrollarea. Once the thread is
   scrolled, that "top: 0" wins over the container's own padding-top and the
   bar sticks flush with the viewport top — directly under the fixed
   hamburger (top:12px, height:40px), obscuring the conversation title.
   Sticking at the same 58px offset as the container's padding keeps the bar
   (and its title) permanently clear of the button instead.
   Placed AFTER the base .convo-bar rule above (not inside the shell's own
   860px media block near the top of this file) — same specificity, so
   source order decides, and a rule earlier in the file loses to one later
   in it regardless of which is behind a media query. */
@media (max-width: 860px) {
  .convo-bar { top: 58px; }
}
.rename-form { display: none; align-items: center; gap: 7px; flex-wrap: wrap; }
.rename-form.active { display: flex; }
.rename-form input { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--text); font-size: 14px; min-width: 180px; }
.rename-form button { border: 1px solid var(--ink); border-color: light-dark(var(--ink), rgba(243, 240, 230, .3)); border-radius: 8px; background: var(--acid); color: #162019; font-weight: 800; font-size: 12.5px; padding: 6px 12px; }
.rename-form .cancel { border-color: var(--line); background: transparent; color: var(--muted); font-weight: 700; }

.thread { padding: 4px 0 22px; }
.seam { display: flex; align-items: center; gap: 12px; margin: 14px 0 12px; }
.seam:first-child { margin-top: 0; }
.seam .rule { flex: 1; height: 1px; background: var(--line); }
.seam .tag { display: inline-flex; align-items: center; gap: 8px; padding: 6px 13px; border-radius: 999px; background: var(--ink); background: light-dark(var(--ink), rgba(243, 240, 230, .08)); color: var(--acid); color: light-dark(var(--acid), #f2efe6); font-size: 11.5px; font-weight: 850; white-space: nowrap; }
:root[data-theme="dark"] .seam .tag { outline: 1px solid var(--line); }
.you-block { margin: 0 0 14px; padding: 2px 0 2px 14px; border-left: 3px solid light-dark(rgba(22, 61, 41, .35), rgba(143, 224, 175, .4)); }
.you-block h6 { margin: 0 0 3px; color: var(--muted); font-size: 10.5px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase; }
.you-block p { margin: 0; color: var(--text); font-size: 13.5px; line-height: 1.55; }
.you-block .brief-item + .brief-item { margin-top: 8px; }
.you-block .brief-label { display: block; color: var(--muted); font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 2px; }

/* The curated next step, drawn under the newest delivered document
   (docs/SPEC_MODULES.md §4.4(2)). It borrows the picker's own .mod-grid and
   .mod-card wholesale, so a suggested module and a browsed one are visibly
   the same object and quote their price the same way. Only the frame around
   them is new, and it is deliberately quieter than a document: the same
   uppercase muted h6 the "You told us" note uses, so it reads as the product
   talking rather than as a fourth section of the result. */
.suggests { margin: 14px 0 4px; padding-top: 14px; border-top: 1px solid var(--line); }
.suggests h6 { margin: 0 0 3px; color: var(--muted); font-size: 10.5px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase; }
.suggests .suggests-note { margin: 0 0 13px; color: var(--muted); font-size: 13px; line-height: 1.5; max-width: 62ch; }
/* One suggestion should not stretch to the full width of the pane — at that
   size a single card reads as a banner ad rather than as one of the same
   cards the gallery draws. Two or more fall back to the shared auto-fill. */
.suggests .mod-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.suggests .mod-grid:has(> :only-child) { grid-template-columns: minmax(240px, 420px); }

.vtabs { display: flex; gap: 6px; margin-bottom: -1px; position: relative; z-index: 1; padding-left: 2px; }
.vtabs button { border: 1px solid var(--line); border-bottom: 0; border-radius: 8px 8px 0 0; background: var(--well); color: var(--muted); font-size: 11.5px; font-weight: 850; padding: 7px 13px; }
.vtabs button.on { background: var(--card); color: var(--text); }

.mdoc { border-radius: 12px; background: var(--card); overflow: hidden; margin-bottom: 4px; }
.mdoc-bar { display: flex; align-items: center; gap: 10px; padding: 11px 16px; border-bottom: 1px solid var(--line); font-size: 12.5px; font-weight: 850; }
.mdoc-bar .v { color: var(--muted); font-weight: 750; }
.mdoc-bar .sp { flex: 1; }
.mdoc-bar .act { min-height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--text); font-size: 11.5px; font-weight: 800; }
.mdoc-bar .act.solid { background: var(--ink); background: light-dark(var(--ink), var(--acid)); color: #fff; color: light-dark(#fff, #162019); border-color: transparent; }
.mdoc-body { padding: var(--space-3); font-family: var(--serif); font-size: 14.5px; line-height: 1.65; }
.mdoc-body p { margin: 0 0 11px; white-space: pre-wrap; }
.mdoc-body p:last-child { margin: 0; }
.mdoc-body .addr { color: var(--muted); font-size: 12.5px; font-family: var(--sans); }
.mdoc-body h4 { margin: 14px 0 6px; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); font-family: var(--sans); }
.mdoc-body h4:first-child { margin-top: 0; }
.mdoc-body ul, .mdoc-body ol { margin: 0 0 11px; padding-left: 20px; font-family: var(--sans); font-size: 14px; }
.mdoc-body .record { padding: 12px 0; border-top: 1px solid var(--line); font-family: var(--sans); }
.mdoc-body .record:first-of-type { border-top: 0; padding-top: 0; }
.mdoc-body .record h5 { margin: 0 0 4px; font-size: 13.5px; font-weight: 800; }
.mdoc-body .record p { margin: 0 0 4px; font-size: 13px; color: var(--muted); white-space: normal; }
.mdoc-body video { display: block; width: 100%; max-width: 480px; border-radius: 10px; margin: 0 0 8px; background: #0f150c; }
.run-status { margin: 0 0 16px; padding: 12px 16px; border: 1px dashed var(--line); border-radius: 12px; color: var(--muted); font-size: 13.5px; font-family: var(--sans); }

/* ---- the artifact panel itself (T-LU-286, §4.3) ---- */
.artifact-panel { flex: 1 1 auto; min-width: 0; height: 100%; overflow-y: auto; border-left: 1px solid var(--line); background: var(--paper); }
.panel-head { display: flex; align-items: center; gap: 10px; position: sticky; top: 0; z-index: 2; padding: 14px 28px; background: var(--paper); border-bottom: 1px solid var(--line); }
.panel-title { font-weight: 870; letter-spacing: -.03em; font-size: 15px; }
.panel-head .sp { flex: 1; }
.panel-close { display: none; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--text); font-size: 12.5px; font-weight: 800; padding: 8px 14px; }
/* Generous width, own scroll, no nested card chrome — the document reads as
   the page of this column, not a box floating inside a bigger one (§4.3
   item 4). `.mdoc` keeps its radius/background everywhere else it might
   ever appear, but inside the panel it is the panel's own content. */
.artifact-panel .doc-section { max-width: 84ch; margin: 0 auto; padding: 24px 28px 8px; }
.artifact-panel .doc-section .mdoc { background: transparent; border-radius: 0; }
.artifact-panel .doc-section .mdoc-bar { padding: 0 0 12px; }
.artifact-panel .doc-section .mdoc-body { padding: 0; font-size: 15.5px; }
.artifact-panel .panel-body .seam { max-width: 84ch; margin: 18px auto 0; padding: 0 28px; }
.artifact-panel .vtabs { padding-left: 0; }

/* The rail's own toggle into the panel, on mobile only (hidden on desktop
   because the panel already sits beside the rail — see the 860px block). */
.panel-toggle { display: none; border: 1px solid var(--line); border-radius: 999px; background: var(--well); color: var(--text); font-size: 12px; font-weight: 800; padding: 7px 13px; white-space: nowrap; }

@media (max-width: 860px) {
  .scrollarea:has(.reading) { overflow-y: auto; }
  .reading { display: block; height: auto; }
  .thread-rail { max-width: none; height: auto; overflow-y: visible; padding: 0 14px 30px; }
  .reading:not(:has(.artifact-panel)) .thread-rail { padding: 0 14px 30px; }
  /* Full-screen sheet: off-canvas by default, slid in over the thread once
     `.reading` carries `.panel-open` — same fixed+transform shape the
     sidebar drawer already uses for its own off-canvas pattern. */
  .artifact-panel {
    position: fixed;
    inset: 0;
    z-index: 17;
    height: 100vh;
    width: 100%;
    max-width: none;
    border-left: 0;
    transform: translateX(100%);
    transition: transform .16s ease;
  }
  .reading.panel-open .artifact-panel { transform: translateX(0); }
  .reading:has(.artifact-panel) .panel-toggle { display: inline-flex; }
  .panel-close { display: inline-flex; }
  .reading.panel-open .doc-scrim { display: block; position: fixed; inset: 0; background: rgba(10, 14, 10, .4); z-index: 16; }
  /* The hamburger (z-index 20) would otherwise sit on top of the document
     sheet (z-index 17) and cover the panel's own title. It opens the
     sidebar, which has no business floating over a document that has
     already taken the whole screen, so it is hidden outright while the
     sheet is open rather than re-stacked under it. */
  /* menu-toggle is a sibling of .shell in the markup, not a descendant of
     it (app.html), so the :has() guard has to reach from their common
     ancestor. */
  body:has(.reading.panel-open) .menu-toggle { display: none; }
  .artifact-panel .doc-section, .artifact-panel .panel-body .seam { padding-left: 16px; padding-right: 16px; }
}

.actionbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.actionbar .lbl { flex: 1; min-width: 100px; color: var(--muted); font-size: 11.5px; font-weight: 850; letter-spacing: .06em; text-transform: uppercase; margin-right: 2px; }
.mbtn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 17px; border: 1px solid transparent; border-radius: 11px; background: var(--ink); background: light-dark(var(--ink), var(--acid)); color: #fff; color: light-dark(#fff, #162019); font-size: 14px; font-weight: 850; letter-spacing: -.01em; text-decoration: none; }
.mbtn:hover { background: var(--green); background: light-dark(var(--green), #eaffa0); }
.mbtn:disabled { cursor: not-allowed; border-color: var(--line); background: transparent; color: var(--muted); }
.mbtn.is-busy { opacity: .7; cursor: progress; }
.mbtn.ghost { background: transparent; border-color: var(--line); color: var(--text); font-weight: 800; }
.mbtn.ghost:hover { border-color: var(--text); background: transparent; }
.actionbar .mnote { flex-basis: 100%; margin-top: 2px; color: var(--muted); font-size: 12px; font-weight: 700; }
.actionbar .ask-form { display: none; flex-basis: 100%; gap: 10px; margin-top: 4px; }
.actionbar .ask-form.active { display: flex; flex-wrap: wrap; }
.actionbar .ask-form textarea { flex: 1 1 260px; min-height: 60px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--text); font-size: 13.5px; resize: vertical; }

/* ---- guided intake, the "Kind Form" stepper: progress + answered turns
   stay in the scrolling thread; the ACTIVE question lives in the composer
   below (.composer .stepper-body), the one bottom bar every state shares. ---- */
/* T-336 — dock the stepper block just above the composer while the thread
   is short: an empty first flex child absorbs the slack, so progress + done
   answers sit directly over the active question instead of leaving a void.
   Once content is tall enough to scroll it collapses to zero (min-height).
   The active question is NOT moved — it stays in .composer .stepper-body. */
.scrollarea:has(.stepper)::before { content: ""; flex: 1 0 0; min-height: 0; }
.stepper { margin: 10px 0 0; }
.stepper-head { display: flex; align-items: center; gap: 12px; padding: 0 0 10px; border-bottom: 1px solid var(--line); }
.stepcount { font-size: 11.5px; font-weight: 900; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.stepbar { flex: 1; height: 6px; border-radius: 99px; background: var(--well); overflow: hidden; }
.stepbar i { display: block; height: 100%; border-radius: inherit; background: var(--acid); transition: width .16s ease; }
.stepdone { margin: 0; padding: 12px 0 0; list-style: none; display: grid; gap: 6px; }
.stepdone li { display: flex; gap: 8px; align-items: baseline; color: var(--muted); font-size: 12.5px; }
.stepdone li::before { content: "✓"; color: var(--green-ink); font-weight: 900; flex: none; }
.stepdone li b { color: var(--text); font-weight: 750; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stepdone li .edit { margin-left: auto; color: var(--green-ink); font-weight: 800; font-size: 11.5px; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; border: 0; background: none; padding: 0; }
.stepper-body { display: grid; gap: 12px; }
.stepq { margin: 0; font-size: 16.5px; font-weight: 850; letter-spacing: -.03em; line-height: 1.3; }
.stepq .optional { font-weight: 650; color: var(--muted); font-size: 13.5px; }
.stephint { margin: -4px 0 0; color: var(--muted); font-size: 12.5px; }
.stepper-body textarea, .stepper-body input[type="text"], .stepper-body input[type="url"] { width: 100%; padding: var(--space-2); border: 1px solid var(--line); border-radius: 10px; background: var(--paper); color: var(--text); font-size: 15px; resize: vertical; }
.stepper-body textarea { max-height: 160px; }
.stepper-body textarea:focus, .stepper-body input:focus { border-color: var(--text); }
.step-counter { justify-self: end; color: var(--muted); font-size: 11.5px; font-weight: 700; }
.step-counter.short { color: var(--rust); }
.choices { display: flex; flex-wrap: wrap; gap: 7px; }
.choice { min-height: 40px; padding: 0 14px; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--text); font-size: 13.5px; font-weight: 750; }
.choice:hover { border-color: var(--text); }
.choice.on { border-color: transparent; background: var(--acid); color: #162019; font-weight: 850; }
.step-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.step-actions .mnote { flex: 1; min-width: 160px; margin: 0; }
.step-skip { order: 1; border: 1px solid var(--line); border-radius: 10px; background: transparent; color: var(--muted); font-size: 12.5px; font-weight: 800; padding: 0 13px; min-height: 40px; }
.step-skip:hover { border-color: var(--text); color: var(--text); }
.step-actions .mbtn { order: 2; }
.step-error { flex-basis: 100%; min-height: 0; color: var(--rust); font-size: 13px; font-weight: 700; }
.step-error:empty { display: none; }

/* T-LU-285 — the honest wait state. .gen-wait-note is the plain, static
   sentence a buffered (safety-gated) job shows: no bar, no motion, nothing
   implying visible progress the page cannot actually see. .gen-live replaces
   it for a streaming-eligible job with the model's own raw text arriving in
   real time — genuine progress, not a simulated one — appended via
   document.createTextNode only (public/app.js's XSS invariant). */
.gen-wait { flex-basis: 100%; margin-top: 4px; }
.gen-wait-note { margin: 0; color: var(--muted); font-size: 13px; font-weight: 700; }
.gen-live {
  margin: 0; max-height: 260px; overflow-y: auto; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--card);
  color: var(--text); font: 13px/1.6 var(--mono, ui-monospace, "SF Mono", Menlo, monospace);
  white-space: pre-wrap; word-break: break-word;
}

/* T-LU-287 — the mount point for Stripe's own Embedded Checkout iframe. No
   border/background of its own competing with Stripe's own chrome inside the
   iframe; flex-basis: 100% matches every other full-width stepper child
   (.step-error, .gen-wait) so it sits on its own row rather than squeezed
   beside the tier picker. */
.embedded-checkout { flex-basis: 100%; min-height: 420px; }

/* Photo intake inside the stepper */
.photo-field input[type="file"] { width: 100%; padding: 12px; border: 1px dashed var(--line); border-radius: 11px; background: var(--paper); color: var(--muted); font-size: 13.5px; }
.photo-field input[type="file"]::file-selector-button { margin-right: 12px; min-height: 34px; padding: 0 13px; border: 1px solid var(--ink); border-radius: 9px; background: var(--acid); color: #162019; font-size: 12.5px; font-weight: 800; }
.photo-list { display: grid; gap: 6px; margin: 8px 0 0; padding: 0; list-style: none; }
.photo-list li { display: flex; align-items: center; gap: 10px; padding: 8px 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); font-size: 13px; }
.photo-list .photo-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.photo-list .photo-size { color: var(--muted); font-size: 11.5px; }
.photo-list .photo-remove { border: 1px solid var(--line); border-radius: 8px; background: none; color: var(--muted); font-size: 11px; font-weight: 800; padding: 4px 9px; }

/* Consent, its own quiet step at the end */
.consent-row { display: flex; align-items: flex-start; gap: 11px; min-height: 44px; padding: 4px 2px; border-radius: 9px; cursor: pointer; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.consent-row input { flex: none; width: 19px; height: 19px; margin: 2px 0 0; accent-color: var(--ink); }

/* Opening turn: what this module is + price, before the first question */
.opening-note { margin: 0 0 4px; padding: var(--space-3); border-radius: 11px; background: var(--well); font-size: 13.5px; line-height: 1.5; }
.opening-note .price { font-weight: 850; color: var(--green-ink); display: block; margin-bottom: 3px; }
/* One honest fact about the moment, folded under the price — not a boxed
   warning of its own. Same treatment whether the cause is a missing local
   model key or a genuine outage: the buyer sees one sentence, not a defect. */
.opening-note .notice { margin: 6px 0 0; color: var(--orange-ink); font-weight: 700; }

/* T-332 — talk-first /app empty state.
   Same shell as .picker above (.picker-head + .mod-grid reuse), but the
   body of the page is the opening-note, an EmptyHandhold row of chip
   examples, a free-text StartComposer (textarea + submit), and a results
   area that IntentSuggest populates with .mod-card instances. The Browse-
   all link is the only escape to the full gallery — kept as a quiet line,
   not a button, so it never competes with the composer for the buyer's
   first press. */
.intent-empty .opening-note { margin: 12px 0 var(--space-3); }
.intent-empty .opening-note .price { font-size: 16px; }

.empty-handhold { margin: 0 0 var(--space-3); }
.empty-handhold-label {
  margin: 0 0 var(--space-2);
  color: var(--muted);
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.empty-handhold .choices { gap: 8px; }
.empty-handhold .choice { font-size: 14px; }

.start-composer { display: grid; gap: var(--space-2); margin: 0 0 var(--space-3); }
.start-composer textarea {
  width: 100%;
  min-height: 86px;
  padding: var(--space-2);
  border: 2px solid var(--ink);
  border-color: light-dark(var(--ink), rgba(243, 240, 230, .32));
  border-radius: 14px;
  background: var(--card);
  color: var(--text);
  font-size: 15.5px;
  line-height: 1.5;
  resize: vertical;
}
.start-composer textarea:focus-visible { outline: 3px solid var(--text); outline-offset: 2px; }
.composer-actions { display: flex; justify-content: flex-end; gap: 10px; }
.composer-error { margin: 0; color: var(--rust); font-size: 13px; font-weight: 700; min-height: 0; }
.composer-error:empty { display: none; }

.intent-results { margin: var(--space-3) 0 0; padding-top: var(--space-3); border-top: 1px solid var(--line); }
.intent-results .results-heading {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 870;
  letter-spacing: -.02em;
}
.intent-results .results-note { margin: 0 0 12px; color: var(--muted); font-size: 13px; line-height: 1.55; }
.intent-results .mod-grid { gap: 12px; }

.intent-browse { margin: 6px 0 0; color: var(--muted); font-size: 13px; }
.intent-browse-link { color: var(--green-ink); font-weight: 800; text-decoration: underline; text-underline-offset: 3px; }
.intent-browse-link:hover { color: var(--text); }

/* Mobile: same composer width as the picker, no extra gutter. */
@media (max-width: 640px) {
  .start-composer textarea { font-size: 16px; }
}

/* ---------------------------------------------------------------------------
   The writer picker, on the last step above the consent.

   Every option is styled IDENTICALLY apart from the selected outline. No rung
   is highlighted, badged "best value", tinted, enlarged or ordered by anything
   but price — the moment one of them looks like the intended answer the
   control stops being a choice and becomes a nudge. The only emphasis is the
   "Included" pill on the cheapest option, which points DOWN the ladder. */
.tier-pick { margin: 0 0 18px; }
.tier-heading { margin: 0; font-size: 17px; font-weight: 900; letter-spacing: -.02em; }
.tier-lede { margin: 6px 0 0; color: var(--muted); font-size: 13px; line-height: 1.55; max-width: 54ch; }
.tier-options { display: grid; gap: 9px; margin: 14px 0 0; }
.tier-option {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  gap: 12px;
  align-items: start;
  min-height: 44px;
  padding: 13px 15px;
  border: 1.5px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  cursor: pointer;
}
.tier-option:hover { background: var(--well); }
.tier-option.is-selected { border-color: var(--text); }
.tier-option input { flex: none; width: 19px; height: 19px; margin: 2px 0 0; accent-color: var(--ink); accent-color: light-dark(var(--ink), var(--acid)); }
.tier-text { display: grid; gap: 4px; }
.tier-name { font-size: 14.5px; font-weight: 900; letter-spacing: -.015em; }
.tier-included {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--acid) 45%, transparent);
  color: var(--green-ink);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .07em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.tier-desc { color: var(--muted); font-size: 12.5px; line-height: 1.5; max-width: 44ch; }
/* Both figures, as a right-aligned pair. The cap is quieter than the typical
   price but never hidden: it is on screen before any click. */
.tier-price { text-align: right; font-size: 12.5px; font-weight: 850; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tier-cap { display: block; margin-top: 3px; color: var(--muted); font-weight: 700; font-size: 11px; }
.tier-note {
  margin: 13px 0 0;
  padding: 11px 14px;
  border-left: 4px solid var(--acid);
  border-radius: 10px;
  background: var(--well);
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.6;
  max-width: 60ch;
}

/* ---------------------------------------------------------------------------
   The second take, directly under the delivered document.

   The visual hierarchy IS the ethics here. .is-keep carries the solid button
   and every paid row carries a ghost one, so the free option is the loudest
   thing in the strip. Nothing is coloured to draw the eye downward, no paid row
   is larger, and the whole block is quieter than the document above it — this
   is an offer, not the point of the page. */
.retake { margin: 14px 0 0; border: 1px solid var(--line); border-radius: 16px; background: var(--card); overflow: hidden; }
.retake-head { padding: 16px 20px 2px; }
.retake-head h4 { margin: 0; font-size: 16px; font-weight: 900; letter-spacing: -.02em; }
.retake-head p { margin: 6px 0 0; color: var(--muted); font-size: 13px; line-height: 1.55; max-width: 60ch; }
.retake-list { list-style: none; margin: 12px 0 0; padding: 0; }
.retake-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 14px 20px;
  border-top: 1px solid var(--line);
}
.retake-name { font-size: 14px; font-weight: 850; }
.retake-desc { margin: 3px 0 0; color: var(--muted); font-size: 12.5px; line-height: 1.5; max-width: 52ch; }
/* Both figures, on the row, before the click. */
.retake-price { margin: 4px 0 0; color: var(--muted); font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.retake-foot { padding: 13px 20px 16px; border-top: 1px dashed var(--line); color: var(--muted); font-size: 12.5px; line-height: 1.6; }
.retake-row .mbtn { white-space: nowrap; }

@media (max-width: 640px) {
  .scrollarea { padding-left: 14px; padding-right: 14px; padding-bottom: 30px; }
  .composer { padding: 5px 14px; }
  /* The row label is the only thing forcing the composer to two lines at
     this width — the price and the action are both already on the button. */
  .actionbar .lbl { display: none; }
  .mdoc-body { padding: var(--space-3); }
  .picker { margin-top: 24px; }
  /* The price moves under the description rather than squeezing the name. */
  .tier-option { grid-template-columns: 20px 1fr; }
  .tier-price { grid-column: 2; text-align: left; margin-top: 5px; }
  .tier-cap { display: inline; margin: 0 0 0 8px; }
  /* The button drops under the text rather than crushing it to two words. */
  .retake-row { grid-template-columns: 1fr; }
  .retake-row .mbtn { justify-self: start; }
}

/* The link to the receipts, inside the de-pressure note. Underlined and in the
   body colour rather than styled as a button: it is a footnote offering the
   whole bill, not a third thing competing with the two prices above it. */
.tier-receipts { color: inherit; font-weight: 800; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }

/* T-331 — RightDrawer (N13). Slides from the right; opens over the existing
   artifact panel rather than moving it (the panel keeps its slot, the
   drawer rides on top). Tokens come from the existing palette; nothing
   new is declared here. */
.right-drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 100%);
  display: none;
  z-index: 30;
}
.right-drawer.is-open { display: block; }
.right-drawer-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 30%, transparent); }
.right-drawer-panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(420px, 100%);
  background: var(--paper);
  border-left: 1px solid var(--line);
  box-shadow: -8px 0 24px color-mix(in srgb, var(--ink) 12%, transparent);
  display: flex; flex-direction: column;
}
.right-drawer-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.right-drawer-tabs { display: flex; gap: 4px; flex: 1; }
.right-drawer-tab {
  border: 1px solid var(--line); background: transparent; color: var(--text);
  padding: 4px 10px; border-radius: 999px; font-size: 13px; font-weight: 750; cursor: pointer;
}
.right-drawer-tab.on { background: var(--acid); border-color: var(--ink); color: var(--ink); font-weight: 850; }
.right-drawer-close { border: 0; background: transparent; font-size: 22px; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 6px; }
.right-drawer-body { padding: 12px; overflow: auto; }
.right-drawer-section[hidden] { display: none; }
.right-drawer-section-head { font-size: 14px; font-weight: 850; margin: 0 0 8px; }
.right-drawer-empty { color: var(--muted); font-size: 13px; margin: 0; }
.right-drawer-answer-list, .right-drawer-artifact-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.right-drawer-answer { display: flex; flex-direction: column; gap: 2px; padding: var(--space-3); border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
.right-drawer-answer-q { font-size: 12px; color: var(--muted); font-weight: 700; }
.right-drawer-answer-a { font-size: 14px; color: var(--text); white-space: pre-wrap; }
.right-drawer-progress-step { margin: 0 0 4px; font-weight: 850; }
.right-drawer-progress-label { margin: 0; color: var(--muted); font-size: 13px; }
.right-drawer-artifact a { color: var(--text); font-weight: 750; text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 640px) {
  .right-drawer, .right-drawer-panel { width: 100%; }
}

/* Drawer handle inside the existing conversation bar — quiet, last in the
   row, underlined like the rename button so it reads as a footnote control
   rather than a third primary action. */
.convo-bar .drawer-handle { border: 0; background: none; padding: 3px 7px; margin: -3px -2px; border-radius: 7px; color: var(--muted); font-size: 12px; font-weight: 800; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.convo-bar .drawer-handle:hover { color: var(--text); background: var(--well); }

/* T-334 — LeftStartNav. A flat, ~5-item start menu that replaces the legacy
   "+ New chat" + empty-gate top of /app's left rail when the ui.startNav
   flag is on. Logged-in: 5 items (New · Occasions · Speeches · Messages ·
   All jobs). Logged-out: 2 items (All jobs · Sign in). History / projects /
   wallet / account stay as the lower sections — only the top slot is
   swapped, so the existing side-row chrome is reused to keep the family
   read consistent. Tokens come from the sidebar's own palette — no new
   colour declarations. */
.sidebar-start-nav { padding: 4px 14px; }
.start-nav-list { display: grid; gap: 2px; margin: 2px 0 6px; }
.start-nav-item {
  font-weight: 800;
  font-size: 14px;
  letter-spacing: -0.01em;
}
.start-nav-item:hover { background: var(--sidebar-fill-strong); }
.start-nav-item:focus-visible { outline-color: var(--sidebar-ink); }
