/* GeoUK catalogue — light theme only, by request.
   Contrast targets: body text >= 7:1, muted text >= 4.5:1, all AA at minimum.
   No italic in the interface (PRD R-8.23). No colour-only encoding (R-8.24). */

:root {
  --ground:      #f4f6f8;
  --surface:     #ffffff;
  --alt:         #e9edf1;
  --sunk:        #dfe5eb;

  --ink:         #0f141a;   /* 16.9:1 on surface */
  --body:        #29313a;   /* 11.4:1 */
  --muted:       #545e69;   /*  6.6:1 */
  --faint:       #6b7681;   /*  4.6:1 — the floor, used only for counts */

  --rule:        #ccd4dc;
  --rule-soft:   #e2e8ed;

  --accent:      #0d4d60;   /*  8.4:1 */
  --accent-2:    #1a6c85;
  --accent-bg:   #e4eff2;

  --open:        #14603c;
  --open-bg:     #e6f2ea;
  --cond:        #6f4a0c;
  --cond-bg:     #f8f0e0;
  --restr:       #7d3419;
  --restr-bg:    #f8ebe5;
  --unc:         #4f3f79;
  --unc-bg:      #eeebf6;

  --focus:       #ffd23f;

  --sp: 4px;
  --radius: 4px;
}

* { box-sizing: border-box; }

/* The browser hides [hidden] with display:none from its own stylesheet, and
   any author rule that sets display wins. `.flist` sets display:flex, so a
   hidden sub-list stayed on screen while el.hidden reported true — the page
   and the test disagreed, and the test was the one that was wrong. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--body);
  font-family: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums lining-nums;
}

h1, h2, h3, h4 {
  font-family: 'Archivo', system-ui, sans-serif;
  color: var(--ink);
  letter-spacing: -.01em;
  margin: 0;
  text-wrap: balance;
}

a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--accent-2); }

/* GOV.UK-style focus: yellow block with a dark underline. Never removed. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 0;
  box-shadow: 0 3px 0 0 var(--ink);
  background-color: var(--focus);
  color: var(--ink);
  border-radius: 1px;
}
a:focus-visible, button:focus-visible { text-decoration: none; }
input:focus-visible, select:focus-visible {
  background-color: var(--surface);
  outline: 3px solid var(--focus);
  box-shadow: 0 0 0 5px var(--ink);
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ink); color: #fff; padding: 12px 18px; font-weight: 600;
}
.skip:focus { left: 8px; top: 8px; }

/* One container, one left edge.

   GOV.UK sets its page width to 960px with a 30px gutter either side, and its
   breakpoints at 641px (tablet) and 769px (desktop). A catalogue with a filter
   rail and a wide results table needs more room than 960px, so the container
   here is wider, but the discipline is the same one: every band on the page
   uses this rule and only this rule, so the masthead, the heading, the prose
   and the footer all start at the same x. The gutter grows with the viewport
   instead of sitting at a fixed 24px, which is what made the margins look
   arbitrary between widths.

   1560 rather than 1260 so the six category cards sit on one row on a laptop.
   Widening a container usually costs readability, and does not here: body text
   is held to its own measure and the results list to another, so the extra
   width goes to the cards and the tables, which are the things that wanted
   it. */
.wrap {
  max-width: var(--page, 1560px);
  margin: 0 auto;
  padding: 0 clamp(16px, 3vw, 30px);
}
.mono { font-family: 'IBM Plex Mono', ui-monospace, monospace; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.hide { display: none !important; }

/* ---------------------------------------------------------------- banner */
.banner {
  background: var(--accent-bg); border-bottom: 1px solid var(--rule);
  color: var(--accent); font-family: 'IBM Plex Mono', monospace;
  font-size: 11.5px; letter-spacing: .04em; padding: 7px 0; text-align: center;
}

/* ---------------------------------------------------------------- header */
header.site { background: var(--surface); border-bottom: 1px solid var(--rule); padding: 16px 0; }
.site-in { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.brand { text-decoration: none; display: flex; flex-direction: column; gap: 1px; }
.brand .eyebrow {
  font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
}
.brand strong { font-family: 'Archivo', sans-serif; font-size: 21px; font-weight: 600; color: var(--ink); }
/* On a phone the four links wrap under the title. Without nowrap they wrap
   inside themselves instead, and "By project stage" comes out three lines
   tall in a column two words wide. */
nav.main { display: flex; gap: 3px 4px; flex-wrap: wrap; }
nav.main a { white-space: nowrap; }
nav.main a {
  color: var(--muted); text-decoration: none; font-size: 14.5px;
  padding: 6px 12px; border-radius: var(--radius); border: 1px solid transparent;
}
nav.main a:hover { background: var(--alt); color: var(--ink); }
nav.main a[aria-current="page"] {
  background: var(--alt); color: var(--ink); border-color: var(--rule); font-weight: 600;
}

/* ---------------------------------------------------------------- intro */
.intro { padding-top: 26px; padding-bottom: 18px; border-bottom: 1px solid var(--rule); }
.intro > p { margin: 0; max-width: 78ch; font-size: 17px; color: var(--body); }
/* The stat line lists OVERLAPPING properties of the same records, not a
   breakdown. Presented as an undifferentiated row it invites the reader to add
   them up and conclude the catalogue is broken, which is exactly what happened.
   The total is set apart and the subsets are introduced as such. */
.statline {
  display: flex; gap: 6px 20px; flex-wrap: wrap; align-items: baseline;
  margin: 15px 0 0; font-size: 13.5px; color: var(--muted); max-width: none;
}
.statline b { color: var(--ink); font-weight: 600; }
.statline .total { font-size: 15.5px; color: var(--ink); }
.statline .of { color: var(--faint); }

/* Same problem in the sidebar: nation, technology and data-form counts sum to
   far more than the record count because a record carries several values. */
.fnote { margin: 0 0 7px; font-size: 12px; color: var(--faint); line-height: 1.4; }

/* Separate cards rather than one sealed slab with hairline gaps. Six
   categories in a five-column auto-fit left one cell of the second row empty,
   and with the container painted in the rule colour to draw those hairlines
   the empty cell came out as a grey block the width of four cards. Cards with
   their own borders leave page background in the gaps, which is invisible at
   any count.

   The track floor is 186px rather than 212 so six cards hold one row down to
   a 1280 laptop; below that they fall to two rows of three. */
.cats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  gap: 10px; margin-top: 20px;
}
.catcard {
  background: var(--surface); text-align: left; padding: 15px 16px;
  border: 1px solid var(--rule); border-radius: 5px;
  cursor: pointer; font: inherit; color: var(--body);
  display: flex; flex-direction: column; gap: 3px; text-decoration: none;
}
.catcard:hover { background: var(--alt); border-color: var(--accent-2); }
.cc-count { font-family: 'Archivo', sans-serif; font-size: 25px; font-weight: 600; color: var(--ink); line-height: 1; }
.cc-name { font-weight: 600; color: var(--ink); font-size: 14.5px; }
.cc-blurb { font-size: 12.5px; color: var(--muted); line-height: 1.4; }

/* ---------------------------------------------------------------- layout */
.layout {
  display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 36px;
  padding-top: 24px; padding-bottom: 80px; align-items: start;
}
aside.facets { min-width: 0; position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow-y: auto; padding-right: 6px; }
.fgroup { margin-bottom: 20px; }
.fgroup h3 {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
  padding-bottom: 6px; border-bottom: 1px solid var(--rule); margin-bottom: 7px;
}
.flist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.flist label {
  display: flex; align-items: center; gap: 9px; padding: 4px 5px;
  cursor: pointer; font-size: 13.5px; border-radius: 3px;
}
.flist label:hover { background: var(--alt); }
.flist input { accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; margin: 0; }
.flist .fl { flex: 1; color: var(--body); }
.flist .fc { font-family: 'IBM Plex Mono', monospace; font-size: 11.5px; color: var(--faint); }
.flist label.zero { opacity: .5; cursor: default; }
.flist label.zero .fl { color: var(--faint); }

/* ---------------------------------------------------------------- toolbar */
.toolbar { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
#q {
  flex: 1; min-width: 240px; padding: 10px 12px; border: 1px solid var(--rule);
  border-radius: var(--radius); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 15px;
}
#q::placeholder { color: var(--faint); }
.tb-right { display: flex; gap: 8px; align-items: center; }
select {
  font: inherit; font-size: 13.5px; padding: 7px 9px; border: 1px solid var(--rule);
  border-radius: var(--radius); background: var(--surface); color: var(--ink);
}
.viewtoggle { display: flex; border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; }
.viewtoggle button {
  background: var(--surface); border: 0; padding: 7px 13px; font: inherit;
  font-size: 13px; color: var(--muted); cursor: pointer;
}
.viewtoggle button[aria-pressed="true"] { background: var(--accent); color: #fff; font-weight: 600; }

.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; background: var(--accent-bg);
  color: var(--accent); border: 1px solid var(--accent-2); border-radius: var(--radius);
  padding: 3px 6px 3px 10px; font-size: 12.5px; font-weight: 600;
}
.chip button {
  background: none; border: 0; color: inherit; font: inherit; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 1px 4px; border-radius: 3px;
}
.chip button:hover { background: var(--accent); color: #fff; }
.chip.clear { background: none; border-style: dashed; color: var(--muted); border-color: var(--rule); padding: 3px 10px; cursor: pointer; }

.count {
  font-size: 13.5px; color: var(--muted); margin: 0 0 10px;
  padding-bottom: 9px; border-bottom: 1px solid var(--rule);
}
.count b { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------- results */
.row { padding: 13px 12px; border-bottom: 1px solid var(--rule-soft); margin: 0 -12px; }
.row:hover { background: var(--surface); }
.row[data-child="1"] { display: none; }
/* A matching child row used to be indented behind a left rule, which reads as
   "belongs to the row above". In a filtered list the row above is usually an
   unrelated record, so two platform layers that happened to land next to each
   other looked deliberately grouped. A result is a result; the row's own
   description already says which platform it comes from. */
.row[data-child="1"].shown { display: block; }
.rtitle { font-size: 16.5px; font-weight: 600; line-height: 1.3; margin-bottom: 3px; }
.rtitle a { color: var(--ink); text-decoration: none; }
.rtitle a:hover { color: var(--accent); text-decoration: underline; }
.rmeta { margin: 0 0 5px; font-size: 13px; color: var(--muted); }
.rdesc {
  margin: 0 0 7px; font-size: 14px; color: var(--body); max-width: 58ch;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rtags { margin: 0; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* A badge that wraps mid-phrase renders its border and its fill around each
   fragment, so "Open, with conditions" came out as two half-boxes with the
   rule running through the middle of the words. The licence badge is short
   enough to hold one line, and box-decoration-break covers the tag that is
   not. */
.lic {
  font-size: 11.5px; font-weight: 600; padding: 2px 8px; border-radius: 3px;
  border: 1px solid; white-space: nowrap;
}
.lic, .tag { -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.lic-open       { background: var(--open-bg);  color: var(--open);  border-color: var(--open); }
.lic-conditions { background: var(--cond-bg);  color: var(--cond);  border-color: var(--cond); }
.lic-restricted { background: var(--restr-bg); color: var(--restr); border-color: var(--restr); }
.lic-unclear,
.lic-unknown    { background: var(--unc-bg);   color: var(--unc);   border-color: var(--unc); }

.tag {
  font-size: 11.5px; color: var(--muted); border: 1px solid var(--rule);
  padding: 2px 8px; border-radius: 3px; background: var(--surface);
}
.tag.review { color: var(--cond); border-color: var(--cond); background: var(--cond-bg); }
mark { background: var(--focus); color: var(--ink); padding: 0 1px; border-radius: 2px; }

/* ---------------------------------------------------------------- tables */
/* Scrollable on a narrow screen, so it is focusable and named (WCAG 2.1.1:
   a region you can only reach by scrolling has to be reachable by keyboard). */
.tablewrap {
  overflow-x: auto; border: 1px solid var(--rule); border-radius: 5px;
  background: var(--surface);
}
.tablewrap:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
table { border-collapse: collapse; width: 100%; min-width: 840px; font-size: 13.5px; }
th, td { text-align: left; padding: 9px 13px; border-bottom: 1px solid var(--rule-soft); vertical-align: top; }
thead th {
  background: var(--alt); font-family: 'IBM Plex Mono', monospace; font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
  font-weight: 500; white-space: nowrap; position: sticky; top: 0;
}

/* Nine columns, one of them carrying a sentence. Without a floor on the first
   column the stage name broke one word per line while six numeric columns sat
   in acres of space, and the long category headings forced the whole table
   wider than the screen. */
.stagetable { min-width: 0; width: 100%; }
.stagetable th:first-child, .stagetable td:first-child { min-width: 15rem; }
.stagetable thead th { white-space: normal; line-height: 1.3; }
.stagetable thead th:not(:first-child):not(:nth-child(2)) { text-align: right; }
.stagetable td.num { min-width: 4.5rem; }
/* Wide enough for the longest licence label on one line. */
#tableview th.c-lic, #tableview td.c-lic { min-width: 12.5rem; white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
td a { color: var(--ink); font-weight: 600; text-decoration: none; }
td a:hover { color: var(--accent); text-decoration: underline; }
.num { text-align: right; }
td.gc { position: relative; }
td.gc::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--w, 0); background: var(--accent-bg); }
.gv { position: relative; z-index: 1; }
.tot { font-weight: 600; color: var(--ink); }
.scope {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; padding: 2px 8px;
  border-radius: 3px; background: var(--alt); color: var(--body); white-space: nowrap;
}
.why { color: var(--muted); font-size: 13px; }

/* ---------------------------------------------------------------- zero */
.zero-state { padding: 34px 0; max-width: 62ch; }
.zero-state h2 { font-size: 19px; margin-bottom: 8px; }
.zero-state p { color: var(--muted); margin: 0 0 14px; }
.relax { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }
.relax button {
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 8px 13px; font: inherit; font-size: 14px; color: var(--ink); cursor: pointer; text-align: left;
}
.relax button:hover { border-color: var(--accent); color: var(--accent); }

/* ---------------------------------------------------------------- record */
.record { padding-top: 22px; padding-bottom: 80px; }
.crumb { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.crumb a { color: var(--muted); }
.record h1 { font-size: 30px; font-weight: 700; line-height: 1.15; margin-bottom: 6px; max-width: 26ch; }
.rholder { font-size: 16px; color: var(--muted); margin: 0 0 18px; }
.dgrid { display: grid; grid-template-columns: minmax(0,1fr) 310px; gap: 40px; align-items: start; }

.answers {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px;
  background: var(--rule); border: 1px solid var(--rule); border-radius: 5px;
  overflow: hidden; margin: 0 0 22px;
}
.ans { background: var(--surface); padding: 12px 14px; }
.ans dt {
  font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}
.ans dd { margin: 0; font-size: 15px; color: var(--ink); font-weight: 600; }

.dsec { margin-bottom: 24px; }
.dsec h2 {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
  padding-bottom: 6px; border-bottom: 1px solid var(--rule); margin-bottom: 10px;
}
.dsec p { margin: 0 0 10px; max-width: 70ch; }
dl.kv { margin: 0; display: grid; grid-template-columns: 180px minmax(0,1fr); gap: 8px 18px; font-size: 14.5px; }
dl.kv dt { color: var(--muted); font-size: 13px; }
dl.kv dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }

.side {
  border: 1px solid var(--rule); border-radius: 5px; background: var(--surface);
  padding: 18px; position: sticky; top: 12px;
}
.gobtn {
  display: block; background: var(--accent); color: #fff; text-align: center;
  padding: 12px 14px; border-radius: var(--radius); text-decoration: none;
  font-weight: 600; font-size: 14.5px; margin-bottom: 8px;
}
.gobtn:hover { background: var(--accent-2); color: #fff; }
.gonote { font-size: 12.5px; color: var(--muted); margin: 0 0 14px; }
.subtle {
  display: block; text-align: center; padding: 9px; border: 1px solid var(--rule);
  border-radius: var(--radius); font-size: 13px; color: var(--body); text-decoration: none;
  margin-bottom: 6px; background: var(--surface); width: 100%; font-family: inherit; cursor: pointer;
}
.subtle:hover { border-color: var(--accent); color: var(--accent); }
.cite {
  font-family: 'IBM Plex Mono', monospace; font-size: 11.5px; color: var(--muted);
  background: var(--alt); padding: 10px; border-radius: var(--radius);
  line-height: 1.5; margin-top: 14px; overflow-wrap: anywhere;
}

.warn {
  background: var(--cond-bg); border: 1px solid var(--cond); border-left-width: 3px;
  border-radius: var(--radius); padding: 12px 15px; font-size: 14px;
  color: var(--body); margin-bottom: 16px; max-width: 72ch;
}
.warn strong {
  color: var(--cond); font-family: 'IBM Plex Mono', monospace; font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; display: block; margin-bottom: 4px;
}

/* ---------------------------------------------------------------- pages */
/* Shorthand padding here would cancel the container's horizontal gutter,
   which is what put the h1 30px to the left of the text under it. */
.page-head { padding-top: 28px; padding-bottom: 4px; }
.page-head h1 { font-size: clamp(23px, 1.1rem + 1.1vw, 29px); font-weight: 600; margin-bottom: 6px; }
.page-head p { color: var(--muted); max-width: 58ch; margin: 0 0 16px; font-size: 15.5px; }

/* Content pages: stages, coverage, about.

   Three widths are in play and they were previously fighting. Body text wants
   50 to 75 characters a line (Baymard), and WCAG 1.4.8 caps it at 80. A data
   table wants as much width as it can get. The section list wants to be out of
   the way but reachable. So the page is a two-column grid inside the shared
   container: everything readable on the left, a contents rail on the right.

   The rail is what fixes the About page. It has no tables, so a measured
   column on its own left the right half of a 1900px screen permanently empty.

   The earlier version of this rule carried `max-width: none`, which cancelled
   the container's centring on `.prose` alone. The prose then started at the
   viewport edge while the h1 above it started at the container edge, and the
   two blocks visibly disagreed about where the page began. */
.contentlayout { display: grid; align-items: start; padding-bottom: 72px; }

/* A page carrying a wide table gives the table the whole container and puts
   the section list along the top.

   The list comes first in the source, which is where a contents list belongs
   and what lets a page that has too few sections to need one simply leave it
   out without a stray empty row. */
.contentlayout { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
.contentlayout > .prose { grid-column: 1; }
.contentlayout > .toc {
  grid-column: 1; position: static;
  border-left: 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: 11px 0; margin: 8px 0 20px;
}
.contentlayout > .toc ol { display: flex; flex-wrap: wrap; gap: 4px 22px; }
.contentlayout > .toc li { margin: 0; }
.contentlayout > .toc a {
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}

/* A page that is all prose keeps the list as a rail next to the text, and the
   pair sits at the left of the container rather than drifting apart across it. */
@media (min-width: 1081px) {
  .contentlayout.rail {
    grid-template-columns: min(58ch, 100%) 216px;
    column-gap: clamp(32px, 4vw, 64px);
    justify-content: start;
  }
  .contentlayout.rail > .prose { grid-column: 1; grid-row: 1; }
  .contentlayout.rail > .toc {
    grid-column: 2; grid-row: 1; position: sticky; top: 16px;
    align-self: start;
    border: 0; border-left: 1px solid var(--rule);
    padding: 0 0 0 18px; margin: 8px 0 0;
  }
  .contentlayout.rail > .toc ol { display: block; }
  .contentlayout.rail > .toc li { margin-bottom: 7px; }
  .contentlayout.rail > .toc a { color: var(--body); text-decoration: none; }
  .contentlayout.rail > .toc a:hover {
    color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
  }
}

/* Inside the left column, prose is measured and tables break out to the full
   width of that column. */
.prose {
  display: grid;
  grid-template-columns:
    [text-start] min(58ch, 100%) [text-end]
    minmax(0, 1fr) [wide-end];
  column-gap: 40px;
  align-content: start;
  min-width: 0;
}
.prose > * { grid-column: text-start / text-end; min-width: 0; }
.prose > .tablewrap,
.prose > .wide { grid-column: text-start / wide-end; }
/* A caption belongs to the table above it, not to the text measure. */
.prose > .tnote {
  grid-column: text-start / wide-end;
  margin: -10px 0 6px; font-size: 12.5px; color: var(--muted);
}

.prose h2 {
  font-size: 19.5px; margin: 34px 0 12px;
  padding-bottom: 7px; border-bottom: 1px solid var(--rule-soft);
  scroll-margin-top: 16px;
}
.prose > h2:first-child { margin-top: 4px; }
/* On a page whose sections carry wide tables, the section rule runs the width
   of the content it introduces rather than stopping at the text measure. */
.contentlayout:not(.rail) .prose > h2 { grid-column: text-start / wide-end; }
.prose > p { margin: 0 0 13px; }
.prose ul { padding-left: 22px; }
.prose li { margin-bottom: 6px; }

/* On this page. Server-rendered, so it works with scripts off. */
.toc {
  position: sticky; top: 16px;
  font-size: 13px; line-height: 1.45;
  border-left: 1px solid var(--rule); padding-left: 16px;
  margin-top: 8px;
}
.toc-h {
  font-family: 'IBM Plex Mono', monospace; font-size: 10.5px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  font-weight: 500; margin: 0 0 9px; border: 0; padding: 0;
}
.toc ol { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
.toc li { margin-bottom: 7px; }
.toc a { color: var(--body); text-decoration: none; }
.toc a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }

/* Below the desktop breakpoint the rail has nowhere to sit, so it moves above
   the content and turns into a plain list, which is what GOV.UK does with a
   contents list on a phone. */
/* Below the tablet breakpoint the breakout column has no room left, so the
   grid collapses. The measure still has to be held: a full-width paragraph at
   this font size runs past 100 characters on a landscape tablet. */
@media (max-width: 860px) {
  .prose { display: block; }
  .prose > * { max-width: 100%; }
  .prose > p, .prose > ul, .prose > ol, .prose > .inset { max-width: 58ch; }
  .prose > .tnote { margin-top: 6px; }
}

footer.site {
  border-top: 1px solid var(--rule); background: var(--surface);
  padding: 22px 0; font-size: 13px; color: var(--muted);
}
footer.site a { color: var(--muted); }

@media (max-width: 1000px) {
  .layout { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  aside.facets { position: static; max-height: none; }
  .dgrid { grid-template-columns: 1fr; gap: 24px; }
  .side { position: static; }
}
@media (max-width: 620px) {
  .site-in { gap: 14px; }
  nav.main { width: 100%; margin-left: -12px; }
  nav.main a { font-size: 14px; padding: 6px 10px; }
  dl.kv { grid-template-columns: 1fr; gap: 2px 0; }
  dl.kv dd { margin-bottom: 8px; }
}

@media print {
  aside.facets, .toolbar, .chips, nav.main, .banner, .side { display: none; }
  .dgrid, .layout { grid-template-columns: 1fr; }
  body { background: #fff; font-size: 11pt; }
}

/* Link-check stamp on the record page. Deliberately understated: it reports
   the strength of the evidence, and for an automated check that evidence is
   weak. Nothing here should read as a guarantee. No italic (PRD R-8.23), and
   the bad state carries a word as well as a colour (R-8.24). */
.lcheck{margin:14px 0 0;padding:10px 12px;border:1px solid var(--rule-soft);
  border-radius:var(--radius);background:var(--alt);
  display:flex;flex-direction:column;gap:4px}
.lcheck-bad{border-color:var(--cond);background:var(--cond-bg)}
.lcstat{font-weight:600;font-size:12.5px;color:var(--ink)}
.lcdet{font-size:12px;color:var(--muted);line-height:1.45}
.lccav{font-size:11.5px;color:var(--muted);line-height:1.45;padding-top:6px;
  border-top:1px solid var(--rule-soft)}
.lcheck .mono{font-size:11.5px;word-break:break-all}

/* Project-stage tags. Distinguished from the generic tag by weight and a tinted
   ground, not by colour alone (PRD R-8.24), and set in the accent family so the
   stage axis reads as a different kind of fact from the licence badge. */
.tag.stage{color:var(--accent);border-color:var(--accent-2);background:var(--accent-bg);
  font-weight:600;white-space:nowrap}
.rtags .tag.stage{font-size:11px}
.dsec .rtags{margin-bottom:12px}

/* Two-level facet. Explore is three matrix columns and the other five phases
   are one each; showing all eight flat buries the phase structure and puts
   three Explore rows in front of someone who only wants "early stage". The
   sub-stages are a disclosure, closed by default. */
.frow { display: flex; align-items: center; gap: 2px; }
.frow > label { flex: 1; min-width: 0; }
.fkids {
  flex: none; width: 22px; height: 22px; padding: 0; cursor: pointer;
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: 3px; color: var(--muted);
  font: 600 13px/1 'IBM Plex Mono', monospace;
}
.fkids:hover { border-color: var(--accent); color: var(--accent); }
.fkids[aria-expanded="true"] { background: var(--accent-bg); color: var(--accent); border-color: var(--accent-2); }
.fsub {
  margin: 1px 0 4px 10px; padding-left: 9px;
  border-left: 1px solid var(--rule);
}
.fsub label { font-size: 13px; }
.fsub .fl { color: var(--muted); }

/* What the active filters cannot see. Sits under the result count rather than
   in the sidebar, because it is only true once a filter is on, and a warning
   that is always on screen stops being read. Deliberately quiet: this is a
   fact about the data, not an error the reader has made. */
.blindspot {
  margin: -2px 0 12px; font-size: 12.5px; color: var(--muted);
  border-left: 3px solid var(--rule); padding: 1px 0 1px 11px;
  max-width: 74ch;
}

/* GOV.UK-style disclosure. The explanation for a facet is real and worth
   keeping, and almost nobody needs it on the way past, so it collapses.
   Sidebar groups are now legend, hint, boxes — nothing else competing. */
.fhelp { margin: 7px 0 0; font-size: 12.5px; }
.fhelp > summary {
  cursor: pointer; color: var(--accent); text-decoration: underline;
  text-underline-offset: 2px; list-style: none; padding: 2px 0;
}
.fhelp > summary::-webkit-details-marker { display: none; }
.fhelp > summary::before { content: "\25b8 "; display: inline-block; width: 11px; }
.fhelp[open] > summary::before { content: "\25be "; }
.fhelp > summary:hover { color: var(--accent-2); }
.fhelp > div {
  border-left: 2px solid var(--rule); padding: 4px 0 2px 10px;
  margin: 4px 0 0 4px; color: var(--muted); line-height: 1.45;
}
.fhelp p { margin: 0 0 7px; }
.fhelp p:last-child { margin-bottom: 0; }

/* A merged entry. Its page survives because the id is a URL somebody may have
   cited; the notice is the whole point of the page, so it leads. */
.warn.moved { border-color: var(--accent-2); background: var(--accent-bg); }
.warn.moved strong { color: var(--accent); }
.warn.quiet { border-color: var(--rule); background: var(--alt); }
.warn.quiet strong { color: var(--muted); }

/* Page guidance. An amber warn box was doing this job, which told a reader
   something had gone wrong when nothing had. */
.inset {
  border-left: 3px solid var(--rule); padding: 2px 0 2px 16px;
  margin: 4px 0 20px; color: var(--muted);
}
.inset p { margin: 0 0 9px; }
.inset p:last-child { margin: 0; }
