/* customer.css — hand-written, no build step. Semantic classes only (the templ files reference
   ONLY these, never Tailwind utilities). Dark near-black, slate text, monospace for data, one
   restrained green accent. Premium. */

/* Design tokens (:root --bg/--text/--accent/--nav-accent/…) live in nav.css, the single source of
   truth for the nav + tokens. layout.templ loads nav.css BEFORE this file, so every var() here
   resolves. Do not re-declare tokens here. */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
.mono { font-family: var(--mono); }

/* The top bar and the Index (.topbar/.line-index/.topbar-right) live in nav.css — the single nav
   source shared with the React shell. */

/* ── page frame ── */
.wrap { max-width: 1180px; margin: 0 auto; padding: 26px 20px 80px; }
/* .page-title (canonical H1) now lives in typography.css, loaded alongside nav.css on every page. */
.page-sub { color: var(--text-dim); font-size: 13px; margin: 0 0 22px; }
.section-label {
  font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-faint); margin: 26px 0 10px;
}

/* ── quality ribbon (Home) ── */
.ribbon { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.cell {
  position: relative; flex: 1 1 150px; min-width: 150px; max-width: 240px;
  border-radius: 10px; padding: 14px 14px 12px; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.06);
  color: #0a0b0d; overflow: hidden;
  transition: transform 0.08s ease;
}
.cell:hover { transform: translateY(-2px); }
.cell.unscored {
  background: var(--bg-3); color: var(--text-dim);
  border: 1px dashed var(--line-2);
}
.cell .cell-name {
  font-weight: 600; font-size: 13px; margin-bottom: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
}
.cell.unscored .cell-name { text-shadow: none; color: var(--text); }
.cell .cell-meta { font-family: var(--mono); font-size: 10px; opacity: 0.85; }
.cell.unscored .cell-meta { opacity: 1; color: var(--text-faint); }
.cell .cell-score {
  font-family: var(--mono); font-size: 26px; font-weight: 700; line-height: 1;
  margin: 6px 0 2px; text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

/* grade chip */
.grade-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  padding: 2px 7px; border-radius: 5px;
  background: rgba(0,0,0,0.28); color: inherit;
}
.grade-chip .word { font-weight: 400; opacity: 0.85; letter-spacing: 0.02em; }

.btn {
  display: inline-block; font-family: var(--mono); font-size: 11px;
  padding: 5px 10px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--line-2); background: var(--bg-2); color: var(--text);
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.accent { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
.btn.danger { border-color: #7f2b2b; color: #f0a3a3; }
.btn.danger:hover { border-color: #c0504d; color: #ffbcbc; }
.cell .btn { margin-top: 8px; }

.grade-chip.lg { font-size: 13px; padding: 4px 9px; }
/* The two named quality measures, always shown together (QualityPair). Each line is a small
   grid with fixed tracks, so the two lines of a pair and every row of a list line up, and the
   note is the only part allowed to shrink: it is cut with an ellipsis, never pushed sideways. */
.q-pair { display: grid; gap: 4px; min-width: 0; width: 100%; }
.q-measure { display: grid; grid-template-columns: 62px 26px 22px minmax(0, 1fr); column-gap: 6px;
  align-items: center; min-width: 0; white-space: nowrap; }
.q-label { font-size: 11px; color: var(--text-dim); }
.q-num { font-family: var(--mono); font-size: 13px; text-align: right;
  font-variant-numeric: tabular-nums; }
.q-chip { justify-self: start; padding: 1px 5px; font-size: 10.5px; }
.q-note, .q-none { font-size: 11px; color: var(--text-faint); overflow: hidden;
  text-overflow: ellipsis; }
.q-none { grid-column: 2 / -1; font-family: var(--mono); }
.q-inline { font-family: var(--mono); font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.q-inline b { color: var(--text); font-weight: 600; }
.q-inline-none { color: var(--text-faint); }
.q-headline { display: flex; flex-wrap: wrap; gap: 14px 32px; align-items: flex-start; }
.q-head-measure .q-label { display: block; min-width: 0; margin-bottom: 2px; }
/* .cli-example — a static, copy-free command block for teaching moments on pages that load
   neither home.css's .code component (home_dashboard.templ, keys.templ) nor docs.templ's own
   .qs-snippet tabs (b03's API and forge-cli lane for a plan without Max). No copy button: there
   is no copy helper in this page's own JS bundle to reuse. */
.cli-example {
  margin: 12px 0 0; max-width: 520px; padding: 12px 14px; text-align: left;
  border: 1px solid var(--line-2); border-radius: 8px; background: var(--bg-2);
  font-size: 12.5px; color: var(--text-dim); white-space: pre-wrap; word-break: break-word;
}

/* ── drill workbench ── */
.drill-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 22px; margin-bottom: 22px; }
.drill-head > * { min-width: 0; }
.drill-score { font-family: var(--mono); font-weight: 800; font-size: 58px; line-height: 0.9; }
.score-max { font-size: 0.4em; font-weight: 500; color: var(--text-dim); margin-left: 2px; }
.drill-grade { margin-top: 6px; }
.drill-meta { color: var(--text-dim); font-size: 13px; }
.drill-note { color: var(--text-dim); font-size: 12px; line-height: 1.5; margin: 8px 0 0;
  padding: 8px 11px; border-left: 2px solid var(--accent); background: rgba(52,211,153,0.06); border-radius: 0 6px 6px 0; }
.drill-meta b { color: var(--text); font-weight: 600; }
.drill-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
@media (min-width: 900px) { .drill-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); } }

.stat-row { display: flex; gap: 26px; margin: 4px 0 0; }
.stat { }
.stat .num { font-family: var(--mono); font-size: 20px; font-weight: 700; color: #eef2f7; }
.stat .lbl { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.08em; }

/* A metric that cannot be computed is greyed and says N/A. It must never look like a measured
   zero: "0 contradictions" on a one-passage corpus reads as "we looked" when nothing was
   comparable at all. */
.stat-na .num { color: var(--text-faint); font-weight: 500; }
.stat-na .lbl { opacity: .65; }
.basis-warn { display: block; margin-top: 4px; color: #E6C584; font-size: 12px; }

/* Why this grade — the four density dimensions, worst first. Same ramp colours as every other
   score in the product, so one colour means one quality level everywhere. */
.grade-why { margin: 22px 0 26px; padding: 18px 20px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg-2); }
.why-dims { display: flex; flex-direction: column; gap: 9px; margin-top: 12px; }
.why-dim { display: grid; grid-template-columns: 120px 120px 40px minmax(0,1fr); gap: 12px;
  align-items: center; }
.why-k { font-size: 13px; color: var(--text); }
.why-bar { background: var(--bg-3); border-radius: 4px; height: 8px; overflow: hidden; }
.why-bar i { display: block; height: 100%; border-radius: 4px; }
.why-v { font-family: var(--mono); font-size: 12px; color: var(--text-dim); text-align: right; }
.why-note { font-size: 12px; color: var(--text-faint); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.why-basis, .why-danglers, .why-judge { font-size: 12.5px; color: var(--text-dim);
  line-height: 1.6; margin: 14px 0 0; }
.why-danglers { color: #E6C584; }
.why-judge { border-left: 2px solid var(--line-2); padding-left: 12px; }
@media (max-width: 760px) {
  .why-dim { grid-template-columns: minmax(0,1fr) 84px 40px; }
  .why-note { display: none; }
}

/* weak-docs table */
.weak-list { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.weak-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px;
  border-top: 1px solid var(--line); font-size: 13px;
}
.weak-row:first-child { border-top: none; }
.weak-pill {
  flex-shrink: 0; width: 42px; text-align: center; border-radius: 5px; margin-top: 1px;
  font-family: var(--mono); font-weight: 700; font-size: 12px; padding: 4px 0; color: #0a0b0d;
}
.weak-body { min-width: 0; flex: 1; }
.weak-body .weak-doc {
  color: var(--text-faint); font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .04em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.weak-body .weak-preview {
  color: var(--text); margin-top: 3px; line-height: 1.42;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.weak-body .weak-why { color: var(--accent); font-size: 11px; margin-top: 4px; }

/* force graph island */
#force-graph { position: relative; width: 100%; height: 380px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg-2); overflow: hidden; }

.tier { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em; padding: 3px 7px;
  border-radius: 4px; border: 1px solid var(--line-2); color: var(--text-dim); white-space: nowrap; }
.unscored-note { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.tier-note { color: var(--text-dim); font-size: 12.5px; margin: 14px 2px 0; line-height: 1.55; }
.tier-note b { color: var(--text); }

/* Max-only capability, answered in place (402) instead of a paywall over the product */
.locked { border: 1px solid var(--line-2); border-radius: 10px; padding: 18px 20px;
  background: var(--bg-2); max-width: 620px; }
.locked-title { font-weight: 600; color: #eef2f7; margin-bottom: 8px; }
.locked p { color: var(--text-dim); line-height: 1.6; margin: 0 0 14px; }

#force-graph canvas { display: block; width: 100%; height: 100%; }
.graph-hint { position: absolute; bottom: 8px; left: 10px; font-size: 10px; color: var(--text-faint); font-family: var(--mono); }

/* scanwait ("Judging the grades…") — replaces the old single sliding-bar thermometer, which
   carried no information beyond "still running". This one shows the real document/passage count
   already known before the scan finishes, and cycles through the two real phases the pipeline
   runs instead of one static line the whole time the scan takes. */
.scanwait { margin: 18px 0; }
.scanwait-bars { display: flex; align-items: flex-end; gap: 3px; height: 34px; margin-bottom: 14px; }
.scanwait-bars i { flex: 1; display: block; border-radius: 2px 2px 0 0; height: 100%;
  transform: scaleY(0.22); transform-origin: bottom;
  animation: swBar 1.15s ease-in-out infinite; opacity: 0.88;
  transition: opacity .15s ease; }
/* The one bit of "little interactivity" this wait state has: hovering pauses the wave so a
   passing look at it doesn't feel like a spinner you can't interrupt, and each bar dims except
   the one under the pointer — a small acknowledgement that someone is actually there. */
.scanwait-bars:hover i { animation-play-state: paused; opacity: 0.35; }
.scanwait-bars i:hover { opacity: 1; }
@keyframes swBar { 0%, 100% { transform: scaleY(0.22); } 50% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) {
  .scanwait-bars i { animation: none; transform: scaleY(0.62); }
}
.scanwait-count { color: #dbe2ee; font-size: 13.5px; font-variant-numeric: tabular-nums; margin-bottom: 6px; }
.scanwait-phases { position: relative; height: 1.4em; color: var(--text-dim); font-size: 12px; }
.swp { position: absolute; left: 0; top: 0; right: 0; opacity: 0;
  animation: swpCycle 12s ease-in-out infinite; }
@keyframes swpCycle { 0%, 100% { opacity: 0; } 4% { opacity: 1; } 29% { opacity: 1; } 33% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .swp { animation: none; opacity: 0; }
  .swp:first-child { opacity: 1; }
}

.card { border: 1px solid var(--line); border-radius: 10px; padding: 16px; background: var(--bg-2); }
.card h3 { margin: 0 0 12px; font-size: 13px; color: #eef2f7; font-weight: 600; }
.back-link { color: var(--text-dim); font-size: 12px; font-family: var(--mono); margin-bottom: 14px; display: inline-block; }
.back-link:hover { color: var(--accent); }
.actions { display: flex; gap: 10px; margin-top: 8px; }

/* ── Max entry point (/wield/ui/max) ────────────────────────────────────────────
   Four blocks in order: state, measurement, capabilities, action. The state block is
   the only one that changes colour, because whether the add-on is ON is the one fact
   the page must never leave ambiguous — the tier chip it replaces said ACTIVE because
   of the URL it was on. */
.max-state { border: 1px solid var(--line); border-left-width: 3px; border-radius: 10px;
  padding: 16px 18px; background: var(--bg-2); margin: 0 0 6px; }
.max-state.on { border-left-color: var(--accent); }
.max-state.off { border-left-color: var(--line-2); }
.max-state.pending { border-left-color: #e6c584; }
.max-state.pending .max-state-head { color: #e6c584; }
.max-state-head { font-weight: 600; color: #eef2f7; font-size: 15px; margin-bottom: 6px; }
.max-state.on .max-state-head { color: var(--accent); }
.max-state p { color: var(--text-dim); line-height: 1.6; margin: 0; max-width: 70ch; }
.max-state .actions { margin-top: 14px; }

/* measurement rows: the customer's own corpora, measured or not. An unmeasured corpus
   still gets a row — a filtered list reads as data loss. */
.max-rows { border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: var(--bg-2); }
.max-row { display: flex; align-items: flex-start; gap: 16px; padding: 14px 16px;
  border-top: 1px solid var(--line); }
.max-row:first-child { border-top: none; }
.max-row:hover { background: var(--bg-3); }
.max-score { flex-shrink: 0; width: 54px; text-align: right; font-family: var(--mono);
  font-size: 30px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.max-score.none { color: var(--text-faint); font-weight: 400; }
.max-row-body { flex: 1; min-width: 0; }
.max-row-name { font-weight: 600; color: var(--text); font-size: 14px; }
.max-row-name:hover { color: var(--accent); }
.max-row-detail { color: var(--text-dim); font-size: 12.5px; line-height: 1.5; margin-top: 3px; }
.max-row-cond { color: var(--text-faint); font-family: var(--mono); font-size: 10.5px;
  line-height: 1.5; margin-top: 6px; }
.max-delta { margin-top: 7px; font-size: 12.5px; color: var(--text-dim);
  padding: 6px 10px; border-left: 2px solid var(--accent);
  background: rgba(52,211,153,0.06); border-radius: 0 6px 6px 0; }
.max-delta b { color: var(--accent); font-family: var(--mono); font-weight: 700; }
.max-row-action { flex-shrink: 0; }

.max-caps { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 780px) { .max-caps { grid-template-columns: 1fr 1fr; } }
.max-cap { border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px;
  background: var(--bg-2); }
.max-cap b { color: #eef2f7; font-size: 13.5px; font-weight: 600; }
.max-cap p { color: var(--text-dim); font-size: 12.5px; line-height: 1.55; margin: 6px 0 0; }

/* The action block: the ONLY place in this package a figure appears, and it renders
   nothing at all for an account that already holds the add-on. */
.max-buy { border: 1px solid var(--line); border-radius: 10px; padding: 18px 20px;
  background: var(--bg-2); max-width: 640px; }
.max-buy p { color: var(--text-dim); line-height: 1.6; margin: 0 0 14px; }
.max-buy-btn { font-size: 13px; padding: 9px 16px; }
.max-buy-note { color: var(--text-faint); font-size: 12px; margin: 12px 0 0 !important; }

@media (max-width: 620px) {
  .max-row { flex-wrap: wrap; }
  .max-row-action { width: 100%; }
}

/* ── upsell fragment ── */

/* ── shared example corpora (migration 0009): the drill page of one says it is borrowed. Gold,
   the same accent the landing page uses for a claim, so it reads as "ours, on the house". */
.drill-note.sample-note { border-left: 2px solid rgba(230,197,132,.5); padding-left: 12px; }

/* ── passage reader + note editor ─────────────────────────────────────────────
   The surface this replaces hid the passage list behind an unlabelled "▶ N" glyph
   at 50% opacity that only reached full opacity on row hover. Everything here is
   the opposite of that: a full-width row that is a button, a visible verb on it,
   and a resting state with no hover dependency (which is also the only version
   that works on a touch screen). */
.doc-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.doc-row { border: 1px solid var(--line); border-radius: 8px; background: var(--bg-2); overflow: hidden; }
.doc-open {
  display: flex; align-items: baseline; gap: 14px; width: 100%; text-align: left;
  padding: 12px 14px; background: none; border: 0; cursor: pointer; color: var(--text);
  font: inherit;
}
.doc-open:hover, .doc-open:focus-visible { background: rgba(255,255,255,.03); }
.doc-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.doc-name { font-weight: 600; flex: 0 1 auto; }
.doc-meta { color: var(--text-faint); font-size: 11px; flex: 1 1 auto; }
.doc-cta { color: var(--accent); font-size: 12px; white-space: nowrap; }
.chunk-slot:empty { display: none; }
/* Replace a document (document_replace.go): a disclosure under the row, no script, no modal. The
   summary is a visible word, like "Read passages", never a glyph. */
.doc-replace { border-top: 1px solid rgba(255,255,255,.05); }
.doc-replace > summary { list-style: none; cursor: pointer; padding: 8px 14px; font-size: 12px;
  color: var(--text-dim); }
.doc-replace > summary::-webkit-details-marker { display: none; }
.doc-replace > summary:hover, .doc-replace > summary:focus-visible { color: var(--accent); }
.doc-replace > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.doc-replace[open] > summary { color: var(--accent); }
.doc-replace-form { display: flex; flex-direction: column; gap: 10px; padding: 0 14px 14px; }
/* "Replace pricing.pdf or keep both?" lands inside the upload form that asked. */
.upload-ask:empty { display: none; }
.upload-ask-q { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  border-left: 2px solid #ffb454; background: rgba(255,180,84,.07); border-radius: 4px; }
.upload-ask-h { margin: 0; font-weight: 600; color: var(--text-heading, var(--text));
  overflow-wrap: anywhere; }
.upload-ask-q .pass-muted { margin: 0; overflow-wrap: anywhere; }
.line-act .upload-ask { margin: 0 0 14px; }
.pass-flash-act { margin-top: 8px; }
.chunk-list { border-top: 1px solid var(--line); }
.chunk-row { padding: 14px; border-bottom: 1px solid rgba(255,255,255,.05); }
.chunk-row:last-child { border-bottom: 0; }
.chunk-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.chunk-num { font-size: 11px; color: var(--text-dim); }
.chunk-tok { font-size: 11px; color: var(--text-faint); }
.chunk-saved { font-size: 11px; color: var(--accent); }
.chunk-open { margin-left: auto; padding: 3px 9px; border-radius: 4px; border: 1px solid var(--line);
  background: none; color: var(--text-dim); font-size: 11px; cursor: pointer; }
.chunk-open:hover { border-color: var(--accent); color: var(--accent); }
.chunk-text {
  white-space: pre-wrap; line-height: 1.55; color: var(--text-dim); font-size: 13px;
  max-height: 15em; overflow-y: auto; padding: 10px 12px; border-radius: 6px;
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.05);
}
.chunk-note { display: flex; flex-direction: column; gap: 5px; margin-top: 10px; }
.note-label {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-faint);
}
.note-input {
  background: rgba(0,0,0,.3); border: 1px solid var(--line); border-radius: 6px;
  padding: 7px 9px; color: var(--text); font: inherit; font-size: 13px; width: 100%;
}
.note-input:focus { outline: none; border-color: var(--accent); }
.note-area { resize: vertical; min-height: 3em; }
.chunk-note .btn { align-self: flex-start; margin-top: 4px; }
.note-help { color: var(--text-faint); font-size: 11px; line-height: 1.5; margin: 2px 0 0; }
.chunk-note-ro { color: var(--text-dim); font-size: 12px; margin-top: 8px; }
.pass-muted { color: var(--text-faint); font-size: 12px; padding: 8px 0; }
.pass-spin { display: none; }
.pass-spin.htmx-request { display: block; color: var(--text-faint); font-size: 11px; padding: 0 14px 10px; }

/* ── passage flyout ───────────────────────────────────────────────────────────
   Fixed panel rather than a modal over the page: the customer is comparing the passage against
   the corpus behind it, and a modal that blacks out the context makes that impossible. */
.pf { position: fixed; top: 0; right: 0; bottom: 0; width: min(560px, 100vw); z-index: 60;
  overflow-y: auto; padding: 18px 20px 40px; background: var(--bg-2);
  border-left: 1px solid var(--line); box-shadow: -18px 0 60px rgba(0,0,0,.5); }
.pf[hidden] { display: none; }
.pf-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pf-hd-l { display: flex; align-items: baseline; gap: 10px; }
.pf-score { font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pf-grade { font-family: var(--mono); font-size: 12px; }
.pf-none { color: var(--text-faint); }
.pf-x { background: none; border: 0; color: var(--text-faint); font-size: 24px; cursor: pointer; line-height: 1; }
.pf-x:hover { color: #fff; }
.pf-flash { margin: 10px 0 0; padding: 8px 11px; border-radius: 4px; background: rgba(51,255,136,.08);
  border-left: 3px solid var(--accent); font-size: 13px; }
.pf-flash.pf-err { background: rgba(255,180,84,.08); border-left-color: #ffb454; }

/* Did that help. The score the flyout opened with, versus the one it has now — the answer to
   the fifth of the six customer questions, which had no answer anywhere before this. A drop is
   stated as plainly as a rise: an edit that made things worse and said nothing would be the
   worst outcome for a tool whose promise is that you can see the effect. */
.pf-delta { margin: 10px 0 0; padding: 9px 12px; border-radius: 4px; font-size: 13px;
  font-weight: 600; border-left: 2px solid var(--line-2); }
.pf-delta.up { background: rgba(51,255,136,.08); border-left-color: #33ff88; color: #9df5c4; }
.pf-delta.down { background: rgba(239,68,68,.09); border-left-color: #EF4444; color: #f0a9a9; }
.pf-delta.flat { background: rgba(255,255,255,.03); color: var(--text-dim); font-weight: 500; }

/* When a rewrite cannot move the score, the GAPS are the finding and the rewrite is a
   distraction from it. This block leads; the proposal is demoted below it. */
.pf-nohelp { margin: 0 0 18px; padding: 14px 16px; border-radius: 6px;
  background: rgba(230,197,132,.06); border-left: 2px solid #E6C584; }
.pf-nohelp-why { margin: 8px 0 0; font-size: 13px; line-height: 1.6; color: var(--text-dim); }
.pf-sug-secondary { margin-top: 20px; opacity: .7; font-size: 13px; }
.pf-dims { margin: 16px 0 0; display: flex; flex-direction: column; gap: 6px; }
.pf-dim { display: grid; grid-template-columns: 108px 1fr 34px; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 11px; }
.pf-dim-k { color: var(--text-faint); }
.pf-dim-bar { height: 5px; border-radius: 3px; background: rgba(255,255,255,.07); overflow: hidden; }
.pf-dim-bar i { display: block; height: 100%; }
.pf-dim-v { text-align: right; font-variant-numeric: tabular-nums; }
.pf-note { margin: 8px 0 0; font-size: 12px; color: var(--text-faint); line-height: 1.5; }
.pf-judge { margin: 10px 0 0; padding: 8px 11px; border-radius: 4px; font-size: 12.5px;
  background: rgba(148,158,255,.08); border-left: 3px solid #949eff; line-height: 1.5; }
.pf-judge-why { display: block; color: var(--text-faint); margin-top: 3px; }
.pf-flags { margin: 14px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pf-flags-k { font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: #ffb454; width: 100%; }
.pf-flag { padding: 2px 7px; border-radius: 3px; font-family: var(--mono); font-size: 11px;
  color: #ffd9a3; background: rgba(255,180,84,.13); border: 1px solid rgba(255,180,84,.3); }
.pf-flags-note { width: 100%; font-size: 12px; color: var(--text-faint); margin-top: 2px; }
.pf-text { width: 100%; margin-top: 14px; padding: 12px; border-radius: 6px; resize: vertical;
  background: var(--bg-3); color: #dbe2ee; border: 1px solid var(--line);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.65; }
.pf-text:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.pf-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.pf-btn { padding: 8px 14px; border-radius: 5px; border: 1px solid var(--line);
  background: transparent; color: #dbe2ee; font: inherit; font-size: 13px; cursor: pointer; }
.pf-btn:hover { border-color: var(--accent); color: var(--accent); }
.pf-btn-primary { background: var(--accent); border-color: var(--accent); color: #04120a; font-weight: 600; }
.pf-btn-primary:hover { color: #04120a; }
.pf-sug { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.pf-sug-h { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
.pf-caveat { margin: 0 0 12px; padding: 10px 12px; border-radius: 4px; font-size: 12.5px;
  line-height: 1.55; color: #e8d9b8; background: rgba(255,180,84,.09);
  border: 1px solid rgba(255,180,84,.32); }
.pf-caveat strong { display: block; color: #ffb454; margin-bottom: 3px; }
.pf-prop { margin: 0 0 12px; padding: 11px; border-radius: 5px; background: var(--bg-3);
  border: 1px solid var(--line); font-family: var(--mono); font-size: 12px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word; max-height: 260px; overflow-y: auto; }
.pf-claims, .pf-gaps { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.pf-claims-h { font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-faint); }
.pf-claim { display: grid; grid-template-columns: 96px 1fr; gap: 9px; align-items: baseline;
  padding: 6px 8px; border-radius: 4px; background: rgba(255,255,255,.02); font-size: 12.5px; }
.pf-claim.bad { background: rgba(255,90,90,.09); border: 1px solid rgba(255,90,90,.3); }
.pf-claim-m { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; }
.pf-claim-m.ok { color: #6fe39a; }
.pf-claim-m.bad { color: #ff7a7a; font-weight: 700; }
.pf-claim-e { grid-column: 2; color: var(--text-faint); font-size: 11.5px; font-style: italic; }
.pf-gap { padding: 5px 8px; border-radius: 4px; font-size: 12.5px; color: #cfd7e3;
  background: rgba(148,158,255,.08); border-left: 2px solid #949eff; }
.pf-warn { margin: 0; font-size: 12.5px; color: #ffb4b4; line-height: 1.5; }
@media (max-width: 640px) { .pf { width: 100vw; border-left: 0; } }


/* Add a passage — paste-first. The primary input is a paste target, not a file picker: what a
   person has when they notice a passage is missing is the text itself, in their clipboard. */
.add-pass { margin: 16px 0 0; padding: 14px 16px; border: 1px dashed var(--line-2);
  border-radius: 8px; display: flex; flex-direction: column; gap: 10px; }
.add-pass.ro { border-style: solid; opacity: .75; }
.add-pass-h { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .08em; }
.add-pass-text { width: 100%; box-sizing: border-box; background: var(--bg-2); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 6px; padding: 10px 12px; font-size: 13.5px;
  line-height: 1.6; font-family: inherit; resize: vertical; }
.add-pass-text:focus { outline: none; border-color: var(--accent, #33ff88); }
.add-pass-acts { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pass-flash { margin: 0 0 12px; padding: 9px 12px; border-radius: 4px; font-size: 13px;
  background: rgba(51,255,136,.08); border-left: 2px solid #33ff88; color: #9df5c4; }
.pass-flash.err { background: rgba(255,180,84,.09); border-left-color: #ffb454; color: #f2d09a; }

.add-pass-name { width: 100%; box-sizing: border-box; background: var(--bg-2); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 6px; padding: 9px 12px; font-size: 13.5px;
  font-family: inherit; }
.add-pass-name:focus { outline: none; border-color: var(--accent, #33ff88); }

/* Paste/upload tab toggle: two forms, one visible at a time, no JS — same :has() pattern
   home_dashboard.css's .cadence-seg already uses for its radio-driven toggle. */
.add-pass-tabs { display: flex; gap: 8px; }
.add-pass-tab { position: relative; padding: 5px 10px; border: 1px solid var(--line-2);
  border-radius: 6px; font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-faint); cursor: pointer; user-select: none; }
.add-pass-tab input { position: absolute; opacity: 0; width: 0; pointer-events: none; }
.add-pass-tab:has(input:checked) { background: var(--accent, #33ff88); color: #08130C;
  border-color: transparent; }
.add-pass-paste, .add-pass-upload { display: flex; flex-direction: column; gap: 10px; }
.add-pass:has(.add-pass-tab:last-child input:checked) .add-pass-paste { display: none; }
.add-pass:not(:has(.add-pass-tab:last-child input:checked)) .add-pass-upload { display: none; }
.add-pass-file { width: 100%; box-sizing: border-box; background: var(--bg-2); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 6px; padding: 9px 12px; font-size: 13px;
  font-family: inherit; }

.pf-meta-note { margin: 12px 0 0; padding: 10px 12px; border-radius: 4px; font-size: 12.5px;
  line-height: 1.6; color: #f2d09a; background: rgba(230,197,132,.07);
  border-left: 2px solid #E6C584; }

/* Score Pairs (/wield/ui/quality/score) — its own hero header and editor card, not the generic
   .page-title/.add-pass treatment every small utility form in this console reuses. This page
   carries the "prove it on your data" pitch; looking like a minor paste-a-passage utility
   undersold it. The RESULTS side below this block still reuses .weak-list/.stat-row/.drill-score
   /.grade-chip — only the INPUT side gets a bespoke treatment. */
.score-hero { margin: 4px 0 26px; }
.score-hero-eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
/* Deliberately its own size — see typography.css's header comment. Pulls font/color from the
   shared tokens so "exception" can only ever mean size, never a silent drift on those too. */
.score-hero-title { font-family: var(--sans); font-size: clamp(26px, 3vw, 34px); font-weight: 700;
  letter-spacing: -0.02em; margin: 0 0 10px; color: var(--text-heading); }
.score-hero-sub { font-size: 14px; line-height: 1.6; color: var(--text-dim); max-width: 640px; margin: 0; }

/* The editor card. A distinct surface (bg-2 on bg, a real border) instead of a dashed-outline
   utility box floating on the page background — the raw tab-separated paste inside it still
   looks like data, not prose, so it needs a container that visibly reads as "input surface",
   not "paragraph of text". */
.score-editor { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 12px; }
.score-editor-head, .score-slideout-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; }
.score-editor-label { font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text); }
.score-editor-hint { font-family: var(--mono); font-size: 11px; color: var(--text-faint); }

/* Only present when arriving via ?corpus= — see scorePairsCorpusPrefill's doc comment. Tinted
   rather than a full alert box: it's context, not a warning. */
.score-prefill-note { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-dim);
  background: rgba(52,211,153,0.08); border: 1px solid rgba(52,211,153,0.22); border-radius: 8px;
  padding: 8px 12px; }
.score-prefill-note b { color: var(--accent); }

.score-textarea { width: 100%; box-sizing: border-box; background: #060708; color: var(--text);
  border: 1px solid var(--line-2); border-radius: 8px; padding: 14px 16px; font-size: 13.5px;
  line-height: 1.7; font-family: var(--mono); resize: vertical; tab-size: 4; }
.score-textarea:focus { outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(52,211,153,0.14); }

.score-toolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* Segmented pill picker, not a bare <select> — three radios visually hidden under their own
   label, :has(:checked) marks the active pill. Reads as a real control, and unlike a <select> the
   three choices (and which one is live) are visible without opening anything. */
.score-tier-picker { display: inline-flex; background: var(--bg-3); border: 1px solid var(--line-2);
  border-radius: 8px; padding: 3px; gap: 2px; }
.score-tier-option { position: relative; }
.score-tier-option input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.score-tier-option span { display: block; padding: 6px 14px; border-radius: 6px;
  font-family: var(--mono); font-size: 12px; color: var(--text-dim);
  transition: background .12s, color .12s; }
.score-tier-option:has(input:checked) span { background: var(--accent-dim); color: var(--accent); font-weight: 600; }
.score-tier-option:hover span { color: var(--text); }

.score-k-field { display: flex; align-items: center; gap: 8px; font-family: var(--mono);
  font-size: 11.5px; color: var(--text-faint); }
.score-k-field input { width: 92px; box-sizing: border-box; background: var(--bg-3); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 6px; padding: 6px 9px; font-size: 12.5px; font-family: inherit; }
.score-k-field input:focus { outline: none; border-color: var(--accent); }

/* The one billed action on the page — sized and colored to be the obvious next step, not a
   same-weight peer of the free controls beside it. :disabled gets a REAL visual change (dimmed,
   not-allowed cursor) matching what hx-disabled-elt toggles during a real, billed request — it
   used to be functionally disabled with no visible difference at all. */
.score-cta { margin-left: auto; padding: 10px 22px; border-radius: 8px; border: 1px solid var(--accent);
  background: var(--accent-dim); color: var(--accent); font-family: var(--mono); font-weight: 700;
  font-size: 13px; letter-spacing: 0.02em; cursor: pointer; transition: background .12s, transform .08s; }
.score-cta:hover { background: rgba(52,211,153,0.2); }
.score-cta:active { transform: scale(0.98); }
.score-cta:disabled { opacity: 0.55; cursor: not-allowed; background: var(--bg-3);
  border-color: var(--line-2); color: var(--text-faint); transform: none; }

/* Beside the button, not a quiet sentence below everything else. htmx toggles this element's
   htmx-request-driven visibility (hx-indicator="#score-busy" on the form); .score-busy only adds
   the spinner + layout, matching htmx's default indicator display:none-until-active mechanism. */
.score-busy { display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 12px; color: var(--accent); }
.score-spinner { width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid rgba(52,211,153,0.25); border-top-color: var(--accent);
  animation: score-spin 0.7s linear infinite; }
@keyframes score-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .score-spinner { animation: none; } }

/* Scroll-margin, not scroll-padding on the page — this is the one element the "Score" click
   scrolls to (see the hx-on::after-swap on #score-results in the templ), and without this the
   sticky topbar (60px, see nav.css) would cover the top of a freshly-scrolled-to result. */
#score-results { scroll-margin-top: 76px; }

.score-parse { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); margin: 2px 0 0; }
.score-parse.ok { color: var(--accent); }
.score-parse.err { color: #f2d09a; }

/* Fixed three-band chips for the pairs table, which (unlike the scored results view) has no
   query-group max to scale RampHex's continuous ramp against — rows from different queries, each
   on their own pasted scale, sit in the same table. */
.grade-chip.r0 { background: rgba(120,140,170,0.16); color: var(--text-dim); }
.grade-chip.r1 { background: #fed17e; color: #0a0b0d; }
.grade-chip.r2 { background: #006837; color: #f5f7fa; }

/* "+ Add pairs" (and, with a corpus in context, "Generate from corpus") — sit in
   .score-editor-head's own flex row, right side, replacing what used to be a plain hint sentence.
   Small and quiet like .btn, not .btn.accent — these open a panel or run an action, neither
   commits to anything the customer hasn't reviewed yet. */
.score-editor-head-actions { display: flex; align-items: center; gap: 10px; }
.score-add-btn { font-family: var(--mono); font-size: 11.5px; padding: 5px 12px; border-radius: 7px;
  border: 1px solid var(--line-2); background: transparent; color: var(--text-dim); cursor: pointer; }
.score-add-btn:hover { border-color: var(--accent); color: var(--accent); }
.score-add-btn:disabled { opacity: 0.5; cursor: default; }

/* The persistent pairs table — the record of what Score will actually see, not a preview of
   unsaved typing (there is none anymore: editing happens in the slide-out). Three content columns
   plus a 4th for the row's own Edit/Delete controls. */
.score-pairs-table { margin-top: 2px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.score-pairs-row { display: grid; grid-template-columns: 1fr 1.6fr auto auto; gap: 12px;
  padding: 6px 12px; font-size: 12px; align-items: center; border-top: 1px solid var(--line); }
.score-pairs-row:first-child { border-top: none; }
.score-pairs-row .mono { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: default; }
/* A row whose query is the same as the one above it (Generate-from-corpus adds several ranked
   passages per question back-to-back) sheds its own top border so it visually reads as continuing
   the group above rather than a new, separate entry — the "↳ same query" text does the rest. */
.score-pairs-row-grouped { border-top: none; padding-top: 2px; }
.score-pairs-row .mono.dim { color: var(--text-faint); font-style: italic; }
/* Click-to-expand (item 4): the Query/Passage cells are real <button>s so a truncated long value
   is reachable without a mouse (the title= tooltip stays too, for a hover). Reset button chrome
   to look exactly like the plain text it replaces, then let .expanded flip the single-line
   ellipsis to a wrapped, full-height cell on click/Enter/Space. */
.score-cell-expand { display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; }
.score-cell-expand:hover, .score-cell-expand:focus-visible { color: var(--accent); }
.score-cell-expand.expanded { overflow: visible; text-overflow: clip; white-space: normal;
  word-break: break-word; cursor: text; color: inherit; }
.score-pairs-head { background: var(--bg-3); font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); }
.score-pairs-row-actions { display: flex; gap: 10px; white-space: nowrap; }
.score-row-act { font-family: var(--mono); font-size: 11px; color: var(--text-faint);
  background: none; border: none; padding: 0; cursor: pointer; text-decoration: underline;
  text-decoration-color: transparent; text-underline-offset: 2px; }
.score-row-act:hover { color: var(--accent); text-decoration-color: currentColor; }
.score-row-act.danger:hover { color: #f0a3a3; }

/* The add/edit slide-out — the ONLY place a customer types a raw query/passage/relevance line now
   (scorePairsSlideout's own doc comment explains why: it lives inside <form id="score-form">, so
   every button in it MUST stay type="button" or a click would trigger the form's billed submit).
   A light entrance animation earns "slide out", nothing more elaborate — respects
   prefers-reduced-motion like every other animated element on this page. */
.score-slideout-panel { margin-top: 10px; padding: 14px 16px; border: 1px solid var(--accent);
  border-radius: 10px; background: rgba(52,211,153,0.05); display: flex; flex-direction: column;
  gap: 10px; animation: score-slideout-in 160ms ease-out; }
@keyframes score-slideout-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .score-slideout-panel { animation: none; } }
.score-slideout-actions { display: flex; justify-content: flex-end; gap: 10px; }

/* Recent runs (migration 086) — a compact glance-back list, not a data table. */
.score-history { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.score-history-row { display: flex; align-items: center; gap: 14px; padding: 8px 14px;
  border-top: 1px solid var(--line); font-size: 12.5px; }
.score-history-row:first-child { border-top: none; }
.score-history-when { color: var(--text-faint); flex: 0 0 130px; }
.score-history-model { color: var(--text-dim); flex: 0 0 50px; }
.score-history-q { color: var(--text-faint); flex: 1; }

.score-tier-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }

.score-delta { display: inline-block; font-size: 10.5px; font-family: var(--mono);
  padding: 1px 7px; border-radius: 4px; margin-left: 10px; white-space: nowrap; }
.score-delta.match { color: var(--text-faint); }
.score-delta.buried { color: #e8c979; background: rgba(232,201,121,.10); }
.score-delta.promoted { color: #8fb4ff; background: rgba(148,158,255,.10); }

/* Per-query recall@k badge (item 2), beside the existing nDCG@k badge in .score-q-head — see
   scorePairsQueryCard. .dim marks a trivial recall (k covers the whole group, see
   scorePairsRecallTrivial): still a real number, but muted so it doesn't read with the same
   confidence as a genuine measurement. */
.score-q-ndcg.dim { color: var(--text-faint); }

/* Measured-vs-estimated model comparison (item 3) — a div-based grid table, same language as
   .score-pairs-table, rather than a bare <table> (no other page in this console uses one). Rows
   are metric x provenance (nDCG Measured, nDCG Estimated, Recall Measured, Recall Estimated);
   columns are Turbo/Pro/Ultra/external, aligned 1:1 with scorePairsCompareVM.Tiers. */
.score-compare-table { margin-top: 10px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.score-compare-row { display: grid; grid-template-columns: 150px repeat(4, 1fr); gap: 12px;
  padding: 8px 12px; font-size: 12px; align-items: center; border-top: 1px solid var(--line); }
.score-compare-row:first-child { border-top: none; }
.score-compare-head { background: var(--bg-3); font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); }
.score-compare-tier { color: var(--text-dim); }
.score-compare-tier.bold { color: var(--text); font-weight: 700; }
.score-compare-metric { display: flex; flex-direction: column; gap: 1px; font-family: var(--mono);
  font-size: 11.5px; color: var(--text-dim); }
.score-compare-metric .score-compare-prov { font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-faint); }
.score-compare-row-est { color: var(--text-faint); }
.score-compare-num { font-weight: 600; color: var(--text); }
.score-compare-na { font-size: 11px; color: var(--text-faint); line-height: 1.4; }
.score-compare-run { font-family: var(--mono); font-size: 11px; color: var(--accent);
  background: none; border: 1px solid var(--line-2); border-radius: 6px; padding: 4px 10px;
  cursor: pointer; white-space: nowrap; }
.score-compare-run:hover { border-color: var(--accent); background: rgba(52,211,153,0.08); }
@media (max-width: 720px) {
  .score-compare-row { grid-template-columns: 110px repeat(4, minmax(72px, 1fr)); gap: 6px; font-size: 11px; }
}

/* ── Document grades (/wield/ui/quality/{corpus}/documents) ──
   Layout only: colours are the shared tokens and the quality ramp, badges are .weak-pill, bars
   are .why-bar. Single column by default (it is read on a phone); nothing here can overflow. */
.dg-lede { max-width: 62ch; line-height: 1.55; }
.dg-dist { display: flex; flex-direction: column; gap: 9px; }
.dg-dist-row { display: grid; grid-template-columns: 74px minmax(0,1fr) 44px; gap: 12px; align-items: center; }
.dg-dist-k { font-family: var(--mono); font-size: 12px; color: var(--text); }
.dg-cards { display: grid; grid-template-columns: minmax(0,1fr); gap: 10px; }
@media (min-width: 900px) { .dg-cards { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.dg-card { min-width: 0; }
.dg-card-head { display: flex; align-items: flex-start; gap: 10px; }
.dg-name { flex: 1 1 0; min-width: 0; color: var(--text-heading); font-weight: 600; font-size: 14px;
  line-height: 1.35; overflow-wrap: anywhere; }
.dg-reasons { margin: 12px 0 0; padding-left: 18px; color: var(--text); font-size: 13px; line-height: 1.5; }
.dg-reasons li + li { margin-top: 4px; }
.dg-facts { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 12px;
  font-size: 12px; color: var(--text-dim); }
.dg-facts b { font-family: var(--mono); color: var(--text); font-weight: 600; }
.dg-note { margin-top: 12px; }
.dg-what { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.dg-what-k { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-faint); }
.dg-what p { margin: 6px 0 0; font-size: 13px; line-height: 1.55; color: var(--text-dim); overflow-wrap: anywhere; }
.dg-cap { margin: 0 0 10px; }
.dg-details > summary { cursor: pointer; }
.dg-details > summary:hover { color: var(--text-dim); }
.dg-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.dg-rows { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.dg-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; border-top: 1px solid var(--line); }
.dg-row:first-child { border-top: none; }
.dg-row-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dg-row-why { font-size: 12px; color: var(--text-dim); line-height: 1.45; }
.dg-link { margin: 18px 0 0; }

/* What POST /line/go answers when it does not navigate (line_go.templ): a miss with its nearest
   verbs, an ext link, a not-yet fact. Quiet mono lines; no card, no bubble. */
.line-out { margin: 12px 0; font-size: 13px; color: var(--text-dim); }
.line-out p { margin: 0 0 8px; overflow-wrap: anywhere; }
.line-head { color: var(--text); }
.line-index { list-style: none; margin: 0; padding: 0; }
.line-index a { display: flex; flex-wrap: wrap; gap: 4px 10px; padding: 6px 0; color: var(--text); text-decoration: none; border-top: 1px solid var(--line); }
.line-index li:first-child a { border-top: none; }
.line-index a:hover .line-title, .line-index a:focus-visible .line-title { text-decoration: underline; }
.line-group { font-size: 11px; color: var(--text-faint); min-width: 7.5em; }
.line-desc { color: var(--text-dim); }

/* What the Line answers in place (line_out.templ): a fact, a cited answer card, the chips. Facts
   are one line in the sentence face; receipts and sources stay mono. Severity dots are the only
   colour besides the lamp. */
.line-etch { font-family: var(--mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); }
.fact { font-family: var(--sans); font-size: clamp(18px, 2.4vw, 26px); font-weight: 400; color: var(--text-heading, var(--text)); display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: baseline; overflow-wrap: anywhere; }
.fact .copy, .fact .fact-link { font-family: var(--mono); font-size: 11px; background: none; border: 1px solid var(--line-2); color: var(--text-dim); padding: 3px 8px; cursor: pointer; text-decoration: none; border-radius: 2px; }
.fact .copy:hover, .fact .fact-link:hover, .fact .copy:focus-visible, .fact .fact-link:focus-visible { border-color: rgba(0, 255, 65, .38); color: var(--text); }
.acard { margin-top: 6px; border: 1px solid var(--line-2); background: var(--bg-2); padding: 16px 18px; max-width: 72ch; color: var(--text); font-size: 14px; line-height: 1.55; }
.acard > p { margin: 0 0 12px; }
.acard .src { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 6px; }
.acard .src summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.acard .src-n { font-size: 10px; color: var(--nav-accent); }
.acard .src-meta { font-size: 11px; color: var(--text-faint); }
.acard .src-text { margin: 6px 0 4px; padding: 8px 12px; border-left: 1px solid var(--line-2); color: var(--text-dim); white-space: pre-wrap; font-size: 13px; }
.acard-foot { margin: 12px 0 0; font-size: 11px; color: var(--text-faint); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { font-family: var(--sans); font-size: 13.5px; color: var(--text-dim); background: transparent; border: 1px solid var(--line-2); padding: 7px 12px 7px 10px; border-radius: 2px; cursor: pointer; display: inline-flex; gap: 9px; align-items: baseline; text-align: left; max-width: 100%; overflow-wrap: anywhere; }
.chip i { font-style: normal; font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); }
.chip .sev { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint); align-self: center; flex: none; }
.chip .sev.crit { background: #ff6b5a; }
.chip .sev.warn { background: #e8b04a; }
.chip .sev.cool { background: #7fb3ff; }
.chip:hover, .chip:focus-visible { border-color: rgba(0, 255, 65, .38); color: var(--text); }

/* The sentence header (sentence_header.templ, rule 3): the page is titled by the sentence that
   summoned it. The sentence face for the verb, mono tokens for its slots, the lamp on a token and
   nothing else. A token that offers alternatives is armed by customer.js; until then it is text. */
.shead-wrap { max-width: 1180px; margin: 0 auto; padding: 30px 20px 0; }
.shead-wrap:empty { display: none; }
.shead { margin: 0; font-family: var(--sans); font-size: clamp(22px, 2.6vw, 30px); font-weight: 400; line-height: 1.4; letter-spacing: -0.01em; color: var(--text-heading); text-wrap: balance; overflow-wrap: anywhere; }
.shead .stok-slot { position: relative; display: inline-block; max-width: 100%; }
.shead .stok { display: inline-block; font-family: var(--nav-mono); font-size: .6em; line-height: 1.5; color: var(--nav-accent); border: 1px solid rgba(0, 255, 65, .38); padding: 0 8px; border-radius: 2px; vertical-align: .18em; max-width: 100%; overflow-wrap: anywhere; }
.shead .stok.miss { color: var(--text-dim); border-style: dashed; border-color: var(--line-2); }
.shead .stok[role="button"] { cursor: pointer; }
.shead .stok[role="button"]:hover, .shead .stok[aria-expanded="true"] { background: rgba(0, 255, 65, .14); }
.shead .stok:focus-visible { outline: 1px solid var(--nav-accent); outline-offset: 3px; }
.stok-pop { position: absolute; left: 0; top: calc(100% + 6px); z-index: 30; display: grid; gap: 2px; min-width: 190px; max-width: min(320px, calc(100vw - 32px)); max-height: 60vh; overflow-y: auto; padding: 6px; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 2px; font-size: 15px; line-height: 1.3; letter-spacing: 0; }
.stok-pop[hidden] { display: none; }
.stok-pop button { font-family: var(--nav-mono); font-size: 12px; text-align: left; background: none; border: 0; color: var(--text); padding: 7px 8px; cursor: pointer; border-radius: 2px; overflow-wrap: anywhere; }
.stok-pop button:hover, .stok-pop button:focus-visible, .stok-pop button.cur { color: var(--nav-accent); background: rgba(0, 255, 65, .14); outline: none; }
/* Under a sentence, the page's own frame starts closer: the sentence is its title. */
.shead-wrap:not(:empty) + #content > .wrap:first-child { padding-top: 14px; }
.shead-wrap:not(:empty) + #content .greet-action { margin-top: 0; }
.shead-wrap:not(:empty) + #content .sb-wrap { padding-top: 18px; }
@media (max-width: 640px) {
  .shead-wrap { padding: 22px 16px 0; }
  .shead-wrap:not(:empty) + #content > .wrap:first-child { padding-left: 16px; padding-right: 16px; }
}
@media (prefers-reduced-motion: no-preference) {
  .stok-pop:not([hidden]) { animation: stok-settle .12s ease-out; }
}
@keyframes stok-settle { from { transform: translateY(-3px); opacity: .4; } to { transform: none; opacity: 1; } }

/* A plan (line_plan.templ, kind plan): the steps of one urgent change, in order, filled in, and
   one commit. A step that is a navigation is a link and is not run by the commit. */
.line-plan { max-width: 680px; }
.line-plan .plan-lede { color: var(--text-dim); font-size: 14px; line-height: 1.55; margin: 6px 0 14px; }
.line-plan .plan-err { color: #ff6b5a; font-size: 14px; margin: 8px 0; }
.line-plan .plan { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line-2); border: 1px solid var(--line-2); }
.line-plan .plan-step { background: var(--bg-2); padding: 12px 16px; display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 10px; color: var(--text); font-size: 14.5px; line-height: 1.5; }
.line-plan .plan-n { font-family: var(--nav-mono); font-weight: 400; color: var(--nav-accent); }
.line-plan .plan-step.link .plan-n { color: var(--text-faint); }
.line-plan .plan-step a { color: var(--text); text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.line-plan .plan-step a:hover { text-decoration-color: var(--text-dim); }
.line-plan .plan-detail { margin: 4px 0 0; font-family: var(--nav-mono); font-size: 11.5px; color: var(--text-faint); overflow-wrap: anywhere; }
.line-plan .plan-field { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin-top: 8px; font-size: 12.5px; color: var(--text-dim); }
.line-plan .plan-field input { flex: 1 1 200px; min-width: 0; padding: 7px 10px; border-radius: 2px; border: 1px solid var(--line-2); background: var(--bg); color: var(--text); font: inherit; font-family: var(--nav-mono); font-size: 12.5px; }
.line-plan .plan-result { margin: 6px 0 0; font-family: var(--nav-mono); font-size: 12px; color: var(--text-dim); overflow-wrap: anywhere; }
.line-plan .plan-step.done .plan-result b { color: var(--nav-accent); font-weight: 400; }
.line-plan .plan-step.failed .plan-result b { color: #ff6b5a; font-weight: 400; }
.line-plan .plan-step.skipped .plan-result b { color: var(--text-faint); font-weight: 400; }
.line-plan .plan-commit { margin-top: 16px; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.line-plan .plan-commit button { font-family: var(--sans); font-size: 14px; font-weight: 500; background: var(--text-heading); color: var(--bg); border: 0; padding: 9px 16px; border-radius: 2px; cursor: pointer; }
.line-plan .plan-commit button:hover { background: #fff; }
.line-plan .plan-commit button:focus-visible { outline: 1px solid var(--nav-accent); outline-offset: 3px; }
.line-plan .plan-commit span { font-family: var(--nav-mono); font-size: 11.5px; color: var(--text-faint); }
.line-plan .plan-outcome { margin: 14px 0 0; font-size: 14.5px; color: var(--text); }
.line-plan .plan-key { margin-top: 14px; border: 1px solid rgba(0, 255, 65, .38); background: var(--bg-2); padding: 12px 16px; }
.line-plan .plan-key p { margin: 0 0 8px; font-size: 13.5px; color: var(--text-dim); }
.line-plan .plan-key .plan-code { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.line-plan .plan-key code { font-family: var(--nav-mono); font-size: 13px; color: var(--text-heading); overflow-wrap: anywhere; min-width: 0; }
.line-plan .plan-key button { font-family: var(--nav-mono); font-size: 11px; background: none; border: 1px solid var(--line-2); color: var(--text-dim); padding: 3px 8px; cursor: pointer; border-radius: 2px; }

/* Addressable actions (W8a, line_actions.templ): a prefill surface on the plan's footing. One
   form, its fields already filled from the address, one commit. */
.line-act .act-detail { margin: 0 0 8px; font-size: 11.5px; color: var(--text-faint); overflow-wrap: anywhere; }
.line-act .act-field { display: grid; gap: 6px; margin: 0 0 14px; font-size: 12.5px; color: var(--text-dim); }
.line-act .act-field input[type=text], .line-act .act-field textarea { width: 100%; box-sizing: border-box; min-width: 0; padding: 8px 10px; border-radius: 2px; border: 1px solid var(--line-2); background: var(--bg); color: var(--text); font: inherit; font-size: 14px; }
.line-act .act-field textarea { font-family: var(--sans); line-height: 1.5; resize: vertical; }
.line-act .act-field input[type=file] { color: var(--text-dim); font-size: 13px; max-width: 100%; }
.line-act .act-field em { font-style: normal; font-family: var(--nav-mono); font-size: 11.5px; color: var(--text-faint); }
.line-act .act-checks { border: 1px solid var(--line-2); margin: 0 0 4px; padding: 0; max-height: 420px; overflow: auto; }
.line-act .act-checks legend { font-size: 11.5px; color: var(--text-dim); padding: 0 6px; }
.line-act .act-check { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 2px 10px; padding: 9px 14px; border-top: 1px solid var(--line-2); font-size: 14px; color: var(--text); cursor: pointer; }
.line-act .act-check:first-of-type { border-top: 0; }
.line-act .act-check input { margin: 3px 0 0; accent-color: var(--nav-accent); }
.line-act .act-check em { grid-column: 2; font-style: normal; font-size: 11.5px; color: var(--text-faint); }
.line-act .plan-commit button.danger { background: #c0504d; color: #fff; }
.line-act .plan-commit button.danger:hover { background: #d9625e; }
.line-act .plan-commit button:disabled { opacity: .55; cursor: default; }
.line-act .act-links { margin: 16px 0 0; display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 13.5px; }
.line-act .act-links a { color: var(--text-dim); text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.line-act .act-links a:hover { color: var(--text); }
.score-gen-cta { margin-left: 0; }

/* b03 without Max: the API and forge-cli lane under the surface (line_actions.templ, createViaAPI). */
.line-act-extra { max-width: 640px; margin: 18px 0 0; }
.line-act-extra .act-note { margin: 16px 0 0; font-size: 12.5px; color: var(--text-dim); }
