/* ============================================================
   Job Application HQ — KofiAi design system
   Dark charcoal + lime. Space Grotesk headings, Instrument Sans body.
   Every UI agent codes against THESE class names — do not rename.
   ============================================================ */

:root {
  /* dark shell */
  --bg-top: #101216;
  --bg-bottom: #0b0d10;
  --text: #f2f4ee;
  --muted: #8b93a1;
  --muted2: #9aa1ad;
  --faint: #5d646f;
  --surface: #191c22;
  --surface2: #22262e;
  --border: #262a32;
  --border2: #2a2e37;
  /* accent */
  --lime: #c9f24b;
  --lime-ink: #101216;
  --lime-dark: #1a2005;
  /* cream cards (tables / light panels) */
  --cream: #fbfcf8;
  --cream-ink: #14161a;
  --cream-muted: #8a9099;
  --cream-faint: #a5aab2;
  --cream-border: #eceee6;
  --cream-row-border: #f1f3ec;
  --cream-hover: #f4f6ef;
  /* status colors (bg / text / border) */
  --st-saved-bg: #f1f3ec;    --st-saved-fg: #5d646f;    --st-saved-bd: #e2e5dc;
  --st-outreach-bg: #fdf3d7; --st-outreach-fg: #8a6410; --st-outreach-bd: #f3e3ab;
  --st-applied-bg: #eef6d8;  --st-applied-fg: #4a6109;  --st-applied-bd: #d9ecab;
  --st-interview-bg: #c9f24b;--st-interview-fg: #1a2005;--st-interview-bd: #c9f24b;
  --st-offer-bg: #14161a;    --st-offer-fg: #c9f24b;    --st-offer-bd: #14161a;
  --st-rejected-bg: #fdeceb; --st-rejected-fg: #b3402f; --st-rejected-bd: #f6d5d0;
  --st-passed-bg: #ededee;   --st-passed-fg: #6b7075;   --st-passed-bd: #d9dadd;
  /* misc */
  --danger: #e5695a;
  --good: #679410;
  --radius: 14px;
  --font-head: 'Space Grotesk', sans-serif;
  --font-body: 'Instrument Sans', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Saved career-platform evidence: quiet metadata, not another application action. */
.career-platform-tag { display: inline-block; max-width: 100%; margin-top: 5px; padding: 1px 7px; border: 1px solid var(--st-saved-bd); border-radius: 999px; background: var(--st-saved-bg); color: var(--st-saved-fg); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }
.career-platform-tools { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 12px 20px; min-width: 0; }
.career-platform-filter { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 12.5px; color: var(--muted2); min-width: 0; }
.career-platform-filter select { max-width: 100%; min-width: 0; padding: 7px 12px; border: 1px solid var(--border2); border-radius: 10px; background: var(--surface); color: var(--text); font: inherit; }
.career-platform-summary { flex: 1; min-width: 0; padding: 7px 0; font-size: 12.5px; color: var(--muted2); }
.career-platform-summary summary { cursor: pointer; width: fit-content; }
.career-platform-summary p { max-width: 65ch; margin: 10px 0; }
.career-platform-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); gap: 5px 14px; }
.career-platform-counts button { display: flex; justify-content: space-between; gap: 12px; min-width: 0; text-align: left; border: 1px solid var(--border); border-radius: 999px; padding: 6px 10px; font: inherit; background: var(--surface); color: var(--text); cursor: pointer; }
.career-platform-counts button span { overflow-wrap: anywhere; }
.career-platform-counts strong { font-variant-numeric: tabular-nums; }
.career-platform-counts button:hover, .career-platform-counts button[aria-pressed="true"] { border-color: var(--muted2); background: var(--surface2); }
.career-platform-tools :is(select,button,summary):focus-visible { outline: 2px solid var(--lime); outline-offset: 3px; }
@media (max-width: 600px) { .career-platform-filter, .career-platform-summary { width: 100%; flex-basis: 100%; } .career-platform-filter select { flex: 1; width: 100%; } }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  min-height: 100vh;
  background: linear-gradient(180deg, var(--bg-top) 0%, var(--bg-bottom) 100%) fixed;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--lime); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { font-family: var(--font-head); letter-spacing: -0.02em; margin: 0; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--faint); }

/* ---------- App shell ---------- */
.app-shell { max-width: 1360px; margin: 0 auto; padding: 28px 32px 48px; display: flex; flex-direction: column; gap: 24px; }
.topnav { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); cursor: pointer; }
.brand-logo { width: 34px; height: 34px; border-radius: 10px; background: var(--lime); display: grid; place-items: center; color: var(--lime-ink); font-family: var(--font-head); font-weight: 700; font-size: 17px; }
.brand-name { font-family: var(--font-head); font-weight: 600; font-size: 18px; letter-spacing: -0.01em; }
.nav-pills { display: flex; gap: 4px; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 5px; }
.nav-pill { padding: 9px 20px; border-radius: 999px; color: var(--muted2); font-size: 13.5px; background: none; border: none; cursor: pointer; font-family: var(--font-body); }
.nav-pill:hover { color: var(--text); }
.nav-pill.active { background: var(--lime); color: var(--lime-ink); font-weight: 600; }
/* The world switch lives inside the nav pill bar, but it is not a tab: a hairline separates
   "which Kofi am I in" from "which screen of it". Without it the bar reads as four peer tabs
   and the mode is indistinguishable from a page (live look, 2026-09-18). */
.mode-pill { font-weight: 600; white-space: nowrap; }
.mode-sep { width: 1px; align-self: stretch; margin: 4px 6px; background: var(--border); }
.avatar { width: 36px; height: 36px; border-radius: 999px; background: var(--surface2); display: grid; place-items: center; font-family: var(--font-head); font-weight: 600; font-size: 13px; color: var(--lime); }

.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.page-title { font-family: var(--font-head); font-size: 38px; font-weight: 600; letter-spacing: -0.03em; line-height: 1; }
.page-sub { margin-top: 10px; color: var(--muted); font-size: 15px; }

/* ---------- Cards ---------- */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; }
.cream-card { background: var(--cream); border-radius: 26px; padding: 10px 24px 18px; color: var(--cream-ink); }
.card h3, .cream-card h3 { font-size: 15px; margin-bottom: 4px; }
.card .hint { color: var(--faint); font-size: 12px; margin: 0 0 12px; }
.cream-card .hint { color: var(--cream-muted); font-size: 12px; margin: 0 0 12px; }

/* ---------- Buttons ---------- */
.btn { display: inline-flex; align-items: center; gap: 7px; background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: 9px 16px; border-radius: 999px; cursor: pointer; font-size: 13px; font-weight: 600; font-family: var(--font-body); }
.btn:hover { border-color: var(--border2); background: var(--surface2); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); }
.btn-primary:hover { filter: brightness(1.05); background: var(--lime); }
.btn-danger { color: var(--danger); }
.btn-sm { padding: 5px 11px; font-size: 11.5px; }
.discover-card { transition: border-color .12s, background .12s; }
.discover-card:hover { border-color: var(--lime); }
.discover-title:hover { text-decoration: underline !important; }
/* on cream cards */
.cream-card .btn { background: #fff; border-color: var(--cream-border); color: var(--cream-ink); }
.cream-card .btn:hover { background: var(--cream-hover); }
.cream-card .btn-primary { background: var(--lime-ink); border-color: var(--lime-ink); color: var(--lime); }

/* ---------- Inputs ---------- */
.input, .textarea, .select {
  background: var(--bg-bottom); border: 1px solid var(--border); color: var(--text);
  padding: 9px 12px; border-radius: 10px; font-size: 13.5px; font-family: var(--font-body);
  outline: none; width: 100%;
}
.input:focus, .textarea:focus, .select:focus { border-color: var(--lime); }
.textarea { resize: vertical; min-height: 70px; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
.search-pill { display: flex; align-items: center; gap: 10px; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 6px 18px; width: 300px; }
.search-pill input { flex: 1; background: transparent; border: none; outline: none; color: var(--text); font-size: 14px; font-family: var(--font-body); padding: 6px 0; }
.search-pill .glyph { color: var(--faint); font-size: 14px; }

/* ---------- Filter pills ---------- */
.filter-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* The Needs-me LENS sits apart from the journey chips and combines with them. */
.needs-toggle { margin-left: auto; border-style: dashed; }
.needs-toggle.active { border-style: solid; }
/* The status report: big narrative sections (To do / Waiting on them / Closed) with the
   verb / waiting-reason sub-headers nested inside. */
.section-head { font-family: var(--font-head); font-size: 15px; font-weight: 700;
  color: var(--cream-ink); padding: 18px 2px 8px; border-bottom: 2px solid var(--cream-ink); }
.section-head:first-child { padding-top: 4px; }
.section-head .count { opacity: 0.55; margin-left: 6px; font-size: 13px; }
.group-head { font-family: var(--font-head); font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--cream-muted); padding: 14px 2px 6px; border-bottom: 1px solid var(--cream-border); }
.group-head .count { opacity: 0.7; margin-left: 4px; }
.filter-pill { border: 1px solid var(--border); background: var(--surface); color: var(--muted2); font-size: 13px; font-weight: 600; padding: 9px 18px; border-radius: 999px; cursor: pointer; font-family: var(--font-body); display: flex; align-items: center; gap: 8px; }
.filter-pill .count { font-family: var(--font-head); opacity: 0.75; }
.filter-pill.active { background: var(--lime); color: var(--lime-ink); border-color: var(--lime); }

/* ---------- Table (cream) ---------- */
.table-head { display: grid; gap: 14px; padding: 16px 14px 12px; border-bottom: 1px solid var(--cream-border); font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; color: var(--cream-muted); text-transform: uppercase; }
.table-row { display: grid; gap: 14px; align-items: center; padding: 13px 14px; border-bottom: 1px solid var(--cream-row-border); border-radius: 12px; }
.table-row > * { min-width: 0; } /* long values truncate instead of blowing the grid open */
.cell-dim { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table-row:hover { background: var(--cream-hover); }
.table-foot { padding: 16px 14px 6px; font-size: 12.5px; color: var(--cream-muted); }
.cell-main { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell-sub { font-size: 12px; color: var(--cream-muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell-dim { font-size: 12.5px; color: var(--faint); }

/* ---------- Status pill + chips ---------- */
.status-pill { border: 1px solid; font-size: 11.5px; font-weight: 600; padding: 6px 13px; border-radius: 999px; cursor: pointer; font-family: var(--font-body); white-space: nowrap; }
.status-saved     { background: var(--st-saved-bg);     color: var(--st-saved-fg);     border-color: var(--st-saved-bd); }
.status-outreach  { background: var(--st-outreach-bg); color: var(--st-outreach-fg); border-color: var(--st-outreach-bd); }
.status-applied   { background: var(--st-applied-bg);   color: var(--st-applied-fg);   border-color: var(--st-applied-bd); }
.status-interview { background: var(--st-interview-bg); color: var(--st-interview-fg); border-color: var(--st-interview-bd); }
.status-offer     { background: var(--st-offer-bg);     color: var(--st-offer-fg);     border-color: var(--st-offer-bd); }
.status-rejected  { background: var(--st-rejected-bg);  color: var(--st-rejected-fg);  border-color: var(--st-rejected-bd); }
.status-passed    { background: var(--st-passed-bg); color: var(--st-passed-fg); border-color: var(--st-passed-bd); } /* did not apply: closed, quiet, not red */
/* WO24: the reply-window countdown compressed into a pill (user, 2026-08-26: "just a small
   pill before 'Asked for a referral', stating 63h"). Amber like the outreach pill it sits
   beside; the last 12 hours borrow the rejected reds for urgency. Sentence in the tooltip. */
.timer-pill { border: 1px solid var(--st-outreach-bd); background: var(--st-outreach-bg); color: var(--st-outreach-fg); font-size: 11.5px; font-weight: 600; padding: 6px 10px; border-radius: 999px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.timer-pill.timer-hot { border-color: var(--st-rejected-bd); background: var(--st-rejected-bg); color: var(--st-rejected-fg); }

.chip { font-size: 11px; font-weight: 600; padding: 5px 10px; border-radius: 999px; white-space: nowrap; display: inline-block; }
.chip-on  { background: var(--st-applied-bg); color: var(--st-applied-fg); }
.chip-off { background: var(--st-saved-bg); color: var(--cream-faint); }
.chip-dark { background: var(--surface2); color: var(--muted2); border: 1px solid var(--border); }

.initials { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; font-family: var(--font-head); font-weight: 600; font-size: 14px; flex-shrink: 0; }

.match-score { font-family: var(--font-head); font-weight: 600; font-size: 14px; }
.match-high { color: var(--good); }
.match-low { color: var(--cream-muted); }

/* ---------- Stat tiles ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
.stat-tile { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 15px 16px; }
.stat-k { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
.stat-v { font-family: var(--font-head); font-size: 28px; font-weight: 600; margin-top: 6px; line-height: 1; }
.stat-v.lime { color: var(--lime); }
.stat-sub { font-size: 11px; color: var(--faint); margin-top: 5px; }

/* ---------- Modal ---------- */
.modal-overlay { position: fixed; inset: 0; background: rgba(6, 8, 12, 0.74); backdrop-filter: blur(3px); display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; z-index: 50; overflow: auto; }
.modal { background: var(--surface); border: 1px solid var(--border2); border-radius: 18px; width: 100%; max-width: 640px; box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.modal-wide { max-width: 900px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; border-bottom: 1px solid var(--border); }
.modal-head h3 { font-size: 17px; }
.modal-body { padding: 22px; max-height: 68vh; overflow: auto; display: flex; flex-direction: column; gap: 14px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 22px; border-top: 1px solid var(--border); }
.modal-close { background: none; border: none; color: var(--muted); font-size: 22px; cursor: pointer; line-height: 1; }

/* ---------- Review workspace (docs + refine chat) ---------- */
.modal-full { max-width: 1280px; }
/* grid-template-rows minmax(0,1fr) + overflow hidden: without them an auto row grows
   with long chats past max-height and the content paints over the modal footer. */
.workspace { display: grid; grid-template-columns: 1fr 320px; grid-template-rows: minmax(0, 1fr); height: 74vh; min-height: 60vh; overflow: hidden; }
/* Expanded chat: conversation gets the bigger share, documents stay alongside. */
.workspace.chat-wide { grid-template-columns: 1fr 1.35fr; }
.workspace.chat-wide .bubble { font-size: 13.5px; line-height: 1.55; padding: 11px 15px; max-width: 78%; }
.workspace.chat-wide .chat-scroll { padding: 18px 22px 8px; gap: 12px; }
.workspace.chat-wide .chat-input { padding: 14px 22px 18px; }
.workspace.chat-wide .chat-input .textarea { min-height: 88px; font-size: 13.5px; }
.workspace-docs { padding: 20px 22px; overflow-y: auto; min-width: 0; }
.workspace-chat { border-left: 1px solid var(--border); display: flex; flex-direction: column; min-height: 0; }
.chat-head { padding: 14px 16px 10px; font-family: var(--font-head); font-weight: 600; font-size: 13.5px; border-bottom: 1px solid var(--border); }
.chat-scroll { flex: 1; overflow-y: auto; padding: 14px 14px 6px; display: flex; flex-direction: column; gap: 10px; }
.chat-input { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; border-top: 1px solid var(--border); }
.bubble { border-radius: 14px; padding: 9px 13px; font-size: 12.5px; line-height: 1.45; max-width: 92%; white-space: pre-wrap; }
.bubble-you { align-self: flex-end; background: var(--lime); color: var(--lime-ink); border-bottom-right-radius: 4px; }
.bubble-claude { align-self: flex-start; background: var(--surface2); color: var(--text); border: 1px solid var(--border); border-bottom-left-radius: 4px; }
.bubble-busy { color: var(--muted); font-style: italic; }
.doc-editor { width: 100%; min-height: 480px; background: var(--cream); color: var(--cream-ink); border: 1px solid var(--cream-border); border-radius: 12px; padding: 28px 32px; font-family: Georgia, "Times New Roman", serif; font-size: 14px; line-height: 1.65; resize: vertical; outline: none; }
@media (max-width: 1000px) { .workspace { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; } .workspace-chat { border-left: none; border-top: 1px solid var(--border); max-height: 300px; } }

/* ---------- Misc ---------- */
.empty { color: var(--faint); text-align: center; padding: 36px 20px; font-size: 13.5px; }
.banner { border: 1px solid var(--border); border-left: 3px solid var(--lime); background: var(--surface); border-radius: 12px; padding: 13px 16px; font-size: 13px; color: var(--muted2); } /* impeccable-disable-line side-tab -- the 3px accent edge is the system's signature flag (DESIGN.md Shapes) */
.banner.warn { border-left-color: var(--danger); }
.banner b { color: var(--text); }
.log-tail { background: var(--bg-bottom); border: 1px solid var(--border); border-radius: 10px; padding: 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--muted2); white-space: pre-wrap; max-height: 200px; overflow: auto; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-2 > * { min-width: 0; } /* stop wide children (resume preview) blowing out the page */
.row { display: flex; align-items: center; gap: 10px; }
.spacer { flex: 1; }
.tag { font-size: 10.5px; font-weight: 700; padding: 3px 10px; border-radius: 999px; letter-spacing: 0.04em; text-transform: uppercase; background: var(--surface2); color: var(--muted2); }
.tag.lime { background: var(--lime); color: var(--lime-ink); }
.tag.warn { background: var(--st-rejected-bg); color: var(--st-rejected-fg); }

@media (max-width: 900px) {
  .app-shell { padding: 18px 14px 40px; }
  .grid-2 { grid-template-columns: 1fr; }
  .page-title { font-size: 28px; }
}

/* ---------- Resume preview (Resume Studio) ---------- */
/* CMU Serif matches the compiled Jake's LaTeX PDF look. */
.resume-preview { font-family: "CMU Serif", Georgia, "Times New Roman", Times, serif; background: #fff; color: #000; overflow-x: auto; }
.resume-preview [class^="tpl-"] * { font-family: inherit; } /* one template, one typeface — on screen too */
.resume-caps { font-variant: small-caps; }
/* WO21: a value Kofi estimated with no evidence, still unreviewed — the same amber the
   status chips use on white. Preview-only: the mark clears when the value is edited or
   the documents are saved (accepted), and it never reaches the PDF or the .tex. */
.boost-est { background: var(--st-outreach-bg); color: inherit; border-bottom: 2px dotted var(--st-outreach-fg); border-radius: 4px; padding: 0 2px; cursor: help; }

@media print {
  body { background: #fff; overflow: visible; }
  body * { visibility: hidden; }
  .resume-preview, .resume-preview * { visibility: visible; }
  .resume-preview { position: absolute; inset: 0; width: 100%; max-width: none; min-height: auto; box-shadow: none; padding: 0.5in; }
  /* Direct Cmd+P with the review modal open: flatten the modal so the resume prints in normal flow. */
  .modal-overlay { position: static; padding: 0; background: #fff; backdrop-filter: none; overflow: visible; }
  .modal, .modal-full { max-width: none; border: none; box-shadow: none; background: #fff; }
  .workspace { display: block; max-height: none; }
  .workspace-docs { overflow: visible; padding: 0; }
  .workspace-chat, .modal-head, .modal-foot { display: none; }
}


/* ---------- 2.0 polish: overflow + small-screen hardening ---------- */
.cream-card { overflow-x: auto; } /* wide grid tables scroll inside the card, never break the page */
.cream-card .table-head, .cream-card .table-row { min-width: 860px; }
.card { min-width: 0; } /* grid children must be shrinkable or they blow out the layout */
.workspace-docs .card { overflow-x: auto; }
.filter-row { flex-wrap: wrap; row-gap: 8px; }
button, .btn { touch-action: manipulation; } /* no double-tap zoom on iPad */
@media (max-width: 760px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .grid-2 { grid-template-columns: 1fr; }
  .page-head { flex-wrap: wrap; gap: 10px; }
}

/* Grid cells must be shrinkable and clipped, else a wide cell (4 doc chips) paints
   over the next column — showed up as "Ref ✓" overlapping the match score. */
.table-row > *, .table-head > * { min-width: 0; overflow: hidden; }
.table-row .chip, .table-row .status-pill { flex: 0 0 auto; }

/* ---------- v2.9.0 UX pass ---------- */
/* Toasts: bottom-right, auto-dismiss. Success is quiet; errors carry the server's words. */
#kofi-toasts { position: fixed; right: 18px; bottom: 18px; z-index: 200; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.toast { background: var(--surface); border: 1px solid var(--border2); border-left: 3px solid var(--lime); color: var(--text); /* impeccable-disable-line side-tab -- accent edge, see DESIGN.md Shapes */
  border-radius: 10px; padding: 10px 14px; font-size: 13px; max-width: 340px; box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  animation: toast-in .18s ease-out; }
.toast-error { border-left-color: var(--danger); }
.toast-out { opacity: 0; transform: translateY(6px); transition: opacity .35s, transform .35s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Skeletons: the Review modal opens instantly and shows these while documents load. */
.skeleton { border-radius: 10px; background: linear-gradient(100deg, var(--border) 40%, var(--border2) 50%, var(--border) 60%);
  background-size: 200% 100%; animation: skeleton-sheen 1.2s linear infinite; }
@keyframes skeleton-sheen { from { background-position: 120% 0; } to { background-position: -80% 0; } }
/* Navbar activity badge: visible whenever any tailor is running. */
.run-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--lime);
  border: 1px solid var(--border2); border-radius: 999px; padding: 4px 11px; cursor: pointer; background: transparent; }
.run-badge .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--lime); animation: run-pulse 1.2s ease-in-out infinite; } /* impeccable-disable-line pulsing-dot -- only rendered while a tailor job is genuinely running */
@keyframes run-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* THE ON/OFF SWITCH. Lives in the navbar, on every page, because stopping and starting the
   writer is the most basic control there is and it used to be a checkbox buried in
   Diagnostics — the user asked twice for a button on the site. Reads its own state: lime
   when Kofi is writing, red when it is stopped. */
.power { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600;
  border: 1px solid var(--border2); border-radius: 999px; padding: 4px 11px 4px 8px; cursor: pointer;
  background: transparent; color: var(--faint); transition: color .12s, border-color .12s; }
.power:hover { border-color: var(--faint); }
.power[disabled] { cursor: progress; opacity: .6; }
.power .led { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.power.on { color: var(--lime); }
.power.off { color: var(--danger); }

/* Chart hover readout — the exact value, without the native title tooltip's ~1s delay and
   OS styling. CSS-only: no state, no re-render, no listener per bar (there are 21 + 24 of
   them). The bar keeps its own `title` off so the two don't stack. */
.bar-tip { position: relative; }
.bar-tip::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 7px;
    border-radius: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 11px;
    line-height: 1.3;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;          /* never eat the hover that summoned it */
    transition: opacity .09s ease;
    z-index: 20;
}
.bar-tip:hover::after, .bar-tip:focus-visible::after { opacity: 1; }
/* A 1-day bar is ~3px wide, so an edge tooltip would clip outside the card. These two pin
   the first/last few to their own edge instead of centring. */
.bar-tip:nth-child(-n+3)::after { left: 0; transform: none; }
.bar-tip:nth-last-child(-n+3)::after { left: auto; right: 0; transform: none; }

/* Ten-second undo toast: the house answer to "are you sure?" — it must be clickable, so it
   opts out of the toast host's pointer-events:none. */
.toast-undo { display: flex; align-items: center; gap: 10px; border-left-color: var(--cream); }
.toast-undo .btn { flex-shrink: 0; }

/* Today's hero: one sentence, big enough to read across the room, with its button attached. */
.hero-card { border-left: 3px solid var(--lime); padding: 20px 22px; } /* impeccable-disable-line side-tab -- accent edge, see DESIGN.md Shapes */
.hero-card.hero-danger { border-left-color: var(--danger); }
.hero-line { font-family: var(--font-head); font-size: 22px; font-weight: 600; line-height: 1.25; color: var(--text); }
.hero-sub { margin: 8px 0 14px; font-size: 14px; line-height: 1.55; color: var(--muted2); max-width: 62ch; }
.startup-lead { margin: 16px 0; }
.startup-envelope { max-width: 760px; margin: 14px 0; padding: 16px 17px; border: 1px solid var(--border2);
  border-radius: 14px; background: var(--surface); }
.startup-lead .startup-envelope { max-width: none; }
.startup-envelope-to { color: var(--muted); font-size: 12px; margin-bottom: 4px; }
.startup-envelope-reason { color: var(--muted2); font-size: 12.5px; margin-bottom: 10px; }
.startup-envelope-subject { color: var(--text); font-family: var(--font-head); font-size: 15px;
  font-weight: 600; letter-spacing: -.02em; margin-bottom: 9px; }
.startup-envelope pre, .startup-reply pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
  max-width: 78ch; font: inherit; color: var(--text); line-height: 1.55; }
.startup-envelope-foot { color: var(--muted); font-size: 12px; margin: 10px 0; }
.startup-envelope .btn { margin-top: 12px; }
.startup-reply { margin-top: 12px; padding: 12px 14px; border-radius: 12px;
  background: var(--surface2); border: 1px solid var(--border2); }
.startup-reply p { margin: 5px 0; color: var(--muted2); }
.startup-envelope-green { border-top: 4px solid var(--good); padding-top: 13px; }
.startup-experiment { margin: 14px 0 18px; padding: 18px 20px; border: 1px solid var(--cream-border);
  border-radius: 26px; background: var(--cream); color: var(--cream-ink); }
.startup-experiment-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; }
.startup-experiment h2 { margin: 0; font-family: var(--font-head); font-size: 18px; letter-spacing: -.02em; }
.startup-experiment p { margin: 5px 0 0; color: var(--cream-muted2); font-size: 12.5px; line-height: 1.45; }
.startup-experiment-result { flex: 0 0 auto; font-family: var(--font-head); font-size: 14px; font-weight: 600;
  color: var(--good); font-variant-numeric: tabular-nums; }
.startup-progress { height: 6px; margin: 14px 0; overflow: hidden; border-radius: 6px;
  background: var(--cream-surface2); }
.startup-progress span { display: block; height: 100%; border-radius: inherit; background: var(--good);
  transition: width .45s cubic-bezier(.16, 1, .3, 1); }
.startup-arm-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: 1px solid var(--cream-border); }
.startup-arm { min-width: 0; padding: 12px 12px 2px 0; }
.startup-arm b { display: block; font-size: 12px; }
.startup-arm span { display: block; margin-top: 3px; color: var(--cream-muted2); font-size: 11.5px;
  font-variant-numeric: tabular-nums; }
.startup-experiment .startup-experiment-note { margin-top: 12px; font-size: 11.5px; }
.startup-controls { flex-wrap: wrap; }
.startup-controls .btn { white-space: nowrap; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); text-decoration: underline; }
.btn-ghost:hover { color: var(--text); }
.app-footer { font-size: 11.5px; color: var(--faint); padding: 6px 2px 2px; }
@media (max-width: 640px) {
  .hero-line { font-size: 19px; }
  .hero-card { padding: 16px 15px; }
  .hero-card .btn, .hero-card .btn-primary { width: 100%; justify-content: center; }
  .hero-card .btn-ghost { width: auto; }
  .startup-envelope { padding: 14px; }
  .startup-experiment { padding: 16px 15px; }
  .startup-experiment-head { display: block; }
  .startup-experiment-result { margin-top: 8px; }
  .startup-arm-grid { grid-template-columns: 1fr 1fr; }
  .page-head .startup-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .startup-controls > * { min-width: 0; }
}

/* The Review path: three steps, where you are, how far back you can go. */
.step-rail { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.step-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--surface);
  border: 1px solid var(--border); color: var(--muted); border-radius: 999px;
  padding: 7px 15px 7px 8px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.step-pill:hover { color: var(--text); }
.step-pill.active { border-color: var(--lime); color: var(--text); }
.step-pill.done { color: var(--muted2); }
.step-n { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: 999px; background: var(--border); color: var(--muted2); font-size: 11px; }
.step-pill.active .step-n { background: var(--lime); color: var(--lime-ink); }
.step-pill.done .step-n { background: var(--lime-ink); color: var(--lime); }
.step-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 16px; }
.why-expander { margin-top: 18px; }
.why-expander > summary { color: var(--muted); }
.why-expander[open] > summary { color: var(--text); margin-bottom: 4px; }
.send-state { font-size: 12.5px; color: var(--muted); margin-top: 8px; }
.send-state-good { color: var(--lime); }
.send-state-bad { color: var(--danger); }
@media (max-width: 640px) {
  .step-rail { gap: 6px; }
  .step-pill { padding: 6px 11px 6px 6px; font-size: 11.5px; }
  .step-actions .btn, .step-actions .btn-primary { width: 100%; justify-content: center; }
}

/* The Applications list: a row is a company, a sentence, and one button. */
.group-head { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin: 0 2px 8px; }
.group-head .count { background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 1px 8px; margin-left: 7px; font-size: 11px; letter-spacing: 0; }
.app-row { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border-bottom: 1px solid var(--border); }
.app-row:last-child { border-bottom: none; }
.app-row-line { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
@media (max-width: 640px) {
  .app-row { flex-wrap: wrap; }
  .app-row > .row:last-child { width: 100%; justify-content: flex-start; }
  .app-row .btn-primary { flex: 1; justify-content: center; }
}

/* ---------- phones ----------------------------------------------------------------------
   The second click ("send the other 7") and the reply alerts moved server-side, so acting on
   them no longer needs a laptop. Everything on the two daily screens has to be comfortable at
   375px: the header wraps instead of scrolling sideways, and nothing overflows the viewport. */
@media (max-width: 640px) {
  .app-shell { padding: 12px 12px 40px; }
  .topnav { flex-wrap: wrap; gap: 10px; }
  .topnav .brand-name { display: none; }          /* the logo alone identifies it */
  .nav-pills { order: 3; width: 100%; justify-content: space-between; overflow-x: auto; }
  .nav-pill { padding: 7px 12px; font-size: 12.5px; white-space: nowrap; }
  .topnav > .row { margin-left: auto; }
  .avatar { display: none; }
  .page-head { flex-direction: column; align-items: stretch; }
  .page-title { font-size: 24px; }
  .search-pill { width: 100%; }
  .page-head .row { width: 100%; }
  .page-head .btn { flex: 1; justify-content: center; }
  .modal, .modal-full { width: 100%; max-width: 100%; border-radius: 0; }
  .toast, .toast-undo { max-width: calc(100vw - 24px); }
  #kofi-toasts { right: 12px; left: 12px; bottom: 12px; }
  /* Wide content scrolls inside its own box; the page body never scrolls sideways. */
  .resume-preview, .log-tail { overflow-x: auto; }
}
/* `clip`, not `hidden`: overflow-x:hidden on <body> makes it a scroll container, and a
   scroll container kills position:sticky for everything inside it — the sticky topnav
   below measured -4988px at scrollY 5000 until this changed. `clip` fences off the same
   sideways overflow without creating one. */
html, body { overflow-x: clip; }

@media (max-width: 640px) {
  /* The Review on a phone: the documents get the screen, the conversation is a strip at the
     bottom you can still reach. The step rail must stay put — it is how you get to the send. */
  .modal-full { height: 100vh; max-height: 100vh; }
  .modal-full .modal-head h3 { font-size: 14px; line-height: 1.3; }
  .workspace-chat { max-height: 190px; }
  .step-rail { position: sticky; top: 0; z-index: 2; background: var(--bg-bottom); box-shadow: 0 6px 10px var(--bg-bottom); padding: 8px 10px; margin: 0 -10px 12px; }
  .resume-preview { padding: 10px !important; }
}


/* ---------- WO19 design restore: the cream contrast layer -------------------------------
   The system is DARK SHELL + CREAM CONTENT CARDS (ApplicationsPage is the reference).
   The WO17/18 rebuilds styled Today, the Review's cards and the send panel with only the
   shell half of the palette — gray boxes on a gray page. This block restores the cream:
   `.cream-surface` (and every card inside the Review's document pane) re-maps the shell
   variables, so each component's own classes and inline styles pick cream-legible ink
   with no markup or copy changes. */
.cream-surface, .workspace-docs .card {
  --text: var(--cream-ink);
  --muted: var(--cream-muted);
  --muted2: #67707c;
  --faint: var(--cream-faint);
  --surface: #ffffff;
  --surface2: #eef0e9;
  --border: var(--cream-border);
  --border2: #e2e5dc;
  --bg-bottom: #ffffff;
  background: var(--cream);
  color: var(--cream-ink);
  border-color: var(--cream-border);
}
/* Primary action on cream — same treatment the Applications rows already wear. */
.cream-surface .btn-primary, .workspace-docs .card .btn-primary {
  background: var(--lime-ink); border-color: var(--lime-ink); color: var(--lime);
}
.cream-surface .btn-primary:hover, .workspace-docs .card .btn-primary:hover {
  background: #23262c; border-color: #23262c; filter: none;
}
.cream-surface .btn-ghost, .workspace-docs .card .btn-ghost {
  background: transparent; border-color: transparent;
}
/* Lime text is a dark-shell accent; on cream the system's green carries "good". */
.cream-surface .send-state-good, .workspace-docs .card .send-state-good { color: var(--good); }
/* The failed-job hero keeps its danger accent, the way the system does red on cream. */
.cream-surface.hero-danger { border-left-color: var(--danger); }
.cream-surface.hero-danger .hero-line { color: var(--st-rejected-fg); }
/* Nested cards (the Why-expander's sections, the send panel's sub-panels) sit WHITE on
   the cream, or the hierarchy disappears — their vars are already remapped above. */
.cream-surface .card, .workspace-docs .card .card { background: #fff; }
/* A bare link on cream is lime-on-white — invisible. On cream the system's green is the
   link colour; classed links (.btn, .chip-on, .tag) keep their own. */
.cream-surface a:not([class]), .workspace-docs .card a:not([class]) { color: var(--good); }


/* ---------- WO25: a 1,900-row list on a phone --------------------------------------------
   Live QA on the real dataset: the Applications page is ~250 screens tall, the nav scrolled
   away and never came back, and twelve filter chips wrapped onto five lines pushed the first
   job below the fold. Three fixes, all CSS. */

/* 1. The nav follows you down. Sticky, not fixed, so it keeps its slot in the shell's flex
   column and covers nothing at rest; the padding/margin pair cancel out at rest and only
   become breathing room once the bar is pinned to the viewport edge.
   z-index 30: above the list (auto), below the modal overlay (50) and below the
   position:fixed status/row menus (61) that must be able to open over it. Nothing here
   adds a transform or a filter to an ancestor of the list, so those menus keep measuring
   against the viewport. The background is the body's own gradient painted against the
   viewport (`fixed`), so the strip matches the page behind it at every scroll offset. */
.topnav {
  position: sticky;
  top: 0;
  z-index: 30;
  background: linear-gradient(180deg, var(--bg-top) 0%, var(--bg-bottom) 100%) fixed;
  padding: 10px 0;
  margin: -10px 0;
}

/* 2. Long lists: rows outside the viewport skip layout and paint. `auto` in
   contain-intrinsic-size makes each row remember its real height once it has been rendered,
   so the scrollbar settles instead of drifting for the rest of the session.
   The :not(:has(...)) is LOAD-BEARING, not decoration. content-visibility implies
   `contain: paint`, which makes the row (a) a containing block for the position:fixed
   StatusPill / RowMenu popups rendered inside it — measured: a fixed probe at top:100px
   landed at 491px — and (b) a stacking context, which would trap their z-index:61 under
   the sticky nav. The one row holding an OPEN menu opts out; the other 1,899 keep the
   saving. Browsers without :has() drop the rule and simply render as before. */
.app-row:not(:has([data-kofi="status.option"], [data-kofi^="menu.item."])) {
  content-visibility: auto;
  contain-intrinsic-size: auto 62px;   /* CONTENT box: a desktop row is 89px, less 26px padding and its 1px rule */
}

@media (max-width: 640px) {
  /* 3. The chips: one row that scrolls sideways instead of five stacked lines. No chip is
     removed and none moves, so it still reads right when the zero-count ones are hidden.
     The bleed puts the first/last chip against the screen edge, which is what tells you
     there is more to the right. `.needs-toggle`'s margin-left:auto keeps right-aligning it
     while the chips still fit, and collapses to 0 once they overflow. */
  .filter-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    margin-inline: -12px;            /* the shell's phone gutter */
    padding-inline: 12px;
    scroll-snap-type: x proximity;
  }
  .filter-row::-webkit-scrollbar { display: none; }   /* phones overlay it; this is 8px of screen */
  .filter-row .filter-pill { flex: 0 0 auto; scroll-snap-align: start; }
  /* Inside a dialog there is no screen gutter to bleed into, and two tabs were never the
     problem — the Import modal keeps wrapping. */
  .modal .filter-row { flex-wrap: wrap; overflow-x: visible; margin-inline: 0; padding-inline: 0; }

  /* The bar is now permanent, so its height is rent. Forcing the pills onto their own line
     spent 113px of an 812px screen on every screenful; letting them share line one with the
     logo costs 53px. Nothing is removed and nothing is reordered — the pill strip already
     scrolls sideways, and it keeps a 240px floor so the transient right-hand cluster
     ("3 being written", "Save failed — retry your edit", "no claude CLI") wraps to a second
     line instead of crushing the pills to 10px, which is what a plain nowrap row did. */
  .topnav { gap: 8px; padding: 6px 0; margin: -6px 0; }
  .nav-pills { order: 0; width: auto; flex: 1 1 240px; min-width: 240px; justify-content: flex-start; }
  .nav-pills::-webkit-scrollbar { display: none; }
  .topnav > .row { flex: 0 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; }

  /* Rows wrap their action bar onto a second line down here, so the placeholder is taller. */
  .app-row:not(:has([data-kofi="status.option"], [data-kofi^="menu.item."])) {
    contain-intrinsic-size: auto 117px;  /* content box; phone rows run 129-201px, this is the mean */
  }
}

/* KOFI'S NUMBERS banner. One line, above the chips: a statement of what is being held back
   and the single click that releases it. Styled as a notice rather than an alert — nothing
   is broken, there is just a decision waiting, and an alarm colour on a routine decision
   teaches people to ignore the colour. */
.notice-row {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 12px 16px; border-radius: var(--radius);
    background: var(--surface2);
    border: 1px solid var(--border2);
    color: var(--text);
    font-size: 14px; line-height: 1.45;
}
.notice-row > span { flex: 1 1 260px; min-width: 0; }
.notice-row .btn { flex: 0 0 auto; }

/* Posted age on a row. Quiet by default — it is context, not the headline — but a posting
   from the last week gets the accent, because that is the window where applying early
   still changes the outcome and it is the only reason the "Newest posted" lens exists. */
.posted-age { color: inherit; }
.posted-age.fresh { color: var(--good); font-weight: 600; }
.filter-pill.fresh-toggle { margin-left: auto; }
.filter-pill.fresh-toggle + .needs-toggle { margin-left: 0; }

/* The three shortlists. Each carries its own accent so the lists stay distinguishable at a
   glance, drawn from the existing status ramps rather than new colours: the top tier reads
   as the board's headline lime, the under-the-radar list as the "in progress" amber, and
   the middle as the applied green. */
.filter-pill.tier-elite.active    { background: var(--lime); color: var(--lime-ink); border-color: var(--lime); }
.filter-pill.tier-startup.active  { background: var(--st-outreach-bg); color: var(--st-outreach-fg); border-color: var(--st-outreach-bd); }
.filter-pill.tier-solid.active    { background: var(--st-applied-bg); color: var(--st-applied-fg); border-color: var(--st-applied-bd); }
.tier-why { color: var(--cream-faint); }
/* The second row is a different KIND of control from the stage chips above it, and it must
   look like one: a caption names it, the row sits closer, and an inactive shortlist pill is
   dashed and faint — an overlay you can switch on, not a place a job is. */
.filter-row.lens { margin-top: -6px; gap: 6px; align-items: center; }
.lens-caption { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--faint); margin-right: 4px; }
.filter-pill.tier-pill:not(.active) { border-style: dashed; color: var(--faint); }
.filter-pill.tier-pill:not(.active) .count { opacity: .7; }

/* The number flag on a row: information, not a task. */
.flag-note { opacity: .65; }
