/* ==========================================================================
   Viola Hernandez portfolio — transit route theme

   Layout is driven by a few tokens. Everything on the route is measured from
   --gutter (the page margin), so moving the route or the margins is a
   one-line change. Breakpoints only override tokens where possible:

     Desktop  ≥ 1024px   Figma layout (1280 frame), shrinks fluidly
     Tablet   700–1023   Smaller margins; Featured Work cards stack below 1140px
     Phone    < 700      Smaller signs and stops, tighter spacing

   On every size the route is one straight line down the left, with the
   sub-projects stacked on a dotted branch beside it.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  /* Colour (from the homepage refresh mockup) */
  --bg: #f6f5ef;
  --ink: #252525;
  --ink-muted: #575757;
  --on-color: #f1f1f1;
  --placeholder: #d9d9d9;

  --hero: #25247a;       /* hero heading + Contact area (indigo) */
  --aqua: #2c9c8c;        /* Notable Mentions branch line + stops (3.1:1 on the background; decoration only, never text) */
  --orange: #e8913a;      /* About Me line + sign (text on it is --ink: 6.2:1) */
  --purple: #884cc0;      /* This and That branch line; This and That sub-project pages */
  --pin: #a70608;         /* "You Are Here" pin */
  --sign-dark: #16171f;   /* on-board sign panel (Route Map "Next stop") */
  --sign-amber: #f5c34b;  /* its text: 10.9:1 on the panel */
  --red: #b6322b;
  --navy: #2c55a5;        /* Featured Work: line, sign, summaries, spec labels */
  --navy-dark: #003763;   /* project titles, Notable Mentions titles + pages, case study ## headings */
  --teal-text: #1d7d77;   /* teal TEXT: ### headings, Notable Mentions card titles. 4.5:1 on the background: passes AA, but only just */

  --font-body: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;   /* body text */
  --font-brand: "Overpass", var(--font-body);                                      /* headings, stop names, section titles */
  --cap-nudge: 0.1em;   /* Overpass capitals sit 0.1em above the centre of their line (deep descender space);
                           boxed labels (signs, pills) move their text down by this much to look centred */

  /* Page geometry */
  --container: 1280px;
  --gutter: 57px;                                      /* page margin, left and right */
  --header-h: 72px;
  --sign-stop: 52.5px;                                 /* sign's left edge → centre of its stop */
  --rail: calc(var(--gutter) + var(--sign-stop));      /* x of the main line */
  --col: calc(var(--rail) + 66.5px);                   /* main text column */
  /* Branch (Notable Mentions, This and That): leaves the interchange oval (27px right of the main line),
     swings right through two curves of --branch-radius, then runs straight down through its stops */
  --interchange-out: 27px;
  --branch-radius: 60px;
  --branch-stop: calc(var(--rail) + var(--interchange-out) + 2 * var(--branch-radius));
  --branch-text: calc(var(--branch-stop) + 44px);     /* sub-project names and summaries */

  /* Stops + signs */
  --stop-lg: 62px;
  --stop-lg-border: 13px;
  --stop-sm: 39px;
  --stop-sm-border: 7px;
  --sign-h: 100px;
  --sign-radius: 34px;

  /* Type scale: fluid between the phone size (375px wide) and the desktop size (1280px wide) */
  --fs-hero: clamp(48px, calc(48px + 52 * (100vw - 375px) / 905), 100px);
  --fs-hero-sub: clamp(24px, calc(24px + 16 * (100vw - 375px) / 905), 40px);
  --fs-lead: clamp(18px, calc(18px + 6 * (100vw - 375px) / 905), 24px);
  --fs-hero-body: clamp(18px, calc(18px + 4 * (100vw - 375px) / 905), 22px);     /* intro paragraph under "Hello, I'm Viola" */
  --fs-sign: 45px;          /* section sign labels: fixed, like the signs (phones: see below) */
  --fs-intro: clamp(19px, calc(19px + 7 * (100vw - 375px) / 905), 26px);
  --fs-project: clamp(24px, calc(24px + 8 * (100vw - 375px) / 905), 32px);
  --fs-body: clamp(17px, calc(17px + 3 * (100vw - 375px) / 905), 20px);
  --fs-card-title: clamp(20px, calc(20px + 4 * (100vw - 375px) / 905), 24px);
  --fs-quote: clamp(18px, calc(18px + 6 * (100vw - 375px) / 905), 24px);
  --fs-button: clamp(15px, calc(15px + 4 * (100vw - 375px) / 905), 19px);
  --fs-site-name: clamp(20px, calc(20px + 6 * (100vw - 375px) / 905), 26px);     /* "Viola Hernandez" in the header */
  --fs-nav: clamp(15px, calc(15px + 3 * (100vw - 375px) / 905), 18px);           /* top navigation */
  --fs-caption: clamp(13px, calc(13px + 3 * (100vw - 375px) / 905), 16px);       /* small caps lines, e.g. testimonial organisation */
  --fs-next-label: clamp(20px, calc(20px + 4 * (100vw - 375px) / 905), 24px);    /* "Next stop" stop names */
  --fs-next-home: clamp(28px, calc(28px + 17 * (100vw - 375px) / 905), 45px);     /* "Home" at the end of the Next stop line */
  --fs-pin: 20px;           /* "You Are Here" */
  --fs-card-project: clamp(30px, calc(30px + 18 * (100vw - 375px) / 905), 48px);  /* Featured Work card titles (larger than the section sign) */
  --fs-pull: clamp(21px, calc(21px + 7 * (100vw - 375px) / 905), 28px);  /* Kind Words pull quotes */
  --fs-cite: clamp(16px, calc(16px + 2 * (100vw - 375px) / 905), 18px);  /* testimonial names */
  --fs-about: clamp(17px, calc(17px + 2 * (100vw - 375px) / 905), 19px);  /* About paragraphs */
  --route-map-bar: 56px;    /* height of the Route Map tab */
  --fs-tag: clamp(16px, calc(16px + 2 * (100vw - 375px) / 905), 18px);  /* role and tools line on Featured Work cards */
  --card-indent: clamp(16px, calc(16px + 24 * (100vw - 375px) / 905), 40px);  /* Featured Work cards sit in from the section text, giving the detours room */
  --kind-indent: clamp(16px, calc(16px + 80 * (100vw - 375px) / 905), 96px);  /* testimonials sit further in (no image beside them), so their detours swing wider */
  --fs-summary: clamp(18px, calc(18px + 4 * (100vw - 375px) / 905), 22px);       /* project summary on the homepage card */
  --fs-spec: clamp(16px, calc(16px + 2 * (100vw - 375px) / 905), 18px);          /* spec list values (Role & Scope…) */
  --fs-spec-label: clamp(14px, calc(14px + 2 * (100vw - 375px) / 905), 16px);    /* spec list labels on case study pages */
  --fs-highlight-label: clamp(20px, calc(20px + 4 * (100vw - 375px) / 905), 24px); /* "Problem" / "Challenge" / "Results" on homepage cards (= sub-project titles) */
  --fs-card-text: clamp(17px, calc(17px + 3 * (100vw - 375px) / 905), 20px);     /* homepage card: spec values + Problem/Challenge/Results text (= sub-project summaries) */
  --fs-card-spec: clamp(16px, calc(16px + 2 * (100vw - 375px) / 905), 18px);     /* homepage card: spec list values (labels use --fs-spec-label) */
  --fs-prose: clamp(17px, calc(17px + 3 * (100vw - 375px) / 905), 20px);         /* case study body text */
  --fs-h3: clamp(22px, calc(22px + 5 * (100vw - 375px) / 905), 27px);            /* ### headings in case studies */
  --fs-h4: clamp(16px, calc(16px + 3 * (100vw - 375px) / 905), 19px);            /* #### headings in case studies (uppercase) */
  --fs-callout: clamp(19px, calc(19px + 5 * (100vw - 375px) / 905), 24px);       /* ::: callout highlighted paragraphs */
  --fs-accordion: clamp(18px, calc(18px + 4 * (100vw - 375px) / 905), 22px);     /* accordion titles (uppercase) */
  --fs-figcaption: clamp(14px, calc(14px + 2 * (100vw - 375px) / 905), 16px);    /* image captions */
  --fs-contact: clamp(36px, calc(36px + 28 * (100vw - 375px) / 905), 64px);  /* "You've reached the end of the line." */
  --contact-drop: 150px;    /* how far into the indigo area the terminal stop sits (the line turns down above it) */
  --fs-direction: clamp(18px, calc(18px + 2 * (100vw - 375px) / 905), 20px);     /* "Head Northbound" / "Head Southbound" */
  --fs-nav-menu: 20px;      /* items in the hamburger menu */
  --fs-footer-stop: clamp(20px, calc(20px + 2 * (100vw - 375px) / 905), 22px);   /* footer: main stops */
  --fs-footer-sub: clamp(18px, calc(18px + 2 * (100vw - 375px) / 905), 20px);    /* footer: Notable Mentions / This and That */
  --fs-footer-item: 16px;   /* footer: project + sub-project links */

  /* Fonts */
  --font-body-weight: 400;

  /* Surfaces + effects */
  --stop-fill: #fff;        /* inside of every stop */
  --marker-ring: #000;      /* interchange markers */
  --shadow-color: rgb(37 37 37 / 0.35);

  /* Route drawing (read by route.js) */
  --route-width: 23;
  --branch-width: 12;
  --turn-radius: 121;
  --branch-layout: vertical;   /* rows | snake | vertical (route.js) */
  --branch-detour: 24;         /* how far a snake turn swings past the cards */
}

/* Each section's line colour. --line = the route colour, --line-text = accessible text colour. */
[data-line="hero"]     { --line: var(--hero);    --line-text: var(--hero); }
[data-line="featured"] { --line: var(--navy);    --line-text: var(--navy);  --sign-bg: var(--navy);
                         --h2: var(--navy-dark); --h3: var(--navy); --h4: var(--navy-dark); --h2-sign: var(--navy-dark); --callout: var(--navy); }
[data-line="notable"]  { --line: var(--navy-dark); --line-text: var(--navy-dark); --sign-bg: var(--navy-dark);
                         --h2: var(--navy); --h3: var(--navy); --h4: var(--navy); --h2-sign: var(--navy); --callout: var(--navy); }
[data-line="kind"]     { --line: var(--red);     --line-text: var(--red);   --sign-bg: var(--red); }
[data-line="about"]    { --line: var(--orange);  --line-text: var(--ink);   --sign-bg: var(--orange); --sign-text: var(--ink); }
[data-line="more"]     { --line: var(--purple);  --line-text: var(--purple); --sign-bg: var(--purple);
                         --h2: var(--purple); --h3: var(--ink); --h4: var(--purple); }
[data-line="contact"]  { --line: var(--hero);    --line-text: var(--hero); }

/* Branch lines take their own colour (the stops set it; route.js follows the stops). */
.section--notable .branch-cards { --line: var(--aqua); }
.section--more .branch-cards { --line: var(--purple); }

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

html {
  overflow-x: clip;
  scroll-padding-top: calc(var(--header-h) + 32px);  /* anchors land 32px below the sticky header */
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: var(--font-body-weight);
  font-size: var(--fs-body);
  line-height: 1.4;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
:where(ul, ol)[role="list"] { list-style: none; padding: 0; }
img { display: block; max-width: 100%; }
a { color: inherit; }

/* Overpass for headings, stop names and section titles; Public Sans (body) for everything else */
:is(h1, h2, h3, h4, h5, h6, .section-title, .direction__label, .next-stop__label, .fl__stop) { font-family: var(--font-brand); }

strong, b { font-weight: 700; }
/* Italics only where written by hand (*emphasis* in Markdown, meant for paragraph text): nothing in the
   design is italic on its own, so these elements, which browsers italicise by default, stay upright */
cite, address { font-style: normal; }
/* ==highlight== — brand-colour emphasis; follows the colour of the line it sits on. */
mark { background: none; color: var(--line-text, var(--navy)); }

:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 4px;
  border-radius: 4px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 16px; top: -100px;
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: #fff;
  font-weight: 700;
  border-radius: 8px;
}
.skip-link:focus { top: 16px; }

.container {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
}

/* ---------- Header + nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  box-shadow: 0 6px 18px -10px var(--shadow-color);  /* always on, so the header never blends into the page */
  transition: transform 0.3s ease;
}
/* Hidden while scrolling down (nav.js); the extra 20px hides the shadow too */
.site-header[data-hidden] { transform: translateY(calc(-100% - 20px)); }
@media (prefers-reduced-motion: reduce) { .site-header { transition: none; } }
.site-header__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  min-height: var(--header-h);
  padding: 0 var(--gutter);
}
.site-name {
  position: relative;
  top: var(--cap-nudge);   /* Overpass sits high in its line: nudge it to the bar's centre (measured) */
  flex: none;
  font-family: var(--font-brand);
  font-size: var(--fs-site-name);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0;
  text-decoration: none;
}
.site-nav { position: relative; }
.site-nav ul { display: flex; gap: 48px; }
.site-nav__link {
  --nav-line: 3px;
  position: relative;
  display: block;
  padding: 8px 0;
  font-family: var(--font-body);
  font-size: var(--fs-nav);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0;
  text-decoration: none;
  white-space: nowrap;
}
/* Static underline under the current item: used without JS. Otherwise the sliding underline below
   takes over. */
.site-nav__link[aria-current]::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--nav-line);
  border-radius: 2px;
  background: var(--line);
}

/* Sliding underline: follows the hovered/focused item, rests on the current one, and takes on each
   item's line colour as it moves. */
.site-nav__indicator {
  --nav-line: 3px;
  position: absolute;
  left: 0;
  top: 0;
  width: var(--w, 0px);
  height: var(--nav-line);
  transform: translate(var(--x, 0px), var(--y, 0px));
  opacity: 0;
  pointer-events: none;
  will-change: transform;
}
.site-nav__indicator[data-ready] { transition: transform 0.35s ease, width 0.35s ease, opacity 0.2s ease; }
.site-nav__indicator[data-visible] { opacity: 1; }
.site-nav__indicator[data-jump] { transition: none; }
.site-nav__indicator::before { content: ""; position: absolute; inset: 0; border-radius: 2px; background: var(--color, var(--navy)); }
.site-nav__indicator[data-ready]::before { transition: background-color 0.35s ease; }
@media (prefers-reduced-motion: reduce) {
  .site-nav__indicator,
  .site-nav__indicator::before { transition: none; }
}

/* Menu button (phones only) */
.nav-toggle { display: none; }
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 24px;
  height: 3px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s ease, background-color 0.2s ease;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -8px; }
.nav-toggle__bars::after { top: 8px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { transform: translateY(-8px) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) {
  .nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after { transition: none; }
}

/* ---------- Route ---------- */
.route-host { position: relative; display: block; outline: none; }
.route {
  position: absolute;
  inset: 0 auto auto 0;
  z-index: 2;              /* over the section signs (as in Figma) */
  pointer-events: none;
  overflow: hidden;
}
/* Sections don't form their own layers, so stops and markers (z-index 3+) can sit above the line
   while everything else stays beneath it. */
.route-host > :not(.route) { position: relative; }

/* Stops. Placed by CSS; route.js reads their centres and draws the line through them. */
.stop {
  position: absolute;
  left: calc(var(--rail) - var(--stop-col, var(--col)));
  top: var(--stop-y, 50%);
  z-index: 3;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--stop-fill);
}
/* Large stops (in the section signs, the hero, the end of the line): ringed in their section's colour,
   with a drop shadow so they stand off a sign of the same colour */
.stop--lg {
  width: var(--stop-lg);
  height: var(--stop-lg);
  border: var(--stop-lg-border) solid var(--stop-ring, var(--line));
  filter: drop-shadow(5px 4px 3.5px rgb(0 0 0 / 0.25));
}
.stop--sm { width: var(--stop-sm); height: var(--stop-sm); border: var(--stop-sm-border) solid var(--line); }
.stop--terminus { --stop-ring: var(--line); }

/* Scroll progress (homepage; progress.js sets data-progress on each main-line stop):
   ahead = pale ring, passed = filled, current = filled with a gentle pulse */
[data-route-progress] .stop[data-progress] { transition: background-color 0.3s ease, border-color 0.3s ease; }
[data-route-progress] .stop--sm[data-progress="ahead"] { border-color: color-mix(in srgb, var(--line) 35%, var(--bg)); }
/* filled in a faded tint, like the detours */
[data-route-progress] .stop:is(.stop--sm, .stop--lg):is([data-progress="passed"], [data-progress="current"]) { background: color-mix(in srgb, var(--line) 50%, var(--stop-fill)); }
@media (prefers-reduced-motion: no-preference) {
  [data-route-progress] .stop[data-progress="current"] { animation: stop-pulse 2.4s ease-out infinite; }
}
@keyframes stop-pulse {
  0%        { box-shadow: 0 0 0 0 var(--pulse, color-mix(in srgb, var(--line) 45%, transparent)); }
  70%, 100% { box-shadow: 0 0 0 14px transparent; }
}
/* On a sign of the same colour the pulse radiates white instead */
.line-sign .stop { --pulse: rgb(255 255 255 / 0.6); }
@media (prefers-reduced-motion: reduce) {
  [data-route-progress] .stop[data-progress] { transition: none; }
  /* no pulse: a still halo marks the current stop instead */
  [data-route-progress] .stop[data-progress="current"] { box-shadow: 0 0 0 6px var(--pulse, color-mix(in srgb, var(--line) 30%, transparent)); }
}
.stop--anchor { width: 0; height: 0; background: none; }

/* ---------- Shared type ---------- */
.section-intro {
  margin: 34px var(--gutter) 0 var(--col);
  max-width: 965px;
  color: var(--ink);
  font-size: var(--fs-intro);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0;
}
.section-intro p + p { margin-top: 1.4em; }

.section-title {
  color: var(--line-text);
  font-size: var(--fs-sign);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.button {
  display: inline-block;
  background: var(--bg);
  padding: 18px 24.5px;
  border: 3px solid var(--ink);
  border-radius: 13px;
  font-size: var(--fs-button);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
}
.button:hover { background: var(--ink); color: var(--bg); }
.button:focus-visible { border-radius: 13px; }

.text-link {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-button);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
}
.text-link:hover { text-decoration: underline; text-underline-offset: 4px; }
.text-link > [aria-hidden="true"] { flex: none; margin-left: 12px; }

/* Line sign: the coloured pill a line's first stop sits in (Featured Works, Kind Words, About Me).
   Its left edge sits on the page margin. */
.line-sign {
  --stop-col: var(--gutter);
  position: relative;
  display: flex;
  align-items: center;
  width: fit-content;
  max-width: calc(100% - 2 * var(--gutter));
  min-height: var(--sign-h);
  margin-left: var(--gutter);
  padding: 0 40px 0 calc(var(--col) - var(--gutter));
  border-radius: var(--sign-radius);
  background: var(--sign-bg);
}
.line-sign .stop { left: var(--sign-stop); }
.line-sign__label {
  position: relative;
  top: var(--cap-nudge);
  color: var(--sign-text, var(--on-color));
  font-size: var(--fs-sign);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

/* Interchange: where a dashed branch leaves the main line (Notable Mentions, This and That). */
.interchange {
  --marker-w: 76px;
  --marker-h: 44px;
  --marker-border: 7px;
  position: relative;
  padding: 0 var(--gutter) 0 calc(var(--rail) + 89.5px);
}
.interchange .stop--anchor { --stop-col: 0px; }
.interchange__marker {
  position: absolute;
  left: calc(var(--rail) - var(--marker-w) * 0.362);
  top: 50%;
  z-index: 3;
  width: var(--marker-w);
  height: var(--marker-h);
  transform: translateY(-50%);
  border: var(--marker-border) solid var(--marker-ring);
  border-radius: 24px;
  background: var(--stop-fill);
}

/* ---------- Hero ---------- */
.hero { padding-top: calc(214px - var(--header-h)); }
.hero__title {
  --stop-y: 0.55lh;
  position: relative;
  margin: 0 var(--gutter) 0 var(--col);
  color: var(--hero);
  font-size: var(--fs-hero);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
/* Bold positioning statement + short intro (spacing and line breaks follow the refresh mockup) */
.hero__subtitle {
  margin: 26px var(--gutter) 0 var(--col);
  max-width: 15.5em;
  font-family: var(--font-brand);
  font-size: var(--fs-hero-sub);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.01em;   /* a hair tighter, as in the mockup */
}
.hero__body {
  margin: 24px var(--gutter) 0 var(--col);
  max-width: 34em;
  font-size: var(--fs-hero-body);
  line-height: 1.6;
}
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 32px; margin: 32px var(--gutter) 0 var(--col); }

/* Pill buttons and tags: simple placeholders for the refresh (style to be refined later) */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 26px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs-button);
  font-weight: 700;
  line-height: 1.1;
  text-decoration: none;
}
.pill:hover { background: var(--ink); color: var(--bg); }
.pill--solid { background: var(--ink); color: var(--bg); }
.pill--solid:hover { border-color: var(--hero); background: var(--hero); }
.pill:focus-visible { outline-offset: 4px; }
.pill__icon { flex: none; }
.ext-icon { flex: none; width: 0.85em; height: 0.85em; }

/* Nav items that aren't stops (Resume): a plain link after the route, with the new-tab icon */
.site-nav__link--ext { --line: var(--ink); display: inline-flex; align-items: center; gap: 6px; }

/* "Head Southbound" (under the intro) and "Head Northbound" (back to top, in Contact Me) */
.direction__link {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  color: var(--ink);
  text-decoration: none;
}
.direction__text { display: grid; }
.direction__label {
  font-size: var(--fs-direction);
  font-weight: 700;
  line-height: 1.3;
}
/* the arrow sits in a stop-style ring */
.direction__arrow {
  flex: none;
  box-sizing: content-box;
  padding: 10px;
  border: 2px solid currentColor;
  border-radius: 50%;
  background: var(--stop-fill);
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}
.direction__link:hover .direction__label { text-decoration: underline; text-underline-offset: 5px; }
.direction__link:hover .direction__arrow { background: var(--ink); color: var(--stop-fill); }
.direction--north .direction__link { flex-direction: column; gap: 12px; }
/* Head southbound: in the hero's indigo, no fill behind the arrow */
.direction__link--south { color: var(--hero); }
.direction__link--south .direction__arrow { background: transparent; }
.direction__link--south:hover .direction__arrow { background: var(--hero); color: var(--stop-fill); }
/* The arrow inside the ring bounces gently and continuously toward where it points */
.direction__arrow path { transform-box: fill-box; }
@media (prefers-reduced-motion: no-preference) {
  .direction__link--south .direction__arrow path { animation: hop-down 1.4s ease-in-out infinite; }
  .direction--north .direction__arrow path { animation: hop-up 1.4s ease-in-out infinite; }
}
@keyframes hop-down { 0%, 100% { transform: translateY(-1.5px); } 50% { transform: translateY(2.5px); } }
@keyframes hop-up   { 0%, 100% { transform: translateY(1.5px); } 50% { transform: translateY(-2.5px); } }
@media (prefers-reduced-motion: reduce) { .direction__arrow { transition: none; } }

/* ---------- Featured Work ---------- */
.section--featured { padding-top: 163px; }

/* Text on the left (title → summary → Read case study → tags), one large image on the right */
.project-card {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  column-gap: 48px;
  align-items: start;
  margin: 120px var(--gutter) 0 calc(var(--col) + var(--card-indent));
}
.section-intro + .project-card { margin-top: 96px; }
.project-card__title {
  --stop-col: calc(var(--col) + var(--card-indent));
  --stop-y: 0.55lh;
  position: relative;
  font-size: var(--fs-card-project);   /* larger than the section sign */
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
}
.project-card__title a { text-decoration: none; transition: color 0.2s ease; }
.project-card__title a:is(:hover, :focus-visible) { color: var(--line-text); }
.project-card__summary { max-width: 34em; margin-top: 18px; line-height: 1.55; }

/* "Case study": an outlined sign in the section colour with the end stop of the project's dotted
   detour inside it (route.js draws the line to that stop), like the section signs */
.project-card__cta { margin-top: 36px; text-align: right; }   /* the detour runs across to it */
.detour-sign {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: calc(8px + var(--cap-nudge)) 22px calc(8px - var(--cap-nudge)) 14px;
  border: 2px solid var(--line);
  border-radius: 999px;
  background: var(--bg);
  font-family: var(--font-brand);
  font-size: var(--fs-button);
  font-weight: 700;
  text-decoration: none;
  transition: background-color 0.2s ease;
}
.detour-sign:hover { background: color-mix(in srgb, var(--line) 10%, var(--bg)); }
.detour-sign__arrow { flex: none; margin-top: calc(-2 * var(--cap-nudge)); transition: transform 0.2s ease; }
.detour-sign:hover .detour-sign__arrow { transform: translateX(3px); }
.stop--detour {
  position: relative;
  left: auto;
  top: calc(-1 * var(--cap-nudge));   /* centred in the sign, not on the nudged text */
  flex: none;
  width: 20px;
  height: 20px;
  transform: none;
  border: 4px solid var(--line);
}
/* a stop a detour leaves from (Featured Work, Kind Words): dotted line of beads, wide soft turns */
[data-branch-layout="detour"] { --detour-width: 7; --detour-gap: 2.6; --detour-radius: 48; }
/* a taken detour (an open testimonial): its end stop stays filled */
[data-detour-taken] .stop--detour { background: var(--line); }
@media (prefers-reduced-motion: reduce) {
  .project-card__title a, .detour-sign, .detour-sign__arrow { transition: none; }
  .detour-sign:hover .detour-sign__arrow { transform: none; }
}

/* Page changes slide sideways like a train pulling out (cross-document View Transitions; detour.js tags
   each change "forward" or "back"). The header stays put. Browsers without support just change page. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.site-header { view-transition-name: site-header; }
::view-transition-old(root) { animation: 260ms cubic-bezier(0.45, 0, 0.55, 1) both vt-leave; }
::view-transition-new(root) { animation: 320ms cubic-bezier(0.25, 0, 0.25, 1) both vt-enter; }
html:active-view-transition-type(back)::view-transition-old(root) { animation-name: vt-leave-back; }
html:active-view-transition-type(back)::view-transition-new(root) { animation-name: vt-enter-back; }
@keyframes vt-leave      { to   { opacity: 0; transform: translateX(-56px); } }
@keyframes vt-enter      { from { opacity: 0; transform: translateX(56px); } }
@keyframes vt-leave-back { to   { opacity: 0; transform: translateX(56px); } }
@keyframes vt-enter-back { from { opacity: 0; transform: translateX(-56px); } }

/* Role and tools: a label line under the title in the section colour, items separated by small dots
   (not boxed: pills are for buttons). Semibold Overpass so it reads as a label, not body text. */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 0;
  margin: 12px 0 0 -24px;   /* each item carries its dot in 24px on its left; the first 24px is clipped */
  padding: 0;
  list-style: none;
  clip-path: inset(-4px -4px -4px 24px);   /* …so a line never starts with a dot when the list wraps */
  color: var(--line-text);
  font-family: var(--font-brand);
  font-size: var(--fs-tag);
  font-weight: 600;
  line-height: 1.45;
}
.tag::before {
  content: "";
  display: inline-block;
  width: 4px;
  height: 4px;
  margin: 0 10px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
  vertical-align: middle;
}

.project-card__media { display: block; }
a.project-card__media > * { transition: opacity 0.2s ease; }
a.project-card__media:hover > * { opacity: 0.85; }
.project-card__image { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 16px; }
.img-placeholder { background: var(--placeholder); }
@media (prefers-reduced-motion: reduce) { a.project-card__media > * { transition: none; } }

/* ---------- Spec list: three columns (homepage cards + case studies) ---------- */
.specs {
  --spec-gap: 30px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--spec-gap);
}
.specs__col { min-width: 0; }
.meta { font-size: var(--fs-spec); line-height: 1.5; letter-spacing: 0.005em; }
.meta dt { margin-bottom: 3px; color: var(--line-text); font-weight: 700; }
.meta dd { color: var(--ink-muted); }   /* values in muted grey so they read as specs */
.meta strong { color: var(--ink); font-weight: 700; }   /* **bold** call-outs stand out a little more */
.meta__p { margin: 0; }
.meta__p + .meta__p, .meta__p + .meta__list, .meta__list + .meta__p { margin-top: 6px; }
.meta .meta__row + .meta__row { margin-top: 14px; }
/* A spec value given as a list: one item per line, with a small route dot */
.meta__list { margin: 0; padding: 0; list-style: none; }
.meta__list li { position: relative; padding-left: 15px; }
.meta__list li + li { margin-top: 3px; }
.meta__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(0.75em - 3px);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--line);
}

/* Tool icons after the spec list */
.tool-icons { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 18px; }
.tool-icons img { width: 34px; height: 34px; }

/* "Read case study" sits under the third column, after the tool icons */
.specs__cta { margin-top: 28px; }

/* ---------- Branch sections (Notable Mentions, This and That) ---------- */
.section--notable { padding: 128px 0 120px; }   /* the branch curves back and runs alongside into Kind Words */
/* intro lines up with the section title (both branch sections) */
.section--branch .section-intro { margin: 30px var(--gutter) 0 calc(var(--rail) + 89.5px); }
.section--notable { --card-title: var(--teal-text); }
.section--notable .section-title { color: var(--navy-dark); }
.section--more { padding: 59px 0 222px; --card-title: var(--purple); }

/* Sub-projects: one after another down a dotted branch that swings out from the interchange and runs
   down beside the main line, so they read as a detour. Adding a project just makes the branch longer.
   route.js draws the branch through the stops, back alongside the main line, and into the next stop. */
.branch-cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 48px;
  margin: 80px var(--gutter) 0 var(--branch-text);
}
.branch-card { position: relative; display: flex; flex-direction: column; align-items: flex-start; }
/* each stop sits on the branch, left of its text */
.branch-card .stop { left: calc(var(--branch-stop) - var(--branch-text)); top: calc(var(--fs-card-title) * 0.7); }
.branch-card__title {
  color: var(--card-title, var(--navy));
  font-size: var(--fs-card-title);
  font-weight: 700;
  line-height: 1.4;
}
.branch-card__summary {
  max-width: 34em;
  margin: 6px 0 0;
  color: var(--ink-muted);
  font-weight: 600;
}
.branch-card__title a { text-decoration: none; }
/* the title is the link: another site gets the new-tab icon after it */
.branch-card__ext { display: inline-block; width: 0.7em; height: 0.7em; margin-left: 0.35em; vertical-align: 0.05em; }
.branch-card__title a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }

/* ---------- Kind Words ---------- */
.section--kind { padding: 72px 0 92px; }
.section--kind .section-intro a { color: var(--line-text); text-decoration-thickness: 2px; text-underline-offset: 4px; }
.section--kind .section-intro a[href^="http"]::after { content: " ↗" / ""; }   /* another site (decorative arrow) */

/* Each testimonial: its stop on the red line, then a large pull quote, who said it, and a button at the
   end of a detour that opens the full text. Indented further than the Featured Work cards (no image
   beside them), so the detours swing wider. */
.testimonials { margin-top: 64px; }
.testimonial + .testimonial { margin-top: 80px; }
.testimonial__rule { position: relative; margin: 0 var(--gutter) 0 var(--col); }
.testimonial__rule .stop { top: 1.5px; }   /* on the line, level with the top of the testimonial */
.testimonial__figure {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 780px;
  margin: 12px var(--gutter) 0 calc(var(--col) + var(--kind-indent));
}
.testimonial__mark {
  height: 0.5em;
  color: var(--line-text);
  font-family: var(--font-brand);
  font-size: 72px;
  font-weight: 800;
  line-height: 1;
}
.testimonial__pull { margin-top: 10px; }
.testimonial__pull p {
  max-width: 24em;
  font-family: var(--font-brand);
  font-size: var(--fs-pull);
  font-weight: 600;
  line-height: 1.35;
  text-wrap: balance;
}
.testimonial__cite { display: grid; justify-items: start; margin-top: 22px; }
.testimonial__name { display: flex; align-items: center; font-family: var(--font-brand); font-size: var(--fs-cite); font-weight: 700; line-height: 1.3; }
.testimonial__role { margin-top: 2px; color: var(--ink-muted); font-size: var(--fs-caption); line-height: 1.4; }
.testimonial__linkedin {
  position: relative;
  top: calc(-1 * var(--cap-nudge));   /* centred on the name's capitals, not its line box */
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin: -7px -7px -7px 3px;
  border-radius: 6px;
}
.testimonial__linkedin svg { width: 18px; height: 18px; }
.testimonial__linkedin:hover { background: color-mix(in srgb, var(--ink) 10%, transparent); }
/* "Full testimonial": the end of the testimonial's detour, under who said it */
.testimonial__cta { margin-top: 24px; }
.testimonial__toggle { color: var(--ink); cursor: pointer; }
.testimonial__toggle:hover .detour-sign__arrow { transform: none; }
.testimonial__chevron { transition: transform 0.3s ease; }
.testimonial__toggle[aria-expanded="true"] .testimonial__chevron { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .testimonial__chevron { transition: none; } }
/* Full text */
.testimonial__full { align-self: stretch; }
.testimonial__full blockquote { max-width: 62ch; padding-top: 24px; line-height: 1.6; }
.testimonial__full p + p { margin-top: 1em; }

/* ---------- About Me ---------- */
.section--about { padding-top: 154px; }
/* Bold lead line (same voice as the hero statement), then upright paragraphs at a comfortable width */
.about__lead {
  max-width: min(22em, calc(40 * var(--fs-about)));   /* never wider than the paragraphs below */
  text-wrap: balance;   /* lines of even length, so no lone word hangs at the end */
  margin: 34px var(--gutter) 0 var(--col);
  font-family: var(--font-brand);
  font-size: var(--fs-hero-sub);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.01em;   /* a hair tighter, as in the mockup */
}
.about__body {
  max-width: 40em;
  margin: 24px var(--gutter) 0 var(--col);
  font-size: var(--fs-about);
  line-height: 1.65;
}
.about__body p + p { margin-top: 1em; }
/* Links stay near-black with an underline in the line colour (orange text would be too faint to read) */
.about__body a { text-decoration-color: var(--line); text-decoration-thickness: 2px; text-underline-offset: 4px; }
.about__body a:hover { text-decoration-thickness: 3px; }
.about__actions { margin: 32px var(--gutter) 56px var(--col); }

/* ---------- Contact: the end of the line ----------
   The orange line runs across above the indigo area, turns down into it (route.js turns at the top of
   the section, then needs one turn radius before the stop) and ends at the terminal stop. The indigo
   area runs to the bottom of the page. */
.section--contact { padding-top: 72px; }
.contact {
  display: flow-root;           /* keeps the stop's top margin inside the area */
  padding: 0 var(--gutter) 32px;
  background: var(--hero);
  color: var(--on-color);
  text-align: center;
}
.contact :focus-visible { outline-color: var(--on-color); }
.contact .stop {
  --line: var(--orange);        /* the terminal stop belongs to the orange line arriving (ring, fill, pulse) */
  --stop-ring: var(--orange);
  position: relative;
  display: block;
  left: 0;
  top: 0;
  margin: calc(var(--contact-drop) - var(--stop-lg) / 2) auto 0;   /* centre sits --contact-drop into the area */
  transform: none;
}
.contact__title {
  max-width: 13em;
  margin: 36px auto 0;
  font-size: var(--fs-contact);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.contact__message { max-width: 30em; margin: 24px auto 0; font-size: var(--fs-about); line-height: 1.6; }
.contact__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 32px; }
/* Pills on the indigo area */
.pill--light { border-color: var(--on-color); background: transparent; color: var(--on-color); }
.pill--light:hover { background: var(--on-color); color: var(--hero); }
.pill--light-solid { border-color: var(--on-color); background: var(--on-color); color: var(--hero); }
.pill--light-solid:hover { border-color: #fff; background: #fff; color: var(--hero); }
.contact__social { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 8px; margin: 22px 0 0; padding: 0; list-style: none; }
.contact__social a { display: inline-block; padding: 10px 8px; font-size: 15px; text-underline-offset: 4px; }
.contact__social a:hover { text-decoration-thickness: 2px; }
.contact .direction--north { margin-top: 72px; }
.contact .direction__link { color: var(--on-color); }
.contact .direction__arrow { background: transparent; }
.contact .direction__link:hover .direction__arrow { background: var(--on-color); color: var(--hero); }
/* Copyright on the left, how the site was made on the right (stacked on phones) */
.contact__colophon {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 24px;
  margin-top: 64px;
  padding-top: 24px;
  border-top: 1px solid color-mix(in srgb, var(--on-color) 25%, transparent);
  color: color-mix(in srgb, var(--on-color) 85%, transparent);
  font-size: 14px;
}

/* ---------- Route Map (homepage, desktop only; route-map.js) ----------
   A small tab hangs from the top-right edge, like the "Next stop" sign on a bus: dark panel, amber
   text, and a button that pulls the map down. It hangs under the header and rises with it when the
   header slides away. Only the current stop is highlighted on the map. */
.route-host > .route-map {   /* (beats the route host's "position: relative" for its children) */
  position: fixed;
  z-index: 15;               /* under the header */
  top: var(--header-offset, var(--header-h));   /* the header's real height (route-map.js) */
  right: calc(max(0px, (100vw - var(--container)) / 2) + var(--gutter));   /* lined up with the header */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  width: 300px;
  border-radius: 0 0 14px 14px;
  box-shadow: 0 10px 30px -12px var(--shadow-color), 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
  transition: top 0.3s ease;
}
body:has(.site-header[data-hidden]) .route-host > .route-map { top: 0; }
@media (max-width: 859px) { .route-host > .route-map { display: none; } }   /* the menu button takes over */
@media (prefers-reduced-motion: reduce) { .route-host > .route-map { transition: none; } }
/* One piece: the tab hangs from the top edge (flat along it, rounded below); the map unfolds from the
   tab's bottom edge as part of the same sign */
.route-map__tab,
.route-map__panel { width: 100%; background: #fff; }
.route-map__tab { display: flex; align-items: center; gap: 4px; padding: 6px; border-radius: 0 0 14px 14px; }
.route-map:has([aria-expanded="true"]) .route-map__tab { border-radius: 0; }
.route-map__panel { border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); }
/* "NEXT STOP" on a small line above the name, as on the sign at the front of a bus */
.route-map__next {
  display: grid;
  flex: 1;
  align-content: center;
  gap: 1px;
  min-width: 0;
  min-height: 44px;
  padding: 5px 12px;
  border-radius: 9px;
  background: var(--sign-dark);
  color: var(--sign-amber);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: 0.02em;
  line-height: 1.3;
  white-space: nowrap;
}
/* the name, in capitals like an LED sign; too long to fit, it scrolls across (route-map.js), or with
   reduced motion it is cut short with "…" */
.route-map__name { overflow: hidden; text-transform: uppercase; text-overflow: ellipsis; }
.route-map__name[data-scroll] { text-overflow: clip; }
.route-map__name[data-scroll] > span { display: inline-block; padding-right: 3em; }   /* scrolled by route-map.js */
.route-map__next-label { display: inline-flex; align-items: center; gap: 6px; color: #c9cad3; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
.route-map__next-label::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--sign-amber); }
.route-map__toggle {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 2px;
  min-width: 44px;
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.route-map__toggle:hover,
.route-map__toggle[aria-expanded="true"] { background: color-mix(in srgb, var(--ink) 7%, transparent); }
.route-map__icon { flex: none; }
.route-map__chevron { flex: none; transition: transform 0.3s ease; }
.route-map__toggle[aria-expanded="true"] .route-map__chevron { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .route-map__chevron { transition: none; } }

/* The map: under the tab, as tall as the screen allows; scrolls inside if the screen is short */
.route-map__panel {
  max-height: calc(100vh - var(--header-offset, var(--header-h)) - var(--route-map-bar) - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-padding-top: 56px;   /* the current stop never hides under the sticky title */
  padding: 0 20px 12px;
  border-radius: 0 0 14px 14px;
}
/* "Route Map / Stop x of y" stays in view while the map scrolls; the stops fade out under it */
.route-map__head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 -20px 6px;
  padding: 16px 20px 8px;
  background: #fff;
}
.route-map__head::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 18px;
  background: linear-gradient(#fff, rgb(255 255 255 / 0));
  pointer-events: none;
}
.route-map__title { font-size: 18px; font-weight: 700; }
.route-map__count { color: var(--ink-muted); font-size: 13px; }
.route-map__line { margin: 0; padding: 0; list-style: none; }
.route-map__item { position: relative; }
/* the line down to the next stop, in this stop's section colour */
.route-map__item:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 20px;
  top: 17px;
  width: 4px;
  height: 100%;
  background: var(--line);
}
/* Rows are 34px: tighter than the 44px used for touch, which is fine for a mouse-only map */
.route-map__stop {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 34px;
  padding: 6px 8px 6px 44px;
  border-radius: 8px;
  text-decoration: none;
}
.route-map__stop:hover { background: color-mix(in srgb, var(--line) 8%, transparent); }
.route-map__dot {
  position: absolute;
  left: 12px;
  top: 7px;
  width: 20px;
  height: 20px;
  border: 4px solid var(--line);
  border-radius: 50%;
  background: var(--stop-fill);
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
/* More room before each section, so sections read as the main stops (the line runs through the gap) */
.route-map__item:has(+ :is(.route-map__item--section, .route-map__item--interchange)) { padding-bottom: 14px; }

/* Labels: sections larger and bolder, like their signs; everything else in a lighter grey */
.route-map__label { color: var(--ink-muted); font-family: var(--font-brand); font-size: 14px; font-weight: 600; line-height: 1.3; }
:is(.route-map__item--section, .route-map__item--interchange) > .route-map__stop .route-map__label { color: var(--ink); font-size: 17px; font-weight: 700; }
/* Where you've been: reached stops fill in a faded tint (as on the page); the current one also glows */
:is(.route-map__item[data-passed="true"] > .route-map__stop, .route-map__stop[aria-current]) .route-map__dot { background: color-mix(in srgb, var(--line) 50%, var(--stop-fill)); }
.route-map__stop[aria-current] .route-map__dot { box-shadow: 0 0 0 5px color-mix(in srgb, var(--line) 25%, transparent); }

/* Interchange (Notable Mentions, This and That): the oval marker, as on the page */
.route-map__item--interchange > .route-map__stop .route-map__dot { left: 8px; top: 8px; width: 28px; height: 18px; border-color: var(--marker-ring); border-radius: 10px; }
.route-map__item--interchange:is([data-passed="true"]) > .route-map__stop .route-map__dot,
.route-map__item--interchange > .route-map__stop[aria-current] .route-map__dot { background: color-mix(in srgb, var(--ink) 40%, var(--stop-fill)); }
.route-map__item--interchange > .route-map__stop[aria-current] .route-map__dot { box-shadow: 0 0 0 5px color-mix(in srgb, var(--ink) 15%, transparent); }

/* Branch: a dotted line drops from the interchange's oval just beside the main line, runs down past
   its stops, then eases back into the main line (drawn by route-map.js). */
.route-map__branch { position: relative; margin: 0; padding: 2px 0 12px; list-style: none; }
.route-map [data-branch="notable"] { --line: var(--aqua); }
.route-map [data-branch="more"] { --line: var(--purple); }
.route-map__branch-line { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.route-map__branch-line path { fill: none; stroke: var(--line); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 0 5.5; }
.route-map__item--branch::before { display: none; }   /* the dotted branch is the line here */
/* Branch stops sit on a line just beside the main one, so their names line up almost with the rest */
.route-map__item--branch > .route-map__stop { padding-left: 52px; }
.route-map__item--branch .route-map__dot { left: 29px; top: 10px; z-index: 1; width: 14px; height: 14px; border-width: 3px; }
@media (prefers-reduced-motion: reduce) { .route-map__dot { transition: none; } }


/* ---------- Footer: "All stops" site map ---------- */
.site-footer {
  --footer-muted: #bdb6ad;   /* 7.6:1 on the footer */
  --fl-dot: 33px;
  --fl-col-gap: 32px;
  position: relative;
  z-index: 1;
  background: var(--ink);
  color: var(--on-color);
}
.footer__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: 72px var(--gutter) 32px;
}
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-underline-offset: 4px; }
.footer__heading {
  margin-bottom: 30px;
  color: var(--footer-muted);
  font-size: var(--fs-button);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

/* Main line: one column per stop, a line joining the stops' centres */
.fl__main { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 var(--fl-col-gap); }
.fl__col { position: relative; }
.fl__col:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(var(--fl-dot) / 2);
  top: calc(var(--fl-dot) / 2 - 3.5px);
  width: calc(100% + var(--fl-col-gap));
  height: 7px;
  background: var(--on-color);
}
.fl__stop {
  position: relative;
  display: grid;
  justify-items: start;
  gap: 23px;
  font-size: var(--fs-footer-stop);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.03em;
}
.fl__dot {
  width: var(--fl-dot);
  height: var(--fl-dot);
  border: 6px solid var(--on-color);
  border-radius: 50%;
  background: var(--line);
}

/* Branch under a stop: a thin line with the links beside it */
.fl__branch {
  margin: 18px 0 0 calc(var(--fl-dot) / 2 - 1px);
  padding-left: 21px;
  border-left: 2px solid var(--footer-muted);
}
.fl__list { display: grid; gap: 13px; }
.fl__list a {
  display: block;
  max-width: 254px;
  color: var(--footer-muted);
  font-size: var(--fs-footer-item);
  line-height: 1.4;
  letter-spacing: 0.03em;
}
.fl__list a { max-width: 254px; }
.fl__list a:hover { color: var(--on-color); }
.fl__sub + .fl__list, .fl__list + .fl__sub { margin-top: 18px; }
.fl__sublabel {
  position: relative;
  display: block;
  margin-bottom: 11px;
  font-size: var(--fs-footer-sub);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.03em;
}
.fl__subdot {
  position: absolute;
  left: -32px;              /* centred on the branch line */
  top: calc(0.7em - 9.5px);
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--dot);
}

.footer__brand {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 64px;
}
.footer__name { font-family: var(--font-brand); font-size: var(--fs-site-name); font-weight: 400; }
.footer__bottom > * { margin: 0; }
.footer-social { display: flex; gap: 8px; margin-right: -10px; }
.footer-social__link { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 8px; }
.footer-social__link svg { width: auto; height: 26px; }
.footer-social__link:hover { background: rgb(255 255 255 / 0.1); }
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid rgb(255 255 255 / 0.18);
  color: var(--footer-muted);
  font-size: var(--fs-caption);
}
.footer__top { color: var(--on-color); }

/* Colophon ("Human-designed in Figma…"): beside the copyright; on its own line on phones */
.colophon { color: var(--footer-muted); font-size: var(--fs-caption); }
.colophon a { color: var(--on-color); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 699px) {
  .colophon { display: block; margin-top: 4px; }
  .colophon__sep { display: none; }
}

/* ---------- Case study + sub-project pages ---------- */
.case {
  --sign-stop: 61px;
  --rail: calc(var(--gutter) + var(--sign-stop));
  --col: calc(var(--rail) + 70px);
  --prose-col: calc(var(--rail) + 74px);
  --next-gap: 157px;
  padding-bottom: 140px;
}

.case__hero { margin: 26px var(--gutter) 0; }
.case__image { width: 100%; height: auto; aspect-ratio: 1166 / 509; object-fit: cover; }

.case__header { padding: 0 var(--gutter) 0 var(--col); }
/* Title sits in the sign, its left edge on the page margin, overlapping the banner's bottom edge */
.case__sign {
  max-width: calc(100% + var(--col) - 2 * var(--gutter));
  margin: -50px 0 0 calc(var(--gutter) - var(--col));
  padding-right: 80px;
}
.case--page .case__header:first-child .case__sign { margin-top: 61px; }  /* no banner above */
.case__summary {
  max-width: 965px;
  margin-top: 38px;
  color: var(--ink);
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0;
}
.case__meta { margin-top: 44px; }

/* Case study spec columns: thin rules between columns; values in muted grey so they read as specs */
/* Spec columns (homepage cards + case studies): thin rules between the columns */
.specs { --rule: #bdb6ad; column-gap: 0; }
.specs .specs__col + .specs__col { padding-left: 22px; border-left: 1px solid var(--rule); }
.specs .specs__col:not(:last-child) { padding-right: 22px; }

.prose {
  --stop-col: var(--prose-col);
  margin: 0 var(--gutter) 0 var(--prose-col);
  max-width: 990px;
}
/* Body text (Figma 2:399): 20px medium, line height 1.7, 27px between paragraphs,
   lines capped at ~70 characters for comfortable reading. */
.prose { font-size: var(--fs-prose); line-height: 1.7; letter-spacing: 0.01em; }
/* Body text stays at roughly 60–70 characters per line */
.prose > :is(p, ul, ol) { max-width: 68ch; }
.prose :is(p, li) { font-weight: 500; }
.prose strong { font-weight: 800; }
.prose > :is(p, ul, ol, blockquote) { max-width: var(--prose-measure, 70ch); }
.prose > * + * { margin-top: var(--prose-gap, 27px); }
/* ## Section: a stop on the route. Colours per page theme: --h2 / --h3 / --h4 (see [data-line]). */
.prose h2 {
  --stop-y: 0.5lh;
  position: relative;
  margin: var(--section-gap, 64px) 0 var(--heading-gap, 18px);
  color: var(--h2, var(--line-text));
  font-size: var(--fs-project);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0;
}
.prose > h2:first-child { margin-top: 64px; }
/* ## Section as a stop sign (Figma 79:122): a pill in --h2-sign with light text, its stop on the
   route line inside the pill's left end. Pages without --h2-sign keep plain coloured headings. */
:is([data-line="featured"], [data-line="notable"]) .prose h2 {
  --sign-inset: 43px;                                 /* pill's left edge → centre of its stop */
  --stop-col: calc(var(--rail) - var(--sign-inset));  /* puts the stop back on the route line */
  --stop-y: 50%;
  width: fit-content;
  max-width: calc(100% + var(--prose-col) - var(--rail) + var(--sign-inset));
  margin-left: calc(var(--rail) - var(--sign-inset) - var(--prose-col));
  padding: calc(10px + var(--cap-nudge)) 40px calc(10px - var(--cap-nudge)) calc(var(--prose-col) - var(--rail) + var(--sign-inset));
  border-radius: 25px;
  background: var(--h2-sign);
  color: var(--on-color);
}
.prose h3 {
  margin-bottom: 10px;
  color: var(--h3, var(--ink));
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0;
}
.prose > h3 { margin-top: 40px; }
.prose h4 {
  margin: 20px 0 10px;
  color: var(--h4, var(--ink));
  font-size: var(--fs-h4);
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.prose h3 + h4 { margin-top: 12px; }
.prose h2 + *, .prose h3 + *, .prose h4 + * { margin-top: 0; }
.prose a { color: var(--line-text); text-underline-offset: 3px; }

/* Highlighted paragraph (::: callout) */
/* Callout (Figma 79:122): semibold in the page's lighter blue */
.prose__callout { max-width: 60ch; color: var(--callout, var(--line-text)); font-size: var(--fs-callout); font-weight: 600; line-height: 1.6; letter-spacing: 0.01em; }
.prose__callout p { font-weight: inherit; }
.prose__callout p + p { margin-top: 16px; }

/* Bullets as a route: a ring per item, joined by a dotted line, in the page's line colour.
   Sub-bullets are small solid stops. Numbered lists stay as numbers. */
.prose ul { list-style: none; padding-left: 40px; }
.prose ul > li { position: relative; }
.prose ul > li + li { margin-top: 11px; }
.prose ul > li::before {
  content: "";
  position: absolute;
  left: -40px;
  top: calc(0.85em - 12px);
  z-index: 1;
  width: 24px;
  height: 24px;
  border: 4px solid var(--bullet, var(--line));
  border-radius: 50%;
  background: var(--stop-fill);
}
.prose ul > li:not(:last-child)::after {   /* dotted line down to the next item */
  content: "";
  position: absolute;
  left: -30px;
  top: 0.85em;
  height: calc(100% + 11px);
  border-left: 4px dotted var(--bullet, var(--line));
}
.prose ul.list--h3 { --bullet: var(--h3, var(--line)); }   /* lists under a ### heading */
.prose ul ul { margin: 11px 0 18px; padding-left: 26px; }   /* extra room after the last sub-bullet */
.prose li > ul:last-child { margin-bottom: 18px; }
.prose li:last-child > ul:last-child { margin-bottom: 0; }
.prose > :is(ul, ol) + * { margin-top: 36px; }                 /* extra room after a whole list */
.prose ul ul > li::before { left: -21px; top: calc(0.85em - 5.5px); width: 11px; height: 11px; border: 0; background: var(--ink); }
.prose ul ul > li::after { display: none; }
.prose ol { padding-left: 1.4em; }
.prose ol > li + li { margin-top: 11px; }

/* Images: centred in the text column; never wider than it, never stretched if smaller */
.prose img { height: auto; }
.prose__figure { margin: 48px auto; text-align: center; }
.prose__figure img { margin-inline: auto; max-width: 100%; }
.prose__figure figcaption {
  margin-top: 5px;
  color: var(--ink-muted);
  font-size: var(--fs-figcaption);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: -0.005em;
}
.prose > .prose__figure + * { margin-top: 0; }

/* Two (or three) images side by side: equal columns, tops aligned, each with its own caption */
.prose__figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: 24px;
  margin: 48px 0;
}
.prose__figures--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.prose__figures .prose__figure { margin: 0; }
.prose__figures img { width: 100%; }   /* fill the column; ratio kept, never cropped */
.prose > .prose__figures + * { margin-top: 0; }
.prose :is(h2, h3, h4) + :is(.prose__figure, .prose__figures) { margin-top: 14px; }

/* Call-to-action buttons in body text (same style as "Read case study") */
.prose__actions { display: flex; flex-wrap: wrap; gap: 16px; margin-block: 32px; }
.prose__actions--center { justify-content: center; }
.prose__actions--right { justify-content: flex-end; }
.prose > .prose__actions { max-width: var(--prose-measure, 70ch); }   /* "right" lines up with the text's right edge */
.prose a.button { color: var(--ink); text-decoration: none; }
.prose a.button:hover { color: var(--bg); }
.button__ext { display: inline-block; margin-left: 10px; vertical-align: -1px; }

/* ---------- Text beside an image (::: columns) ---------- */
.prose__columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  gap: 56px;
}
.prose__col > * + * { margin-top: 27px; }
.prose__col :is(.prose__figure, .prose__figures, .carousel) { margin: 0; }
.prose__col .prose__figure img { width: 100%; }
/* ::: columns narrow: a badge or logo beside the text, shown as is (no frame) */
.prose__columns--narrow { grid-template-columns: minmax(0, 1fr) 180px; align-items: center; }
.cs-body .prose__columns--narrow .prose__figure img { border: 0; border-radius: 0; }

/* ---------- Carousel ---------- */
.carousel { position: relative; }
.prose > .carousel { margin-block: 48px; }
.carousel__track {
  display: flex;
  align-items: flex-start;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track:focus-visible { outline-offset: 6px; }
.carousel__slide { flex: 0 0 100%; margin: 0; scroll-snap-align: start; text-align: center; }
/* Optional carousel title (::: carousel "Title"), styled like a #### heading */
.prose .carousel__title {
  margin: 0 0 10px;
  color: var(--h4, var(--ink));
  font-size: var(--fs-h4);
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.carousel__slide img { width: 100%; height: auto; }
.carousel__slide figcaption {
  margin-top: 5px;
  color: var(--ink-muted);
  font-size: var(--fs-figcaption);
  font-weight: 400;
  line-height: 1.6;
}
/* Controls appear once the script is running; without it the images simply scroll sideways. */
.carousel__controls { display: none; align-items: center; justify-content: center; margin-top: 16px; }
.carousel[data-ready] .carousel__controls { display: flex; }

/* Stops: a mini route line with a stop per image; the current one is filled */
.carousel__stops { position: relative; display: flex; gap: 28px; }
.carousel__stops::before {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  top: 50%;
  border-top: 4px dotted var(--aqua);
  transform: translateY(-50%);
}
.carousel__stop {
  position: relative;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 4px solid var(--line);
  border-radius: 50%;
  background: var(--stop-fill);
  cursor: pointer;
}
.carousel__stop[aria-current="true"] { background: var(--line); }
.carousel__stop:hover { background: color-mix(in srgb, var(--line) 35%, var(--stop-fill)); }
.carousel__stop[aria-current="true"]:hover { background: var(--line); }
.carousel__stop:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.carousel__stop::after { content: ""; position: absolute; inset: -12px; }   /* 44px touch target */

/* Carousel control versions: B = arrows over the image edges, stops below */

/* ---------- Accordion (::: accordion) ----------
   A card with a stripe in the line colour, an optional round thumbnail, the title, a 3-line
   preview, and a round +/- button. Opening slides the content down (carousel.js). */
.accordion {
  position: relative;
  border-left: 8px solid var(--line);
  border-radius: 0 17px 17px 0;
  background: rgb(255 255 255 / 0.75);
  box-shadow: 0 1px 0 #bdb6ad, 0 -1px 0 #bdb6ad;
}
.prose > .accordion { margin-block: 32px; }
.prose > .accordion + .accordion { margin-top: 20px; }
.accordion__summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 52px;
  align-items: center;
  gap: 22px;
  padding: 18px 22px;
  border-radius: 0 17px 17px 0;
  list-style: none;
  cursor: pointer;
  transition: background-color 0.3s ease, color 0.3s ease;
}
.accordion__summary::-webkit-details-marker { display: none; }
.accordion--thumb .accordion__summary { grid-template-columns: 112px minmax(0, 1fr) 52px; }
.accordion--thumb .accordion__thumb { order: -1; }
.accordion__thumb img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 50%; }
.prose .accordion__title {
  margin: 0 0 6px;
  color: var(--line);
  font-size: var(--fs-accordion);
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transition: color 0.3s ease;
}
.accordion__preview { display: block; font-size: 18px; font-weight: 400; line-height: 1.55; }
/* Preview text: at most 3 lines while closed (full text once open) */
.accordion:not([open]) .accordion__preview {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
/* Round +/- button: a plus while closed; the vertical bar turns flat into a minus when open */
.accordion__toggle {
  position: relative;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--line);
  transition: background-color 0.3s ease;
}
.accordion__toggle::before,
.accordion__toggle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 4px;
  border-radius: 2px;
  background: var(--stop-fill);
  transform: translate(-50%, -50%);
  transition: transform 0.4s ease, background-color 0.3s ease;
}
.accordion__toggle::after { transform: translate(-50%, -50%) rotate(90deg); }
.accordion[data-state="open"] .accordion__toggle::after,
.accordion[open]:not([data-state]) .accordion__toggle::after { transform: translate(-50%, -50%) rotate(0deg); }
.accordion[open] .accordion__summary { border-bottom: 1px solid #bdb6ad; border-radius: 0 17px 0 0; }
.accordion__summary:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; }
.accordion__summary:hover .accordion__title { text-decoration: underline; text-underline-offset: 5px; }
.accordion__body { padding: 28px 22px 32px; }
.accordion__body > * + * { margin-top: 27px; }

/* Once open, the top part flips to the line colour with white text (5.7:1),
   and the button turns white with a coloured minus */
.accordion[data-state="open"] .accordion__summary { background: var(--line); color: var(--on-color); border-bottom-color: transparent; }
.prose .accordion[data-state="open"] .accordion__title { color: var(--on-color); }
.accordion[data-state="open"] .accordion__toggle { background: var(--stop-fill); }
.accordion[data-state="open"] .accordion__toggle::before,
.accordion[data-state="open"] .accordion__toggle::after { background: var(--line); }
.accordion__cue { display: none; }   /* old "Read more" label, if a page was built before it was removed */

@media (prefers-reduced-motion: reduce) {
  .accordion__summary, .accordion__title, .accordion__toggle,
  .accordion__toggle::before, .accordion__toggle::after { transition: none; }
}
@media (max-width: 699px) {
  /* thumbnail hidden on phones so the text gets the width; button tucked top-right */
  .accordion__thumb { display: none; }
  .accordion__summary,
  .accordion--thumb .accordion__summary { grid-template-columns: minmax(0, 1fr); padding-right: 66px; }
  .accordion__toggle { position: absolute; right: 14px; top: 14px; width: 40px; height: 40px; }
  .accordion__toggle::before, .accordion__toggle::after { width: 16px; }
}

/* ---------- TL;DR summary box (::: tldr) ---------- */
.tldr { --tldr-pad: 30px; max-width: 990px; }
.prose > .tldr { margin-block: 40px 56px; }
.tldr > * + * { margin-top: 20px; }
.tldr .prose__actions { margin-block: 24px 0; }
.prose .tldr__label {
  color: var(--h4, var(--ink));
  font-size: var(--fs-h4);
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Panel: a light card with a stripe in the line colour (same family as the accordions) */
.tldr {
  padding: var(--tldr-pad);
  border-left: 8px solid var(--line);
  border-radius: 0 17px 17px 0;
  background: rgb(255 255 255 / 0.75);
  box-shadow: 0 1px 0 #bdb6ad, 0 -1px 0 #bdb6ad;
}

@media (max-width: 699px) { .tldr { --tldr-pad: 20px; } }

/* ---------- Videos (pasted YouTube / Vimeo embeds) ---------- */
.prose__video {
  width: 100%;
  max-width: var(--video-w, 990px);   /* the embed's width attribute: never shown wider */
  margin-inline: auto;
}
.prose > .prose__video { margin-block: 40px; }
.prose :is(h2, h3, h4) + .prose__video { margin-top: 14px; }
.prose__video iframe {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--video-ratio, 16 / 9);
  border: 0;
  border-radius: 8px;
}

/* ---------- Tables ---------- */
.prose__table { max-width: 100%; overflow-x: auto; }   /* scrolls sideways on narrow screens */
.prose__table:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.prose__table table {
  width: 100%;
  border: 3px solid var(--line);
  border-radius: 17px;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;   /* columns share the width equally */
  font-size: var(--fs-prose);
  line-height: 1.44;
}
.prose__table caption {
  padding: 0 0 10px;
  caption-side: top;
  color: var(--h4, var(--ink));
  font-size: var(--fs-h4);
  font-weight: 800;
  letter-spacing: 0.05em;
  text-align: left;
  text-transform: uppercase;
}
.prose__table th {
  padding: 12px 22px;
  background: var(--line);
  color: var(--on-color);
  font-weight: 700;
  text-align: left;
  vertical-align: bottom;
}
.prose__table td { padding: 13px 22px; vertical-align: top; }
/* round the corner cells to follow the table's rounded border */
.prose__table thead tr:first-child > :first-child { border-top-left-radius: 14px; }
.prose__table thead tr:first-child > :last-child { border-top-right-radius: 14px; }
.prose__table tbody tr:last-child > :first-child { border-bottom-left-radius: 14px; }
.prose__table tbody tr:last-child > :last-child { border-bottom-right-radius: 14px; }
.prose__table tbody tr:nth-child(even) { background: var(--on-color); }
.prose__table tbody tr:nth-child(odd) { background: var(--stop-fill); }
.prose__table :is(th, td) + :is(th, td) { border-left: 3px solid var(--line); }

/* Next stop: every project on one dashed line, a pin on the current one, then Home. */
.next-stop { margin-top: 81px; }
.next-stop__title {
  margin-left: var(--prose-col);
  color: var(--line-text);
  font-size: var(--fs-project);
  font-weight: 700;
  line-height: 1.4;
}
.next-stop__list {
  display: flex;
  margin: 98px 190px 0 calc(var(--rail) + 128.5px);  /* right: room for "Home" */
  padding-bottom: 290px;                               /* room for the angled labels (~35 characters) */
}
/* Each stop sits on its item's left edge; spacing shrinks to fit when there are many projects. */
.next-stop__item { position: relative; flex: 0 1 var(--next-gap); height: 62px; }
.next-stop__item--home { flex: none; width: 0; margin-left: 12.5px; }
.next-stop__link {
  position: absolute;
  left: -22px;
  top: 9px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--line-text);
  text-decoration: none;
}
.next-stop__link .stop { --stop-col: 0px; left: 22px; top: 22px; }
/* Labels run diagonally away from the lower right of their stop (Figma, case study frame). */
.next-stop__label {
  position: absolute;
  left: 54px;
  top: 41px;
  width: max-content;
  white-space: nowrap;      /* a wrapped second line would run into the next diagonal label */
  transform: rotate(45deg);
  transform-origin: 0 0;
  font-size: var(--fs-next-label);
  font-weight: 700;
  line-height: 1.4;
}
.next-stop__label--home {
  left: 73px;
  top: 55px;
  font-size: var(--fs-next-home);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
a.next-stop__link:hover .next-stop__label { text-decoration: underline; text-underline-offset: 4px; }
.next-stop__link:focus-visible { outline-offset: 2px; border-radius: 50%; }

/* "You Are Here" pin, its tip on the current stop */
.next-stop__pin { position: absolute; z-index: 4; left: -1.6px; top: -62px; line-height: 0; }
.next-stop__pin svg { width: 47px; height: auto; }
.next-stop__here {
  position: absolute;
  left: 59.5px;
  top: -57.5px;
  width: max-content;
  color: var(--pin);
  font-size: var(--fs-pin);
  font-weight: 700;
  line-height: 1.1;
}
.next-stop__here-break { display: block; }
.next-stop__ext { display: inline-block; margin-left: 8px; vertical-align: -1px; }

.page-end { position: relative; height: 62px; margin: 140px 0 0 calc(var(--rail) + 128.5px); }
.page-end .next-stop__link { top: 9px; }

/* ---------- Case study pages (case-study.njk) ----------
   The intro (back link, title, summary, facts, banner) runs the full width between the page margins.
   Below it, the text sits in the homepage's text column (--col) with the route on the homepage's rail
   (--rail): each ## section is a stop, filled in as you scroll (progress.js). "On this trip" lists the
   sections on the right on wide screens. The page ends in an indigo band (no "All stops" footer). */
.cs {
  --fs-cs-title: clamp(40px, calc(40px + 40 * (100vw - 375px) / 905), 80px);
  --fs-cs-summary: clamp(21px, calc(21px + 9 * (100vw - 375px) / 905), 30px);
  --fs-cs-h2: clamp(28px, calc(28px + 14 * (100vw - 375px) / 905), 42px);
  --fs-cs-h3: clamp(22px, calc(22px + 8 * (100vw - 375px) / 905), 30px);   /* a step under the H2, and lighter */
  --fs-stat: clamp(30px, calc(30px + 12 * (100vw - 375px) / 905), 42px);
  --cs-rule: #dcd8d0;
  --trip-w: 220px;
  /* the route sits closer to the page margin than on the homepage, leaving more room for the text */
  --rail: calc(var(--gutter) + 16px);
  --col: calc(var(--rail) + 56px);
  padding: 0 var(--gutter) 0 var(--col);
}
.cs__header { margin-left: calc(var(--gutter) - var(--col)); padding-top: 64px; }
/* "Back to the route": a detour sign like the homepage's "Case study". A dotted line runs in from the
   left edge to its stop, which sits on the route's column (the main line further down). Clicking it
   fills the line and the sign slides away left, back towards the route (detour.js). */
.cs-back-wrap { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; }
.cs-back {
  position: relative;
  color: var(--ink);
}
.cs-back .stop--detour { z-index: 1; }
.cs-back__track {
  position: absolute;
  top: 50%;
  right: calc(100% - 14px);   /* up to the stop's left edge (the sign's left padding) */
  width: 100vw;
  height: 7px;
  margin-top: calc(-3.5px - var(--cap-nudge) / 2);
  pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--line) 50%, transparent) 3.5px, transparent 3.9px) right center / 18.2px 7px repeat-x;
}
.cs-back__fill { position: absolute; inset: 0; border-radius: 4px; background: var(--line); transform: scaleX(0); transform-origin: right center; }
.cs-back:hover .cs-back__arrow { transform: translateX(-3px); }
/* "Next stop: …" opposite it: a quiet text link to the next case study (the last one loops to the first) */
.cs-next {
  display: inline-flex;
  align-items: center;
  gap: 0 6px;
  flex-wrap: wrap;
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: var(--fs-button);
  font-weight: 700;
  text-decoration: none;
}
.cs-next__label { color: var(--ink-muted); font-weight: 500; }
.cs-next__name { text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 2px; text-underline-offset: 4px; transition: text-decoration-color 0.2s ease; }
.cs-next:hover .cs-next__name { text-decoration-color: var(--line); }
.cs-next:hover .cs-next__arrow { transform: translateX(3px); }
.cs__title {
  margin-top: 80px;
  color: var(--hero);
  font-size: var(--fs-cs-title);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
/* The summary: a bold lead, like the homepage hero's */
.cs__summary {
  max-width: 23em;
  margin-top: 28px;
  font-family: var(--font-brand);
  font-size: var(--fs-cs-summary);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;   /* a hair tighter, as in the mockup */
}
/* Facts: one row of label/value pairs between thin rules; wraps on narrow screens */
.cs-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px 32px;
  margin-top: 44px;
  padding-block: 24px;
  border-block: 1px solid var(--cs-rule);
  line-height: 1.35;
}
.cs-facts dt { color: var(--ink-muted); font-size: var(--fs-figcaption); }
/* a value given as a list: one item per line with a small dot */
.cs-facts .meta__list li::before { background: var(--hero); }
.cs-facts .meta__list li + li { margin-top: 4px; }
.cs-facts dd { margin-top: 4px; color: var(--hero); font-size: var(--fs-spec); font-weight: 600; }
.cs__banner { margin-top: 40px; }
.cs__image { width: 100%; height: auto; aspect-ratio: 1166 / 509; object-fit: cover; border-radius: 20px; }

.cs__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--trip-w);
  gap: 64px;
  padding-bottom: 120px;
}
.cs-body { font-size: var(--fs-prose); line-height: 1.7; }
.cs-body img { height: auto; }   /* images carry their width/height (so their space is kept while they load) */
.cs-section > :is(p, ul, ol, h2, h3, h4) { max-width: 68ch; }   /* text at a comfortable measure; images use the full column */
.cs-body a { color: var(--navy); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.cs-body strong { font-weight: 700; }

/* The route on case studies (trying out the mockup's look): a 12px flat line without the drop shadow,
   pale blue ahead; stops are 30px rings: hollow and half-strength ahead, a blue "target" once passed,
   and the one you've reached radiating a soft glow (a still halo with reduced motion). */
[data-page="case-study"] .route-host { --route-width: 12; --route-ahead-base: #fff; }

.cs { --stop-sm: 30px; --stop-sm-border: 4px; --stop-dot: 7px; }
[data-route-progress] .cs .stop.stop--sm { border-color: color-mix(in srgb, var(--line) 50%, #fff); background: var(--stop-fill); }
[data-route-progress] .cs .stop.stop--sm:is([data-progress="passed"], [data-progress="current"]) {
  border-color: var(--line);
  background: radial-gradient(circle, var(--line) var(--stop-dot), var(--stop-fill) calc(var(--stop-dot) + 0.5px));
}
/* the stop you've reached radiates a soft glow; passed stops keep just the dot */
@media (prefers-reduced-motion: no-preference) {
  [data-route-progress] .cs .stop.stop--sm[data-progress="current"] { --pulse: color-mix(in srgb, var(--line) 40%, transparent); animation: stop-pulse 2.4s ease-out infinite; }
}

/* Sections: the ## heading is a stop on the route */
.cs-section { padding-top: 96px; }
.cs-section:first-child { padding-top: 80px; }
.cs-section > * + * { margin-top: 24px; }
.cs-section__title {
  --stop-y: 0.5lh;
  position: relative;
  color: var(--ink);
  font-size: var(--fs-cs-h2);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
}
/* ### Decisions (numbered in the text) and #### (for later use) */
.cs-body h3 { color: var(--ink); font-size: var(--fs-cs-h3); font-weight: 600; line-height: 1.25; letter-spacing: -0.005em; }
.cs-section > h3 { margin-top: 64px; }
.cs-section > h2 + h3 { margin-top: 40px; }
.cs-section > h3 + * { margin-top: 14px; }
.cs-body h4 { color: var(--ink); font-family: var(--font-body); font-size: inherit; font-weight: 600; line-height: 1.5; }
.cs-section > h4 { margin-top: 32px; }
.cs-section > h4 + * { margin-top: 6px; }
/* A numbered ### ("### 1. …"): the number as a route badge, the heading text hanging beside it */
.cs-step { --badge: 1.6em; display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 16px; align-items: start; }
.cs-step__num {
  display: grid;
  place-items: center;
  min-width: var(--badge);
  height: var(--badge);
  margin-top: -0.31em;   /* its middle level with the middle of the first line's capitals */
  padding: 0.23em 0.3em 0;   /* Overpass digits sit ~0.11em above the middle of the line; this centres them */
  box-sizing: border-box;
  border-radius: 10px;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-brand);
  font-size: 1em;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* Bulleted outcomes (each starts with a bold phrase) */
.cs-body :is(ul, ol):not([role]) { padding-left: 1.1em; }
.cs-body :is(ul, ol):not([role]) > li { padding-left: 0.2em; }
.cs-body :is(ul, ol):not([role]) > li + li { margin-top: 12px; }
/* Titled points (Outcome): a bold title, its description under it, a thin rule like the stats */
.cs-points { display: grid; gap: 28px; }
.cs-point { display: grid; gap: 6px; padding-left: 18px; border-left: 2px solid var(--navy); }
.cs-point__title { color: var(--navy); font-family: var(--font-brand); font-size: calc(var(--fs-body) * 1.2); font-weight: 700; line-height: 1.3; letter-spacing: -0.005em; }
.cs-point__text { color: var(--ink-muted); line-height: 1.55; }

/* Blocks get a little more room around them than paragraphs */
.cs-section > :is(.prose__figure, .prose__figures, .cs-pair, .cs-window, .cs-rotate, .cs-stats, .cs-insight, .cs-videos),
.cs-section > :is(.prose__figure, .prose__figures, .cs-pair, .cs-window, .cs-rotate, .cs-stats, .cs-insight, .cs-videos) + * { margin-top: 40px; }
.cs-section > h3 + :is(.prose__figure, .prose__figures, .cs-pair, .cs-window, .cs-rotate) { margin-top: 28px; }

/* Stat figures: side by side, each with a thin route-blue rule on the left */
.cs-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px 32px; }
.cs-stats[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cs-stats[data-count="1"] { grid-template-columns: minmax(0, 1fr); max-width: 32em; }
.cs-stat { display: grid; align-content: start; gap: 8px; padding-left: 18px; border-left: 2px solid var(--navy); }
.cs-stat__figure { color: var(--navy); font-family: var(--font-brand); font-size: var(--fs-stat); font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; }
.cs-stat__label { margin-top: -2px; color: var(--navy); font-family: var(--font-brand); font-size: calc(var(--fs-body) * 1.1); font-weight: 700; line-height: 1.3; }
.cs-stat__text { color: var(--ink-muted); font-size: var(--fs-spec); line-height: 1.45; }
.cs-stat__label + .cs-stat__text { margin-top: -4px; }

/* Figures: one image per point, captioned; a before/after pair side by side */
.cs-body .prose__figure { margin-inline: 0; text-align: left; }
.cs-body .prose__figure img { width: 100%; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); border-radius: 16px; }
.cs-body figcaption { margin-top: 10px; color: color-mix(in srgb, var(--ink-muted) 82%, var(--bg)); font-size: var(--fs-figcaption); line-height: 1.5; text-align: left; }
.cs-body .prose__figures { gap: 24px; }
.cs-body .prose__figures figcaption { margin-top: 10px; }
@media (min-width: 700px) {
  .cs-body .prose__figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* A pair (::: pair): two images side by side under one caption */
.cs-pair { margin: 0; }
.cs-pair__images { display: grid; gap: 24px 16px; }
/* Rotating screens (::: rotate): one frame, the screens crossfade in turn. Under it, the caption for the
   screen that's showing (led by its name), then a play/pause button and a pill per screen (the current
   one fills while it's up) */
.cs-rotate { --rotate-hold: 5s; margin: 0; }
.cs-rotate__screens { display: grid; }
.cs-rotate__screen { grid-area: 1 / 1; opacity: 0; visibility: hidden; transition: opacity 0.6s ease, visibility 0s linear 0.6s; }
.cs-rotate__screen.is-active { opacity: 1; visibility: visible; transition: opacity 0.6s ease; }
.cs-rotate__screen img { width: 100%; height: auto; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); border-radius: 16px; }
.cs-rotate__controls { display: none; align-items: center; gap: 10px; margin-top: 10px; }
.cs-rotate[data-ready] .cs-rotate__controls { display: flex; }
.cs-rotate__toggle {
  flex: none;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.cs-rotate__toggle:hover { background: var(--ink); color: var(--bg); }
.cs-rotate__icon--play, .cs-rotate[data-paused] .cs-rotate__icon--pause { display: none; }
.cs-rotate[data-paused] .cs-rotate__icon--play { display: block; }
.cs-rotate__dots { display: flex; align-items: center; margin: 0; padding: 0; list-style: none; }
/* one pill per screen, all the same size so nothing shifts; the current one fills with blue while it's up */
.cs-rotate__dot { display: grid; align-items: center; padding: 10px 4px; border: 0; background: none; cursor: pointer; }
.cs-rotate__dot::before { content: ""; grid-area: 1 / 1; width: 32px; height: 8px; border-radius: 4px; background: color-mix(in srgb, var(--ink) 18%, transparent); transition: background 0.2s ease; }
.cs-rotate__dot:hover::before { background: color-mix(in srgb, var(--ink) 35%, transparent); }
.cs-rotate__fill { grid-area: 1 / 1; width: 32px; height: 8px; border-radius: 4px; background: var(--navy); transform: scaleX(0); transform-origin: left; }
.cs-rotate__dot[aria-current] .cs-rotate__fill { transform: scaleX(1); }
/* while playing, the current pill fills over its hold time (rotate.js moves on when it's full) */
.cs-rotate:not([data-paused]) .cs-rotate__dot[aria-current] .cs-rotate__fill { animation: rotate-fill var(--rotate-hold) linear both; }
.cs-rotate[data-offscreen]:not([data-paused]) .cs-rotate__dot[aria-current] .cs-rotate__fill { animation-play-state: paused; }
@keyframes rotate-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.cs-rotate .cs-rotate__captions { margin-top: 12px; }
.cs-rotate__name { color: var(--ink); font-weight: 600; }
/* phone screens: a phone-sized frame, with the caption and controls beside it on wider screens */
.cs-rotate[data-portrait] .cs-rotate__screens { max-width: 300px; }
.cs-rotate[data-portrait] .cs-rotate__screen img { border-radius: 28px; border: 6px solid var(--ink); }
@media (min-width: 700px) {
  .cs-rotate[data-portrait] { display: grid; grid-template-columns: 300px minmax(0, 1fr); grid-template-rows: 1fr auto auto 1fr; column-gap: 40px; padding-inline: clamp(0px, 8vw - 40px, 72px); }
  .cs-rotate[data-portrait] .cs-rotate__screens { grid-row: 1 / -1; }
  .cs-rotate[data-portrait] .cs-rotate__captions { grid-column: 2; grid-row: 2; margin-top: 0; }
  .cs-rotate[data-portrait] .cs-rotate__controls { grid-column: 2; grid-row: 3; margin-top: 16px; }
}
@media (max-width: 699px) { .cs-rotate[data-portrait] .cs-rotate__screens { margin-inline: auto; } }
@media (prefers-reduced-motion: reduce) { .cs-rotate__screen, .cs-rotate__screen.is-active, .cs-rotate__dot::before { transition: none; } }

/* a pair image's label ("2019", "Before") sits above it, like a figure label, so nothing covers the image */
.cs-pair__item { display: grid; gap: 8px; align-content: start; }
.cs-pair__label {
  color: var(--navy);
  font-family: var(--font-brand);
  font-size: var(--fs-figcaption);
  font-weight: 700;
  line-height: 1.3;
}
.cs-pair__images img { width: 100%; height: auto; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); border-radius: 16px; }
@media (min-width: 700px) { .cs-pair__images { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
/* three images (e.g. phone screens) in a row */
@media (min-width: 600px) { .cs-pair__images:has(> :nth-child(3)) { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* phone screens get the same phone-like frame as the rotating ones */
.cs-pair[data-portrait] .cs-pair__images img { border: 5px solid var(--ink); border-radius: 24px; }
@media (max-width: 599px) { .cs-pair[data-portrait] .cs-pair__item { width: min(100%, 300px); margin-inline: auto; } }
/* a looping screen recording (an .mp4 figure), with its play/pause button in the corner */
.cs-loop { position: relative; }
.cs-loop video { display: block; width: 100%; height: auto; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); border-radius: 16px; background: color-mix(in srgb, var(--ink) 6%, transparent); }
.cs-loop__toggle { position: absolute; left: 12px; bottom: 12px; background: var(--bg); }
.cs-loop__toggle[hidden] { display: none; }
.cs-loop[data-paused] .cs-rotate__icon--pause { display: none; }
.cs-loop[data-paused] .cs-rotate__icon--play { display: block; }
/* Browser window (::: window): a whole web page that scrolls inside a frame on desktop; on phones a
   cropped preview with "See the full page" (window.js opens it in a dialog) */
.cs-window { margin: 0; }
.cs-window__frame { position: relative; overflow: hidden; border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); border-radius: 14px; background: #fff; box-shadow: 0 12px 32px -18px var(--shadow-color); }
.cs-window__bar { display: flex; align-items: center; gap: 16px; height: 40px; padding: 0 14px; border-bottom: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); background: #eeede8; }
.cs-window__dots { display: flex; gap: 6px; }
.cs-window__dots i { width: 11px; height: 11px; border-radius: 50%; background: #d3d1ca; }
.cs-window__address { flex: 1; max-width: 420px; margin-inline: auto; padding: 4px 12px; overflow: hidden; border-radius: 6px; background: #fff; color: var(--ink-muted); font-size: 13px; line-height: 1.3; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
.cs-window__view { height: 560px; overflow-y: auto; }
.cs-window__view:focus-visible { outline-offset: -3px; }
.cs-window__view img { display: block; width: 100%; height: auto; }
/* a soft fade at the bottom until the end is reached, and a hint until the first scroll */
.cs-window__frame::after { content: ""; position: absolute; inset: auto 0 0; height: 72px; pointer-events: none; background: linear-gradient(transparent, rgb(255 255 255 / 0.95)); transition: opacity 0.3s ease; }
.cs-window[data-end] .cs-window__frame::after { opacity: 0; }
.cs-window__hint {
  position: absolute;
  left: 50%;
  bottom: 16px;
  z-index: 1;
  display: inline-flex;
  gap: 6px;
  padding: 7px 14px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.cs-window[data-scrolled] .cs-window__hint { opacity: 0; }
.cs-window__open { display: none; }
@media (prefers-reduced-motion: reduce) { .cs-window__frame::after, .cs-window__hint { transition: none; } }
@media (max-width: 699px) {
  .cs-window__view { height: 360px; overflow: hidden; }   /* no scrolling inside the page on a phone */
  .cs-window__hint { display: none; }
  /* the whole preview opens the full page; a small chip in the corner says so */
  .cs-window__open { position: absolute; inset: 40px 0 0; z-index: 2; display: block; border-radius: 0 0 14px 14px; }
  .cs-window__chip {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: rgb(37 37 37 / 0.85);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
  }
  .cs-window[data-end] .cs-window__frame::after { opacity: 1; }
}

/* Every image opens in the lightbox (lightbox.js wraps it in a .cs-zoom button): a zoom cursor, and on
   hover or keyboard focus a small expand chip in the corner */
.cs-zoom { position: relative; display: block; width: 100%; padding: 0; border: 0; border-radius: 16px; background: none; cursor: zoom-in; }
.cs-zoom::after {
  content: "";
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgb(37 37 37 / 0.85) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M10 2h4v4M6 14H2v-4M14 2 9 7M2 14l5-5' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat;
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.cs-zoom:is(:hover, :focus-visible)::after { opacity: 1; }
.cs-zoom:focus-visible { outline-offset: 4px; }
.cs-window__view .cs-zoom { border-radius: 0; }
.cs-window__view .cs-zoom::after { display: none; }   /* the window has its own hint */
@media (prefers-reduced-motion: reduce) { .cs-zoom::after { transition: none; } }

/* The lightbox: the page stays visible behind a dark veil; the image as large as fits with its
   caption right under it (set larger: it's the only text there), and its position above */
.lightbox {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #f1f1f1;
}
.lightbox[open] { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
.lightbox::backdrop { background: rgb(20 20 28 / 0.82); backdrop-filter: blur(4px); }   /* the page shows through, softened so it doesn't compete */
.lightbox :focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; }
.lightbox__count { font-size: 15px; font-variant-numeric: tabular-nums; color: rgb(241 241 241 / 0.75); }
.lightbox__close { min-height: 44px; padding: 0 12px; border: 0; border-radius: 8px; background: none; color: inherit; font: 600 16px/1 var(--font-body); cursor: pointer; }
.lightbox__close:hover { background: rgb(255 255 255 / 0.1); }
.lightbox__stage { display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; padding: 0 80px 32px; overflow: hidden; }
/* the image shrinks to fit the space left after its caption */
.lightbox__figure { display: flex; flex-direction: column; align-items: center; max-width: 100%; max-height: 100%; min-height: 0; margin: 0; }
.lightbox__img { flex: 0 1 auto; min-height: 0; max-width: 100%; width: auto; height: auto; object-fit: contain; border-radius: 6px; }
.lightbox__caption { flex: none; box-sizing: border-box; width: 100%; max-width: 60ch; margin-top: 18px; color: #f1f1f1; font-size: var(--fs-body); line-height: 1.5; text-align: center; }
.lightbox__where { display: block; margin-bottom: 4px; color: rgb(241 241 241 / 0.65); font-size: var(--fs-figcaption); }
.lightbox__text { display: block; }
.lightbox__where:empty, .lightbox__text:empty { display: none; }
/* a whole web page: full width up to a readable size, scrolling; its caption stays in view at the bottom */
.lightbox__stage[data-tall] { align-items: flex-start; overflow-y: auto; padding-bottom: 0; }
.lightbox__stage[data-tall] .lightbox__figure { max-height: none; }
.lightbox__stage[data-tall] .lightbox__img { width: min(100%, 1100px); }
.lightbox__stage[data-tall] .lightbox__caption { position: sticky; bottom: 0; max-width: none; margin-top: 0; padding: 14px 20px 18px; background: rgb(20 20 28 / 0.92); }
.lightbox__nav {
  position: absolute;
  top: 50%;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  transform: translateY(-50%);
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.12);
  color: #fff;
  font-size: 22px;
  cursor: pointer;
}
.lightbox__nav:hover { background: rgb(255 255 255 / 0.22); }
.lightbox__nav--prev { left: 16px; }
.lightbox__nav--next { right: 16px; }
@media (max-width: 699px) {
  .lightbox[open] { padding-bottom: 60px; }   /* room for the arrows along the bottom */
  .lightbox__stage { padding: 0 12px 12px; }
  .lightbox__nav { top: auto; bottom: 8px; transform: none; width: 44px; height: 44px; }
  /* where it's from, and one line of the caption until tapped */
  .lightbox__caption { margin-top: 14px; text-align: left; cursor: pointer; }
  .lightbox__caption:not([data-open]) .lightbox__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Diagrams drawn in the page (inline SVG) */
.cs-diagram svg { display: block; width: 100%; max-width: 680px; height: auto; margin-inline: auto; }

/* Note: a soft tinted box with a bold label */
.cs-note { padding: 16px 20px; border-radius: 12px; background: color-mix(in srgb, var(--ink) 5%, var(--bg)); font-size: var(--fs-spec); line-height: 1.55; }
.cs-note > * + * { margin-top: 10px; }
.cs-section > .cs-note { margin-top: 32px; }
/* Insight call-out: white panel, route-blue bar on the left, bold label */
.cs-insight { padding: 22px 26px; border-left: 6px solid var(--navy); border-radius: 0 12px 12px 0; background: #fff; }
.cs-insight__label { color: var(--navy); font-family: var(--font-brand); font-weight: 700; }
.cs-insight > * + * { margin-top: 8px; }

/* Link row (::: links): outlined buttons, like the route signs, with ↗ (another site) or → */
.cs-links { display: flex; flex-wrap: wrap; gap: 12px 16px; }
.cs-section > .cs-links { margin-top: 28px; }
.cs-body .cs-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: calc(8px + var(--cap-nudge)) 22px calc(8px - var(--cap-nudge));
  border: 2px solid var(--line);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: var(--fs-button);
  font-weight: 700;
  line-height: 1.1;
  text-decoration: none;
  transition: background-color 0.2s ease;
}
.cs-body .cs-link:hover { background: color-mix(in srgb, var(--line) 10%, var(--bg)); }
.cs-link__arrow { display: inline-block; margin-top: calc(-2 * var(--cap-nudge)); transition: transform 0.2s ease; }
.cs-link:hover .cs-link__arrow { transform: translate(2px, -2px); }
.cs-link[href^="/"]:hover .cs-link__arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) { .cs-body .cs-link { transition: none; } }

/* Videos side by side, stacked on narrow screens */
.cs-videos { display: grid; gap: 24px; }
.cs-video { margin: 0; }
.cs-video .prose__video { max-width: none; }
/* a YouTube video: its thumbnail (cropped to 16:9, which trims YouTube's letterbox bars) with YouTube's
   red play button in the middle, so it's clear it plays on YouTube; it opens YouTube in a new tab */
.cs-video__link { position: relative; display: block; overflow: hidden; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); border-radius: 16px; background: var(--ink); text-decoration: none; }
.cs-video__link img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; transition: transform 0.4s ease; }
.cs-video__play { position: absolute; top: 50%; left: 50%; width: 68px; height: 48px; margin: -24px 0 0 -34px; filter: drop-shadow(0 2px 8px rgb(0 0 0 / 0.35)); transition: transform 0.2s ease; }
.cs-video__play-bg { fill: #ff0033; transition: fill 0.2s ease; }
/* on hover (always, on touch screens) a pill in the corner says it opens YouTube */
.cs-video__badge { position: absolute; left: 12px; bottom: 12px; padding: 6px 12px; border-radius: 999px; background: #fff; color: var(--ink); box-shadow: 0 2px 10px rgb(0 0 0 / 0.25); font-size: var(--fs-figcaption); font-weight: 600; line-height: 1.2; opacity: 0; transform: translateY(4px); transition: opacity 0.2s ease, transform 0.2s ease; }
.cs-video__link:is(:hover, :focus-visible) .cs-video__badge { opacity: 1; transform: none; }
@media (hover: none) { .cs-video__badge { opacity: 1; transform: none; } }
.cs-video__link:hover img { transform: scale(1.02); }
.cs-video__link:is(:hover, :focus-visible) .cs-video__play { transform: scale(1.08); }
.cs-video__link:is(:hover, :focus-visible) .cs-video__play-bg { fill: #cc0029; }
@media (prefers-reduced-motion: reduce) { .cs-video__link img, .cs-video__play, .cs-video__play-bg, .cs-video__badge { transition: none; } .cs-video__link:is(:hover, :focus-visible) :is(img, .cs-video__play) { transform: none; } }
/* side by side in pairs; an odd one out (e.g. the final video) runs the full width below */
@media (min-width: 700px) {
  .cs-videos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cs-video:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* "On this trip": the page's sections as stops on a small line; passed ones filled, the current one
   ringed, as on the route */
.cs-trip { padding-top: 80px; }
.cs-trip__inner { position: sticky; top: calc(var(--header-h) + 24px); }
.cs-trip__title { color: var(--ink); font-family: var(--font-body); font-size: var(--fs-spec); font-weight: 700; }
.cs-trip__list { margin-top: 12px; }
.cs-trip__item { position: relative; }
.cs-trip__item:not(:last-child)::before {   /* the line on to the next section */
  content: "";
  position: absolute;
  left: 6px;
  top: 22px;
  height: 100%;
  width: 3px;
  background: color-mix(in srgb, var(--line) 25%, var(--bg));
}
.cs-trip__link {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-left: -8px;
  padding: 11px 8px;
  border-radius: 8px;
  color: var(--ink-muted);
  font-family: var(--font-brand);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
  text-decoration: none;
}
.cs-trip__link:hover { background: color-mix(in srgb, var(--line) 8%, transparent); color: var(--ink); }   /* as on the Route Map */
.cs-trip__dot {
  flex: none;
  width: 15px;
  height: 15px;
  margin-top: 1px;
  border: 3px solid color-mix(in srgb, var(--line) 35%, var(--bg));
  border-radius: 50%;
  background: var(--stop-fill);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}
.cs-trip__link:is([data-passed], [aria-current]) .cs-trip__dot { border-color: var(--line); background: color-mix(in srgb, var(--line) 50%, var(--stop-fill)); }
.cs-trip__link[aria-current] { color: var(--ink); font-weight: 700; }
.cs-trip__link[aria-current] .cs-trip__dot { box-shadow: 0 0 0 4px color-mix(in srgb, var(--line) 25%, transparent); }
@media (prefers-reduced-motion: reduce) { .cs-trip__dot, .cs-link__arrow { transition: none; } }
@media (max-width: 1099px) {
  .cs__layout { grid-template-columns: minmax(0, 1fr); }
  .cs-trip { display: none; }
}

/* ---------- The end of a case study: an indigo band ----------
   "Next stop…", then every Featured Work project as a stop on a short line, names at 45° as on a
   route diagram, a "You are here" pin on this project, and "Return to the route" at the end of the
   line. Down the left on narrower screens. Then the copyright line. */
.cs-end { background: var(--hero); color: var(--on-color); }
.cs-end :focus-visible { outline-color: var(--on-color); }
.cs-end__inner { padding: 72px var(--gutter) 32px; }
.pill--light:hover { text-decoration: none; }

.cs-line { --dot: 24px; --dot-ring: 5px; --track: 6px; --step: clamp(112px, 12vw, 150px); --amber: var(--sign-amber); }
.cs-line__title {
  color: var(--on-color);
  font-size: var(--fs-contact);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.02em;
}
.cs-line__stops { display: flex; align-items: flex-start; margin-top: 88px; padding-bottom: 150px; }   /* room for the pin above and the angled names below */
.cs-line__item { position: relative; flex: none; width: var(--step); height: var(--dot); }
.cs-line__item:not(.cs-line__item--end)::before {   /* the track on to the next stop */
  content: "";
  position: absolute;
  left: calc(var(--dot) / 2);
  top: calc(var(--dot) / 2 - var(--track) / 2);
  width: var(--step);
  height: var(--track);
  background: color-mix(in srgb, var(--on-color) 35%, transparent);
}
.cs-line__link { position: absolute; inset: 0 auto auto 0; display: block; width: var(--dot); height: var(--dot); border-radius: 50%; color: color-mix(in srgb, var(--on-color) 80%, transparent); text-decoration: none; }
.cs-line__dot { position: absolute; inset: 0; border: var(--dot-ring) solid var(--on-color); border-radius: 50%; background: var(--hero); transition: background-color 0.2s ease; }
/* names run diagonally away from the lower right of their stop */
.cs-line__name {
  position: absolute;
  left: calc(var(--dot) + 12px);   /* clear of the stop */
  top: calc(var(--dot) - 2px);
  width: max-content;
  white-space: nowrap;             /* one line, unless map_name breaks it with a | */
  transform: rotate(45deg);
  transform-origin: 0 0;
  font-family: var(--font-brand);
  font-size: var(--fs-spec);
  font-weight: 600;
  line-height: 1.25;
}
a.cs-line__link:hover { color: var(--on-color); }
a.cs-line__link:hover .cs-line__name { text-decoration: underline; text-underline-offset: 4px; }
a.cs-line__link:hover .cs-line__dot { background: var(--on-color); }
a.cs-line__link:focus-visible { outline-offset: 4px; }
.is-current .cs-line__link { color: var(--on-color); }
.is-current .cs-line__name { font-weight: 800; }
.is-current .cs-line__dot { border-color: var(--amber); background: var(--amber); box-shadow: 0 0 0 5px color-mix(in srgb, var(--amber) 30%, transparent); }
/* this project's stop glows, like the current stop on the route */
@media (prefers-reduced-motion: no-preference) {
  .is-current .cs-line__dot { --pulse: color-mix(in srgb, var(--amber) 55%, transparent); animation: stop-pulse 2.4s ease-out infinite; }
}
/* the pin stands on the stop, "You are here" beside it */
.cs-line__here { position: absolute; left: -6px; bottom: calc(var(--dot) / 2 - 2px); display: flex; align-items: flex-start; gap: 10px; width: max-content; color: var(--amber); font-family: var(--font-brand); font-size: var(--fs-pin); font-weight: 700; line-height: 1; }
/* the text centred on the pin's hole (18px down a 36px-wide pin); Overpass sits high, so nudge it down */
.cs-line__here-text { margin-top: calc(18px - 0.5em + var(--cap-nudge)); }
.cs-line__pin { line-height: 0; }
.cs-line__pin svg { width: 36px; height: auto; }
.cs-line__pin path { fill: var(--amber); }
.cs-line__pin circle { fill: var(--hero); }
/* "Return to the route" at the end of the line: a sign like "Back to the route", the line running into
   its stop (the transfer back to the main route) */
.cs-line__item--end { display: flex; align-items: center; width: auto; }
.cs-line__item:nth-last-child(2)::before {   /* from the last project's stop right into the sign's stop */
  z-index: 2;
  left: var(--dot);
  width: calc(var(--step) - var(--dot) + 16px);   /* 16px: the sign's border and left padding */
}
.cs-line__return { --line: var(--on-color); border-color: var(--on-color); background: var(--hero); color: var(--on-color); white-space: nowrap; }
.cs-line__return:hover { background: color-mix(in srgb, var(--on-color) 12%, var(--hero)); }
.cs-line__return .stop--detour { background: var(--hero); }
.cs-line__return:hover .cs-line__arrow { transform: translateX(3px); }

.cs-end__colophon {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 24px;
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid color-mix(in srgb, var(--on-color) 20%, transparent);
  color: color-mix(in srgb, var(--on-color) 85%, transparent);
  font-size: 14px;
}
@media (prefers-reduced-motion: reduce) { .cs-line__dot { transition: none; } }
@media (max-width: 899px) {
  /* the line runs down the left, names beside the stops, "Return to the route" at the end */
  .cs-line__stops { flex-direction: column; margin-top: 40px; padding: 0 0 0 calc(26px - var(--dot) / 2); }   /* room for the sign's left edge */
  .cs-line__item { width: auto; height: auto; padding-bottom: 18px; }
  .cs-line__item:not(.cs-line__item--end)::before { left: calc(var(--dot) / 2 - var(--track) / 2); top: calc(var(--dot) / 2); width: var(--track); height: 100%; }
  .cs-line__link { position: relative; display: grid; grid-template-columns: var(--dot) minmax(0, 1fr); gap: 0 16px; width: auto; height: auto; border-radius: 4px; }
  .cs-line__dot { position: relative; grid-column: 1; grid-row: 1; height: var(--dot); }
  .cs-line__name { position: static; grid-column: 2; grid-row: 1; width: auto; white-space: normal; transform: none; padding-top: 1px; }
  .cs-line__br { display: none; }   /* names fit beside their stops: the | break is just a space */
  /* "You are here" under the name instead of a pin above the stop */
  .cs-line__here { position: static; grid-column: 2; grid-row: 2; margin-top: 6px; }
  .cs-line__pin { display: none; }
  .cs-line__here-text { margin-top: 0; font-size: var(--fs-figcaption); }
  .cs-line__item--end { padding: 6px 0 0; }
  .cs-line__item:nth-last-child(2)::before { left: calc(var(--dot) / 2 - var(--track) / 2); top: var(--dot); width: var(--track); height: calc(100% - var(--dot) + 20px); }   /* down into the sign's stop (6px gap + 14px to the stop's top) */
  .cs-line__return { margin-left: calc(var(--dot) / 2 - 26px); }   /* its stop on the line */
}
@media (max-width: 699px) {
  .cs { --stop-sm: 24px; --stop-sm-border: 3.5px; --stop-dot: 5px; }
  .cs__header { padding-top: 40px; }
  .cs__title { margin-top: 48px; }
  .cs-stats, .cs-stats[data-count] { grid-template-columns: minmax(0, 1fr); }
  .cs-section { padding-top: 72px; }
  .cs-section:first-child { padding-top: 56px; }
  .cs-end__inner { padding-top: 64px; }
}

/* Featured Work cards stack (text, then image) once the text column would run much taller than the
   image beside it (the image keeps its own shape, so side by side it would leave a gap under it) */
@media (max-width: 1139px) {
  .project-card { grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
  .project-card__text { max-width: 640px; }
  .project-card__media { max-width: 640px; }
}

/* ==========================================================================
   Tablet: 700–1023px
   ========================================================================== */
@media (max-width: 1023px) {
  :root {
    --gutter: 40px;
  }

  .site-nav ul { gap: 32px; }

  .hero { padding-top: 110px; }
  .section--featured { padding-top: 120px; }

  .specs { --spec-gap: 22px; }


  .section--notable { padding-bottom: 104px; }
  .section--kind { padding-top: 64px; }
  .section--more { padding-bottom: 180px; }
}

@media (max-width: 1023px) {
  /* side-by-side images stack on tablet and phone */
  .prose__figures, .prose__figures--3 { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  /* text beside an image stacks: text first, then the image */
  .prose__columns { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .prose__columns--narrow .prose__figure img { width: 160px; }
  .specs .specs__col + .specs__col { padding-left: 16px; }
  .specs .specs__col:not(:last-child) { padding-right: 16px; }
  .prose > h2:first-child { margin-top: 56px; }
  .next-stop__list { margin-right: 150px; }
}

/* ==========================================================================
   Hamburger menu: < 860px (four nav items no longer fit beside the name)
   ========================================================================== */
@media (max-width: 859px) {
  /* Header: name + menu button; the nav opens as a panel underneath.
     (Without JS the nav simply sits under the name.) */
  .site-header__inner { flex-direction: column; align-items: flex-start; gap: 10px; padding-top: 16px; }

  .site-nav ul { gap: 22px; margin-top: 0; }

  .site-header[data-js] { --header-h: 64px; }
  .site-header[data-js] .site-header__inner { flex-direction: row; align-items: center; padding-top: 0; }
  .site-header[data-js] .nav-toggle {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin-right: -10px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ink);
    cursor: pointer;
  }
  .site-header[data-js] .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: 4px var(--gutter) 20px;
    background: var(--bg);
    box-shadow: 0 10px 18px -12px var(--shadow-color);
  }
  .site-header[data-js][data-open] .site-nav { display: block; }

  /* Menu as a mini route, drawn like the Route Map: white stops ringed in each section's colour, joined
     by a line in that colour down to the next stop. The section on screen fills in a tint and glows. */
  .site-header[data-js] .site-nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding-left: 44px;
  }
  .site-header[data-js] .site-nav li { position: relative; }
  .site-header[data-js] .site-nav li[data-line]::before {   /* the stop */
    content: "";
    position: absolute;
    left: -42px;
    top: 50%;
    z-index: 1;
    width: 22px;
    height: 22px;
    transform: translateY(-50%);
    border: 5px solid var(--line);
    border-radius: 50%;
    background: var(--stop-fill);
    transition: background-color 0.3s ease, box-shadow 0.3s ease;
  }
  .site-header[data-js] .site-nav li[data-line]:has(+ li[data-line])::after {   /* the line to the next stop */
    content: "";
    position: absolute;
    left: -33.5px;
    top: 50%;
    width: 5px;
    height: 100%;
    background: var(--line);
  }
  .site-header[data-js] .site-nav li[data-line]:has([aria-current])::before {
    background: color-mix(in srgb, var(--line) 50%, var(--stop-fill));
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--line) 25%, transparent);
  }
  /* Resume isn't a stop: it sits under the route, lined up with the stops' names */
  .site-header[data-js] .site-nav__ext { margin-top: 8px; }
  .site-header[data-js] .site-nav__link { padding: 14px 0; font-size: var(--fs-nav-menu); }
  .site-header[data-js] .site-nav__link::before,
  .site-header[data-js] .site-nav__link::after { display: none; }
  /* The sliding indicator becomes a coloured underline (no stop) */
  .site-header[data-js] .site-nav__indicator { --nav-stop: 4px; --nav-line: 4px; margin-top: -8px; }
  .site-header[data-js] .site-nav__indicator::after { display: none; }
}
@media (min-width: 860px) {
  .site-nav[data-indicator] .site-nav__link::before,
  .site-nav[data-indicator] .site-nav__link::after { display: none; }
}

/* ==========================================================================
   Phone: < 700px — one column, the whole route on the left
   ========================================================================== */
@media (max-width: 699px) {
  :root {
    --gutter: 16px;
    --sign-stop: 30px;
    --col: calc(var(--rail) + 36px);
    --stop-lg: 44px;
    --stop-lg-border: 10px;
    --stop-sm: 28px;
    --stop-sm-border: 5px;
    --sign-h: 60px;
    --sign-radius: 22px;
    --fs-sign: 28px;
    --header-h: 64px;

    --route-width: 14;
    --branch-width: 8;
    --turn-radius: 48;
    --interchange-out: 19px;
    --branch-radius: 24px;
    --branch-text: calc(var(--branch-stop) + 28px);
  }

  .hero { padding-top: 40px; }
  .hero__subtitle { margin-top: 24px; }
  .hero__actions { margin-top: 24px; }
  .hero__body { margin-top: 20px; }

  .line-sign { padding-block: 10px; padding-right: 24px; }
  .section-intro { margin-top: 20px; }

  .button { padding: 14px 18px; border-width: 2px; border-radius: 10px; }

  /* Featured work: one column */
  .section--featured { padding-top: 72px; }
  /* section intros get the same extra room below on phones, so dividers and branch curves
     never crowd the text (Featured Works, Notable Mentions, This and That) */
  .project-card { margin-top: 88px; }
  .section-intro + .project-card { margin-top: 64px; }

  /* Spec columns stack into one */
  .specs { grid-template-columns: minmax(0, 1fr); row-gap: 14px; }
  .specs .specs__col,
  .specs .specs__col:not(:last-child) { padding-right: 0; }
  .specs .specs__col + .specs__col { padding-left: 0; border-left: 0; }
  .specs { row-gap: 18px; }
  .specs .specs__col + .specs__col { padding-top: 18px; border-top: 1px solid var(--rule); }


  .prose__table table { font-size: 16px; }
  .prose__table :is(th, td) { padding: 10px 14px; }
  .prose ul { padding-left: 34px; }
  .prose ul > li::before { left: -34px; width: 20px; height: 20px; top: calc(0.85em - 10px); }
  .prose ul > li:not(:last-child)::after { left: -26px; }

  /* Branches */
  .interchange { --marker-w: 52px; --marker-h: 30px; --marker-border: 5px; padding-left: calc(var(--rail) + 46px); }
  .interchange__marker { border-radius: 16px; }
  .section--notable { padding: 72px 0 96px; }
  .section--branch .section-intro { margin: 20px var(--gutter) 0 calc(var(--rail) + 46px); }
  .section--more { padding: 64px 0 144px; }   /* room for the branch to curve back and run alongside */
  .branch-cards { row-gap: 40px; margin-top: 64px; }

  /* Kind Words */
  .section--kind { padding: 72px 0 48px; }
  .testimonials { margin-top: 40px; }
  .testimonial + .testimonial { margin-top: 56px; }
  .testimonial__figure { max-width: none; margin-top: 20px; }

  /* About */
  .section--about { padding-top: 72px; }
  .about__lead { margin-top: 20px; }
  .about__body { margin-top: 16px; }
  .about__actions { margin-top: 24px; margin-bottom: 32px; }

  /* Contact */
  .section--contact { padding-top: 48px; }
  .contact .direction--north { margin-top: 56px; }
  .contact__colophon { flex-direction: column; align-items: center; margin-top: 48px; }
}

/* Case study on phones: the whole route runs straight down, Next stop included. */
@media (max-width: 699px) {
  .case {
    --sign-stop: 30px;
    --col: calc(var(--rail) + 36px);
    --prose-col: var(--col);
    padding-bottom: 72px;
  }
  .case__hero { margin-top: 16px; }
  .case__sign { margin-top: -24px; padding-right: 24px; }
  .case__summary { margin-top: 16px; }
  .case__meta, .prose > h2:first-child { margin-top: 40px; }
  .prose h2 { margin: 48px 0 8px; }
  :is([data-line="featured"], [data-line="notable"]) .prose h2 { --sign-inset: 30px; padding: calc(8px + var(--cap-nudge)) 20px calc(8px - var(--cap-nudge)) calc(var(--prose-col) - var(--rail) + var(--sign-inset)); border-radius: 20px; }
  .prose > * + * { margin-top: 20px; }
  .prose__figure { margin-block: 32px; }

  .next-stop { margin-top: 56px; }
  .next-stop__list { flex-direction: column; margin: 28px var(--gutter) 0 var(--rail); padding-bottom: 0; }
  .next-stop__item { flex: none; height: 64px; }
  .next-stop__item--home { width: auto; margin: 12px 0 0; }
  .next-stop__label,
  .next-stop__label--home {
    left: 52px;
    top: 22px;
    max-width: calc(100vw - var(--rail) - 30px - var(--gutter));
    white-space: normal;
    transform: translateY(-50%);
    font-size: var(--fs-next-label);
    line-height: 1.2;
  }
  .next-stop__label--home { font-size: var(--fs-next-home); }

  .next-stop__pin { left: 8px; top: -29px; }
  .next-stop__pin svg { width: 28px; }
  /* Pin only on phones; "You Are Here" stays available to screen readers. */
  .next-stop__here {
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .page-end { margin: 72px 0 0 var(--rail); }
}

/* Footer on smaller screens */
@media (max-width: 1023px) {
  /* two stops per row; the joining line would break between rows, so it's dropped */
  .fl__main { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 40px; }
  .fl__col::before { display: none; }
}
@media (max-width: 699px) {
  .footer__inner { padding-top: 48px; }
  /* one column: the main line runs down the left through every stop */
  .fl__main { grid-template-columns: minmax(0, 1fr); row-gap: 28px; }
  .fl__col:not(:last-child)::before {
    display: block;
    left: calc(var(--fl-dot) / 2 - 3.5px);
    top: calc(var(--fl-dot) / 2);
    width: 7px;
    height: calc(100% + 28px);
  }
  .fl__stop { grid-template-columns: var(--fl-dot) 1fr; align-items: center; gap: 16px; }
  .fl__branch { margin-left: calc(var(--fl-dot) + 16px); border-left: 0; padding-left: 0; }
  /* branch dots sit on the main line, like interchanges */
  .fl__subdot { left: calc(-1 * (var(--fl-dot) + 16px) + var(--fl-dot) / 2 - 9.5px); z-index: 1; }
}
