@charset "utf-8";
/* ═══════════════════════════════════════════════════════════════════════════
   Direction A — "The Rail"
   Warm Paper palette. Newsreader for display, Instrument Sans for body,
   IBM Plex Mono for metadata. All self-hosted, all SIL Open Font License.

   Contrast ratios noted against each token below are WCAG 2.1 and clear AA
   throughout — accessibility floor from the brief.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── fonts ───────────────────────────────────────────────────────────────── */
/* Display face settled 12 Aug: Newsreader 400. Chosen over Source Serif 4,
   Fraunces and Instrument Serif — the first pass used Instrument Serif, which
   Will correctly read as narrow and vertically stretched. Static single-weight
   instances, not variable: ~22KB each against ~132KB for the variable cut. */
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/assets/fonts/newsreader-roman.woff2') format('woff2');
}
@font-face {
  font-family: 'Newsreader'; font-style: italic; font-weight: 400;
  font-display: swap; src: url('/assets/fonts/newsreader-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Sans'; font-style: normal; font-weight: 400 700;
  font-display: swap; src: url('/assets/fonts/instrument-sans-var.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('/assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
}

/* ── tokens ──────────────────────────────────────────────────────────────── */
:root {
  --bg:         #F7F4EF;
  --surface:    #EDE8DF;
  --ink:        #16150F;   /* 16.67:1 on bg — AAA */
  --ink-muted:  #57534A;   /*  6.98:1 on bg — AA  */
  --rule:       #D6CEC1;
  --accent:     #9A3D00;   /*  6.29:1 on bg — AA, body-text safe */
  --accent-soft:#C25A10;

  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --sans:  'Instrument Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono:  'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --measure: 62ch;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --rail-w: 30rem;

  color-scheme: light;
}

/* ── reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }

/* Visible focus. A developer tabbing through and finding this works reads it
   as a signal about everything else on the page. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--bg);
  padding: 0.75rem 1.25rem; z-index: 99; font: 500 0.875rem var(--mono);
}
.skip:focus { left: 1rem; top: 1rem; }

/* ── layout ──────────────────────────────────────────────────────────────── */
.shell {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  max-width: 90rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
@media (min-width: 62rem) {
  .shell {
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    gap: clamp(3rem, 6vw, 7rem);
  }
}

/* ── the rail ────────────────────────────────────────────────────────────── */
.rail {
  padding-block: clamp(2.5rem, 6vw, 5rem) 2rem;
}
@media (min-width: 62rem) {
  .rail {
    position: sticky;
    top: 0;
    height: 100svh;
    display: flex;
    flex-direction: column;
    padding-block: clamp(4rem, 8vh, 7rem) 3rem;

    /* The rail is pinned to the viewport height and cannot scroll with the
       page — that is the whole point of it. So anything taller than the
       viewport was simply unreachable: no scrollbar, no way down. This is the
       backstop that makes that impossible at any height, zoom level or font
       size. The rule below stops it from being needed in normal use. */
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;

    /* Setting overflow on one axis forces the other: a visible axis paired
       with a non-visible one computes to auto, so the rail quietly became
       horizontally scrollable too. .railnav bleeds 0.75rem each side, on
       purpose, so its rules line up with the text rather than the link
       padding — and that bleed turned into 12px of horizontal scrollbar.

       Padding the rail by the same amount and pulling it back with an equal
       negative margin lands the bleed exactly on the padding edge instead of
       outside it. Nothing moves visually and there is nothing to scroll.
       overflow-x: clip was the other candidate and is worse: paired with a
       scrolling axis it computes to hidden, which would cut the right-hand
       end off every rule in the nav. */
    padding-inline: 0.75rem;
    margin-inline: -0.75rem;
  }
}

.rail__name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3rem, 7vw, 4.75rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  margin-bottom: 1.25rem;
}
.rail__name em { font-style: italic; }

.rail__lead {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  line-height: 1.45;
  max-width: 24ch;
  margin-bottom: 0.5rem;
}
.rail__years {
  font: 500 0.8125rem/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 2rem;
}

/* ── availability: the status board ──────────────────────────────────────── */
/* The highest-value element on the page. Modelled on a service status board
   because that is a shape this reader already knows how to parse instantly. */
.status {
  border: 1px solid var(--rule);
  background: var(--surface);
  border-radius: 0.5rem;
  padding: 0.875rem 1rem;
  margin-bottom: 1.5rem;
  max-width: 24rem;
}
.status__row { display: flex; align-items: center; gap: 0.5rem; }
.status__dot {
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--accent); flex: none;
  /* Never the only signal — the text beside it says the same thing. */
}
.status--on .status__dot { animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgb(154 61 0 / 0.45); }
  50%      { box-shadow: 0 0 0 0.3rem rgb(154 61 0 / 0); }
}
.status__label {
  font: 500 0.8125rem/1 var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.status__value { font: 400 0.9375rem/1.4 var(--sans); margin-top: 0.5rem; }
.status__sub   { font: 400 0.8125rem/1.4 var(--sans); color: var(--ink-muted); margin-top: 0.125rem; }

/* ── section index ───────────────────────────────────────────────────────── */
/* Occupies the space a full-height sticky rail would otherwise leave blank,
   and doubles as a table of contents on a long page. */
/* Desktop only. On a phone it would push the actual pitch below the fold, and
   a scroll-through page that short does not need a table of contents. */
.railnav { display: none; margin-top: 1.75rem; margin-inline: -0.75rem; }
@media (min-width: 62rem) { .railnav { display: block; } }
.railnav ol { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--rule); }
.railnav li { border-bottom: 1px solid var(--rule); }
.railnav a {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  align-items: baseline;
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
  font: 400 0.875rem/1.5 var(--sans);
  text-decoration: none;
  color: var(--ink-muted);
  transition: color .15s;
}
.railnav a span { font: 500 0.6875rem var(--mono); letter-spacing: 0.08em; }
.railnav a:hover { color: var(--accent); }

/* ── contact ─────────────────────────────────────────────────────────────── */
.rail__contact { margin-top: auto; padding-top: 2rem; }
.email {
  display: inline-block;
  font: 500 clamp(0.9375rem, 0.9rem + 0.25vw, 1.0625rem)/1.3 var(--mono);
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.28em;
  text-decoration-thickness: 1px;
  word-break: break-all;
  transition: color .15s;
}
.email:hover { color: var(--ink); }
.rail__meta {
  margin-top: 0.875rem;
  font: 400 0.8125rem/1.7 var(--mono);
  color: var(--ink-muted);
}
.rail__meta a { color: inherit; text-decoration: underline; text-underline-offset: 0.2em; }

/* ── main column ─────────────────────────────────────────────────────────── */
.main { padding-block: 0 clamp(4rem, 10vh, 8rem); }
@media (min-width: 62rem) { .main { padding-block: clamp(4rem, 8vh, 7rem) clamp(6rem, 14vh, 11rem); } }

.section { padding-block: clamp(3rem, 7vh, 5.5rem); border-top: 1px solid var(--rule); }
.section:first-child { border-top: 0; padding-top: 0; }

.section__num {
  font: 500 0.75rem/1 var(--mono);
  letter-spacing: 0.14em;
  color: var(--ink-muted);
  margin-bottom: 1rem;
  display: block;
}
.section__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.875rem, 1.4rem + 2.2vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  margin-bottom: 1rem;
  max-width: 20ch;
}
.section__intro {
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.55;
  max-width: var(--measure);
  color: var(--ink-muted);
  margin-bottom: 2.5rem;
}

/* ── claim (top of main) ─────────────────────────────────────────────────── */
.claim {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 1.2rem + 2.6vw, 3.25rem);
  line-height: 1.12;
  letter-spacing: -0.018em;
  max-width: 20ch;
  margin-bottom: 1.5rem;
}
.claim em { font-style: italic; color: var(--accent); }
.claim__sub {
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink-muted);
  max-width: 46ch;
}

/* ── agency evidence ─────────────────────────────────────────────────────── */
.clients { list-style: none; padding: 0; margin: 0 0 3rem; border-top: 1px solid var(--rule); }
.clients li {
  display: grid; gap: 0.25rem 2rem;
  padding-block: 1rem;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 40rem) { .clients li { grid-template-columns: 14rem minmax(0, 1fr); align-items: baseline; } }
.clients__name { font: 500 1rem/1.3 var(--sans); }
.clients__detail { font-size: 0.9375rem; line-height: 1.5; color: var(--ink-muted); }

.terms { display: grid; gap: 1.75rem; margin-bottom: 3rem; }
@media (min-width: 48rem) { .terms { grid-template-columns: 1fr 1fr; gap: 2rem 3rem; } }
.terms__label {
  font: 500 0.75rem/1 var(--mono);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 0.5rem;
}
.terms__body { font-size: 0.9375rem; line-height: 1.6; max-width: 42ch; }

.tostart { background: var(--surface); border: 1px solid var(--rule); border-radius: 0.5rem; padding: 1.5rem; }
.tostart h3 { font: 500 0.75rem/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 0.875rem; }
.tostart ol { margin: 0; padding-left: 1.1rem; }
.tostart li { font-size: 0.9375rem; line-height: 1.7; }

/* ── case studies ────────────────────────────────────────────────────────── */
.cases { display: grid; gap: 1rem; }
.case {
  border: 1px solid var(--rule);
  border-radius: 0.5rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--bg);
  transition: border-color .2s, background .2s;
}
.case:hover { border-color: var(--ink); background: var(--surface); }
.case__head {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1rem;
  align-items: baseline; margin-bottom: 1rem;
}
.case__kind {
  font: 500 0.6875rem/1 var(--mono);
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--bg); background: var(--accent);
  padding: 0.3rem 0.5rem; border-radius: 0.2rem;
}
.case__client { font: 400 0.875rem/1 var(--mono); color: var(--ink-muted); }
.case__row { display: grid; gap: 0.25rem 1.5rem; padding-block: 0.625rem; }
@media (min-width: 44rem) { .case__row { grid-template-columns: 6.5rem minmax(0, 1fr); } }
.case__k {
  font: 500 0.6875rem/1.6 var(--mono);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-muted);
}
.case__v { font-size: 0.9375rem; line-height: 1.6; max-width: 58ch; }
.case__v code {
  font: 400 0.875em var(--mono);
  background: var(--surface); padding: 0.1em 0.35em; border-radius: 0.2rem;
}
.case__stack { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 1rem; }
.case__stack span {
  font: 400 0.6875rem/1 var(--mono);
  border: 1px solid var(--rule); border-radius: 0.2rem;
  padding: 0.3rem 0.45rem; color: var(--ink-muted);
}

/* TODO blocks are deliberately loud. They must not survive to production. */
.todo {
  display: block;
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--bg));
  padding: 0.75rem 1rem;
  font: 400 0.875rem/1.6 var(--sans);
  border-radius: 0 0.3rem 0.3rem 0;
}
.todo::before {
  content: 'TODO';
  display: block;
  font: 500 0.6875rem/1 var(--mono);
  letter-spacing: 0.12em;
  color: var(--accent);
  margin-bottom: 0.375rem;
}

/* ── capabilities ────────────────────────────────────────────────────────── */
.caps { display: grid; gap: 2rem; }
@media (min-width: 40rem) { .caps { grid-template-columns: repeat(2, 1fr); gap: 2.5rem 3rem; } }
@media (min-width: 64rem) { .caps { grid-template-columns: repeat(3, 1fr); } }
.caps h3 {
  font: 500 0.75rem/1 var(--mono);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent);
  padding-bottom: 0.625rem; margin-bottom: 0.875rem;
  border-bottom: 1px solid var(--rule);
}
.caps ul { list-style: none; padding: 0; }
.caps li { font-size: 0.9375rem; line-height: 1.5; padding-block: 0.375rem; }

/* ── apps ────────────────────────────────────────────────────────────────── */
.stats { display: grid; gap: 1.5rem; margin-bottom: 1.5rem; }
@media (min-width: 34rem) { .stats { grid-template-columns: repeat(3, 1fr); } }
.stat__figure {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.5rem, 1.8rem + 3vw, 4rem);
  line-height: 1; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font: 400 0.8125rem/1.4 var(--mono);
  color: var(--ink-muted); margin-top: 0.375rem;
}

/* ── footer ──────────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--rule);
  padding-block: 2rem 3rem;
  display: flex; flex-wrap: wrap; gap: 0.5rem 2rem;
  align-items: baseline;
  font: 400 0.8125rem/1.7 var(--mono);
  color: var(--ink-muted);
}
.foot a { color: inherit; text-decoration: underline; text-underline-offset: 0.2em; }
.foot a:hover { color: var(--accent); }

/* ── motion ──────────────────────────────────────────────────────────────── */
/* Scroll-driven, native, zero JavaScript. Falls back to fully visible where
   unsupported — nothing depends on the animation to be readable. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
  }
}
@keyframes reveal {
  from { opacity: 0; transform: translateY(1.25rem); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ── print ───────────────────────────────────────────────────────────────── */
/* Agency leads forward things internally as PDFs. */
@media print {
  :root { --bg: #fff; --ink: #000; --ink-muted: #333; --rule: #bbb; --accent: #000; }
  .shell { display: block; max-width: none; padding: 0; }
  .rail { position: static; height: auto; }
  .status__dot, .skip { display: none; }
  .section { break-inside: avoid; border-top: 1px solid var(--rule); }
  .case { break-inside: avoid; border: 1px solid var(--rule); }
  a { text-decoration: underline; }
}


/* ── case study pages ────────────────────────────────────────────────────── */
.rail__back { margin-bottom: 1.5rem; }
.rail__back a {
  font: 500 0.8125rem/1 var(--mono);
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-muted); text-decoration: none;
}
.rail__back a:hover { color: var(--accent); }
.rail__name--sm { font-size: clamp(2.25rem, 4.5vw, 3.25rem); }

.case__link { text-decoration: none; color: inherit; background-image: linear-gradient(var(--rule), var(--rule));
              background-size: 100% 1px; background-repeat: no-repeat; background-position: 0 100%;
              transition: background-size .2s, color .15s; }
.case__link:hover { color: var(--accent); }

.case__more {
  font: 500 0.6875rem/1 var(--mono);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent); text-decoration: none;
  padding: 0.3rem 0; margin-left: auto; align-self: center;
}
.case__more:hover { text-decoration: underline; text-underline-offset: 0.25em; }

.nextlink { text-decoration: none; color: inherit; }
.nextlink:hover { color: var(--accent); }

/* ── cross-page transitions ──────────────────────────────────────────────── */
/* Native View Transitions. Makes navigating into a case study feel continuous
   without a single line of JavaScript or any client-side router. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ── stack line under the role ───────────────────────────────────────────── */
.rail__stack {
  font: 400 0.8125rem/1.5 var(--mono);
  color: var(--ink-muted);
  margin-bottom: 0.375rem;
  max-width: 26ch;
}

/* ── evidence list (section 03) ──────────────────────────────────────────── */
.points { margin: 0; }
.points dt {
  font: 500 0.75rem/1.4 var(--mono);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent);
  padding-top: 1.25rem; margin-top: 1.25rem;
  border-top: 1px solid var(--rule);
}
.points dt:first-child { padding-top: 0; margin-top: 0; border-top: 0; }
.points dd {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem; line-height: 1.65;
  max-width: 58ch;
}

/* ── direct clients (section 01) ─────────────────────────────────────────── */
.direct { margin-bottom: 2.5rem; }
.direct h3 {
  font: 500 .6875rem/1 var(--mono);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .625rem;
}
.direct__intro { font-size: .9375rem; line-height: 1.6; color: var(--ink-muted); margin-bottom: 1rem; max-width: 52ch; }
.clients--tight { margin-bottom: 0; }

/* A dated row reads as past without needing its own layout. */
.clients__period {
  display: block; margin-top: .2rem;
  font: 400 .75rem/1 var(--mono); letter-spacing: .06em;
  color: var(--ink-muted);
}


/* ── sticky section headings ─────────────────────────────────────────────── */
/* Each heading is sticky inside its own <section>, which is what produces the
   hand-off: a sticky element can never escape its parent, so heading 02 pushes
   heading 01 out of the way as section 02 arrives. No JavaScript, and the
   transition between the two is the browser's own scrolling.

   The background is always var(--bg). At rest it sits on the same colour so it
   is invisible; once stuck it is what stops the content scrolling through the
   text. Only the shadow is conditional. */
.section__head {
  position: relative;
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg);
  padding-block: 1.5rem 1.5rem;
  margin-block: -1.5rem 0;
  /* full-bleed within the column so nothing shows through at the edges */
  padding-inline: var(--gutter);
  margin-inline: calc(var(--gutter) * -1);
}
.section__head .section__title { margin-bottom: 0; }
.section__head .section__num { margin-bottom: 0.5rem; }
.section__intro { margin-top: 0.75rem; }

/* Shadow appears only while the heading is stuck. Driven by a class toggled
   from a two-line IntersectionObserver in index.php rather than by a
   scroll-driven timeline: a sticky element barely moves while stuck, so its
   own view() timeline is useless, and measuring the parent section's exit
   range turned out to be fragile across section heights. The observer is
   ~700 bytes and simply correct. */
.section__head::after {
  content: '';
  /* the head is full-bleed so its background covers the gutter, but the rule
     should line up with the content rather than overhang it */
  position: absolute; left: var(--gutter); right: var(--gutter); bottom: 0;
  height: 1px;
  background: var(--rule);
  box-shadow: 0 10px 20px -16px rgb(22 21 15 / 0.55);
  opacity: 0;
  transition: opacity .18s ease-out;
  pointer-events: none;
}
.section__head.is-stuck::after { opacity: 1; }

/* ── the rail nav follows the section in view ────────────────────────────── */
.railnav a { border-radius: .25rem; transition: color .2s, background .2s; }
.railnav a.is-current {
  color: var(--ink);
  background: var(--surface);
}
.railnav a.is-current span { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .section__head::after, .railnav a { transition: none; }
}

/* ── 404 ─────────────────────────────────────────────────────────────────── */
/* The requested path, echoed back. Reads as an admission that the site knows
   exactly what was asked for, rather than the shrug of "page not found". */
.notfound__asked { margin: 1.25rem 0 0; }
.notfound__asked code {
  font: 400 0.875rem/1.5 var(--mono);
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 0.25rem;
  padding: 0.3rem 0.55rem;
  overflow-wrap: anywhere;
}
.notfound__routes { margin: 2.5rem 0; }
.notfound__routes .terms__label { margin-bottom: 0.875rem; }
.notfound__routes .clients__name a { color: var(--ink); text-decoration-color: var(--rule); }
.notfound__routes .clients__name a:hover { color: var(--accent); text-decoration-color: currentColor; }


/* ── wide but short ──────────────────────────────────────────────────────────
   The two-column layout starts at 62rem of WIDTH and says nothing about
   height, so a viewport could be wide enough for the sticky rail and far too
   short to hold it. In its roomy form the rail needs 817px, which meant the
   nav and the contact block fell off the bottom on:

     1024 x 600   netbook / small tablet     141px lost
     1254 x 752   landscape Android tablet    65px lost   <- reported
     1280 x 720   laptop                      97px lost
     1366 x 768   laptop                      49px lost
     1280 x 800   laptop                      17px lost

   1366x768 and 1280x720 are among the most common laptop sizes in use, so
   this was never really a small-screen bug. Everything below buys vertical
   space so the rail fits without an inner scrollbar. Nothing is hidden and
   no rule is dropped — it is the same rail, tighter. */
@media (min-width: 62rem) and (max-height: 56rem) {
  .rail { padding-block: 2.5rem 2rem; }

  /* Biggest single saving: two lines of display serif at 4.75rem is 144px. */
  .rail__name       { font-size: clamp(2.5rem, 4.5vw, 3.25rem); margin-bottom: 0.875rem; }
  .rail__name--sm   { font-size: clamp(1.75rem, 3vw, 2.25rem); }

  .rail__lead       { margin-bottom: 0.375rem; }
  .rail__years      { margin-bottom: 1.25rem; }
  .status           { padding: 0.75rem 0.875rem; margin-bottom: 1rem; }
  .railnav          { margin-top: 1rem; }
  .railnav a        { padding-block: 0.375rem; }
  .rail__contact    { padding-top: 1.25rem; }
}

/* Shorter still. The availability line and the email address are the two
   things worth protecting, so the section index is the first thing to go —
   it is a convenience on a page whose sections are all reachable by
   scrolling, and it is the single tallest block after the name. */
@media (min-width: 62rem) and (max-height: 40rem) {
  .railnav      { display: none; }
  .rail__stack  { display: none; }
  .rail__name   { font-size: 2.25rem; }
}

/* Direct client links. Underline offset rather than a colour change, so the
   list still reads as a list rather than a row of calls to action — these are
   evidence, not the thing the page wants clicked. */
.clients__name a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.18em;
  transition: text-decoration-color .15s, color .15s;
}
.clients__name a:hover { color: var(--accent); text-decoration-color: currentColor; }
