@import url("fonts.css");

/* ============================================================
   DIGITAL SAMADHI — core design system

   Direction: oceanic depth. The brand gradient appears only as
   LIGHT (the spine, one lit headline) and never as a filled
   background — that restraint is what separates cinematic from
   crypto. Atmosphere comes from photography and grain.

   Type: Switzer (voice) + Fraunces (display serif, variable
   opsz/SOFT/WONK) + IBM Plex Mono (metadata). Three registers.
   ============================================================ */

:root {
  /* ---- Ground: one hue cast across every surface, ~5% lightness
     per step. On dark, elevation is lightness — shadows don't read. */
  --s0: #05070B;   /* page */
  --s1: #0B0F16;   /* section / card */
  --s2: #131822;   /* nested / hover */
  --s3: #1B212D;   /* overlay */

  --line:      rgba(233, 229, 221, 0.11);
  --line-soft: rgba(233, 229, 221, 0.055);

  /* ---- Ink: warm bone against cool ground. Pure white on near-black
     halates; the warm/cool tension is the whole palette. */
  --bone:     #E9E5DD;   /* 16.0:1 on --s0 */
  --bone-dim: #A9A49B;   /*  8.1:1 */
  --mute:     #7A828D;   /*  5.2:1 on --s0, 4.6:1 even on --s2 — the smallest text on the site,
                             so it has to clear 4.5:1 on every surface, not merely look quiet */

  /* ---- Brand, sampled from the wordmark. Used as light, twice. */
  --azure:  #0A8FD8;
  --cyan:   #00BFC5;
  --spring: #00D89A;
  --grad: linear-gradient(100deg, var(--azure) 0%, var(--cyan) 52%, var(--spring) 100%);

  /* ---- Type families */
  --sans:  "Switzer", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
  --mono:  "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ---- Scale: deliberately non-uniform. Ratios widen at the top and
     compress at the bottom, the way Apple's ladder actually behaves —
     a single modular ratio cannot produce this. 390px -> 1440px. */
  /* Hero is sized for a short *phrase*. 180px is single-word edge-to-edge
     scale and would push the CTA below the fold. Apple's own marketing
     headline sits at 96px. */
  --t-hero:  clamp(2.5rem,    1.06rem  +  5.90vw,  6.75rem);  /*  40 -> 108 */
  --t-h1:    clamp(2.25rem,   0.857rem +  5.71vw,  6rem);     /*  36 ->  96 */
  --t-h2:    clamp(1.75rem,   1.100rem +  2.67vw,  3.5rem);   /*  28 ->  56 */
  --t-h3:    clamp(1.375rem,  1.143rem +  0.95vw,  2rem);     /*  22 ->  32 */
  --t-lead:  clamp(1.25rem,   1.100rem +  0.61vw,  1.75rem);  /*  20 ->  28 */
  --t-body:  clamp(1.0625rem, 1.016rem +  0.19vw,  1.1875rem);/*  17 ->  19 */
  --t-label: clamp(0.75rem,   0.727rem +  0.10vw,  0.8125rem);/*  12 ->  13 */

  /* ---- Tracking tightens as size grows. Negative at every size at or
     above body is the single most imitable Apple property. */
  --tr-hero:  -0.045em;
  --tr-h1:    -0.04em;
  --tr-h2:    -0.03em;
  --tr-h3:    -0.02em;
  --tr-lead:  -0.012em;
  --tr-body:  -0.005em;
  --tr-label:  0.14em;

  /* ---- Space. Text and grid get different maxima: text locks near
     65ch, grids run to 1440. */
  --gutter:  clamp(1.5rem, 5vw, 6rem);
  --measure: 62ch;
  --grid-max: 1440px;
  --text-max: 61rem;

  /* Nav: the logo's height plus its padding. The capsule sits 0.45rem inside
     that, which leaves ~0.8rem of clear space above and below the mark.
     Anchors, the sticky work bar and scroll padding all key off --nav-h. */
  --nav-logo: clamp(52px, 5vw, 66px);
  --nav-pad: 1.25rem;
  --nav-h: calc(var(--nav-logo) + 2 * var(--nav-pad) + env(safe-area-inset-top, 0px));

  /* Section rhythm: one value, so the gap between any two sections is the
     same on every page (twice this, top plus bottom). */
  --pad-md: clamp(5.5rem, 12vh, 9rem);

  /* ---- Motion. Named curves, per-element durations, never one global. */
  --ease-expo:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  /* Weighted: accelerates hard, then settles like an object with mass. Used for
     anything the hand moves — buttons, the menu, the nav capsule. */
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --d-press:  140ms;
  --d-hover:  240ms;
  --d-reveal: 1000ms;

  --radius: 5px;
  --radius-lg: 1.5rem;

  /* ---- Depth. On dark, elevation is a machined edge rather than a shadow:
     a surface sits in a faint tray, the tray has a hairline lip, and the
     surface catches one line of light along its top edge. Drawn as rings
     outside the element, so no card needs an extra wrapper in the markup. */
  --bezel-tray: rgba(233, 229, 221, 0.022);
  --bezel-edge: rgba(233, 229, 221, 0.07);
  --bezel-lift: inset 0 1px 0 rgba(255, 255, 255, 0.055);
  --bezel: var(--bezel-lift), 0 0 0 6px var(--bezel-tray), 0 0 0 7px var(--bezel-edge);
  /* The recommended option: the same tray with a cyan lip and the faintest
     glow beneath — light, never a fill. */
  --bezel-hi:
    var(--bezel-lift),
    0 0 0 6px var(--bezel-tray),
    0 0 0 7px color-mix(in srgb, var(--cyan) 24%, transparent),
    0 40px 90px -50px color-mix(in srgb, var(--cyan) 28%, transparent);

  /* The logo's descending rule sits 42.1% across the mark, not at its
     centre. Nudging by the 7.9% difference lands it on the page spine. */
  --stroke-offset: 7.9%;
}

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

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

body {
  margin: 0;
  background: var(--s0);
  color: var(--bone);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.55;
  letter-spacing: var(--tr-body);
  font-weight: 400;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures contextual;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* height:auto is required alongside the width/height attributes that
   reserve space for CLS — without it the intrinsic height wins and the
   image stretches. */
img, svg, video { max-width: 100%; height: auto; display: block; }

/* Controls don't inherit type on their own — without this a <button> renders
   in the system face (Arial on most machines) instead of Switzer. */
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: color-mix(in oklab, var(--cyan) 32%, transparent); }

/* The outline follows the element's own radius, so pills keep their shape
   when focused — no radius is set here. */
:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
}

/* ---------- Type ----------
   Weight ladder is 300 / 400 / 600 / 700 — 500 is deliberately absent,
   which forces genuine contrast rather than a mushy middle. */

.display {
  font-weight: 300;
  line-height: 0.94;
  letter-spacing: var(--tr-h1);
  text-wrap: balance;
  max-inline-size: 24ch;
  margin: 0;
}
.display.hero-type { font-size: var(--t-hero); letter-spacing: var(--tr-hero); line-height: 0.96; text-wrap: initial; }
.t-h1 { font-size: var(--t-h1); }
.t-h2 { font-size: var(--t-h2); letter-spacing: var(--tr-h2); line-height: 1.02; }
.t-h3 { font-size: var(--t-h3); letter-spacing: var(--tr-h3); line-height: 1.15; }

/* Fraunces carries the soul lines. WONK + low optical size give it a
   warmth Switzer deliberately doesn't have. */
.serif {
  font-family: var(--serif);
  font-weight: 400;
  font-variation-settings: "SOFT" 30, "WONK" 1;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.4;
  letter-spacing: var(--tr-lead);
  color: var(--bone-dim);
  text-wrap: pretty;
  max-inline-size: 34ch;
  margin: 0;
}

.label {
  font-family: var(--mono);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--tr-label);
  font-weight: 400;
  color: var(--mute);
  margin: 0;
}

/* Eyebrows. A label that introduces a display heading becomes a small pill, so every section opens on one precise object rather
   than loose text. Labels inside cards stay plain. */
.label:has(+ .display) {
  display: inline-flex;
  align-items: center;
  gap: 0.65em;
  padding: 0.52em 1em 0.52em 0.85em;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in srgb, var(--s1) 60%, transparent);
  box-shadow: var(--bezel-lift);
  color: var(--bone-dim);
  line-height: 1.2;
}
/* Numbered sections ("01 — The problem") read in the brand teal, so the
   thread through the page is easy to follow. */
.label.num-label:has(+ .display) {
  color: var(--cyan);
  border-color: color-mix(in srgb, var(--cyan) 38%, transparent);
  background: color-mix(in srgb, var(--cyan) 9%, var(--s1));
}
.label:has(+ .display)::before {
  content: "";
  flex: none;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 10px color-mix(in srgb, var(--cyan) 55%, transparent);
}

.prose { max-inline-size: var(--measure); color: var(--bone-dim); }
.prose strong { color: var(--bone); font-weight: 600; }

/* Numerals: tabular wherever a figure sits in a column or changes. */
.num { font-variant-numeric: tabular-nums lining-nums; }

/* The gradient, used as light on type. One of only two uses site-wide. */
.lit {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Layout ---------- */

.wrap { max-width: var(--grid-max); margin-inline: auto; padding-inline: var(--gutter); }
.wrap-text { max-width: var(--text-max); margin-inline: auto; padding-inline: var(--gutter); }

.section { padding-block: var(--pad-md); position: relative; }

/* Hero loops: a silent, seamless video over each page's still plate. It stays
   invisible until it can play, then fades in, so there is never a blank frame
   or a jump; site.js skips it entirely for reduced motion and data saver. The
   plate's own ::after veil still paints above it, keeping text contrast. */
.plate-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--hero-focus, 50%) 50%; pointer-events: none;
  opacity: 0; transition: opacity 1.4s var(--ease-out);
}
.plate-video.on { opacity: 1; }

/* Inner-page hero: one height, one fade and one padding on every page, so
   each page opens the same way and its first section starts the same
   distance below. The plate is decorative; the words sit low over it. */
.page-hero { min-height: 68svh; display: grid; align-items: end; position: relative; overflow: hidden; }
.page-hero .plate { position: absolute; inset: 0; z-index: -2; }
.page-hero .plate img { width: 100%; height: 100%; object-fit: cover; object-position: var(--hero-focus, 50%) 50%; }
.page-hero .plate::after {
  content: ""; position: absolute; inset: 0;
  /* Same veil as the home hero, so every page's horizon glows the same teal. */
  background: linear-gradient(to bottom, rgba(5,7,11,0.7) 0%, rgba(5,7,11,0.28) 36%, rgba(5,7,11,0.88) 86%, var(--s0) 100%);
}
/* A grid item with auto side margins shrinks to its content; full width keeps
   the hero on the same left edge as every section below. */
.page-hero .inner { padding-block: 9rem 4.5rem; width: 100%; }
.page-hero .actions { margin-top: 2.5rem; display: flex; gap: 1.1rem; flex-wrap: wrap; align-items: center; }

/* Let the content set the height on small screens, with enough room beneath
   the fixed navigation. The image and loop share the same scene framing. */
@media (max-width: 1199px) {
  .page-hero .inner { padding-block: calc(var(--nav-h) + 3rem) 3.5rem; }
  /* Near the fold, the reveal's initial translation can keep its own
     observer from firing. Primary hero actions must already be usable. */
  .hero-actions.rise, .page-hero .actions.rise { opacity: 1; translate: 0 0; }
}
@media (max-width: 899px) {
  .page-hero .inner { padding-block: calc(var(--nav-h) + 2rem) 3rem; }
}
@media (max-width: 1199px) and (orientation: portrait) {
  .page-hero .plate[data-plate="island"] { --hero-focus: 68%; }
  .page-hero .plate[data-plate="shore"] { --hero-focus: 32%; }
}
@media (max-width: 559px) {
  .page-hero { min-height: 74svh; }
  .page-hero .inner { padding-block: calc(var(--nav-h) + 0.75rem) 2.5rem; }
  .page-hero .lead { font-size: 1.125rem; }
  .page-hero .actions { margin-top: 1.5rem; gap: 0.5rem; flex-direction: column; align-items: flex-start; }
  .page-hero .actions .cta { width: 100%; max-width: 20rem; min-height: 44px; justify-content: space-between; }
  .page-hero .actions .cta-ghost { min-height: 44px; padding-block: 0.5rem; }
}

/* Long pages: skip offscreen layout work. Intrinsic size prevents
   scrollbar jump. */
.defer { content-visibility: auto; contain-intrinsic-size: auto 800px; }

/* ---------- The Spine ----------
   The logo's vertical rule, extended through the document. Everything
   composes around a single still axis — which is what samadhi means. */

.spine {
  position: fixed;
  inset-block: 0;
  left: 50%;
  width: 1px;
  translate: -50% 0;
  background: var(--line-soft);
  z-index: 1;
  pointer-events: none;
}
.spine::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--progress, 0) * 100%);
  width: 1px;
  height: 24vh;
  background: var(--grad);
  opacity: 0.85;
  mask-image: linear-gradient(to bottom, transparent, #000 38%, #000 62%, transparent);
}

/* Single-column below the .split breakpoint: there is no gutter for the axis
   to sit in, so it would strike through every line of copy. */
@media (max-width: 899px) {
  .spine { display: none; }
}

/* ---------- Grain ----------
   Load-bearing on dark: it dithers gradient banding on 8-bit displays
   as well as adding the film texture. */

.grain {
  position: fixed;
  inset: 0;
  z-index: 900;
  pointer-events: none;
  opacity: 0.055;
  background-size: 182px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 600'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.72' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)'/%3E%3C/svg%3E");
}

/* ---------- Reveal ---------- */

.rise {
  opacity: 0;
  translate: 0 2rem;
  transition:
    opacity var(--d-reveal) var(--ease-expo),
    translate var(--d-reveal) var(--ease-expo),
    filter var(--d-reveal) var(--ease-expo);
  transition-delay: var(--d, 0ms);
}
/* Type also resolves out of a soft focus, like a lens pulling in. Only text:
   blurring large images or grids costs frames on phones for no visible gain. */
.rise:is(h1, h2, h3, p, ul, blockquote) { filter: blur(6px); }
.rise.in { opacity: 1; translate: 0 0; filter: none; }

/* ---------- Controls ---------- */

.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.65em;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--s0);
  text-decoration: none;
  padding: 0.9em 1.6em;
  border-radius: 100px;
  background: var(--bone);
  border: 0;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 10px 30px -14px rgba(233, 229, 221, 0.35);
  transition:
    translate var(--d-hover) var(--ease-spring),
    scale var(--d-press) var(--ease-spring),
    background var(--d-hover) var(--ease-out),
    box-shadow var(--d-hover) var(--ease-out);
}
.cta:hover { translate: 0 -2px; background: #fff; box-shadow: inset 0 1px 0 #fff, 0 16px 36px -14px rgba(233, 229, 221, 0.45); }
.cta:active { scale: 0.98; translate: 0 0; }

/* A jump down the page: the disc drops rather than leaning forward. */
.cta-ghost[href^="#"]:hover .arrow { translate: 0 2px; }

/* Button-in-button: the arrow is its own small disc, sitting flush inside the
   pill's right edge. On hover it moves a beat ahead of the button. */
.cta:has(> .arrow) { gap: 0.75em; padding: 0.72em 0.55em 0.72em 1.5em; }
.cta .arrow {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.95em; height: 1.95em;
  border-radius: 50%;
  background: rgba(5, 7, 11, 0.075);
  font-size: 0.95em;
  line-height: 1;
  transition:
    translate var(--d-hover) var(--ease-spring),
    scale var(--d-hover) var(--ease-spring),
    background var(--d-hover) var(--ease-out);
}
.cta:hover .arrow { translate: 2px -1px; scale: 1.06; background: rgba(5, 7, 11, 0.11); }

.cta-ghost {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-size: 0.9375rem;
  color: var(--bone-dim);
  text-decoration: none;
  padding: 0.9em 0.2em;
  transition: color var(--d-hover) var(--ease-out);
}
.cta-ghost:hover { color: var(--bone); }
.cta-ghost .arrow {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.95em; height: 1.95em;
  border-radius: 50%;
  border: 1px solid var(--line);
  font-size: 0.95em;
  line-height: 1;
  transition:
    translate var(--d-hover) var(--ease-spring),
    border-color var(--d-hover) var(--ease-out),
    background var(--d-hover) var(--ease-out);
}
.cta-ghost:hover .arrow { translate: 2px -1px; border-color: color-mix(in srgb, var(--bone) 40%, transparent); background: rgba(233, 229, 221, 0.05); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
  .rise, .rise:is(h1, h2, h3, p, ul, blockquote) { opacity: 1; translate: 0; filter: none; }
}

/* ============================================================
   CHROME — navigation, footer
   ============================================================ */

.nav {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 800;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: calc(var(--nav-pad) + env(safe-area-inset-top, 0px)) max(var(--gutter), env(safe-area-inset-right, 0px)) var(--nav-pad) max(var(--gutter), env(safe-area-inset-left, 0px));
  /* Transparent over the hero plate, so nothing letterboxes the opening image. */
  background: transparent;
}
/* Once scrolled, the chrome becomes a floating capsule inset from the edges —
   never a bar glued to the top of the screen. It lives on a pseudo-element so
   it can fade and settle in using only opacity and scale; the logo and links
   never move. */
.nav::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 0.45rem calc(var(--gutter) * 0.5);
  border-radius: 1.5rem;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--s0) 74%, transparent);
  /* saturate() is the part everyone omits — without it the glass reads grey */
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  box-shadow: var(--bezel-lift), 0 24px 48px -30px rgba(0, 0, 0, 0.9);
  opacity: 0;
  scale: 0.985;
  pointer-events: none;
  transition: opacity 0.5s var(--ease-spring), scale 0.6s var(--ease-spring);
}
.nav.stuck::before { opacity: 1; scale: 1; }
/* The capsule sits at z-index 0; the logo, links and toggle are stacked
   explicitly above it rather than relying on paint order. */
.nav-links { position: relative; z-index: 1; }

.nav a.brand { display: flex; align-items: center; text-decoration: none; position: relative; z-index: 2; }
/* The real mark, sized by height because it is near-square (2461x2217).
   The wordmark is only ~28% of that height, so it needs ~60px before the type
   is legible. The cropped horizontal lockup was rejected — do not bring it back. */
.nav a.brand img { height: var(--nav-logo); width: auto; }

/* Original PSD wordmark, with its full blue-to-green gradient and transparent background. */
.brand-mark { position: relative; display: block; width: fit-content; }
.brand-mark img { display: block; width: 100%; height: auto; }

.nav-links { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2.1rem); }
.nav-links a {
  font-size: 0.875rem;
  color: var(--bone-dim);
  text-decoration: none;
  letter-spacing: -0.008em;
  transition: color var(--d-hover) var(--ease-out);
}
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--bone); }
/* .nav-links a (0,2,1) outranks .cta (0,1,0), so the button's dark-on-bone
   colour has to be restated here or it inherits the muted link colour. */
.nav-links a.cta { color: var(--s0); padding: 0.62em 1.15em; font-size: 0.875rem; }
.nav-links a.cta:has(> .arrow) { padding: 0.42em 0.42em 0.42em 1.1em; }
.nav-links a.cta:hover { color: var(--s0); }

.nav-toggle {
  display: none;
  min-height: 44px;
  position: relative;
  z-index: 2;
  align-items: center;
  gap: 0.7rem;
  background: color-mix(in srgb, var(--s0) 45%, transparent);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--bezel-lift);
  color: var(--bone);
  padding: 0.62rem 1rem 0.62rem 0.9rem;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: background var(--d-hover) var(--ease-out), border-color var(--d-hover) var(--ease-out), scale var(--d-press) var(--ease-spring);
}
.nav-toggle:active { scale: 0.97; }

/* Two lines that fold into an X — added by site.js, so the markup on every
   page stays a plain labelled button if scripts don't run. */
.burger { position: relative; display: inline-block; width: 16px; height: 9px; flex: none; }
.burger i {
  position: absolute; left: 0; right: 0; height: 1.5px;
  border-radius: 2px; background: currentColor;
  transition: translate 0.55s var(--ease-spring), rotate 0.55s var(--ease-spring);
}
.burger i:first-child { top: 0; }
.burger i:last-child { bottom: 0; }
.nav-toggle[aria-expanded="true"] .burger i:first-child { translate: 0 3.75px; rotate: 45deg; }
.nav-toggle[aria-expanded="true"] .burger i:last-child { translate: 0 -3.75px; rotate: -45deg; }

/* The page underneath doesn't scroll while the menu is open. */
html.menu-open { overflow: hidden; }

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  /* A full-screen sheet of dark glass. It fades rather than slides, so the
     links can make the entrance instead. */
  .nav-links {
    position: fixed;
    inset: 0;
    z-index: 1;
    padding: calc(var(--nav-h) + 1.5rem) var(--gutter) max(3rem, env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.4rem;
    background: color-mix(in srgb, var(--s0) 84%, transparent);
    backdrop-filter: saturate(160%) blur(28px);
    -webkit-backdrop-filter: saturate(160%) blur(28px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.45s var(--ease-spring), visibility 0s 0.45s;
  }
  .nav-links[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.45s var(--ease-spring), visibility 0s;
  }
  .nav-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: clamp(2.1rem, 9vw, 3rem);
    font-weight: 300;
    letter-spacing: -0.035em;
    line-height: 1.15;
    color: var(--bone);
    opacity: 0;
    translate: 0 2.5rem;
    transition: opacity 0.6s var(--ease-spring), translate 0.8s var(--ease-spring), color var(--d-hover) var(--ease-out);
  }
  .nav-links[data-open="true"] a { opacity: 1; translate: 0 0; }
  /* Each link rises a beat after the one above it. */
  .nav-links[data-open="true"] a:nth-child(1) { transition-delay: 70ms; }
  .nav-links[data-open="true"] a:nth-child(2) { transition-delay: 120ms; }
  .nav-links[data-open="true"] a:nth-child(3) { transition-delay: 170ms; }
  .nav-links[data-open="true"] a:nth-child(4) { transition-delay: 220ms; }
  .nav-links[data-open="true"] a:nth-child(5) { transition-delay: 290ms; }
  .nav-links a.cta { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; margin-top: 2rem; }
}

@media (max-height: 540px) and (max-width: 860px) {
  :root { --nav-pad: 0.75rem; }
  .nav-links { justify-content: flex-start; gap: 0.5rem; padding-top: calc(var(--nav-h) + 1rem); padding-bottom: 2rem; }
  .nav-links a { font-size: 1.75rem; }
  .nav-links a.cta { margin-top: 0.75rem; }
}

/* Mobile navigation uses flat, translucent surfaces above the scene. The
   selection moves on transform while the backdrop blur remains stationary. */
.mobile-dock { display: none; }
@media (max-width: 860px) {
  .has-mobile-dock { --dock-clearance: calc(5.75rem + env(safe-area-inset-bottom, 0px)); scroll-padding-bottom: var(--dock-clearance); }
  .has-mobile-dock body { padding-bottom: var(--dock-clearance); }
  .has-mobile-dock .nav-toggle, .has-mobile-dock .nav-links { display: none; }
  .has-mobile-dock .nav::before { display: none; }
  .mobile-dock {
    position: fixed; z-index: 850;
    left: 50%; bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
    translate: -50% 0;
    width: min(30rem, calc(100% - 20px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)));
    display: flex; align-items: center; gap: 8px;
  }
  .mobile-dock-nav, .mobile-dock-book {
    position: relative; isolation: isolate;
    border: 1px solid rgba(233, 229, 221, 0.1);
    background-color: rgba(16, 24, 31, 0.76);
    background-image: none;
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    box-shadow: none;
    border-radius: 999px;
  }
  .mobile-dock-nav {
    flex: 1; min-width: 0; padding: 4px;
    display: grid; grid-template-columns: repeat(var(--dock-count, 5), minmax(0, 1fr));
  }
  .mobile-dock-pill {
    position: absolute; z-index: -1; left: 4px; top: 4px; bottom: 4px;
    width: calc((100% - 8px) / var(--dock-count, 5)); border-radius: 999px;
    background: rgba(233, 229, 221, 0.12);
    box-shadow: none;
    transform: translateX(calc(var(--dock-index, 0) * 100%)); opacity: 0;
  }
  .mobile-dock-nav[data-active="true"] .mobile-dock-pill { opacity: 1; }
  .mobile-dock-nav[data-ready="true"] .mobile-dock-pill { transition: transform 260ms var(--ease-spring), opacity 180ms ease; }
  .mobile-dock-link {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-width: 0; min-height: 54px; border-radius: 999px;
    text-decoration: none; font-size: 0.6875rem; font-weight: 600; line-height: 1.2; letter-spacing: -0.015em;
    color: #C8CCD0; -webkit-tap-highlight-color: transparent;
    transition: color 180ms ease;
  }
  .mobile-dock-link svg { width: 20px; height: 20px; transition: scale 180ms var(--ease-spring), color 180ms ease; }
  .mobile-dock-link[data-selected="true"] { color: var(--bone); }
  .mobile-dock-link[data-selected="true"] svg { color: #7CE2DD; }
  .mobile-dock-link:active svg { scale: 0.9; }
  .mobile-dock-link:focus-visible { outline-offset: -2px; }
  .mobile-dock-book {
    display: flex; align-items: center; justify-content: center; flex: none;
    width: 60px; height: 60px; color: var(--s0); text-decoration: none;
    background-color: rgba(233, 229, 221, 0.88);
    border-color: transparent;
    transition: scale 180ms var(--ease-spring), background-color 180ms ease;
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-dock-book svg { width: 25px; height: 25px; stroke-width: 1.7; }
  .mobile-dock-book:active { scale: 0.93; }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mobile-dock-nav { background-color: #131B23; }
  .mobile-dock-book { background-color: var(--bone); }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .mobile-dock-nav { background: #131B23; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .mobile-dock-book { background: var(--bone); backdrop-filter: none; -webkit-backdrop-filter: none; }
}
@media (forced-colors: active) {
  .mobile-dock-nav, .mobile-dock-book { background: Canvas; color: CanvasText; border-color: ButtonText; box-shadow: none; }
  .mobile-dock-link, .mobile-dock-link[data-selected="true"], .mobile-dock-link[data-selected="true"] svg { color: LinkText; }
  .mobile-dock-pill { background: Canvas; border: 2px solid Highlight; box-shadow: none; }
}

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

/* The footer is where the page lands, not another section — so it is tight, and
   the page's own hero plate rises out of the bottom edge and dissolves upward
   into the black. Full-bleed: the wrap lives on the three children instead. */
.foot {
  position: relative; isolation: isolate;
  margin-top: clamp(3rem, 6vh, 4.5rem);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem) 1.1rem;
}
/* The plate reaches up past the footer into the dead space at the end of the
   page, so the page finishes on an image instead of on empty black. */
.foot::before,
.foot::after { content: ""; position: absolute; inset: -280px 0 0; pointer-events: none; }
.foot::before {
  z-index: -2;
  background: url("../img/plates/stillness.jpg") center bottom / cover no-repeat;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 46%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 46%);
  opacity: 0.62;
}
/* Ramps to near-solid before the columns start, so the type keeps its contrast
   ratios no matter which plate is behind it. */
.foot::after {
  z-index: -1;
  background: linear-gradient(to bottom,
    transparent 0%, rgba(5,7,11,0.18) 26%, rgba(5,7,11,0.72) 46%, rgba(5,7,11,0.95) 62%, rgba(5,7,11,0.97) 100%);
}
.foot[data-plate="lake"]::before      { background-image: url("../img/plates/lake.jpg"); }
.foot[data-plate="jetty"]::before     { background-image: url("../img/plates/jetty.jpg"); }
.foot[data-plate="sea"]::before       { background-image: url("../img/plates/sea.jpg"); }
.foot[data-plate="island"]::before    { background-image: url("../img/plates/island.jpg"); }
.foot[data-plate="shore"]::before     { background-image: url("../img/plates/shore.jpg"); }

.foot-mark, .foot-grid, .foot-base {
  max-width: var(--grid-max); margin-inline: auto; padding-inline: var(--gutter);
}
/* The mark signs off the page, centred above the columns. */
.foot-mark { display: block; margin-block: 0 clamp(2.4rem, 4.5vw, 3.6rem); }
.foot-mark .brand-mark { margin-inline: auto; translate: var(--stroke-offset) 0; }
.foot-mark img { height: clamp(88px, 9vw, 120px); width: auto; }
.foot-grid { display: grid; gap: 2rem; grid-template-columns: 1fr; }
@media (min-width: 780px) { .foot-grid { grid-template-columns: 1.4fr repeat(3, minmax(0,1fr)); gap: 2.25rem; } }
.foot .foot-h { font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--mute); font-weight: 400; margin: 0 0 1.1rem; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.foot a { color: var(--bone-dim); text-decoration: none; font-size: 0.9375rem; transition: color var(--d-hover) var(--ease-out); }
.foot a:hover { color: var(--bone); }
.foot a[aria-current="page"] { color: var(--bone); }
.foot .foot-line { color: var(--mute); font-size: 0.9375rem; max-inline-size: 30ch; margin: 0 0 1.2rem; }
.foot .foot-line .cta-ghost { color: var(--bone-dim); }
.foot .foot-dim { color: var(--mute); font-size: 0.9375rem; }
.foot-legal { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; }
.foot-legal a { font-size: 0.875rem; }
.foot-base {
  display: flex; flex-wrap: wrap; gap: 0.8rem 2rem; justify-content: space-between;
  margin-block: 1.75rem 0; padding-top: 1rem; border-top: 1px solid var(--line-soft);
  font-size: 0.8125rem; color: var(--mute);
}

/* ============================================================
   SECTION PATTERNS
   ============================================================ */

/* Asymmetric editorial split — the default interior layout. */
.split { display: grid; gap: clamp(2rem, 4vw, 5rem); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.9fr); align-items: end; }
}


/* Process — a real sequence, so numbering carries information. Each step is
   its own machined card with air between, not a cell of one ruled grid. */
.steps { display: grid; gap: clamp(1.1rem, 2vw, 1.6rem); margin-top: 3.25rem; }
@media (min-width: 800px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step {
  background: linear-gradient(180deg, var(--s1), var(--s0) 140%);
  border-radius: var(--radius-lg);
  box-shadow: var(--bezel);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}
.step .n { font-family: var(--mono); font-size: var(--t-label); color: var(--cyan); letter-spacing: var(--tr-label); }
.step h3 { font-size: var(--t-h3); font-weight: 300; letter-spacing: var(--tr-h3); margin: 1.1rem 0 0.7rem; line-height: 1.15; }
.step p { color: var(--bone-dim); margin: 0; font-size: 0.9375rem; line-height: 1.55; }

/* The whole offer as one scannable line. Nine cards with descriptions is
   reading; nine words at display size is understood at a glance. */
.every {
  list-style: none; margin: 3rem 0 0; padding: 0;
  display: grid; gap: 0.6em 1.4em;
  grid-template-columns: 1fr;
  font-size: clamp(1.35rem, 2.8vw, 2.1rem);
  font-weight: 300; letter-spacing: -0.03em; line-height: 1.2;
  color: var(--bone);
}
/* Fixed columns rather than wrapping: eight items divide evenly at every
   breakpoint, so no item is ever left stranded alone on a row. */
@media (min-width: 620px)  { .every { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .every { grid-template-columns: repeat(4, 1fr); } }
.every li { display: flex; align-items: baseline; gap: 0.5em; }
.every li::before {
  content: ""; flex: none;
  width: 0.19em; height: 0.19em; border-radius: 50%;
  background: var(--cyan); opacity: 0.75; translate: 0 -0.3em;
}

/* Capability grid — an unordered set, so no numbering. Same construction as
   .steps: separate machined cards with air between, not cells of a ruled grid. */
.cap { display: grid; gap: clamp(1rem, 1.8vw, 1.4rem); margin-top: 3.25rem; }
@media (min-width: 620px)  { .cap { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .cap { grid-template-columns: repeat(4, 1fr); } }
.cap div {
  background: linear-gradient(180deg, var(--s1), var(--s0) 140%);
  border-radius: 1.25rem;
  box-shadow: var(--bezel);
  padding: 1.8rem 1.6rem 2rem;
}
.cap h3 { font-size: 1.0625rem; font-weight: 600; margin: 0 0 0.6rem; letter-spacing: -0.012em; }
.cap p { margin: 0; color: var(--mute); font-size: 0.9375rem; line-height: 1.5; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 1000;
  background: var(--bone); color: var(--s0); padding: 0.8rem 1.2rem; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; }

/* ============================================================
   LIVE SITES — the showcase of work we built and still host
   ============================================================ */

.sites {
  display: grid;
  gap: clamp(0.9rem, 1.8vw, 1.6rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  margin-top: 3rem;
}

/* Double bezel: the button is the tray, the screenshot is the plate sitting in
   it, with its own concentric corners. */
.site {
  appearance: none;
  border: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--s1) 75%, transparent);
  border-radius: 1.4rem;
  overflow: hidden;
  padding: 6px;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  display: flex;
  flex-direction: column;
  box-shadow: var(--bezel-lift);
  transition:
    border-color var(--d-hover) var(--ease-out),
    background var(--d-hover) var(--ease-out),
    translate 0.6s var(--ease-spring);
}
.site:hover { border-color: var(--line); background: var(--s1); translate: 0 -4px; }
.site img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top center;
  background: var(--s2);
  border-radius: calc(1.4rem - 6px);
  transition: scale 0.8s var(--ease-spring);
}
.site:hover img { scale: 1.02; }
.site figcaption,
.site .cap-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.8rem; padding: 0.95rem 0.75rem 0.7rem;
}
.site .nm { font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.012em; }
.site .kind {
  font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--mute); white-space: nowrap;
}

/* ---- Lightbox ---- */
#siteview {
  border: 1px solid var(--line);
  background: var(--s1);
  color: var(--bone);
  border-radius: var(--radius-lg);
  box-shadow: var(--bezel-lift), 0 40px 100px -40px rgba(0, 0, 0, 0.9);
  padding: 0;
  width: min(1080px, calc(100vw - 2rem));
  max-width: none;
  max-height: 92svh;
  overflow: hidden;
}
#siteview::backdrop { background: rgba(5, 7, 11, 0.86); backdrop-filter: blur(6px); }
#siteview img { width: 100%; max-height: 68svh; object-fit: contain; background: var(--s0); display: block; }
.sv-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem 1.5rem; flex-wrap: wrap; padding: 1.1rem 1.4rem;
  border-top: 1px solid var(--line-soft);
}
.sv-meta h3 { margin: 0; font-size: 1.125rem; font-weight: 600; letter-spacing: -0.015em; }
.sv-meta p { margin: 0.35rem 0 0; color: var(--bone-dim); font-size: 0.9375rem; max-inline-size: 56ch; }
.sv-actions { display: flex; align-items: center; gap: 0.6rem; margin-left: auto; }
.sv-nav {
  appearance: none; background: none; border: 1px solid var(--line);
  color: var(--bone-dim); width: 38px; height: 38px; border-radius: 50%;
  cursor: pointer; font: inherit; font-size: 1rem; line-height: 1;
  transition: color var(--d-hover) var(--ease-out), border-color var(--d-hover) var(--ease-out), scale var(--d-press) var(--ease-spring);
}
.sv-nav:hover { color: var(--bone); border-color: var(--bone-dim); }
.sv-nav:active { scale: 0.94; }
.sv-visit {
  display: inline-flex; align-items: center; gap: 0.6em;
  background: var(--bone); color: var(--s0); text-decoration: none;
  font-size: 0.875rem; font-weight: 600; padding: 0.42em 0.42em 0.42em 1.15em; border-radius: 100px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transition: translate var(--d-hover) var(--ease-spring), scale var(--d-press) var(--ease-spring);
}
.sv-visit:hover { translate: 0 -1px; }
.sv-visit:active { scale: 0.98; }
/* Same button-in-button disc as .cta */
.sv-visit > span {
  display: inline-grid; place-items: center; width: 1.9em; height: 1.9em;
  border-radius: 50%; background: rgba(5, 7, 11, 0.075);
  transition: translate var(--d-hover) var(--ease-spring);
}
.sv-visit:hover > span { translate: 1px -1px; }

/* ============================================================
   WORK — shared by the home page stage and the work page. Data
   lives in assets/js/work.js; see tools/build-work.mjs.
   ============================================================ */

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- Discipline bar: sticks just under the nav capsule ---- */
.dbar {
  position: sticky; top: calc(var(--nav-h) - 0.2rem); z-index: 600;
  margin-top: clamp(1rem, 3vw, 2rem);
}
.dbar ul {
  list-style: none; margin: 0 auto; padding: 0.4rem;
  display: flex; gap: 0.25rem; overflow-x: auto; scrollbar-width: none;
  width: max-content; max-width: calc(100% - 2 * var(--gutter));
  border-radius: 100px; border: 1px solid var(--line);
  background: color-mix(in srgb, var(--s0) 78%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  box-shadow: var(--bezel-lift), 0 24px 48px -30px rgba(0, 0, 0, 0.9);
}
.dbar ul::-webkit-scrollbar { display: none; }
.dbar a {
  display: flex; align-items: baseline; gap: 0.5em; white-space: nowrap;
  padding: 0.5rem 0.95rem; border-radius: 100px;
  color: var(--mute); text-decoration: none; font-size: 0.9375rem;
  transition: color var(--d-hover) var(--ease-out), background var(--d-hover) var(--ease-out);
}
.dbar small { font-family: var(--mono); font-size: var(--t-label); letter-spacing: 0.08em; }
.dbar a:hover { color: var(--bone-dim); }
.dbar a[aria-current="true"] { color: var(--bone); background: var(--s2); box-shadow: var(--bezel-lift); }
.dbar a[aria-current="true"] small { color: var(--cyan); }

/* Anchors land below both the nav and the bar. */
.wsec { scroll-margin-top: calc(var(--nav-h) + 4rem); }
.sec-blurb { margin: 0.9rem 0 0; color: var(--bone-dim); max-inline-size: 52ch; }
.sub-h {
  margin: 2.6rem 0 0; font-family: var(--mono); font-size: var(--t-label); font-weight: 400;
  text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--mute);
}

/* ---- Work grid: uniform tiles, first one doubled for rhythm ---- */
.wgrid {
  list-style: none; padding: 0; margin: 2rem 0 0;
  display: grid; gap: clamp(0.6rem, 1.2vw, 1rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}
.wgrid li[hidden] { display: none; }
.wi {
  position: relative; display: block; overflow: hidden; height: 100%;
  border-radius: var(--radius); background: var(--s1);
  aspect-ratio: var(--r, 3 / 2);
}
@media (min-width: 760px) {
  .wgrid > li:first-child { grid-column: span 2; grid-row: span 2; }
}
.wi img { width: 100%; height: 100%; object-fit: cover; transition: scale 0.7s var(--ease-out); }
.wi[data-fit="contain"] img { object-fit: contain; }
.wi:hover img { scale: 1.035; }
.wcap {
  position: absolute; inset-inline: 0; bottom: 0; padding: 1.4rem 1rem 0.9rem;
  font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--bone); opacity: 0; translate: 0 6px;
  background: linear-gradient(to top, rgba(5,7,11,0.92), transparent);
  transition: opacity var(--d-hover) var(--ease-out), translate var(--d-hover) var(--ease-out);
}
.wi:hover .wcap, .wi:focus-visible .wcap { opacity: 1; translate: 0 0; }
@media (hover: none) { .wcap { opacity: 1; translate: 0 0; } }

.more {
  appearance: none; font: inherit; cursor: pointer;
  margin-top: 1.8rem; display: inline-flex; align-items: center; gap: 0.6em;
  padding: 0.7rem 1.25rem; border-radius: 100px;
  background: none; border: 1px solid var(--line); color: var(--bone); font-size: 0.9375rem;
  transition: border-color var(--d-hover) var(--ease-out), scale var(--d-press) var(--ease-spring);
}
.more:hover { border-color: color-mix(in srgb, var(--cyan) 50%, transparent); }
.more:active { scale: 0.98; }

/* ---- Video: one featured player, a grid that loads into it ---- */
.vfeature {
  margin-top: 2.2rem; padding: 10px; border-radius: var(--radius-lg);
  background: var(--s1); box-shadow: var(--bezel);
}
.player { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: calc(var(--radius-lg) - 10px); background: #000; }
.player img, .player iframe { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border: 0; }
.play { position: absolute; inset: 0; display: grid; place-items: center; color: var(--bone); text-decoration: none; }
.play > span[aria-hidden] {
  width: clamp(3.5rem, 7vw, 5.25rem); aspect-ratio: 1; display: grid; place-items: center; padding-left: 0.2em;
  border-radius: 50%; font-size: clamp(1rem, 1.6vw, 1.4rem);
  background: rgba(5, 7, 11, 0.55); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 0 1px rgba(233, 229, 221, 0.18);
  transition: scale var(--d-hover) var(--ease-spring);
}
.play:hover > span[aria-hidden] { scale: 1.08; }
.fmeta { display: flex; justify-content: space-between; align-items: baseline; gap: 0.4rem 1rem; flex-wrap: wrap; padding: 1rem 0.5rem 0.35rem; }
.fmeta h3 { flex: 1 1 auto; margin: 0; font-size: var(--t-h3); font-weight: 300; letter-spacing: var(--tr-h3); }
.fmeta .vout { font-size: 0.875rem; }
.fmeta p { margin: 0; font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--mute); }

.vgrid {
  list-style: none; padding: 0; margin: 1.6rem 0 0;
  display: grid; gap: 1.4rem 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}
.vc { display: block; color: inherit; text-decoration: none; }
.vc .th { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--radius); background: var(--s1); box-shadow: 0 0 0 1px var(--line-soft); }
.vc img { width: 100%; height: 100%; object-fit: cover; opacity: 0.84; transition: scale 0.7s var(--ease-out), opacity var(--d-hover) var(--ease-out); }
.vc:hover img { scale: 1.04; opacity: 1; }
.vc[aria-current="true"] .th { box-shadow: 0 0 0 2px var(--cyan); }
.vc[aria-current="true"] img { opacity: 1; }
.dur { position: absolute; right: 0.5rem; bottom: 0.5rem; padding: 0.2rem 0.45rem; border-radius: 4px; background: rgba(5,7,11,0.72); font-family: var(--mono); font-size: var(--t-label); }
.vc .nm { display: block; margin-top: 0.75rem; font-size: 1rem; line-height: 1.3; }
.vc .k { display: block; margin-top: 0.25rem; font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: 0.12em; color: var(--mute); }

/* Two up on a phone: one column of full-width art is a very long scroll. */
@media (max-width: 559px) {
  .wgrid, .vgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wgrid > li:first-child { grid-column: span 2; }
  .vc .nm { font-size: 0.875rem; }
  .vc .k { display: none; }
}

/* ---- Stage (home, 02): disciplines beside a board of real work ---- */
.stage { display: grid; gap: clamp(1.25rem, 3vw, 2.5rem); margin-top: clamp(2.5rem, 5vw, 3.75rem); }
@media (min-width: 900px) { .stage { grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.6fr); align-items: start; } }
.stage-tabs { display: grid; gap: 0.15rem; }
.stage-tabs [role="tab"] {
  appearance: none; border: 0; background: none; font: inherit; cursor: pointer; text-align: left;
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding: 0.85rem 1.1rem; border-radius: 0.9rem;
  /* Kay, Sep 2026: a few points smaller, so the work carries the section. 18 -> 24 */
  font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem); font-weight: 300; letter-spacing: var(--tr-h3); color: var(--mute);
  transition: color var(--d-hover) var(--ease-out), background var(--d-hover) var(--ease-out);
}
.stage-tabs small { font-family: var(--mono); font-size: var(--t-label); letter-spacing: 0.1em; }
.stage-tabs [role="tab"]:hover { color: var(--bone-dim); }
.stage-tabs [aria-selected="true"] { color: var(--bone); background: var(--s2); box-shadow: var(--bezel-lift); }
.stage-tabs [aria-selected="true"] small { color: var(--cyan); }
@media (max-width: 899px) {
  /* A swipeable pill row; bleeds to the screen edge so it reads as scrollable. */
  .stage-tabs {
    display: flex; gap: 0.4rem; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
  }
  .stage-tabs::-webkit-scrollbar { display: none; }
  .stage-tabs [role="tab"] {
    flex: none; font-size: 0.9375rem; letter-spacing: -0.01em; font-weight: 400;
    padding: 0.55rem 1rem; border-radius: 100px; border: 1px solid var(--line);
  }
  .stage-tabs [aria-selected="true"] { border-color: transparent; }
  .stage-tabs small { display: none; }
}

.stage-board { padding: 10px; border-radius: var(--radius-lg); background: var(--s1); box-shadow: var(--bezel); }
/* One piece at a time, whole, at its own proportions. Behind it a blurred,
   darkened copy of itself fills the frame, so a gold mark sits in gold and a
   dark site in dark, instead of every piece being cropped to the same box. */
.stage-reel {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: calc(var(--radius-lg) - 10px); background: var(--s2);
}
.stage-reel figure {
  position: absolute; inset: 0; margin: 0; display: grid; place-items: center;
  opacity: 0; transition: opacity 0.9s var(--ease-out);
}
.stage-reel figure[data-on] { opacity: 1; }
.stage-wash {
  position: absolute; inset: -8%; width: 116%; height: 116%; object-fit: cover;
  filter: blur(34px) saturate(1.15) brightness(0.72);
}
/* Marks and covers sit inset, at their own proportions — present, not huge. */
.stage-piece {
  position: absolute; inset: 7%; width: 86%; height: 86%;
  object-fit: contain; filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.4));
}
/* Screens, photos and films already fill a 16:10 frame; let them run edge to edge. */
.stage-reel[data-disc="web"] .stage-piece,
.stage-reel[data-disc="print"] .stage-piece,
.stage-reel[data-disc="video"] .stage-piece,
.stage-reel[data-disc="world"] .stage-piece { inset: 0; width: 100%; height: 100%; object-fit: cover; filter: none; }
.stage-reel figure[data-fit="contain"] .stage-piece { object-fit: contain; }
.stage-reel figcaption {
  position: absolute; left: 0.75rem; bottom: 0.7rem; padding: 0.3rem 0.6rem; border-radius: 100px;
  background: rgba(5, 7, 11, 0.62); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: 0.12em; color: var(--bone);
}
.stage-play {
  position: absolute; top: 0.75rem; right: 0.75rem; width: 2.25rem; height: 2.25rem; display: grid; place-items: center;
  border-radius: 50%; font-size: 0.75rem; padding-left: 0.12em; color: var(--bone);
  background: rgba(5, 7, 11, 0.55); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.stage-dots { display: flex; gap: 0.2rem; margin-left: auto; }
.stage-dots button {
  appearance: none; border: 0; background: none; cursor: pointer; padding: 0.6rem 0.3rem;
}
.stage-dots button::before {
  content: ""; display: block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--line); transition: background var(--d-hover) var(--ease-out);
}
.stage-dots button[aria-current="true"]::before { background: var(--cyan); }
.stage-foot { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.6rem 1.5rem; padding: 1rem 0.6rem 0.4rem; }
.stage-foot p { margin: 0; color: var(--bone-dim); font-size: 0.9375rem; max-inline-size: 46ch; }
@keyframes stage-in { from { opacity: 0; translate: 0 8px; } }

/* ---- Client voices: a quote beside the work it describes ---- */
.voices { margin-top: clamp(2.5rem, 5vw, 3.75rem); }
.voice { display: grid; gap: clamp(1.25rem, 3vw, 3rem); align-items: center; }
.voice + .voice { margin-top: 2.5rem; }
.voice[hidden] { display: none; }
@media (min-width: 820px) { .voice { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); } }
.voice-work { overflow: hidden; border-radius: var(--radius-lg); box-shadow: 0 0 0 7px var(--bezel-tray), 0 0 0 8px var(--bezel-edge); }
.voice-work img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; object-position: top center; }
.voice .pull { margin: 0; }
.voice:not([hidden]) { animation: stage-in 0.6s var(--ease-out) both; }
.voice-nav { display: flex; align-items: center; gap: 0.9rem; margin-top: 1.8rem; }
.voice-count { font-family: var(--mono); font-size: var(--t-label); letter-spacing: var(--tr-label); color: var(--mute); min-width: 3.5ch; text-align: center; }

/* ---- The team (home): three faces, the same people every month ---- */
.team { list-style: none; padding: 0; margin: clamp(2.5rem, 5vw, 3.5rem) 0 0; display: grid; gap: clamp(1rem, 2.5vw, 2rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.team li { display: grid; gap: 0.35rem; }
.team img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--radius); margin-bottom: 0.9rem; filter: grayscale(1) contrast(1.05); transition: filter 0.7s var(--ease-out); }
.team li:hover img { filter: none; }
.team strong { font-weight: 600; font-size: 1.125rem; letter-spacing: -0.015em; }
.team span { font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--mute); }
@media (max-width: 559px) {
  /* On a phone: compact rows, not three full-screen portraits. */
  .team { gap: 1.1rem; }
  .team li { grid-template-columns: 5.5rem 1fr; grid-template-rows: auto auto; column-gap: 1.1rem; row-gap: 0.25rem; align-items: end; }
  .team img { grid-row: span 2; aspect-ratio: 1; margin: 0; border-radius: 50%; filter: none; }
  .team span { align-self: start; }
}

/* Fine print under prices: legible, never hidden. */
.fine { margin: 1.4rem 0 0; font-size: 0.875rem; line-height: 1.55; color: var(--mute); max-inline-size: 72ch; }
.fine a { color: var(--bone-dim); }

/* Services: each discipline links to its proof. */
.disc { scroll-margin-top: calc(var(--nav-h) + 1rem); }
.disc-proof { margin: 1.4rem 0 0; }

/* ============================================================
   LEGAL PAGES — plain language, easy to scan, easy to print
   ============================================================ */
.legal { padding-block: 10rem var(--pad-md); }
.legal h2 { font-size: var(--t-h3); font-weight: 600; letter-spacing: -0.015em; margin: 3rem 0 1rem; scroll-margin-top: calc(var(--nav-h) + 1rem); }
.legal h3 { font-size: 1.0625rem; font-weight: 600; margin: 1.8rem 0 0.6rem; }
.legal p, .legal li, .legal td, .legal th { color: var(--bone-dim); max-inline-size: 66ch; }
.legal ul, .legal ol { padding-left: 1.2rem; display: grid; gap: 0.5rem; }
.legal a:not(.cta):not(.cta-ghost) { color: var(--bone); }
.legal .updated { font-family: var(--mono); font-size: var(--t-label); color: var(--mute); letter-spacing: var(--tr-label); text-transform: uppercase; margin-top: 2.5rem; }
.legal .toc { margin: 2.2rem 0 0; padding: 1.4rem 1.6rem; border-radius: var(--radius-lg); background: var(--s1); box-shadow: var(--bezel-lift); }
.legal .toc p { margin: 0 0 0.8rem; font-family: var(--mono); font-size: var(--t-label); text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--mute); }
.legal .toc ol { margin: 0; columns: 2 16rem; column-gap: 2rem; display: block; }
.legal .toc li { margin: 0 0 0.45rem; break-inside: avoid; }
.legal table { border-collapse: collapse; width: 100%; margin: 1rem 0 0; font-size: 0.9375rem; }
.legal th, .legal td { text-align: left; vertical-align: top; padding: 0.7rem 1rem 0.7rem 0; border-bottom: 1px solid var(--line-soft); }
.legal th { color: var(--bone); font-weight: 600; }
.legal .tbl { overflow-x: auto; }
@media print {
  .nav, .foot, .spine, .grain, .skip { display: none !important; }
  body { background: #fff !important; }
  .legal { padding: 0; }
  .legal p, .legal li, .legal td, .legal th, .legal h1, .legal h2, .legal h3 { color: #111 !important; }
}

/* ---- Touch and keyboard comfort ----
   Sticky chrome never hides the focused element or an anchor target, and on
   touch screens every small control grows to a 44px target. */
html { scroll-padding-top: calc(var(--nav-h) + 1rem); }
@media (pointer: coarse) {
  .nav-links a { display: inline-flex; align-items: center; min-height: 44px; }
  .sv-nav { width: 44px; height: 44px; }
  .dbar a, .stage-tabs [role="tab"] { min-height: 44px; align-items: center; }
  .stage-dots button { min-height: 44px; min-width: 32px; }
  .foot-legal a, .foot ul a { display: inline-block; padding-block: 0.3rem; }
}

/* ---- Work lightbox: same object as the site preview ---- */
.lb {
  border: 1px solid var(--line); background: var(--s1); color: var(--bone);
  border-radius: var(--radius-lg); padding: 0; overflow: hidden;
  box-shadow: var(--bezel-lift), 0 40px 100px -40px rgba(0, 0, 0, 0.9);
  width: min(1200px, calc(100vw - 2rem)); max-width: none; max-height: 94svh;
}
.lb::backdrop { background: rgba(5, 7, 11, 0.88); backdrop-filter: blur(6px); }
.lb img { display: block; width: 100%; height: min(78svh, 900px); object-fit: contain; background: var(--s0); }
.lb .sv-meta h3 { font-weight: 400; }
.lb .lb-close { font-size: 1.1rem; }
