/* ============================================================
   Nia — Portfolio v2
   Fixed desktop layout, 1440px canvas — pixel-matched to Figma
   ("spacing v2": 160px gutters, 1120 content column).
   Tablet and mobile layouts take over below 1024 (end of file).
   ============================================================ */

:root {
  /* ---- Color: sand ---- */
  --sand-050: #f9f6f3;
  --sand-100: #f4ece4;
  --sand-200: #ecdac8;
  --sand-500: #d39558;
  /* ---- Color: sage ---- */
  --sage-100: #ecefe9;
  --sage-200: #dae1d3;
  --sage-300: #c6d2ba;
  --sage-700: #63774e;
  --sage-800: #4c5b3c;
  --sage-900: #353f29;
  /* ---- Color: neutral / plum / olive ---- */
  --neutral-100: #f1efec;
  --neutral-900: #292622;
  --neutral-950: #1a1815;
  --plum-950: #23080f;
  --olive: #6f7350;

  /* ---- Semantic text ---- */
  --text-primary: #1a1815;
  --text-secondary: #3e3a35;
  --text-muted: #736d65;
  --text-muted-strong: #635d55;   /* muted text on tinted fills (sage, sand-100/200): keeps 4.5:1 */
  --text-on-inverse: #f4ece4;
  --text-on-inverse-muted: #b3aea6;

  /* ---- Type families ---- */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --ink: #1a1815;          /* grid-line colour */
  --bleed: 0px;            /* set by main.js: full-bleed overhang past the canvas */

  /* ---- Motion: one family of curves for the whole site ---- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);      /* arrivals, UI feedback */
  --ease-draw: cubic-bezier(0.65, 0, 0.2, 1);     /* hairlines drawing in */
}

/* ---------------------------------------------------------- Reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--sand-050); }
body {
  margin: 0;
  background: var(--sand-050);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* Paper grain, in two layers so it never reads as a grey film:
   ::after — mid-grey noise averaging exactly 50% under overlay, which leaves
   50% grey untouched: specks lighten or darken the colour beneath, the mean
   never moves. Shows on photos and dark sections, vanishes near white.
   ::before — sparse warm-ink specks (--neutral-950, not black) for the light
   sand backgrounds; mean darkening ≈ 1.4 levels of 255.
   256px tiles drawn at 128px = crisp on 2x screens. */
body::before, body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none;
  background-position: 0 0; background-size: 128px 128px; background-repeat: repeat;
}
body::before {
  z-index: 9998; background-image: url("assets/grain-ink.png"); opacity: 0.1;
  view-transition-name: grain-ink;    /* stays put while pages cross-fade */
}
body::after {
  z-index: 9999; background-image: url("assets/grain.png");
  mix-blend-mode: overlay; opacity: 0.2;
  view-transition-name: grain;
}
@media print { body::before, body::after { display: none; } }
img { display: block; max-width: none; }
h1, h2, h3, p, dl, dd, figure, blockquote { margin: 0; }
dt, dd { margin: 0; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* Fixed canvas ------------------------------------------------ */
.page {
  width: 1440px;
  margin: 0 auto;
  background: var(--sand-050);
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--neutral-950); color: var(--text-on-inverse);
  padding: 10px 16px; font-family: var(--font-mono); font-size: 14px;
}
.skip-link:focus { left: 12px; top: 12px; }
:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 3px; }
/* sage ring is too faint on the dark footer (2.3:1): light ring there */
.footer :focus-visible { outline-color: var(--sand-100); }

/* ---------------------------------------------------------- Shared type */
.sec-head { display: flex; align-items: flex-end; gap: 8px; }
.sec-head h2 {
  flex: 1;
  font-family: var(--font-display); font-weight: 400;
  font-size: 64px; line-height: 72px; letter-spacing: -1.28px;
  color: var(--text-primary);
}
.sec-head__meta {
  font-family: var(--font-mono); font-weight: 500;
  font-size: 16px; line-height: 24px; letter-spacing: 1.28px;
  color: var(--text-muted); white-space: nowrap;
}

/* Work-section labels — muted caption (My role / Scope / Stage / Year) */
.precord__meta dt {
  font-family: var(--font-mono); font-weight: 500;
  font-size: 12px; line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-muted);
}
/* Hero meta labels — uppercase, same weight/colour as their values */
.meta-cell dt {
  font-family: var(--font-mono); font-weight: 400;
  font-size: 16px; line-height: 24px; letter-spacing: 0.08px;
  text-transform: uppercase; color: var(--text-secondary);
}
.meta-cell dd, .precord__meta dd {
  font-family: var(--font-mono); font-weight: 400;
  font-size: 16px; line-height: 24px; letter-spacing: 0.08px;
  color: var(--text-secondary);
}

/* ========================================================== NAV */
/* Full-width bar fixed to the screen width, outside the scaled canvas:
   native size on every screen, name hard-left, links hard-right, the gap
   between them stretches with the viewport. Line always reaches both edges. */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: var(--sand-050);
  border-bottom: 1px solid var(--sage-800);
}
.nav__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px 160px;
}
.nav__brand {
  font-family: var(--font-display); font-weight: 600;
  font-size: 24px; line-height: 32px; letter-spacing: -0.12px;
  color: var(--text-primary);
}
.nav__links {
  margin-left: auto; display: flex; gap: 32px; align-items: center;
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.nav__links a { position: relative; padding: 2px 0; }
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left; transition: transform .28s ease;
}
.nav__links a:hover::after { transform: scaleX(1); }
/* sound toggle (added by sound.js): four bars, flat when muted, they hop
   when a sound plays */
.nav__sound {
  margin: -8px -8px -8px 24px; padding: 8px; border: 0; background: none;
  color: var(--text-secondary); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.nav__sound > span { display: flex; align-items: center; gap: 3px; height: 16px; }
.nav__sound i {
  display: block; width: 2px; height: 100%; border-radius: 1px; background: currentColor;
  transform-origin: center; transition: transform .35s var(--ease-out), opacity .35s ease;
}
.nav__sound i:nth-child(1) { transform: scaleY(.45); }
.nav__sound i:nth-child(2) { transform: scaleY(.85); }
.nav__sound i:nth-child(3) { transform: scaleY(.6); }
.nav__sound i:nth-child(4) { transform: scaleY(1); }
.nav__sound[aria-pressed="false"] i { transform: scaleY(.14); opacity: .6; }
.nav__sound.is-sounding i:nth-child(odd) { transform: scaleY(1); transition-duration: .12s; }
.nav__sound.is-sounding i:nth-child(even) { transform: scaleY(.4); transition-duration: .12s; }
.nav__sound:hover { color: var(--text-primary); }
.nav__sound:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 2px; border-radius: 4px; }

/* ========================================================== HERO */
.hero {
  position: relative;
  display: flex; flex-direction: column; gap: 40px;
  padding: 96px 160px;
}
.hero__vline {
  position: absolute; top: 0; bottom: 0; left: 160px;   /* header line → hero bottom */
  width: 1px; color: var(--ink); background: currentColor;
  pointer-events: none;
}

.hero__card { border: 1px solid var(--neutral-950); }
.hero__top {
  display: flex; gap: 32px; align-items: stretch;
  border-bottom: 1px solid var(--neutral-950);
}
.hero__portrait { flex: 0 0 256px; align-self: stretch; overflow: hidden; }   /* 4096:2730 at the 180px row */
.hero__portrait img,
.hero__thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: url(#hero-gradient-map);
}
.hero__intro {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 16px; padding: 24px 0;
}
.hero__name {
  font-family: var(--font-display); font-weight: 400;
  font-size: 88px; line-height: 88px; letter-spacing: -2.2px;
  color: var(--text-primary);
}
.hero__role {
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-secondary);
}
.hero__statement {
  display: flex; justify-content: center;
  padding: 24px 32px;
}
.hero__statement p {
  flex: 1 1 0; min-width: 0;
  font-family: var(--font-display); font-weight: 400;
  font-size: 64px; line-height: 72px; letter-spacing: -1.28px;
  color: var(--text-primary);
}
.hero__statement em { font-style: italic; color: var(--sage-700); }

/* Cursor-guided shimmer on the hero headline: a warm light spot (radial
   gradient clipped to the text) that main.js eases toward the pointer.
   Base text and the sage accents keep their own colour away from the spot.
   Mouse only, and disabled under reduced motion — otherwise the text just
   shows its normal colours (glow parked off-canvas). */
@media (prefers-reduced-motion: no-preference) and (pointer: fine) {
  .hero__statement p {
    --mx: -400px; --my: -400px;
    padding-bottom: 0.1em; margin-bottom: -0.1em;   /* room for descenders */
    background: radial-gradient(circle 190px at var(--mx) var(--my),
      #fbeeda 0%, #e2b782 16%, #cc9256 34%, var(--text-primary) 100%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
  }
  .hero__statement em {   /* sage accents catch a pink light instead */
    --mx: -400px; --my: -400px;
    padding-right: 0.12em; margin-right: -0.12em;   /* italic overhang */
    background: radial-gradient(circle 190px at var(--mx) var(--my),
      #ffe2e8 0%, #e08aa0 16%, #b15572 34%, var(--sage-700) 100%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

.hero__meta {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 24px 32px; padding-left: 32px; width: 960px;
}
.meta-cell { display: flex; flex-direction: column; gap: 4px; }

.hero__thumb {
  position: absolute; right: 72px; top: 432px;   /* top edge 36px above the card bottom (card bottom at 468px) */
  width: 176px; height: 220px; border-radius: 0; overflow: hidden;
}

/* gradient-map placeholder (stands in for photos until images land) */
.gradient-map {
  background:
    radial-gradient(120% 120% at 15% 10%, rgba(211,149,88,0.55), transparent 55%),
    linear-gradient(135deg, var(--sage-700) 0%, var(--olive) 38%, var(--sand-500) 72%, var(--sand-200) 100%);
}

/* image slot placeholder */
.media-slot { background: var(--sand-200); border-radius: 0; }

/* ========================================================== WORK */
.work {
  border-top: 1px solid var(--neutral-950);
  background: var(--sand-050);
  padding: 96px 160px;
  display: flex; flex-direction: column; gap: 32px;
}
.work__grid { position: relative; }

/* full-bleed rules (1440) top & bottom of the grid */
.work__grid::before,
.work__grid::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  width: calc(1440px + 2 * var(--bleed)); height: 1px;
  background: var(--ink); pointer-events: none;
}
.work__grid::before { top: 0; }
.work__grid::after { bottom: 0; }

/* vertical rules at the content edges */
.work__grid .vrule {
  position: absolute; top: 0; bottom: 0; width: 1px; background: var(--ink);
  pointer-events: none;
}
.work__grid .vrule--left { left: 0; }
.work__grid .vrule--right { right: 0; }

.precord { position: relative; display: flex; gap: 32px; align-items: stretch; padding: 32px; }
.precord + .precord { border-top: 1px solid var(--ink); }
.precord--reverse { flex-direction: row; }

/* card image: the frame sets the 512x456 / 512x416 card shapes from Figma
   (the photo just covers it) and clips the hover lean-in. */
.precord__media {
  position: relative; isolation: isolate; overflow: hidden;
  flex: 1 1 0; min-width: 0; align-self: flex-start;
  aspect-ratio: 512 / 456;
  border-radius: 0; background: var(--sand-200);
}
.precord--reverse .precord__media { aspect-ratio: 512 / 416; }
.precord__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.2s var(--ease-out);
}
.precord:hover .precord__media img { transform: scale(1.025); }
.precord__body { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 24px; }
.precord__title {
  font-family: var(--font-display); font-weight: 400;
  font-size: 32px; line-height: 40px; letter-spacing: -0.32px;
  color: var(--text-primary);
}
.precord__lede { display: flex; flex-direction: column; gap: 8px; }
.precord__lede p {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.precord__lede .em { font-weight: 500; }

.precord__meta { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 32px; }
.precord__meta > div { min-width: 0; display: flex; flex-direction: column; gap: 4px; }

.precord__link {
  font-family: var(--font-mono); font-weight: 500; font-size: 16px;
  line-height: 24px; letter-spacing: 0.08px; color: var(--text-secondary);
  align-self: flex-start;
}
.precord__link span { display: inline-block; transition: transform .25s var(--ease-out); }
.precord__link:hover, .precord:hover .precord__link { color: var(--text-primary); }
.precord__link:hover span, .precord:hover .precord__link span { transform: translateX(5px); }
/* whole card is clickable: the link's ::after stretches over the card */
.precord .precord__link::after { content: ""; position: absolute; inset: 0; z-index: 2; }
.precord .precord__link:focus-visible { outline: none; }
.precord:has(.precord__link:focus-visible) { outline: 2px solid var(--ink); outline-offset: -2px; }

/* ========================================================== SAID */
.said {
  background: var(--sage-200);
  padding: 96px 160px;
  display: flex; flex-direction: column;
}
.said__grid { display: flex; gap: 32px; align-items: flex-start; }
.quote {
  flex: 1 1 0; min-width: 0;
  background: var(--sage-100); border-radius: 0; padding: 32px;
  display: flex; flex-direction: column; gap: 24px;
}
.quote__mark { width: 30px; height: 24px; }
.quote blockquote {
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-secondary);
}
.quote figcaption { display: flex; flex-direction: column; gap: 4px; }
.quote__by {
  font-family: var(--font-display); font-weight: 600;
  font-size: 24px; line-height: 32px; letter-spacing: -0.12px;
  color: var(--text-primary);
}
.quote__role {
  font-family: var(--font-mono); font-weight: 500; font-size: 16px;
  line-height: 24px; letter-spacing: 1.28px; color: var(--text-muted-strong);
}
.said .sec-head__meta { color: var(--text-muted-strong); }

/* ========================================================== ARCHETYPE */
.arch {
  background: var(--neutral-950); color: var(--text-on-inverse);
  padding: 96px 160px;
  display: flex; flex-direction: column;
}
.arch .sec-rule { color: var(--neutral-100); }   /* light rule on dark bg */
.arch__content { display: flex; flex-direction: column; gap: 64px; }
.arch__head { display: flex; flex-direction: column; gap: 16px; }
.arch__head h2 {
  font-family: var(--font-display); font-weight: 400;
  font-size: 64px; line-height: 72px; letter-spacing: -1.28px;
  color: var(--text-on-inverse);
}
.arch__sub {
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-on-inverse);
}
.arch__body { display: flex; gap: 32px; align-items: flex-start; }
.arch__copy {
  flex: 1 1 0; min-width: 0;
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-on-inverse);
}
.quote--dark {
  flex: 1 1 0; min-width: 0;
  background: var(--neutral-900); border-radius: 0; padding: 32px;
  display: flex; flex-direction: column; gap: 16px;
}
.quote--dark blockquote {
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-on-inverse);
}
.quote--dark .quote__role { color: var(--text-on-inverse-muted); }

.arch__explorer { display: flex; flex-direction: column; gap: 24px; }
.arch__tabs { position: relative; }
/* one row of tabs on a hairline, scrolling sideways when it doesn't fit */
.arch__strip {
  /* desktop: all twelve fit the column, spread edge to edge (~24px gaps) */
  display: flex; flex-wrap: nowrap; justify-content: space-between; gap: 16px;
  border-bottom: 1px solid var(--sage-300);
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  font-family: var(--font-mono); font-weight: 500; font-size: 16px;
  line-height: 24px; letter-spacing: 1.28px; color: var(--text-on-inverse-muted);
}
.arch__strip::-webkit-scrollbar { display: none; }
.arch__tab {
  appearance: none; -webkit-appearance: none; flex: none;
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 12px 0 10px; margin: 0;   /* 48 tall with the 2px underline */
  font: inherit; letter-spacing: inherit; line-height: inherit;
  color: var(--text-on-inverse-muted); white-space: nowrap;
  cursor: pointer; transition: color .2s ease, border-color .2s ease;
}
.arch__tab:hover { color: var(--text-on-inverse); }
.arch__tab.is-active { color: var(--text-on-inverse); border-bottom-color: var(--text-on-inverse); }
/* with JS, one underline slides between tabs instead */
.arch__strip.has-ink { position: relative; }
.arch__strip.has-ink .arch__tab.is-active { border-bottom-color: transparent; }
.arch__ink {
  position: absolute; left: 0; bottom: 0; height: 2px; width: 0;
  background: var(--text-on-inverse); pointer-events: none;
  transition: transform .5s var(--ease-out), width .5s var(--ease-out);
}
.arch__tile { transition: opacity .3s ease, transform .5s var(--ease-out); }
.arch__tile.is-swapping { opacity: 0; transform: translateY(6px); transition-duration: .16s; }
/* inset ring: the scrolling row would clip one drawn outside the tab */
.arch__tab:focus-visible { outline: 2px solid var(--sage-700); outline-offset: -2px; border-radius: 2px; }
.arch__examples { display: flex; gap: 24px; }
/* example tiles keep the 354x275 frame ratio at every size */
.arch__tile {
  flex: 1 1 0; min-width: 0; height: auto; aspect-ratio: 354 / 275;
  object-fit: cover; border-radius: 0; background: var(--neutral-900);
}
.arch__note {
  font-family: var(--font-mono); font-weight: 500; font-size: 16px;
  line-height: 24px; letter-spacing: 1.28px; color: var(--text-on-inverse-muted);
}

/* ========================================================== ABOUT */
.about { padding: 96px 160px 32px; display: flex; flex-direction: column; }
/* full-bleed rule between a section heading and its content */
.sec-rule {
  height: 1px; color: var(--ink); background: currentColor;
  margin-block: 32px 31px;   /* sits inside the 64px gap: 32 + 1 + 31 */
  margin-inline: calc(-160px - var(--bleed));
}
.about__row { display: flex; gap: 32px; align-items: flex-start; }
.about__prose { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 24px; }
.about__prose p {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.about__portrait { flex: 0 0 448px; width: 448px; height: 576px; }

/* ---- About portrait: 3D flip card (gradient-map front, real photo back) --- */
.about__portrait.flip {
  position: relative; border-radius: 0; cursor: pointer;
  perspective: 1400px;
  -webkit-tap-highlight-color: transparent;
}
.about__portrait.flip:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 4px; }
.flip__inner {
  position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transform: rotateY(0deg);
  will-change: transform;
}
.flip__face {
  position: absolute; inset: 0; border-radius: 0; overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: 0 18px 40px -24px rgba(26, 24, 21, 0.55);
}
.flip__face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.flip__face--back { transform: rotateY(180deg); }

/* held (fully flipped) state */
.about__portrait.flipped .flip__inner { transform: rotateY(180deg); }

/* the flip animations — wind-up, fast turn, overshoot, settle, with a slight
   off-axis wobble and lift so it reads hand-held rather than mechanical */
.about__portrait.flipping-forward .flip__inner {
  animation: flipFwd 0.95s cubic-bezier(0.33, 0, 0.2, 1) 0.08s both;
}
.about__portrait.flipping-backward .flip__inner {
  animation: flipBwd 0.95s cubic-bezier(0.33, 0, 0.2, 1) 0.08s both;
}
@keyframes flipFwd {
  0%   { transform: rotateY(0deg)   rotateX(0deg)   scale(1); }
  68%  { transform: rotateY(186deg) rotateX(1.5deg) scale(1.02); }
  100% { transform: rotateY(180deg) rotateX(0deg)   scale(1); }
}
@keyframes flipBwd {
  0%   { transform: rotateY(180deg) rotateX(0deg)    scale(1); }
  68%  { transform: rotateY(-6deg)  rotateX(-1.5deg) scale(1.02); }
  100% { transform: rotateY(0deg)   rotateX(0deg)    scale(1); }
}

/* shimmer — a warm specular band sweeping across the card as it turns */
.flip__shine {
  position: absolute; inset: 0; border-radius: 0; pointer-events: none;
  opacity: 0; mix-blend-mode: screen;
  background: linear-gradient(105deg,
    transparent 24%,
    rgba(255, 249, 235, 0.12) 42%,
    rgba(255, 249, 235, 0.55) 50%,
    rgba(255, 249, 235, 0.12) 58%,
    transparent 76%);
  background-size: 300% 100%;
  background-position: 130% 0;
}
.about__portrait.flipping-forward .flip__shine,
.about__portrait.flipping-backward .flip__shine {
  animation: flipShine 0.95s cubic-bezier(0.4, 0, 0.2, 1) 0.08s;
}
@keyframes flipShine {
  0%   { opacity: 0;    background-position: 135% 0; }
  28%  { opacity: 0.9; }
  100% { opacity: 0;    background-position: -85% 0; }
}

/* reduced motion: no spin/shimmer — the JS does a plain instant reveal */
@media (prefers-reduced-motion: reduce) {
  .about__portrait.flipped .flip__inner { transition: none; }
}

/* ========================================================== CRAFT MARQUEE */
.craft {
  padding: 32px 0 96px;
  margin-inline: calc(-1 * var(--bleed));       /* bleed to the window edges */
  overflow: hidden;
}
.craft__track {
  display: flex; width: max-content;
  will-change: transform;
}
/* hover eases it to a stop and it can be dragged/flung (main.js) */
.craft__track { cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.craft__track.is-dragging { cursor: grabbing; }
.craft__item img { -webkit-user-drag: none; pointer-events: none; }
/* gap lives on the items (as margin) so the duplicated set loops seamlessly */
.craft__item { flex: 0 0 280px; width: 280px; height: 360px; margin-right: 24px; }
.craft__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ========================================================== CONTACT */
.contact { background: var(--sand-100); padding: 96px 160px; border-top: 1px solid var(--neutral-950); }
.contact__inner { display: flex; flex-direction: column; gap: 40px; }
.contact__display {
  font-family: var(--font-display); font-weight: 400;
  font-size: 128px; line-height: 140px; letter-spacing: -3.2px;
  text-align: center; color: var(--plum-950);
}
.contact__display em { font-style: italic; color: var(--sage-800); }
.contact__channels { display: flex; gap: 32px; }
.channel {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 8px; padding: 24px 0;
}
.channel__rule {
  height: 1px; width: 100%; background: var(--sage-800);
  transform-origin: left; transition: transform .3s ease;
}
.channel:hover .channel__rule { transform: scaleY(3); }
.channel__label {
  font-family: var(--font-mono); font-weight: 500; font-size: 12px;
  line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-secondary); margin-top: 16px;   /* rule → label: 24px with the gap */
}
.channel__value {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.channel:hover .channel__value { color: var(--text-primary); }
.contact__note {
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-secondary); text-align: center; text-wrap: balance;
}

/* ========================================================== FOOTER */
.footer {
  position: relative; isolation: isolate;
  background: var(--sage-900); color: var(--text-on-inverse);
  padding: 64px 160px 40px;
  display: flex; flex-direction: column; gap: 40px;
  overflow: hidden;
}
/* Botanical gradient-map background, one image per breakpoint as in Figma.
   Desktop: the Figma render rebuilt 1694x352 (the 1440x272 footer plus 127px
   each side for wide windows and 40px top/bottom for the drift), drawn at
   that size so the footer shows exactly Figma's crop. */
.footer::before {
  content: ""; position: absolute; inset: -40px 0; z-index: -2;
  translate: 0 var(--py, 0px);      /* slow drift, set by main.js */
  background: var(--sage-900) url("assets/footer-bg-desktop.jpg") center / max(1694px, 100%) auto no-repeat;
}
.footer::after {                  /* Figma "Overlay": flat 40% black for text contrast */
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(0, 0, 0, 0.4);
}
.footer__grid { display: flex; gap: 80px; align-items: flex-start; }
.footer__brand {
  font-family: var(--font-display); font-weight: 400;
  font-size: 48px; line-height: 52px; letter-spacing: -0.72px;
  color: var(--text-on-inverse);
}
.footer__spacer { flex: 1; }
.footer__col { display: flex; flex-direction: column; gap: 8px; }
.footer__col a, .footer__col p {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-on-inverse);
}
.footer__col a { width: max-content; }
.footer__col a:hover { color: var(--sand-500); }
/* .footer__col p would otherwise win on specificity */
.footer__col .footer__label {
  font-family: var(--font-mono); font-weight: 500; font-size: 12px;
  line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-on-inverse-muted);
}
.footer__base {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;   /* the two lines never touch; the second drops below when tight */
  font-family: var(--font-mono); font-weight: 500; font-size: 12px;
  line-height: 16px; letter-spacing: 1.2px; color: var(--text-on-inverse-muted);
}
.footer__base p:first-child { flex: 1; }

/* ================================================== FULL-BLEED FILLS */
/* Colour fills and the Work rules reach the window edges on large screens,
   while their content stays in the canvas column. --bleed (set by main.js)
   is 0 until the canvas is capped and centred. */
.work, .said, .arch, .contact, .footer {
  margin-inline: calc(-1 * var(--bleed));
  padding-inline: calc(160px + var(--bleed));
}

/* ========================================================== MOTION */
/* Reveals (main.js adds .is-in once, on first view). Start states only apply
   under html.motion-ok, set in <head> when reduced motion is off. */
.rl { display: block; overflow: hidden; padding: 0 0.12em 0.16em; margin: 0 -0.12em -0.16em; }
.rl__in { display: block; }
.motion-ok [data-reveal="lines"]:not(.is-split) { opacity: 0; }
.motion-ok [data-reveal="lines"] .rl__in {
  transform: translateY(110%);
  transition: transform 1s var(--ease-out) calc(var(--i, 0) * 90ms);
}
.motion-ok [data-reveal="lines"].is-in .rl__in { transform: none; }
[data-reveal="lines"].is-done .rl { overflow: visible; }

.motion-ok [data-reveal="up"],
.motion-ok [data-reveal="stagger"] > * {
  opacity: 0; translate: 0 16px;
  transition: opacity .8s ease var(--d, 0ms), translate 1s var(--ease-out) var(--d, 0ms);
}
.motion-ok [data-reveal="up"] { --d: 120ms; }
.motion-ok [data-reveal="up"].is-in,
.motion-ok [data-reveal="stagger"].is-in > * { opacity: 1; translate: none; }

/* hairlines draw themselves in. The stroke is a ::before that scales from
   zero; the line itself stays full size and unclipped, so the reveal
   observer always sees it (a rule that is itself scaled or clipped to
   nothing has no visible area, and browsers then don't report it). */
.motion-ok :is(.sec-rule, .hero__vline)[data-draw] { background: none; }
.motion-ok .sec-rule[data-draw] { position: relative; }
.motion-ok :is(.sec-rule, .hero__vline)[data-draw]::before {
  content: ""; position: absolute; inset: 0; background: currentColor;
  transition: scale 1.3s var(--ease-draw);
}
.motion-ok .sec-rule[data-draw]::before { scale: 0 1; transform-origin: left; }
.motion-ok .hero__vline[data-draw]::before { scale: 1 0; transform-origin: top; transition-duration: 1.6s; transition-delay: .15s; }
.motion-ok [data-draw].is-in::before { scale: 1; }
/* borders drawn in by main.js (data-draw-border): one span per side,
   sitting exactly on the border it replaces */
.draw-edge { position: absolute; pointer-events: none; transition: scale .9s var(--ease-draw); }
.draw-edge--top    { top: calc(-1 * var(--w)); left: calc(-1 * var(--w)); right: calc(-1 * var(--w)); height: var(--w); transform-origin: left; }
.draw-edge--right  { top: calc(-1 * var(--w)); bottom: calc(-1 * var(--w)); right: calc(-1 * var(--w)); width: var(--w); transform-origin: top; }
.draw-edge--bottom { bottom: calc(-1 * var(--w)); left: calc(-1 * var(--w)); right: calc(-1 * var(--w)); height: var(--w); transform-origin: right; }
.draw-edge--left   { top: calc(-1 * var(--w)); bottom: calc(-1 * var(--w)); left: calc(-1 * var(--w)); width: var(--w); transform-origin: bottom; }
.motion-ok .draw-edge--top, .motion-ok .draw-edge--bottom { scale: 0 1; }
.motion-ok .draw-edge--left, .motion-ok .draw-edge--right { scale: 1 0; }
.motion-ok .is-in > .draw-edge { scale: 1; }
.nav > .draw-edge { transition-duration: 1.3s; transform-origin: left; left: 0; right: 0; }
.motion-ok .work__grid::before,
.motion-ok .work__grid::after,
.motion-ok .work__grid .vrule { transition: scale 1.4s var(--ease-draw); }
.motion-ok .work__grid::before { scale: 0 1; transform-origin: left; }
.motion-ok .work__grid::after { scale: 0 1; transform-origin: right; transition-delay: .35s; }
.motion-ok .work__grid .vrule { scale: 1 0; transform-origin: top; transition-delay: .15s; }
.motion-ok .work__grid.is-in::before,
.motion-ok .work__grid.is-in::after,
.motion-ok .work__grid.is-in .vrule { scale: 1; }
.motion-ok .contact__channels .channel__rule { scale: 0 1; transition: transform .3s ease, scale 1.2s var(--ease-draw) calc(var(--d, 0ms) + 150ms); }
.motion-ok .contact__channels.is-in .channel__rule { scale: 1; }

/* little arrows lean the way they point */
.channel__value span[aria-hidden],
.footer__col a span[aria-hidden] { display: inline-block; transition: transform .3s var(--ease-out); }
.channel:hover .channel__value span[aria-hidden],
.footer__col a:hover span[aria-hidden] { transform: translate(3px, -3px); }
.channel__label { transition: color .2s ease; }
.channel.is-copied .channel__label { color: var(--sage-800); }

/* page transitions: the project image travels into the case-study hero */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.nav { view-transition-name: nav; }
/* the page behind just cross-fades (no sliding), so the image's flight is
   the only movement */
::view-transition-old(root) { animation: vt-fade-out .22s ease both; }
::view-transition-new(root) { animation: vt-fade-in .4s ease .12s both; }
/* the project image flies into the case study's lead visual. The two have
   different shapes, so both snapshots fill the moving frame (cover) inside
   a rounded clip instead of being stretched to it */
::view-transition-group(edge-ai-media),
::view-transition-group(sonosift-media) { animation-duration: .65s; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); }
::view-transition-image-pair(edge-ai-media),
::view-transition-image-pair(sonosift-media) { overflow: clip; border-radius: 0; }
::view-transition-old(edge-ai-media), ::view-transition-new(edge-ai-media),
::view-transition-old(sonosift-media), ::view-transition-new(sonosift-media) {
  width: 100%; height: 100%; object-fit: cover; animation-duration: .4s;
}
/* Below 1024 the case-study header also holds the section progress bar, so a
   shared nav would stretch mid-flight, and the case-study hero image sits
   below the fold. There the pages just cross-fade. */
@media (max-width: 1023px) {
  .nav, [style*="view-transition-name"] { view-transition-name: none !important; }
}
@keyframes vt-fade-out { to { opacity: 0; } }
@keyframes vt-fade-in { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

/* Drop cap on the opening paragraph (About, each case study's situation),
   at every breakpoint. The Playfair capital always spans exactly three lines
   of the paragraph: its cap top lines up with the first line's cap height,
   its baseline with the third line's, and the fourth line runs full width.
   For body text s/L (font-size/line-height), from the font metrics
   (Plex Mono ascent 1.025, descent .275, cap .698; Playfair ascent 1.082,
   descent .251, cap .708):
     font-size   F = (2L + 0.698s) / 0.708
     line-height   = 3L
     margin-top    = L + 0.375s - 0.4155F
   16/24 (desktop, tablet): F 83.57, line-height 72, margin-top -4.72.
   14/20 (mobile, below):   F 70.30, line-height 60, margin-top -3.96. */
.dropcap::first-letter {
  float: left; margin: -4.72px 10px 0 0;
  font-family: var(--font-display); font-weight: 400;
  font-size: 83.57px; line-height: 72px; letter-spacing: 0;
  color: var(--text-primary);
}
.about .dropcap::first-letter { margin-right: 12px; }   /* the narrow I gets a wider gap */
@media (max-width: 767px) {
  .dropcap::first-letter { font-size: 70.3px; line-height: 60px; margin: -3.96px 8px 0 0; }
  .about .dropcap::first-letter { margin-right: 10px; }
}

/* End mark: a small inked square with an N, closing each case study */
.endmark {
  display: inline-block; width: 12px; height: 12px; border-radius: 1px;
  background: var(--text-secondary); color: var(--sand-050);
  font-family: var(--font-display); font-weight: 600; font-size: 10px;
  line-height: 12px; letter-spacing: 0; text-align: center;
  vertical-align: middle; position: relative; top: -1px;   /* 7px into the 24px line */
}

/* ================================================== CASE STUDY PAGES */
/* Shared by edge-ai.html and sonosift.html. Same 1440 canvas, content in
   the 1120 column (160px gutters); section rules in neutral-950, inner
   hairlines (asides, script, quotes) in text-muted. */
.cs-hero {
  display: flex; flex-direction: column; gap: 24px; align-items: flex-start;
  padding: 96px 160px 48px;
}
.cs-caps {   /* small caps-style caption: back link, eyebrow, labels */
  font-family: var(--font-mono); font-weight: 500;
  font-size: 12px; line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-muted);
}
.cs-back { transition: color .2s ease; }
.cs-back:hover { color: var(--text-primary); }
.cs-hero h1 {
  font-family: var(--font-display); font-weight: 400;
  font-size: 64px; line-height: 72px; letter-spacing: -1.28px;
  color: var(--text-primary);
}
.cs-hero__lede {
  width: 760px;
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-secondary);
}
.cs-hero__lede b, .cs-prose b, .cs-decision b, .cs-fig figcaption b, .cs-list b { font-weight: 500; }

.cs-lead-fig { padding: 0 160px 64px; }

/* figures */
.cs-fig { display: flex; flex-direction: column; gap: 12px; }
.cs-fig > img { width: 100%; height: auto; border-radius: 0; }

/* scrollshot — a long page inside a browser frame that scrolls on hover.
   Viewport geometry comes from the 1110×624 Figma frame: window at 181,132, 746×423.5;
   the 804-wide page sits 29px left of the viewport edge. */
.scrollshot { position: relative; overflow: hidden; border-radius: 0; outline-offset: 4px; }
.scrollshot__frame { display: block; width: 100%; height: auto; }
.scrollshot__view {
  position: absolute; left: 16.326%; top: 21.154%; width: 67.207%; height: 67.877%;
  overflow: hidden; border-radius: 0 0 1.338% 1.338% / 0 0 2.356% 2.356%;
}
.scrollshot__page {
  position: absolute; top: 0; left: -3.887%; width: 107.775%; max-width: none; height: auto;
  transition: transform 1.2s cubic-bezier(.45, 0, .2, 1);
}
/* page height 4782, viewport 423.5 → travel 91.143% of the page */
.scrollshot:hover .scrollshot__page,
.scrollshot:focus-visible .scrollshot__page {
  transform: translateY(-91.143%);
  transition: transform 10s cubic-bezier(.35, 0, .65, 1);
}
/* no hover, or no motion: let people scroll the window themselves */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .scrollshot__view { overflow: hidden auto; overscroll-behavior: contain; }
  .scrollshot__page { position: relative; display: block; transition: none; }
  .scrollshot:hover .scrollshot__page,
  .scrollshot:focus-visible .scrollshot__page { transform: none; }
}
.cs-fig figcaption {
  font-family: var(--font-mono); font-size: 12px; line-height: 20px;
  letter-spacing: 0.12px; color: var(--text-muted);
}
.cs-ph {   /* image placeholder — dashed frame with a description */
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: var(--ar, 1110 / 480); padding: 32px 40px;
  border: 1px dashed var(--sage-300);
}
.cs-ph p {
  max-width: 560px; text-align: center;
  font-family: var(--font-mono); font-size: 12px; line-height: 20px;
  letter-spacing: 0.12px; color: var(--text-muted);
}
.cs-media { display: flex; flex-direction: column; gap: 40px; }
.cs-two { display: flex; gap: 32px; align-items: flex-start; }
.cs-two > .cs-fig { flex: 1 1 0; min-width: 0; }

/* meta strip */
.cs-meta { padding: 0 160px; }
.cs-meta__row {
  display: flex; gap: 32px; padding: 24px 0;
  border-top: 1px solid var(--neutral-950);
}
.cs-meta__row > div { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.cs-meta__row dd {
  font-family: var(--font-mono); font-size: 12px; line-height: 20px;
  letter-spacing: 0.12px; color: var(--text-secondary);
}

/* content block: rule, label column + prose column, then decision/media */
.cs-block {
  display: flex; flex-direction: column; gap: 40px;
  padding: 64px 160px;
  scroll-margin-top: 40px;
}
.cs-block::before { content: ""; height: 1px; background: var(--neutral-950); }
.cs-cols { display: flex; gap: 32px; align-items: flex-start; }
.cs-cols > .cs-caps { flex: 0 0 448px; }
.cs-prose { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 24px; }
.cs-prose p {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.cs-prose h2 {
  font-family: var(--font-display); font-weight: 400;
  font-size: 32px; line-height: 40px; letter-spacing: -0.32px;
  color: var(--text-primary);
}

/* decision: tags, then the story on the page itself (no card), lined up
   with the prose column (label 448 + gap 32) */
.cs-decision { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; padding-left: 480px; }
.cs-decision > p, .cs-list {
  width: 640px;
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}
.cs-tags { display: flex; gap: 8px; }
.cs-tag {
  padding: 4px 12px; border-radius: 2px; background: var(--sand-200);
  font-family: var(--font-mono); font-weight: 500;
  font-size: 12px; line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-muted-strong);
}

/* aside: trade-off / still open / what I rejected — hairline on the left */
.cs-aside {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 8px; padding-left: 16px;
  border-left: 1px solid var(--text-muted);
  max-width: 640px;
}
.cs-aside p {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-muted);
}
.cs-prose .cs-aside { margin-top: 0; }

/* dash list */
.cs-list { display: flex; flex-direction: column; gap: 12px; }
.cs-list li { position: relative; padding-left: 20px; }
.cs-list li::before {
  content: ""; position: absolute; left: 0; top: 11.5px;
  width: 8px; height: 1px; background: var(--sage-700);
}

/* film script */
.cs-script {
  display: flex; flex-direction: column; gap: 16px;
  padding: 4px 0 4px 16px; border-left: 1px solid var(--text-muted);
}
.cs-script li { display: flex; flex-direction: column; gap: 8px; }
.cs-script q {
  quotes: none;
  font-family: var(--font-mono); font-size: 20px; line-height: 28px;
  color: var(--text-primary);
}

/* pull quote */
.cs-pull {
  display: flex; flex-direction: column; gap: 16px;
  padding: 12px 0 12px 16px;
  border-left: 1px solid var(--text-muted);
}
.cs-pull blockquote {
  font-family: var(--font-display); font-weight: 600;
  font-size: 24px; line-height: 32px; letter-spacing: -0.12px;
  color: var(--text-primary);
}
/* testimonial: the headline line, the full note under it, then who said it */
.cs-pull--note { gap: 16px; padding-left: 24px; }
.cs-pull__note {
  font-family: var(--font-mono); font-size: 16px; line-height: 24px;
  letter-spacing: 0.08px; color: var(--text-secondary);
}

/* colophon */
.cs-colophon {
  display: flex; flex-direction: column; gap: 24px;
  padding: 64px 160px 96px;
}
.cs-colophon::before { content: ""; height: 1px; background: var(--neutral-950); }
.cs-colophon div { display: flex; flex-direction: column; gap: 4px; }
.cs-colophon p {
  font-family: var(--font-mono); font-size: 12px; line-height: 20px;
  letter-spacing: 0.12px; color: var(--text-muted);
}

/* section progress rail — fixed at the left edge, outside the scaled canvas */
.cs-rail {
  position: fixed; left: 48px; top: 50%; z-index: 50;
  transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 8px;
  opacity: 0; pointer-events: none; transition: opacity .3s ease;
}
.cs-rail.is-visible, .cs-rail:focus-within { opacity: 1; pointer-events: auto; }
.cs-rail a { display: flex; align-items: center; gap: 12px; height: 2px; }
.cs-rail .bar {
  flex: 0 0 auto; width: 20px; height: 2px; border-radius: 1px;
  background: var(--sage-300); opacity: .45;
  transition: width .25s ease, background-color .25s ease, opacity .25s ease;
}
.cs-rail .is-past .bar { background: var(--text-secondary); opacity: .7; }
.cs-rail .is-active .bar { width: 32px; background: var(--text-primary); opacity: 1; }
.cs-rail .label {
  font-family: var(--font-mono); font-weight: 500;
  font-size: 12px; line-height: 16px; letter-spacing: 1.2px;
  color: var(--text-muted); white-space: nowrap;
  opacity: 0; transition: opacity .25s ease;
}
.cs-rail .is-active .label,
.cs-rail a:hover .label,
.cs-rail a:focus-visible .label { opacity: 1; }
/* main.js adds .is-tight to an item whose label would run into the content
   column (narrow gutters); the bar still shows, the label waits for hover */
.cs-rail .is-active.is-tight .label { opacity: 0; }
.cs-rail .is-active.is-tight:hover .label { opacity: 1; }
@media (max-width: 1023px) { .cs-rail { display: none; } }

/* ---- Case study: compact progress bar (tablet & mobile; the rail is desktop) */
.cs-progress, .cs-menu { display: none; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.br-narrow { display: none; }

/* ================================================== TABLET (768–1023) */
/* Below 1024 main.js stops zooming the 1440 canvas and these layouts take
   over: fluid width, 40px gutters, columns collapse where Figma does. */
@media (max-width: 1023px) {
  html, body { overflow-x: clip; }
  .page { width: auto; }
  .work, .said, .arch, .contact, .footer { margin-inline: 0; }

  .nav__inner { padding: 16px 40px; }

  /* shared headings */
  .sec-head h2, .arch__head h2 { font-size: 48px; line-height: 52px; letter-spacing: -0.72px; }
  .sec-rule { margin-block: 24px 23px; margin-inline: -40px; }

  /* hero */
  .hero { padding: 80px 40px; }
  .hero__vline { left: 40px; }
  /* the text column sets the row height; the photo just fills it */
  .hero__top { gap: 24px; }
  .hero__portrait { position: relative; flex: 0 0 246px; }
  .hero__portrait img { position: absolute; inset: 0; }
  .hero__intro { padding: 24px 0; }
  .hero__name { font-size: 64px; line-height: 72px; letter-spacing: -1.28px; }
  .hero__role { line-height: 28px; }
  .hero__statement { padding: 24px; }
  .hero__statement p { font-size: 48px; line-height: 52px; letter-spacing: -0.72px; }
  .hero__meta {
    width: auto; padding-left: 24px;
    grid-template-columns: repeat(2, 240px); gap: 24px 16px;
  }
  .hero__thumb { right: 56px; top: 349px; width: 109px; height: 136px; }

  /* work */
  .work { padding: 80px 40px; gap: 24px; }
  .work__grid::before, .work__grid::after { width: 100vw; }
  .precord, .precord--reverse { flex-direction: column; gap: 24px; padding: 24px; }
  .precord--reverse .precord__media { order: -1; }
  .precord__media { flex: none; width: 100%; min-height: 0; height: 590px; }
  .precord__body {
    display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px;
    grid-template-areas: "title meta" "lede meta" "lede link";
    grid-template-rows: auto 1fr auto;
  }
  .precord__title {
    grid-area: title;
    font-size: 24px; line-height: 32px; letter-spacing: -0.12px; font-weight: 400;
  }
  .precord__lede { grid-area: lede; }
  .precord__lede .em, .precord__link { letter-spacing: 1.28px; }   /* Caption/Large */
  .precord__meta, .precord__meta--two {
    grid-area: meta; align-self: start;
    display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  }
  .precord__link { grid-area: link; align-self: end; }

  /* testimonials */
  .said { padding: 80px 40px; }
  .quote { padding: 24px; align-self: stretch; }
  .said__grid { gap: 16px; align-items: stretch; }

  /* archetypes */
  .arch { padding: 80px 40px; }
  .arch__sub { line-height: 28px; }
  .arch__content { gap: 48px; }
  .arch__body { gap: 16px; }
  .quote--dark { padding: 24px; }
  /* tab row runs to the screen edge, with a fade hinting there's more */
  .arch__tabs { margin-right: -40px; }
  .arch__strip { justify-content: flex-start; gap: 24px; padding-right: 48px; }
  .arch__tabs::after {
    content: ""; position: absolute; top: 0; right: 0; width: 72px; height: 43px;
    background: linear-gradient(90deg, rgba(26, 24, 21, 0), var(--neutral-950));
    pointer-events: none; transition: opacity .2s ease;
  }
  .arch__tabs.is-end::after { opacity: 0; }

  /* about */
  .about { padding: 80px 40px 32px; }
  .about__row { gap: 24px; }
  .about__portrait { order: -1; flex: 0 0 244px; width: 244px; height: 312px; }

  /* craft */
  .craft { padding: 32px 0 80px; }
  .craft__item { flex-basis: 240px; width: 240px; height: 308px; }

  /* contact */
  .contact { padding: 80px 40px; }
  .contact__display { font-size: 92px; line-height: 100px; letter-spacing: -2.3px; }
  .contact__channels { flex-direction: column; gap: 0; }
  .contact__note { line-height: 28px; }

  /* footer */
  .footer { padding: 48px 40px 40px; }
  /* tablet image fills the footer height exactly (Figma "Fill"), so there is
     no spare picture to drift: it sits still below 1024 */
  .footer::before {
    inset: 0; translate: none;
    background: var(--sage-900) url("assets/footer-bg.webp") center / cover no-repeat;
  }
  .footer__grid { gap: 48px; }
  .footer__brand { flex: 1; font-size: 32px; line-height: 40px; letter-spacing: -0.32px; }
  .footer__spacer { display: none; }

  /* ---- case studies ---- */
  /* the bar is a button: tap to open the section list */
  .cs-progress {
    display: flex; flex-direction: column; gap: 8px; padding: 8px 0 0;
    width: 100%; margin: 0; border: 0; border-radius: 0;
    background: var(--sand-050); color: inherit; font: inherit; text-align: left;
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .cs-progress:focus-visible { outline: 2px solid var(--sage-700); outline-offset: -2px; }
  .cs-progress__row {
    display: flex; justify-content: space-between; align-items: center; padding: 0 40px;
    font-family: var(--font-mono); font-weight: 500;
    font-size: 12px; line-height: 16px; letter-spacing: 1.2px;
    color: var(--text-muted); white-space: nowrap;
  }
  .cs-progress__track { position: relative; height: 2px; background: var(--sage-300); }
  .cs-progress__fill {
    position: absolute; inset: 0 auto 0 0; width: 100%;
    background: var(--sage-700);
    transform: scaleX(var(--p, 0)); transform-origin: left;
  }
  .cs-progress__meta { display: flex; align-items: center; gap: 8px; }
  .cs-progress__chevron { display: block; color: var(--text-muted); transition: transform .2s ease; }
  .cs-progress[aria-expanded="true"] .cs-progress__chevron { transform: rotate(180deg); }

  /* section list: drops from under the bar; the dimmed area below closes it */
  .cs-menu:not([hidden]) {
    position: absolute; top: 100%; left: 0; right: 0;
    height: calc(100dvh - var(--cs-header, 100px));
    display: flex; flex-direction: column;
  }
  .cs-menu__list {
    flex: none; max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
    padding: 8px 0; background: var(--sand-050); border-bottom: 1px solid var(--sage-300);
  }
  .cs-menu__list a {
    display: flex; align-items: center; gap: 16px; padding: 12px 40px;
    white-space: nowrap; -webkit-tap-highlight-color: transparent;
  }
  .cs-menu__list a:focus-visible { outline: 2px solid var(--sage-700); outline-offset: -2px; }
  .cs-menu__num {
    font-family: var(--font-mono); font-weight: 500;
    font-size: 12px; line-height: 16px; letter-spacing: 0.96px; color: var(--text-muted);
  }
  .cs-menu__name {
    font-family: var(--font-mono); font-size: 16px; line-height: 24px;
    letter-spacing: 0.08px; color: var(--text-primary);
  }
  .cs-menu__scrim {
    flex: 1; min-height: 0; margin: 0; padding: 0; border: 0;
    background: rgba(26, 24, 21, 0.24); cursor: pointer;
  }
  html.cs-menu-open { overflow: hidden; }   /* page stays put behind the list */

  /* jumps land with the section top just under the nav + bar (main.js measures it) */
  .cs-block { scroll-margin-top: var(--cs-header, 100px); }

  .nav:has(.cs-progress) { border-bottom: 0; }
  .nav:has(.cs-progress) .nav__inner { border-bottom: 1px solid var(--sage-800); }

  .cs-hero { padding: 80px 40px 48px; }
  .cs-hero h1 { font-size: 48px; line-height: 52px; letter-spacing: -0.72px; }
  .cs-hero__lede { width: auto; line-height: 28px; }
  .cs-lead-fig { padding: 0 40px 64px; }
  .cs-meta { padding: 0 40px; }
  .cs-meta__row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 16px; }
  .cs-block { padding: 48px 40px; }
  .cs-cols { gap: 24px; }
  .cs-cols > .cs-caps { flex: 0 0 154px; }
  .cs-prose { gap: 24px; }
  /* decision sits in the prose column, 24 under the heading */
  .cs-decision { padding-left: 178px; }
  .cs-cols + .cs-decision { margin-top: -16px; }
  .cs-media { gap: 32px; }
  .cs-two { gap: 16px; }
  .cs-prose h2 { font-size: 24px; line-height: 32px; letter-spacing: -0.12px; font-weight: 600; }
  .cs-decision > p, .cs-list { width: auto; }
  .cs-aside { max-width: none; }
  .cs-script q { width: auto; }
  .cs-ph { padding: 32px 24px; }
  .cs-colophon { padding: 48px 40px 64px; }
}

/* ================================================== MOBILE (< 768) */
@media (max-width: 767px) {
  .nav__inner { padding: 16px; }
  .nav__brand { font-size: 20px; line-height: 28px; }
  .nav__links { gap: 24px; font-size: 14px; line-height: 20px; letter-spacing: 0.07px; }

  .sec-head h2, .arch__head h2 { font-size: 36px; line-height: 40px; letter-spacing: -0.54px; }
  .sec-head__meta { font-size: 12px; line-height: 16px; letter-spacing: 0.96px; }
  .sec-rule { margin-block: 24px 23px; margin-inline: -16px; }

  /* Mobile type: Body/Small 14/20, Body/Large 16/24 */
  .meta-cell dt, .meta-cell dd, .precord__meta dd, .precord__lede p,
  .arch__copy, .about__prose p, .channel__value, .footer__col a, .footer__col p,
  .cs-prose p, .cs-decision > p, .cs-list, .cs-aside p, .cs-pull__note {
    font-size: 14px; line-height: 20px; letter-spacing: 0.07px;
  }
  .hero__role, .quote blockquote, .quote--dark blockquote, .arch__sub,
  .contact__note, .cs-hero__lede { font-size: 16px; line-height: 24px; }
  .precord__link, .arch__note, .quote__role {
    font-size: 14px; line-height: 20px; letter-spacing: 0.07px;   /* Body/Small/Emphasized */
  }

  /* hero */
  .hero { padding: 48px 16px 64px; }
  .hero__vline { left: 16px; }
  .hero__top { gap: 0; }
  .hero__portrait { flex: 1 1 0; min-width: 0; }
  .hero__intro { flex: 0 0 248px; gap: 8px; padding: 16px; }
  .hero__name { font-size: 44px; line-height: 44px; letter-spacing: -0.88px; }
  .hero__statement { padding: 16px; }
  .hero__statement p { font-size: 36px; line-height: 40px; letter-spacing: -0.54px; }
  .br-narrow { display: inline; }
  .hero__meta { grid-template-columns: 1fr; gap: 16px; padding-left: 16px; }
  .hero__thumb { right: 0; top: 294px; width: 96px; height: 120px; border-radius: 0; }   /* flush to the screen edge, square */

  /* work */
  .work { padding: 64px 16px; gap: 24px; }
  .precord, .precord--reverse { padding: 16px; }
  .precord__media { height: 286px; }
  .precord__body { display: flex; flex-direction: column; gap: 24px; }
  .precord__meta, .precord__meta--two { gap: 16px; }
  .precord__lede .em { letter-spacing: 0.07px; }
  .precord__title { font-weight: 400; }
  .precord__link { align-self: flex-start; }
  .precord__meta dt { letter-spacing: 0.96px; }

  /* testimonials */
  .said { padding: 64px 16px; }
  .said__grid { flex-direction: column; gap: 24px; }
  .quote { padding: 32px 24px; }
  .quote__by { font-size: 20px; line-height: 28px; letter-spacing: 0; }

  /* archetypes */
  .arch { padding: 64px 16px; }
  .arch__head { gap: 12px; }
  .arch__content { gap: 40px; }
  .arch__tabs { margin-right: -16px; }
  .arch__tabs::after { width: 56px; }
  .arch__body { flex-direction: column; gap: 32px; }
  .arch__copy, .quote--dark { flex: none; width: 100%; }
  .quote--dark { padding: 32px 24px; }
  .arch__examples {   /* swipeable row; tiles run off the right edge */
    gap: 16px; margin-right: -16px; padding-right: 16px;
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  }
  .arch__examples::-webkit-scrollbar { display: none; }
  .arch__tile { flex: 0 0 308px; scroll-snap-align: start; }

  /* about */
  .about { padding: 64px 16px 32px; }
  .about__row { flex-direction: column; gap: 24px; }
  .about__prose { gap: 16px; }
  .about__portrait { flex: none; width: 100%; height: 440px; }

  /* craft */
  .craft { padding: 24px 0 64px; }
  .craft__item { flex-basis: 200px; width: 200px; height: 257px; margin-right: 16px; }

  /* contact */
  .contact { padding: 64px 16px; }
  .contact__display { font-size: 64px; line-height: 72px; letter-spacing: -1.28px; }
  .channel__value { overflow-wrap: anywhere; }
  .channel__label { margin-top: 20px; }   /* rule → label: 28px on mobile */

  /* footer */
  .footer { padding: 48px 16px 40px; }
  /* mobile: Figma's zoomed-in crop of the same image (stem and leaf edge),
     cut from the 4096px original so it stays sharp */
  .footer::before { background-image: url("assets/footer-bg-mobile.jpg"); }
  .footer__grid { flex-wrap: wrap; gap: 32px 16px; }
  .footer__brand { flex: 0 0 100%; font-size: 28px; line-height: 32px; letter-spacing: -0.28px; }
  .footer__col { flex: 1 1 140px; gap: 8px; }
  .footer__col .footer__label, .footer__base { letter-spacing: 0.96px; }   /* Mobile/Caption/Small: 8% */
  .footer__base { flex-direction: column; align-items: flex-start; gap: 8px; }

  /* ---- case studies ---- */
  .cs-progress { gap: 8px; padding-top: 8px; }
  .cs-progress__row { padding: 0 16px; letter-spacing: 0.96px; }
  .cs-menu__list a { padding: 12px 16px; }
  .cs-caps { letter-spacing: 0.96px; }

  /* spacing from the Mobile 390 frames: each section is rule → 32 → content,
     closed by 48 below; label → prose 16; paragraphs 16 */
  .cs-hero { gap: 24px; padding: 32px 16px; }
  .cs-hero h1 { font-size: 36px; line-height: 40px; letter-spacing: -0.54px; }
  .cs-lead-fig { padding: 0 0 48px; }
  .cs-lead-fig figcaption { padding: 0 16px; }
  .cs-meta { padding: 0 16px 48px; }
  .cs-meta__row { padding: 32px 0 0; }
  .cs-block { gap: 32px; padding: 0 16px 48px; }
  .cs-cols { flex-direction: column; gap: 16px; }
  .cs-cols > .cs-caps { flex: none; }
  .cs-prose { width: 100%; gap: 16px; }
  .cs-prose h2 { font-weight: 400; }
  .cs-decision { gap: 16px; padding-left: 0; }
  .cs-cols + .cs-decision { margin-top: 0; }
  .cs-tag { padding: 4px 8px; }
  /* hairline runs the height of the text; the 8px sits outside it */
  .cs-aside, .cs-prose .cs-aside { margin-block: 8px; padding-left: 16px; }
  .cs-list { gap: 24px; }
  .cs-list li { padding: 9px 0 0; }
  .cs-list li::before { top: 0; width: 100%; background: var(--sage-300); }
  .cs-media { gap: 24px; }
  .cs-two { flex-direction: column; gap: 24px; }
  .cs-two > .cs-fig { width: 100%; }
  .cs-ph { padding: 16px; }
  .cs-script { gap: 16px; margin-block: 8px; padding: 0 0 0 16px; }
  .cs-script q { font-size: 16px; line-height: 24px; }
  .cs-pull { gap: 12px; margin-block: 8px; padding: 0 0 0 16px; }
  .cs-pull blockquote { font-size: 20px; line-height: 28px; letter-spacing: 0; }
  .cs-colophon { gap: 32px; padding: 0 16px 48px; }
  .cs-colophon div { gap: 8px; }
}

/* ================================================== NARROW PHONES (< 360) */
/* At 320 the fixed 248px intro left the portrait a 38px sliver and the
   headline ran under the thumbnail. */
@media (max-width: 359px) {
  .nav__links { gap: 16px; }
  .hero__intro { flex-basis: 200px; }
  .hero__thumb { display: none; }
}

/* 404 page: the case-study hero, given room so the footer doesn't ride up */
.cs-hero--404 { min-height: 60vh; padding-bottom: 120px; }
.cs-hero--404 .precord__link { align-self: flex-start; }

/* ================================================== LAUNCH MATERIALS (Edge AI) */
/* Landing page in a browser frame, the promo film, the Instagram band
   (Reel + carousel) and the App Store strip. Ported from the v1 case study. */

/* landing page in browser chrome; only the address pill links out */
.siteframe {
  overflow: hidden;
  border: 1px solid rgba(26, 24, 21, 0.15); border-radius: 0;
  background: var(--sand-050); box-shadow: 0 1px 2px rgba(40, 30, 20, 0.05);
}
.siteframe__bar {
  display: flex; align-items: center; gap: 16px; padding: 12px 16px;
  background: var(--sand-100); border-bottom: 1px solid rgba(26, 24, 21, 0.15);
}
.siteframe__dots { display: flex; gap: 8px; }
.siteframe__dots i { display: block; width: 12px; height: 12px; border-radius: 50%; background: rgba(26, 24, 21, 0.15); }
.siteframe__url {
  padding: 4px 16px; border-radius: 100px;
  background: var(--sand-050); border: 1px solid rgba(26, 24, 21, 0.15);
  font-family: var(--font-mono); font-size: 12px; line-height: 16px; letter-spacing: 0.24px;
  color: var(--text-secondary);
  transition: color .2s ease, border-color .2s ease;
}
.siteframe__url:hover { color: var(--text-primary); border-color: var(--text-secondary); }
.siteframe__url:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 2px; }
.siteframe > img { width: 100%; height: auto; }

/* films */
.cs-film { overflow: hidden; border-radius: 0; background: #0c0c0d; }
.cs-video { display: block; width: 100%; height: auto; }

/* Instagram band: dark stage, Reel beside a feed post. They stay side by
   side down to 768px (both shrink together) and stack only on mobile. */
.social-band {
  display: flex; justify-content: center; align-items: flex-start;
  gap: 56px; padding: 48px 64px; border-radius: 0;
  background: linear-gradient(135deg, #222226 0%, #1a191e 100%);
  /* --u = 1px at the 340px design width of a column, so the phone UI
     inside scales as one piece instead of reflowing. Resolved against the
     nearest .social-col (a size container). */
  --u: calc(100cqw / 340);
}
.social-col {
  container-type: inline-size;
  flex: 0 1 340px; min-width: 0;
  display: flex; flex-direction: column; gap: 12px;
}
.social-cap {
  display: flex; flex-wrap: wrap; gap: 4px 8px;
  font-family: var(--font-mono); font-size: 12px; line-height: 16px;
  letter-spacing: 0.84px; text-transform: uppercase; color: rgba(255, 255, 255, 0.82);
}
.social-cap b { font-weight: 500; color: #fff; }
.social-reel__frame { overflow: hidden; border-radius: 0; background: #0c0c0d; }
.social-reel video { aspect-ratio: 9 / 16; object-fit: cover; }

/* Instagram feed post: every measurement in --u so it scales with the column */
.igpost {
  overflow: hidden; border-radius: 0; background: var(--sand-050);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.igpost__head {
  display: flex; align-items: center;
  gap: calc(var(--u) * 12); padding: calc(var(--u) * 12) calc(var(--u) * 16);
}
.igpost__avatar {
  flex: none; width: calc(var(--u) * 36); height: calc(var(--u) * 36);
  border-radius: 50%; overflow: hidden; background: #0c0c0d;
}
.igpost__avatar img { width: 100%; height: 100%; object-fit: cover; }
.igpost__id { display: flex; flex-direction: column; min-width: 0; line-height: 1.22; white-space: nowrap; }
.igpost__handle { font-size: calc(var(--u) * 14); font-weight: 600; color: var(--text-primary); }
.igpost__sub { font-size: calc(var(--u) * 12); color: var(--text-muted); }
.igpost__more {
  margin-left: auto; font-size: calc(var(--u) * 16); letter-spacing: calc(var(--u) * 2);
  color: var(--text-primary);
}
.igpost__media {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  background: #0c0c0d; touch-action: pan-y; user-select: none;
}
.igpost__track { display: flex; height: 100%; transition: transform .5s cubic-bezier(.2, .7, .2, 1); }
.igpost__slide { flex: 0 0 100%; height: 100%; }
.igpost__slide img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
.igpost__counter {
  position: absolute; top: calc(var(--u) * 12); right: calc(var(--u) * 12);
  padding: calc(var(--u) * 4) calc(var(--u) * 8); border-radius: 100px;
  background: rgba(15, 15, 22, 0.7); color: #fff;
  font-size: calc(var(--u) * 12); line-height: 1.33;
}
.igpost__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center;
  width: calc(var(--u) * 32); height: calc(var(--u) * 32); padding: 0;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.85);
  color: #111; font-size: calc(var(--u) * 18); line-height: 1; cursor: pointer;
  box-shadow: 0 2px 9px rgba(0, 0, 0, 0.2);
  opacity: 0; transition: opacity .2s;
}
.igpost__media:hover .igpost__nav, .igpost__nav:focus-visible { opacity: 1; }
@media (hover: none) { .igpost__nav { opacity: 1; } }
.igpost__nav:disabled { opacity: 0 !important; pointer-events: none; }
.igpost__nav.prev { left: calc(var(--u) * 8); }
.igpost__nav.next { right: calc(var(--u) * 8); }
.igpost__dots { display: flex; justify-content: center; gap: calc(var(--u) * 8); padding-top: calc(var(--u) * 12); }
.igpost__dots i {
  width: calc(var(--u) * 8); height: calc(var(--u) * 8); border-radius: 50%;
  background: rgba(0, 0, 0, 0.16); transition: transform .25s, background .25s;
}
.igpost__dots i.on { background: #7093ff; transform: scale(1.18); }
.igpost__foot { padding: calc(var(--u) * 12) calc(var(--u) * 16) calc(var(--u) * 16); }
.igpost__meta {
  font-family: var(--font-mono); font-size: calc(var(--u) * 10); line-height: 1.4;
  letter-spacing: calc(var(--u) * 0.7); text-transform: uppercase; color: var(--text-muted);
}
.igpost__cap { margin-top: calc(var(--u) * 8); font-size: calc(var(--u) * 14); line-height: 1.45; color: var(--text-primary); }
.igpost__cap b { font-weight: 600; }

/* the band and the strip are bigger pieces than a figure: give them air */
.cs-media > .social-band, .cs-media > .social-band + .cs-fig { margin-top: 24px; }

/* App Store strip: sideways scroll, like the store page */
.asostrip {
  display: flex; gap: 20px; padding-bottom: 16px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity; overscroll-behavior-x: contain;
}
.asostrip:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 4px; }
.asostrip::-webkit-scrollbar { height: 8px; }
.asostrip::-webkit-scrollbar-thumb { background: rgba(26, 24, 21, 0.15); border-radius: 100px; }
.asostrip img {
  flex: 0 0 auto; width: 244px; height: auto;
  border-radius: 0; background: #0c0c0d; scroll-snap-align: start;
}

@media (max-width: 1023px) {
  .social-band { gap: 24px; padding: 32px 24px; }
  .asostrip img { width: 200px; }
}
@media (max-width: 767px) {
  .social-band { flex-direction: column; align-items: center; gap: 32px; padding: 32px 16px; }
  .social-col { flex: none; width: min(340px, 100%); }
  .asostrip { gap: 12px; }
  .asostrip img { width: 176px; }
}

/* ================================================== JOURNAL SHOTS (Edge AI) */
/* Phones on a dark ground with soft colour glows, rebuilt from the Figma
   frames (523x560) in percentages so they scale with the column and stay
   sharp: vector glows, 2x phone renders. */
.jshot {
  position: relative; overflow: hidden; isolation: isolate;
  aspect-ratio: 523 / 560; background: #1e1e23;
}
.jshot--coach { background: #202025; }
.jshot__glow { position: absolute; max-width: none; mix-blend-mode: lighten; pointer-events: none; }
.jshot__phones { position: absolute; max-width: none; height: auto; }
/* athlete: purple bottom-right, blue behind the middle phone */
.jshot--athlete .jshot__glow--purple { left: -14.34%; top: 1.07%;  width: 181.26%; }
.jshot--athlete .jshot__glow--blue   { left: -47.8%;  top: -34.82%; width: 169.41%; }
.jshot--athlete .jshot__phones       { left: -13.96%; top: 5.18%;  width: 127.92%; }
/* coach: green top, blue bottom-left, arrow from "Create report" to the report */
.jshot--coach .jshot__glow--green { left: -21.99%; top: -44.64%; width: 177.06%; }
.jshot--coach .jshot__glow--blue  { left: -55.07%; top: -10%;    width: 169.41%; }
.jshot--coach .jshot__phones      { left: -19.12%; top: 1.61%;   width: 138.24%; }
.jshot__arrow {
  position: absolute; inset: 62.14% 42.7% 20.32% 38.81%;
  display: flex; align-items: center; justify-content: center;
}
.jshot__arrow img { width: 75.7%; height: 69.9%; flex: none; transform: rotate(-58.6deg) scaleX(-1); }
/* the lead image runs edge to edge on mobile: square corners there */
@media (max-width: 767px) { .cs-lead-fig .cs-fig > img, .cs-lead-fig .scrollshot { border-radius: 0; } }

/* ================================================== CONTACT GARDEN */
/* contact-garden.js: vines drawn on two canvases, behind and in front of
   the words, and the letter-by-letter roll between phrases */
.contact { position: relative; }
.garden-layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.garden-layer--back { z-index: 0; }
.garden-layer--front { z-index: 2; }
.garden-head { position: relative; z-index: 1; }
.garden-words {
  display: inline-grid; vertical-align: top; justify-items: center; align-items: start;
  /* extra room on the right for italic overhang (the f in "scarf") */
  overflow: hidden; padding: 0 0.32em 0.16em 0.12em; margin: 0 -0.32em -0.16em -0.12em;
  cursor: pointer; touch-action: pan-y; -webkit-tap-highlight-color: transparent;
}
.garden-words:focus-visible { outline: 2px solid var(--sage-700); outline-offset: 6px; border-radius: 4px; }
.garden-word { grid-area: 1 / 1; }
.garden-w { white-space: nowrap; }
/* when a swap changes the line count (phones), the box glides to the new height */
.motion-ok .garden-words { transition: height .7s var(--ease-out); }
/* the swap: old letters roll up and out, new ones roll up from below */
.garden-ch {
  display: inline-block; white-space: pre;
  transition: transform .7s var(--ease-out) var(--d, 0ms), opacity .5s ease var(--d, 0ms);
}
.garden-ch.is-above { transform: translateY(-105%); opacity: 0; }
.garden-ch.is-below { transform: translateY(105%); opacity: 0; transition: none; }
.garden-hint {
  margin-top: -24px; text-align: center;
  font-family: var(--font-mono); font-size: 12px; line-height: 16px;
  letter-spacing: 0.96px; text-transform: uppercase; color: var(--text-muted-strong);
  opacity: 0; translate: 0 6px;
  transition: opacity .8s ease, translate .9s var(--ease-out);
}
.garden-hint.is-shown { opacity: 1; translate: none; }
.garden-hint.is-gone { opacity: 0; transition-duration: .4s; }
