/* ==========================================================================
   Sarah — Portfolio
   Editorial-Swiss: uppercase grotesk + italic serif, colour-blocked chapters
   ========================================================================== */

:root {
  --paper: #F4F1EC;
  --ink: #0E0F10;
  --mauve: #7B6671;
  --wine: #4A1426;

  /* Page field — eased between chapters by main.js */
  --bg: var(--paper);
  --fg: var(--ink);

  --sans: "Geist", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Instrument Serif", "Times New Roman", Times, serif;

  --gutter: clamp(16px, 4vw, 64px);
  --rule: color-mix(in srgb, currentColor 24%, transparent);

  --ease: cubic-bezier(.65, 0, .15, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 17px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  transition: background-color 1.1s var(--ease), color 1.1s var(--ease);
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
::selection { background: var(--fg); color: var(--bg); }
html.case-open { overflow: hidden; }

.skip {
  position: absolute; left: var(--gutter); top: -80px; z-index: 70;
  padding: 10px 16px; background: var(--ink); color: var(--paper);
}
.skip:focus { top: 16px; }

/* Paper grain */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 60; pointer-events: none; opacity: .06;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Type ---------- */
.display {
  font-family: var(--sans);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: -.04em;
  line-height: .88;
}
.display em,
.serif-i {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -.005em;
  text-transform: none;
}
.display em { font-size: .6em; margin: 0 .06em; }

.label {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .14em;
  line-height: 1.5;
  text-transform: uppercase;
}

.cta { display: inline-block; }
.cta::before { content: "\2022\00a0"; font-style: normal; }
.cta span,
.u {
  background: linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0 1px;
  transition: background-size .7s var(--ease-out);
}
a:hover .cta span, .cta:hover span, a.u:hover, a:hover .u { background-size: 100% 1px; }

/* ---------- Image slots (placeholder until an image loads) ---------- */
.slot {
  position: relative;
  aspect-ratio: var(--r, 4 / 3);
  overflow: hidden;
  background: color-mix(in srgb, currentColor 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
}
.slot::after {
  content: attr(data-file);
  position: absolute; left: 10px; bottom: 8px; right: 10px;
  font: 500 10px/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  opacity: .7; text-align: left; text-shadow: none;
}
.slot img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  scale: var(--zoom, 1);
  translate: 0 var(--shift, 0);
  transition: transform 1.4s var(--ease-out);
}

/* ---------- Nav ---------- */
/* Floating pill (ported from Navbar1) */
.nav {
  position: fixed; inset: 0 0 auto; z-index: 40;
  display: flex; justify-content: center;
  padding: 20px 16px;
  pointer-events: none;
}
.nav__pill {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  width: 100%; max-width: 768px;
  padding: 10px 10px 10px 14px;
  background: #fff; color: var(--ink);
  border-radius: 999px;
  box-shadow: 0 10px 30px -8px rgba(14, 15, 16, .22), 0 2px 6px rgba(14, 15, 16, .06);
  pointer-events: auto;
}
.nav__logo {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--ink); color: var(--paper);
  font-size: 22px; line-height: 1;
  transition: transform .3s var(--ease-out);
}
.nav__logo span { transform: translate(-1px, 1px); }
.nav__logo:hover { transform: rotate(10deg); }

.nav__links { display: flex; align-items: center; gap: 32px; }
.nav__links a {
  display: inline-block;
  font-size: 14px; font-weight: 500; color: var(--ink);
  transition: transform .3s var(--ease-out), color .3s;
}
.nav__links a:hover { transform: scale(1.05); color: #5a5a5a; }

.nav__cta {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 9px 20px; border-radius: 999px;
  background: var(--ink); color: #fff;
  font-size: 14px; font-weight: 500;
  transition: transform .3s var(--ease-out), background-color .3s;
}
.nav__cta:hover { transform: scale(1.05); background: #2a2b2d; }

.nav__toggle { display: none; padding: 6px; color: var(--ink); transition: transform .15s; }
.nav__toggle:active { transform: scale(.9); }

/* Entrance: logo scales in, links drop in, CTA slides from the right */
html.js .nav__logo { transform: scale(.8); }
html.js .nav__links a { opacity: 0; transform: translateY(-10px); transition: opacity .3s ease, transform .3s ease; }
html.js .nav__pill .nav__cta { opacity: 0; transform: translateX(20px); transition: opacity .3s ease .2s, transform .3s ease .2s; }
html.is-loaded .nav__logo { transform: none; }
html.is-loaded .nav__links a,
html.is-loaded .nav__pill .nav__cta { opacity: 1; transform: none; }
html.is-loaded .nav__links a:hover,
html.is-loaded .nav__pill .nav__cta:hover { transform: scale(1.05); transition-delay: 0s; }

/* Mobile overlay menu */
.menu {
  position: fixed; inset: 0; z-index: 2;
  padding: 96px 24px 24px;
  background: #fff; color: var(--ink);
  pointer-events: auto;
  opacity: 0; transform: translateX(100%);
  transition: transform .5s cubic-bezier(.34, 1.3, .64, 1), opacity .3s ease;
}
.menu[hidden] { display: none; }
.menu.is-open { opacity: 1; transform: none; }
.menu__close { position: absolute; top: 24px; right: 24px; padding: 8px; opacity: 0; transition: opacity .3s ease .2s, transform .15s; }
.menu.is-open .menu__close { opacity: 1; }
.menu__close:active { transform: scale(.9); }
.menu__links { display: flex; flex-direction: column; gap: 24px; }
.menu__links a {
  font-size: 16px; font-weight: 500;
  opacity: 0; transform: translateX(20px);
  transition: opacity .4s ease, transform .4s ease;
  transition-delay: calc(var(--i) * .1s + .1s);
}
.menu__links .menu__cta { width: 100%; margin-top: 24px; padding: 13px 20px; font-size: 16px; transform: translateY(20px); transition-delay: .5s; }
.menu.is-open .menu__links a { opacity: 1; transform: none; }
html.menu-open { overflow: hidden; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  height: 100svh; min-height: 620px;
  padding: clamp(96px, 18svh, 200px) var(--gutter) 0;
  text-align: center;
}
.hero__kicker { margin-bottom: clamp(18px, 3svh, 36px); }
.hero__title { font-size: clamp(44px, min(9.4vw, 14.5svh), 172px); }
.line { display: block; overflow: hidden; padding: .02em 0 .1em; margin-bottom: -.1em; }
.line > span { display: inline-block; }
.hero__aka { margin-left: 1.4em; vertical-align: .35em; letter-spacing: .14em; }

.hero__side { position: absolute; top: 46%; text-align: left; }
.hero__side--l { left: var(--gutter); }
.hero__side--r { right: var(--gutter); }
.hero__side .dot {
  display: inline-block; width: 7px; height: 7px; margin-right: 8px; border-radius: 50%;
  background: currentColor; vertical-align: .1em;
}

.hero__img { position: absolute; bottom: 0; z-index: 2; display: block; }
.hero__img--1 { left: 0; width: clamp(150px, 24vw, 480px); transform: translateY(42%); }
.hero__img--2 { right: 0; width: clamp(180px, 29vw, 580px); transform: translateY(calc(34% + 100px)); }
/* Colour-change cards (ported from ColorChangeCards): greyscale until hover on desktop,
   image zooms, arrow turns, title letters roll, text brightens */
.hero__img .slot img { transition: transform .5s ease, filter .5s ease; }
.hero__img:hover .slot img,
.hero__img:focus-visible .slot img { transform: scale(1.1); }
@media (hover: hover) and (min-width: 768px) {
  .hero__img .slot img { filter: saturate(0); }
  .hero__img:hover .slot img,
  .hero__img:focus-visible .slot img { filter: saturate(1); }
}

.hcard {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 16px;
  text-align: left; color: rgba(244, 241, 236, .8);
  background: linear-gradient(to top, rgba(14, 15, 16, .55), rgba(14, 15, 16, 0) 60%);
  pointer-events: none;
  transition: color .5s ease;
}
html.js .hcard.reveal { transition: color .5s ease, opacity 1.2s var(--ease-out) var(--d, 0s), transform 1.2s var(--ease-out) var(--d, 0s); }
.hero__img:hover .hcard,
.hero__img:focus-visible .hcard { color: #fff; }

.hcard__arrow { align-self: flex-end; width: 28px; height: 28px; transition: transform .5s ease; }
.hero__img:hover .hcard__arrow,
.hero__img:focus-visible .hcard__arrow { transform: rotate(-45deg); }

.hcard__title {
  margin-bottom: 8px;
  font: 500 clamp(20px, 2vw, 30px)/1 var(--sans);
  letter-spacing: -.02em; text-transform: uppercase;
}
.roll { display: inline-block; height: 1em; overflow: hidden; vertical-align: top; }
.roll-word { display: inline-block; white-space: nowrap; }
.roll__inner { display: flex; flex-direction: column; transition: transform .5s ease; transition-delay: calc(var(--i) * .035s); }
.roll__inner > span { display: block; height: 1em; min-width: .25em; }
.hero__img:hover .roll__inner,
.hero__img:focus-visible .roll__inner { transform: translateY(-50%); }

.hero-after {
  position: relative;
  padding: clamp(80px, 16svh, 180px) var(--gutter) clamp(80px, 14svh, 160px);
  text-align: center;
}
.hero__intro { max-width: 22ch; margin: 0 auto; font-size: clamp(26px, 2.7vw, 42px); line-height: 1.12; }
.hero__explore { margin-top: 68px; font-size: clamp(19px, 1.5vw, 23px); }

/* ---------- WORK intro: scattered letters ---------- */
.work-intro { min-height: 65svh; display: flex; align-items: center; padding: 0 var(--gutter); margin-bottom: -60px; }
.letters {
  position: relative; width: 100%;
  height: clamp(170px, 24vw, 390px);
  font: 400 clamp(72px, 10.5vw, 190px)/1 var(--sans);
  color: color-mix(in srgb, currentColor 22%, transparent);
}
.letters span { position: absolute; }
.letters--scrub span { will-change: transform, opacity; }

/* ---------- WORK: project list + live card preview ----------
   Mobile-first: a stacked list with each project's main mock inline.
   With a mouse on a wide screen, the list sits left and a 3-card stage previews the
   active project on the right (see "Work section" in main.js). */
.work { padding: clamp(110px, 16svh, 180px) var(--gutter) clamp(80px, 12svh, 140px); }
.opener__top { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; margin-bottom: clamp(32px, 6svh, 64px); }
.opener__range { font-size: clamp(22px, 2vw, 30px); line-height: 1; }

.index { border-top: 1px solid var(--rule); }
.index a {
  display: grid; grid-template-columns: 2.5rem 1fr; column-gap: 16px; row-gap: 4px; align-items: baseline;
  padding: 20px 0; border-bottom: 1px solid var(--rule);
  transition: padding-left .7s var(--ease-out), opacity .4s ease;
}
.index__num { font-size: 24px; line-height: 1; }
.index__name { font-size: clamp(22px, 2.4vw, 36px); font-weight: 500; letter-spacing: -.025em; line-height: 1.05; text-transform: uppercase; }
.index__name em { font-size: .7em; }
.index__disc, .index__metric { grid-column: 2; }
.index__metric { opacity: .75; }
.index__year { display: none; }
.index__mock { grid-column: 1 / -1; display: block; margin-top: 16px; }
.work-stage { display: none; }

@media (min-width: 1024px) and (hover: hover) and (pointer: fine) {
  .work { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; }
  .work__grid { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 24px; align-items: center; }
  .index { grid-column: 1 / 6; }
  .index a { grid-template-columns: 4.5rem 1fr auto; }
  .index__metric, .index__mock, .index__year { display: none; }
  .index__disc { grid-column: auto; text-align: right; }
  .index a:hover, .index a.is-active { padding-left: 14px; }
  .index.has-active a:not(.is-active) { opacity: .4; }

  .work-stage {
    display: block; position: relative; grid-column: 6 / 13; justify-self: end;
    left: -50px;
    width: min(100%, calc(64svh / .85)); aspect-ratio: 1 / .85;
  }
}

/* One set of 3 cards per project; only the active set is visible */
.card-set { position: absolute; inset: 0; display: block; visibility: hidden; pointer-events: none; transition: visibility 0s linear .6s; }
.card-set.is-active { visibility: visible; pointer-events: auto; transition: none; }

.wcard {
  position: absolute;
  opacity: 0; translate: 0 14px;
  transition: opacity .45s ease, translate .6s var(--ease-out);
}
.card-set.is-active .wcard { opacity: 1; translate: 0 0; transition-delay: calc(var(--k) * 60ms + 60ms); }
.wcard.slot { box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent), 0 30px 60px -24px rgba(0, 0, 0, .55); }
.card-set:hover .wcard--main img { transform: scale(1.03); }

.wcard--main   { left: 18%; top: 0;   width: 82%; }
.wcard--second { left: 0;   top: 44%; width: 32%; rotate: -1.5deg; }
.wcard--info {
  left: 40%; top: 60%; width: 46%; rotate: 1deg;
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 20px 22px;
  background: var(--paper); color: var(--ink);
  box-shadow: 0 24px 50px -24px rgba(0, 0, 0, .5);
}
.wcard__desc { font-size: clamp(18px, 1.4vw, 22px); line-height: 1.2; }
.wcard__award { opacity: .7; }

/* Faster colour ease while hovering through the list */
html.field-fast body { transition-duration: .6s; }

/* ---------- Focus ---------- */
/* Quieter hierarchy: one headline, one short paragraph, a ruled supporting list */
.focus {
  min-height: 100svh;
  display: grid; grid-template-columns: 1.2fr 1fr; gap: clamp(48px, 8vw, 160px); align-items: start;
  padding: clamp(140px, 22svh, 240px) var(--gutter) clamp(120px, 18svh, 200px);
}
.focus h2 { margin-top: 28px; font-size: clamp(36px, 4.4vw, 80px); line-height: .95; }
.focus__statement {
  max-width: 34ch; margin-top: clamp(40px, 7svh, 72px);
  font-size: clamp(17px, 1.25vw, 20px); line-height: 1.55; opacity: .9;
}
.focus__more { margin-top: 28px; font-size: clamp(19px, 1.5vw, 23px); }
/* "What I help with": a small editorial index — number, name, note on hover */
.focus__list { margin-top: 28px; border-top: 1px solid var(--rule); }
.focus__list li {
  position: relative;
  display: grid; grid-template-columns: 2.75rem 1fr auto; align-items: baseline; column-gap: 16px;
  padding: 14px 0; border-bottom: 1px solid var(--rule);
}
html.js .focus__list li.reveal { transition: opacity 1.2s var(--ease-out) var(--d, 0s), transform 1.2s var(--ease-out) var(--d, 0s); }
html.js .focus__list li.reveal.is-in { transition: opacity .4s ease; }
/* Underline that draws across from the left on hover */
.focus__list li::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .7s var(--ease-out);
}
.help__num { font-style: normal; opacity: .6; }
.help__name { font-size: clamp(22px, 1.8vw, 28px); line-height: 1.25; transition: translate .6s var(--ease-out); }
.help__note { font-style: normal; text-align: right; opacity: 0; translate: -8px 0; transition: opacity .4s ease, translate .6s var(--ease-out); }
.help__plus { display: inline-block; transition: rotate .6s var(--ease-out); }

@media (hover: hover) {
  .focus__list:hover li:not(:hover) { opacity: .45; }
  .focus__list li:hover::after { transform: scaleX(1); }
  .focus__list li:hover .help__name { translate: 10px 0; }
  .focus__list li:hover .help__note { opacity: .8; translate: 0 0; }
  .help--delight:hover .help__plus { rotate: 90deg; }
}
/* Touch: notes always visible, tucked under the name */
@media not (hover: hover) {
  .focus__list li { grid-template-columns: 2.25rem 1fr; row-gap: 4px; }
  .help__note { grid-column: 2; text-align: left; opacity: .7; translate: 0 0; }
}

/* ---------- Explorations ---------- */
.play { position: relative; min-height: 110svh; padding: clamp(110px, 16svh, 180px) var(--gutter); }
.play__head { position: relative; z-index: 2; }
.play__letters {
  position: absolute; inset: 30% 16% 30%;
  font: 400 clamp(90px, 12vw, 220px)/1 var(--sans);
}
.play__letters span { position: absolute; }
/* Each exploration card gets its own light tint, from the same muted family as the
   insight cards. Once a thumbnail is dropped in, the image covers the tint. */
.thumb {
  position: absolute; width: clamp(84px, 7.4vw, 140px);
  animation: float 9s ease-in-out infinite; animation-delay: var(--f, 0s);
  background: var(--tint, #EFE4CE);
  color: var(--ink);
  transition: scale .45s var(--ease-out), opacity .35s ease;
}
.play__thumbs .thumb:nth-child(1) { --tint: #EFE4CE; }
.play__thumbs .thumb:nth-child(2) { --tint: #D9E7E2; }
.play__thumbs .thumb:nth-child(3) { --tint: #E7DFF1; }
.play__thumbs .thumb:nth-child(4) { --tint: #F2DED8; }
.play__thumbs .thumb:nth-child(5) { --tint: #E2E7D7; }
.play__thumbs .thumb:nth-child(6) { --tint: #DCE4EF; }
.play__thumbs .thumb:nth-child(7) { --tint: #F1E8D4; }
.play__thumbs .thumb:nth-child(8) { --tint: #E8DCD4; }
@keyframes float { 50% { transform: translateY(-10px); } }
.play__text { position: absolute; right: 12%; bottom: 8%; max-width: 17ch; font-size: clamp(28px, 3vw, 50px); line-height: 1.08; }
.play__text .cta { margin-top: 20px; font-size: clamp(19px, 1.5vw, 23px); }

/* ---------- Hover preview card (ported from ProjectShowcase) ----------
   Hovering a thumbnail reveals a larger frame of it that trails the cursor. */
/* No positioning here — the thumbs resolve their left/top against .play itself */
.play__thumbs .thumb { cursor: pointer; }
.play__thumbs.is-on .thumb { opacity: .45; }
.play__thumbs.is-on .thumb.is-on { opacity: 1; scale: 1.08; }

/* Thumbnails rest in greyscale; the hovered one returns to colour. The preview
   card is never desaturated. */
.play__thumbs .thumb img { filter: grayscale(1); transition: filter .45s var(--ease-out); }
.play__thumbs .thumb.is-on img { filter: none; }

.play__preview {
  position: fixed; left: 0; top: 0; z-index: 46;
  width: clamp(240px, 22vw, 320px); pointer-events: none;
  opacity: 0; scale: .85;
  transition: opacity .3s var(--ease-out), scale .3s var(--ease-out);
}
.play__thumbs.is-on ~ .play__preview,
.play__preview.is-on { opacity: 1; scale: 1; }
.play__preview .slot {
  position: absolute; inset: 0; width: 100%;
  background: var(--tint, #EFE4CE); color: var(--ink);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, .55);
  opacity: 0; transition: opacity .45s var(--ease-out);
}
.play__preview .slot:first-child { position: relative; }
.play__preview .slot.is-on { opacity: 1; }

@media (hover: none), (max-width: 760px) {
  /* Nothing to trail without a cursor; the thumbnails stand on their own, in colour */
  .play__preview { display: none; }
  .play__thumbs.is-on .thumb { opacity: 1; }
  .play__thumbs.is-on .thumb.is-on { scale: 1; }
  .play__thumbs .thumb img { filter: none; }
}

/* ---------- About ----------
   Minimal: headline + a real quote on the left; bio, one meta line and 3 roles on the right */
.about {
  display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 24px; row-gap: 48px; align-items: start;
  padding: clamp(120px, 18svh, 200px) var(--gutter);
}
.about__main  { grid-column: 1 / 7; }
.about__aside { grid-column: 8 / 13; padding-top: 46px; }
.about h2 { margin-top: 28px; font-size: clamp(40px, 5vw, 92px); line-height: .92; }

.about__quote { max-width: 30ch; margin: clamp(40px, 7svh, 72px) 0 0; padding-top: 20px; border-top: 1px solid var(--rule); }
.about__quote blockquote { margin: 0; font-size: clamp(22px, 1.9vw, 30px); line-height: 1.22; }
.about__quote figcaption { margin-top: 14px; opacity: .7; }

.about__lede { max-width: 26ch; margin-top: clamp(24px, 4svh, 40px); font-size: clamp(24px, 2.2vw, 34px); line-height: 1.16; }
.about__bio { max-width: 52ch; margin-top: clamp(28px, 4svh, 44px); font-size: 18px; line-height: 1.6; }
.about__bio p + p { margin-top: 1.1em; }
.about__meta { margin-top: 24px; opacity: .75; }

/* At a glance: 2 × 2 facts */
.facts { display: grid; grid-template-columns: 1fr 1fr; margin: 0; border-top: 1px solid var(--rule); }
.facts > div { display: flex; flex-direction: column-reverse; gap: 8px; padding: 20px 16px 22px 0; border-bottom: 1px solid var(--rule); }
.facts > div:nth-child(even) { padding-left: 20px; border-left: 1px solid var(--rule); }
.facts dt { opacity: .75; }
.facts dd { margin: 0; font-size: clamp(34px, 3.4vw, 56px); line-height: .9; }

/* Experience and recognition rows */
.about h3 { margin: clamp(40px, 6svh, 64px) 0 16px; }
.timeline { border-top: 1px solid var(--rule); }
.timeline li {
  display: grid; grid-template-columns: 7.5rem 1fr auto; gap: 6px 16px; align-items: baseline;
  padding: 16px 0; border-bottom: 1px solid var(--rule);
}
.timeline strong { display: block; font-weight: 500; }
.timeline .serif-i { display: block; margin-top: 2px; font-size: 18px; opacity: .8; }
.timeline > li > .label:last-child { opacity: .7; text-align: right; }
/* Awards carry no date column, so they run full width */
.timeline--awards li { grid-template-columns: 1fr; }
/* Roles get a short description under the organisation */
.role__note { display: block; margin-top: 8px; max-width: 44ch; font-size: 15px; line-height: 1.5; opacity: .72; }
.timeline--roles li { padding: 20px 0 22px; }
/* Each aside block needs air from the one above it */
.about__aside > h3 { margin-top: clamp(36px, 5svh, 56px); opacity: .7; }
.about__aside > h3:first-child { margin-top: 0; }
.about__aside > h3 + .facts,
.about__aside > h3 + .timeline { margin-top: 14px; }
/* "End-to-end" is a word, not a number — it needs a smaller size than 5+ or M.Des */
.facts dd { font-size: clamp(34px, 3.4vw, 56px); }
.facts > div:nth-child(4) dd { font-size: clamp(20px, 1.9vw, 30px); line-height: 1.05; }
.facts > div:nth-child(3) dd { font-size: clamp(26px, 2.6vw, 42px); }
.tools { font-size: clamp(19px, 1.6vw, 24px); line-height: 1.4; }
.roles { margin-top: clamp(36px, 6svh, 56px); border-top: 1px solid var(--rule); }
.roles li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 16px 0; border-bottom: 1px solid var(--rule);
}
.roles strong { font-weight: 500; }
.roles .label { opacity: .75; text-align: right; }

/* ---------- Kind words: auto-advancing testimonials (ported from design-testimonial) ---------- */
.kind { padding: clamp(110px, 17svh, 200px) var(--gutter) clamp(90px, 14svh, 160px); }
.kind__top { margin-bottom: clamp(40px, 7svh, 72px); }
.kind h2 { margin-top: 28px; font-size: clamp(40px, 5vw, 92px); line-height: .92; }

/* Attribution: name, then the role in tracked caps */
.kind__name { display: block; font-size: 18px; font-weight: 500; }
.kind__role { display: block; margin-top: 6px; opacity: .8; }

.tmo { position: relative; display: flex; gap: clamp(24px, 4vw, 64px); }

/* Oversized index numeral, drifting with the pointer */
.tmo__num {
  position: absolute; z-index: 0; left: 6%; top: 46%;
  font: 500 min(22vw, 300px)/1 var(--sans); letter-spacing: -.05em;
  color: color-mix(in srgb, currentColor 7%, transparent);
  translate: var(--nx, 0) calc(-50% + var(--ny, 0px));
  pointer-events: none; user-select: none;
  transition: translate .6s var(--ease-out);
}

/* Left rail: vertical label + progress */
.tmo__rail { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 24px; padding-right: clamp(20px, 3vw, 48px); border-right: 1px solid var(--rule); }
.tmo__vert { writing-mode: vertical-rl; }
.tmo__progress { position: relative; flex: 1; min-height: 120px; width: 1px; background: var(--rule); }
.tmo__progress span { position: absolute; inset: 0 0 auto; height: var(--p, 20%); background: currentColor; transition: height .5s var(--ease-out); }

/* Slides stacked in one cell, so the height never jumps */
.tmo__stage { position: relative; z-index: 1; display: grid; flex: 1; }
.tmo__slide {
  grid-area: 1 / 1; margin: 0;
  opacity: 0; visibility: hidden;
  transition: opacity .45s ease, visibility 0s linear .45s;
}
.tmo__slide.is-active { opacity: 1; visibility: visible; transition: opacity .45s ease; }

.tmo__badge { display: inline-flex; align-items: center; gap: 9px; padding: 7px 14px; border: 1px solid var(--rule); border-radius: 999px; }
.tmo__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.tmo__slide blockquote {
  /* quote and attribution sit to the right; the badge stays left */
  margin: clamp(24px, 4svh, 40px) 0 clamp(28px, 5svh, 48px) auto;
  max-width: 40ch;
  font-size: clamp(24px, 2.6vw, 42px); line-height: 1.18;
}
/* Words rise and settle, staggered (main.js splits them) */
.tmo__word { display: inline-block; }
.tmo__slide.is-active .tmo__word {
  animation: tmo-word .5s cubic-bezier(.22, 1, .36, 1) backwards;
  animation-delay: calc(var(--i) * .045s);
}
@keyframes tmo-word { from { opacity: 0; translate: 0 18px; } to { opacity: 1; translate: 0 0; } }

.tmo__slide figcaption { display: flex; align-items: center; gap: 16px; max-width: 40ch; margin-left: auto; padding-right: 132px; }
/* Designation leads, name sits under it */
.tmo__slide figcaption > span:last-child { display: flex; flex-direction: column-reverse; }
.tmo__slide .kind__role { margin: 0; font-size: clamp(14px, 1.1vw, 17px); letter-spacing: .1em; opacity: 1; }
.tmo__slide .kind__name { margin-top: 8px; font-size: 15px; font-weight: 400; opacity: .7; }
.tmo__rule { width: 32px; height: 1px; background: currentColor; }
.tmo__slide.is-active .tmo__rule { animation: tmo-rule .6s var(--ease-out) .25s backwards; }
@keyframes tmo-rule { from { scale: 0 1; } to { scale: 1 1; } }

.tmo__nav { position: absolute; z-index: 2; right: 0; bottom: 0; display: flex; gap: 12px; }
.tmo__btn {
  display: grid; place-items: center; width: 48px; height: 48px;
  border: 1px solid var(--rule); border-radius: 50%;
  transition: background-color .3s ease, color .3s ease, scale .2s ease;
}
.tmo__btn:hover { background: currentColor; }
.tmo__btn:hover svg { color: var(--bg); }
.tmo__btn:active { scale: .95; }

.kind__tail { display: flex; flex-wrap: wrap; gap: 16px clamp(28px, 5vw, 64px); margin-top: clamp(32px, 5svh, 48px); font-size: clamp(19px, 1.5vw, 23px); }
.kind__tail .cta:first-child { opacity: .7; }

@media (max-width: 760px) {
  .tmo__rail { display: none; }
  .tmo__num { font-size: 42vw; }
  .tmo__slide { padding-bottom: 64px; }
  .tmo__nav { bottom: 0; right: auto; left: 0; }
  .tmo__slide figcaption { padding-right: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tmo__num { transition: none; }
}

/* ---------- Contact ---------- */
/* Curtain reveal (from CinematicFooter): the footer sits beneath the page and the last
   sections slide up off it. Sticky rather than fixed, so a tall footer on a short screen
   simply scrolls normally instead of being clipped. */
main > section:not(.contact) {
  position: relative; z-index: 1;
  background: var(--bg);
  transition: background-color 1.1s var(--ease);
}
/* Its own colours rather than the shared page field: being 100svh and pinned to the
   bottom, it would otherwise sit permanently across the field observer's centre line
   and hold the whole page on the footer's ink. */
.contact {
  position: sticky; bottom: 0; z-index: 0;
  background: var(--ink); color: var(--paper);
  min-height: 100svh; overflow: hidden;
  display: flex; flex-direction: column; justify-content: space-between;
  /* Top padding clears the floating nav pill (~96px) with room to spare */
  padding: clamp(130px, 19svh, 220px) var(--gutter) 40px;
  text-align: center;
}
.contact > *:not(.contact__ghost) { position: relative; z-index: 1; }

/* Too short to hold the footer in one screen: drop the curtain and let it scroll, so
   nothing is ever clipped behind the nav */
@media (max-height: 700px) {
  .contact { position: static; min-height: 0; padding-top: 120px; }
}

/* Outlined wordmark filling the foot of the page */
.contact__ghost {
  position: absolute; left: 50%; bottom: -.13em; translate: -50% 0; z-index: 0;
  font-size: 20vw; line-height: .78; white-space: nowrap;
  /* currentColor would resolve to the transparent fill, so the stroke names the paper directly */
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--paper) 13%, transparent);
  pointer-events: none; user-select: none;
}
/* Sized by height as well as width: the footer is a fixed 100svh curtain, so type that
   only answers to vw overflows it on a wide, short window and the top gets clipped. */
.contact h2 { margin-top: 24px; font-size: clamp(48px, min(13vw, 20svh), 240px); }
.contact__mail {
  display: inline-block; max-width: 100%;
  margin-top: clamp(26px, 4svh, 56px);
  font-size: clamp(20px, min(3.4vw, 5svh), 56px); line-height: 1.15; word-break: break-word;
}

/* Details: one ruled row per channel */
.contact__details {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0;
  width: 100%; margin: clamp(40px, 7svh, 120px) 0 0;
  text-align: left;
  border-top: 1px solid var(--rule);
}
.contact__details > div { padding: 30px 28px 34px 0; border-bottom: 1px solid var(--rule); }
.contact__details > div + div { padding-left: 32px; border-left: 1px solid var(--rule); }
.contact__details dt { opacity: .6; }
.contact__details dd { margin: 14px 0 0; font-size: clamp(15px, 1.15vw, 18px); line-height: 1.45; word-break: break-word; }

.foot {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;
  margin-top: clamp(40px, 7svh, 110px); padding-top: 24px;
  border-top: 1px solid var(--rule); opacity: .8;
}
/* Circular back-to-top, magnetic like the rest of the interactive type */
.foot__top {
  display: grid; place-items: center; flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--rule);
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
.foot__top:hover { border-color: currentColor; background: color-mix(in srgb, currentColor 9%, transparent); }
.foot__top svg { width: 17px; height: 17px; transition: translate .4s var(--ease-out); }
.foot__top:hover svg { translate: 0 -3px; }

@media (max-width: 900px) {
  .contact__details { grid-template-columns: 1fr 1fr; }
  .contact__details > div:nth-child(odd) { padding-left: 0; border-left: 0; }
  .contact__details > div:nth-child(even) { padding-left: 24px; border-left: 1px solid var(--rule); }
}
@media (max-width: 560px) {
  .contact__details { grid-template-columns: 1fr; }
  .contact__details > div, .contact__details > div + div { padding: 20px 0 22px; border-left: 0; }
  .foot { justify-content: flex-start; }
}

/* ---------- Magnetic cursor (ported from MagneticCursor) ---------- */
.cursor {
  position: fixed; left: 0; top: 0; z-index: 9999; pointer-events: none;
  display: none; place-items: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: #fff;
  mix-blend-mode: exclusion;
  -webkit-backdrop-filter: contrast(1.5);
  backdrop-filter: contrast(1.5);
  opacity: 0;
  will-change: transform, width, height, border-radius;
}
html.has-cursor .cursor { display: grid; }
.cursor__label {
  font: italic 400 24px/1 var(--serif); color: #000; white-space: nowrap;
  opacity: 0; transform: scale(.6);
  transition: opacity .3s ease, transform .45s var(--ease-out);
}
.cursor.is-view .cursor__label { opacity: 1; transform: none; transition-delay: .08s; }

/* Magnetic pull uses the independent `translate` property, so it never fights
   the CSS transforms already used for reveals and hover effects */
:where([data-magnetic]) { display: inline-block; }

/* ---------- Case study panel ---------- */
.case {
  position: fixed; inset: 0; z-index: 50;
  overflow-y: auto; overscroll-behavior: contain;
  --bg: var(--case-bg, var(--ink));
  /* --tint is eased by main.js as you scroll, so the field drifts between tones */
  background: color-mix(in srgb, var(--bg), var(--paper) calc(var(--tint, 0) * 1%));
  color: var(--paper);
  visibility: hidden; transform: translateY(100%);
  transition: transform .9s var(--ease), visibility 0s linear .9s;
}
/* Hairline column grid behind the content */
.case::before {
  content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image: linear-gradient(90deg, color-mix(in srgb, currentColor 6%, transparent) 0 1px, transparent 1px);
  background-size: calc(100% / 12) 100%;
  opacity: .8;
}
.case__bar, .case__body { position: relative; z-index: 1; }
.case.is-open { visibility: visible; transform: none; transition: transform .9s var(--ease); }
.case:focus { outline: none; }
.case__bar {
  position: sticky; top: 0; z-index: 2;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 18px var(--gutter);
  background: var(--case-bg, var(--ink));
  border-bottom: 1px solid var(--rule);
}
.case__close { font: italic 400 24px/1 var(--serif); }

.cs { padding: 0 var(--gutter); }
.case__body { container-type: inline-size; }

/* ---------- Title card ---------- */
/* One screen, one job: image zone left, a single type cluster right. Nothing else is
   large, so nothing competes with the title. */
.cs-hero {
  position: relative;
  display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(24px, 4vw, 56px);
  align-items: center;
  min-height: min(72svh, 680px);
  margin: 0 calc(-1 * var(--gutter));
  padding: clamp(40px, 7svh, 88px) var(--gutter);
}
/* The tinted zone, bleeding off the left edge behind the image */
.cs-hero::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 44%;
  background: color-mix(in srgb, #000 20%, transparent);
}
.cs-hero > * { position: relative; }

.cs-hero__fig { grid-column: 1 / 7; position: relative; margin: 0; overflow: hidden; }
.cs-hero__fig:focus { outline: none; }

/* ---------- Project details card (ported from CardHoverReveal) ----------
   Default state is the honest one: the card is simply part of the page, visible to
   everyone including touch and no-JS. The overlay/reveal behaviour is layered on only
   where hover actually exists. */
.cs-card {
  background: color-mix(in srgb, #000 16%, transparent);
  color: inherit;
}
.cs-card__head {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 11px 20px;
  font-size: 10px; opacity: .85;
  border-top: 1px solid color-mix(in srgb, currentColor 30%, transparent);
  border-bottom: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  background: linear-gradient(color-mix(in srgb, currentColor 7%, transparent), transparent);
}
.cs-card__list li strong { font-weight: 400; }
/* Small plus, rotating to a minus when the card is open */
/* Only meaningful where the card actually opens and closes */
.cs-card__cue { display: none; position: relative; width: 11px; height: 11px; flex: none; }
.cs-card__cue::before,
.cs-card__cue::after {
  content: ""; position: absolute; inset: 50% 0 auto; height: 1px; background: currentColor;
}
.cs-card__cue::after { rotate: 90deg; transition: rotate .45s var(--ease-out); }

/* Four muted accents, one per group, so the card can be scanned by colour as well as
   position. Desaturated on purpose — they have to sit quietly on six different fields. */
.cs-card__body {
  --a-time: #D9A441;
  --a-team: #5E9E93;
  --a-tool: #9B8AC4;
  --a-resp: #E4E0D8;
  display: grid; gap: 13px; padding: 14px 20px 16px;
}
.cs-card__body .label {
  display: flex; align-items: center; gap: 7px;
  margin-bottom: 6px; font-size: 10px; opacity: .75;
}
.cs-card__body .label::before {
  content: ""; width: 6px; height: 6px; flex: none; border-radius: 1px;
  background: var(--a, currentColor);
}
.cs-card__pair > div:nth-child(1) { --a: var(--a-time); }
.cs-card__pair > div:nth-child(2) { --a: var(--a-team); }
.cs-card__grp:has(.cs-chips) { --a: var(--a-tool); }
.cs-card__grp:has(.cs-card__list) { --a: var(--a-resp); }

.cs-card p { font-size: 13px; line-height: 1.4; }
/* Timeline and Team share a row; everything else runs full width */
.cs-card__pair { display: grid; grid-template-columns: 1fr 1.7fr; gap: 12px 20px; }

/* Tools / methods as chips — the one rounded form on the page, echoing the nav pill */
.cs-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.cs-chips li {
  padding: 3px 10px 4px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--a, currentColor) 45%, transparent);
  background: color-mix(in srgb, var(--a, currentColor) 10%, transparent);
  font-size: 11px; line-height: 1.35; opacity: .95;
}

.cs-card__list { display: grid; gap: 4px; }
.cs-card__list li {
  display: grid; grid-template-columns: 1.9rem 1fr; align-items: baseline;
  font-size: 13px; line-height: 1.4;
  counter-increment: card;
}
.cs-card__list { counter-reset: card; }
.cs-card__list li::before {
  content: counter(card, decimal-leading-zero);
  font: italic 400 13px/1.4 var(--serif); opacity: .5;
}

/* Where there is room and a pointer, the card becomes an overlay that peeks from the
   bottom edge and slides up on hover or keyboard focus. The header stays visible so the
   detail is discoverable rather than hidden. */
@media (hover: hover) and (min-width: 1024px) {
  .cs-card {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
    background: color-mix(in srgb, #000 74%, transparent);
    -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
    color: var(--paper);
    translate: 0 calc(100% - var(--peek, 38px));
    transition: translate .55s var(--ease-out);
  }
  .cs-card__cue { display: block; }
  .cs-hero__fig:hover .cs-card,
  .cs-hero__fig:focus-visible .cs-card,
  .cs-hero__fig:focus-within .cs-card { translate: 0; }
  .cs-hero__fig:hover .cs-card__cue::after,
  .cs-hero__fig:focus-visible .cs-card__cue::after,
  .cs-hero__fig:focus-within .cs-card__cue::after { rotate: 0deg; }
  .cs-hero__fig .slot img { transition: scale .6s var(--ease-out); }
  .cs-hero__fig:hover .slot img,
  .cs-hero__fig:focus-visible .slot img { scale: 1.04; }
}
@media (prefers-reduced-motion: reduce) {
  .cs-card, .cs-card__cue::after, .cs-hero__fig .slot img { transition: none; }
}
.cs-hero__type { grid-column: 8 / -1; }

/* A hairline ties the two ends together, so they read as one header band rather than
   two labels stranded at opposite edges of a wide column */
.cs-hero__eyebrow {
  display: flex; justify-content: space-between; gap: 16px;
  margin-bottom: clamp(20px, 3svh, 32px); padding-bottom: 12px;
  opacity: .6;
  border-bottom: 1px solid var(--rule);
}
.cs-title { margin: 0 0 clamp(16px, 2.2svh, 26px); font-size: clamp(38px, 4.8vw, 80px); }
/* ~a third of the title, set tight beneath it — the title/subtitle pair carries the fold */
.cs-lede { max-width: 30ch; margin: 0; font-size: clamp(19px, 1.9vw, 28px); line-height: 1.2; }
/* The rule measures with the lede above it instead of stopping at an arbitrary width */
.cs-hero__role {
  max-width: 30ch;
  margin-top: clamp(28px, 4svh, 44px); padding-top: 18px;
  font-size: 16px; opacity: .85;
  border-top: 1px solid var(--rule);
}

/* Facts band: the first thing below the fold, with room of its own */

.cs-block {
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px;
  padding: clamp(64px, 12svh, 140px) 0;
  border-top: 1px solid var(--rule);
}
.cs-block:first-of-type { border-top: 0; }
.cs-block > h3 { grid-column: 1 / 4; }
.cs-text { grid-column: 5 / 12; }
.cs-text p { max-width: 62ch; font-size: 18px; }
.cs-text p + p { margin-top: 1em; }
.cs-text .cs-quote { max-width: 26ch; margin-bottom: 28px; font-size: clamp(26px, 2.6vw, 42px); line-height: 1.14; }
.cs-list { margin-top: 28px; border-top: 1px solid var(--rule); counter-reset: cs; }
.cs-list li { display: grid; grid-template-columns: 3rem 1fr; padding: 12px 0; border-bottom: 1px solid var(--rule); counter-increment: cs; }
.cs-list li::before { content: counter(cs, decimal-leading-zero); font: italic 400 20px/1.3 var(--serif); }
.cs-text .cs-flow { max-width: none; margin-top: 28px; padding: 16px 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); font-size: 12px; line-height: 2; }

/* ---------- Research case study blocks ---------- */
/* Full-width blocks (insights, insight → action) */
.cs-block--full > h3 { grid-column: 1 / -1; margin-bottom: 28px; }
.cs-block--full > :not(h3) { grid-column: 1 / -1; }

/* The research question */
.cs-text .cs-question { max-width: 24ch; margin-bottom: 28px; font-size: clamp(26px, 2.8vw, 44px); line-height: 1.14; }

/* Methods: cards on a deeper tone so the approach reads as its own block */
.cs-methods {
  grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px;
  margin-top: clamp(24px, 4svh, 48px);
}
.cs-methods > div {
  display: flex; flex-direction: column;
  padding: 28px 30px 30px;
  background: color-mix(in srgb, #000 18%, transparent);
}
.cs-methods .cs-bar { margin-top: auto; }
.cs-methods strong { display: block; font-size: clamp(19px, 1.5vw, 23px); font-weight: 500; }
.cs-methods p { max-width: 34ch; margin: 8px 0 12px; font-size: 16px; opacity: .85; }
.cs-methods .label { opacity: .7; }

/* Key insights: three cards side by side, readable without scrolling */
.cs-insights { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; }
/* Light cards, one tint each, lifting the insights off the dark case field. Text flips to
   ink; --rule is currentColor-based so the hairlines follow automatically. */
.cs-insights li {
  display: flex; flex-direction: column;
  padding: 30px 30px 32px;
  background: var(--card, color-mix(in srgb, #000 14%, transparent));
  color: var(--ink);
}
.cs-insights li:nth-child(1) { --card: #EFE4CE; }
.cs-insights li:nth-child(2) { --card: #D9E7E2; }
.cs-insights li:nth-child(3) { --card: #E7DFF1; }
.cs-insights__num { font-size: clamp(30px, 2.4vw, 40px); line-height: 1; opacity: .45; }
.cs-insights__title { margin-top: 14px; font-size: clamp(21px, 1.7vw, 27px); line-height: 1.08; }
.cs-insights li p { margin-top: 14px; font-size: 16px; line-height: 1.5; opacity: .9; }
.cs-insights blockquote {
  margin: auto 0 0; padding: 20px 0 0;
  border-top: 1px solid var(--rule);
  font-size: clamp(18px, 1.35vw, 21px); line-height: 1.25;
}
.cs-insights li .label { margin-top: 12px; opacity: .65; }
.cs-insights li > div { display: flex; flex-direction: column; flex: 1; }
.cs-insights blockquote::before { font-size: 3.4em; }

/* Insight → action pairs */
.cs-actions { border-top: 1px solid var(--rule); }
.cs-actions li { display: grid; grid-template-columns: 1fr 2.5rem 1fr; align-items: baseline; gap: 12px; padding: 20px 0; border-bottom: 1px solid var(--rule); }
.cs-actions li::before { content: "→"; grid-column: 2; grid-row: 1; justify-self: center; opacity: .6; }
.cs-actions__from { grid-column: 1; font-size: clamp(18px, 1.4vw, 21px); opacity: .8; }
.cs-actions__to { grid-column: 3; font-size: clamp(18px, 1.4vw, 21px); font-weight: 500; }

@media (max-width: 1024px) {
  .cs-insights, .cs-methods { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .cs-methods { grid-template-columns: 1fr; }
  .cs-methods > div:nth-child(even) { padding-left: 0; border-left: 0; }
  .cs-insights, .cs-methods { grid-template-columns: 1fr; }
  .cs-actions li { grid-template-columns: 1fr; gap: 6px; }
  .cs-actions li::before { grid-column: 1; grid-row: 2; justify-self: start; }
  .cs-actions__from, .cs-actions__to { grid-column: 1; }
  .cs-actions__to { grid-row: 3; }
}

.cs-metrics { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.cs-metrics li { padding: clamp(32px, 6svh, 64px) 24px clamp(32px, 6svh, 64px) 0; }
.cs-metrics li + li { padding-left: 24px; border-left: 1px solid var(--rule); }
.cs-metrics strong { display: block; margin-bottom: 14px; font-size: clamp(48px, 6vw, 108px); }
/* Word facts instead of numbers — for cases where a percentage would be invented */
.cs-metrics--words strong { margin-bottom: 12px; font-size: clamp(22px, 2.3vw, 38px); line-height: 1.05; }

.cs-media { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 2vw, 32px); margin-top: clamp(24px, 4svh, 48px); }
.cs-media--wide { grid-template-columns: 1fr; }
/* Figures with captions; quieter frames on the case panel colour */
.cs-fig { margin: 0; }
.cs-fig figcaption { margin-top: 12px; opacity: .7; }
.cs-cover.cs-fig figcaption { padding: 0 var(--gutter); }
.case .slot { box-shadow: none; background: color-mix(in srgb, currentColor 7%, transparent); }
.cs-note { margin-top: 16px; opacity: .65; }

.cs-next {
  display: block; margin: 0 var(--gutter);
  padding: clamp(80px, 16svh, 180px) 0; border-top: 1px solid var(--rule);
  text-align: center;
}
.cs-next__title { display: block; margin: 24px 0 28px; font-size: clamp(56px, 10vw, 184px); }
.cs-next .cta { font-size: clamp(20px, 1.7vw, 26px); }



/* ---------- Case title: blur reveal (ported from blur-reveal) ----------
   Each letter blurs in and rises into place, staggered letter by letter. */
@keyframes cs-blur-in {
  from { opacity: 0; filter: blur(12px); translate: 0 10px; }
  to { opacity: 1; filter: blur(0); translate: 0 0; }
}
.br-word { display: inline-block; white-space: nowrap; }
.br-char {
  /* Visible by default; the animation only plays the reveal */
  display: inline-block;
  animation: cs-blur-in .6s ease backwards;
  /* waits for the case panel to finish sliding up, so the reveal is actually seen */
  animation-delay: calc(var(--i) * .02s + .85s);
}

/* ---------- Case study pacing: acts, section forms, surfaces ---------- */
/* Act divider (inserted by main.js before the first block of each act) */
.cs-act {
  display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
  margin-top: clamp(100px, 16svh, 190px); padding-bottom: 18px;
  border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}
.cs-act__num { font: 500 clamp(40px, 5vw, 80px)/1 var(--sans); letter-spacing: -.04em; }
.cs-act__name { opacity: .8; }
.cs-act + .cs-block { padding-top: clamp(40px, 6svh, 72px); }

/* Form: the opening statement — large type, left aligned, spanning the page */
.cs-block--lead .cs-text { grid-column: 3 / 13; }
.cs-block--lead .cs-question { max-width: 26ch; margin-bottom: clamp(36px, 6svh, 56px); font-size: clamp(30px, 3.6vw, 58px); line-height: 1.06; }
.cs-block--lead .cs-list { max-width: 72ch; }

/* Small tags that break up a run of text */
.cs-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.cs-chips span { padding: 7px 14px; border: 1px solid var(--rule); opacity: .85; }

/* Form: compact (methods, participants) */
.cs-block--compact .cs-text p { font-size: 16px; }
.cs-block--compact { padding-top: clamp(40px, 6svh, 72px); }

/* Form: quiet, offset (reflection) */
.cs-block--quiet .cs-text { grid-column: 6 / 12; opacity: .85; }
.cs-block--quiet .cs-text p { font-size: 17px; }
.cs-block--quiet .cs-text p:first-child {
  font-family: var(--serif); font-style: italic; font-size: clamp(21px, 1.9vw, 28px);
  line-height: 1.22; opacity: 1;
}

/* Surface rhythm */
.cs-surface--deep {
  margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter));
  padding-left: var(--gutter); padding-right: var(--gutter);
  background: color-mix(in srgb, #000 12%, transparent);
}

/* Images that run edge to edge; captions stay in the gutter */
.cs-fig--bleed { margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter)); }
.cs-fig--bleed figcaption, .cs-cover.cs-fig figcaption { padding: 0 var(--gutter); }

/* Section labels track their section on wide screens */
@media (min-width: 1024px) {
  .cs-block > h3.label { position: sticky; top: 88px; align-self: start; }
}

@media (max-width: 1024px) {
  .cs-block--quiet .cs-text, .cs-block--lead .cs-text { grid-column: 1; }
  .cs-act { margin-top: clamp(72px, 12svh, 120px); }
  /* The tinted zone is a wide-screen device; on one column it would just darken the hero */
  .cs-hero {
    grid-template-columns: 1fr; min-height: 0; align-items: start;
    padding-bottom: clamp(28px, 4svh, 40px);
  }
  .cs-hero::before { display: none; }
  .cs-hero__fig, .cs-hero__type { grid-column: 1; }
  /* Name the project before showing the mockup */
  .cs-hero__type { order: -1; margin-top: 0; }
  .cs-hero__fig { margin-top: clamp(28px, 4svh, 40px); }
}

/* Photo covers graded towards the case colour so they sit in the page */
.slot--grade::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: var(--bg);
  mix-blend-mode: soft-light; opacity: var(--grade, .75);
}

/* ---------- Case study: code-drawn visuals ---------- */
/* Section icons sit beside the small label headings */
.cs-ico { width: 16px; height: 16px; margin-right: 9px; vertical-align: -3px; opacity: .65; }

/* Ghost numerals drifting behind each block (data-ghost set by main.js) */
.cs-block[data-ghost] { position: relative; }
.cs-block[data-ghost]::before {
  content: attr(data-ghost);
  position: absolute; z-index: -1; right: 0; top: -.28em;
  font: 500 clamp(140px, 19vw, 320px)/1 var(--sans); letter-spacing: -.05em;
  color: color-mix(in srgb, currentColor 5%, transparent);
  translate: 0 var(--ghost-y, 0px);
  pointer-events: none;
}

/* Two surfaces: insights sit on a lighter tint, metrics on a deeper one */
.cs-surface {
  margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter));
  padding-left: var(--gutter); padding-right: var(--gutter);
  background: color-mix(in srgb, currentColor 5%, transparent);
}
.cs-metrics { background: color-mix(in srgb, #000 10%, transparent); }

/* Journey diagram (built from the old text step strips by main.js) */
.cs-journey {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap;
  margin-top: 28px; padding: 0; list-style: none;
}
.cs-journey li {
  position: relative; flex: 1 1 0; min-width: 132px;
  padding: 30px 16px 4px 0;
  font: 500 11px/1.45 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  opacity: .85;
}
.cs-journey li::before { content: ""; position: absolute; top: 9px; left: 0; right: 0; height: 1px; background: var(--rule); }
.cs-journey li::after {
  content: ""; position: absolute; top: 5px; left: 0;
  width: 9px; height: 9px; border-radius: 50%;
  background: currentColor; opacity: .8;
}
.cs-journey li:last-child::before { right: 16px; }
.cs-journey__ico { display: block; width: 20px; height: 20px; margin-bottom: 10px; opacity: .8; }
.cs-journey__ico svg { width: 100%; height: 100%; display: block; }

/* Scroll-in: the rule draws left to right, then the dot lands, then the label rises */
html.js .cs-journey.reveal { opacity: 1; transform: none; }
html.js .cs-journey.reveal li {
  opacity: 0; transform: translateY(12px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
  transition-delay: calc(var(--i, 0) * .1s + .1s);
}
html.js .cs-journey.reveal li::before {
  transform: scaleX(0); transform-origin: left;
  transition: transform .6s var(--ease-out);
  transition-delay: calc(var(--i, 0) * .1s);
}
html.js .cs-journey.reveal li::after {
  scale: 0;
  transition: scale .45s var(--ease-out);
  transition-delay: calc(var(--i, 0) * .1s + .22s);
}
html.js .cs-journey.reveal.is-in li { opacity: .85; transform: none; }
html.js .cs-journey.reveal.is-in li::before { transform: scaleX(1); }
html.js .cs-journey.reveal.is-in li::after { scale: 1; }

/* Status tag pinned inside an image slot — "Coming soon", "In progress" and the like */
.cs-soon {
  position: absolute; top: 14px; right: 14px; z-index: 3;
  padding: 5px 11px 6px; border-radius: 999px;
  font-size: 10px;
  color: var(--paper);
  background: color-mix(in srgb, #000 62%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid color-mix(in srgb, #F4F1EC 26%, transparent);
}

/* Credential tag — an award or recognition worth carrying on the fold */
.cs-award {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 16px; padding: 6px 13px 7px; border-radius: 999px;
  font-size: 10px; opacity: .9;
  border: 1px solid color-mix(in srgb, #D9A441 55%, transparent);
  background: color-mix(in srgb, #D9A441 12%, transparent);
}
.cs-award svg { width: 13px; height: 13px; flex: none; color: #D9A441; }

/* ---------- Method hub ----------
   Four methods arranged around a centre, the way a research approach is usually drawn
   on a whiteboard: one study, four complementary lenses. Panels flank the ring so each
   quadrant's colour ties to its description. */
.cs-hub {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr clamp(230px, 24vw, 320px) 1fr;
  gap: clamp(16px, 2vw, 32px) clamp(18px, 2.4vw, 40px);
  align-items: center;
  margin-top: clamp(28px, 5svh, 56px);
  --m1: #D9A441;  /* observation */
  --m2: #5E9E93;  /* staff */
  --m3: #9B8AC4;  /* customers */
  --m4: #C98A76;  /* synthesis */
}
.cs-hub__ring {
  position: relative; grid-column: 2; grid-row: 1 / span 2;
  aspect-ratio: 1; border-radius: 50%;
  background: conic-gradient(from 0deg,
    var(--m2) 1.2deg 88.8deg, transparent 88.8deg 91.2deg,
    var(--m4) 91.2deg 178.8deg, transparent 178.8deg 181.2deg,
    var(--m3) 181.2deg 268.8deg, transparent 268.8deg 271.2deg,
    var(--m1) 271.2deg 358.8deg, transparent 358.8deg 360deg);
  -webkit-mask: radial-gradient(circle at 50% 50%, transparent 0 45%, #000 45.5%);
  mask: radial-gradient(circle at 50% 50%, transparent 0 45%, #000 45.5%);
}
/* Icons sit at each quadrant's midpoint */
.cs-hub__ico {
  position: absolute; width: 26px; height: 26px; translate: -50% -50%;
  color: var(--ink); opacity: .85;
}
.cs-hub__ico svg { width: 100%; height: 100%; display: block; }
/* 14.5% of the box each way puts them on the middle of the band, not on the box diagonal
   (the mask's radial-gradient sizes to the farthest corner, so the hole is ~32%, not 45%) */
.cs-hub__ico--tl { left: 35.5%; top: 35.5%; }
.cs-hub__ico--tr { left: 64.5%; top: 35.5%; }
.cs-hub__ico--bl { left: 35.5%; top: 64.5%; }
.cs-hub__ico--br { left: 64.5%; top: 64.5%; }

/* Shares the ring's grid cell rather than being absolutely positioned — the ring's mask
   would clip a child out of the very hole the label needs to sit in */
.cs-hub__core {
  grid-column: 2; grid-row: 1 / span 2; place-self: center;
  max-width: 58%; text-align: center;
}
.cs-hub__core .label { display: block; font-size: 10px; opacity: .55; }
.cs-hub__core strong { display: block; margin-top: 6px; font-size: 15px; font-weight: 500; line-height: 1.25; }

.cs-hub__item { --a: currentColor; }
.cs-hub__item--tl { grid-column: 1; grid-row: 1; text-align: right; --a: var(--m1); }
.cs-hub__item--tr { grid-column: 3; grid-row: 1; --a: var(--m2); }
.cs-hub__item--bl { grid-column: 1; grid-row: 2; text-align: right; --a: var(--m3); }
.cs-hub__item--br { grid-column: 3; grid-row: 2; --a: var(--m4); }
.cs-hub__item strong {
  display: block; margin-bottom: 8px;
  font-size: clamp(16px, 1.35vw, 20px); font-weight: 500; line-height: 1.2;
  color: var(--a);
}
.cs-hub__item p { font-size: 15px; line-height: 1.5; opacity: .88; }
.cs-hub__item .label { display: block; margin-top: 10px; font-size: 10px; opacity: .6; }

@media (max-width: 900px) {
  /* Ring first, then the four methods in one column — the colour is the only link needed */
  .cs-hub { grid-template-columns: 1fr; justify-items: center; gap: clamp(20px, 4svh, 32px); }
  .cs-hub__ring { grid-column: 1; grid-row: 1; width: min(260px, 70vw); }
  .cs-hub__item { grid-column: 1 !important; grid-row: auto !important; text-align: left !important; }
  .cs-hub__item { padding-left: 14px; border-left: 2px solid var(--a); }
}

/* ---------- Service blueprint ---------- */
/* Journey stages across, service lanes down, with the line of visibility drawn between
   what the customer sees and what happens behind it. Scrolls sideways on narrow screens
   rather than collapsing, because the grid is the point. */
.cs-blueprint {
  grid-column: 1 / -1;
  margin-top: clamp(28px, 4svh, 48px);
  overflow-x: auto; overscroll-behavior-x: contain;
}
.cs-bp {
  display: grid; grid-template-columns: 124px repeat(6, minmax(122px, 1fr));
  min-width: 780px;
  border-top: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
.cs-bp > * {
  padding: 11px 13px 13px;
  border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.cs-bp__stage,
.cs-bp__lane {
  font: 500 10px/1.4 var(--sans); letter-spacing: .12em; text-transform: uppercase;
}
.cs-bp__stage { opacity: .8; background: color-mix(in srgb, #000 14%, transparent); }
.cs-bp__lane { opacity: .55; background: color-mix(in srgb, #000 8%, transparent); }
.cs-bp__cell { font-size: 12.5px; line-height: 1.4; opacity: .9; }
.cs-bp__cell em { display: block; font-style: normal; opacity: .55; }
/* The labelled divider that gives a blueprint its name */
.cs-bp__vis {
  grid-column: 1 / -1;
  padding: 7px 13px;
  font: 500 9px/1.4 var(--sans); letter-spacing: .16em; text-transform: uppercase;
  opacity: .6;
  border-top: 1px dashed color-mix(in srgb, currentColor 55%, transparent);
  border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.cs-blueprint__hint { margin-top: 12px; opacity: .55; }
@media (min-width: 900px) { .cs-blueprint__hint { display: none; } }

/* Sample-size bars under each method */
.cs-bar { display: block; height: 2px; margin-top: 10px; background: color-mix(in srgb, currentColor 22%, transparent); }
.cs-bar span { display: block; height: 100%; width: var(--w, 0%); background: currentColor; opacity: .75; }

/* Participant split bar */
.cs-split { display: flex; height: 8px; margin-top: 28px; overflow: hidden; }
.cs-split span { width: var(--w, 33%); background: currentColor; }
.cs-split span:nth-child(1) { opacity: .85; }
.cs-split span:nth-child(2) { opacity: .55; }
.cs-split span:nth-child(3) { opacity: .3; }
.cs-split-key { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 12px; opacity: .8; }

/* Insight numerals in outline, and a quote mark behind each quote */
.cs-insights__num {
  font-size: clamp(40px, 4vw, 68px); line-height: 1;
  opacity: .4;
}
.cs-insights blockquote { position: relative; }
.cs-insights blockquote::before {
  content: "\201C"; position: absolute; z-index: -1; left: -.22em; top: -.42em;
  font: italic 400 4.5em/1 var(--serif);
  color: color-mix(in srgb, currentColor 12%, transparent);
  pointer-events: none;
}

@media (max-width: 760px) {
  .case::before { background-size: calc(100% / 4) 100%; }
  .cs-block[data-ghost]::before { font-size: 34vw; top: -.2em; }
  .cs-journey li { flex: 0 0 50%; min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cs-block[data-ghost]::before { translate: 0 0 !important; }
}

/* ---------- Motion (JS enabled) ---------- */
html.js .line > span { transform: translateY(110%); transition: transform 1.4s var(--ease-out) var(--d, 0s); }
html.is-loaded .line > span { transform: none; }

html.js .reveal { opacity: 0; transform: translateY(26px); transition: opacity 1.2s var(--ease-out) var(--d, 0s), transform 1.2s var(--ease-out) var(--d, 0s); }
html.js .reveal.is-in { opacity: 1; transform: none; }
/* Image reveal: a cover in the page colour lifts away (clip-path on the target would stop IntersectionObserver firing) */
html.js .slot.reveal { opacity: 1; transform: none; }
html.js .slot.reveal::before {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: var(--bg); transform-origin: 50% 0;
  transition: transform 1.5s var(--ease) var(--d, 0s);
}
html.js .slot.reveal.is-in::before { transform: scaleY(0); }

html.js .drift span { opacity: 0; transform: translate(var(--dx, 0), var(--dy, 0)); transition: opacity 1.6s var(--ease-out) var(--d, 0s), transform 2s var(--ease-out) var(--d, 0s); }
html.js .drift.is-in span { opacity: 1; transform: none; }

/* ---------- Responsive ---------- */
@media (max-width: 1100px) {
  .hero__side { position: static; margin-top: 24px; text-align: center; }
  .hero__side--l { display: none; }
}

@media (max-width: 1024px) {
  .focus { grid-template-columns: 1fr; }

  .about { row-gap: 56px; }
  .about__main, .about__aside { grid-column: 1 / -1; }
  .about__aside { padding-top: 0; }
  .facts { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 767px) {
  .nav__links, .nav__pill .nav__cta { display: none; }
  .nav__toggle { display: flex; }
  .nav__pill { padding: 8px 10px 8px 12px; }
}

@media (max-width: 760px) {
  body { font-size: 16px; }

  .hero { min-height: 560px; }
  .hero__side { position: static; margin-top: 28px; text-align: center; }
  .hero__side--l { display: none; }
  .hero__img { bottom: 4svh; }
  .hero__img--1 { width: 46vw; transform: none; }
  .hero__img--2 { width: 50vw; transform: translateY(-14%); }
  .hero__aka { display: block; margin: 14px 0 0; vertical-align: 0; }
  .hcard { padding: 10px; }
  .hcard__arrow { width: 20px; height: 20px; }
  .hcard__desc { display: none; }

  .focus__statement, .focus__more { margin-left: 0; }

  .play { min-height: auto; }
  .play__letters, .play__text { position: static; }
  .play__letters { display: flex; justify-content: space-between; margin: 32px 0; font-size: 24vw; }
  .play__letters span { position: static; }
  .play__thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
  .thumb { position: static; width: auto; }
  .play__text { margin-top: 40px; }

  .about { grid-template-columns: 1fr; }
  .timeline li { grid-template-columns: 1fr; }
  .timeline > li > .label:last-child { text-align: left; }
  .roles li { flex-direction: column; gap: 2px; }
  .roles .label { text-align: left; }

  .cs-block { grid-template-columns: 1fr; }
  .cs-block > h3, .cs-text, .cs-media { grid-column: 1; }
  .cs-metrics { grid-template-columns: 1fr; }
  .cs-metrics li + li { padding-left: 0; border-left: 0; border-top: 1px solid var(--rule); }
  .cs-media { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; transition-delay: 0s !important; }
  html.js .line > span, html.js .reveal, html.js .drift span { opacity: 1 !important; transform: none !important; }
  html.js .cs-journey.reveal li { opacity: .85 !important; transform: none !important; }
  html.js .cs-journey.reveal li::before { transform: scaleX(1) !important; }
  html.js .cs-journey.reveal li::after { scale: 1 !important; }
  html.js .slot.reveal::before { display: none; }
}
