/* Eauxwell Connect — the design system in design_handoff_eauxwell_connect/.
 *
 * One stylesheet, no build step, no font fetch. Three things about it are
 * deliberate and worth knowing before editing:
 *
 * Nothing is rounded. Structure is drawn with rules instead — 2px under a
 * section heading, 1px between table rows, 1px gaps inside a 2px frame for the
 * metric grids. Everything is flush left, including button labels.
 *
 * The handoff's tokens use color-mix(). This file writes the same values as
 * rgba() because the field devices this runs on are not all new, and a colour
 * that fails to parse takes the rule with it.
 *
 * Archivo is the intended typeface. It is not fetched from Google Fonts: the
 * capture form has to work with no network, and a webfont request is a network
 * request. Drop the files into static/fonts/ and uncomment the @font-face block
 * below and every heading picks them up; until then the stack falls through to
 * the closest grotesque the device already has.
 */

/* @font-face { font-family: "Archivo"; font-weight: 400; font-display: swap;
     src: url("/static/fonts/Archivo-Regular.woff2") format("woff2"); }
   @font-face { font-family: "Archivo"; font-weight: 600; font-display: swap;
     src: url("/static/fonts/Archivo-SemiBold.woff2") format("woff2"); }
   @font-face { font-family: "Archivo"; font-weight: 800; font-display: swap;
     src: url("/static/fonts/Archivo-ExtraBold.woff2") format("woff2"); } */

:root {
  --bg: #f3f2f2;
  --surface: #eae9e9;
  --ink: #201e1d;
  --paper: #f3f2f2;

  --accent: #03088C;
  --accent-100: #eef0fb;
  --accent-200: #dde1f7;
  --accent-300: #c2c9ef;
  --accent-400: #5d68c8;
  --accent-600: #02066f;
  --accent-700: #02055a;
  --accent-800: #010445;
  --accent-900: #010332;

  /* The one place a distinct colour earns its keep. The system says no status
     rainbow, and that rule is about tags — a mandatory field nobody has filled in
     is not a status, it is the thing standing between a record and a claim, and
     it has to be findable at a glance on a phone in the sun. */
  --need: #B3261E;
  --need-tint: #fdecea;

  --divider: rgba(32, 30, 29, .40);
  --ink-04: rgba(32, 30, 29, .04);
  --ink-07: rgba(32, 30, 29, .07);
  --ink-14: rgba(32, 30, 29, .14);
  --ink-55: rgba(32, 30, 29, .55);
  --ink-60: rgba(32, 30, 29, .60);
  --ink-65: rgba(32, 30, 29, .65);
  --ink-72: rgba(32, 30, 29, .72);
  --ink-78: rgba(32, 30, 29, .78);

  --font: "Archivo", "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --mono: "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace;

  --gutter: clamp(16px, 3vw, 40px);
  --page: 1320px;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  text-wrap: pretty;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0 0 8px;
}
h1 { font-size: 32px; }
h2 { font-size: 20px; letter-spacing: -0.01em; }
h3 { font-size: 17px; text-transform: none; letter-spacing: -0.01em; color: inherit; }

p { margin: 0 0 12px; }
a { color: var(--accent-700); text-underline-offset: 3px; }
a:hover { color: var(--accent); }
img { display: block; max-width: 100%; }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: var(--accent-200); }

.mono, code { font-family: var(--mono); font-size: .94em; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.lede { font-size: 14.5px; line-height: 24px; color: var(--ink-72); margin: 8px 0 0; max-width: 66ch; }
.hint, .sub, .footnote { font-size: 12.5px; line-height: 20px; color: var(--ink-65); }
.hint { margin: 6px 0 0; }
.sub { margin: 8px 0 0; }
.footnote { margin: 12px 0 0; }
.error-text { font-size: 12.5px; color: var(--need); margin: 5px 0 0; }

/* --- the shell ----------------------------------------------------------- */

/* The application bar is solid accent. The landing page keeps the light one —
   it is a public page, not a place you are working. */
header.top {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 14px max(var(--gutter), calc((100% - var(--page)) / 2 + var(--gutter)));
  background: var(--accent);
  color: var(--paper);
}
header.top .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  font-weight: 800;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--paper);
}
header.top .brand a { display: block; color: inherit; text-decoration: none; }
header.top .brand img { height: 30px; width: auto; }
header.top .brand span { font-size: 24px; line-height: 1; }
header.top .brand span br { display: none; }

header.top nav { display: flex; gap: 18px; flex-wrap: wrap; flex: 1; }
header.top nav a {
  color: rgba(243, 242, 242, .78);
  text-decoration: none;
  font-size: 14px;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
}
header.top nav a:hover { color: var(--paper); }
header.top nav a.on { color: var(--paper); font-weight: 600; border-bottom-color: var(--paper); }

header.top .who {
  font-size: 14px;
  line-height: 20px;
  text-align: right;
  color: rgba(243, 242, 242, .75);
}
header.top .who strong {
  display: block;
  color: var(--paper);
  font-weight: 600;
  font-size: 15px;
}
header.top .who a { color: rgba(243, 242, 242, .7); text-decoration: none; }
header.top .who a:hover { color: var(--paper); }
header.top .who form { display: inline; }
header.top .who .guide-link::before { content: " · "; color: rgba(243, 242, 242, .45); }
header.top .who button {
  background: none;
  border: 1px solid rgba(243, 242, 242, .5);
  color: var(--paper);
}
header.top .who button:hover { background: rgba(243, 242, 242, .14); color: var(--paper); }

main {
  max-width: var(--page);
  margin: 0 auto;
  padding: 36px var(--gutter) 64px;
}
main.narrow { max-width: 1100px; }

/* --- rules and sections -------------------------------------------------- */

hr, .rule { height: 2px; border: 0; margin: 16px 0; background: var(--divider); }

.section-head {
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-60);
  font-weight: 600;
  margin: 36px 0 0;
}
.section-head:first-of-type { margin-top: 20px; }

/* A panel is a titled section, drawn with a rule rather than a box. */
.panel { background: none; border: 0; padding: 0; margin: 0 0 36px; }
/* A table with nowhere to go squashes its columns until a row no longer reads
   as a line: on the capture settings screen the label and its tick box ended up
   in different places, and the left-hand column was off the side of the phone
   entirely. Thirty-three tables were sitting in a panel that could not scroll —
   only the ones wrapped in `.scroll` could. Every panel scrolls now, so wide
   content moves inside its own box and the page itself never goes sideways. */
.panel { overflow-x: auto; }
/* And it scrolls rather than crushing: below this width the columns keep their
   own line and the panel gains a scrollbar. */
@media (max-width: 760px) { .panel table { min-width: 540px; } }
/* A label and the control that belongs to it read as one thing or they read as
   two. On the settings screens the tick box and the word "require" wrapped onto
   separate lines as the column narrowed, so the row stopped being a row. */
/* The live scanner. A viewfinder is the primary way to read a barcode, so the
   button reads as an action and not as a footnote to the photograph. */
.pick-scan {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--paper);
  border-radius: 4px;
  padding: 11px 15px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  align-self: center;
}
.pick-scan:hover { background: var(--accent-700); }
.scan-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(0, 0, 0, .86);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
/* An author display beats the hidden attribute, so spell it out — without
   this, a finished scan leaves a dead black overlay nobody can dismiss. */
.scan-overlay[hidden] { display: none; }
.scan-box { width: min(560px, 100%); text-align: center; }
.scan-stage { position: relative; }
.scan-video {
  width: 100%;
  max-height: 66vh;
  border-radius: 4px;
  background: #000;
  object-fit: cover;
  display: block;
}
/* The box a person aims with. A barcode is read across its bars, so the guide
   is wide and short — it teaches the right framing without a word. */
.scan-guide {
  position: absolute;
  left: 9%;
  right: 9%;
  top: 50%;
  height: 28%;
  transform: translateY(-50%);
  border: 2px solid rgba(255, 255, 255, .9);
  border-radius: 3px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .28);
  pointer-events: none;
}
.scan-say {
  color: #fff;
  margin: 12px 0;
  font-size: 15px;
  line-height: 1.4;
}
.scan-alt { margin: 4px 0 8px; }
.scan-alt-hint { color: rgba(255, 255, 255, .85); font-size: 13.5px; margin: 0 0 10px; }
.scan-alt button {
  display: block;
  width: 100%;
  margin: 0 0 8px;
  padding: 12px;
  font: inherit;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 1px;
  background: var(--paper);
  color: var(--accent);
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}
.scan-overlay .actions { justify-content: center; }
.scan-overlay button { background: none; color: #fff; border-color: rgba(255,255,255,.6); }

/* A disabled action still has to read as the action it will be. Faded, not
   hidden — hiding it is what made the delete buttons look absent. */
button[disabled] { opacity: .45; cursor: not-allowed; }
td .check, th .check { white-space: nowrap; display: inline-flex; align-items: center; }
td .check input, th .check input { flex: none; }
.panel > h2 {
  margin: 0 0 12px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--divider);
}
.panel > h2 .tag { margin-left: 8px; vertical-align: middle; }
.panel > h3 { margin: 20px 0 8px; }

.grid { display: grid; gap: clamp(24px, 3vw, 48px); }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }

/* --- ruled metric grid --------------------------------------------------- */

/* The ruled frame is a 1px gap showing a divider-coloured ground through it.
   Flex rather than grid because the number of cells varies from one to eight: a
   fixed column count leaves empty tracks, and an empty track in this pattern is
   a grey block where a cell should be. */
.grid.metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--divider);
  border: 2px solid var(--divider);
  margin: 24px 0 20px;
}
.metric { background: var(--bg); padding: 20px; flex: 1 1 190px; min-width: 0; }

/* The same framed pattern at card size — report definitions, evidence packs. */
.grid.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  background: var(--divider);
  border: 2px solid var(--divider);
  margin: 24px 0 36px;
}
.grid.cards > .panel {
  background: var(--bg);
  padding: 24px;
  margin: 0;
  flex: 1 1 360px;
  min-width: 0;
}
.grid.cards .kv { grid-template-columns: 110px minmax(0, 1fr); font-size: 13.5px; }
.grid.cards .kv dt, .grid.cards .kv dd { padding: 6px 12px 6px 0; border-bottom: 0; }
.grid.cards .grid.three { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.grid.cards > .panel > h2 {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 19px;
  border-bottom: 0;
  padding-bottom: 0;
  margin-bottom: 16px;
}
.metric .k {
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-60);
  margin: 0;
}
.metric .n {
  font-weight: 800;
  font-size: 38px;
  line-height: 1;
  color: var(--accent);
  margin: 10px 0 0;
  font-variant-numeric: tabular-nums;
}
.metric .sub { font-size: 12.5px; color: var(--ink-65); margin: 8px 0 0; }
/* No status rainbow: a metric that needs attention says so in its own words. */
.metric.good .n, .metric.warn .n, .metric.bad .n { color: var(--accent); }

/* --- notices ------------------------------------------------------------- */

.notice {
  border: 2px solid var(--divider);
  padding: 16px 20px;
  margin: 0 0 24px;
  font-size: 14px;
  line-height: 23px;
}
.notice p { margin: 0 0 8px; }
.notice p:last-child { margin-bottom: 0; }
.notice.info { border-color: var(--divider); }
.notice.warn { border-color: var(--accent); background: var(--accent-100); }
/* A refusal is drawn in the same red as a field being asked for, and for the
   same reason: it is the thing standing between the officer and a saved record.
   Drawn in the house blue it read as one more piece of information. */
.notice.bad { border-color: var(--need); background: var(--need-tint); }
.notice.need { border-color: var(--need); background: var(--need-tint); }
/* Two ways to give a photograph, side by side. Android's own chooser was going
   straight to the gallery on some handsets, so the choice is made explicit here
   rather than left to whatever the phone decides to offer. */
.pick { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 2px; }
.pick-btn {
  flex: 1 1 150px;
  border: 1px solid var(--ink-14);
  border-radius: 4px;
  padding: 11px 13px;
  cursor: pointer;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 9px;
}
.pick-btn { flex: 0 1 auto; }
.pick-btn:hover { border-color: var(--accent); color: var(--accent); }
/* The camera is a way out for handsets that open the sheet in the gallery, not
   a second front door. It reads as a link so it does not compete with the
   button — five photographs on one form means five of each. */
.pick-link {
  border: 0;
  background: none;
  padding: 0 4px;
  font: inherit;
  font-size: 13px;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
  align-self: center;
}
.pick-link:hover { text-decoration: none; }
.pick-btn .ico { font-size: 18px; line-height: 1; flex: none; }
.pick-btn .sub {
  display: block;
  font-size: 11.5px;
  font-weight: 400;
  color: var(--ink-60);
  margin-top: 1px;
}
/* Reachable by keyboard and by a screen reader, invisible to everyone else.
   display:none would take it out of the form on some browsers. */
.pick-input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
}
.pick-chosen { margin: 4px 0 2px; }

/* Page links. Small, quiet, and out of the way of the table above them. */
/* The one-line message after an action. It had no styling at all, so it arrived
   as a bare line of text above the page and was easy to miss entirely. */
.flash {
  border: 1px solid var(--accent-300);
  border-left-width: 3px;
  background: var(--accent-100);
  color: var(--accent-700);
  padding: 11px 15px;
  border-radius: 0 3px 3px 0;
  margin: 0 0 18px;
  font-size: 15px;
}

/* A message about something that went wrong. Red, and it stays on the page the
   person was already on rather than replacing it with an error screen. */
.flash-bad {
  border-color: var(--need);
  background: var(--need-tint);
  color: var(--need);
  font-weight: 600;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 14px 0 4px;
  font-size: 14px;
}
.pager-count { color: var(--ink-60); }
/* The top pager sits between the filters and the table, so it needs a rule to
   read as a boundary rather than as another row of the form above it. */
.pager-top {
  margin: 4px 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ink-14);
}
.pager-links { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.pager-links a, .pager-here, .pager-off {
  min-width: 34px;
  padding: 6px 10px;
  border: 1px solid var(--ink-14);
  border-radius: 3px;
  text-align: center;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.pager-links a { color: var(--accent); }
.pager-links a:hover { border-color: var(--accent); background: var(--accent-100); }
.pager-here { border-color: var(--accent); background: var(--accent); color: var(--paper); font-weight: 600; }
.pager-off { border-color: transparent; color: var(--ink-14); }
.pager-gap { padding: 0 2px; color: var(--ink-60); }

.need-list { margin: 10px 0 0; padding-left: 20px; columns: 2; }
/* On a phone two columns wrap every item onto two lines. A field name is a
   phrase, not a word, so it gets the full width. */
@media (max-width: 560px) { .need-list { columns: 1; } }
.need-list a { color: var(--need); font-weight: 600; }
.notice.ok { border-color: var(--ink); }
.notice .actions { margin-top: 12px; }

/* --- tags ---------------------------------------------------------------- */

.tag {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  letter-spacing: .02em;
  padding: 3px 10px;
  background: var(--surface);
  color: var(--ink);
}
.tag.ok, .tag.good { background: var(--surface); color: var(--ink); }
.tag.warn, .tag.bad { background: var(--accent-100); color: var(--accent-800); }
.tag.info { background: none; border: 1px solid var(--accent); color: var(--accent); }
.tag.need { background: var(--need-tint); color: var(--need); font-weight: 600; }

/* A box still to be filled: marked where it is, and lit when arrived at from the
   outstanding list, so following a link lands somewhere obvious. */
.needed { border-left: 3px solid var(--need); padding-left: 10px; color: var(--need); }
.needed input, .needed select, .needed textarea { border-color: var(--need); }
.needed:target, :target > .needed { background: var(--need-tint); }
:target { scroll-margin-top: 90px; }
label.check.needed { padding-left: 10px; }

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

button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font);
  font-weight: 800;
  font-size: 14px;
  line-height: 1.2;
  padding: 10px 15px;
  border: 1px solid transparent;
  border-radius: 0;
  background: var(--accent);
  color: var(--paper);
}
button:hover, .btn:hover { background: var(--accent-600); color: var(--paper); }
button:active, .btn:active { background: var(--accent-700); }
button:disabled { opacity: .45; cursor: not-allowed; }

.btn.ghost, button.ghost {
  background: none;
  color: var(--accent-700);
  border-color: var(--divider);
}
.btn.ghost:hover, button.ghost:hover { background: var(--ink-07); color: var(--accent); }

/* Destructive actions keep their own weight. The system's rule against a status
   rainbow is about tags; a button that erases a customer is not a status. */
button.danger, .btn.danger { background: var(--ink); color: var(--paper); }
button.danger:hover, .btn.danger:hover { background: #000; }

button.small, .btn.small { padding: 6px 10px; font-size: 12.5px; }
.actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 16px; }
form.inline { display: inline; }

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

label { display: block; font-size: 12px; margin-bottom: 5px; color: var(--ink-72); }
input, select, textarea {
  width: 100%;
  min-height: 38px;
  padding: 7px 10px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  caret-color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 0;
}
input:hover, select:hover, textarea:hover { border-color: rgba(32, 30, 29, .45); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  border-color: var(--accent);
  outline-offset: 0;
}
textarea { min-height: 90px; resize: vertical; }
input[type="checkbox"], input[type="radio"] { width: auto; min-height: 0; }
input.field-error, select.field-error, textarea.field-error { border-color: var(--need); border-width: 2px; }

fieldset { border: 0; border-top: 2px solid var(--divider); padding: 20px 0 0; margin: 0 0 28px; }
legend {
  padding: 0 12px 0 0;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-60);
}
fieldset.lead { border-top-color: var(--accent); border-top-width: 2px; }
fieldset.lead > legend { color: var(--accent); }
.lead-photo input { padding: 14px; font-size: 16px; }

label.check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink);
  margin: 0 0 8px;
}
label.check input { width: auto; margin: 0; }

/* --- filter bar and selection bar ---------------------------------------- */

.filters {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-end;
  padding: 16px 0;
  border-bottom: 2px solid var(--divider);
  margin-bottom: 16px;
}
.filters label { margin: 0 0 4px; }
.filters > div { min-width: 160px; }
.filters .check { padding: 9px 0; margin: 0; white-space: nowrap; }
.filter-actions { display: flex; gap: 8px; align-items: flex-end; }

.select-bar {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  margin: 0 0 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
}
.select-bar .check { margin: 0; font-weight: 600; }

/* --- the field bar ------------------------------------------------------- */
/* Where you are, whether there is a network, what is still held on the phone,
   and the button that empties it. The desk filter bar was doing this and wrapped
   into four ragged rows on a small screen, each with its own label above it. */
.fieldbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  padding: 10px 0;
  border-top: 1px solid var(--ink-14);
  border-bottom: 1px solid var(--ink-14);
}
.fieldbar select { flex: 1 1 200px; min-width: 0; margin: 0; }
.fieldbar-site { font-weight: 600; }
/* A photograph's own label, above its button. Without this it reads as the tail
   of the hint above it rather than as the name of the thing below. */
.pick-label { display: block; font-weight: 600; margin: 14px 0 2px; }
.pick-label .tag { margin-left: 6px; font-weight: 400; vertical-align: middle; }
.fieldbar-state { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.fieldbar-state .tag { margin: 0; }
/* On a phone the select takes the width and the state sits under it, which is
   two tidy rows rather than four ragged ones. */
@media (max-width: 560px) {
  .fieldbar { gap: 8px; }
  .fieldbar select, .fieldbar-site { flex: 1 1 100%; }
  .fieldbar-state { margin-left: 0; width: 100%; }
  .fieldbar-state button { margin-left: auto; }
}

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

.scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-60);
  padding: 10px 12px 10px 0;
  border-bottom: 2px solid var(--divider);
  white-space: nowrap;
}
td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--divider); vertical-align: top; }
tbody tr:hover, table tr:hover { background: var(--ink-04); }
th.num, td.num { text-align: right; padding-right: 0; }
th.pick, td.pick { width: 28px; padding-right: 0; }
td.pick input, th.pick input { width: auto; margin: 0; }
.row-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

dl.kv { display: grid; grid-template-columns: 190px minmax(0, 1fr); margin: 0; }
dl.kv dt {
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-60);
  padding: 11px 12px 11px 0;
  border-bottom: 1px solid var(--divider);
}
dl.kv dd { margin: 0; padding: 11px 0; border-bottom: 1px solid var(--divider); font-size: 14px; }

.thumbs { display: flex; gap: 12px; flex-wrap: wrap; }
.thumbs img { filter: grayscale(1) contrast(1.08); border: 1px solid var(--divider); }

.issued {
  font-size: 18px;
  font-weight: 600;
  padding: 2px 8px;
  background: var(--bg);
  border: 1px solid var(--divider);
  user-select: all;
}

details.tight summary { cursor: pointer; font-size: 12px; color: var(--accent-700); margin-top: 4px; }
details.tight form { padding: 8px 0 0; }
details.tight .check { margin: 0 0 4px; white-space: nowrap; }

.trace { font-family: var(--mono); font-size: 12px; white-space: pre-wrap; color: var(--ink-65); }

/* --- sign-in ------------------------------------------------------------- */

body.signin { background: var(--accent); }
.signin-split { min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.signin-brand {
  padding: clamp(28px, 5vw, 64px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: var(--paper);
}
.signin-brand img { width: 180px; height: auto; }
.signin-brand h1 {
  font-size: clamp(34px, 3.6vw, 52px);
  line-height: 1.06;
  margin: 0 0 0 -0.058em;
  color: var(--paper);
}
.signin-brand h1 span { display: block; }
.signin-brand .statement { font-size: 15px; line-height: 25px; margin: 24px 0 0; max-width: 44ch; color: rgba(243, 242, 242, .75); }
.signin-brand .ndpa { font-size: 12.5px; line-height: 20px; margin: 0; max-width: 52ch; color: rgba(243, 242, 242, .65); }
.signin-form { background: var(--bg); padding: clamp(28px, 5vw, 64px); display: flex; align-items: center; }
.signin-form > div { width: min(400px, 100%); }
.signin-form .kicker {
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-700);
  margin: 0 0 16px;
}
.signin-form h2 { font-size: 28px; margin: 0 0 8px; }
.signin-form form { display: grid; gap: 18px; }

/* On a phone the brand panel is a masthead, not a second screen. Stacked
   above the form, it says who this is in four lines and hands over — the
   full-height spread is a desktop composition. */
@media (max-width: 860px) {
  .signin-split { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .signin-brand { padding: 24px 20px; gap: 14px; justify-content: flex-start; }
  .signin-brand img { width: 110px; }
  .signin-brand h1 { font-size: 26px; }
  .signin-brand .statement { display: none; }
  .signin-brand .ndpa { font-size: 11.5px; line-height: 17px; }
  .signin-form { padding: 28px 20px 40px; }
}

/* --- landing ------------------------------------------------------------- */

.landing { --page: 1200px; }
.landing main { max-width: 1200px; padding-top: 0; }
.landing header.top {
  padding-inline: max(clamp(20px, 4vw, 64px), calc((100% - 1200px) / 2 + clamp(20px, 4vw, 64px)));
  background: var(--bg);
  color: var(--ink);
  border-bottom: 2px solid var(--divider);
}
.landing header.top nav { flex: 0 1 auto; gap: 24px; }
.landing header.top .brand { color: var(--ink); }
.landing header.top nav a { color: var(--ink); }
.landing header.top nav a:hover { color: var(--accent); }

/* On a phone the landing bar carries exactly two things: the name and a way
   in. The section links are anchors into a page that will be scrolled anyway,
   and the second button lives 100px lower in the hero — repeating either up
   here is what made the bar wrap into a heap. */
@media (max-width: 860px) {
  .landing header.top { flex-wrap: nowrap; gap: 12px; min-height: 0; padding: 12px 20px; }
  .landing header.top .brand { flex: 0 1 auto; padding: 0; }
  .landing header.top .brand span { display: inline; font-size: 19px; }
  .landing header.top .brand img { height: 24px; }
  .landing header.top nav { display: none; }
  .landing header.top .actions { margin-left: auto; flex-wrap: nowrap; }
  .landing header.top .actions .btn { display: none; }
  .landing header.top .actions .btn.ghost {
    display: inline-block;
    padding: 9px 18px;
    font-size: 14px;
    white-space: nowrap;
  }
  /* Two stats a row, sized for a phone. One a row read as a tower of
     numbers with a screen of scrolling to pass them. */
  .landing .stat-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 18px;
    padding: 36px 0;
  }
  .landing .stat-row .n { font-size: 30px; }
  .landing .stat-row .k { font-size: 10.5px; margin-top: 8px; }
  .landing .hero { padding: 44px 0 40px; }
  /* The hero and the closing poster set their buttons full width, equal
     height, in one column — not two widths ragged against each other. */
  .landing .hero .actions, .landing .poster .actions {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .landing .hero .actions .btn, .landing .poster .actions .btn {
    text-align: center;
    justify-content: center;
    padding: 13px 18px;
  }
}

.hero { padding: clamp(64px, 9vw, 112px) 0 84px; }
.hero h1 { font-size: clamp(42px, 6vw, 80px); line-height: 1.06; letter-spacing: -0.02em; margin: 0 0 0 -0.058em; }
.hero h1 span { display: block; }
.hero p { font-size: 17px; line-height: 28px; max-width: 52ch; margin: 36px 0 0; color: var(--ink-78); }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 42px 28px; padding: 56px 0; }
.stat-row .n { font-weight: 800; font-size: clamp(34px, 3.4vw, 48px); line-height: 1; color: var(--accent); margin: 0; text-align: left; }
.stat-row .k { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-72); margin: 12px 0 0; }

.kicker { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-700); margin: 0 0 20px; }

.feature {
  display: grid;
  grid-template-columns: minmax(64px, 140px) minmax(0, 400px) minmax(0, 1fr);
  gap: 20px clamp(24px, 4vw, 64px);
  align-items: baseline;
  padding: 36px 0;
}
.feature + .feature { border-top: 2px solid var(--divider); }
.feature .no { font-weight: 800; font-size: 15px; margin: 0; font-variant-numeric: tabular-nums; }
.feature h3 { font-size: 24px; line-height: 28px; margin: 0; }
.feature p { font-size: 15.5px; line-height: 26px; margin: 0; color: var(--ink-78); max-width: 52ch; }

.screen-links { display: flex; gap: 10px 24px; flex-wrap: wrap; align-items: baseline; }
.screen-links a { font-weight: 800; font-size: 17px; text-decoration: none; }

.poster { background: var(--accent); color: var(--paper); }
.poster .inner { max-width: 1200px; margin: 0 auto; padding: 84px clamp(20px, 4vw, 64px); }
.poster h2 { font-size: clamp(34px, 4.2vw, 56px); line-height: 1.06; margin: 0 0 0 -0.058em; color: var(--paper); }
.poster h2 span { display: block; }
.poster .actions { margin-top: 42px; }
.poster .btn.ghost { color: var(--paper); border-color: var(--paper); }
.poster .btn.ghost:hover { background: rgba(243, 242, 242, .12); color: var(--paper); }

.site-footer {
  max-width: 1200px;
  margin: 0 auto;
  padding: 42px clamp(20px, 4vw, 64px);
  font-size: 13px;
  line-height: 22px;
  color: var(--ink-72);
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  justify-content: space-between;
}

/* --- the phone drawer ---------------------------------------------------- */

.nav-button, .nav-backdrop, .nav-drawer-head { display: none; }
.nav-drawer > nav > .nav-group > .group-head { display: none; }
.nav-drawer, .nav-group, .group-links { display: contents; }

@media (max-width: 860px) {
  header.top { padding: 0 16px; gap: 10px; min-height: 56px; }
  header.top .brand { padding: 10px 0; flex: 1; margin-right: 0; }
  header.top .brand span { display: none; }

  .nav-button {
    display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
    color: var(--paper); font-size: 14px; font-weight: 800; padding: 9px 14px;
    border: 1px solid rgba(243, 242, 242, .5); background: none;
    -webkit-tap-highlight-color: transparent;
  }
  .nav-bars, .nav-bars::before, .nav-bars::after {
    display: block; width: 15px; height: 2px; background: var(--paper); content: "";
  }
  /* The landing bar stays light, so its button does too. */
  .landing .nav-button { color: var(--ink); border-color: var(--divider); }
  .landing .nav-bars, .landing .nav-bars::before, .landing .nav-bars::after {
    background: var(--ink);
  }
  .nav-bars { position: relative; }
  .nav-bars::before { position: absolute; top: -5px; }
  .nav-bars::after { position: absolute; top: 5px; }

  .nav-backdrop {
    display: block; position: fixed; inset: 0; z-index: 59;
    background: rgba(32, 30, 29, .55); opacity: 0; pointer-events: none;
    transition: opacity .2s ease;
  }
  .nav-toggle:checked ~ .nav-backdrop { opacity: 1; pointer-events: auto; }

  .nav-drawer {
    display: flex; flex-direction: column;
    border-left: 2px solid rgba(243, 242, 242, .25);
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 60;
    width: min(86vw, 330px);
    background: var(--accent); color: var(--paper);
    transform: translateX(101%); transition: transform .22s ease;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 0 0 env(safe-area-inset-bottom);
  }
  .nav-toggle:checked ~ .nav-drawer { transform: translateX(0); }

  .nav-drawer-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 18px; font-size: 12px; letter-spacing: .08em;
    text-transform: uppercase; color: rgba(243, 242, 242, .6);
    border-bottom: 2px solid rgba(243, 242, 242, .25);
    position: sticky; top: 0; background: var(--accent);
  }
  .nav-close { cursor: pointer; font-size: 26px; line-height: 1; color: var(--paper);
               padding: 0 6px; margin: -4px -6px 0 0; }

  header.top nav { display: block; padding: 0; flex: 1; }

  .nav-group { display: block; }
  .nav-group + .nav-group { border-top: 1px solid rgba(243, 242, 242, .18); }
  .nav-drawer > nav > .nav-group > .group-head {
    display: flex; align-items: center; justify-content: space-between;
    cursor: pointer; margin: 0; padding: 14px 18px;
    font-size: 12px; letter-spacing: .09em; text-transform: uppercase;
    color: rgba(243, 242, 242, .6); -webkit-tap-highlight-color: transparent;
  }
  .nav-drawer > nav > .nav-group > .group-head::after {
    content: ""; width: 7px; height: 7px; margin-left: 10px;
    border-right: 2px solid rgba(243, 242, 242, .5);
    border-bottom: 2px solid rgba(243, 242, 242, .5);
    transform: rotate(45deg) translate(-2px, -2px); transition: transform .15s ease;
  }
  .group-toggle:checked ~ .group-head { color: var(--paper); }
  .group-toggle:checked ~ .group-head::after { transform: rotate(-135deg) translate(-2px, -2px); }
  .group-links { display: none; }
  .group-toggle:checked ~ .group-links { display: block; padding-bottom: 6px; }
  .nav-group:not(:has(a)) { display: none; }

  header.top nav a {
    display: block; padding: 11px 18px; font-size: 15.5px;
    color: rgba(243, 242, 242, .9); border-bottom: none;
    border-left: 3px solid transparent;
  }
  header.top nav a:hover { color: var(--paper); }
  header.top nav a.on {
    color: var(--paper); font-weight: 600; background: rgba(243, 242, 242, .12);
    border-left-color: var(--paper); border-bottom-color: transparent;
  }

  header.top .who {
    text-align: left; padding: 16px 18px; font-size: 12px;
    border-top: 2px solid rgba(243, 242, 242, .25); color: rgba(243, 242, 242, .7);
  }
  header.top .who strong { font-size: 15px; color: var(--paper); }
  header.top .who a { color: rgba(243, 242, 242, .7); }
  header.top .who form { display: block; margin-top: 12px; }
  header.top .who button {
    width: 100%; padding: 11px; font-size: 15px; justify-content: center;
    background: var(--paper); color: var(--accent);
  }

  main { padding: 24px 16px 48px; }
  h1 { font-size: 26px; }
  .grid.two, .grid.three { grid-template-columns: 1fr; }
  .metric { flex-basis: 44%; padding: 16px; }
  .metric .n { font-size: 30px; }
  .filters > div { min-width: 0; flex: 1 1 46%; }
  table { display: block; overflow-x: auto; white-space: nowrap; }
  dl.kv { grid-template-columns: 1fr; }
  dl.kv dt { border-bottom: 0; padding-bottom: 0; }
  input, select, textarea { font-size: 16px; }   /* stops iOS zooming */

  .signin-split { grid-template-columns: 1fr; }
  .signin-brand { min-height: auto; gap: 28px; }
  .feature { grid-template-columns: 1fr; }
  .site-footer { flex-direction: column; gap: 10px; }
}

/* 2-up is the floor: a metric one to a row turns a glanceable strip into a
   scroll, and 375px is an ordinary phone rather than a narrow one. */
@media (max-width: 360px) {
  header.top .brand img { height: 20px; }
  .metric { flex-basis: 100%; }
}
