/*
 * Design tokens. Nothing in this product may introduce a colour, type size or
 * spacing value outside this block — see DESIGN.md.
 *
 * The character to hold: institutional, calm and precise; closer to a well-set
 * statutory report than to consumer software. Every visual device carries
 * information. The one place the design is allowed to be loud is the
 * classification language, because that is the product's voice.
 */
:root {
  /* Base — warm, low-glare, closer to paper than to a screen. The cream is
     what a statutory report is printed on; the ink is a near-black green so
     that text and brand belong to the same family rather than arguing. */
  --paper: #f6f3ec;
  --surface: #fffdf8;
  --ink: #15211c;
  --ink-2: #55605a;
  /* Paragraph text: darker than --ink-2, lighter than --ink. Long prose set at
     full --ink on a cream ground reads as heavy; this is the running text. */
  --ink-soft: #333f39;
  --line: #ddd6c6;

  /* Brand — interactive elements and the app frame only. Never status. */
  --brand: #1c4a38;
  --brand-ink: #ffffff;
  /* The dark ground: panels and footers that need to sit under the brand
     rather than beside it. White on it measures 15.7:1. */
  --deep: #12271f;

  /* The accent. Eyebrows, numerals and one call to action on the landing page,
     and nothing in the app: a warm accent beside --attention would be two
     oranges meaning different things. Held here rather than in landing.css
     because it is a brand colour, and the rule is that those live in one
     place. */
  --accent: #a8431f;
  --accent-ink: #8a3516;

  /* The landing page's extended palette.
     DESIGN.md allows exactly one surface its own bands — the public page at
     `/`, which has to hold somebody's attention rather than hold a register —
     and this is that palette. It lives here rather than in landing.css so the
     rule that colours are declared in one place survives the exception, and so
     tests/unit/design/contrast.spec.ts can measure it.
     Every pairing below is asserted there. */
  --sage: #e4ece3;
  --sage-line: #c9d6c9;

  /* The text ramp for --deep and --brand grounds, lightest first. */
  --on-deep: #e9efe9;
  --on-deep-2: #d5e0d7;
  --on-deep-3: #c4d2c8;
  --on-deep-4: #a9bdb1;
  --on-deep-line: #3b5a4c;
  --on-brand-line: #5e8472;
  /* The accent, lightened until it reads on a dark ground. */
  --on-deep-accent: #f0b48e;

  /* The same, for the accent ground. --accent-deep is the label on a cream
     button sitting on it, where --accent itself would be too light. */
  --on-accent: #ffe3d2;
  --on-accent-2: #ffede2;
  --on-accent-line: #d98b66;
  --accent-deep: #7a2e12;

  /* The unselected half of a segmented control: --paper is the page, so the
     track has to sit a shade below it to read as a well. */
  --track: #ece7db;

  /* The operator console's frame. A second brand rather than a second palette:
     the console swaps these in for --brand so every badge, button and link
     follows without being restyled. Slate so that a screenshot of an operator
     screen can never be mistaken for one of a firm's register.
     SUPERADMIN.md, principle 4 — and the warm repaint served that principle
     rather than threatening it: the console's cool grey ground is now dE 4.8
     from the firm's cream, where it was 2.1 from the old near-white. */
  --slate: #3d4a5c;
  --slate-rail: #2c3542;
  --slate-paper: #f4f5f7;

  /* Semantic — these ARE the product. Used for nothing else.

     --clear moved from #1e6e3c when the base palette went warm: the brand had
     become #1c4a38, and a "signed off" badge that reads as the frame colour
     breaks the one rule this block exists to hold — the brand is never status.
     #2e6b2e is a leafier, yellower green, dE 28 from the brand rather than 25,
     and it clears AA with more margin than the colour it replaces.

     --attention keeps the value DESIGN.md argued it up to. On the warm ground
     it measures 4.99:1 on its own tint over --surface and 4.59:1 over --paper;
     still the tightest pairing in the system, and still above the floor.
     Verified by tests/unit/design/contrast.spec.ts. */
  --material: #8c1d2f;
  --attention: #985000;
  --clear: #2e6b2e;
  /* Deliberately the same value as --ink-2: grey means "no answer yet", and it
     is the absence of a classification rather than one of them. */
  --unassessed: #55605a;

  /* Type scale */
  --t-dense: 13px;
  --t-body: 14px;
  --t-section: 16px;
  --t-page: 20px;
  --t-figure: 28px;

  /* Space */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  --radius: 4px;
  --rail: 240px;
  --row: 40px;
  --prose: 70ch;
  --form: 560px;

  /* The one shadow in the system: overlays and menus. */
  --shadow: 0 4px 16px rgba(26, 35, 48, 0.12);
  --motion: 140ms;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: var(--t-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* This product is mostly numbers, dates and dense tables. Figures align. */
td,
th,
.figure,
.num,
.mono,
time {
  font-variant-numeric: tabular-nums;
}

.mono {
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: 0.95em;
  /* An arrangement reference is one token; it must not break across lines. */
  white-space: nowrap;
}

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

/* Sentence case everywhere. No all-caps labels, no letter-spaced eyebrows. */
h1,
h2,
h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: 0;
}
h1 {
  font-size: var(--t-page);
}
h2 {
  font-size: var(--t-section);
}
h3 {
  font-size: var(--t-body);
}

p {
  margin: 0 0 var(--s-3);
  max-width: var(--prose);
}
p:last-child {
  margin-bottom: 0;
}

/* Visible keyboard focus on everything interactive.
   `summary` is in this list because a disclosure is operated with the keyboard
   like a button but is none of the element types above — which is exactly how
   it gets left out and how the rule reference and the account-closure control
   end up with no focus ring. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
  border-radius: var(--radius);
}

/* Transitions only on user action. */
@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

/* ------------------------------------------------------------------ shell */
.shell {
  display: grid;
  grid-template-columns: var(--rail) 1fr;
  min-height: 100vh;
  min-width: 1280px;
}

.rail {
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: var(--s-5) 0;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.rail-brand {
  padding: 0 var(--s-5) var(--s-5);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--s-4);
}
.rail-brand strong {
  display: block;
  font-size: var(--t-body);
  font-weight: 600;
  color: var(--brand);
}
.rail-brand span {
  display: block;
  font-size: var(--t-dense);
  color: var(--ink-2);
}

.rail nav {
  display: flex;
  flex-direction: column;
}
/* Current section marked with a 3px brand bar, not a filled pill. */
.rail nav a {
  color: var(--ink);
  padding: var(--s-2) var(--s-5);
  border-left: 3px solid transparent;
  font-weight: 500;
  transition: color var(--motion) ease;
}
.rail nav a:hover {
  background: var(--paper);
  text-decoration: none;
}
.rail nav a[aria-current='page'] {
  border-left-color: var(--brand);
  color: var(--brand);
}

.rail-foot {
  margin-top: auto;
  padding: var(--s-4) var(--s-5) 0;
  border-top: 1px solid var(--line);
  font-size: var(--t-dense);
  color: var(--ink-2);
}
.rail-foot strong {
  display: block;
  color: var(--ink);
  font-size: var(--t-body);
  font-weight: 500;
}

.main {
  padding: var(--s-6) var(--s-6) var(--s-7);
  max-width: 1440px;
}

/* ------------------------------------------------------------- page title */
/* Title left, one primary action right, then content. */
.page-title {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}
.page-title .lede {
  color: var(--ink-2);
  margin-top: var(--s-1);
}

/* ----------------------------------------------------------------- panels */
/* Separated by space and a single rule, not boxed into cards. */
.panel {
  /* Always spaced. `:first-of-type` matched on element type rather than class,
     so a panel following a two-column block lost its separation entirely. */
  margin-top: var(--s-6);
}
.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--s-3);
}
.panel-note {
  color: var(--ink-2);
  font-size: var(--t-dense);
  max-width: var(--prose);
}

.columns {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: 1fr 1fr;
  align-items: start;
}

/* ---------------------------------------------------------------- figures */
.figures {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5);
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s-5);
}
.figure .value {
  font-size: var(--t-figure);
  font-weight: 600;
  line-height: 1.2;
}
.figure .label {
  font-size: var(--t-dense);
  color: var(--ink-2);
  font-weight: 500;
}
.figure .note {
  font-size: var(--t-dense);
  color: var(--ink-2);
  margin-top: var(--s-1);
  max-width: 28ch;
}
.figure.material .value {
  color: var(--material);
}

.meter {
  height: 6px;
  background: var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: var(--s-2);
}
.meter > span {
  display: block;
  height: 100%;
  background: var(--brand);
}

/* ----------------------------------------------------------------- tables */
/* Full width, 40px rows, hairline separators, no zebra, no card-per-row. */
table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  font-size: var(--t-dense);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
th {
  text-align: left;
  font-size: var(--t-dense);
  font-weight: 500;
  color: var(--ink-2);
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td {
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  height: var(--row);
}
tbody tr:last-child td {
  border-bottom: none;
}
tbody tr:hover {
  background: var(--paper);
}
td.num,
th.num {
  text-align: right;
}
.cell-note {
  color: var(--ink-2);
  margin-top: 2px;
}

/* ---------------------------------------------------- classification badge */
/*
 * The signature component. Same shape, same wording, everywhere a
 * classification appears — tables, detail headers, dashboard, exports.
 * Tinted fill at 12% of its semantic colour, full-strength text.
 */
.badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: var(--radius);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--tone, var(--unassessed));
  background: color-mix(in srgb, var(--tone, var(--unassessed)) 12%, var(--surface));
}
.badge.material {
  --tone: var(--material);
}
.badge.attention {
  --tone: var(--attention);
}
.badge.clear {
  --tone: var(--clear);
}
.badge.unassessed {
  --tone: var(--unassessed);
}
.badge-row {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- notices */
/* Semantic colour as a left border accent and text, never a large wash. */
.notice {
  border-left: 3px solid var(--tone, var(--ink-2));
  background: var(--surface);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  font-size: var(--t-dense);
  max-width: var(--prose);
}
.notice strong {
  display: block;
  color: var(--tone, var(--ink));
  font-weight: 600;
  margin-bottom: 2px;
}
.notice.material {
  --tone: var(--material);
}
.notice.attention {
  --tone: var(--attention);
}
.notice.clear {
  --tone: var(--clear);
}
.notice.info {
  --tone: var(--brand);
}

.empty {
  padding: var(--s-6) 0;
  color: var(--ink-2);
  max-width: var(--prose);
}
.empty strong {
  display: block;
  color: var(--ink);
  font-weight: 500;
  margin-bottom: var(--s-1);
}

/* ---------------------------------------------------------------- settings */
/* Sub-navigation for a section that is six pages rather than one. Kept out of
   the left rail so the everyday work is not read past six times a day. */
.subnav {
  display: flex;
  gap: var(--s-4);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--s-5);
}
.subnav a {
  display: block;
  padding: var(--s-3) 0;
  margin-bottom: -1px;
  color: var(--ink-2);
  text-decoration: none;
  font-size: var(--t-body);
  border-bottom: 2px solid transparent;
}
.subnav a:hover {
  color: var(--ink);
}
.subnav a[aria-current='page'] {
  color: var(--ink);
  font-weight: 500;
  border-bottom-color: var(--brand);
}

/* A credential, shown once. Monospaced and selectable on sight: somebody is
   about to copy this into another system and a wrapped character costs them an
   afternoon. */
.secret {
  display: block;
  user-select: all;
  word-break: break-all;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s-3);
  margin: var(--s-3) 0;
  font-size: var(--t-dense);
}

/* Two controls in a row that belong to different forms. */
.inline-form {
  display: flex;
  gap: var(--s-2);
  align-items: center;
}
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  align-items: flex-start;
}

/* A checkbox with its own explanation, for lists of choices in a form. */
.choice-line {
  display: flex;
  gap: var(--s-2);
  align-items: flex-start;
  padding: var(--s-2) 0;
  font-size: var(--t-body);
  max-width: var(--prose);
}
.choice-line .help {
  display: block;
  margin-top: 2px;
}

/* Irreversible actions sit behind a disclosure, never adjacent to routine ones
   (DESIGN.md). The red is the semantic --material, which is the only red in the
   system and already means "this is the serious one". */
.danger {
  border: 1px solid var(--line);
  border-left: 3px solid var(--material);
  border-radius: var(--radius);
  padding: var(--s-3) var(--s-4);
  max-width: var(--form);
}
.danger > summary {
  cursor: pointer;
  color: var(--material);
  font-weight: 500;
  font-size: var(--t-body);
}
.danger[open] > summary {
  margin-bottom: var(--s-4);
}
.button.danger,
button.danger {
  border-color: var(--material);
  color: var(--material);
  background: var(--surface);
}
.button.danger:hover:not(:disabled),
button.danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--material) 8%, var(--surface));
}

/* A meter that reads as neutral until it is not. */
.meter.attention > span {
  background: var(--attention);
}
.meter.material > span {
  background: var(--material);
}
.figure-note {
  margin: var(--s-2) 0 0;
  font-size: var(--t-dense);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* Present to a screen reader, absent on the page: labels for controls whose
   meaning is obvious in context but not in a list of form fields. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------- first run */
/* The three steps a firm walks on its first day. Numbered because the order is
   real — you cannot map an arrangement to a business service you have not
   defined — and ticked off rather than removed, so progress is visible. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--prose);
}
.steps li {
  display: flex;
  gap: var(--s-4);
  padding: var(--s-4) 0;
  border-top: 1px solid var(--line);
}
.steps li:first-child {
  border-top: 0;
}
.steps h3 {
  margin: 0 0 var(--s-1);
  font-size: var(--t-body);
  font-weight: 600;
}
.steps p {
  margin: 0 0 var(--s-2);
  color: var(--ink-2);
  font-size: var(--t-body);
}
.steps .marker {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  font-size: var(--t-dense);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.steps li.done .marker {
  border-color: var(--clear);
  color: var(--clear);
}
.steps li.done h3 {
  color: var(--ink-2);
  font-weight: 500;
}
.steps li.next .marker {
  border-color: var(--brand);
  color: var(--brand);
  font-weight: 600;
}

/* ------------------------------------------------------------ the editor */
/* Two columns: the definition and the form it produces. Side by side rather
   than tabbed, because the whole justification for a JSON editor is that
   somebody can see the consequence of what they typed without leaving it. */
.editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-5);
  margin-bottom: var(--s-6);
}
@media (max-width: 1100px) {
  .editor {
    grid-template-columns: minmax(0, 1fr);
  }
}
.editor-pane {
  min-width: 0;
}
.editor-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-2);
  margin-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
}
.editor-head h2 {
  margin: 0;
  font-size: var(--t-section);
}
.editor-state {
  font-size: var(--t-dense);
  color: var(--ink-2);
}

/* A code field, not a prose field: tabular figures, no ligatures, and enough
   room that a section is visible at once. */
textarea.code {
  width: 100%;
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: var(--t-dense);
  line-height: 1.5;
  tab-size: 2;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  resize: vertical;
  min-height: 420px;
}

/* --------------------------------------------------------------- preview */
/* The questionnaire as the person answering sees it, with the rules that
   govern each question shown beneath rather than hidden in the JSON. */
.preview {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--s-4);
  max-height: 720px;
  overflow-y: auto;
}
.preview-head h3 {
  margin: 0 0 var(--s-1);
  font-size: var(--t-section);
}
.preview-head p {
  margin: 0 0 var(--s-3);
  color: var(--ink-2);
  font-size: var(--t-body);
  max-width: var(--prose);
}
.preview-section {
  border-top: 1px solid var(--line);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
}
.preview-section h4 {
  margin: 0 0 var(--s-2);
  font-size: var(--t-body);
  font-weight: 600;
}
.preview-question {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--paper);
  max-width: var(--prose);
}
.preview-prompt {
  font-size: var(--t-body);
  margin-bottom: var(--s-1);
}
.preview-options {
  list-style: none;
  margin: var(--s-2) 0 0;
  padding: 0;
  font-size: var(--t-dense);
}
.preview-options li {
  padding: 2px 0;
  color: var(--ink-2);
}
.preview-marker {
  display: inline-block;
  width: 18px;
  color: var(--line);
}
.preview-value {
  margin-left: var(--s-2);
  font-size: 12px;
  color: var(--ink-2);
  font-family: var(--font-mono), ui-monospace, monospace;
}
.preview-box {
  margin-top: var(--s-2);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: var(--s-2) var(--s-3);
  color: var(--ink-2);
  font-size: var(--t-dense);
}
.preview-box.tall {
  padding-bottom: var(--s-5);
}
.preview-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
  margin-top: var(--s-2);
  font-size: 12px;
  color: var(--ink-2);
}
/* The rules that govern a question: quiet, but present, because a condition
   that never fires is invisible in the JSON and obvious here. */
.preview-rule {
  margin: var(--s-1) 0 0;
  font-size: 12px;
  color: var(--ink-2);
  border-left: 2px solid var(--line);
  padding-left: var(--s-2);
}
.tone-material {
  color: var(--material);
}

/* --------------------------------------------------------------- overlay */
/* The one shadow in the system, and the only overlay: a confirmation that has
   to be read before something irreversible for every future assessment. */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(26, 35, 48, 0.4);
  display: grid;
  place-items: center;
  padding: var(--s-5);
  z-index: 10;
}
.overlay-panel {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--s-5);
  max-width: 560px;
  width: 100%;
}
.overlay-panel h2 {
  margin: 0 0 var(--s-3);
  font-size: var(--t-section);
}
.overlay-panel p {
  margin: 0 0 var(--s-3);
  font-size: var(--t-body);
  color: var(--ink-2);
}

/* --------------------------------------------------------------- controls */
button,
.button {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  padding: 6px 12px;
  border-radius: var(--radius);
  font-size: var(--t-dense);
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition:
    background var(--motion) ease,
    border-color var(--motion) ease;
}
button:hover,
.button:hover {
  background: var(--paper);
  border-color: var(--ink-2);
  text-decoration: none;
}
.button.primary,
button.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
}
/* Derived from the brand token rather than picked by eye: DESIGN.md allows one
   authority colour, and a second hex here is a second colour whether or not it
   was chosen to look like the first. */
.button.primary:hover,
button.primary:hover {
  background: color-mix(in srgb, var(--brand) 86%, #000);
  border-color: color-mix(in srgb, var(--brand) 86%, #000);
}
button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.actions {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  flex-wrap: wrap;
}
/* Irreversible actions are set apart from routine ones. */
.actions-deliberate {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

label {
  display: block;
  font-weight: 500;
  margin-bottom: var(--s-1);
}
input[type='text'],
input[type='search'],
input[type='date'],
select,
textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 10px;
  font-family: inherit;
  font-size: var(--t-dense);
  background: var(--surface);
  color: var(--ink);
}
textarea {
  min-height: 88px;
  resize: vertical;
  line-height: 1.5;
}
.field {
  margin-bottom: var(--s-4);
  max-width: var(--form);
}
.field .help {
  color: var(--ink-2);
  font-weight: 400;
  font-size: var(--t-dense);
  margin-top: var(--s-1);
  max-width: var(--prose);
}
/* Forms and questionnaires are a single column. */
.form {
  max-width: var(--form);
}

.filters {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: var(--s-4);
}
.filters .field {
  margin: 0;
  min-width: 170px;
  max-width: 220px;
}

/* ------------------------------------------------------------ definitions */
.defs {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--s-2) var(--s-5);
  font-size: var(--t-dense);
  margin: 0;
}
.defs dt {
  color: var(--ink-2);
}
.defs dd {
  margin: 0;
}

/* ------------------------------------------------------------------ cites */
/* Present, not shouting. The provision is revealed on hover or focus. */
.cite {
  font-size: var(--t-dense);
  color: var(--ink-2);
  font-style: italic;
}
details.cite-detail summary {
  cursor: pointer;
  list-style: none;
  color: var(--ink-2);
  font-size: var(--t-dense);
  font-style: italic;
}
details.cite-detail summary::-webkit-details-marker {
  display: none;
}
details.cite-detail[open] summary {
  margin-bottom: var(--s-1);
}
details.cite-detail p {
  font-size: var(--t-dense);
  color: var(--ink-2);
  margin: 0;
}

.reasons {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}
.reasons li {
  border-left: 3px solid var(--line);
  padding-left: var(--s-3);
  max-width: var(--prose);
}

/* ---------------------------------------------------------- questionnaire */
.section-title {
  margin-top: var(--s-6);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line);
}
.section-title .guidance {
  color: var(--ink-2);
  font-size: var(--t-dense);
  margin-top: var(--s-1);
  max-width: var(--prose);
}
.question {
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line);
  max-width: var(--form);
}
.question .prompt {
  font-weight: 500;
  margin-bottom: var(--s-1);
}
.question .guidance {
  color: var(--ink-2);
  font-size: var(--t-dense);
  margin-bottom: var(--s-2);
}
.choices {
  display: grid;
  gap: var(--s-1);
}
.choice {
  display: flex;
  gap: var(--s-2);
  align-items: flex-start;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  font-weight: 400;
  margin: 0;
  font-size: var(--t-dense);
  transition: border-color var(--motion) ease;
}
.choice:hover {
  border-color: var(--ink-2);
}
.choice.selected {
  border-color: var(--brand);
}
.choice input {
  margin: 3px 0 0;
  accent-color: var(--brand);
}

/* --------------------------------------------------------------- sign-in */
.signin {
  min-height: 100vh;
  min-width: 0;
  display: grid;
  place-items: center;
  padding: var(--s-6);
  background: var(--paper);
}
.signin-panel {
  width: 100%;
  max-width: 460px;
  background: var(--surface);
  border: 1px solid var(--line);
  padding: var(--s-6);
}
/* The sign-in panel with a QR code in it. A symbol beside its instructions
   needs the width a single column of fields does not, and squeezing it into
   460px would either shrink the code or push the steps under it on a desktop
   screen with room to spare. */
.signin-panel.wide {
  max-width: 680px;
}

/* ---------------------------------------------------------------- brand */

/* Mark and wordmark set as one object. The gap is proportional to the mark,
   so the lockup holds together at any size it is used at. */
.lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  line-height: 1;
}
/* Set against the mark's height rather than its box: the quill is a sparse
   diagonal and reads optically smaller than the square it occupies, so a word
   matched to the box overpowers it. */
.lockup-word {
  font-size: 1.55em;
  font-weight: 600;
  /* The name is set tight; DESIGN.md forbids letter-spaced labels, and a
     wordmark is not a label. */
  letter-spacing: -0.01em;
}
.lockup-console {
  font-size: 1.55em;
  font-weight: 400;
  color: var(--brand-ink);
  opacity: 0.72;
}
/* On a light panel the word takes the console's own frame colour, which is
   what --brand already resolves to inside .console-shell. */
.lockup-console-ink {
  color: var(--brand);
  opacity: 1;
}

/* The parent brand whispers: secondary ink, one step down in size. */
.attribution {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-2);
  font-size: var(--t-dense);
}
.legal-footer {
  margin: 0;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.5;
  max-width: 46ch;
}

/* The sign-in screen's own header block: lockup, then attribution beneath. */
.signin-brand {
  display: grid;
  justify-items: center;
  gap: 10px;
  margin-bottom: var(--s-5);
  text-align: center;
}
/* Fields fill the panel. A 460px card with 180px inputs reads as a form that
   was never looked at. */
.signin-panel .field input,
.signin-panel .field textarea,
.signin-panel .field select {
  width: 100%;
  max-width: none;
}
/* Except the authenticator code, which is six digits and should look like it. */
.signin-panel .field input[inputmode='numeric'] {
  max-width: 180px;
}
.signin-foot {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
  display: grid;
  justify-items: center;
  text-align: center;
}

/* ---------------------------------------------- non-production banner */

/* Fixed, above everything, no dismiss control. An environment you can hide
   the label of is one somebody will mistake for live. --attention at a 12%
   tint, per the badge conventions in DESIGN.md. */
.env-banner {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 5px var(--s-3);
  background: color-mix(in srgb, var(--attention) 12%, var(--surface));
  color: var(--attention);
  font-size: 12px;
  font-weight: 500;
  border-bottom: 1px solid color-mix(in srgb, var(--attention) 28%, var(--surface));
}
.env-banner-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.account {
  display: flex;
  width: 100%;
  text-align: left;
  gap: var(--s-3);
  align-items: center;
  justify-content: space-between;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--t-dense);
}
.account:hover {
  border-color: var(--brand);
}
.account .who strong {
  display: block;
  font-weight: 500;
}
.account .who span {
  color: var(--ink-2);
}

/* ------------------------------------------------------------------ print */
/* Compliance people print things for board packs. */
@media print {
  /* Everything that is a control rather than a fact. A board pack is read on
     paper by people who cannot click any of it, and a printed page full of
     dead buttons reads as a screenshot rather than a document. */
  .rail,
  .actions,
  .filters,
  .subnav,
  .danger,
  form {
    display: none !important;
  }
  /* Steps are guidance for somebody using the product, not part of the record. */
  .steps {
    display: none !important;
  }
  /* Semantic colour survives printing, because the badge carries meaning that
     the surrounding text does not repeat. A greyscale printer still gets the
     word, which is why the badge has always had one. */
  .badge {
    border: 1px solid currentColor;
    background: none !important;
  }
  /* A disclosure the reader cannot open must print open. */
  details {
    display: block;
  }
  details > summary {
    list-style: none;
  }
  .shell {
    display: block;
    min-width: 0;
  }
  .main {
    padding: 0;
    max-width: none;
  }
  body {
    background: var(--surface);
    font-size: 11px;
  }
  table {
    page-break-inside: auto;
  }
  tr {
    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  a {
    color: var(--ink);
    text-decoration: none;
  }
  .panel {
    page-break-inside: avoid;
  }
  /* Where a link points is information on paper, and the reader cannot hover to
     find out. Only for real destinations: an in-page anchor prints as noise. */
  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 9px;
    color: var(--ink-2);
  }
}

/* The register details form: twenty template fields, filled in once a year.
   Two columns on a wide screen so the whole set is visible at once — a form
   this long in one column is one somebody loses their place in. */
.register-details > summary {
  cursor: pointer;
  font-weight: 500;
  color: var(--brand);
}
.register-details[open] > summary {
  margin-bottom: var(--s-4);
}
.register-details form {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
}
.register-details label {
  margin-bottom: 0;
}
.register-details input[type='number'] {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 10px;
  font-family: inherit;
  font-size: var(--t-dense);
  background: var(--surface);
  color: var(--ink);
}
.register-details select[multiple] {
  height: auto;
}
.register-details .actions {
  grid-column: 1 / -1;
}
.register-details .notice {
  grid-column: 1 / -1;
}
@media (min-width: 900px) {
  .register-details form {
    grid-template-columns: 1fr 1fr;
  }
}

/* Evidence sits with the answer it supports, not in a drawer at the bottom:
   the claim and the certificate are one thing, and a firm that files them
   apart cannot say later which claim a document supported. */
.evidence {
  margin-top: var(--s-3);
  padding: var(--s-3);
  border: 1px solid var(--line);
  border-left: 3px solid var(--attention);
  border-radius: var(--radius);
  background: var(--paper);
}
.evidence-head:empty {
  display: none;
}
.evidence-list {
  list-style: none;
  margin: var(--s-2) 0 0;
  padding: 0;
}
.evidence-list li {
  display: flex;
  gap: var(--s-3);
  align-items: baseline;
  padding: 2px 0;
}
.evidence-upload {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
  margin-top: var(--s-2);
}
.evidence-upload select,
.evidence-upload input[type='date'] {
  width: auto;
  min-width: 160px;
}
button.link {
  border: 0;
  background: none;
  padding: 0;
  color: var(--brand);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

/* The console frame.
   Slate where the product is green, so a screenshot of an operator screen can
   never be mistaken for a screenshot of somebody's register. The palette is
   swapped at the root of the console rather than restyled component by
   component, so every badge, button and link follows without being told. */
.console-shell {
  --brand: var(--slate);
  --paper: var(--slate-paper);
}
.console-shell .rail {
  background: var(--slate-rail);
}
/* The rail's brand block is now a lockup, which says "Console" itself; the
   line beneath names the side rather than repeating it. */
.console-shell .rail-brand span {
  color: rgba(255, 255, 255, 0.72);
}

/* The banner a firm sees while somebody at the vendor can read their data.
   Across the top of every screen, in the colour this product uses for the
   things that must not be missed. A support grant nobody can see is
   indistinguishable from a back door. */
.support-banner {
  background: var(--material);
  color: var(--brand-ink);
  padding: var(--s-3) var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: baseline;
  justify-content: space-between;
}
.support-banner strong {
  font-weight: 600;
}
.support-banner a {
  color: var(--brand-ink);
  text-decoration: underline;
}

/* Companies House results, under the search box.
   A list rather than a dropdown: it is read, compared and chosen from, and two
   companies with the same name are told apart by the number and the town
   underneath — which a one-line combobox has nowhere to put. */
.company-results {
  list-style: none;
  margin: var(--s-2) 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  max-width: var(--form);
  overflow: hidden;
}
.company-results li + li {
  border-top: 1px solid var(--line);
}
.company-results button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: var(--surface);
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  font: inherit;
  color: var(--ink);
}
.company-results button:hover {
  background: var(--paper);
}
.company-name {
  display: block;
  font-weight: 500;
}
.company-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: baseline;
  margin-top: 2px;
  color: var(--ink-2);
  font-size: var(--t-dense);
}

/* ---------------------------------------------------------------
   In-app help
   --------------------------------------------------------------- */

/* A heading and its help button, side by side.
   The button is a sibling of the heading rather than a child of it: inside, its
   label would join the heading's accessible name and a screen reader would
   announce "Contracts, help colon how the gap report rolls up". Inside a
   <label> it would be worse — clicking the label would activate the button. */
.titled {
  display: flex;
  align-items: baseline;
  gap: 0;
}
.titled > h1,
.titled > h2,
.titled > h3,
.titled > label,
.titled > strong {
  margin: 0;
}

/* The "?" beside a heading or a label. Quiet by design: secondary ink, no
   fill, no animation. It should be findable when somebody has a question and
   invisible when they do not. */
.help-button {
  appearance: none;
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  margin-left: var(--s-2);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  /* Aligns with the cap height of the text it follows rather than its
     baseline, which would sit it noticeably low beside a 16px section title. */
  vertical-align: 1px;
}
.help-button:hover {
  border-color: var(--ink-2);
  color: var(--ink);
}
.help-button:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* A side panel, not a modal: help is read while a form is being filled in, and
   a modal would make somebody choose between the guidance and the field it
   describes. It uses the system's one shadow. */
.help-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  max-width: 100vw;
  overflow-y: auto;
  padding: var(--s-5);
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow);
  z-index: 20;
}
.help-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
}
.help-panel-head h2 {
  margin: 0;
  font-size: var(--t-section);
}

/* Rendered help content. Narrow measure, generous leading: this is prose in a
   product that is otherwise dense tables, and it should read like prose. */
.help-panel .prose {
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--ink);
}
.help-panel .prose p,
.help-panel .prose ul,
.help-panel .prose ol {
  margin: 0 0 var(--s-4);
  max-width: var(--prose);
}
.help-panel .prose ul,
.help-panel .prose ol {
  padding-left: var(--s-5);
}
.help-panel .prose li {
  margin-bottom: var(--s-2);
}
.help-panel .prose h3,
.help-panel .prose h4 {
  margin: var(--s-5) 0 var(--s-2);
  font-size: var(--t-body);
  font-weight: 600;
}
.help-panel .prose > :last-child {
  margin-bottom: 0;
}
.help-panel .prose code {
  font-size: var(--t-dense);
}

@media (prefers-reduced-motion: no-preference) {
  .help-panel {
    animation: help-panel-in 140ms ease-out;
  }
}
@keyframes help-panel-in {
  from {
    transform: translateX(8px);
    opacity: 0;
  }
}

/* Six digits, in six boxes. The shape an authenticator shows them in, so the
   field looks like the thing being copied from rather than like a text box that
   happens to want six characters. Sized generously: this is read off a phone at
   arm's length and typed in a hurry. */
.code-label {
  display: block;
  font-weight: 600;
  margin-bottom: 6px;
}
.code-boxes {
  display: flex;
  gap: 8px;
}
.code-boxes input {
  width: 46px;
  height: 56px;
  padding: 0;
  text-align: center;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 24px;
  line-height: 1;
  /* The boxes fill the panel on a narrow screen rather than overflowing it;
     six at their natural width plus the gaps is about 340px. */
  max-width: none;
  min-width: 0;
  flex: 1 1 0;
}
/* The third gap is wider, because the app shows "123 456" and the eye is
   already grouping them that way. */
.code-boxes input:nth-child(3) {
  margin-right: 10px;
}

/* The authenticator enrolment: the symbol beside the steps, stacking on a
   narrow screen rather than shrinking the code to something a camera struggles
   with. */
.enrol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
  align-items: flex-start;
}
.enrol-steps {
  flex: 1 1 320px;
  min-width: 0;
}
/* The base32 key, whole.
   Thirty-two characters at 0.08em of tracking come to a little over 34ch, so a
   box sized at the character count clips the last few — and a key somebody has
   to read out or copy into a desktop authenticator is no use with its tail
   missing. The allowance is for the tracking and the box's own padding. */
.enrol .field input.mono {
  letter-spacing: 0.08em;
  width: 100%;
  max-width: 38ch;
}

/* Your own account, in the rail's foot. Quiet: it is not navigation through
   the product, it is the two things that are yours rather than the firm's. */
.rail-account {
  display: flex;
  gap: var(--s-3);
  margin-top: var(--s-2);
  font-size: var(--t-dense);
}
.rail-account a {
  color: var(--ink-2);
}
.rail-account a:hover {
  color: var(--brand);
}
/* A firm that requires a second factor, on an account that has none. Not a
   decoration: this person is one session away from being locked out. */
.rail-flag {
  display: inline-grid;
  place-items: center;
  width: 14px;
  height: 14px;
  margin-left: var(--s-1);
  border-radius: 50%;
  background: var(--material);
  color: var(--brand-ink);
  font-size: 10px;
  font-weight: 600;
}
