/**
 * Tend.ai Compile — compiler console.
 *
 * Same world as the alerts console: the statutory instrument rendered as software.
 * Square corners without exception, hairline rules and tonal layering instead of
 * shadows, a signage grotesque for prose and a mono reserved strictly for values that
 * are measured, cited or legally identified. See DESIGN.md; those rules are
 * load-bearing, not preferences, and this file previously ignored all of them — it
 * invented a blue-grey palette, a blue accent, 6px radii and no webfont at all, which
 * made the two consoles look like products from different companies.
 *
 * Deliberately a subset of admin/style.css rather than a copy of it. The tokens, the
 * controls, the table and the state vocabulary are the same shapes; the view-specific
 * furniture of a fourteen-module console is not here because nothing in this one needs
 * it yet. Where a shape exists in both, it is the admin shape.
 *
 * Two rules from PRODUCT.md carry into every choice: the console must be usable at
 * 320px and legible in bright outdoor light, and colour is never the sole carrier of
 * meaning — every gate state carries a word as well as a colour, because a compiler
 * checking a job on a phone outside a client's office is the normal case.
 *
 * Fonts are self-hosted because the console's CSP is `default-src 'self'` — a
 * fonts.googleapis.com link is blocked outright, and silently falling back to Helvetica
 * would collapse the world this console is supposed to inhabit.
 */

/* --------------------------------------------------------------------------
   Faces
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Martian Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('fonts/martian-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Martian Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('fonts/martian-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

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

:root {
  /* Ledger stock and printing ink. */
  --paper: #e7eae1;
  --paper-lit: #f3f5ef;
  --paper-sunk: #daded1;
  --ink: #0b0d0a;
  --ink-secondary: #4a5148;
  --rule: #c3c9bc;
  --pula: #0a5c9e;
  --pula-deep: #073f6d;
  --pula-tint: #bbd9f0;
  --mark: #ff3b00;      /* 24px and above, or on ink. Never below. */
  --mark-ink: #b82a00;  /* the only orange permitted on small text */
  --scan: #8b9384;

  /* Aliases for the names this stylesheet already used, so nothing had to be renamed
     to be restyled. Every one of them previously held an invented colour. */
  --bg: var(--paper);
  --card: var(--paper-lit);
  --line: var(--rule);
  --muted: var(--ink-secondary);
  --accent: var(--mark-ink);
  --ok: var(--ink);          /* there is no green in this palette */
  --warn: var(--mark-ink);
  --bad: var(--mark-ink);

  --display: 'Archivo', Helvetica, Arial, sans-serif;
  --mono: 'Martian Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --hair: 1px;
  --xs: 4px;
  --sm: 8px;
  --md: 16px;
  --lg: 32px;
  --xl: 64px;

  color-scheme: light;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

* { box-sizing: border-box; }

/* An author `display` beats the UA stylesheet's rule for [hidden], and `.gate` is a
   grid. Without this the sign-in card stays on screen after a successful sign-in,
   sitting over the console. Stated once, with !important, for the same reason admin
   states it: every future layout rule would otherwise have to remember. */
[hidden] { display: none !important; }

/* Square corners, everywhere, without exception. A rule rather than a value, so a new
   control cannot quietly acquire a radius. */
button, input, select, textarea, table, th, td, img, .card, .sheet, .status { border-radius: 0; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--display);
  font-size: 0.9375rem;
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { margin: 0 0 var(--sm); font-weight: 700; letter-spacing: -0.02em; }
h1 { font-size: clamp(1.5rem, 3.4vw, 2rem); font-variation-settings: 'wdth' 118; line-height: 1.05; }
h2 { font-size: clamp(1.25rem, 2.6vw, 1.5rem); font-variation-settings: 'wdth' 112; font-weight: 650; }
h3 {
  font-size: 0.8125rem;
  font-weight: 650;
  font-variation-settings: 'wdth' 106;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}

p { margin: 0 0 var(--md); max-width: 68ch; }

:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Controls
   -------------------------------------------------------------------------- */

button {
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  min-height: 44px;              /* the phone-outside-a-client's-office case */
  padding: var(--sm) var(--md);
  background: var(--paper-lit);
  color: var(--ink);
  border: 1px solid var(--ink);
  cursor: pointer;
}

button:hover { background: var(--paper-sunk); }

/* The marking paint rule: the primary action is Marking Orange with STATUTORY INK on
   it, never white. 5.3:1 against 3.2:1, and marking paint is always read dark-on-orange
   in the world this console borrows from. */
button.primary { background: var(--mark); color: var(--ink); border-color: var(--ink); }
button.primary:hover { background: var(--mark-ink); color: var(--paper-lit); }

/* State by weight and colour, never by opacity — a dimmed control is unreadable in the
   bright outdoor light PRODUCT.md names as a normal condition. */
button[disabled], button:disabled {
  color: var(--ink-secondary);
  background: transparent;
  border-color: var(--rule);
  cursor: not-allowed;
}

button.link {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  padding: var(--sm) var(--xs);
  min-height: 44px;
  font-weight: 600;
}
button.link:hover { background: none; border-bottom-color: var(--ink); }

input, select, textarea {
  font: inherit;
  font-size: 0.875rem;
  width: 100%;
  padding: var(--sm);
  background: var(--paper-lit);
  color: var(--ink);
  border: 1px solid var(--rule);
}

input:focus, select:focus, textarea:focus { border-color: var(--ink); outline-offset: 1px; }

/* Measured values are set in mono, including while they are being typed. A date and an
   hour count are measured things. */
input[type='date'], input[type='number'] { font-family: var(--mono); font-size: 0.8125rem; }

input[type='checkbox'] { width: auto; min-width: 20px; min-height: 20px; accent-color: var(--ink); }

label {
  display: block;
  margin: var(--md) 0 var(--xs);
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}

label.inline {
  display: inline-flex;
  align-items: center;
  gap: var(--xs);
  margin: 0;
  min-height: 44px;
  text-transform: none;
  letter-spacing: 0.02em;
  font-family: var(--display);
  font-size: 0.8125rem;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Sign-in
   -------------------------------------------------------------------------- */

.gate { display: grid; place-items: start center; padding: 12vh var(--md) var(--lg); }

/* There are no cards in this system — a sheet is ruled, square and tonally layered. */
.gate-card {
  width: 100%;
  max-width: 26rem;
  background: var(--paper-lit);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--ink);
  padding: var(--lg) var(--md) var(--md);
}

/* The mark sits above the wordmark on the gate, separated by the same hairline the
   sheets use, so the sign-in reads as a headed notice rather than a form with a logo. */
.gate-mark {
  display: block;
  width: 40px;
  height: 40px;
  margin-bottom: var(--sm);
}

.gate-card form { display: block; }
.gate-card button { width: 100%; margin-top: var(--md); }

/* --------------------------------------------------------------------------
   Chrome
   -------------------------------------------------------------------------- */

.bar {
  /* The nav row below bleeds to the bar's own edges with a negative margin, so the two
     have to agree on one number. They did not, and the 8px difference was the whole
     document's horizontal overflow at 375px. */
  --bar-pad: var(--md);

  display: flex;
  align-items: center;
  gap: var(--md);
  flex-wrap: wrap;
  row-gap: var(--sm);
  padding: var(--sm) var(--bar-pad);
  background: var(--paper-lit);
  border-bottom: 1px solid var(--ink);
}

.bar strong {
  font-size: 0.9375rem;
  font-variation-settings: 'wdth' 112;
  letter-spacing: -0.015em;
}

/* The mark carries no colour of its own — it takes `currentColor`, so it inverts with
   whatever text colour the surface it sits on has already established. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--xs);
}

.brand-mark {
  display: block;
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

.bar nav { display: flex; gap: var(--xs); }

.tab {
  border: 1px solid transparent;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--ink-secondary);
  font-weight: 600;
}
.tab:hover { background: var(--paper-sunk); }
.tab[aria-selected='true'] {
  color: var(--ink);
  border-bottom-color: var(--mark-ink);
  background: var(--paper);
}

.spacer { flex: 1; }

#whoami {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  overflow-wrap: anywhere;
}

main { padding: var(--md); max-width: 68rem; margin: 0 auto; }

/* --------------------------------------------------------------------------
   Toolbar
   -------------------------------------------------------------------------- */

.controls {
  display: flex;
  align-items: center;
  gap: var(--sm);
  flex-wrap: wrap;
  padding-bottom: var(--sm);
  margin-bottom: var(--md);
  border-bottom: 1px solid var(--rule);
}

.controls label { margin: 0; }
.controls select { width: auto; min-width: 10rem; }

/* --------------------------------------------------------------------------
   Table
   -------------------------------------------------------------------------- */

/* Six columns will not fit 320px and `width:100%` cannot shrink a table below its
   min-content width, so without this the whole document scrolls sideways. The table
   scrolls inside its own box instead. */
.scroller {
  overflow-x: auto;
  border-top: 1px solid var(--rule);
  margin-bottom: var(--lg);
}
.scroller table { min-width: 100%; }

table { border-collapse: collapse; width: 100%; }

th {
  text-align: left;
  padding: var(--sm);
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  white-space: nowrap;
  border-bottom: 1px solid var(--ink);   /* the head/body division is an emphasis rule */
}

td {
  padding: var(--sm);
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  vertical-align: top;
}

/* Prose in a cell is prose, not a measured value. */
td.prose { font-family: var(--display); font-size: 0.8125rem; }

tbody tr { cursor: pointer; }
tbody tr:hover { background: var(--paper-lit); }
tbody tr:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

.days-urgent { color: var(--mark-ink); font-weight: 700; }
.days-soon { font-weight: 700; }
.days-past { text-decoration: line-through; color: var(--ink-secondary); }

/* --------------------------------------------------------------------------
   Gates
   -------------------------------------------------------------------------- */

.gates { list-style: none; margin: 0 0 var(--md); padding: 0; }

.gates li {
  padding: var(--sm) var(--md);
  margin-bottom: var(--hair);
  background: var(--paper-lit);
  border-left: 2px solid var(--rule);
}

.gates li.pass { border-left-color: var(--ink); }
.gates li.fail { border-left-color: var(--mark-ink); }

.gates .state {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: block;
}
.gates li.fail .state { color: var(--mark-ink); }

.cols { display: grid; gap: var(--lg); }
.actions { display: grid; gap: var(--sm); justify-items: start; }
.stack { max-width: 26rem; }

/* --------------------------------------------------------------------------
   State vocabulary — every colour carries a word
   -------------------------------------------------------------------------- */

.muted { color: var(--ink-secondary); }
.small { font-size: 0.8125rem; }

/* A refusal. Red, bold, and reserved for things that actually went wrong — a clean
   machine gate is reported through .result, not here. */
.error { color: var(--mark-ink); font-weight: 600; }

.result {
  font-family: var(--mono);
  font-size: 0.75rem;
  padding: var(--sm) var(--md);
  border-left: 2px solid var(--ink);
  background: var(--paper-lit);
  margin: var(--md) 0;
}
.result.ok { border-left-color: var(--ink); }
.result.error { border-left-color: var(--mark-ink); color: var(--mark-ink); }

.status {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px var(--xs);
  border: 1px solid currentColor;
}

/* An empty queue is a real answer, so it is printed like one rather than left looking
   like a view that failed to load. */
.empty { padding: var(--lg) 0; border-top: 1px solid var(--rule); }
.empty-mark {
  display: block;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mark-ink);
  margin-bottom: var(--xs);
}

/* --------------------------------------------------------------------------
   Reason dialog
   -------------------------------------------------------------------------- */

/* Replaces three window.prompt() calls. Those are rounded chrome from another world,
   they state none of the consequence, they cannot hold a labelled field or a fixed list
   of enum values, and in some embedding contexts they are suppressed outright —
   returning null so the action silently does nothing, which is the one refusal this
   console may never make. */
dialog#reason-dialog {
  padding: 0;
  border: 1px solid var(--ink);
  background: var(--paper-lit);
  color: var(--ink);
  max-width: 30rem;
  width: calc(100vw - var(--lg));
}
dialog#reason-dialog::backdrop { background: rgb(11 13 10 / 0.55); }
dialog#reason-dialog .dialog-body { padding: var(--md); }
dialog#reason-dialog h2 { margin-bottom: var(--xs); }
dialog#reason-dialog .dialog-actions {
  display: flex;
  gap: var(--sm);
  justify-content: flex-end;
  padding: var(--md);
  border-top: 1px solid var(--rule);
}

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

/* The system's breakpoints are 900 and 420. The old 46rem here was invented. */
@media (min-width: 900px) {
  .cols { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  /* The nav takes its own full-width row rather than competing with the wordmark and
     the identity for what is left of a phone's width. */
  .bar { row-gap: var(--sm); }
  .bar strong { order: 1; }
  .spacer { order: 2; }
  #whoami { order: 3; text-align: right; }
  #signout { order: 4; }
  .bar nav {
    order: 5;
    flex: 1 0 100%;
    /* Full bleed to the bar's edges: pull out by exactly the bar's padding and put it
       back as the nav's own, so the row is 100% wide and not 100% plus two paddings. */
    margin: 0 calc(var(--bar-pad) * -1);
    padding: 0 var(--bar-pad);
    border-top: 1px solid var(--rule);
  }
  .bar nav .tab { flex: 1 1 auto; }

  .controls select, .controls button { flex: 1 1 auto; }
  .actions { justify-items: stretch; }
  .actions button { width: 100%; }
}

@media (max-width: 420px) {
  main { padding: var(--sm); }
  .bar { --bar-pad: var(--sm); }
  h1 { font-size: 1.375rem; }
  td, th { padding: var(--xs) var(--sm); }
}

/* ---------------------------------------------------------------------------
   The eight steps.

   Three states, never two. A step not required for this class reads
   `skipped — not required for this class`, because that is a different fact from
   a step nobody has done yet, and the difference matters when the job is read back
   months later.
   --------------------------------------------------------------------------- */

.steps {
  list-style: none;
  margin: var(--md) 0 var(--lg);
  padding: 0;
  border: 1px solid var(--rule);
  background: var(--paper-lit);
}
.step {
  display: grid;
  grid-template-columns: 2.25rem 8rem minmax(0, 1fr);
  align-items: baseline;
  gap: var(--sm);
  padding: var(--sm) var(--md);
  border-bottom: 1px solid var(--rule);
}
.step:last-child { border-bottom: 0; }

.step-n {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-secondary);
  font-variant-numeric: tabular-nums;
}
.step-name { font-size: 0.9375rem; }
.step-word {
  grid-column: 3;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.step-detail {
  grid-column: 3;
  font-size: 0.8125rem;
  color: var(--ink-secondary);
  line-height: 1.45;
}

/* Complete carries the ink rule; open carries nothing; skipped is stated in words
   and is deliberately not dimmed — state is never expressed by opacity alone. */
.step-complete { border-left: 3px solid var(--ink); }
.step-complete .step-word { color: var(--ink); }
.step-open { border-left: 3px solid var(--rule); }
.step-open .step-word { color: var(--mark-ink); }
.step-skipped { border-left: 3px solid transparent; background: var(--paper-sunk); }
.step-skipped .step-word,
.step-skipped .step-name { color: var(--ink-secondary); }

/* ---------------------------------------------------------------------------
   The machine gate.

   Its own plate, because it is the hardest rule in the product: deterministic, and
   with no override at any role. Stating that plainly is what stops somebody going
   looking for the override button.
   --------------------------------------------------------------------------- */

.gate-panel {
  border: 1px solid var(--ink);
  box-shadow: 3px 3px 0 0 var(--ink);
  background: var(--paper-lit);
  padding: var(--md);
  margin: 0 3px var(--lg) 0;
}
.gate-word {
  margin: 0 0 var(--xs);
  font-family: var(--mono);
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  font-weight: 700;
}
.gate-passed { color: var(--ink); }
.gate-failed { color: var(--mark); }
.gate-not-run { color: var(--ink-secondary); }

.gate-said { margin: 0 0 var(--sm); font-size: 0.9375rem; }
.gate-rule {
  margin: 0 0 var(--md);
  padding-left: var(--sm);
  border-left: 2px solid var(--ink);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-secondary);
  max-width: 68ch;
}
.gate-peer {
  margin: var(--md) 0 0;
  padding-top: var(--sm);
  border-top: 1px solid var(--rule);
  font-size: 0.875rem;
  line-height: 1.5;
  max-width: 68ch;
}

@media (max-width: 40rem) {
  .step { grid-template-columns: 2rem minmax(0, 1fr); }
  .step-word, .step-detail { grid-column: 2; }
  .gate-word { font-size: 1.25rem; }
}

/* ---------------------------------------------------------------------------
   Findings.

   Every one names its rule, its gap and its remedy. The schema makes all three
   NOT NULL because a finding that names a problem without naming the remedy sends
   a compiler hunting, and at three jobs a day that is the difference between a gate
   that gets used and one that gets skipped.
   --------------------------------------------------------------------------- */

.findings { margin-top: var(--md); border-top: 1px solid var(--rule); }
.finding {
  border-bottom: 1px solid var(--rule);
  padding: var(--sm) 0 var(--sm) var(--sm);
  border-left: 3px solid var(--rule);
}
.finding-fatal { border-left-color: var(--mark-ink); }

.finding-head {
  margin: 0 0 var(--xs);
  display: flex;
  gap: var(--sm);
  align-items: baseline;
  flex-wrap: wrap;
}
.finding-sev {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  font-weight: 700;
}
.finding-fatal .finding-sev { color: var(--mark-ink); }
.finding-gate {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.08em;
  color: var(--ink-secondary);
}
.finding-rule { margin: 0 0 var(--xs); font-size: 0.9375rem; line-height: 1.45; }
.finding-line {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-secondary);
  max-width: 72ch;
}
.finding-remedy { color: var(--ink); }

.findings-none,
.findings-failed {
  margin: var(--sm) 0 0;
  font-size: 0.875rem;
  color: var(--ink-secondary);
  max-width: 68ch;
}

/* ==========================================================================
   The console grew from two screens to forty.
   ==========================================================================

   Everything below serves views that did not exist when the file above was
   written: the client record, the eight wizard steps, the practice reports and
   the governance registers. The rules the file already held still hold — square
   corners without exception, hairline rules and tonal layering rather than
   shadows, mono reserved for values that are measured, cited or legally
   identified, and never colour as the only carrier of meaning.

   The one shape genuinely new here is the tab, which is now a link rather than a
   button. Every view has a URL, so the nav is anchors and the current item is
   marked with `aria-current` — which is what a screen reader announces as the
   current page, where `aria-selected` on an anchor announces nothing at all.
   -------------------------------------------------------------------------- */

a { color: var(--ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-color: var(--mark-ink); }

a.tab,
a.link {
  display: inline-flex;
  align-items: center;
  gap: var(--xs);
  text-decoration: none;
}

a.tab {
  padding: var(--xs) var(--sm);
  min-height: 34px;
  border: 1px solid transparent;
  border-bottom: 2px solid transparent;
  color: var(--ink-secondary);
  font-weight: 600;
  font-size: 0.8125rem;
}
a.tab:hover { background: var(--paper-sunk); color: var(--ink); }
a.tab[aria-current] {
  color: var(--ink);
  border-bottom-color: var(--mark-ink);
  background: var(--paper);
}

/* The count on a nav item. A badge that reads zero is noise, so the shell omits
   it entirely rather than rendering a nought. */
.tab-count {
  font-family: var(--mono);
  font-size: 0.625rem;
  padding: 0 4px;
  background: var(--ink);
  color: var(--paper-lit);
}

.bar nav { display: flex; gap: var(--xs); flex-wrap: wrap; }
.bar-search { display: flex; }
.bar-search input { width: 12rem; margin: 0; }

/* A second row of tabs, inside a view. Same grammar as the header's, one step
   quieter, because two rows of equally loud tabs is a screen with no hierarchy. */
.subnav {
  display: flex;
  gap: var(--xs);
  flex-wrap: wrap;
  margin: var(--md) 0;
  padding-bottom: var(--xs);
  border-bottom: 1px solid var(--rule);
}

.crumbs { display: flex; gap: var(--md); margin-bottom: var(--sm); }

/* --------------------------------------------------------------------------
   Panels, blocks and facts
   -------------------------------------------------------------------------- */

.panel, .block {
  margin: 0 0 var(--lg);
  padding-top: var(--md);
  border-top: 1px solid var(--rule);
}
.panel > h3, .block > h3 { display: flex; align-items: baseline; gap: var(--sm); }

/* The count beside a block heading is read from the rows below it, never from a
   separate query — a tile that disagrees with the list under it is worse than no
   tile. */
.count {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-secondary);
}

.facts {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  gap: var(--xs) var(--md);
  margin: 0 0 var(--md);
  font-size: 0.875rem;
}
.facts dt { color: var(--ink-secondary); }
.facts dd { margin: 0; }
/* Values that are measured, cited or legally identified. Not prose. */
.facts dd { font-family: var(--mono); font-size: 0.8125rem; }

ul.plain, ol.plain { margin: 0 0 var(--md); padding-left: var(--md); }
ul.plain { list-style: square; }
ul.plain li, ol.plain li { margin-bottom: var(--xs); line-height: 1.5; }

.row { display: flex; flex-wrap: wrap; gap: var(--sm); align-items: center; }
.actions.row { display: flex; }

fieldset {
  border: 1px solid var(--rule);
  padding: var(--md);
  margin: 0 0 var(--md);
}
legend { font-weight: 700; padding: 0 var(--xs); }

.field { margin-bottom: var(--md); }
.field .muted { margin-top: var(--xs); }
form.wide { max-width: 48rem; }

/* --------------------------------------------------------------------------
   Cards — the triage board and the narrative sections
   -------------------------------------------------------------------------- */

.cards { display: grid; gap: var(--md); }
@media (min-width: 60rem) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.card {
  border: 1px solid var(--rule);
  background: var(--paper-lit);
  padding: var(--md);
}
.card h3 { margin-bottom: var(--xs); }
.card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sm);
  align-items: center;
  margin-top: var(--md);
  padding-top: var(--sm);
  border-top: 1px solid var(--rule);
}

/* The verdict, in words. 🟢🟡🔴 is a colour-only vocabulary and this console does
   not have one: the word is the carrier, the colour is the second channel. */
.verdict-head { display: flex; align-items: baseline; gap: var(--sm); flex-wrap: wrap; }
.verdict-word {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 0.875rem;
  letter-spacing: 0.08em;
}
.verdict-proceed, .verdict-eligible { color: var(--ink); }
.verdict-proceed_with_gaps, .verdict-eligible_with_gaps { color: var(--pula-deep); }
.verdict-decline, .verdict-not_eligible { color: var(--mark-ink); }
.verdict-none { color: var(--ink-secondary); }
.verdict-when { font-family: var(--mono); font-size: 0.625rem; color: var(--ink-secondary); }
.verdict-reasons { margin-top: var(--sm); }

/* --------------------------------------------------------------------------
   The step rail, now that each step is a link
   -------------------------------------------------------------------------- */

.step-link {
  display: grid;
  grid-template-columns: 2rem 10rem 12rem 1fr;
  gap: var(--sm);
  align-items: baseline;
  text-decoration: none;
  padding: var(--xs) 0;
}
.step-link:hover { background: var(--paper-sunk); }
.step-link[aria-current] { background: var(--paper-sunk); outline: 1px solid var(--ink); }
@media (max-width: 48rem) {
  .step-link { grid-template-columns: 2rem 1fr; }
  .step-link .step-detail { grid-column: 2; }
}

.step-body, .tab-body { margin-top: var(--lg); }

/* --------------------------------------------------------------------------
   Step 1 — extracted values beside their evidence
   -------------------------------------------------------------------------- */

.evidence {
  font-family: var(--display);
  font-size: 0.8125rem;
  color: var(--ink-secondary);
  quotes: '“' '”';
}
.extraction-detail { margin-top: var(--lg); }

/* --------------------------------------------------------------------------
   Step 4 — sections, claims and the binding tray
   -------------------------------------------------------------------------- */

.sections { display: grid; gap: var(--lg); }
.section-card .criterion {
  margin: 0 0 var(--md);
  padding-left: var(--md);
  border-left: 2px solid var(--rule);
  font-size: 0.875rem;
  color: var(--ink-secondary);
}

.tray {
  margin: var(--md) 0;
  padding: var(--sm) var(--md);
  background: var(--paper);
  border: 1px solid var(--rule);
}
.tray h4 { margin: 0 0 var(--xs); font-size: 0.8125rem; }

.claims { list-style: none; margin: 0 0 var(--sm); padding: 0; }
.claim {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sm);
  align-items: center;
  padding: var(--xs) 0;
  border-top: 1px solid var(--rule);
}
.claim .state {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  min-width: 4.5rem;
}
/* An unbound claim is a block, not a warning: generation is refused while one
   exists, so it is marked the way a refusal is. */
.claim-unbound .state { color: var(--mark-ink); }
.claim-unbound { border-left: 2px solid var(--mark-ink); padding-left: var(--sm); }
.claim-text { flex: 1 1 20rem; font-size: 0.875rem; }
.claim select { width: auto; max-width: 22rem; margin: 0; }

/* Generated prose, shown as written. `pre` because a bid section's paragraphing
   is part of what a compiler is reviewing. */
.prose-body, .sheet {
  font-family: var(--display);
  font-size: 0.875rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0 0 var(--md);
  padding: var(--md);
  background: var(--paper-lit);
  border-left: 2px solid var(--rule);
  max-width: 72ch;
}
.sheet { font-family: var(--mono); font-size: 0.75rem; }
.tells { margin-top: var(--sm); }

/* --------------------------------------------------------------------------
   Step 6 — declarations
   -------------------------------------------------------------------------- */

.declarations { list-style: none; margin: 0; padding: 0; }
.declaration {
  padding: var(--md) 0;
  border-top: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  padding-left: var(--md);
}
.declaration.unpaired { border-left-color: var(--mark-ink); }
.declaration-head { display: flex; gap: var(--sm); align-items: baseline; flex-wrap: wrap; }
.declaration-head .state {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.declaration.unpaired .state { color: var(--mark-ink); }

/* --------------------------------------------------------------------------
   The capacity planner grid
   -------------------------------------------------------------------------- */

.cell-edit {
  width: 100%;
  justify-content: flex-start;
  border: 1px solid transparent;
  background: none;
  font-family: var(--mono);
  font-size: 0.75rem;
}
.cell-edit:hover { border-color: var(--ink); background: var(--paper-lit); }

/* --------------------------------------------------------------------------
   Flash — the one-line result at the top of a view
   -------------------------------------------------------------------------- */

.flash { margin-top: 0; }

/* --------------------------------------------------------------------------
   The dialog, now that it holds arbitrary forms
   -------------------------------------------------------------------------- */

dialog#form-dialog {
  border: 1px solid var(--ink);
  background: var(--paper-lit);
  color: var(--ink);
  padding: 0;
  width: min(44rem, calc(100vw - 2rem));
  max-height: calc(100vh - 4rem);
}
dialog#form-dialog::backdrop { background: rgb(11 13 10 / 0.55); }
dialog#form-dialog form { display: flex; flex-direction: column; max-height: inherit; }
dialog#form-dialog .dialog-body { padding: var(--md); overflow-y: auto; }
dialog#form-dialog h2 { margin-bottom: var(--xs); }
dialog#form-dialog textarea { min-height: 6rem; font-family: var(--display); }
dialog#form-dialog .dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--sm);
  padding: var(--sm) var(--md);
  border-top: 1px solid var(--rule);
  background: var(--paper);
}
dialog#form-dialog #form-error { margin: 0 var(--md) var(--sm); }

/* --------------------------------------------------------------------------
   Tables that are read rather than worked
   -------------------------------------------------------------------------- */

/* A table with no row action is not clickable, and the cursor should not claim
   it is. `dom.js` sets this inline for the same reason; the rule is here so a
   hand-written table gets it too. */
table td button.link { padding: 0; }

/* --------------------------------------------------------------------------
   The task drawer
   --------------------------------------------------------------------------

   Anchored to the right rather than centred, because it is opened from the bar
   and glanced at — a centred modal reads as "stop what you are doing", and this
   is the opposite of that. Full height, because the list is the content.
   -------------------------------------------------------------------------- */

dialog#task-drawer {
  border: 1px solid var(--ink);
  border-right: 0;
  background: var(--paper-lit);
  color: var(--ink);
  padding: 0;
  margin: 0 0 0 auto;
  height: 100vh;
  max-height: 100vh;
  width: min(42rem, calc(100vw - 2rem));
}
dialog#task-drawer::backdrop { background: rgb(11 13 10 / 0.45); }
dialog#task-drawer form { display: flex; flex-direction: column; height: 100%; }
dialog#task-drawer .drawer-body { padding: var(--md); overflow-y: auto; flex: 1; }
dialog#task-drawer .dialog-actions {
  display: flex;
  justify-content: flex-end;
  padding: var(--sm) var(--md);
  border-top: 1px solid var(--rule);
  background: var(--paper);
}

.tasks { list-style: none; margin: 0; padding: 0; }
.task {
  display: grid;
  grid-template-columns: 7rem 8rem 1fr;
  gap: var(--xs) var(--sm);
  align-items: baseline;
  padding: var(--sm) 0;
  border-top: 1px solid var(--rule);
}
.task-when { font-family: var(--mono); font-size: 0.6875rem; }
.task-kind {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.task-what { font-size: 0.875rem; }
.task-detail { grid-column: 3; font-size: 0.8125rem; color: var(--ink-secondary); }
.task .muted { grid-column: 3; }

@media (max-width: 40rem) {
  .task { grid-template-columns: 1fr; }
  .task-detail, .task .muted { grid-column: 1; }
}

/* What the machine gate cannot see. A clean gate on inputs step 1 never read is
   not a pass, and this is the only thing on the screen that can say so. */
.blind-spots { margin: var(--md) 0; }
