@layer reset {
  :where(h1, h2, h3, h4, h5, p, ul, ol, dl, dd, figure, blockquote, pre, table) {
    margin: 0;
  }
}

:root {
  --bg: #f0ecef;
  --ink: #2e262c;
  --accent: #a32a63;
  --accent2: #50505c;
  --surface: #fbf8fa;

  --slab: color-mix(in srgb, var(--bg) 82%, var(--accent2));
  --slab-deep: color-mix(in srgb, var(--bg) 62%, var(--accent2));
  --hairline: color-mix(in srgb, var(--ink) 22%, transparent);
  --hairline-firm: color-mix(in srgb, var(--ink) 42%, transparent);
  --quiet: color-mix(in srgb, var(--ink) 78%, var(--bg));
  --quieter: color-mix(in srgb, var(--ink) 70%, var(--bg));
  --accent-wash: color-mix(in srgb, var(--accent) 12%, var(--surface));
  --accent-edge: color-mix(in srgb, var(--accent) 55%, var(--accent2));
  --rail: color-mix(in srgb, var(--accent2) 78%, var(--ink));

  --u: 0.55rem;
  --gut: calc(var(--u) * 2.4);
  --hang: 2.35rem;
  --rail-h: 7px;
  --measure: 36rem;

  --head: "Economica", "Haettenschweiler", "Arial Narrow", sans-serif;
  --body: "Scada", "Trebuchet MS", "Segoe UI", sans-serif;

  --draw: 2400ms;
  --snap: 220ms;
  --settle: 450ms;
  --ease-rail: cubic-bezier(0.22, 0.68, 0.18, 1);
}

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

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

body {
  font-family: var(--body);
  font-size: clamp(0.97rem, 0.92rem + 0.3vw, 1.06rem);
  line-height: 1.62;
  color: var(--ink);
  background-color: var(--bg);
  /* concrete-wash: a poured, floated slab seen in raking light. Mottle, screed
     streaks and a faint magenta bloom where the trowel turned. */
  background-image:
    radial-gradient(118% 62% at 8% -6%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 62%),
    radial-gradient(76% 44% at 96% 12%, color-mix(in srgb, var(--surface) 86%, transparent), transparent 70%),
    radial-gradient(42% 30% at 24% 48%, color-mix(in srgb, var(--accent2) 9%, transparent), transparent 72%),
    radial-gradient(52% 36% at 78% 76%, color-mix(in srgb, var(--accent2) 7%, transparent), transparent 74%),
    repeating-linear-gradient(104deg,
      color-mix(in srgb, var(--ink) 3%, transparent) 0 1px,
      transparent 1px 11px),
    repeating-linear-gradient(16deg,
      color-mix(in srgb, var(--surface) 42%, transparent) 0 2px,
      transparent 2px 23px);
  background-attachment: fixed, fixed, fixed, fixed, scroll, scroll;
  margin: 0;
  overflow-wrap: break-word;
}

::selection {
  background: color-mix(in srgb, var(--accent) 30%, var(--surface));
  color: var(--ink);
}

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

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--snap) linear, background-color var(--snap) linear;
}

a:hover,
a:focus-visible {
  color: var(--ink);
  background-color: color-mix(in srgb, var(--accent) 16%, transparent);
}

/* ---------- hanging-indent heads ------------------------------------- */

h1,
h2,
h3,
h4 {
  font-family: var(--head);
  font-weight: 700;
  letter-spacing: 0.012em;
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--ink);
}

.hang {
  padding-left: var(--hang);
  text-indent: calc(var(--hang) * -1);
}

.hang-mark {
  display: inline-block;
  width: calc(var(--hang) - 0.55rem);
  margin-right: 0.55rem;
  text-indent: 0;
  border-top: 3px solid var(--accent);
  vertical-align: 0.28em;
}

.hang-mark[data-tone="grey"] {
  border-top-color: var(--accent2);
}

h1 {
  font-size: clamp(2.1rem, 1.5rem + 4.4vw, 3.5rem);
}

h2 {
  font-size: clamp(1.55rem, 1.25rem + 1.9vw, 2.3rem);
}

h3 {
  font-size: clamp(1.2rem, 1.08rem + 0.7vw, 1.46rem);
}

h4 {
  font-size: 1.04rem;
  letter-spacing: 0.07em;
}

p + p,
p + ul,
p + ol,
p + dl,
ul + p,
dl + p,
figure + p {
  margin-top: calc(var(--u) * 1.5);
}

.standfirst {
  font-size: 1.06em;
  color: var(--quiet);
}

.tag {
  font-family: var(--head);
  font-size: 0.9rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent2);
}

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

.skip {
  position: absolute;
  left: -200vw;
  top: 0;
  z-index: 40;
  padding: calc(var(--u) * 1.4) calc(var(--u) * 2);
  background: var(--ink);
  color: var(--surface);
  font-family: var(--head);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: left 0ms linear;
}

.skip:focus {
  left: 0;
  background: var(--ink);
  color: var(--surface);
}

/* Three measures live on this page and they are meant to be felt: the text
   spine, a wider one for the figures that are compared, and the band, which
   has no measure at all and runs the full window. */
.wrap {
  width: 100%;
  max-width: 74rem;
  margin: 0 auto;
  padding-inline: calc(var(--u) * 1.6);
}

.wrap-wide {
  width: 100%;
  max-width: 88rem;
  margin: 0 auto;
  padding-inline: calc(var(--u) * 1.6);
}

@media (min-width: 46rem) {
  .wrap,
  .wrap-wide {
    padding-inline: calc(var(--u) * 3);
  }
}

/* ---------- masthead + dropdown-panel wayfinder ---------------------- */

.masthead {
  border-bottom: 1px solid var(--hairline-firm);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(3px);
}

.masthead-in {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--u);
  min-height: calc(var(--u) * 8);
  padding-block: calc(var(--u) * 1.2);
}

.wordmark {
  font-family: var(--head);
  font-size: clamp(1.15rem, 1rem + 1.1vw, 1.6rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}

.wordmark:hover,
.wordmark:focus-visible {
  color: var(--accent);
  background: transparent;
}

.wordmark small {
  display: block;
  font-family: var(--body);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  color: var(--quieter);
  text-transform: uppercase;
  margin-top: 2px;
}

.wayfinder {
  position: relative;
}

.wayfinder-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: calc(var(--u) * 1.1) calc(var(--u) * 1.9);
  font-family: var(--head);
  font-size: 1.04rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
  color: var(--surface);
  background: var(--rail);
  border: 1px solid var(--rail);
  transition: background-color var(--snap) linear, color var(--snap) linear,
    letter-spacing var(--snap) linear;
}

.wayfinder-tab::-webkit-details-marker {
  display: none;
}

.wayfinder-tab:hover,
.wayfinder-tab:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
}

.wayfinder-caret {
  width: 0.72em;
  height: 0.72em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-0.1em);
  transition: transform var(--snap) var(--ease-rail);
}

.wayfinder[open] > .wayfinder-tab {
  background: var(--accent);
  border-color: var(--accent);
}

.wayfinder[open] .wayfinder-caret {
  transform: rotate(225deg) translateY(-0.1em);
}

.wayfinder-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 1px);
  right: 0;
  width: max-content;
  max-width: min(90vw, 29rem);
  padding: calc(var(--u) * 1.6);
  background: var(--surface);
  border: 1px solid var(--hairline-firm);
  border-top: var(--rail-h) solid var(--accent);
  box-shadow: 0 14px 26px -16px color-mix(in srgb, var(--ink) 55%, transparent);
}

.wayfinder-panel p {
  font-size: 0.82rem;
  color: var(--quieter);
  margin-bottom: var(--u);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.wayfinder-list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 1px;
  background: var(--hairline);
}

.wayfinder-list a {
  display: block;
  padding: calc(var(--u) * 1.1) calc(var(--u) * 1.3);
  background: var(--surface);
  text-decoration: none;
  color: var(--ink);
  transition: background-color var(--snap) linear, padding-left var(--snap) var(--ease-rail);
}

.wayfinder-list a:hover,
.wayfinder-list a:focus-visible {
  background: var(--accent-wash);
  padding-left: calc(var(--u) * 2.1);
}

.wayfinder-list b {
  display: block;
  font-family: var(--head);
  font-size: 1.14rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
}

.wayfinder-list span {
  display: block;
  font-size: 0.8rem;
  color: var(--quieter);
  line-height: 1.4;
}

.wayfinder-list a[aria-current="page"] {
  background: var(--accent-wash);
  box-shadow: inset 4px 0 0 var(--accent);
}

/* ---------- boxed dateline opener ------------------------------------ */

.opener {
  padding-block: calc(var(--u) * 4) calc(var(--u) * 2);
}

.datebox {
  border: 2px solid var(--ink);
  border-left-width: calc(var(--u) * 1.4);
  background: var(--surface);
  padding: calc(var(--u) * 2.2);
  box-shadow: 10px 10px 0 -2px color-mix(in srgb, var(--accent2) 26%, transparent);
}

.dateline {
  font-family: var(--head);
  font-size: 0.98rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--accent);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: var(--u);
  margin-bottom: calc(var(--u) * 1.8);
}

.dateline span {
  color: var(--accent2);
}

.datebox h1 {
  margin-bottom: calc(var(--u) * 1.6);
}

.datebox .lede {
  max-width: var(--measure);
}

/* ---------- bays, selector, card-shelf ------------------------------- */

.bay {
  padding-block: calc(var(--u) * 3.4);
  border-top: 1px solid var(--hairline);
}

.bay:first-of-type {
  border-top: 0;
}

.selector {
  display: inline-flex;
  flex: 0 0 auto;
  border: 1px solid var(--hairline-firm);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  padding: 3px;
  gap: 3px;
}

.selector > button {
  font-family: var(--head);
  font-size: 0.94rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: calc(var(--u) * 0.9) calc(var(--u) * 1.5);
  border: 0;
  background: transparent;
  color: var(--quiet);
  cursor: pointer;
  transition: background-color var(--snap) linear, color var(--snap) linear,
    box-shadow var(--snap) linear;
}

.selector > button:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.selector > button[aria-checked="true"] {
  background: var(--ink);
  color: var(--surface);
  box-shadow: inset 0 -3px 0 var(--accent);
}

.rack {
  display: grid;
  gap: calc(var(--u) * 2.6);
}

/* a shelf: cards stand ON a rail, with steel brackets at the ends */
.shelf {
  position: relative;
  padding-bottom: calc(var(--rail-h) + var(--u) * 1.2);
  transition: opacity var(--settle) linear, filter var(--settle) linear;
}

.shelf::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--rail-h);
  background-color: var(--rail);
  background-image:
    repeating-linear-gradient(135deg,
      color-mix(in srgb, var(--surface) 24%, transparent) 0 4px,
      transparent 4px 14px),
    linear-gradient(color-mix(in srgb, var(--rail) 88%, var(--surface)),
      color-mix(in srgb, var(--rail) 66%, var(--ink)));
  background-size: 28px 100%, 100% 100%;
  background-repeat: repeat, no-repeat;
  box-shadow: 0 2px 5px -2px color-mix(in srgb, var(--ink) 60%, transparent);
  transition: background-color var(--snap) linear, height var(--snap) var(--ease-rail);
}

.shelf::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--rail-h) + 9px);
  background:
    linear-gradient(var(--accent2), var(--accent2)) left bottom / 10px 100% no-repeat,
    linear-gradient(var(--accent2), var(--accent2)) right bottom / 10px 100% no-repeat;
  opacity: 0.55;
}

.shelf-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 calc(var(--u) * 1.6);
  padding-bottom: var(--u);
  border-bottom: 1px dashed var(--hairline);
  margin-bottom: calc(var(--u) * 1.8);
}

.shelf-strip h3 {
  color: var(--accent2);
}

.shelf[data-trade="haul"] .shelf-strip h3 {
  color: var(--accent);
}

.shelf-strip .shelf-note {
  font-size: 0.82rem;
  color: var(--quieter);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.shelf-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--settle) var(--ease-rail);
}

.shelf-body > div {
  overflow: hidden;
  min-height: 0;
  visibility: visible;
  transition: opacity var(--settle) linear, visibility 0s linear 0s;
}

.shelf-cards {
  display: grid;
  gap: calc(var(--u) * 1.6);
  padding-bottom: calc(var(--u) * 1.6);
}

@media (min-width: 40rem) {
  .shelf-cards[data-cols="2"] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 58rem) {
  .shelf-cards[data-cols="3"] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-bottom: 3px solid var(--hairline-firm);
  padding: calc(var(--u) * 1.8);
  transition: transform var(--snap) var(--ease-rail), border-bottom-color var(--snap) linear,
    box-shadow var(--snap) linear;
}

.card:hover {
  transform: translateY(-3px);
  border-bottom-color: var(--accent);
  box-shadow: 0 10px 16px -14px color-mix(in srgb, var(--ink) 70%, transparent);
}

.card h4 {
  color: var(--accent2);
  margin-bottom: calc(var(--u) * 0.9);
}

.card p {
  font-size: 0.94rem;
}

.card dl {
  margin-top: var(--u);
  font-size: 0.88rem;
}

.card dt {
  font-family: var(--head);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--quieter);
  font-size: 0.82rem;
  margin-top: calc(var(--u) * 0.8);
}

.card dd {
  margin-left: 0;
}

/* forward / back states only exist once the script has run */
.has-js .shelf[data-state="back"] {
  opacity: 0.74;
  filter: saturate(0.42);
}

/* The collapsed shelf keeps its strip readable (see chooseShelf in script.js),
   but the dim above composites the strip's note toward the page ground, which
   drops --quieter from 4.91:1 to 3.13:1. Opacity on the group cannot be undone
   by a descendant, so the note carries a darker level for as long as the dim
   is on it. The dark variant is compensated the other way, beside its own dim. */
.has-js .shelf:not(.shelf-dark)[data-state="back"] .shelf-note {
  color: color-mix(in srgb, var(--ink) 90%, var(--bg));
}

.has-js .shelf[data-state="back"] .shelf-body {
  grid-template-rows: 0fr;
}

.has-js .shelf[data-state="back"] .shelf-body > div {
  opacity: 0;
  /* held visible for the length of the collapse, then taken out of the
     accessibility tree - belt and braces beside the inert attribute */
  visibility: hidden;
  transition: opacity var(--settle) linear, visibility 0s linear var(--settle);
}

.has-js .shelf[data-state="back"]::after {
  height: 3px;
}

/* the rail hatch creeps one step as a shelf arrives at the front */
.has-js .shelf[data-state="forward"]::after {
  animation: railCreep 1300ms var(--ease-rail) 1;
}

.has-js .shelf[data-state="forward"] .shelf-strip {
  border-bottom-style: solid;
  border-bottom-color: var(--accent-edge);
}

.has-js .shelf[data-state="back"] .shelf-strip {
  border-bottom: 0;
  margin-bottom: var(--u);
}

.has-js .shelf[data-state="back"] .shelf-note::after {
  content: " — on the back shelf";
}

/* ---------- figures: tachograph trace + site-day band ---------------- */

figure.plate {
  background: var(--surface);
  border: 1px solid var(--hairline-firm);
  padding: calc(var(--u) * 1.6);
}

figure.plate svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

figcaption {
  font-size: 0.84rem;
  color: var(--quiet);
  margin-top: calc(var(--u) * 1.4);
  padding-top: var(--u);
  border-top: 1px solid var(--hairline);
}

.trace-grid line {
  stroke: var(--hairline);
  stroke-width: 1;
}

.trace-axis text,
.band-scale text {
  font-family: var(--body);
  font-size: 12px;
  fill: var(--quieter);
  letter-spacing: 0.04em;
}

.trace-lane text {
  font-family: var(--head);
  font-size: 13px;
  letter-spacing: 0.1em;
  fill: var(--accent2);
  text-transform: uppercase;
}

.trace-blk {
  opacity: 0;
  transition: opacity 320ms linear;
}

.trace-blk[data-kind="drive"] {
  fill: var(--accent);
}

.trace-blk[data-kind="work"] {
  fill: url(#haul-hatch);
  stroke: var(--accent2);
  stroke-width: 1;
}

.trace-stylus {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2.4;
  stroke-linejoin: miter;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  transition: stroke-dashoffset var(--draw) linear;
}

.trace-limit {
  fill: none;
  stroke: var(--accent2);
  stroke-width: 2;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  transition: stroke-dashoffset var(--draw) linear;
}

.trace-limit-label {
  font-family: var(--head);
  font-size: 13px;
  letter-spacing: 0.12em;
  fill: var(--accent2);
  opacity: 0;
  transition: opacity 300ms linear 1900ms;
}

.trace-stop {
  opacity: 0;
  transition: opacity 260ms linear 2300ms;
}

.trace-stop line {
  stroke: var(--accent);
  stroke-width: 2.4;
}

.trace-stop text {
  font-family: var(--head);
  font-size: 13px;
  letter-spacing: 0.1em;
  fill: var(--accent);
}

.is-drawn .trace-stylus,
.is-drawn .trace-limit {
  stroke-dashoffset: 0;
}

.is-drawn .trace-blk {
  opacity: 1;
}

.is-drawn .trace-limit-label {
  opacity: 1;
}

.is-drawn .trace-stop {
  opacity: 1;
  animation: limitTick 900ms var(--ease-rail) 2300ms 2;
}

@keyframes limitTick {
  0% {
    transform: translateX(0);
  }
  38% {
    transform: translateX(5px);
  }
  100% {
    transform: translateX(0);
  }
}

@keyframes outSettle {
  0% {
    box-shadow: inset 0 0 0 2px var(--accent);
  }
  100% {
    box-shadow: inset 0 0 0 2px transparent;
  }
}

@keyframes railCreep {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 28px 0;
  }
}

.band-lane rect {
  transform-box: fill-box;
  transform-origin: left center;
  transform: scaleX(0.001);
  transition: transform 620ms var(--ease-rail);
}

.is-drawn .band-lane rect {
  transform: scaleX(1);
}

.band-lane text {
  font-family: var(--body);
  font-size: 12px;
  fill: var(--ink);
}

.band-lane-title {
  font-family: var(--head) !important;
  font-size: 13px !important;
  letter-spacing: 0.1em;
  fill: var(--accent2) !important;
}

.seg-open {
  fill: color-mix(in srgb, var(--accent) 26%, var(--surface));
}

.seg-quiet {
  fill: url(#works-hatch);
}

.seg-shut {
  fill: color-mix(in srgb, var(--accent2) 18%, var(--surface));
}

.seg-tip {
  fill: var(--accent);
}

.band-rule {
  stroke: var(--hairline-firm);
  stroke-width: 1;
}

/* Winding the trace back to its start must not itself be animated: the
   transition would run forwards towards 'undrawn' and the replay would then
   reverse it a frame later, so the line would never leave zero. */
.plate.is-rewinding,
.plate.is-rewinding * {
  transition: none !important;
}

.replay {
  margin-top: calc(var(--u) * 1.4);
  font-family: var(--head);
  font-size: 0.92rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: calc(var(--u) * 0.9) calc(var(--u) * 1.6);
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--hairline-firm);
  cursor: pointer;
  transition: background-color var(--snap) linear, color var(--snap) linear,
    border-color var(--snap) linear;
}

.replay:hover,
.replay:focus-visible {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--surface);
}

/* ---------- widgets -------------------------------------------------- */

.calc {
  background: var(--surface);
  border: 1px solid var(--hairline-firm);
  border-top: var(--rail-h) solid var(--accent2);
  padding: calc(var(--u) * 1.8);
}

.shelf[data-trade="haul"] .calc {
  border-top-color: var(--accent);
}

.calc fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

.calc legend {
  font-family: var(--head);
  font-size: 1.02rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent2);
  padding: 0;
  margin-bottom: calc(var(--u) * 1.4);
}

.calc-rows {
  display: grid;
  gap: calc(var(--u) * 1.2);
}

@media (min-width: 34rem) {
  .calc-rows {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.calc-rows label {
  display: block;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--quieter);
}

.calc-rows label span {
  display: block;
  margin-bottom: 4px;
}

.calc-rows input {
  width: 100%;
  font-family: var(--body);
  font-size: 1rem;
  color: var(--ink);
  padding: calc(var(--u) * 0.9) var(--u);
  background: color-mix(in srgb, var(--bg) 60%, var(--surface));
  border: 1px solid var(--hairline-firm);
  transition: border-color var(--snap) linear, background-color var(--snap) linear,
    box-shadow var(--snap) linear;
}

/* The ring is hung on the label, not on the control. Focus inside an
   input[type=time] sits in the browser's own shadow tree, and the host
   element then matches neither :focus nor :focus-visible - a time field
   styled through input:focus gets no ring at all. :focus-within on the
   wrapping label does match, for every control in the form. */
.calc-rows label:focus-within input,
.calc-rows input:focus {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: inset 0 -2px 0 var(--accent);
  outline: 3px solid var(--accent);
  outline-offset: 1px;
}

.calc-rows label:focus-within > span {
  color: var(--accent);
}

.calc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--u);
  margin-top: calc(var(--u) * 1.6);
}

.calc-actions button {
  font-family: var(--head);
  font-size: 1rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: calc(var(--u) * 1) calc(var(--u) * 2.2);
  border: 0;
  color: var(--surface);
  background: var(--ink);
  cursor: pointer;
  transition: background-color var(--snap) linear, transform var(--snap) var(--ease-rail);
}

.calc-actions button:hover,
.calc-actions button:focus-visible {
  background: var(--accent);
  transform: translateY(-1px);
}

.calc-out {
  margin-top: calc(var(--u) * 1.8);
  padding: calc(var(--u) * 1.5);
  background: color-mix(in srgb, var(--bg) 72%, var(--surface));
  border-left: 4px solid var(--accent2);
  font-size: 0.94rem;
}

.shelf[data-trade="haul"] .calc-out {
  border-left-color: var(--accent);
}

.calc-out.is-fresh {
  animation: outSettle 900ms linear;
}

.calc-out strong {
  font-family: var(--head);
  font-size: 1.22rem;
  letter-spacing: 0.04em;
  display: block;
  color: var(--ink);
}

.calc-out ul {
  list-style: none;
  padding: 0;
  margin-top: var(--u);
  display: grid;
  gap: 4px;
}

.calc-out li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 var(--u);
  padding-block: 3px;
  border-bottom: 1px dotted var(--hairline);
  font-variant-numeric: tabular-nums;
}

.calc-out li b {
  font-family: var(--head);
  letter-spacing: 0.04em;
}

.sum {
  font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  padding: 1px 5px;
}

.flag {
  display: inline-block;
  margin-top: var(--u);
  padding: 4px 9px;
  font-family: var(--head);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: var(--accent);
  color: var(--surface);
}

.flag[data-ok="yes"] {
  background: var(--accent2);
}

.guide-only {
  margin-top: var(--u);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--quieter);
}

/* ---------- plain prose blocks, tables, lists ------------------------ */

.prose {
  max-width: var(--measure);
}

.keep {
  width: 100%;
  border-collapse: collapse;
  margin-top: calc(var(--u) * 1.6);
  font-size: 0.92rem;
}

.keep caption {
  text-align: left;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--quieter);
  padding-bottom: var(--u);
}

.keep th,
.keep td {
  text-align: left;
  vertical-align: top;
  padding: calc(var(--u) * 1.1) var(--u);
  border-bottom: 1px solid var(--hairline);
}

.keep thead th {
  font-family: var(--head);
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--surface);
  background: var(--accent2);
}

.keep tbody tr {
  transition: background-color var(--snap) linear;
}

.keep tbody tr:hover {
  background: var(--accent-wash);
}

.callout {
  margin-top: calc(var(--u) * 2);
  padding: calc(var(--u) * 1.6) calc(var(--u) * 1.8);
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
  font-size: 0.94rem;
}

.callout b {
  font-family: var(--head);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: block;
  margin-bottom: 4px;
  color: var(--accent);
}

.writeto {
  display: grid;
  gap: calc(var(--u) * 1.8);
  margin-top: calc(var(--u) * 1.6);
}

@media (min-width: 46rem) {
  .writeto {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.writeto > div {
  border-left: 3px solid var(--hairline-firm);
  padding-left: calc(var(--u) * 1.6);
  transition: border-left-color var(--snap) linear;
}

.writeto > div:hover {
  border-left-color: var(--accent);
}

.subjectline {
  display: inline-block;
  margin-top: var(--u);
  padding: 3px 8px;
  font-family: var(--head);
  letter-spacing: 0.06em;
  background: var(--slab);
  border: 1px dashed var(--hairline-firm);
}

/* Two adjacent prose sections read as one figure repeated, which is the
   whole complaint this pass answers. The longer of the two is set in two
   columns with a rule between, so the page's closing stretch has a shape
   as well as a heading. */
.twocol {
  margin-top: calc(var(--u) * 1.6);
}

.twocol .prose,
.twocol > p {
  max-width: none;
}

@media (min-width: 54rem) {
  .twocol {
    columns: 2;
    column-gap: calc(var(--u) * 5);
    column-rule: 1px solid var(--hairline);
  }

  .twocol > p + p {
    margin-top: calc(var(--u) * 1.5);
  }
}

/* ---------- maps and diagrams ---------------------------------------- */

.schematic .road {
  fill: none;
  stroke: var(--accent2);
  stroke-width: 7;
  stroke-linecap: round;
}

.schematic .road-minor {
  fill: none;
  stroke: var(--hairline-firm);
  stroke-width: 3.5;
  stroke-dasharray: 9 6;
}

.schematic .water {
  fill: color-mix(in srgb, var(--accent2) 16%, var(--surface));
}

.schematic .quay {
  fill: var(--slab-deep);
}

.schematic .yard {
  fill: var(--accent);
}

.schematic text {
  font-family: var(--body);
  font-size: 12.5px;
  fill: var(--ink);
}

.schematic .label-road {
  font-family: var(--head);
  font-size: 14px;
  letter-spacing: 0.1em;
  fill: var(--accent2);
}

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

.footer {
  margin-top: calc(var(--u) * 5);
  border-top: var(--rail-h) solid var(--ink);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--ink) 7%, transparent) 0 1px,
    transparent 1px 14px);
}

.footer-in {
  display: grid;
  gap: calc(var(--u) * 2.4);
  padding-block: calc(var(--u) * 3.4);
}

@media (min-width: 48rem) {
  .footer-in {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  }
}

.footer h2 {
  font-size: 1.14rem;
  letter-spacing: 0.1em;
  margin-bottom: var(--u);
}

address.office {
  font-style: normal;
  font-size: 0.98rem;
  line-height: 1.75;
}

address.office b {
  font-family: var(--head);
  font-size: 1.2rem;
  letter-spacing: 0.06em;
  display: block;
}

.registered {
  margin-top: calc(var(--u) * 1.6);
  font-size: 0.86rem;
  color: var(--quiet);
  line-height: 1.8;
}

.registered span {
  display: block;
}

.footer-links {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 2px;
  font-size: 0.92rem;
}

.footer-links a {
  display: inline-block;
  padding-block: 2px;
  text-decoration-color: var(--hairline-firm);
  transition: text-decoration-color var(--snap) linear;
}

.footer-links a:hover {
  text-decoration-color: var(--accent);
}

.mailto {
  font-family: var(--head);
  font-size: 1.1rem;
  letter-spacing: 0.04em;
  word-break: break-all;
}

.sic-note {
  margin-top: calc(var(--u) * 1.6);
  font-size: 0.8rem;
  color: var(--quieter);
}

/* ---------- SVG pattern strokes and labels sitting on dark fills ------ */

#haul-hatch line {
  stroke: var(--accent2);
}

#works-hatch line {
  stroke: var(--accent);
}

.band-lane text.on-dark,
.schematic text.on-dark {
  fill: var(--surface);
}

.schematic .hold {
  fill: color-mix(in srgb, var(--accent2) 22%, var(--surface));
  stroke: var(--hairline-firm);
  stroke-width: 1;
}

.schematic .marker {
  fill: var(--accent);
}

.schematic .queue rect {
  fill: var(--accent2);
  transform-box: fill-box;
  transform-origin: left center;
  transform: scaleX(0.02);
  transition: transform 420ms var(--ease-rail);
}

.is-drawn .schematic .queue rect:nth-of-type(2) {
  transition-delay: 160ms;
}

.is-drawn .schematic .queue rect:nth-of-type(3) {
  transition-delay: 320ms;
}

.is-drawn .schematic .queue rect {
  transform: scaleX(1);
}

.schematic .road {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  transition: stroke-dashoffset 1700ms linear;
}

.is-drawn .schematic .road {
  stroke-dashoffset: 0;
}

.schematic .road-minor {
  opacity: 0;
  transition: opacity 500ms linear 900ms;
}

.is-drawn .schematic .road-minor {
  opacity: 1;
}

/* The finished state for a visitor with no script lives in a <noscript>
   block in the page head, NOT here behind html:not(.has-js). It was here,
   and it quietly killed the set-piece: the undrawn value only became the
   computed value at the moment the script added .has-js, so the trace spent
   its first frames transitioning UP towards undrawn and was then sent
   straight back to zero. The line never visibly moved. A rule that only
   applies when there is no script cannot be written in a file that the
   script's own class selector can switch off mid-transition. */

/* ====================================================================
   COMPOSITION
   One shape per section, each used once. The pairing of the two trades is
   what every shape has to carry; the shape is how it carries it, and no
   two sections carry it the same way.
   ==================================================================== */

/* ---------- 1 · figure-pair ------------------------------------------ */

.pair-sec {
  padding-block: calc(var(--u) * 3.6) calc(var(--u) * 3.2);
}

.pair-mast {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 1.6);
  margin-bottom: calc(var(--u) * 2.6);
}

.pair-mast .standfirst {
  max-width: 46rem;
  margin-top: var(--u);
}

@media (min-width: 56rem) {
  .pair-mast {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: calc(var(--u) * 3);
  }
}

.pair {
  display: grid;
  gap: calc(var(--u) * 3);
  align-items: start;
}

@media (min-width: 62rem) {
  .pair {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: calc(var(--u) * 3.6);
    transition: grid-template-columns var(--settle) var(--ease-rail);
  }

  /* The tab does not hide the other day here - it gives one of them the
     wider panel. A comparison you cannot see both halves of is not one. */
  .has-js .pair:has(.fig[data-trade="haul"][data-state="forward"]) {
    grid-template-columns: minmax(0, 1.42fr) minmax(0, 1fr);
  }

  .has-js .pair:has(.fig[data-trade="works"][data-state="forward"]) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.42fr);
  }
}

.fig {
  min-width: 0;
}

.fig-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 calc(var(--u) * 1.4);
  border-top: 6px solid var(--accent2);
  padding-top: var(--u);
  margin-bottom: calc(var(--u) * 1.4);
  transition: border-top-color var(--settle) linear;
}

.fig[data-trade="haul"] .fig-head {
  border-top-color: var(--accent);
}

.fig-head h3 {
  color: var(--accent2);
}

.fig[data-trade="haul"] .fig-head h3 {
  color: var(--accent);
}

.fig-note {
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--quieter);
}

.fig .plate {
  border-width: 1px;
  transition: opacity var(--settle) linear, box-shadow var(--settle) linear;
}

.has-js .fig[data-state="forward"] .plate {
  box-shadow: 0 16px 24px -22px color-mix(in srgb, var(--ink) 80%, transparent);
}

.has-js .fig[data-state="back"] .fig-head {
  border-top-color: var(--hairline-firm);
}

.has-js .fig[data-state="back"] .plate {
  opacity: 0.9;
}

/* a pair whose two halves are different kinds of drawing, so the weighting
   is fixed rather than switched: a map and a clock are not interchangeable */
@media (min-width: 62rem) {
  .pair-weighted {
    grid-template-columns: minmax(0, 1.52fr) minmax(0, 1fr);
  }
}

.win-axis,
.win-tick line {
  stroke: var(--hairline-firm);
  stroke-width: 1.5;
}

.win-tick text {
  font-family: var(--body);
  font-size: 12.5px;
  fill: var(--quieter);
}

.win-band {
  fill: var(--accent);
  transform-box: fill-box;
  transform-origin: top center;
  transform: scaleY(0.02);
  transition: transform 620ms var(--ease-rail);
}

.is-drawn .win-band {
  transform: scaleY(1);
}

.win-band-label {
  font-family: var(--head);
  font-size: 13px;
  letter-spacing: 0.1em;
  fill: var(--surface);
}

.win-mark {
  opacity: 0;
  transition: opacity 360ms linear 700ms;
}

.win-mark[data-when="inside"] {
  transition-delay: 980ms;
}

.win-mark[data-when="late"] {
  transition-delay: 1260ms;
}

.is-drawn .win-mark {
  opacity: 1;
}

.win-mark line {
  stroke: var(--accent2);
  stroke-width: 2;
  stroke-dasharray: 6 5;
}

.win-mark[data-when="inside"] line {
  stroke: var(--accent);
  stroke-dasharray: none;
}

.win-mark path {
  fill: var(--accent2);
}

.win-mark[data-when="inside"] path {
  fill: var(--accent);
}

.win-mark text {
  font-family: var(--body);
  font-size: 12.5px;
  fill: var(--ink);
}

.win-foot {
  font-family: var(--head);
  font-size: 12px;
  letter-spacing: 0.08em;
  fill: var(--quieter);
}

/* ---------- 2 · full-bleed-band -------------------------------------- */

.gateband {
  margin-block: calc(var(--u) * 1.5);
  padding-block: calc(var(--u) * 4.6);
  color: var(--surface);
  background-color: var(--rail);
  background-image:
    radial-gradient(88% 72% at 10% -10%, color-mix(in srgb, var(--accent) 38%, transparent), transparent 66%),
    radial-gradient(60% 52% at 94% 108%, color-mix(in srgb, var(--accent2) 60%, transparent), transparent 70%),
    repeating-linear-gradient(104deg,
      color-mix(in srgb, var(--surface) 6%, transparent) 0 1px,
      transparent 1px 13px);
  border-block: 3px solid var(--ink);
}

.gateband h2,
.gateband h3,
.gateband h4 {
  color: var(--surface);
}

.gateband .hang-mark[data-tone="band"] {
  border-top-color: var(--surface);
}

.gateband-mast {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--u) * 1.6);
}

@media (min-width: 52rem) {
  .gateband-mast {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: calc(var(--u) * 3);
  }
}

.gateband-lede {
  max-width: 44rem;
  margin-top: calc(var(--u) * 1.8);
  color: color-mix(in srgb, var(--surface) 80%, var(--rail));
}

.gateband .rack,
.gateband-lede + .gatelist {
  margin-top: calc(var(--u) * 3.2);
}

.shelf-dark::after {
  background-color: color-mix(in srgb, var(--surface) 62%, var(--rail));
  background-image:
    repeating-linear-gradient(135deg,
      color-mix(in srgb, var(--ink) 40%, transparent) 0 4px,
      transparent 4px 14px);
  box-shadow: none;
}

.shelf-dark::before {
  background:
    linear-gradient(var(--surface), var(--surface)) left bottom / 10px 100% no-repeat,
    linear-gradient(var(--surface), var(--surface)) right bottom / 10px 100% no-repeat;
  opacity: 0.32;
}

/* a shelf pushed back on the dark band still has to read as a shelf and not
   as a stray dashed line */
.has-js .shelf-dark[data-state="back"]::after {
  height: 4px;
  background-image: none;
  background-color: color-mix(in srgb, var(--surface) 44%, var(--rail));
}

.shelf-dark .shelf-strip {
  border-bottom-color: color-mix(in srgb, var(--surface) 34%, transparent);
}

.shelf-dark[data-trade="haul"] .shelf-strip h3 {
  color: color-mix(in srgb, var(--accent) 46%, var(--surface));
}

.shelf-dark .shelf-note {
  color: color-mix(in srgb, var(--surface) 64%, var(--rail));
}

.has-js .shelf-dark[data-state="forward"] .shelf-strip {
  border-bottom-color: color-mix(in srgb, var(--surface) 62%, transparent);
}

.has-js .shelf-dark[data-state="back"] {
  opacity: 0.7;
  filter: none;
}

/* Same dim, opposite direction: here the note is light on the rail-dark band,
   so the composite darkens it (4.65:1 forward, 3.24:1 back) and it has to be
   lifted toward --surface rather than toward --ink. */
.has-js .shelf-dark[data-state="back"] .shelf-note {
  color: color-mix(in srgb, var(--surface) 92%, var(--rail));
}

.gatelist {
  display: grid;
  gap: calc(var(--u) * 2.4);
  padding-bottom: calc(var(--u) * 1.4);
}

@media (min-width: 52rem) {
  .gatelist {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
  }

  .gatelist > div {
    padding-inline: calc(var(--u) * 2.4);
    border-left: 1px solid color-mix(in srgb, var(--surface) 24%, transparent);
  }

  .gatelist > div:first-child {
    padding-left: 0;
    border-left: 0;
  }

  .gatelist > div:last-child {
    padding-right: 0;
  }
}

.gatelist h4 {
  color: color-mix(in srgb, var(--accent) 37%, var(--surface));
  margin-bottom: calc(var(--u) * 0.9);
  transition: color var(--snap) linear;
}

.gatelist > div:hover h4 {
  color: var(--surface);
}

.gatelist p {
  font-size: 0.95rem;
  color: color-mix(in srgb, var(--surface) 88%, var(--rail));
}

.selector-dark {
  border-color: color-mix(in srgb, var(--surface) 42%, transparent);
  background: color-mix(in srgb, var(--ink) 46%, transparent);
}

.selector-dark > button {
  color: color-mix(in srgb, var(--surface) 74%, var(--rail));
}

.selector-dark > button:hover {
  color: var(--surface);
  background: color-mix(in srgb, var(--surface) 16%, transparent);
}

.selector-dark > button[aria-checked="true"] {
  background: var(--surface);
  color: var(--ink);
  box-shadow: inset 0 -3px 0 var(--accent);
}

.gateband :focus-visible {
  outline-color: var(--surface);
}

/* ---------- 3 · ledger-rows ------------------------------------------ */

.docket-sec {
  padding-block: calc(var(--u) * 4);
}

.docket {
  width: 100%;
  border-collapse: collapse;
  margin-top: calc(var(--u) * 2);
  font-size: 0.94rem;
}

.docket caption {
  text-align: left;
  font-size: 0.88rem;
  color: var(--quiet);
  max-width: 40rem;
  padding-bottom: calc(var(--u) * 1.6);
}

.docket thead th {
  font-family: var(--head);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: left;
  color: var(--quieter);
  padding: calc(var(--u) * 0.7) var(--u);
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--hairline-firm);
}

.docket tbody th[scope="row"] {
  font-family: var(--head);
  font-size: 1.04rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: left;
  vertical-align: top;
  color: var(--ink);
  padding: calc(var(--u) * 1.15) var(--u);
  border-bottom: 1px dotted var(--hairline);
}

.docket td {
  vertical-align: top;
  padding: calc(var(--u) * 1.15) var(--u);
  border-bottom: 1px dotted var(--hairline);
}

.docket td:last-child {
  color: var(--quiet);
  font-size: 0.9rem;
}

.docket tbody tr {
  transition: background-color var(--snap) linear;
}

.docket tbody tr:not(.docket-group):hover {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.docket-group th {
  font-family: var(--head);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: left;
  color: var(--accent);
  padding: calc(var(--u) * 2.6) var(--u) calc(var(--u) * 0.5);
  border-bottom: 2px solid var(--accent);
}

.docket tbody tr:first-child .docket-group th,
.docket-group:first-child th {
  padding-top: calc(var(--u) * 1.4);
}

.docket-group[data-trade="works"] th {
  color: var(--accent2);
  border-bottom-color: var(--accent2);
}

/* A three-column ledger will not fit a 320 px screen, so below the spine
   width each row becomes a block and the column heads move onto the cells
   they label. The table stays a table; only the arrangement changes. */
@media (max-width: 45.99rem) {
  .docket thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .docket tbody tr {
    display: block;
    padding-block: calc(var(--u) * 0.6);
  }

  .docket tbody th[scope="row"] {
    display: block;
    padding: calc(var(--u) * 1.2) 0 calc(var(--u) * 0.4);
    border-bottom: 0;
  }

  .docket td {
    display: block;
    padding: 0 0 calc(var(--u) * 0.6);
    border-bottom: 0;
  }

  .docket td::before {
    content: attr(data-col) " — ";
    font-family: var(--head);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-size: 0.78rem;
    color: var(--quieter);
  }

  .docket tbody tr:not(.docket-group) {
    border-bottom: 1px dotted var(--hairline);
  }

  .docket-group th {
    display: block;
    padding: calc(var(--u) * 2.4) 0 calc(var(--u) * 0.5);
  }
}

/* ---------- 4 · pull-quote ------------------------------------------- */

.quoted {
  padding-block: calc(var(--u) * 4.4) calc(var(--u) * 4);
}

.quoted .tag {
  display: block;
  margin-bottom: calc(var(--u) * 1.8);
}

.pull {
  font-family: var(--head);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 0.98;
  letter-spacing: 0.008em;
  font-size: clamp(2rem, 1rem + 4.6vw, 4.1rem);
  color: var(--ink);
  padding-bottom: calc(var(--u) * 2.6);
  border-bottom: 4px solid var(--accent);
}

.quote-body {
  display: grid;
  gap: calc(var(--u) * 2.2);
  margin-top: calc(var(--u) * 2.6);
}

/* The rule between columns is drawn with padding, never with a negative
   margin. A third paragraph wraps into column one, and a negative margin
   then puts its rule 18 px off the left edge of the window - measured at
   1024 px on the Felixstowe page, where the hairline simply vanished. */
@media (min-width: 52rem) {
  .quote-body {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 0;
    row-gap: calc(var(--u) * 2.8);
  }

  .quote-body > p {
    padding-right: calc(var(--u) * 3);
  }

  .quote-body > p:nth-child(2n) {
    padding-left: calc(var(--u) * 3);
    padding-right: 0;
    border-left: 1px solid var(--hairline);
  }
}

@media (min-width: 66rem) {
  .quote-body-three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .quote-body-three > p,
  .quote-body-three > p:nth-child(2n) {
    padding-inline: calc(var(--u) * 2.6);
    border-left: 1px solid var(--hairline);
  }

  .quote-body-three > p:nth-child(3n + 1) {
    padding-left: 0;
    border-left: 0;
  }

  .quote-body-three > p:nth-child(3n) {
    padding-right: 0;
  }
}

.quote-body p {
  font-size: 1.04rem;
}

/* ---------- 5 · offset-split ----------------------------------------- */

.split-sec {
  padding-block: calc(var(--u) * 3.6);
}

.split {
  display: grid;
  gap: calc(var(--u) * 3);
}

.split-wide .standfirst {
  max-width: var(--measure);
  margin-block: var(--u) calc(var(--u) * 2);
}

.split-wide .selector {
  margin-bottom: calc(var(--u) * 2.4);
}

@media (min-width: 64rem) {
  .split {
    grid-template-columns: minmax(0, 1.78fr) minmax(0, 1fr);
    gap: calc(var(--u) * 6.5);
    align-items: start;
  }

  /* The narrow side carries the figure OVER the gutter. The wide side is
     given a matching right padding so the overhang lands on empty column,
     never on a form field: an overlap that covers content is a collision,
     not a composition. */
  .split-wide {
    padding-right: calc(var(--u) * 8);
    border-right: 1px solid var(--hairline);
  }

  .split-narrow {
    margin-top: calc(var(--u) * 7.5);
    position: relative;
    z-index: 2;
  }

  /* far enough left to cross the column's own edge rule, and the wide side
     is padded by more than the crossing so the figure lands on empty column
     rather than on a paragraph */
  .split-narrow .plate {
    margin-left: calc(var(--u) * -13);
    box-shadow:
      -16px 16px 0 -4px color-mix(in srgb, var(--accent2) 26%, transparent),
      0 0 0 1px var(--hairline-firm);
  }

  .split-narrow .plate-figure svg {
    margin-inline: 0 auto;
  }
}

.plate-figure svg {
  max-width: 22rem;
  margin-inline: auto;
}

.plate-body {
  fill: color-mix(in srgb, var(--accent2) 13%, var(--surface));
  stroke: var(--hairline-firm);
  stroke-width: 1.5;
}

.plate-rivet {
  fill: var(--accent2);
  opacity: 0.5;
}

.plate-cap {
  font-family: var(--head);
  font-size: 13px;
  letter-spacing: 0.2em;
  fill: var(--accent2);
}

.plate-row {
  font-family: var(--body);
  font-size: 13.5px;
  fill: var(--ink);
}

.plate-sum {
  font-family: var(--head);
  font-size: 16px;
  letter-spacing: 0.08em;
  fill: var(--accent);
}

.plate-rule {
  stroke: var(--hairline-firm);
  stroke-width: 1;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 620ms var(--ease-rail);
}

.plate-rule:nth-of-type(2) {
  transition-delay: 160ms;
}

.plate-rule:nth-of-type(3) {
  transition-delay: 320ms;
}

.plate-rule:nth-of-type(4) {
  transition-delay: 480ms;
}

.plate-rule:nth-of-type(5) {
  transition-delay: 640ms;
}

.is-drawn .plate-rule {
  stroke-dashoffset: 0;
}

.plate-bracket {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: square;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 900ms var(--ease-rail) 820ms;
}

.is-drawn .plate-bracket {
  stroke-dashoffset: 0;
}

/* run-in heads: a block of prose that still names its parts, used where a
   ruled list would turn the page into another ledger */
.runin {
  max-width: 42rem;
  margin-top: calc(var(--u) * 2);
}

.runin p {
  padding-left: calc(var(--u) * 2);
  border-left: 2px solid var(--hairline);
  padding-block: calc(var(--u) * 0.3);
  transition: border-left-color var(--snap) linear;
}

.runin p + p {
  margin-top: calc(var(--u) * 1.6);
}

.runin p:hover {
  border-left-color: var(--accent);
}

.runin b {
  font-family: var(--head);
  font-size: 1.06rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent2);
}

/* the loading-bed plan that overhangs the gutter on the haulage page */
.bed-floor {
  fill: color-mix(in srgb, var(--accent2) 9%, var(--surface));
  stroke: var(--hairline-firm);
  stroke-width: 1.5;
}

.bed-board {
  fill: var(--accent2);
}

.bed-item {
  fill: color-mix(in srgb, var(--accent) 17%, var(--surface));
  stroke: var(--accent-edge);
  stroke-width: 1.2;
}

.bed-frame {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-linejoin: round;
}

.bed-strap {
  stroke: var(--ink);
  stroke-width: 2;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 560ms var(--ease-rail);
}

.bed-strap:nth-of-type(2) {
  transition-delay: 150ms;
}

.bed-strap:nth-of-type(3) {
  transition-delay: 300ms;
}

.bed-strap:nth-of-type(4) {
  transition-delay: 450ms;
}

.bed-strap:nth-of-type(5) {
  transition-delay: 600ms;
}

.is-drawn .bed-strap {
  stroke-dashoffset: 0;
}

.bed-label {
  font-family: var(--head);
  font-size: 12px;
  letter-spacing: 0.1em;
  fill: var(--quieter);
}

/* ---------- 6 · card-grid -------------------------------------------- */

.fact-sec {
  padding-block: calc(var(--u) * 3.6);
}

.fact-sec .standfirst {
  max-width: var(--measure);
  margin-top: var(--u);
}

.fact-grid {
  display: grid;
  gap: calc(var(--u) * 2.4);
  margin-top: calc(var(--u) * 2.6);
}

@media (min-width: 38rem) {
  .fact-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .fact-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: calc(var(--u) * 2.6);
  }
}

/* no box: a rule over each fact and nothing else, so this row of four
   cannot be mistaken for the band above it or the plates below */
.fact {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.7);
  padding-top: calc(var(--u) * 1.3);
  border-top: 5px solid var(--accent2);
  transition: border-top-color var(--snap) linear, transform var(--snap) var(--ease-rail);
}

.fact[data-trade="haul"] {
  border-top-color: var(--accent);
}

.fact:hover {
  transform: translateY(-3px);
}

.trade-chip {
  font-family: var(--head);
  font-size: 0.76rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--quieter);
}

.fact h4 {
  font-size: 1.14rem;
  letter-spacing: 0.05em;
  color: var(--ink);
}

.fact p {
  font-size: 0.94rem;
}

.fact dl {
  margin-top: auto;
  padding-top: var(--u);
  border-top: 1px dotted var(--hairline);
  font-size: 0.88rem;
}

.fact dt {
  font-family: var(--head);
  font-size: 0.76rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--quieter);
}

.fact dd {
  margin-left: 0;
}

/* marginalia: notes hanging in the margin beside continuous prose. One
   rule runs the whole height rather than one rule per row, which is what
   keeps this from turning back into a ruled list. */
.marg {
  margin-top: calc(var(--u) * 2.2);
  display: grid;
  gap: calc(var(--u) * 2.2);
}

.marg-row {
  display: grid;
  gap: calc(var(--u) * 0.4);
}

.marg-note {
  font-family: var(--head);
  font-size: 0.86rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.3;
}

.marg-row p:last-child {
  max-width: 42rem;
}

@media (min-width: 56rem) {
  .marg {
    position: relative;
    gap: calc(var(--u) * 2.6);
  }

  /* ONE rule down the whole block, not a rule per row - this is the line
     that keeps a margin a margin instead of a table */
  .marg::before {
    content: "";
    position: absolute;
    left: 13rem;
    top: calc(var(--u) * 0.5);
    bottom: calc(var(--u) * 0.5);
    width: 1px;
    background: var(--hairline-firm);
  }

  /* baseline, not top: the note is set smaller than the prose, so aligning
     the boxes leaves the two first lines visibly out of step */
  .marg-row {
    grid-template-columns: 13rem minmax(0, 1fr);
    column-gap: 0;
    align-items: baseline;
  }

  .marg-note {
    text-align: right;
    padding-right: calc(var(--u) * 2.2);
  }

  .marg-row > p:last-child {
    padding-left: calc(var(--u) * 2.2);
  }
}

/* the identity block as a colophon strip, not a second definition list */
.colophon {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 0.8) calc(var(--u) * 2.8);
  margin-top: calc(var(--u) * 2.6);
  padding-top: calc(var(--u) * 1.4);
  border-top: 3px double var(--ink);
  font-size: 0.9rem;
}

.colophon b {
  font-family: var(--head);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--quieter);
  display: block;
}

/* the retention table stacks on a phone the same way the index ledger
   does, for the same reason: three columns of sentences do not fit */
@media (max-width: 45.99rem) {
  .keep thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .keep tbody tr {
    display: block;
    padding-block: calc(var(--u) * 0.8);
    border-bottom: 1px solid var(--hairline);
  }

  .keep td {
    display: block;
    padding: 0 0 calc(var(--u) * 0.5);
    border-bottom: 0;
  }

  .keep td:first-child {
    font-family: var(--head);
    font-size: 1.04rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding-top: calc(var(--u) * 0.6);
  }

  .keep td[data-col]::before {
    content: attr(data-col) " — ";
    font-family: var(--head);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-size: 0.78rem;
    color: var(--quieter);
  }
}

/* ---------- 7 · step-chain ------------------------------------------- */

.chain-sec {
  padding-block: calc(var(--u) * 3.6) calc(var(--u) * 2);
}

.chain-sec .standfirst {
  max-width: var(--measure);
  margin-top: var(--u);
}

.chains {
  display: grid;
  gap: calc(var(--u) * 4);
  margin-top: calc(var(--u) * 2.8);
}

@media (min-width: 58rem) {
  .chains {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: calc(var(--u) * 6);
  }
}

.chain-track > h3 {
  color: var(--accent2);
  margin-bottom: calc(var(--u) * 1.8);
}

.chain-track[data-trade="haul"] > h3 {
  color: var(--accent);
}

.chain {
  position: relative;
  list-style: none;
  padding: 0;
  display: grid;
  gap: calc(var(--u) * 2.2);
}

/* the rule that runs between the numbers, drawn once on load */
.chain::before {
  content: "";
  position: absolute;
  left: 17px;
  top: 20px;
  bottom: 20px;
  width: 2px;
  background: var(--hairline-firm);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 1000ms var(--ease-rail) 120ms;
}

.is-drawn .chain::before {
  transform: scaleY(1);
}

.chain-step {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  column-gap: calc(var(--u) * 1.6);
  row-gap: 3px;
  align-items: start;
  opacity: 0;
  transform: translateY(7px);
  transition: opacity 420ms linear, transform 420ms var(--ease-rail);
}

.is-drawn .chain-step {
  opacity: 1;
  transform: none;
}

.chain-step:nth-child(2) {
  transition-delay: 380ms;
}

.chain-step:nth-child(3) {
  transition-delay: 680ms;
}

.chain-num {
  grid-row: 1 / span 2;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  font-family: var(--head);
  font-size: 1.32rem;
  line-height: 1;
  color: var(--surface);
  background: var(--accent2);
  border-radius: 50%;
  position: relative;
  z-index: 1;
}

.chain-track[data-trade="haul"] .chain-num {
  background: var(--accent);
}

.chain-step b {
  font-family: var(--head);
  font-size: 1.1rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  align-self: center;
}

.chain-step > span:last-child {
  font-size: 0.94rem;
  color: var(--quiet);
}

.chain-foot {
  margin-top: calc(var(--u) * 2.2);
  max-width: var(--measure);
}

/* One long sequence rather than two short tracks: the same shape, spread
   across the width instead of stacked, because six stages in one column
   would simply be a list again. */
.chain-long {
  margin-top: calc(var(--u) * 2.8);
  gap: calc(var(--u) * 2.6);
}

@media (min-width: 60rem) {
  .chain-long .chain-step {
    grid-template-columns: 36px 17rem minmax(0, 1fr);
    column-gap: calc(var(--u) * 2.4);
    align-items: baseline;
  }

  .chain-long .chain-step b {
    grid-row: 1;
    align-self: baseline;
  }

  .chain-long .chain-step > span:last-child {
    grid-row: 1;
    grid-column: 3;
    max-width: 46rem;
  }

  .chain-long .chain-num {
    grid-row: 1;
    align-self: start;
  }
}

.gatelist-six {
  row-gap: calc(var(--u) * 2.6);
}

@media (min-width: 52rem) {
  .gatelist-six {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    row-gap: calc(var(--u) * 3);
  }

  .gatelist-six > div:nth-child(3n + 1) {
    padding-left: 0;
    border-left: 0;
  }

  .gatelist-six > div:nth-child(3n) {
    padding-right: 0;
  }

  .gatelist-six > div:first-child,
  .gatelist-six > div:last-child {
    padding-inline: calc(var(--u) * 2.4);
  }

  .gatelist-six > div:nth-child(1) {
    padding-left: 0;
  }

  .gatelist-six > div:nth-child(6) {
    padding-right: 0;
  }
}

/* ---------- reduced motion: land everything finished ----------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
  }

  /* the set-piece is DELIVERED, not merely hurried: the trace, the limit
     line, the blocks, the stop bracket and the band segments are all in
     their final geometry whether or not the script ever ran. */
  .trace-stylus,
  .trace-limit,
  .is-drawn .trace-stylus,
  .is-drawn .trace-limit {
    stroke-dashoffset: 0 !important;
  }

  .trace-blk,
  .trace-limit-label,
  .trace-stop,
  .is-drawn .trace-blk,
  .is-drawn .trace-limit-label,
  .is-drawn .trace-stop {
    opacity: 1 !important;
  }

  .is-drawn .trace-stop,
  .has-js .shelf[data-state="forward"]::after {
    animation: none !important;
  }

  .band-lane rect,
  .is-drawn .band-lane rect,
  .schematic .queue rect,
  .is-drawn .schematic .queue rect {
    transform: scaleX(1) !important;
  }

  .schematic .road,
  .is-drawn .schematic .road {
    stroke-dashoffset: 0 !important;
  }

  .schematic .road-minor,
  .is-drawn .schematic .road-minor {
    opacity: 1 !important;
  }

  .shelf,
  .shelf-body,
  .shelf-body > div {
    transition: none !important;
  }

  .calc-out.is-fresh {
    animation: none !important;
  }

  .card:hover,
  .fact:hover {
    transform: none;
  }

  /* the composed sections land finished too: the plate's rules and bracket
     drawn, the chain's rule at full height, every step present */
  .plate-rule,
  .plate-bracket,
  .is-drawn .plate-rule,
  .is-drawn .plate-bracket {
    stroke-dashoffset: 0 !important;
  }

  .chain::before,
  .is-drawn .chain::before {
    transform: scaleY(1) !important;
  }

  .bed-strap,
  .is-drawn .bed-strap {
    stroke-dashoffset: 0 !important;
  }

  .win-band,
  .is-drawn .win-band {
    transform: scaleY(1) !important;
  }

  .win-mark,
  .is-drawn .win-mark {
    opacity: 1 !important;
  }

  .chain-step,
  .is-drawn .chain-step {
    opacity: 1 !important;
    transform: none !important;
  }

  .pair,
  .fig .plate,
  .fig-head {
    transition: none !important;
  }
}

/* ---------- script-dependent controls stay out of the way without JS -- */

html:not(.has-js) [data-needs-js] {
  display: none !important;
}
