/* ============================================
   Daniel Hong — Portfolio
   Design system: Apple-inspired
   Light canvas, SF Pro type, pill buttons, rounded tiles
   ============================================ */

:root {
  --text: #1d1d1f;
  --text-secondary: #6e6e73;
  --text-tertiary: #86868b;
  --bg: #ffffff;
  --bg-alt: #f5f5f7;
  --bg-dark: #000000;
  --blue: #0071e3;
  --blue-hover: #0077ed;
  --border: #d2d2d7;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
          "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --nav-h: 48px;
  --container: 980px;
  --wide: 1250px;
  --radius: 18px;
  --z-nav: 50;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.47059;
  letter-spacing: -0.022em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

::selection { background: rgba(0, 113, 227, 0.2); }

a { color: inherit; text-decoration: none; }

img { max-width: 100%; display: block; }

/* ---------- Type scale ---------- */

h1, h2, h3, h4 {
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.015em;
}

.display {
  font-size: clamp(40px, 7.5vw, 80px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  font-weight: 600;
}

.headline {
  font-size: clamp(32px, 5vw, 48px);
  line-height: 1.08349;
  letter-spacing: -0.003em;
  font-weight: 600;
}

.subhead {
  font-size: clamp(19px, 2.4vw, 24px);
  line-height: 1.375;
  letter-spacing: 0.004em;
  font-weight: 400;
  color: var(--text-secondary);
}

.eyebrow {
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.19;
  letter-spacing: 0.011em;
  font-weight: 600;
  color: var(--blue);
  margin-bottom: 6px;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 22px;
}

.container-wide {
  max-width: var(--wide);
  margin: 0 auto;
  padding: 0 12px;
}

/* ---------- Nav ---------- */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--nav-h);
  z-index: var(--z-nav);
  background: rgba(251, 251, 253, 0.8);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.nav-inner {
  max-width: var(--container);
  height: 100%;
  margin: 0 auto;
  padding: 0 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav-logo {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}

.nav-links {
  display: flex;
  gap: 32px;
  list-style: none;
}

.nav-links a {
  font-size: 12px;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--text);
  opacity: 0.88;
  transition: opacity 0.2s ease;
  cursor: pointer;
}

.nav-links a:hover { opacity: 1; }

/* ---------- Buttons & links ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 12px 23px;
  font-size: 17px;
  line-height: 1.17648;
  font-weight: 400;
  letter-spacing: -0.022em;
  border: 1px solid transparent;
  border-radius: 980px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.btn-primary {
  background: var(--blue);
  color: #fff;
}

/* background-color only: the shorthand would wipe the gradient set below */
.btn-primary:hover { background-color: var(--blue-hover); }

/* Apple-style inline "Learn more >" link */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.19;
  letter-spacing: 0.011em;
  color: var(--blue);
  cursor: pointer;
}

.link-arrow::after {
  content: '\203A';
  font-size: 1.18em;
  line-height: 0.9;
  transition: transform 0.2s ease;
}

.link-arrow:hover { text-decoration: underline; }

.link-arrow:hover::after { transform: translateX(2px); }

a:focus-visible, button:focus-visible {
  outline: 3px solid rgba(0, 113, 227, 0.6);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- Hero ---------- */

.hero {
  padding: calc(var(--nav-h) + 72px) 0 0;
  text-align: center;
  background: var(--bg);
}

.hero .display { margin-bottom: 8px; }

.hero .subhead {
  max-width: 34ch;
  margin: 14px auto 0;
}

.hero-actions {
  display: flex;
  justify-content: center;
  gap: 26px;
  margin-top: 26px;
  flex-wrap: wrap;
}

/* Headshot — Apple product-shot treatment */
.headshot {
  position: relative;
  width: min(420px, 76vw);
  aspect-ratio: 4 / 5;
  margin: 48px auto 0;
  border-radius: 28px;
  overflow: hidden;
  background: var(--bg-alt);
}

.headshot img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Section scaffolding ---------- */

.section { padding: 90px 0; }

.section-alt { background: var(--bg-alt); }

.section-head {
  text-align: center;
  margin-bottom: 44px;
}

.section-head .subhead { margin-top: 12px; }

/* ---------- Project tiles ---------- */

.tile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 12px;
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 52px 28px 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-alt);
  cursor: pointer;
  transition: transform 0.4s cubic-bezier(0.28, 0.11, 0.32, 1);
}

/* .tile.visible:hover outranks .reveal.visible, which pins transform */
.tile:hover,
.tile.visible:hover { transform: scale(1.008); }

.tile-feature {
  grid-column: 1 / -1;
  min-height: 620px;
  padding-top: 60px;
}

.tile-half { min-height: 560px; }

.tile-dark {
  background: var(--bg-dark);
  color: #f5f5f7;
}

.tile-dark .tile-sub { color: #a1a1a6; }

.tile-eyebrow {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 10px;
}

.tile-dark .tile-eyebrow { color: #86868b; }

.tile-title {
  font-size: clamp(28px, 3.6vw, 40px);
  line-height: 1.1;
  letter-spacing: -0.01em;
  font-weight: 600;
  margin-bottom: 10px;
}

.tile-feature .tile-title { font-size: clamp(32px, 4.4vw, 48px); }

.tile-sub {
  font-size: clamp(17px, 1.8vw, 19px);
  line-height: 1.42;
  letter-spacing: 0.01em;
  color: var(--text-secondary);
  max-width: 46ch;
  margin-bottom: 16px;
}

.tile .link-arrow { margin-bottom: 8px; }

/* ---------- About ---------- */

.about .container { max-width: 760px; }

.about p {
  font-size: clamp(19px, 2.2vw, 21px);
  line-height: 1.5;
  letter-spacing: 0.011em;
  color: var(--text-secondary);
  margin-bottom: 22px;
}

.about p strong { color: var(--text); font-weight: 600; }

.toolbox {
  margin-top: 44px;
  text-align: center;
}

.toolbox-label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 18px;
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.tag {
  font-size: 14px;
  letter-spacing: -0.01em;
  color: var(--text);
  padding: 7px 15px;
  border-radius: 980px;
  background: rgba(0, 0, 0, 0.05);
}

.section-alt .tag { background: rgba(255, 255, 255, 0.75); }

/* ---------- Footer ---------- */

.footer {
  background: var(--bg-alt);
  border-top: 1px solid var(--border);
  padding: 30px 0;
  font-size: 12px;
  line-height: 1.33;
  /* --text-tertiary is only 3.3:1 at 12px; step darker to clear 4.5:1 */
  color: var(--text-secondary);
  letter-spacing: -0.01em;
}

.footer .container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

.footer-links { display: flex; gap: 22px; }

.footer-links a { transition: color 0.2s ease; cursor: pointer; }

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

/* ============================================
   Project detail pages
   ============================================ */

.detail-hero {
  padding: calc(var(--nav-h) + 64px) 0 0;
  text-align: center;
}

.back-link {
  display: inline-block;
  font-size: 17px;
  color: var(--blue);
  margin-bottom: 28px;
  cursor: pointer;
}

.back-link::before { content: '\2039'; margin-right: 5px; font-size: 1.18em; }

.back-link:hover { text-decoration: underline; }

.detail-hero .display { margin-bottom: 4px; }

.detail-lede {
  font-size: clamp(19px, 2.4vw, 24px);
  line-height: 1.375;
  letter-spacing: 0.004em;
  color: var(--text-secondary);
  max-width: 44ch;
  margin: 16px auto 0;
}

.detail-section { padding: 80px 0 0; }

.detail-section:last-of-type { padding-bottom: 90px; }

.detail-section .container { max-width: 760px; }

.detail-section h2 {
  font-size: clamp(28px, 3.6vw, 40px);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin-bottom: 22px;
}

.detail-section h3 {
  font-size: clamp(21px, 2.2vw, 24px);
  line-height: 1.16;
  letter-spacing: 0.009em;
  margin: 34px 0 10px;
}

.detail-prose p {
  font-size: clamp(17px, 2vw, 19px);
  line-height: 1.52;
  letter-spacing: 0.011em;
  color: var(--text-secondary);
  margin-bottom: 18px;
}

.detail-prose strong { color: var(--text); font-weight: 600; }

.detail-prose ul {
  color: var(--text-secondary);
  padding-left: 22px;
  margin-bottom: 18px;
  font-size: clamp(17px, 2vw, 19px);
  line-height: 1.52;
}

.detail-prose li { margin-bottom: 12px; }

.detail-prose li::marker { color: var(--text-tertiary); }

.callout {
  background: var(--bg-alt);
  border-radius: var(--radius);
  padding: 26px 30px;
  margin: 30px 0;
  color: var(--text-secondary);
  font-size: 17px;
  line-height: 1.5;
}

.callout-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 8px;
}

/* next / previous project nav */
.project-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 22px 90px;
}

.project-nav a {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 30px 32px;
  background: var(--bg-alt);
  border-radius: var(--radius);
  transition: background-color 0.2s ease;
  cursor: pointer;
}

.project-nav a:hover { background: #ebebed; }

.pn-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.pn-title {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--blue);
}

.project-nav a.pn-next { text-align: right; }

.project-nav a.pn-spacer { visibility: hidden; pointer-events: none; }

/* ---------- Scroll reveal ---------- */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.8s cubic-bezier(0.28, 0.11, 0.32, 1),
              transform 0.8s cubic-bezier(0.28, 0.11, 0.32, 1);
}

.reveal.visible { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 833px) {
  .tile-grid { grid-template-columns: 1fr; }
  .tile-half { min-height: 500px; }
  .tile-feature { min-height: 560px; }
}

@media (max-width: 734px) {
  .section { padding: 64px 0; }
  .nav-links { gap: 20px; }
  .tile { padding: 44px 22px 0; }
  .project-nav { grid-template-columns: 1fr; }
  .project-nav a.pn-next { text-align: left; }
  .footer .container { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   COLOR — Apple system palette + Apple-Intelligence gradients
   Vivid accents, glows and auras layered over the neutral base.
   ============================================================ */

:root {
  /* Apple system colors (iOS/macOS vivid set) */
  --c-blue:   #0A84FF;
  --c-cyan:   #64D2FF;
  --c-teal:   #40C8E0;
  --c-indigo: #5E5CE6;
  --c-purple: #BF5AF2;
  --c-pink:   #FF375F;
  --c-red:    #FF453A;
  --c-orange: #FF9F0A;
  --c-yellow: #FFD60A;
  --c-green:  #30D158;
  --c-mint:   #66D4CF;

  /* darkened variants that stay readable on light backgrounds */
  --ink-blue:   #0062C4;
  --ink-purple: #9F3ED5;
  --ink-orange: #C2410C;
  --ink-green:  #17803D;

  /* the signature multi-stop sweep */
  /* every stop clears 3:1 on white — gradient text animates, so the pale
     end of a sweep WILL scroll into view and must stay readable */
  --grad-spectrum: linear-gradient(100deg,
      #FF2D55 0%, #A93FE0 26%, #5E5CE6 48%, #0071E3 70%, #0E7490 100%);
}

/* ---------- Gradient headline ---------- */

.gradient-text {
  background: var(--grad-spectrum);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: sweep 9s ease-in-out infinite alternate;
}

@keyframes sweep {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

@keyframes drift {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---------- Headshot: smaller, wrapped in a colour aura ---------- */

.headshot-wrap {
  position: relative;
  width: min(300px, 62vw);
  margin: 52px auto 0;
  isolation: isolate;
}

/* rainbow bloom behind the portrait */
.headshot-wrap::before {
  content: '';
  position: absolute;
  inset: -18%;
  z-index: -1;
  border-radius: 50%;
  /* warm only: red, orange, yellow, to match the autumn photo */
  background: conic-gradient(from 210deg,
      #FF3B30, #FF6A1A, #FF9F0A, #FFC300, #FFD60A, #FF9F0A, #FF6A1A, #FF3B30);
  filter: blur(38px);
  opacity: 0.5;
  animation: drift 22s linear infinite;
}

.headshot {
  width: 100%;
  margin: 0;
  border-radius: 24px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.16);
}

/* ---------- Project tiles: per-project accent + bloom ---------- */

.tile-scout { --accent: var(--c-blue);   --accent-2: var(--c-teal);   --accent-ink: var(--ink-blue); }
.tile-bike  { --accent: var(--c-purple); --accent-2: var(--c-pink);   --accent-ink: #D9A6FF; }
.tile-pacer { --accent: var(--c-orange); --accent-2: var(--c-yellow); --accent-ink: var(--ink-orange); }

/* colour bloom rising from the bottom of each tile */
.tile::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -28%;
  width: 130%;
  height: 78%;
  transform: translateX(-50%);
  background: radial-gradient(closest-side,
      var(--accent, var(--c-blue)), transparent 72%);
  opacity: 0.3;
  filter: blur(36px);
  pointer-events: none;
  z-index: 0;
  transition: opacity 0.45s ease;
}

.tile-dark::after { opacity: 0.42; }

.tile:hover::after { opacity: 0.5; }

/* thin gradient hairline across the top edge */
.tile::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent, var(--c-blue)), var(--accent-2, var(--c-teal)));
  z-index: 2;
}

/* keep tile content above the bloom */
.tile > * { position: relative; z-index: 1; }

.tile .tile-eyebrow { color: var(--accent-ink, var(--ink-blue)); }
.tile .link-arrow   { color: var(--accent-ink, var(--ink-blue)); }

.tile:hover {
  box-shadow: 0 24px 60px -20px var(--accent, var(--c-blue));
}

/* ---------- Buttons: gradient + colour glow ---------- */

.btn-primary {
  /* darkened so white 17px label clears 4.5:1 across the whole sweep */
  background: linear-gradient(120deg, #0071E3 0%, #5145D8 55%, #9F3ED5 100%);
  background-size: 180% 100%;
  transition: background-position 0.5s ease, box-shadow 0.3s ease, transform 0.2s ease;
}

.btn-primary:hover {
  background-position: 100% 50%;
  box-shadow: 0 10px 34px -6px rgba(94, 92, 230, 0.6);
}

/* ---------- Callout accents ---------- */

.callout {
  border-left: 3px solid var(--c-purple);
  background: linear-gradient(100deg, rgba(191, 90, 242, 0.07), rgba(10, 132, 255, 0.05));
}

.callout-label { color: var(--ink-purple); }

/* ---------- Detail hero eyebrow picks up the page accent ---------- */

.detail-hero .eyebrow { color: var(--page-accent, var(--ink-blue)); }

/* aurora wash behind the About section */
.about { position: relative; overflow: hidden; }

.about::before {
  content: '';
  position: absolute;
  top: -30%;
  left: 50%;
  width: 120%;
  height: 90%;
  transform: translateX(-50%);
  background:
    radial-gradient(38% 60% at 22% 40%, rgba(255, 55, 95, 0.16), transparent 70%),
    radial-gradient(38% 60% at 52% 30%, rgba(191, 90, 242, 0.16), transparent 70%),
    radial-gradient(38% 60% at 80% 45%, rgba(10, 132, 255, 0.16), transparent 70%);
  filter: blur(30px);
  pointer-events: none;
}

.about > * { position: relative; z-index: 1; }

/* colourful toolbox chips */
.tag-row .tag:nth-child(6n+1) { background: rgba(10, 132, 255, 0.13);  color: #0062c4; }
.tag-row .tag:nth-child(6n+2) { background: rgba(191, 90, 242, 0.14);  color: #7B27B5; }
.tag-row .tag:nth-child(6n+3) { background: rgba(255, 55, 95, 0.12);   color: #B3183C; }
.tag-row .tag:nth-child(6n+4) { background: rgba(255, 159, 10, 0.16);  color: #9A3D07; }
.tag-row .tag:nth-child(6n+5) { background: rgba(48, 209, 88, 0.15);   color: #146E35; }
.tag-row .tag:nth-child(6n+6) { background: rgba(64, 200, 224, 0.16);  color: #0B6076; }

@media (prefers-reduced-motion: reduce) {
  .gradient-text, .headshot-wrap::before { animation: none; }
}

@media (max-width: 734px) {
  .headshot-wrap { width: min(260px, 66vw); }
}

/* ============================================================
   COLOR on project pages ("sub tabs")
   Each project owns a hue family; the whole page carries it.
   ============================================================ */

:root {
  /* fallback so a page without an accent class never loses its headline */
  --page-grad: var(--grad-spectrum);
  --pa:  var(--c-blue);
  --pa2: var(--c-teal);
}

.page-scout {
  --page-accent: var(--ink-blue);
  --pa:  #0A84FF; --pa2: #40C8E0;
  --page-grad: linear-gradient(100deg, #5E5CE6 0%, #0A84FF 55%, #0062C4 100%);
  --page-tint: linear-gradient(160deg, #EAF4FF 0%, #F0FBFF 100%);
}

.page-bike {
  --page-accent: var(--ink-purple);
  --pa:  #BF5AF2; --pa2: #FF375F;
  --page-grad: linear-gradient(100deg, #5E5CE6 0%, #A93FE0 52%, #E0245E 100%);
  --page-tint: linear-gradient(160deg, #F7EDFF 0%, #FFF0F4 100%);
}

.page-pacer {
  --page-accent: var(--ink-orange);
  --pa:  #FF9F0A; --pa2: #FFD60A;
  --page-grad: linear-gradient(100deg, #FF2D55 0%, #E85D04 55%, #C2410C 100%);
  --page-tint: linear-gradient(160deg, #FFF3E0 0%, #FFFBE6 100%);
}

/* ---------- Hero headline picks up the project gradient ---------- */

.detail-hero .display {
  background-image: var(--page-grad);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: sweep 9s ease-in-out infinite alternate;
}

.back-link { color: var(--page-accent); }

/* ---------- Prose accents ---------- */

.detail-prose li::marker { color: var(--page-accent); }

.detail-section h3 { color: var(--page-accent); }

/* callout follows the page hue rather than always purple */
.callout { border-left-color: var(--pa); }
.callout-label { color: var(--page-accent); }

/* ---------- Next / previous cards ---------- */

.project-nav a {
  position: relative;
  overflow: hidden;
  background: var(--page-tint, var(--bg-alt));
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.project-nav a::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--pa), var(--pa2));
}

.project-nav a:hover {
  background: var(--page-tint, var(--bg-alt));
  box-shadow: 0 16px 40px -16px var(--pa);
  transform: translateY(-2px);
}

.pn-title { color: var(--page-accent); }

/* ---------- Aurora wash behind the closing section ---------- */

.detail-section:last-of-type { position: relative; }

.detail-section:last-of-type::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 100%;
  max-width: 1100px;
  height: 70%;
  transform: translateX(-50%);
  background: radial-gradient(50% 60% at 30% 60%, var(--pa), transparent 70%),
              radial-gradient(50% 60% at 72% 50%, var(--pa2), transparent 70%);
  opacity: 0.13;
  filter: blur(50px);
  pointer-events: none;
}

.detail-section:last-of-type > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .detail-hero .display { animation: none; }
}

/* ============================================================
   Journey in Robotics — timeline + video clips
   ============================================================ */

.page-journey {
  --page-accent: #146E35;
  --pa:  #30D158; --pa2: #66D4CF;
  --page-grad: linear-gradient(100deg, #059669 0%, #0E7490 55%, #0071E3 100%);
  --page-tint: linear-gradient(160deg, #E9FBF1 0%, #E9FAFF 100%);
}

.tile-journey { --accent: #30D158; --accent-2: #66D4CF; --accent-ink: #146E35; }

/* ---------- Timeline rail ---------- */

.timeline {
  position: relative;
  max-width: 820px;
  margin: 0 auto;
  padding: 0 22px 0 24px;
}

.timeline::before {
  content: '';
  position: absolute;
  left: 32px;
  top: 12px;
  bottom: 90px;
  width: 2px;
  background: linear-gradient(180deg, var(--pa), var(--pa2) 60%, transparent);
}

.era {
  position: relative;
  padding-left: 44px;
  margin-bottom: 66px;
}

.era::before {
  content: '';
  position: absolute;
  left: 0;
  top: 4px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--pa);
  box-shadow: 0 0 0 5px #fff, 0 0 20px var(--pa);
}

.era-year {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--page-accent);
  margin-bottom: 6px;
}

.era h2 {
  font-size: clamp(24px, 3vw, 32px);
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin-bottom: 12px;
}

.era p {
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: 0.011em;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

/* ---------- Video clip grid ---------- */

.clip {
  background: var(--page-tint, var(--bg-alt));
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, 0.07);
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.clip:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 40px -18px var(--pa);
}

.clip video {
  width: 100%;
  /* height:auto is required — the width/height HTML attributes set a
     presentational height that would otherwise beat aspect-ratio */
  height: auto;
  aspect-ratio: 16 / 9;
  display: block;
  background: #000;
  object-fit: cover;
}

.clip-body { padding: 13px 16px 15px; }

.clip-title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 3px;
}

.clip-note {
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-secondary);
}

/* ---------- Awards row ---------- */

.awards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 10px;
}

.award {
  position: relative;
  overflow: hidden;
  background: var(--bg-alt);
  border-radius: var(--radius);
  padding: 26px 24px;
}

.award::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--aw, var(--c-green));
}

.award:nth-child(1) { --aw: var(--c-yellow); }
.award:nth-child(2) { --aw: var(--c-blue); }
.award:nth-child(3) { --aw: var(--c-purple); }

.award-year {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

.award-name {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

@media (max-width: 734px) {
  .timeline { padding-left: 18px; }
  .timeline::before { left: 26px; }
  .era { padding-left: 38px; }
}

/* ---------- Mixed-orientation clip row ----------
   A landscape clip beside a portrait one: give each its own natural
   aspect instead of cropping the portrait into a 16:9 box. */

.clip-portrait video {
  /* auto = the video's own shape once known; 474:850 until then */
  aspect-ratio: auto 474 / 850;
  object-fit: contain;
  background: #000;
}

.clip figcaption { padding: 13px 16px 15px; }

.clip-wide video { aspect-ratio: 16 / 9; }

/* Hard ceiling on video size. Even if a container rule is missed, no clip
   can grow into a full-bleed band. */
.clip video { max-width: 100%; max-height: 70vh; }
.clip-portrait video { max-height: 62vh; }

/* ============================================================
   Paper card and photo credits
   ============================================================ */

/* the published-paper card */
.paper-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding: 20px 22px;
  background: rgba(255, 255, 255, 0.74);
  border-radius: 14px;
}

.paper-title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.paper-meta {
  font-size: 14px;
  color: var(--text-secondary);
  margin-top: 5px;
}

/* source line under a photo that is not ours */
.cite {
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 10px;
}

.cite a { color: var(--page-accent); text-decoration: underline; }

/* Captions on tinted frames: --text-secondary (#6e6e73) reaches 4.66:1 on
   white but only 4.47:1 on the page tints. One step darker clears it. */
.clip-note,
.cite { color: #5f5f64; }

/* clip titles were inheriting the caption grey; they are headings */
.clip-title { color: var(--text); }

/* ============================================================
   Journey in Robotics: mixed photo + video rows
   Source photos are small (200-500px), so they display at native
   size or smaller and are never stretched. Items in a row share one
   height so each season reads as a contact sheet.
   ============================================================ */

.media-row {
  --h-photo: 220px;
  --h-video: 300px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px;
  margin-top: 22px;
}

/* the Worlds pair in the page hero */
.media-feature {
  --h-photo: 300px;
  --h-video: 300px;
  max-width: 980px;
  margin: 36px auto 0;
  padding: 0 22px;
  justify-content: center;
}

.m {
  flex: none;
  max-width: 100%;
  background: var(--page-tint, var(--bg-alt));
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 14px;
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.m:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 36px -18px var(--pa);
}

.m-photo img {
  display: block;
  height: var(--h-photo);
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* width:auto beats the presentational width attribute, so aspect-ratio
   sizes the box from the shared height */
.m-portrait video,
.m-land video {
  display: block;
  height: var(--h-video);
  width: auto;
  max-width: 100%;
  background: #000;
  object-fit: contain;
}

.m-portrait video { aspect-ratio: 9 / 16; }
.m-land video     { aspect-ratio: 16 / 9; }

/* caption wraps to the media width instead of widening the card */
.m figcaption {
  width: 0;
  min-width: 100%;
  padding: 10px 12px 12px;
}

.m .clip-title { font-size: 14px; margin-bottom: 2px; }
.m .clip-note  { font-size: 13px; line-height: 1.35; }

@media (max-width: 734px) {
  .media-row { --h-photo: 180px; --h-video: 260px; }
  .m-land,
  .m-land video { width: 100%; }
  .m-land video { height: auto; }
}

/* ============================================================
   Wide layout: the homepage fills large screens instead of
   sitting in a phone-width column. Body text keeps a readable
   measure; photos, tiles and the hero go wide.
   ============================================================ */

:root {
  --page-wide: 2000px;
  --page-pad: clamp(16px, 3vw, 64px);
}

/* tiles, nav and footer all line up with the wide page edges */
.container-wide,
.nav-inner,
.footer .container {
  max-width: var(--page-wide);
  padding: 0 var(--page-pad);
}

.tile-grid { gap: clamp(12px, 1vw, 20px); }

/* ---------- Hero: stacked on phones, split on desktop ---------- */

.hero-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 22px;
}

/* the headshot's colour bloom spills past the right edge on wide screens */
.hero { overflow-x: clip; }

@media (min-width: 900px) {
  .hero {
    text-align: left;
    padding-top: calc(var(--nav-h) + 40px);
  }

  .hero-inner {
    max-width: var(--page-wide);
    min-height: min(76vh, 900px);
    padding: 0 var(--page-pad);
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    align-items: center;
    gap: clamp(32px, 5vw, 110px);
  }

  .hero .display { font-size: clamp(64px, 7.4vw, 144px); }

  .hero .subhead {
    max-width: 30ch;
    margin: 20px 0 0;
    font-size: clamp(21px, 1.6vw, 30px);
  }

  .hero-actions { justify-content: flex-start; margin-top: 32px; }

  .headshot-wrap {
    width: clamp(300px, 30vw, 580px);
    margin: 0 auto;
  }
}

/* ---------- Tiles: real photos, edge to edge ---------- */

/* single-column phones keep their shorter tiles from the responsive block */
@media (min-width: 834px) {
  .tile-feature { min-height: clamp(400px, 21vw, 450px); }
  .tile-half    { min-height: clamp(420px, 22vw, 470px); }
}

.tile-title { font-size: clamp(28px, 2.6vw, 48px); }
.tile-feature .tile-title { font-size: clamp(32px, 3.2vw, 60px); }
.tile-sub { font-size: clamp(17px, 1.15vw, 21px); }

/* photo fills the rest of the tile and runs past its side padding.
   the mask fades the photo itself in from the top, so the tile colour
   and its glow show through instead of meeting a flat overlay at a seam */
.tile-photo {
  flex: 1 0 280px;
  align-self: stretch;
  margin: 28px -28px 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(transparent, #000 28%);
  mask-image: linear-gradient(transparent, #000 28%);
}

.tile-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.28, 0.11, 0.32, 1);
}

.tile:hover .tile-photo img { transform: scale(1.03); }

.tile-credit {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 1;
  font-size: 12px;
  color: #fff;
  background: rgba(0, 0, 0, 0.6);
  padding: 3px 9px;
  border-radius: 6px;
}

/* the copy block used by split tiles; centred like any tile on phones */
.tile-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
}

@media (min-width: 900px) {
  .tile-split {
    flex-direction: row;
    align-items: stretch;
    padding: 0;
    text-align: left;
  }

  .tile-split .tile-copy {
    flex: 0 0 47%;
    justify-content: center;
    align-items: flex-start;
    padding: clamp(32px, 2.4vw, 52px);
  }

  /* side by side, the photo fades in from the copy side instead */
  .tile-split .tile-photo {
    flex: 1 1 auto;
    margin: 0;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 22%);
    mask-image: linear-gradient(90deg, transparent, #000 22%);
  }
}

/* Journey tile: one real robot from each season, left to right */
.tile-strip {
  width: 100%;
  max-width: 1000px;   /* the source photos are small; past this they'd blur */
  margin-top: auto;
  padding: 36px 0 44px;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(10px, 1.1vw, 20px);
}

/* each frame grows by its aspect ratio (--ar), so the row fills the tile
   edge to edge and every photo lands at the same height */
.tile-strip figure {
  flex: var(--ar, 1) 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.tile-strip img {
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 12px;
  box-shadow: 0 16px 32px -16px rgba(0, 0, 0, 0.4);
}

.tile-strip figcaption {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--accent-ink);
  white-space: nowrap;
}

@media (max-width: 734px) {
  .tile-photo { margin: 24px -22px 0; flex-basis: 240px; }
  .tile-strip { flex-wrap: wrap; padding: 28px 0 32px; }
  .tile-strip figure { flex: 0 1 auto; }
  .tile-strip img { width: auto; height: 110px; }
}

/* ---------- Homepage: contact card and paper link in the hero ---------- */

.news-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
  padding: 6px 14px 6px 6px;
  border-radius: 980px;
  background: var(--bg-alt);
  font-size: 15px;
  color: var(--text);
  transition: background-color 0.2s ease;
}

.news-pill:hover { background: #ebebed; }

.news-pill::after { content: '\203A'; color: var(--ink-blue); font-size: 1.2em; line-height: 0.9; }

.news-tag {
  padding: 3px 9px;
  border-radius: 980px;
  background: var(--ink-blue);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.hero-contact {
  scroll-margin-top: calc(var(--nav-h) + 24px);
  max-width: 520px;
  margin: 34px auto 0;
  padding: 22px 24px;
  border-radius: var(--radius);
  background: var(--bg-alt);
}

.hero-contact-title {
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.hero-contact-note {
  font-size: 15px;
  line-height: 1.45;
  color: var(--text-secondary);
  margin: 6px 0 16px;
}

.btn-outline {
  color: var(--ink-blue);
  border-color: currentColor;
  background: #fff;
}

.btn-outline:hover { background: rgba(0, 98, 196, 0.06); }

@media (min-width: 900px) {
  .hero-contact {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 6px 28px;
    max-width: 760px;
    margin: 40px 0 0;
    padding: 26px 30px;
  }

  .hero-contact-note { margin: 0; }

  .hero-contact .btn { grid-column: 2; grid-row: 1 / 3; }

  /* the work heading lines up with the tile edges instead of floating centred */
  .section-head.container-wide {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 40px;
    text-align: left;
  }

  .section-head.container-wide .subhead { max-width: 38ch; margin: 0; text-align: right; }
}

/* ---------- Homepage: About spans the page ---------- */

.about-side { text-align: center; }

.about-side .toolbox { margin-top: 28px; }

@media (min-width: 1100px) {
  .about-grid {
    display: grid;
    grid-template-columns: minmax(260px, 0.7fr) minmax(0, 2fr);
    gap: clamp(48px, 6vw, 120px);
    align-items: start;
  }

  .about-side,
  .about-side .toolbox { text-align: left; }

  .about-side .tag-row { justify-content: flex-start; }

  .about-text { columns: 2; column-gap: clamp(40px, 4vw, 80px); }

  .about-text p { break-inside: avoid; }
}

@media (max-width: 1099px) {
  .about-text { max-width: 760px; margin: 36px auto 0; }
}

/* ---------- Inline text links ----------
   the global `a` reset hides links in running text; prose links get the
   page accent and an underline so colour is never the only signal */
.detail-prose a,
.detail-lede a,
.about-text a,
.paper-meta a,
.frame figcaption a,
.m figcaption a {
  color: var(--page-accent, var(--ink-blue));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

/* ============================================================
   Project pages: wide story layout
   Words and media sit side by side across the screen instead of
   stacking down a narrow centre column. Below 1000px it all stacks.
   ============================================================ */

:root { --story-max: 1600px; }

.detail-hero { text-align: left; }

.hero-grid,
.story,
.band {
  width: min(var(--story-max), 100% - 2 * var(--page-pad));
  margin-left: auto;
  margin-right: auto;
}

.hero-grid { display: grid; gap: 44px; }

.hero-grid .detail-lede { margin: 16px 0 0; }

/* the one-line result, under the lede */
.hero-text h2 {
  font-size: clamp(21px, 1.8vw, 28px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: 26px;
}

.hero-text .paper-card { margin-top: 28px; background: var(--page-tint, var(--bg-alt)); }

/* the project's main photo or video, with the page's colour glow behind it */
.hero-media { position: relative; display: flex; justify-content: center; }

.hero-media::before {
  content: '';
  position: absolute;
  inset: 8% 6%;
  background: radial-gradient(closest-side, var(--pa), transparent 72%);
  filter: blur(50px);
  opacity: 0.32;
  pointer-events: none;
}

.hero-media > * { position: relative; }

.hero-media .media-feature { margin: 0; padding: 0; }

/* tinted frame around a photo */
.frame {
  background: var(--page-tint, var(--bg-alt));
  border-radius: var(--radius);
  padding: clamp(14px, 1.6vw, 24px);
}

.frame img {
  width: 100%;
  height: auto;
  border-radius: 10px;
}

/* tall photos stay on screen: capped height, centred in the frame */
.frame.portrait img {
  width: auto;
  max-width: 100%;
  max-height: min(72vh, 780px);
  margin: 0 auto;
}

.frame figcaption {
  font-size: 14px;
  line-height: 1.45;
  color: #5f5f64;
  max-width: 62ch;
  margin: 12px auto 0;
  text-align: center;
}

.frame figcaption .cite { display: block; margin-top: 4px; }

/* a crisp occupancy grid instead of a blurred upscale */
.frame.pixel img { image-rendering: pixelated; }

.story { display: grid; gap: 36px; }

.story-text,
.hero-text { max-width: 680px; }

.story-media { display: grid; gap: 18px; }

.story-media > * { min-width: 0; }

/* portrait clips keep their own width and a sane height */
.story-media .clip-portrait,
.hero-media .clip-portrait {
  justify-self: center;
  width: fit-content;
  max-width: 100%;
}

.story-media .clip-portrait video,
.hero-media .clip-portrait video {
  width: auto;
  height: min(64vh, 680px);
  max-height: none;
}

.story-media .clip-portrait figcaption,
.hero-media .clip-portrait figcaption { width: 0; min-width: 100%; }

/* full-width media between story rows */
.band { margin-top: clamp(72px, 7vw, 120px); }

/* a band that opens its own section already has the section's top padding */
.detail-section > .band:first-child { margin-top: 0; }

.band .clip-wide { max-width: 1180px; margin: 0 auto; }

.band .paper-card { margin: 0; padding: 26px 30px; background: var(--page-tint, var(--bg-alt)); }

.band .cite { margin-top: 12px; }

@media (min-width: 1000px) {
  /* column widths are under "grid shapes" in the big-screen block */
  .hero-grid,
  .story {
    align-items: center;
    gap: clamp(48px, 6vw, 120px);
  }

  .story { padding-top: clamp(80px, 7vw, 140px); }

  /* media on the left for every other row */
  .story.flip > .story-text { order: 2; }

  /* two columns of words: tops line up */
  .story.text-pair { align-items: start; }

  .story.flip > .story-text,
  .story.text-pair > .story-text + .story-text { justify-self: end; width: 100%; }
}

/* ---------- Journey: each season's words beside its photos and clips ---------- */

@media (min-width: 1000px) {
  .timeline { max-width: var(--story-max); padding: 0 var(--page-pad) 0 24px; }

  .era {
    display: grid;
    grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
    gap: 0 clamp(40px, 5vw, 96px);
    align-items: start;
  }

  .era .media-row { margin-top: 0; }

  .detail-section .awards-wrap { max-width: var(--story-max); padding: 0 var(--page-pad); }
}

/* the prev / next cards span the same width as the story above them */
.project-nav {
  max-width: none;
  width: min(var(--story-max), 100% - 2 * var(--page-pad));
  padding: 0 0 90px;
}

/* ---------- Journey: one wide Worlds video above the season's media ---------- */

.era-media { min-width: 0; }

.m-feature { width: 100%; margin-top: 22px; }

.m-feature iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  background: #000;
}

.era-media .media-row { margin-top: 14px; }

@media (min-width: 1000px) {
  .m-feature { margin-top: 0; }
}

/* ---------- Lab Scout's "What's next": its own wide box under the video ---------- */

.next-box .callout {
  margin: 0;
  padding: clamp(28px, 3vw, 72px) clamp(26px, 3.4vw, 80px);
  border-left-width: 5px;
  font-size: clamp(19px, 1.7vw, 42px);
  line-height: 1.45;
  color: var(--text);
}

.next-box .callout-label {
  font-size: clamp(14px, 1.15vw, 28px);
  margin-bottom: 0.7em;
}

/* ---------- Bike: two build photos side by side, one height ----------
   each frame grows by its photo's aspect ratio (--ar) */

.photo-pair {
  display: flex;
  gap: clamp(14px, 1.4vw, 28px);
  margin-top: clamp(24px, 2.4vw, 48px);
}

.photo-pair > .frame { flex: var(--ar, 1) 1 0; min-width: 0; }

}

@media (max-width: 734px) {
  .photo-pair { flex-direction: column; }
  .photo-pair > .frame { flex: none; }
}

/* ---------- Bike: the electronics text runs across the page ---------- */

@media (min-width: 1000px) {
  .story-text.prose-wide { max-width: none; }

  .prose-wide p { columns: 2; column-gap: clamp(40px, 4vw, 96px); }
}

/* ---------- Bike: thank-you bubble at the very end ---------- */

.band.thanks {
  margin-top: clamp(18px, 1.8vw, 36px);
  padding: clamp(28px, 3vw, 64px) clamp(24px, 3vw, 64px);
  border-radius: var(--radius);
  background: var(--page-tint, var(--bg-alt));
  text-align: center;
}

.thanks p {
  font-size: clamp(21px, 1.9vw, 44px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

/* ---------- About: Wally on loop under the toolbox ---------- */

.about-video {
  width: min(100%, 420px);
  margin: clamp(28px, 2.6vw, 48px) auto 0;
}

.about-video video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--bg-alt);
  cursor: pointer;
}

@media (min-width: 1100px) {
  .about-video { margin-left: 0; }
}

/* ============================================================
   Big screens: type and media grow with the window
   Past 1000px these sizes scale with the viewport width, so large
   monitors get proportionally bigger text. Keep this block last: it
   wins over the equal-specificity rules above by source order.
   ============================================================ */

@media (min-width: 1000px) {
  :root {
    --story-max: var(--page-wide);
    --nav-h: clamp(52px, 3.8vw, 92px);
    /* portrait photos and clips: tall, but always fully on screen */
    --tall-h: min(74vh, 46vw, 980px);
  }

  /* ---- shared ---- */
  .nav-logo        { font-size: clamp(17px, 1.4vw, 34px); }
  .nav-links       { gap: clamp(28px, 2.4vw, 60px); }
  .nav-links a     { font-size: clamp(15px, 1.15vw, 28px); }
  .footer          { font-size: clamp(14px, 0.95vw, 22px); }
  .btn             { font-size: clamp(17px, 1.05vw, 25px); padding: 0.7em 1.4em; }
  .link-arrow      { font-size: clamp(21px, 1.3vw, 30px); }
  .eyebrow         { font-size: clamp(21px, 1.3vw, 30px); }
  .headline        { font-size: clamp(48px, 3.4vw, 84px); }
  .subhead         { font-size: clamp(24px, 1.55vw, 38px); }

  /* ---- homepage ---- */
  .hero .display   { font-size: clamp(64px, 7.4vw, 180px); }
  .hero .subhead   { font-size: clamp(21px, 1.6vw, 40px); }
  .news-pill       { font-size: clamp(15px, 1.15vw, 27px); }
  .news-tag        { font-size: clamp(12px, 0.9vw, 21px); }
  .hero-contact-title { font-size: clamp(21px, 1.5vw, 36px); }
  .hero-contact-note  { font-size: clamp(16px, 1.2vw, 28px); }
  .hero-contact    { max-width: 40em; font-size: clamp(15px, 1.05vw, 25px); }
  .tile-eyebrow    { font-size: clamp(13px, 0.7vw, 17px); }
  .tile-title      { font-size: clamp(28px, 2.05vw, 50px); }
  .tile-feature .tile-title { font-size: clamp(34px, 2.7vw, 64px); }
  .tile-sub        { font-size: clamp(17px, 1vw, 24px); }
  .tile .link-arrow { font-size: clamp(17px, 1vw, 24px); }
  /* shorter photo band so the half tiles can shrink with the text */
  .tile-photo      { flex-basis: 200px; }
  .tile-strip figcaption { font-size: clamp(14px, 1.05vw, 25px); }
  .about p         { font-size: clamp(19px, 1.1vw, 26px); }
  .toolbox-label,
  .tag             { font-size: clamp(14px, 1.1vw, 26px); }

  /* ---- project pages ---- */
  .detail-hero .display { font-size: clamp(64px, 6.2vw, 160px); }
  .back-link       { font-size: clamp(17px, 1.25vw, 30px); }
  .hero-grid .detail-lede { font-size: clamp(24px, 1.75vw, 44px); }
  .hero-text h2    { font-size: clamp(24px, 2vw, 50px); }
  .detail-section h2 { font-size: clamp(40px, 3vw, 76px); }
  .detail-section h3 { font-size: clamp(24px, 1.8vw, 44px); }
  .detail-prose p,
  .detail-prose li { font-size: clamp(19px, 1.3vw, 32px); }
  .callout         { font-size: clamp(17px, 1.25vw, 30px); }
  .callout-label   { font-size: clamp(13px, 0.95vw, 22px); }
  .paper-title     { font-size: clamp(17px, 1.4vw, 34px); }
  .paper-meta      { font-size: clamp(15px, 1.1vw, 26px); }
  .frame figcaption,
  .cite            { font-size: clamp(15px, 1.1vw, 26px); }
  .clip-title      { font-size: clamp(16px, 1.3vw, 31px); }
  .clip-note       { font-size: clamp(15px, 1.1vw, 26px); }
  .m .clip-title   { font-size: clamp(15px, 1.1vw, 26px); }
  .m .clip-note    { font-size: clamp(14px, 1vw, 24px); }
  .pn-label        { font-size: clamp(13px, 0.95vw, 22px); }
  .pn-title        { font-size: clamp(19px, 1.5vw, 36px); }
  .era-year,
  .award-year      { font-size: clamp(14px, 1vw, 24px); }
  .era h2          { font-size: clamp(32px, 2.4vw, 60px); }
  .era p           { font-size: clamp(17px, 1.2vw, 29px); }
  .award-name      { font-size: clamp(19px, 1.35vw, 32px); }

  /* text columns are measured in em, so line length stays ~70
     characters however big the type gets */
  .story,
  .hero-grid,
  .story-text,
  .hero-text { font-size: clamp(19px, 1.3vw, 32px); }

  .story-text,
  .hero-text { max-width: 38em; }

  /* ---- grid shapes ----
     default: words | landscape media, media a little wider.
     .tall: the portrait photo or clip sizes its own column, and the
     pair sits centred as one unit with no hole between them. */
  .hero-grid,
  .story           { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .story.flip      { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
  .hero-grid.tall,
  .story.tall      { grid-template-columns: minmax(0, 38em) auto; justify-content: center; }
  .story.flip.tall { grid-template-columns: auto minmax(0, 38em); }
  .story.text-pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

  .story-media .clip-portrait video,
  .hero-media .clip-portrait video { height: var(--tall-h); }

  .story-media .frame.portrait img,
  .hero-media .frame.portrait img {
    height: calc(var(--tall-h) - 3em);
    max-height: none;
  }

  /* a portrait frame hugs its photo; the caption wraps to the photo width */
  .frame.portrait { width: fit-content; justify-self: center; }
  .frame.portrait figcaption { width: 0; min-width: 100%; }

  /* wide clips and strips stay inside one screen height */
  .band .clip-wide { max-width: min(100%, 150vh); }
  .band > .frame   { max-width: min(100%, 230vh); margin: 0 auto; }

  /* the Journey hero holds one clip now, so it grows into the column */
  .media-feature   { --h-video: clamp(260px, 21vw, 620px); }
  .era .media-row  { --h-photo: clamp(260px, 14.5vw, 400px); --h-video: clamp(340px, 19vw, 520px); }
}
