/* ZipRail's and ZipPockets' websites. Docs/specs/website.md is the plan; the owner's brief of
   7 Oct 2026 asked for a bold page with its own identity, built around rail.
   Layout: a station concourse. A cobalt platform-sign band opens the page with a departure board
   hung across it; below it, short panels on a cool paper ground, each a heading and a line.
   TfL and National Rail sit side by side, equally (the owner, 8 Oct 2026; decision 0042).
   Colour: cobalt and signal orange are the app icon's own; amber is a departure board's LEDs; ink
   is the board. No TfL line colours and no roundel shapes anywhere (#125).
   Type: Big Shoulders Display for headings, Doto for the board, and the app's system stack for
   text (D5). Both faces are SIL OFL 1.1, self-hosted in /fonts with their licences; Big Shoulders
   is subset to Latin. Nothing is fetched from another origin.
   The CSP allows only this origin and no inline styles, so all styling is here.
   Website/zippockets/site.css must stay byte-identical: scripts/test-website.sh.
   The tests read the first :root block as light and the second as dark, and check every text
   pair at 4.5:1 or more. Token names are letters and hyphens, values #RRGGBB. */

@font-face {
  font-family: "Big Shoulders Display";
  src: url("/fonts/BigShouldersDisplay-ExtraBold.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Doto";
  src: url("/fonts/Doto-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light dark;
  --bg: #F2F4F8;
  --card: #FFFFFF;
  --line: #D3D9E5;
  --text: #0B1220;
  --muted: #4A5568;
  --link: #1B3FC4;
  --link-hover: #0F2A8A;
  --note-bg: #FFF0D6;
  --note-line: #E59A2E;
  --brand: #1B3FC4;
  --on-brand: #FFFFFF;
  --on-brand-muted: #D4DCFB;
  --on-brand-wash: rgb(255 255 255 / 0.12);
  --board: #0A0F1A;
  --board-edge: #263248;
  --led: #FFB020;
  --led-dim: #A8956E;
  --signal: #FF7A1A;
  --ink-bg: #0A0F1A;
  --ink-text: #E8ECF4;
  --ink-muted: #A3AEC2;
  --ink-link: #FFC24D;
  --focus: #1B3FC4;

  --display: "Big Shoulders Display", "Avenir Next Condensed", "Arial Narrow", sans-serif;
  --board-face: "Doto", ui-monospace, "SF Mono", Menlo, monospace;
  --body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, Roboto, sans-serif;
  --gutter: clamp(16px, 4vw, 40px);
  --measure: 40rem;
}

/* Dark mode keeps the board and the cobalt; the paper turns to night. The cobalt band deepens so
   white text stays calm on it, and links lighten to keep 4.5:1. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #070B14;
    --card: #0F1626;
    --line: #233049;
    --text: #EEF1F7;
    --muted: #A6B0C3;
    --link: #93A8FF;
    --link-hover: #BCCAFF;
    --note-bg: #2B1F0A;
    --note-line: #9A6418;
    --brand: #142F9E;
    --on-brand-muted: #C9D2F7;
    --board: #02050B;
    --board-edge: #2C3A55;
    --ink-bg: #0B1120;
    --focus: #93A8FF;
  }
}

* { box-sizing: border-box; }

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

/* A column, so the footer sits at the foot of a short page. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

main { flex: 1 0 auto; }

img, svg { max-width: 100%; }

a { color: var(--link); text-underline-offset: 0.18em; text-decoration-thickness: 0.08em; }
a:hover { color: var(--link-hover); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 4px; }

.skip {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 10;
  background: var(--card);
  color: var(--link);
  padding: 8px 14px;
  border-radius: 8px;
  border: 2px solid var(--link);
  --focus: var(--on-brand);
}
/* It appears over the cobalt sign bar, so its focus ring is white there. */
.skip:focus { top: 12px; }

.wrap {
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- the sign bar */

.top {
  background: var(--brand);
  color: var(--on-brand);
  --focus: var(--on-brand);
}
.top .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 14px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--on-brand);
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.75rem;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.brand:hover { color: var(--on-brand); }
.brand img { display: block; width: 34px; height: 34px; border-radius: 9px; }

.top nav { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 20px; font-size: 0.9375rem; font-weight: 600; }
.top nav a { color: var(--on-brand); text-decoration: none; padding: 6px 0; }
.top nav a:hover { color: var(--on-brand); text-decoration: underline; }
.nav-wide { display: none; }
@media (min-width: 40rem) { .nav-wide { display: inline; } }

/* ---------------------------------------------------------------- headings */

h1, h2, h3 { text-wrap: balance; }

h1, h2 {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: 0.005em;
}

h1 {
  font-size: clamp(2.75rem, 8vw, 4.5rem);
  line-height: 0.95;
  margin: 0 0 16px;
}

h2 {
  font-size: clamp(2.125rem, 6vw, 3.25rem);
  line-height: 0.98;
  margin: 0 0 12px;
}

h3 {
  font-size: 1.1875rem;
  line-height: 1.3;
  font-weight: 700;
  margin: 0 0 6px;
}

p, ul, ol, dl, blockquote, figure { margin: 0 0 12px; }

.eyebrow {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin: 0 0 12px;
}

.lead { font-size: clamp(1.125rem, 2.2vw, 1.3125rem); line-height: 1.45; max-width: 34rem; }
.muted { color: var(--muted); }

/* ---------------------------------------------------------------- the hero */

.hero {
  background: var(--brand);
  color: var(--on-brand);
  --focus: var(--on-brand);
  padding-block: 28px 56px;
  overflow: hidden;
}
.hero .eyebrow, .hero-note { color: var(--on-brand-muted); }
.hero h1 {
  font-size: clamp(3.5rem, 15vw, 7.5rem);
  line-height: 0.86;
  margin-bottom: 20px;
}
.hero h1 span { display: block; }
.hero .lead { margin-bottom: 24px; }

.hero-grid {
  display: grid;
  gap: 32px;
  align-items: start;
}
.hero-copy, .hero-grid .board { min-width: 0; }
.hero-shot { justify-self: center; }

@media (min-width: 60rem) {
  .hero { padding-block: 48px 72px; }
  .hero-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); column-gap: 56px; }
  .hero-shot { grid-row: 1 / span 2; grid-column: 2; align-self: center; }
}

/* "Coming soon to the App Store": a badge, not a link. Nothing to press until the app is there. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  padding: 10px 20px 10px 14px;
  border-radius: 14px;
  background: var(--board);
  color: var(--ink-text);
  box-shadow: 0 0 0 1px var(--board-edge);
}
.badge svg { width: 26px; height: 26px; flex: none; color: var(--led); }
.badge span { display: grid; line-height: 1.15; }
.badge small { font-size: 0.75rem; color: var(--ink-muted); letter-spacing: 0.02em; }
.badge b { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.01em; }
.hero-note { font-size: 0.9375rem; margin: 0; }

/* The two ways in, side by side: the badge, and joining the test by email. Both sit on the cobalt,
   so the join button is drawn in the text colour, with an inset ring the same height as the badge. */
.get { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 14px; margin: 0 0 14px; }
.get .badge { margin: 0; }
.join {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 10px 20px 10px 14px;
  border-radius: 14px;
  color: var(--on-brand);
  text-decoration: none;
  box-shadow: inset 0 0 0 2px var(--on-brand);
}
.join:hover { color: var(--on-brand); background: var(--on-brand-wash); }
.join svg { width: 26px; height: 26px; flex: none; }
.join span { display: grid; line-height: 1.15; }
.join small { font-size: 0.75rem; color: var(--on-brand-muted); letter-spacing: 0.02em; }
.join b { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.01em; }
.hero-note a, .hero-note a:hover { color: var(--on-brand); }

/* Where the password goes, one line under the buttons (the owner, 13 Oct 2026). */
.trust { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; font-weight: 600; font-size: 0.9375rem; line-height: 1.35; }
.trust svg { width: 22px; height: 22px; flex: none; }
sup { line-height: 0; }

/* ---------------------------------------------------------------- the departure board */

.board { margin: 0; }
.board-face {
  background: var(--board);
  color: var(--led);
  border-radius: 14px;
  padding: 16px 18px 18px;
  box-shadow: 0 0 0 1px var(--board-edge), 0 18px 40px -18px #000000;
  font-family: var(--board-face);
  font-weight: 800;
  font-variation-settings: "ROND" 100;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  overflow: hidden;
}
.board-head, .board-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.board-head {
  color: var(--led-dim);
  font-size: clamp(0.9375rem, 2.6vw, 1.125rem);
  letter-spacing: 0.04em;
  padding-bottom: 10px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--board-edge);
}
.board-row { font-size: clamp(1.25rem, 5vw, 2.125rem); }
.board-row + .board-row { margin-top: 6px; }
.b-dest { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-label { color: var(--led-dim); }
.b-time { white-space: nowrap; }
.b-claim { color: var(--led); }

/* The board shows one sample trip, leg by leg: a train, then the Tube, each claimed from its own
   company (U12). The train leg is over, so it stands still and shows no limit: each train company
   has its own. The Tube leg is the one that ticks. */
.leg + .leg {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--board-edge);
}
.leg-tag {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  color: var(--led-dim);
  font-size: clamp(0.875rem, 2.4vw, 1rem);
  letter-spacing: 0.04em;
}
.leg-mode {
  padding: 3px 8px 2px;
  border: 1px solid var(--led-dim);
  border-radius: 6px;
  color: var(--led);
}
.leg-status {
  margin-top: 10px;
  font-size: clamp(1.125rem, 3.6vw, 1.5rem);
  color: var(--signal);
}
.leg-status span { display: block; }

/* On the Tube leg, the expected minute ticks from :24 to :47. TfL pays from "more than 15
   minutes" on the Tube, so the status changes when the clock passes :39. At rest, and with reduced
   motion, the board shows its last frame: 08:47, 23 minutes late. @property makes the minute an
   integer that animates; a browser without it falls back to 47 in counter-reset, so it shows the
   last frame and nothing ticks. */
@property --minute {
  syntax: "<integer>";
  inherits: false;
  initial-value: 47;
}
.b-min { counter-reset: minute var(--minute, 47); }
.b-min::after { content: counter(minute, decimal-leading-zero); }

.board-meter {
  position: relative;
  height: 10px;
  margin: 18px 0 8px;
  border-radius: 5px;
  background: var(--board-edge);
}
.b-fill {
  position: absolute;
  inset: 0;
  border-radius: 5px;
  background: var(--signal);
  transform-origin: left center;
  transform: scaleX(0.7667);
}
.b-mark {
  position: absolute;
  left: 50%;
  top: -6px;
  bottom: -6px;
  width: 3px;
  margin-left: -1px;
  background: var(--led);
}
.board-scale {
  display: flex;
  justify-content: space-between;
  color: var(--led-dim);
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}
.board-scale span:nth-child(2) { color: var(--led); }

.board-status {
  display: grid;
  margin-top: 14px;
  font-size: clamp(1.125rem, 3.6vw, 1.5rem);
}
.board-status > span { grid-area: 1 / 1; }
.st-on, .st-late { opacity: 0; }
.st-over { color: var(--signal); }
.st-over span { display: block; }

.board figcaption {
  margin-top: 10px;
  font-size: 0.875rem;
  color: var(--on-brand-muted);
}

@media (prefers-reduced-motion: no-preference) {
  .b-min { animation: tick 3.2s linear 0.5s both; }
  .b-fill { animation: fill 3.2s linear 0.5s both; }
  .st-on { animation: show-on 3.2s linear 0.5s both; }
  .st-late { animation: show-late 3.2s linear 0.5s both; }
  .st-over { animation: show-over 3.2s linear 0.5s both; }
}

/* 0 to 25%: on time, held. 25% to 100%: the minute runs :24 to :47, one minute per 3.26%.
   An animated integer rounds to the nearest whole number, so the clock shows :25 from 26.7% and
   :40, the first minute more than 15 late, from 75.6%. The status changes on those frames. */
@keyframes tick {
  0%, 25% { --minute: 24; }
  100% { --minute: 47; }
}
@keyframes fill {
  0%, 25% { transform: scaleX(0); background: var(--led); }
  75.5% { background: var(--led); }
  75.6% { background: var(--signal); }
  100% { transform: scaleX(0.7667); background: var(--signal); }
}
@keyframes show-on {
  0%, 26.6% { opacity: 1; }
  26.7%, 100% { opacity: 0; }
}
@keyframes show-late {
  0%, 26.6% { opacity: 0; }
  26.7%, 75.5% { opacity: 1; }
  75.6%, 100% { opacity: 0; }
}
@keyframes show-over {
  0%, 75.5% { opacity: 0; }
  75.6%, 100% { opacity: 1; }
}

/* ---------------------------------------------------------------- phones */

/* ZipRail's own screens, captured from its demo with sample data, in a frame drawn here. */
.phone {
  position: relative;
  width: min(100%, 300px);
  margin: 0 auto;
  padding: 9px;
  border-radius: 48px;
  background: var(--board);
  box-shadow: 0 0 0 1px var(--board-edge), 0 30px 60px -30px #000000;
}
.phone::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 19px;
  left: 50%;
  width: 31%;
  height: 24px;
  transform: translateX(-50%);
  border-radius: 12px;
  background: var(--board);
}
.phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 39px;
}
.shot { margin: 0; }
.shot figcaption {
  margin-top: 12px;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--muted);
}
.hero .shot figcaption { color: var(--on-brand-muted); }

/* ---------------------------------------------------------------- panels */

.band { padding-block: 64px; }
.band + .band { border-top: 1px solid var(--line); }
.band-head { max-width: var(--measure); margin-bottom: 32px; }
.band-head p { font-size: 1.125rem; }
.band .eyebrow { color: var(--link); }
@media (min-width: 60rem) { .band { padding-block: 88px; } }

/* TfL's limits, one tile per service. */
.modes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 24px;
  padding: 0;
  list-style: none;
}
@media (min-width: 52rem) { .modes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }
/* A column whose name grows, so "Delayed more than" and the minutes line up across a row even
   when one name takes two lines. */
.mode {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  border-radius: 14px;
  background: var(--board);
  color: var(--ink-text);
  box-shadow: 0 0 0 1px var(--board-edge);
}
.mode svg { width: 30px; height: 30px; color: var(--led); }
.mode h4 { font-size: 1rem; line-height: 1.3; font-weight: 700; margin: 0; flex: 1; text-wrap: balance; }
.mode p { margin: 0; color: var(--ink-muted); font-size: 0.875rem; line-height: 1.2; }
.mode-min {
  display: block;
  font-family: var(--board-face);
  font-weight: 800;
  font-variation-settings: "ROND" 100;
  font-size: clamp(3rem, 10vw, 4.25rem);
  line-height: 1;
  color: var(--led);
}
.mode-min small { font-size: 0.35em; margin-left: 4px; color: var(--led-dim); }
/* National Rail's tiles carry words where TfL's carry minutes: its rule has no figure to show. */
.mode-word { font-size: clamp(1.625rem, 4.6vw, 2.25rem); line-height: 1.05; }
.modes-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* The rules, side by side: TfL's and National Rail's, each in its own words. One column on a phone,
   TfL first; two from 60rem, where TfL's four tiles fold to two by two. */
.rules { display: grid; gap: 56px; }
.rule { min-width: 0; border-top: 3px solid var(--text); padding-top: 16px; }
.rule-name {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.25rem, 6vw, 3rem);
  line-height: 0.95;
  margin: 0 0 10px;
}
.rule-lead { font-size: 1.125rem; max-width: var(--measure); margin-bottom: 24px; }
@media (min-width: 60rem) {
  .rules { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 48px; }
  .rule .modes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.source {
  max-width: var(--measure);
  margin: 0 0 20px;
  padding: 18px 20px;
  border-left: 4px solid var(--brand);
  background: var(--card);
  border-radius: 0 12px 12px 0;
}
.source p { margin: 0 0 8px; }
.source ul { margin: 0 0 8px; padding-left: 1.2em; }
.source cite { font-style: normal; font-size: 0.875rem; color: var(--muted); }
.fine { max-width: var(--measure); color: var(--muted); font-size: 0.9375rem; }

/* How it works: four steps, each with its screen. Two columns from 52rem, four from 70rem, so a
   phone never drops below about 230px wide. */
.steps {
  display: grid;
  gap: 48px;
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 52rem) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 48px 32px; } }
@media (min-width: 70rem) { .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px; } }
.step { display: grid; gap: 20px; align-content: start; }
.step-no {
  display: block;
  font-family: var(--board-face);
  font-weight: 800;
  font-variation-settings: "ROND" 100;
  font-size: 4rem;
  line-height: 1;
  color: var(--link);
  margin-bottom: 10px;
}
.step p { margin: 0; color: var(--muted); }
.step .phone { width: min(100%, 230px); }
.steps-note { margin: 32px 0 0; }
@media (min-width: 52rem) { .step .phone { width: min(100%, 260px); } }
/* Side by side, the words take the spare height, so the phones line up whatever the words' length. */
@media (min-width: 52rem) { .step { grid-template-rows: 1fr auto; align-content: stretch; } }
.hero-shot .phone { width: min(100%, 260px); }
@media (min-width: 60rem) { .hero-shot .phone { width: min(100%, 300px); } }

/* Privacy: plain promises. */
.points {
  display: grid;
  gap: 12px;
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
}
@media (min-width: 40rem) { .points { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.points li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: 14px;
  background: var(--card);
  border: 1px solid var(--line);
  font-weight: 600;
}
.points svg { width: 28px; height: 28px; flex: none; color: var(--link); }

/* Sound familiar? Each reason in a speech bubble, the passenger's words, with ZipRail's answer
   under it. */
.familiar { display: grid; gap: 32px 40px; margin: 0 0 28px; padding: 0; list-style: none; }
@media (min-width: 44rem) { .familiar { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.familiar li { display: grid; gap: 18px; align-content: start; min-width: 0; }
.familiar h3 {
  position: relative;
  margin: 0;
  padding: 20px 24px;
  border-radius: 20px;
  background: var(--card);
  border: 1px solid var(--line);
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.625rem, 3.4vw, 2.25rem);
  line-height: 1.05;
}
.familiar h3::after {
  content: "";
  position: absolute;
  left: 30px;
  bottom: -9px;
  width: 16px;
  height: 16px;
  background: var(--card);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transform: rotate(45deg);
}
.familiar p { margin: 0; padding-left: 4px; color: var(--muted); font-size: 1.0625rem; max-width: var(--measure); }
.familiar sup a { font-weight: 700; text-decoration: none; padding: 0 2px; }

/* One card. Two companies. A route line with three stops, drawn in the site's cobalt, never a TfL
   line colour (#125): you tap in, TfL charges you, one leg runs late. The last stop splits into
   two board-style tickets, one per company. Down the page on a phone; across from 52rem, where
   each stop draws the track to the next one. */
.route { display: grid; gap: 36px; margin: 0 0 40px; padding: 0; list-style: none; }
.stop { position: relative; min-width: 0; padding-left: 68px; }
.stop > svg {
  position: absolute;
  left: 0;
  top: 0;
  width: 48px;
  height: 48px;
  padding: 9px;
  border-radius: 50%;
  background: var(--card);
  border: 3px solid var(--link);
  color: var(--link);
}
.stop:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 22px;
  top: 48px;
  bottom: -36px;
  width: 4px;
  background: var(--link);
}
.stop h3 {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.75rem, 3.4vw, 2.125rem);
  line-height: 1.05;
  margin: 8px 0 8px;
}
.stop p { margin: 0; color: var(--muted); max-width: 26rem; }
@media (min-width: 52rem) {
  .route { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
  .stop { padding: 68px 0 0; }
  .stop:not(:last-child)::after { left: 48px; right: -32px; top: 22px; bottom: auto; width: auto; height: 4px; }
}
.tickets { display: grid; gap: 10px; margin: 16px 0 0; padding: 0; list-style: none; }
.tickets li {
  display: grid;
  gap: 6px;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--board);
  box-shadow: 0 0 0 1px var(--board-edge);
}
.tickets span { color: var(--ink-muted); font-size: 0.875rem; line-height: 1.3; }
.tickets b {
  font-family: var(--board-face);
  font-weight: 800;
  font-variation-settings: "ROND" 100;
  font-size: clamp(1.25rem, 3vw, 1.5rem);
  line-height: 1.1;
  color: var(--led);
}
.two-answer { max-width: var(--measure); font-size: 1.125rem; margin: 0; }
/* National Rail's words and ZipRail's answer: stacked on a phone, side by side from 60rem. */
.two-foot .source { margin-bottom: 20px; }
@media (min-width: 60rem) {
  .two-foot { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: center; }
  .two-foot .source { margin-bottom: 0; }
}

/* Fair questions: short answers in two columns. */
.doubts { display: grid; gap: 28px 48px; margin: 0; }
@media (min-width: 52rem) { .doubts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.doubts div { min-width: 0; border-top: 3px solid var(--text); padding-top: 12px; }
.doubts dt { font-family: var(--display); font-weight: 800; font-size: 1.75rem; line-height: 1.05; margin-bottom: 6px; }
.doubts dd { margin: 0; color: var(--muted); }

/* A single board line: the 404 page's "Not in service". */
.next-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
  max-width: var(--measure);
  margin: 0 0 28px;
  padding: 16px 20px;
  border-radius: 14px;
  background: var(--board);
  color: var(--led);
  box-shadow: 0 0 0 1px var(--board-edge);
  font-family: var(--board-face);
  font-weight: 800;
  font-variation-settings: "ROND" 100;
  font-size: clamp(1.375rem, 4.6vw, 2rem);
  line-height: 1.1;
}
.next-line span:last-child { color: var(--signal); }

/* Questions: native disclosure, no script. */
.faq { max-width: 48rem; margin: 0; }
.faq details { border-top: 1px solid var(--line); }
.faq details:last-child { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 18px 0;
  cursor: pointer;
  font-weight: 700;
  font-size: 1.125rem;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
/* The sign is drawn, not read: "/ ''" gives it no words, where the browser knows that syntax. */
.faq summary::after {
  content: "+";
  content: "+" / "";
  flex: none;
  font-family: var(--display);
  font-size: 1.75rem;
  line-height: 1;
  color: var(--link);
}
.faq details[open] summary::after { content: "\2212"; content: "\2212" / ""; }
.faq details p { margin: 0 0 18px; color: var(--muted); max-width: var(--measure); }

/* The closing band. */
.cta { background: var(--brand); color: var(--on-brand); --focus: var(--on-brand); padding-block: 64px; }
.cta h2 { font-size: clamp(3rem, 12vw, 6rem); line-height: 0.9; margin-bottom: 28px; }
.cta p:not(.badge) { color: var(--on-brand-muted); max-width: var(--measure); }
.cta a { color: var(--on-brand); }
.cta a:hover { color: var(--on-brand); }

/* ---------------------------------------------------------------- reading pages */

/* The reading column sits under the sign bar's left edge, at a comfortable measure. */
.doc { padding-block: 40px 64px; }
.doc > * { max-width: 44rem; }
.doc h1 { font-size: clamp(3rem, 10vw, 4.5rem); margin-top: 8px; }
.doc h2 {
  font-size: clamp(1.75rem, 5vw, 2.25rem);
  margin: 40px 0 10px;
  padding-top: 14px;
  border-top: 3px solid var(--text);
}
.doc h3 { margin-top: 24px; }
.doc ul, .doc ol { padding-left: 1.3em; }
.doc li { margin-bottom: 6px; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px 20px;
  margin: 20px 0;
}
.card > :last-child { margin-bottom: 0; }

.note {
  background: var(--note-bg);
  border: 1px solid var(--note-line);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 0 0 20px;
}
.note > :last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- the footer */

.site-footer {
  background: var(--ink-bg);
  color: var(--ink-muted);
  --focus: var(--ink-link);
  font-size: 0.9375rem;
}
.site-footer .wrap { padding-block: 32px 44px; }
.site-footer p { margin: 0 0 10px; max-width: var(--measure); }
.site-footer a { color: var(--ink-link); }
.site-footer a:hover { color: var(--ink-text); }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 4px 24px; margin-top: 14px; }
.site-footer nav a { padding: 6px 0; font-weight: 600; }
.foot-brand { font-family: var(--display); font-weight: 800; font-size: 1.5rem; color: var(--ink-text); }
