/**
 * Mission Control — the design system.
 *
 * Every rule here exists because the Content-Security-Policy in `_headers` sets
 * `style-src 'self'` with no `unsafe-inline`. The design was handed over as a
 * mockup built entirely from inline `style=` attributes; none of them would have
 * rendered. So the design lives in classes, which is where it should have lived
 * anyway — the constraint and the good practice point the same way.
 *
 * Fonts are the same story. The handoff specifies Space Grotesk and JetBrains
 * Mono from Google Fonts, and `font-src 'self'` blocks that host outright. The
 * stacks below NAME those families first, so they bind for anyone who has them
 * installed and bind automatically the day the woff2 files are self-hosted, then
 * fall back to the closest system equivalents. Swapping in real files is a
 * one-token change and no rule below needs to move.
 */

:root {
  /* Surfaces — darkest to lightest. */
  --bg: #0e1116;
  --inset: #0d1015;
  --card: #161b22;
  --pill: #1c2430;
  --pop: #1c2430;

  /* Borders. */
  --line: #21262e;
  --control: #30363d;
  --line-blue: #1f6feb66;
  --line-amber: #d2992244;
  --line-red: #f8514966;
  --line-green: #238636;

  /* Text. */
  --fg: #e6edf3;
  --body: #c9d1d9;
  --muted: #8b949e;
  --bright: #fff;
  --dim: #494f58;

  /* Semantic. */
  --green: #3fb950;
  --green-bg: #23863633;
  --blue: #58a6ff;
  --blue-bg: #1f6feb33;
  --amber: #d29922;
  --amber-bg: #d2992222;
  --red: #f85149;
  --cta: #238636;
  --neutral-bg: #30363d;

  /* The overdue chart's categorical triple. Validated separately from the app
     tokens: the info blue sits too close to the muted grey to carry identity. */
  --c0: #d95926;
  --c1: #3987e5;
  --c2: #199e70;

  --font-ui: 'Space Grotesk', 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', 'Consolas', monospace;

  --r-card: 8px;
  --r-btn: 6px;
  --r-pill: 20px;
  --r-tag: 4px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--blue);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

/* A link the emitter refused to make clickable. Struck through so a dead
   destination reads as dead rather than as an ordinary link that does nothing. */
a.dead,
.dead {
  color: var(--muted);
  text-decoration: line-through;
}

code {
  font-family: var(--font-mono);
  font-size: .92em;
  background: var(--inset);
  border: 1px solid var(--line);
  border-radius: var(--r-tag);
  padding: 1px 5px;
}

/* Visually hidden, still announced. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- header */

.head {
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 14px 28px;
  border-bottom: 1px solid var(--line);
  /* In local mode the header also carries the command picker, the Run button
     and its writes/read-only caption. With no wrap those forced the row to
     557px inside a 430px viewport, squeezing the subtitle into a column two
     words wide and pushing the caption off screen entirely. */
  flex-wrap: wrap;
  row-gap: 10px;
}

.head h1 {
  margin: 0;
  font: 600 15px var(--font-mono);
  color: var(--bright);
  letter-spacing: -.01em;
}

.head .sub {
  margin: 0;
  font-size: 11.5px;
  color: var(--muted);
  max-width: 340px;
}

.headright {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  font: 400 11.5px var(--font-mono);
  color: var(--muted);
  /* Wraps within itself too, so the picker and the Run button stack rather than
     the whole cluster dropping to its own line as one unbreakable row. */
  flex-wrap: wrap;
  row-gap: 8px;
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  display: inline-block;
  flex: none;
}
.dot--amber { background: var(--amber); }
.dot--red { background: var(--red); }

/* ---------------------------------------------------------------- nav */

.rail {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  font-size: 13px;
}

.navitem {
  padding: 6px 12px;
  background: transparent;
  border: 0;
  border-radius: var(--r-btn);
  color: var(--muted);
  font: inherit;
  font-family: var(--font-ui);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.navitem:hover {
  color: var(--fg);
}

.navitem[aria-selected='true'] {
  background: var(--pill);
  color: var(--bright);
  font-weight: 500;
}

/* The count a surface announces about itself. Amber on Actions is the design's
   one deliberate exception: it is the only nav count that means "owed". */
.navitem__c {
  font: 500 11px var(--font-mono);
  color: var(--muted);
}
.navitem[data-view='actions'] .navitem__c {
  color: var(--amber);
}

/* Changed since the last visit. Never colour alone — it carries a title. */
.navitem__new {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--green);
  display: inline-block;
}

/* ---------------------------------------------------------------- capture bar */

.bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 28px;
  background: var(--inset);
  border-bottom: 1px solid var(--line);
}

.bar__icon {
  color: var(--blue);
  font-size: 13px;
  flex: none;
}

.bar textarea {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--fg);
  font: 13px var(--font-ui);
  resize: vertical;
  padding: 0;
}

.bar textarea::placeholder {
  color: var(--muted);
}

.bar textarea:focus {
  outline: none;
}

.bar textarea:disabled {
  color: var(--muted);
}

.kbd {
  font: 400 10.5px var(--font-mono);
  color: var(--muted);
  border: 1px solid var(--control);
  border-radius: var(--r-tag);
  padding: 2px 6px;
  flex: none;
}

.bar__row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.barchips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 0 28px 10px;
  background: var(--inset);
}

.barchips:empty {
  display: none;
}

.barchip {
  font-size: 12px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  color: var(--body);
}

.barchip--co { background: var(--blue-bg); color: var(--blue); }
.barchip--app { background: var(--blue-bg); color: var(--blue); }
.barchip--state { background: var(--green-bg); color: var(--green); }
.barchip--date { background: var(--amber-bg); color: var(--amber); }
.barchip--doc { background: var(--neutral-bg); color: var(--body); }

/* ---------------------------------------------------------------- stat tiles */

/* A 1px grid gap doing the work of borders: the gap colour IS the rule.
   The 120px floor is chosen so all five stat tiles stay on one row down to a
   half-screen laptop. At 150px they wrapped 4 + 1, and the three empty tracks
   in the second row showed the container's own background as a solid slab that
   read like a broken panel. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px;
  background: var(--line);
  border-bottom: 1px solid var(--line);
  /* The band ends in a rule, and whatever followed began immediately against it
     at a measured 0px, because headings carry margin-top: 0 and the next block
     carries no top margin either. 22px matches main's own padding-top, so the
     content clears the divider by the same amount it clears the nav. */
  margin-bottom: 22px;
}

.tile {
  background: var(--bg);
  padding: 16px 28px;
}

.tile__n {
  font: 600 24px var(--font-mono);
  color: var(--fg);
}
.tile__n--green { color: var(--green); }
.tile__n--amber { color: var(--amber); }
.tile__n--blue { color: var(--blue); }

.tile__l {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 2px;
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* ---------------------------------------------------------------- layout */

#main {
  padding: 22px 28px 40px;
}

.cols {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: 28px;
  align-items: start;
  /* Its internal gap does not separate it from what comes after it. On review a
     section began flush against it at 0px, the same defect as the tiles band.
     24px matches the bottom margin a section already carries. */
  margin-bottom: 24px;
}

@media (max-width: 900px) {
  .cols {
    grid-template-columns: 1fr;
  }
}

section {
  margin: 0 0 24px;
}

h2 {
  margin: 0 0 12px;
  font: 500 11px var(--font-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  align-items: baseline;
  gap: 8px;
}

h3 {
  margin: 18px 0 10px;
  font: 500 11px var(--font-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

h1.hub {
  margin: 0 0 6px;
  font: 600 22px var(--font-ui);
  color: var(--fg);
  text-transform: none;
  letter-spacing: 0;
}

.count {
  font: 500 11px var(--font-mono);
  color: var(--muted);
  letter-spacing: 0;
}

.crumb {
  font: 400 11.5px var(--font-mono);
  color: var(--muted);
  margin: 0 0 12px;
}

.note {
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.55;
  /* A note is usually written under a heading, which supplies the space above
     it, so this used to have no top margin. It is also used after a table
     (pipeline) and after .truthlist (review), and both of those carry no bottom
     margin, so the note sat flush against them at a measured 0.0px gap and read
     as another row of the thing above it. Adjacent margins collapse, so giving
     it a top margin fixes those two without doubling the gap under a heading. */
  margin: 12px 0 12px;
  max-width: 78ch;
}

.empty {
  font-size: 12.5px;
  color: var(--muted);
  padding: 14px 0;
}

.loading {
  font-size: 12.5px;
  color: var(--muted);
}

.meta {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
  /* Notes quote paths like interview-prep/linkedin-profile-polish.md and bare
     posting URLs, which have no break opportunity. Letting min-width go to 0
     above only permits the shrink; this is what makes the text actually wrap
     into it instead of overflowing. */
  overflow-wrap: anywhere;
}

.ok { color: var(--green); font-size: 12.5px; }
.error { color: var(--red); font-size: 12.5px; }

/* ---------------------------------------------------------------- cards */

.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* A card's head carries margin-bottom and its verbs row carries margin-top, but
   every line between them had zero margins, so the title and the meta lines ran
   together as one undifferentiated block. This sets a floor rather than an
   override: adjacent margins collapse to the larger value, so the head's 6px and
   the verbs row's 12px are both preserved. */
.card > * + * {
  margin-top: 5px;
}

/* Same problem one level down, between a disclosure's summary and its body. */
.notefull > summary + * {
  margin-top: 6px;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 14px 16px;
  /* .cards is a flex column, so a card is a flex item and defaults to
     min-width: auto, which refuses to shrink below its widest unbreakable
     child. An action note carrying a file path or a posting URL therefore
     pushed the whole document wider than the phone viewport, 84px on the
     actions view, and the page scrolled sideways. */
  min-width: 0;
}

.card__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.card__head strong {
  font-size: 14px;
  font-weight: 500;
  color: var(--fg);
}

.card--focus { border-color: var(--line-blue); }
.card--warn { border-color: var(--line-amber); }
.card--bad { border-color: var(--line-red); }

/* Index numeral on the Daily 3 — the order is the point. */
.card__i {
  font: 600 11px var(--font-mono);
  color: var(--amber);
  flex: none;
}

/* Drag affordance. Inert until the reorder lands; it does not pretend. */
.card__grip {
  color: var(--dim);
  font-size: 12px;
  letter-spacing: -1px;
  flex: none;
}

/* Deliberately NOT `margin-left:auto`. A score is sometimes the leading element
   of a card head (events lead with the rank) and sometimes the trailing one
   (offers), and baking the push into the score itself shoved every event card's
   whole heading to the right edge. Whatever should be pushed says so. */
.score {
  font: 600 12.5px var(--font-mono);
  color: var(--fg);
}
.score--good { color: var(--green); }
.score--mid { color: var(--blue); }

.right {
  margin-left: auto;
}

/* ---------------------------------------------------------------- chips */

.chip {
  font: 500 10px var(--font-mono);
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  color: var(--body);
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.chip--quick { background: var(--green-bg); color: var(--green); }
.chip--focus { background: var(--blue-bg); color: var(--blue); }
.chip--hard { background: var(--amber-bg); color: var(--amber); }
.chip--trigger { background: var(--neutral-bg); color: var(--muted); text-transform: none; }

/* Status chips, keyed to the canonical states. */
.st {
  font: 500 10px var(--font-mono);
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  color: var(--body);
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
}
.st--offer { background: var(--green-bg); color: var(--green); }
.st--interview { background: var(--blue-bg); color: var(--blue); }
.st--hired { background: var(--green-bg); color: var(--green); }
.st--registered { background: var(--green-bg); color: var(--green); }

/* Small square tags: file kinds, lane labels. */
.tag {
  font: 500 10px var(--font-mono);
  padding: 2px 7px;
  border-radius: var(--r-tag);
  background: var(--neutral-bg);
  color: var(--body);
  text-transform: uppercase;
}
.tag--md { background: var(--blue-bg); color: var(--blue); }
.tag--pdf { background: var(--green-bg); color: var(--green); }
.tag--warn { background: var(--amber-bg); color: var(--amber); }

.due {
  margin-left: auto;
  font: 500 10.5px var(--font-mono);
  color: var(--muted);
  white-space: nowrap;
}
.due--soon { color: var(--amber); }
.due--late { color: var(--red); }

/* ---------------------------------------------------------------- buttons */

button {
  font: 500 12px var(--font-ui);
  padding: 5px 12px;
  background: var(--line);
  color: var(--fg);
  border: 1px solid var(--control);
  border-radius: var(--r-btn);
  cursor: pointer;
}

button:hover:not(:disabled) {
  filter: brightness(1.25);
}

button:disabled {
  opacity: .55;
  cursor: not-allowed;
}

button.primary {
  background: var(--cta);
  color: var(--bright);
  border-color: transparent;
}

/* The blocked row's CTA. Amber on dark text: it is asking for the missing
   artifact, which is the only thing that unsticks a 🧠 row. */
button.want {
  background: var(--amber);
  color: var(--bg);
  border-color: transparent;
  font-weight: 600;
}

button.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--blue);
}

button.danger {
  background: transparent;
  border-color: transparent;
  color: var(--red);
}

.verbs {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  flex-wrap: wrap;
}

/* The library and toggle openers are buttons that must read as links. */
.docopen {
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--blue);
  font: 500 13px var(--font-ui);
  cursor: pointer;
  text-align: left;
}
.docopen:hover {
  text-decoration: underline;
  filter: none;
}

/* ---------------------------------------------------------------- forms */

input,
select,
textarea {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--control);
  border-radius: var(--r-btn);
  padding: 5px 10px;
  font: 400 12px var(--font-ui);
}

input:focus,
select:focus,
textarea:focus,
button:focus-visible,
.navitem:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 1px;
}

.propose {
  margin-top: 10px;
}

.propose > summary {
  font: 500 11.5px var(--font-ui);
  color: var(--blue);
  cursor: pointer;
  list-style: none;
}

.propose > summary::-webkit-details-marker {
  display: none;
}

.proposal {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 12px 16px;
  background: var(--card);
  border: 1px solid var(--line-blue);
  border-radius: var(--r-card);
}

.proposal__note {
  flex: 1;
  min-width: 200px;
}

.composer textarea {
  width: 100%;
  font-family: var(--font-ui);
}

.composer__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

/* A queued proposal has NOT moved the tracker, and this says so in amber. */
.pendingnote {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--amber-bg);
  border: 1px solid var(--line-amber);
  border-radius: var(--r-btn);
  font-size: 12.5px;
  color: var(--body);
}

.notefull > summary {
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
}

/* ---------------------------------------------------------------- tables */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

thead tr {
  text-align: left;
  color: var(--muted);
  font: 500 10.5px var(--font-mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

th {
  font-weight: 500;
  padding: 0 0 8px;
}

td {
  padding: 9px 0;
  border-top: 1px solid var(--line);
  vertical-align: top;
}

tbody tr:last-child td {
  border-bottom: 1px solid var(--line);
}

.num {
  font: 500 11px var(--font-mono);
  color: var(--muted);
}

.r {
  text-align: right;
}

/* The status column sits immediately after a right-aligned score, so without
   this the two headings run together and read as one word: "SCORESTATUS". */
.stcol {
  padding-left: 14px;
}

.sub2 {
  color: var(--muted);
  font-size: 12px;
}

/* Whose move. Amber when it is yours — the only column that assigns work. */
.move {
  font: 500 11px var(--font-mono);
  text-transform: uppercase;
}
.move--you { color: var(--amber); }
.move--them { color: var(--muted); }

/* ---------------------------------------------------------------- truths */

.truths {
  margin-bottom: 24px;
}

.truthlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--body);
}

.truthlist li {
  display: flex;
  gap: 10px;
}

.truthlist li::before {
  content: '▲';
  color: var(--amber);
  flex: none;
  font-size: 10px;
  line-height: 1.7;
}

.truthlist li.t--bad::before { color: var(--red); }
.truthlist li.t--mild::before { color: var(--muted); }

/* ---------------------------------------------------------------- funnel */

/* An SVG, because a bar's length is data and an inline width is blocked. */
.funnel {
  width: 100%;
  max-width: 420px;
  height: auto;
  display: block;
}

.fl { font: 400 11px var(--font-mono); fill: var(--muted); }
.fn { font: 500 11px var(--font-mono); fill: var(--fg); }
.fbase { fill: var(--neutral-bg); }
.fmid { fill: #1f6feb; }
.fnear { fill: var(--blue); }
.fend { fill: var(--green); }

/* The expansion row under a pipeline row. No top border: it belongs to the row
   above it, and a rule between them would read as a separate record. */
.rowx > td {
  border-top: 0;
  padding: 0 0 12px;
}

/* ---------------------------------------------------------------- report */

.rhead {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.verdict {
  margin-left: auto;
  text-align: right;
}

.verdict__n {
  font: 600 34px var(--font-mono);
  color: var(--fg);
  line-height: 1.1;
}

.verdict__d {
  font: 400 14px var(--font-mono);
  color: var(--muted);
  margin-left: 6px;
}

.verdict__l {
  font: 500 11px var(--font-mono);
  color: var(--green);
  letter-spacing: .06em;
  text-transform: uppercase;
  margin-top: 2px;
}

.big {
  font: 600 26px var(--font-mono);
  color: var(--fg);
}

/* One rubric dimension. The row IS the summary, so the whole line is the
   click target and the grade stays visible while the body is open. */
.dims {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.dim {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.dim[open] {
  border-color: var(--line-blue);
}

.dim > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  cursor: pointer;
  list-style: none;
  font-size: 12.5px;
}

.dim > summary::-webkit-details-marker {
  display: none;
}

.dim__l {
  width: 150px;
  flex: none;
}

.dim__w {
  font: 400 10.5px var(--font-mono);
  color: var(--muted);
  width: 42px;
  text-align: right;
  flex: none;
}

/* Four grades, four widths — an enum, so no inline width is needed. */
.gbar {
  flex: 1;
  height: 8px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
  min-width: 40px;
}

.gbar__f {
  display: block;
  height: 100%;
  border-radius: 2px;
}

.gbar--a .gbar__f { width: 96%; background: var(--green); }
.gbar--b .gbar__f { width: 82%; background: var(--blue); }
.gbar--c .gbar__f { width: 62%; background: var(--amber); }
.gbar--d .gbar__f { width: 40%; background: var(--red); }

.grade {
  font: 600 11px var(--font-mono);
  width: 16px;
  text-align: center;
  flex: none;
}
.grade--a { color: var(--green); }
.grade--b { color: var(--blue); }
.grade--c { color: var(--amber); }
.grade--d { color: var(--red); }

.dim__body {
  border-top: 1px solid var(--line);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.dim__k {
  font: 500 10px var(--font-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 6px;
}

.dim__k:first-child {
  margin-top: 0;
}

.dim__t {
  font-size: 12.5px;
  color: var(--body);
  line-height: 1.55;
}

.quote {
  margin: 0;
  border-left: 2px solid var(--control);
  padding-left: 12px;
  font-size: 12.5px;
  font-style: italic;
  color: var(--body);
  line-height: 1.55;
}

.flag {
  color: var(--amber);
}

.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pill);
  display: grid;
  place-items: center;
  font: 600 11px var(--font-mono);
  flex: none;
}

/* A link that has to sit in a row of buttons and match them. */
.btnlink {
  font: 500 12px var(--font-ui);
  padding: 5px 12px;
  background: var(--line);
  color: var(--fg);
  border: 1px solid var(--control);
  border-radius: var(--r-btn);
  display: inline-block;
}
.btnlink:hover {
  filter: brightness(1.25);
  text-decoration: none;
}

/* ---------------------------------------------------------------- diff */

/* Removed text is struck and dimmed, added text is green. Never colour alone:
   the strike-through carries the meaning for anyone who cannot see the hue. */
.was {
  color: var(--muted);
  text-decoration: line-through;
  font-size: 13px;
  margin-bottom: 2px;
}

.now {
  color: var(--green);
  font-size: 13px;
}

.mono {
  font: 500 12.5px var(--font-mono);
}

.pills {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* A discard reason and what it cost. Compact on purpose: five of these as full
   cards filled a screen with rows nobody needs to read one at a time. */
.rpill {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 12px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: 12.5px;
  color: var(--body);
}

.rpill__n {
  font: 600 12.5px var(--font-mono);
  color: var(--fg);
}

/* Scoped through .truthlist, not bare: the base marker is `.truthlist li::before`,
   which outranks a lone `.t--good::before` on specificity and left every "good"
   lever wearing the amber warning triangle. */
.truthlist li.t--good::before {
  content: '✓';
  color: var(--green);
}

/* ---------------------------------------------------------------- banners */

.banner,
.stale,
.queue {
  margin: 0;
  padding: 12px 28px;
  font-size: 12.5px;
  line-height: 1.5;
  border-bottom: 1px solid var(--line);
  color: var(--body);
}

#banner {
  background: var(--blue-bg);
  color: var(--fg);
  font-weight: 500;
}

.stale {
  background: var(--amber-bg);
  color: var(--body);
}

.queue--pending {
  background: var(--amber-bg);
  color: var(--body);
}

.queue--clear {
  background: var(--inset);
  color: var(--muted);
}

/* The state sheet: one card per honest failure mode. */
.states {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 760px;
}

.state {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 14px 18px;
}

.state--bad { border-color: var(--line-red); }
.state--warn { border-color: var(--line-amber); }

.state__head {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 6px;
}

.state__head strong {
  font-size: 13.5px;
}

.state__when {
  margin-left: auto;
  font: 400 10.5px var(--font-mono);
  color: var(--muted);
}

.state__body {
  font-size: 12.5px;
  color: var(--body);
  line-height: 1.5;
}

.i--bad { color: var(--red); }
.i--warn { color: var(--amber); }
.i--good { color: var(--green); }
.i--info { color: var(--blue); }
.i--mild { color: var(--muted); }

/* ---------------------------------------------------------------- timeline */

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 12.5px;
  color: var(--body);
}

.tl {
  display: flex;
  gap: 12px;
  align-items: baseline;
}

.tl__when {
  font: 400 10.5px var(--font-mono);
  color: var(--muted);
  width: 62px;
  flex: none;
}

.tl__kind {
  font: 500 10px var(--font-mono);
  color: var(--muted);
  width: 62px;
  flex: none;
  text-transform: uppercase;
}

.tl__what {
  flex: 1;
}

/* ---------------------------------------------------------------- documents */

.doc {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 16px 18px;
  font: 400 12.5px/1.6 var(--font-mono);
  color: var(--body);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

/* ---------------------------------------------------------------- prose */

/**
 * A document, set to be read.
 *
 * Measure is capped at 78 characters. These are evaluation reports and interview
 * kits — continuous prose someone reads top to bottom, not a dashboard panel —
 * and a 1200px line is the single biggest reason the old `<pre>` was unreadable
 * even before the monospace.
 */
.md {
  max-width: 78ch;
  font-size: 14px;
  line-height: 1.65;
  color: var(--body);
}

.md-h {
  color: var(--fg);
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-ui);
  display: block;
  margin: 28px 0 10px;
}

h2.md-h { font-size: 19px; font-weight: 600; }
h3.md-h { font-size: 16px; font-weight: 600; }
h4.md-h { font-size: 14px; font-weight: 600; color: var(--body); }
h5.md-h,
h6.md-h {
  font: 500 11px var(--font-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

.md > .md-h:first-child {
  margin-top: 0;
}

.md-p {
  margin: 0 0 14px;
}

.md-list {
  margin: 0 0 14px;
  padding-left: 22px;
}

.md-list li {
  margin-bottom: 5px;
}

.md-quote {
  margin: 0 0 16px;
  padding: 2px 0 2px 14px;
  border-left: 2px solid var(--control);
  color: var(--muted);
}

.md-hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 24px 0;
}

.md-code {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 12px 14px;
  overflow-x: auto;
  margin: 0 0 16px;
}

.md-code code {
  background: none;
  border: 0;
  padding: 0;
  font: 400 12.5px/1.6 var(--font-mono);
  color: var(--body);
  white-space: pre;
}

/* A wide table scrolls inside its own box rather than widening the page. */
.md-tablewrap {
  overflow-x: auto;
  margin: 0 0 16px;
}

.md-table {
  font-size: 13px;
  min-width: 100%;
}

.md-table th {
  text-transform: none;
  letter-spacing: 0;
  font: 600 12.5px var(--font-ui);
  color: var(--fg);
  border-bottom: 1px solid var(--line);
  padding: 6px 12px 6px 0;
}

.md-table td {
  padding: 6px 12px 6px 0;
}

.md code {
  font-size: 12.5px;
}

/* ---------------------------------------------------------------- print */

/**
 * The PDF path.
 *
 * There are no PDFs in the repository to serve — `/readable` and `*.pdf` are
 * gitignored in the private repo and none is tracked — so "Save as PDF" is the
 * browser's own print-to-PDF over these rules. Everything that is chrome comes
 * off, and the page inverts to ink on paper: a dark document printed as-is wastes
 * a cartridge and reads worse than the screen.
 */
@media print {
  :root {
    --bg: #fff;
    --card: #fff;
    --inset: #fff;
    --fg: #111;
    --body: #1a1a1a;
    --muted: #555;
    --line: #ccc;
    --control: #999;
    --bright: #000;
  }

  .head,
  .rail,
  .bar,
  .barchips,
  .foot,
  .noprint,
  #banner,
  #freshness,
  #queue,
  .crumb,
  .verbs,
  button {
    display: none !important;
  }

  body {
    background: #fff;
    color: #111;
  }

  #main {
    padding: 0;
  }

  .md {
    max-width: none;
    font-size: 11.5pt;
    line-height: 1.5;
    color: #1a1a1a;
  }

  /* A heading is not left stranded at the foot of a page, and a code block or a
     table is not split across one where it can be avoided. */
  .md-h {
    break-after: avoid;
    page-break-after: avoid;
    color: #000;
  }

  .md-code,
  .md-tablewrap,
  blockquote {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .md-code {
    background: #f6f6f6;
    border-color: #ddd;
  }

  /* In print a link's destination is invisible unless it is written out. */
  .md a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
    color: #555;
    word-break: break-all;
  }

  a {
    color: #000;
    text-decoration: underline;
  }
}

/* ---------------------------------------------------------------- chart */

.chart svg {
  width: 100%;
  height: auto;
  max-width: 760px;
  display: block;
}

.cband { fill: var(--pill); opacity: .55; }
.cbandlabel { font: 400 9.5px var(--font-mono); fill: var(--muted); }
.clane { font: 500 11px var(--font-ui); fill: var(--body); }
.ccount { font: 600 11px var(--font-mono); fill: var(--muted); }
.cbase { stroke: var(--line); stroke-width: 1; }
.cdot { opacity: .95; }
.cax { font: 400 9.5px var(--font-mono); fill: var(--muted); }

.ctable {
  margin-top: 12px;
}

.ctable > summary {
  font-size: 12px;
  color: var(--blue);
  cursor: pointer;
}

.ctable table {
  margin-top: 10px;
  font-size: 12px;
}

/* ---------------------------------------------------------------- run drawer */

/**
 * Pinned to the bottom of the viewport rather than placed in the flow.
 *
 * A scan runs for minutes. The point of putting the output here is that you can
 * start one and carry on reading the pipeline while it streams — so it has to
 * stay visible across a view change, which means it cannot live inside #main.
 */
/* The run drawer is fixed, so nothing in normal flow reserves its space and it
   painted over the foot of whatever view was open. On the today view that hid
   the whole funnel block. --drawer-h is kept in sync with its real height by
   app.js, because the drawer grows as output streams in; 46vh is its max-height
   and so is the safe fallback if that sync ever fails. */
body:has(.drawer:not([hidden])) {
  padding-bottom: var(--drawer-h, 46vh);
}

/* `hidden` has to actually hide it.
 *
 * The UA stylesheet says `[hidden] { display: none }`, but any author `display`
 * beats a UA rule, so the `display: flex` below silently defeated the attribute.
 * The drawer therefore painted from first load despite being marked hidden, the
 * Hide button set an attribute that was already set and already inert, and the
 * padding rule below correctly reserved nothing, because the drawer WAS hidden
 * as far as the DOM was concerned while being fully visible on screen. */
.drawer[hidden] {
  display: none;
}

.drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  background: var(--inset);
  border-top: 1px solid var(--line-blue);
  box-shadow: 0 -8px 28px rgba(0, 0, 0, .45);
  max-height: 46vh;
  display: flex;
  flex-direction: column;
}

.drawer__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 28px;
  border-bottom: 1px solid var(--line);
  flex: none;
}

.drawer__head strong {
  font-size: 13px;
  color: var(--fg);
}

.drawer__head #runclear {
  margin-left: auto;
}

.drawer__out {
  margin: 0;
  padding: 12px 28px 16px;
  overflow: auto;
  font: 400 12px/1.55 var(--font-mono);
  color: var(--body);
  white-space: pre-wrap;
  word-break: break-word;
  flex: 1;
}

.drawer__out:empty::before {
  content: 'no output yet';
  color: var(--muted);
}

/* The header's command picker. Compact: it sits in a crowded row. */
#runpick {
  font: 400 12px var(--font-ui);
  padding: 4px 8px;
  max-width: 190px;
}

/* ---------------------------------------------------------------- footer */

.foot {
  padding: 16px 28px 28px;
  border-top: 1px solid var(--line);
  font: 400 11px var(--font-mono);
  color: var(--muted);
}

.foot p {
  margin: 0;
}

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: no-preference) {
  button,
  .navitem {
    transition: background-color 120ms ease, color 120ms ease, filter 120ms ease;
  }
}

/* ---------------------------------------------------------------- offers table */

/* A monogram, not a logo, and the reason is the CSP: img-src is 'self' data:,
   so every logo service is a blocked request. Colour is a class rather than a
   computed inline style because style-src 'self' blocks style attributes, so an
   inline colour would look right locally and silently fail to paint on the
   hosted deployment. Six lanes, picked by a hash of the name, so a company keeps
   the same colour between renders. */
.colog {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: 600 10px var(--font-mono);
  letter-spacing: .02em;
  color: var(--bg);
  background: var(--muted);
}

.colog--0 { background: #6ea8fe; }
.colog--1 { background: #79c0a0; }
.colog--2 { background: #d9a441; }
.colog--3 { background: #c08fd8; }
.colog--4 { background: #e0705e; }
.colog--5 { background: #6fbcc4; }

.coname {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.coname__a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--fg);
  text-decoration: none;
  font-weight: 500;
}

a.coname__a:hover { text-decoration: underline; }

.chip--via { background: color-mix(in srgb, var(--amber) 18%, transparent); color: var(--amber); }
.chip--warn { background: color-mix(in srgb, var(--amber) 18%, transparent); color: var(--amber); }

.muted { color: var(--muted); }
.nowrapc { white-space: nowrap; }

/* A stand-in date is not the same fact as a recorded one, so it is marked
   rather than quietly presented as equal. */
.est { color: var(--amber); font-weight: 600; }

/* A sortable header is a control, so it is a button, styled as the label reads. */
.sortbtn {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-transform: inherit;
  letter-spacing: inherit;
}

.sortbtn:hover { color: var(--fg); }
.sortbtn.is-on { color: var(--fg); }
.sortbtn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.filterbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 14px;
}

.filterbar__l {
  font: 500 11px var(--font-mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.fchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--body);
  cursor: pointer;
}

.fchip.is-on {
  border-color: var(--blue);
  color: var(--fg);
  background: color-mix(in srgb, var(--blue) 14%, transparent);
}

.fchip input { accent-color: var(--blue); margin: 0; }

/* Wide tables scroll inside their own box rather than widening the page. */
.tablewrap { overflow-x: auto; }

/* The base table rule sets `padding: 9px 0`, no horizontal padding at all. That
   works for the wide two-column tables it was written for; here it ran the score
   straight into the location ("3.5Wollerau") and the headers into each other
   ("SCORELOCATION"). Scoped to this table so the others keep the spacing they
   were designed with. */
.offers { width: 100%; }
.offers th,
.offers td { padding-right: 18px; vertical-align: top; }
.offers th:last-child,
.offers td:last-child { padding-right: 0; }
.offers td .meta { margin-top: 2px; }

/* The two links in the last cell are separate destinations, not one phrase. */
.offers td:last-child > * + * { margin-left: 10px; }

/* A key/value block for the report sidebar. */
.kv { width: 100%; font-size: 13px; }
.kv td { padding: 3px 0; vertical-align: top; }
.kv td.k { color: var(--muted); width: 44%; padding-right: 10px; }
