/* =====================================================================
   SARA Companion — visual design pass (Task 10)

   Direction: a lab-bench / specimen-tracking instrument, not a SaaS
   dashboard. Thirty scenarios are literally specimens pulled off a card
   catalog, worked at a bench, and filed back. Numbers are stamped in a
   monospace "readout" face because they are real identifiers (scenario
   numbers, procedure steps) the tester relies on, not decoration. Body
   copy stays in a humanist sans so long-form reading (procedure prose,
   the feedback form) is comfortable. A single teal accent stands in for
   "this is the instrument's own colour" — used for links, primary
   actions, and the "done/filed" status, nowhere else.
   ===================================================================== */

/* ---------- Tokens --------------------------------------------------- */

:root {
  color-scheme: light;

  /* Neutral ramp (paper → ink), cool cast to read as lab paper, not cream. */
  --paper: #f2f5f3;
  --surface: #ffffff;
  --surface-sunken: #eaeeec;
  --line: #d7dcd9;
  --line-strong: #b9c1bd;
  --ink: #171b1a;
  --ink-soft: #4c5652;
  /* Darkened from #7c8884, which measured 3.35:1 on --paper and 3.68:1 on
     --surface — below the 4.5:1 AA floor at every one of its 18 uses. Now
     4.91:1 and 5.39:1. Still the quietest tier; no longer unreadable. */
  --ink-faint: #616d69;

  /* Brand accent — deep instrument teal. Used for links, primary actions,
     focus rings, the wordmark, and the "done" status (the thing that has
     been filed away safely). */
  --accent: #0f6e64;
  --accent-strong: #0a4f48;
  --accent-tint: #e2f0ee;
  --accent-tint-strong: #c7e3df;
  --on-accent: #f3fbf9;

  /* Status triad (workflow: untouched → active → filed). */
  --available-ink: #4b5561;
  --available-bg: #e8ebee;
  --available-border: #c6cdd3;

  --claimed-ink: #8a5a00;
  --claimed-bg: #fbedcf;
  --claimed-border: #e7c064;

  --done-ink: var(--accent-strong);
  --done-bg: var(--accent-tint);
  --done-border: var(--accent-tint-strong);

  /* Verdict triad (judgement). "Partial" deliberately reuses the amber
     used for "claimed" — both mean "not yet resolved," one for workflow,
     one for judgement, so the shared hue is intentional rather than an
     accident of a six-colour palette. */
  --pass-ink: #1e6b39;
  --pass-bg: #dff1e3;
  --pass-border: #a8d6b3;

  --partial-ink: var(--claimed-ink);
  --partial-bg: var(--claimed-bg);
  --partial-border: var(--claimed-border);

  --fail-ink: #9a2b23;
  --fail-bg: #fbe2df;
  --fail-border: #eaaba3;

  /* LDM tag — the one hue the status/verdict triads don't use, so the
     the_one-mirror scenarios read as their own family at a glance. */
  --ldm-ink: #5b3a9b;
  --ldm-bg: #ece5f7;
  --ldm-border: #cfc0e8;

  --danger: #9a2b23;
  --focus-ring: #0f6e64;

  /* Type. Mono carries identifiers and structure; sans carries reading
     copy. Both are system stacks — no CDN, no font files to host. */
  --font-sans: -apple-system, "Segoe UI", "Helvetica Neue", Roboto, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono",
    Consolas, "Liberation Mono", Menlo, monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: 0.9375rem;
  --text-md: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: 1.625rem;
  --text-2xl: 2.0625rem;

  /* Spacing scale. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;

  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --shadow-card: 0 1px 2px rgba(23, 27, 26, 0.06);
  --shadow-panel: 0 1px 3px rgba(23, 27, 26, 0.07);
}

/* ---------- Reset / base --------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

main {
  max-width: 76rem;
  margin: 0 auto;
  padding: var(--space-5) var(--space-5) var(--space-7);
}

h1, h2, h3 { font-weight: 700; line-height: 1.25; margin: 0; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
a:hover { color: var(--accent-strong); }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

[hidden] { display: none !important; }

button, input, select, textarea { font: inherit; color: inherit; }

/* Small mono caps used throughout for eyebrows, badges, stamps. */
.mono-label {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ---------- Buttons ---------------------------------------------------
   Shared shape for every <button> / action <a> across pages. */

button, .primary, .ghost, .claim, .release, .copy {
  appearance: none;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.85rem;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  line-height: 1.2;
  transition: background-color 120ms ease, border-color 120ms ease;
}

button:hover, .ghost:hover, .claim:hover, .release:hover, .copy:hover {
  border-color: var(--ink-faint);
}

a.primary, a.ghost { display: inline-block; text-decoration: none; }

.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }

.ghost { background: transparent; }

.release { color: var(--fail-ink); border-color: var(--fail-border); background: var(--fail-bg); }

/* An action that belongs beside a name rather than standing on its own: no
   border, no fill, and it only takes on the destructive colour when you
   reach for it. A bordered button here put every holder on its own two
   lines and made a two-tester row four lines tall. */
button.linkish {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: var(--text-xs);
  color: var(--ink-faint);
  text-decoration: underline;
  cursor: pointer;
}
button.linkish:hover, button.linkish:focus-visible { color: var(--fail-ink); }

.holder { display: inline-flex; align-items: baseline; gap: 0.4rem; white-space: nowrap; }
.holder + .holder { margin-left: var(--space-3); }
.holder form { display: inline; margin: 0; }
.holder .muted { color: var(--ink-faint); font-size: var(--text-xs); }
.release:hover { border-color: var(--fail-ink); }

.claim { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
.claim:hover { background: var(--accent-strong); border-color: var(--accent-strong); }

.ghost.small { padding: 0.3rem 0.6rem; font-size: var(--text-xs); }

.copy {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.35rem 0.65rem;
}
.copy.is-copied { background: var(--pass-bg); border-color: var(--pass-border); color: var(--pass-ink); }

/* ---------- Header / nav / identity ----------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.wordmark {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--text-md);
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark span {
  color: var(--ink-faint);
  font-weight: 500;
  margin-left: 0.3em;
}
.wordmark:hover { color: var(--accent); }
.wordmark:hover span { color: var(--accent); }

.site-header nav {
  display: flex;
  gap: var(--space-4);
  flex: 1;
}
.site-header nav a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 0.3rem 0;
  border-bottom: 2px solid transparent;
}
.site-header nav a:hover { color: var(--ink); border-color: var(--line-strong); }

.identity {
  display: flex;
  gap: var(--space-2);
  margin-left: auto;
}
.identity input {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  padding: 0.45rem 0.65rem;
  font-size: var(--text-sm);
  width: 9.5rem;
}
.identity button {
  padding: 0.45rem 0.75rem;
  font-size: var(--text-sm);
}

/* ---------- Notices ----------------------------------------------------- */

.notice {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-size: var(--text-sm);
}
.notice-bad { background: var(--fail-bg); border-color: var(--fail-border); color: var(--fail-ink); }
.notice-good { background: var(--pass-bg); border-color: var(--pass-border); color: var(--pass-ink); }

/* ---------- Board ------------------------------------------------------- */

.board-intro h1 {
  font-size: var(--text-xl);
  margin-bottom: var(--space-2);
}
.board-intro .lede {
  color: var(--ink-soft);
  margin: 0 0 var(--space-5);
  max-width: 46rem;
}

.progress { margin-bottom: var(--space-4); }
.progress-bar {
  height: 0.5rem;
  border-radius: 999px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  overflow: hidden;
  margin-bottom: var(--space-2);
}
.progress-fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width 300ms ease;
}
.progress-label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.progress-label strong { color: var(--ink); font-weight: 700; }

.filters {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--space-5);
}
.filter {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 0.55rem 0.85rem;
  font-size: var(--text-sm);
  color: var(--ink-soft);
}
.filter:hover { color: var(--ink); }
.filter.is-active {
  color: var(--accent-strong);
  border-color: var(--accent);
  font-weight: 700;
}
.industry-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
  padding-bottom: 0.35rem;
  font-size: var(--text-sm);
  color: var(--ink-soft);
}
.industry-filter select {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 0.3rem 0.5rem;
  font-size: var(--text-sm);
  color: var(--ink);
}

/* Dense grid: density beats decoration since ~30 cards render at once. */
.scenario-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
}

.scenario-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--available-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.scenario-card.status-testing { border-left-color: var(--claimed-border); }
.scenario-card.status-reported { border-left-color: var(--done-border); }

.scenario-card .card-body {
  display: block;
  padding: var(--space-3) var(--space-3) var(--space-2);
  text-decoration: none;
  color: inherit;
  flex: 1;
}
.card-number {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  letter-spacing: 0.05em;
  margin-bottom: var(--space-1);
}
.scenario-card h2 {
  font-size: var(--text-base);
  font-weight: 700;
  margin: 0 0 0.2rem;
  color: var(--ink);
}
.scenario-card .coverage {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Scenario labels: pills in the exact .badge language (shared base rule
   above), color-coded with the app's own triads — green/amber/red for the
   sweep-derived odds the workshop yields a simulator, purple for the
   the_one/LDM mirror scenarios. */
/* One line, never wrapping: the footer's height is fixed, so anything that
   wrapped here would be clipped rather than pushing the card taller. */
.footer-status {
  display: inline-flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 0.3rem;
  min-width: 0;
}
.labels {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem;
}
.label-pass-high {
  color: var(--pass-ink);
  background: var(--pass-bg);
  border-color: var(--pass-border);
}
.label-pass-mid {
  color: var(--partial-ink);
  background: var(--partial-bg);
  border-color: var(--partial-border);
}
.label-pass-low {
  color: var(--fail-ink);
  background: var(--fail-bg);
  border-color: var(--fail-border);
}
/* Unknown odds — no sweep or pilot evidence yet (the LDM-mirror pack). Neutral,
   so it reads as "not measured" rather than a pass/fail bucket. */
.label-pass-unknown {
  color: var(--ink-soft);
  background: var(--surface-sunken);
  border-color: #c7cecb;
}
.label-ldm-supply {
  color: var(--ldm-ink);
  background: var(--ldm-bg);
  border-color: var(--ldm-border);
}

/* One height for every footer, whatever it holds. Cards sit in a grid of
   41; a footer that grew with its contents gave each row a different
   baseline and made the whole board look restless. */
.card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: 0 var(--space-3);
  border-top: 1px solid var(--line);
  background: var(--surface-sunken);
}
.card-footer form { margin: 0; }
.card-footer button {
  padding: 0.3rem 0.6rem;
  font-size: var(--text-xs);
  /* "Assign to me" wrapping to two lines was what made the footers ragged. */
  white-space: nowrap;
}

/* An untouched scenario has no badge: the element stays in the DOM so the
   poll can fill it without inserting nodes, and hides while it is empty. */
.badge:empty { display: none; }
/* A card that has activity shows that instead of its odds: two pills could
   not share the footer's one line, and the status is what a tester scanning
   the board is actually looking for. */
.footer-status .badge:not(:empty) ~ .labels { display: none; }

/* ---------- Badges (status carries text; colour only reinforces) ------ */

.badge, .label {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--available-border);
  background: var(--available-bg);
  color: var(--available-ink);
  white-space: nowrap;
}
.badge::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.status-testing .badge, .claim-strip.status-testing .badge {
  background: var(--claimed-bg);
  border-color: var(--claimed-border);
  color: var(--claimed-ink);
}
.status-reported .badge, .claim-strip.status-reported .badge {
  background: var(--done-bg);
  border-color: var(--done-border);
  color: var(--done-ink);
}


/* Per-card marker for "the viewer holds this scenario" -- always in the DOM
   (see board.html) so a status flip on poll shows or hides it with no JS of
   its own, purely by the card's data-mine attribute. */
.mine-marker {
  display: none;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent-strong);
}
.scenario-card[data-mine="1"] .mine-marker { display: inline-flex; }

/* Verdict / result tags are a squared-off tag, not a dotted pill, so the
   two families of six-meaning colour stay visually distinct even where a
   hue is shared (done/pass both draw on the resolved-and-good end). */
.verdict-pass .badge, .result-pass, .radio-pass input:checked + span {
  background: var(--pass-bg); border-color: var(--pass-border); color: var(--pass-ink);
}
.verdict-partial .badge, .radio-na input:checked + span {
  background: var(--partial-bg); border-color: var(--partial-border); color: var(--partial-ink);
}
.verdict-fail .badge, .result-fail, .radio-fail input:checked + span {
  background: var(--fail-bg); border-color: var(--fail-border); color: var(--fail-ink);
}
.result-na { color: var(--ink-faint); }

/* A submission's severity badge is a separate fact from its verdict badge —
   don't let it inherit the verdict's tint (e.g. a "partial" verdict with
   "major" severity shouldn't paint both badges the same amber). */
.submission header .badge + .badge {
  background: var(--available-bg); border-color: var(--available-border); color: var(--available-ink);
}

/* ---------- Scenario page ---------------------------------------------- */

.scenario-header { margin-bottom: var(--space-5); }
.back {
  display: inline-block;
  font-size: var(--text-sm);
  color: var(--ink-soft);
  text-decoration: none;
  margin-bottom: var(--space-3);
}
.back:hover { color: var(--accent); }

.eyebrow {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--text-xs);
  color: var(--ink-faint);
  margin: 0 0 var(--space-1);
}
.scenario-header h1 { font-size: var(--text-xl); margin-bottom: var(--space-3); }

.claim-strip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--available-border);
  background: var(--available-bg);
  border-radius: var(--radius-sm);
}
.claim-strip form { margin: 0; }
.claim-strip.status-testing { background: var(--claimed-bg); border-color: var(--claimed-border); }
.claim-strip.status-reported { background: var(--done-bg); border-color: var(--done-border); }
.claim-strip .hint { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
/* Who else is on this scenario — the names the board no longer carries. */
.claim-strip .testers { font-size: var(--text-sm); color: var(--ink-soft); }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-panel);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
}
.panel h2 {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  margin-bottom: var(--space-1);
}
.panel-hint { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--ink-faint); }
.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-1);
}
.panel-head h2 { margin: 0; }

.prompt-panel blockquote {
  margin: 0;
  padding: var(--space-4);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.6;
  white-space: pre-wrap;
}

.attachments { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.attachments a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--ink);
  background: var(--surface-sunken);
}
.attachments a:hover { border-color: var(--ink-faint); }
.attachments .kind {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--accent-strong);
  background: var(--accent-tint);
  border-radius: var(--radius-sm);
  padding: 0.15rem 0.4rem;
}
.attachments .filename { flex: 1; font-weight: 600; }
.attachments .size { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-faint); }
/* Not a badge to click past: it tells the tester this file is not part of
   the build, so it sits after the size and reads as an instruction. */
.attachments .attachment-purpose {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-soft);
  border: 1px dashed var(--line);
  border-radius: 999px;
  padding: .1rem .5rem;
  white-space: nowrap;
}

.intake ul { margin: 0; padding-left: 1.2rem; }
.intake li { margin-bottom: 0.4rem; }
.intake code, .prose code {
  font-family: var(--font-mono);
  background: var(--surface-sunken);
  padding: 0.1em 0.35em;
  border-radius: 0.2em;
  font-size: 0.9em;
}

.step-number {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  min-width: 1.4rem;
  flex: none;
  padding-top: 0.15rem;
}

/* ---------- Feedback form ------------------------------------------------
   The longest thing on the site. One row per check, one per step, both
   built the same way so a tired tester learns the pattern once. */

.feedback-form fieldset {
  border: none;
  margin: 0 0 var(--space-5);
  padding: 0;
}
.feedback-form legend {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  padding: 0;
  margin-bottom: var(--space-1);
}

.check-row, .step-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}
.check-row:nth-child(odd), .step-row:nth-child(odd) { background: var(--surface-sunken); }
.check-row, .step-row { padding-left: var(--space-2); padding-right: var(--space-2); }

.check-text, .step-text {
  margin: 0;
  font-size: var(--text-sm);
  grid-column: 1 / 2;
}
.step-text { display: flex; gap: var(--space-2); }
.step-text .step-number { padding-top: 0; }

.check-row .check-options, .step-row .check-options { grid-column: 2 / 3; grid-row: 1; }
.check-row input[type="text"] {
  grid-column: 1 / 3;
  grid-row: 2;
}

/* Segmented, button-like radios: big enough to hit quickly without
   aiming, and the checked state carries its own colour + a checkmark so
   it never depends on the radio dot alone. */
.check-options {
  display: flex;
  gap: 0.35rem;
  flex-wrap: nowrap;
}
.radio {
  position: relative;
  display: inline-flex;
}
.radio input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}
.radio span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.5rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-soft);
  text-align: center;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.radio input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.radio input:hover + span { border-color: var(--ink-faint); }
.radio-done input:checked + span, .radio-pass input:checked + span {
  background: var(--pass-bg); border-color: var(--pass-border); color: var(--pass-ink);
}
.radio-fail input:checked + span, .radio-not_done input:checked + span {
  background: var(--fail-bg); border-color: var(--fail-border); color: var(--fail-ink);
}
.radio-na input:checked + span, .radio-blocked input:checked + span {
  background: var(--partial-bg); border-color: var(--partial-border); color: var(--partial-ink);
}
.radio input:checked + span::before { content: "✓ "; }

.check-row input[type="text"] {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 0.4rem 0.6rem;
  font-size: var(--text-sm);
  width: 100%;
}

.summary-fields {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.summary-fields label, .notes-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-soft);
}
.summary-fields select, .summary-fields input, .notes-field textarea {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 0.5rem 0.6rem;
  font-size: var(--text-base);
  font-weight: 400;
  color: var(--ink);
  min-width: 12rem;
}
.notes-field { margin-bottom: var(--space-4); }
.notes-field textarea { min-width: 100%; resize: vertical; }

.feedback-panel .primary { padding: 0.65rem 1.2rem; font-size: var(--text-base); }

/* ---------- Account pages: login, admin, your own account ------------- */

.login-panel { max-width: 26rem; margin-inline: auto; }

.login-form {
  display: grid;
  gap: var(--space-3);
  /* A text field as wide as the panel invites nothing and reads as broken;
     these are short values. */
  max-width: 24rem;
  margin: var(--space-3) 0;
}
.login-form label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-soft);
}
.login-form input {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 0.5rem 0.6rem;
  font-size: var(--text-base);
  font-weight: 400;
  color: var(--ink);
}
.login-form button { justify-self: start; }

/* Each account is one table row; its controls sit inline within their cell. */
.inline-form { display: flex; gap: var(--space-2); align-items: center; }
.accounts-table input[type="password"] {
  width: 11rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.5rem;
  font-size: var(--text-sm);
}
.accounts-table .muted { color: var(--ink-faint); }
.accounts-table td { vertical-align: middle; }
/* The table fills the panel; let the name column take the slack so the
   controls stay together on the right instead of drifting apart. */
.accounts-table th:nth-child(2), .accounts-table td:nth-child(2) { width: 100%; }
.accounts-table th:last-child, .accounts-table td:last-child { text-align: right; }
.badge-off { color: var(--ink-soft); background: var(--surface-sunken); }
/* Says the card holds a report in the retired format, so its procedure
   steps and hints are not read as questions the current form asks. */
.badge-legacy { color: var(--ink-faint); background: var(--surface-sunken); border-color: var(--line); }
.submission-legacy .submission-checks li { background: none; }

/* ---------- Submission / report card (shared by scenario + dashboard) - */

.submission {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  background: var(--surface);
}
.submission.verdict-pass { border-left: 4px solid var(--pass-border); }
.submission.verdict-partial { border-left: 4px solid var(--partial-border); }
.submission.verdict-fail { border-left: 4px solid var(--fail-border); }

.submission header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}
.submission header strong { font-size: var(--text-sm); }
.submission header time {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
}
.submission-notes {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}
.submission-checks { list-style: none; margin: 0; padding: 0; font-size: var(--text-sm); }
.submission-checks li {
  display: flex;
  gap: var(--space-2);
  padding: 0.3rem 0;
  border-top: 1px solid var(--line);
}
.submission-checks li:first-child { border-top: none; }
.submission-checks .marker {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  min-width: 2.4rem;
}
.submission-checks .result-pass .marker { color: var(--pass-ink); }
.submission-checks .result-fail .marker { color: var(--fail-ink); }
.submission-checks .result-na .marker { color: var(--ink-faint); }
.submission-checks em { margin-left: auto; color: var(--ink-faint); font-style: italic; }

/* The questionnaire's own vocabulary. Most answers are yes, so yes stays
   quiet and only a no is marked — the same principle the board follows, and
   the reason a report can be read at a glance. The explanation under a no is
   the finding itself, so it reads as content rather than as a faint aside
   pushed to the right margin. (pass/fail/na above belong to the per-scenario
   checks this replaced, and still render the reports filed under them.) */
.submission-checks li { flex-wrap: wrap; }
.submission-checks .result-no { background: var(--fail-bg); }
.submission-checks .result-no .marker { color: var(--fail-ink); }
.submission-checks .result-yes .marker { color: var(--ink-faint); }
.submission-checks .result-no em,
.submission-checks .result-yes em {
  flex-basis: 100%;
  margin: 0.15rem 0 0 calc(2.4rem + var(--space-2));
  color: var(--ink-soft);
  font-style: normal;
}
.submission-steps-label {
  margin: var(--space-3) 0 0;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.submission-checks.submission-steps .result-done .marker { color: var(--pass-ink); }
.submission-checks.submission-steps .result-blocked .marker,
.submission-checks.submission-steps .result-not_done .marker { color: var(--fail-ink); }
.submission-checks.submission-steps .result-unanswered .marker { color: var(--ink-faint); }

/* ---------- Dashboard ---------------------------------------------------- */

.dashboard-head h1 { font-size: var(--text-xl); margin-bottom: var(--space-4); }

.stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.stat-row.verdicts { grid-template-columns: repeat(3, 1fr); }

.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 3px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-card);
}
.stat strong {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1.1;
}
.stat span {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}
.stat.verdict-pass { border-top-color: var(--pass-border); }
.stat.verdict-partial { border-top-color: var(--partial-border); }
.stat.verdict-fail { border-top-color: var(--fail-border); }

.exports { display: flex; gap: var(--space-3); margin: var(--space-4) 0 var(--space-6); }

.grid-table-wrap { overflow-x: auto; }
.grid-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.grid-table th, .grid-table td {
  text-align: left;
  padding: 0.55rem var(--space-3);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.grid-table th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  font-weight: 600;
}
.grid-table td:nth-child(2) { white-space: normal; }
.grid-table tbody tr:hover { background: var(--surface-sunken); }
.grid-table .badge { font-size: 0.7rem; }

/* ---------- Procedure page -----------------------------------------------
   content/procedure.md rendered in the app's own vocabulary: one panel per
   section, and the run's <ol> drawn exactly like the checklist rows the
   tester will meet again in the report form. */

.prose {
  max-width: 42rem;
  font-size: var(--text-md);
  line-height: 1.65;
}
.prose p, .prose ul, .prose ol { margin: 0 0 var(--space-3); }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li { margin-bottom: 0.3rem; }
.prose strong { color: var(--ink); }
.prose > :last-child { margin-bottom: 0; }

.procedure-page { max-width: 46rem; }
.procedure-page .lede {
  font-size: var(--text-md);
  color: var(--ink-soft);
  max-width: 60ch;
}
.procedure-page .panel h2 { margin-bottom: var(--space-3); }

/* The run: chip-numbered rows, same shape as the report's step rows. The
   built-in list-item counter (not a custom one) keeps the numbering honest
   across the phase-split lists, which continue via their start attribute. */
.procedure-page .prose ol {
  list-style: none;
  padding: 0;
}
.procedure-page .prose ol li {
  /* Block, not flex: a flex row would turn every inline <code> in the step
     into its own column. The number sits in the left padding instead.
     Block also drops display:list-item, and with it the automatic list-item
     increment — put the increment back so the start attribute still counts. */
  display: block;
  position: relative;
  counter-increment: list-item;
  margin: 0;
  padding: var(--space-2);
  padding-left: calc(var(--space-2) + 1.4rem + var(--space-3));
  border-bottom: 1px solid var(--line);
}
.procedure-page .prose ol li:last-child { border-bottom: none; }
.procedure-page .prose ol li::before {
  content: counter(list-item);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  position: absolute;
  left: var(--space-2);
  top: calc(var(--space-2) + 0.15rem);
}

/* Phase labels inside the run: which SARA surface the next steps happen on. */
.procedure-page .prose h3 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-strong);
  margin: var(--space-4) 0 var(--space-1);
}
.procedure-page .prose h3:first-child { margin-top: 0; }

/* Checklists: quiet em-dash markers, like the app's other reading lists. */
.procedure-page .prose ul { list-style: none; padding: 0; }
.procedure-page .prose ul li { padding-left: 1.3rem; text-indent: -1.3rem; }
.procedure-page .prose ul li::before { content: "—\00a0\00a0"; color: var(--ink-faint); }

/* Leading keywords (the severity levels) read as badges — the same neutral
   tint the submission cards give severity, which is deliberately not the
   verdict's color. */
.procedure-page .prose li > strong:first-child {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--available-ink);
  background: var(--available-bg);
  border: 1px solid var(--available-border);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.45em;
  text-indent: 0;
  display: inline-block;
}

/* ---------- Responsive ---------------------------------------------------- */

@media (max-width: 1024px) {
  main { padding: var(--space-4); }
  .scenario-grid { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
  .site-header {
    flex-wrap: wrap;
    padding: var(--space-3);
  }
  .site-header nav { order: 3; width: 100%; gap: var(--space-3); }
  .identity { margin-left: 0; }
  .identity input { width: 8rem; }

  .scenario-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); }

  .check-row, .step-row {
    grid-template-columns: 1fr;
  }
  .check-row .check-options, .step-row .check-options { grid-column: 1; grid-row: 2; }
  .check-row input[type="text"] { grid-row: 3; }
  .check-options { flex-wrap: wrap; }

  .summary-fields { flex-direction: column; }
  .summary-fields select, .summary-fields input { min-width: 0; width: 100%; }

  .stat-row, .stat-row.verdicts { grid-template-columns: repeat(2, 1fr); }
}

/* --- Hints ------------------------------------------------------------
   A hint is a deliberate act, so its summary reads as a button rather than
   a disclosure triangle. Opened hints stay visually distinct: which ones a
   tester needed is the point of the exercise, not a mark against them. */
.hints { display: grid; gap: var(--space-2); }

.hint {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.hint > summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  cursor: pointer; list-style: none;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--ink);
}
.hint > summary::-webkit-details-marker { display: none; }
.hint > summary:hover { background: var(--surface-sunken); }
.hint > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.hint-label { font-weight: 600; }
.hint-reveal {
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--accent); border: 1px solid var(--accent-tint-strong);
  border-radius: 999px; padding: .15rem .6rem; white-space: nowrap;
}
.hint[open] { border-color: var(--claimed-border); background: var(--claimed-bg); }
.hint[open] > summary { background: transparent; }
.hint[open] .hint-reveal {
  color: var(--claimed-ink); border-color: var(--claimed-border);
}
.hint[open] .hint-reveal::after { content: " · opened"; }
.hint-answer {
  margin: 0; padding: 0 var(--space-4) var(--space-4);
  color: var(--ink-soft); border-top: 1px solid var(--claimed-border);
  padding-top: var(--space-3);
}

/* --- The customer's full answer sheet --------------------------------
   Deliberately quieter than a hint: it sits below them, is not counted in
   the hint metric, and reads as reference rather than a reveal. */
.sheet {
  margin-top: var(--space-3);
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.sheet > summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  cursor: pointer; list-style: none;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--ink);
}
.sheet > summary::-webkit-details-marker { display: none; }
.sheet > summary:hover { background: var(--surface); }
.sheet > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sheet[open] { border-color: var(--claimed-border); }
.sheet > .panel-hint { padding: 0 var(--space-4); }
.sheet-fields {
  margin: 0; padding: var(--space-3) var(--space-4) var(--space-4) calc(var(--space-4) + 1.1rem);
  display: grid; gap: var(--space-2);
  color: var(--ink-soft); font-size: var(--text-sm);
}

/* --- Report gate ----------------------------------------------------- */
.report-gate > summary {
  cursor: pointer; list-style: none;
  padding: var(--space-3) 0;
}
.report-gate > summary::-webkit-details-marker { display: none; }
.report-gate > summary h2 { margin: 0; }
.report-gate > summary:hover h2 { color: var(--accent); }
.report-gate > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.report-gate[open] > summary { border-bottom: 1px solid var(--line); margin-bottom: var(--space-4); }

.submission-hints { margin: var(--space-2) 0; color: var(--ink-soft); }
.submission-prompt {
  margin: var(--space-2) 0; padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--line-strong); color: var(--ink-soft);
  font-family: var(--font-mono); font-size: var(--text-sm); white-space: pre-wrap;
}

/* --- The operations brief ---------------------------------------------
   Vendored pack markup rendered inline. Its own stylesheet is stripped at
   parse time, so everything it needs lives here, scoped to .brief so the
   pack's generic class names (tag, callout, foot) cannot reach the app. */
.brief {
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.brief > :first-child { margin-top: 0; }
.brief > :last-child { margin-bottom: 0; }

.brief header { margin-bottom: var(--space-4); }
.brief .tag {
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .12em; color: var(--ink-soft);
}
.brief h1 { font-size: var(--text-xl); margin: var(--space-1) 0 var(--space-2); }
.brief h2 {
  font-size: var(--text-md); color: var(--accent-strong);
  margin: var(--space-5) 0 var(--space-2);
}
.brief p { margin: var(--space-2) 0; color: var(--ink-soft); }
.brief header p { color: var(--ink-soft); }

/* The numbers are the reason the brief exists — let a wide table scroll
   inside its own box rather than pushing the page sideways. */
.brief table {
  width: 100%; border-collapse: collapse;
  margin: var(--space-3) 0; font-size: var(--text-sm);
  display: block; overflow-x: auto; white-space: nowrap;
}
.brief th, .brief td {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line); text-align: left;
}
.brief th {
  background: var(--surface-sunken); color: var(--ink);
  font-weight: 600; white-space: nowrap;
}
.brief td { color: var(--ink-soft); }

.brief .callout {
  background: var(--accent-tint); border-left: 3px solid var(--accent);
  padding: var(--space-3) var(--space-4); margin: var(--space-4) 0;
  color: var(--ink); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.brief .foot {
  margin-top: var(--space-4); color: var(--ink-soft);
  font-size: var(--text-xs);
}

.attachments-heading {
  font-family: var(--font-mono); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-faint); margin: 0 0 var(--space-2);
}

