/* Direction F — INK
   Fork of Direction E (Material v3): same skeleton, content, and motion system —
   the material language swapped from machined chrome to ink pressed into paper.

   — every display-type moment runs through a live SVG ink-bleed pipeline
     (warp → dilate → blur → alpha threshold → paper-tooth displacement);
     UI text stays crisp. Defs live inline in each page.
   — hero name set in Erode 700, soaks in wet on load (ink.js animates the
     #ink-reveal primitives; markup defaults are the settled state)
   — hero panel carries live ink: a GPU metaball field in the letters' own
     color, under the name — the cursor's drop, splashes and drips
   — plates go from engraved metal to letterpress: printed bone stat with a
     double-strike ghost, rust registration marks
   — warmer blacks, heavier grain, fixed vignette — the cinematic grade */

/* ---------- type scale: a major third (1.25), 16px base on phones, 18px from 900px ----------
   Every reading size is the base times a power of 1.25, rounded to whole pixels.
   The display tier (hero name, section heads, numerals) is fitted to the measure
   and stays fluid; leads and mid heads run fluid between two steps. */
:root {
  --t:16px;
  --t-2:12px;   /* labels, tags, keys (12px floor) */
  --t-1:15px;   /* nav, chips, meta, captions */
  --t0:16px;    /* base            reading */
  --t1:20px;    /* base * 1.25     deks, card titles */
  --t2:25px;    /* base * 1.25^2   leads, section sub-heads */
  --t3:31px;    /* base * 1.25^3 */
  --t4:39px;    /* base * 1.25^4 */
  --t5:49px;    /* base * 1.25^5 */
  --t6:61px;    /* base * 1.25^6 */
}
/* desktop: 18px base, the same steps, rounded to whole pixels */
/* a pixel that grows with big screens: 1px up to a 1600 screen, then in step with the
   frame (1440 to 1760) up to 1.22px. Figure caps use it so a case study keeps its
   1440 proportions on a wide monitor. Type does not. */
:root { --u:clamp(1px, .0625vw, 1.2222px); }
@media (min-width:900px) { :root { --t:18px; --t-2:13px; --t-1:16px; --t0:18px; --t1:23px; --t2:28px; --t3:35px; --t4:44px; --t5:55px; --t6:69px; } }
:root {
  --void:#0a0908; --panel:#131110; --panel-2:#181613;
  --bone:#edeae3; --dim:#8e8e96; --faint:#5b5b63; --faint-text:#7c7c86;
  --line:rgba(237,234,227,.10); --line-2:rgba(237,234,227,.06);
  --mint:#a8d5b5; --blue:#b9c4dd; --rust:#ec2222;
  --r:20px; --r-lg:28px;
  --ease:cubic-bezier(.22,1,.36,1);
  --serif:'Erode', Georgia, serif;
  /* one typeface: Erode carries every layer, SF Mono the labels */
  --font-body:var(--serif); --font-display:var(--serif);
  --font-mono:"SF Mono", ui-monospace, "JetBrains Mono", Menlo, monospace;
}

* { margin:0; padding:0; box-sizing:border-box; }
html { scroll-behavior:smooth; -webkit-font-smoothing:antialiased; }
body {
  background:var(--void); color:var(--bone);
  font-family:var(--serif); font-size:var(--t0); line-height:1.6;
  overflow-x:hidden;
}
::selection { background:var(--bone); color:var(--void); }
a { color:inherit; text-decoration:none; }
img { max-width:100%; display:block; }
section[id], .other[id] { scroll-margin-top:110px; }

.serif { font-family:var(--serif); font-weight:400; letter-spacing:0; }
.serif em, .serif i { font-style:italic; }
.mono { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--dim); }
/* Erode carries the reading voice and the interface layer */
.nav, .btn, .skip { font-family:var(--font-body); }

/* ---------- focus layer ---------- */
a:focus-visible, .card:focus-visible, .c-item:focus-visible, .skip:focus-visible {
  outline:2px solid var(--bone); outline-offset:3px; border-radius:inherit;
}
a:focus:not(:focus-visible) { outline:none; }
.nav a:focus-visible { color:var(--bone); }
.skip {
  position:fixed; top:22px; left:22px; z-index:90; padding:11px 16px;
  background:var(--bone); color:var(--void); border-radius:999px;
  font-size:var(--t-1); font-weight:700; transform:translateY(-200%);
}
.skip:focus { transform:none; }

/* ---------- view transitions (card → cover morph, persistent nav) ---------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .nav { view-transition-name: nav; }
  ::view-transition-old(root), ::view-transition-new(root) {
    animation-duration:.45s; animation-timing-function:var(--ease);
  }

  /* card to case study (vt.js names the ends): the card's panel travels and
     becomes the stage, its screen lifts out, straightens and lands in the
     stage, and the rest of the page swaps underneath */
  ::view-transition-group(cs-stage), ::view-transition-group(cs-frame) {
    animation-duration:.95s; animation-timing-function:cubic-bezier(.45,0,.12,1); }
  ::view-transition-group(cs-stage) { border-radius:18px; overflow:clip; }
  ::view-transition-old(cs-stage), ::view-transition-new(cs-stage) {
    width:100%; height:100%; object-fit:cover; object-position:50% 0; mix-blend-mode:normal; }
  ::view-transition-old(cs-stage) { animation:vt-out .4s linear .05s both; }
  ::view-transition-new(cs-stage) { animation:vt-in .45s linear .3s both; }
  /* the screen dissolves once, near where it lands: new over old, never both half there */
  ::view-transition-old(cs-frame) { animation:vt-out .2s linear .5s both; mix-blend-mode:normal; }
  ::view-transition-new(cs-frame) { animation:vt-in .28s linear .36s both; mix-blend-mode:normal; }
  :root.vt-card::view-transition-old(root) { animation:vt-sink .38s cubic-bezier(.5,0,.75,0) both; }
  :root.vt-card::view-transition-new(root) { animation:vt-in .5s linear .3s both; }
  /* opening the card: the panel fills the window, the screen straightens in the
     middle and lets go of its crop, then both give way to the case study */
  :root.vt-open::view-transition-group(cs-stage) { background:#0e0d0b;
    animation:vt-cover .72s cubic-bezier(.65,0,.2,1) both, vt-out .34s linear .66s both; }
  :root.vt-open::view-transition-group(cs-frame) { animation:vt-lift .78s cubic-bezier(.65,0,.2,1) both; }
  /* the card's picture goes dark as it opens, so a bright card never floods the window */
  :root.vt-open::view-transition-old(cs-stage) { animation:vt-out .4s linear .28s both; }
  :root.vt-open::view-transition-old(cs-frame) { animation:vt-uncrop .6s cubic-bezier(.65,0,.2,1) both, vt-lift-off .3s cubic-bezier(.5,0,.75,0) .6s both; }
  :root.vt-open::view-transition-new(root) { animation:vt-in .42s linear .74s both; }
  /* phones: a wide card can't fill a tall screen without blowing its snapshot
     up, so the panel grows around the card image, which keeps its own size */
  @media (max-width:899px) {
    :root.vt-open::view-transition-old(cs-stage) { object-fit:none; object-position:50% 50%; animation:vt-out .36s linear .52s both; }
  }
  /* the stage arrives by the transition, so it skips its own entrance */
  .vt-arrive .sc-hero.rise { animation:none; }
}
@keyframes vt-out { to { opacity:0; } }
@keyframes vt-in { from { opacity:0; } }
@keyframes vt-lift-off { to { opacity:0; transform:translateY(-18px) scale(.985); } }
@keyframes vt-sink { to { opacity:0; transform:translateY(-14px) scale(.99); } }

/* ---------- atmosphere ---------- */
.grain {
  position:fixed; inset:-120px; z-index:70; pointer-events:none; opacity:.34; will-change:transform;
  background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="280" height="280"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" stitchTiles="stitch"/><feColorMatrix values="0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.45 0"/></filter><rect width="280" height="280" filter="url(%23n)"/></svg>');
  animation:grain 5s steps(5) infinite;
}
@keyframes grain {
  0%,100% { transform:translate3d(0,0,0); } 20% { transform:translate3d(70px,45px,0); }
  40% { transform:translate3d(-40px,90px,0); } 60% { transform:translate3d(110px,-30px,0); }
  80% { transform:translate3d(-70px,-60px,0); }
}
.glow {
  position:fixed; left:0; top:0; width:64vw; height:64vw; z-index:0; pointer-events:none;
  border-radius:50%; filter:blur(46px);
  background:radial-gradient(circle, rgba(237,234,227,.055) 0%, transparent 62%);
  transform:translate(calc(72vw - 32vw), calc(12vh - 32vw));
  will-change:transform;
}
/* cinematic vignette — corners fall away like a projected frame */
body::after {
  content:''; position:fixed; inset:0; z-index:69; pointer-events:none;
  background:radial-gradient(130% 105% at 50% 42%, transparent 52%, rgba(0,0,0,.42) 100%);
}

/* ---------- entrance choreography (all pages) ---------- */
.js .rise { animation:riseIn .9s var(--ease) both; }
.js .rise.d1 { animation-delay:.09s; }
.js .rise.d2 { animation-delay:.18s; }
.js .rise.d3 { animation-delay:.27s; }
.js .rise.d4 { animation-delay:.44s; }
@keyframes riseIn {
  from { opacity:0; transform:translateY(46px); }
  to   { opacity:1; transform:none; }
}

/* nav: see "nav — three floating tiles" near the end */

/* ---------- layout ---------- */
/* 1440 up to a 1600 screen, then it grows with the screen to 1760, so big monitors
   get a bigger frame with no jump at a breakpoint. Text keeps its measure in ch. */
.wrap { position:relative; z-index:1; max-width:calc(1440 * var(--u)); margin:0 auto; padding:0 clamp(18px,3.4vw,48px); }
.pad { padding-top:104px; }
section { margin-bottom:clamp(90px,11vw,170px); }

.sec-head {
  display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:18px;
  border-top:1px solid var(--line); padding-top:22px; margin-bottom:clamp(28px,4vw,52px);
}
.sec-head h2 {
  font-family:var(--serif); font-weight:700;
  font-size:clamp(44px,6vw,84px); line-height:1.0; letter-spacing:-.01em;
  text-wrap:balance;
}
.sec-head h2 em {
  font-family:var(--serif); font-style:italic; font-weight:400;
  letter-spacing:0; font-size:1.05em;
}

/* ---------- hero — the whole header is the ink story ---------- */
.hero { margin-bottom:clamp(70px,8vw,120px); }
.hero--full {
  position:relative; isolation:isolate; border-radius:var(--r-lg); overflow:hidden;
  min-height:min(calc(100svh - 126px), 1080px);
  display:flex; flex-direction:column; justify-content:space-between;
  gap:clamp(18px,2.6vw,30px);
  padding:clamp(20px,3vw,42px);
  background:
    repeating-linear-gradient(0deg, rgba(237,234,227,.016) 0 1px, transparent 1px 3px),
    radial-gradient(120% 90% at 20% -5%, rgba(237,234,227,.05), transparent 55%),
    linear-gradient(165deg, #15130f 0%, #0e0d0b 55%, #0a0908 100%);
}
.hero--full::before {
  content:''; position:absolute; inset:0; z-index:1; opacity:0; transition:opacity 1.6s linear;
  background:
    radial-gradient(38% 52% at 70% 30%, rgba(237,234,227,.14), transparent 70%),
    radial-gradient(24% 34% at 30% 74%, rgba(237,234,227,.08), transparent 70%),
    radial-gradient(16% 24% at 85% 66%, rgba(237,234,227,.07), transparent 70%);
}
.hero--full.live::before { opacity:.3; }
.hero--full::after {
  content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(to top, rgba(10,9,8,.78) 0%, rgba(10,9,8,.1) 30%, rgba(10,9,8,.08) 62%, rgba(10,9,8,.45) 100%);
}
.hero--full > * { position:relative; z-index:2; }
/* above the panel's shade, under the words: the ink is the letters' own color */
.hero--full .ink-canvas { z-index:2; }
.hero--full .hero-meta { margin-bottom:0; }
.hero--full .hero-name { margin:0 0 0 -.02em; }
.hero--full .fig { position:absolute; right:clamp(18px,2.6vw,34px); top:clamp(88px,13vh,150px); z-index:2; }
.hero--full .hp-foot { display:flex; align-items:flex-end; justify-content:space-between; gap:26px; }
.hero-meta { display:flex; justify-content:space-between; gap:16px; margin-bottom:clamp(24px,3vw,44px); flex-wrap:wrap; }
.hero-meta a { padding:12px 0; margin:-12px 0; }
.hero-meta a:hover { color:var(--bone); }

/* the whole name is ONE pressed line — AJ HARRIS edge-to-edge, one size, so
   the lockup can't sit unbalanced. ink.js fits it to the measure exactly;
   the clamp is the no-JS fallback. */
.hero-name {
  position:relative; z-index:2;
  font-family:var(--serif); font-weight:700; letter-spacing:-.015em; line-height:.86;
  font-size:clamp(46px,15.4vw,230px); text-transform:uppercase;
  margin:0 0 -.08em -.02em;
}
.hero-name .line { display:block; }
.hero-name .sp { display:inline-block; width:.26em; }
.hero-name .lm { display:inline-block; }

/* the ink (ink.js): a drop on the pointer, drawn on the GPU in the letters'
   own color, under the name. Fine pointers only. */
.ink-canvas {
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; opacity:0; transition:opacity 1.6s linear;
}
.hero--full.live .ink-canvas { opacity:1; }
@media (pointer: coarse) { .ink-canvas { display:none; } }

.fig { color:rgba(237,234,227,.78); }
.hero-line {
  font-family:var(--serif); font-weight:400;
  font-size:clamp(var(--t2),2.6vw,var(--t3)); line-height:1.18; max-width:24ch;
  text-wrap:balance;
  text-shadow:0 1px 4px rgba(10,9,8,.7), 0 2px 22px rgba(10,9,8,.85);
}
.hero-line em { font-style:italic; }
.hero-facts { display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; }

.chip {
  display:inline-flex; align-items:center; gap:8px; white-space:nowrap;
  font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase;
  color:var(--bone); padding:9px 15px; border-radius:999px;
  border:1px solid rgba(237,234,227,.22); background:rgba(8,8,10,.5);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
}

.btn {
  display:inline-flex; align-items:center; gap:10px; white-space:nowrap;
  background:var(--bone); color:var(--void); font-weight:700; font-size:var(--t-1);
  padding:14px 22px; border-radius:999px;
  transition:color .45s cubic-bezier(.16,1,.3,1);
}
.btn .go-arr { display:inline-block; transition:transform .4s var(--ease); }

/* ---------- work cards ---------- */
.grid {
  display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
  gap:clamp(16px,2vw,26px); padding-bottom:30px; align-items:start;
}
.card {
  --mx:50%; --my:50%;
  position:relative; display:block; border-radius:var(--r-lg); overflow:hidden; overflow:clip;
  background:var(--panel); border:1px solid var(--line-2);
  transition:transform .55s var(--ease), border-color .4s linear;
}
.card--wide { grid-column:1 / -1; }
.card:hover, .card:focus-visible { transform:translateY(-8px); border-color:var(--line); }
/* the corner arrow is a blot that blooms — same mark the spine leaves at a chapter */
.card .go {
  position:absolute; top:16px; right:16px; z-index:2;
  width:46px; height:46px; display:grid; place-items:center;
  background:var(--bone);
  border-radius:52% 48% 45% 55% / 50% 57% 43% 50%;
  opacity:0; transform:scale(.2) rotate(-14deg);
  transition:opacity .3s linear, transform .55s var(--ease);
  filter:url(#ink-lg);
}
.card:hover .go, .card:focus-visible .go { opacity:1; transform:scale(1) rotate(0deg); }
.card .go svg { width:16px; height:16px; stroke:var(--void); }

/* clip, not hidden: hidden makes the card a scroll container, and the mockup drift
   (card-drift) would then follow a box that never scrolls instead of the page */
.card-media { position:relative; aspect-ratio:4/2.9; overflow:hidden; overflow:clip; background:var(--panel-2); }
.card--wide .card-media { aspect-ratio:21/8; }
.card-media::after { content:''; position:absolute; inset:0; z-index:1; pointer-events:none; background:var(--grain) 0 0 / 220px 220px, radial-gradient(80% 60% at 50% 110%, rgba(0,0,0,.45), transparent 70%); opacity:.28; mix-blend-mode:screen; }
.card-media .ph { z-index:2; }
.card-media > img {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:saturate(.82); transform:scale(1.05);
  transition:transform 1.4s var(--ease);
}
.card:hover .card-media > img { transform:scale(1.11); }

.device {
  position:absolute; left:13%; right:13%; bottom:-2px; height:66%;
  background:rgba(10,10,13,.92); border:1px solid rgba(237,234,227,.16); border-bottom:0;
  border-radius:14px 14px 0 0; box-shadow:0 30px 70px rgba(0,0,0,.55);
  transition:transform .9s var(--ease);
}
.card--wide .device { left:8%; right:8%; height:80%; }
.card:hover .device { transform:translateY(-10px); }
.device .bar { height:24px; display:flex; align-items:center; gap:5px; padding:0 11px; border-bottom:1px solid rgba(237,234,227,.08); }
.device .bar i { width:6px; height:6px; border-radius:50%; background:rgba(237,234,227,.2); }
.device .screen { padding:13px; display:flex; flex-direction:column; gap:9px; }
.device .screen b { height:8px; border-radius:4px; background:rgba(237,234,227,.12); width:72%; }
.device .screen b:nth-child(2) { width:46%; opacity:.7; }
.device .screen b:nth-child(3) { width:60%; opacity:.45; }
.device .screen .row { display:flex; gap:9px; }
.device .screen .row i { flex:1; height:36px; border-radius:7px; background:rgba(237,234,227,.06); border:1px solid rgba(237,234,227,.05); }
.device .screen .shot { width:100%; height:100%; object-fit:cover; object-position:top; filter:saturate(.72); }
.device:has(.shot) .screen, .device .screen:has(.shot) { padding:0; }
.device.phone { left:33%; right:33%; height:74%; border-radius:20px 20px 0 0; }
.card--wide .device.phone { left:38%; right:38%; height:82%; }
.device.phone .bar { justify-content:center; }
.device.phone .bar i { width:30px; height:4px; border-radius:2px; }

/* richer skeleton product UI inside the devices (until real screens land) */
.device { overflow:hidden; }
.screen.ui { flex-direction:row; gap:11px; height:calc(100% - 24px); }
.s-side { width:21%; display:flex; flex-direction:column; gap:8px; padding-top:3px; }
.s-side i { height:7px; border-radius:4px; background:rgba(237,234,227,.08); width:86%; }
.s-side i.on { background:rgba(237,234,227,.24); }
.s-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:10px; }
.s-t { height:9px; width:38%; border-radius:4px; background:rgba(237,234,227,.17); }
.s-stats { display:flex; gap:8px; }
.s-stats i { flex:1; height:26px; border-radius:6px; background:rgba(237,234,227,.06); border:1px solid rgba(237,234,227,.07); }
.screen.pui { flex-direction:column; gap:9px; height:calc(100% - 24px); }
.screen.pui .s-t { width:52%; }
.screen.pui .s-stats i { height:30px; }
.s-list { flex:1; display:flex; flex-direction:column; gap:7px; min-height:0; }
.s-list i { height:22px; flex:none; border-radius:6px; background:rgba(237,234,227,.06); border:1px solid rgba(237,234,227,.05); }
.s-tab { display:flex; gap:6px; margin-top:auto; }
.s-tab i { flex:1; height:5px; border-radius:3px; background:rgba(237,234,227,.08); }
.s-tab i.on { background:rgba(237,234,227,.26); }

.card-body { padding:clamp(18px,2vw,28px); }
.card--wide .card-body { display:grid; grid-template-columns:1fr auto; gap:24px; align-items:end; }
.card--wide .card-body .outcomes { justify-content:flex-end; }
/* card credits: one mono line, like the credits on a record sleeve, no pills */
.tags { display:flex; flex-wrap:wrap; gap:4px 0; margin-bottom:16px; }
.tag {
  font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase;
  color:var(--dim); white-space:nowrap;
}
.tag:not(:last-child)::after { content:'·'; margin:0 .8em; color:var(--faint-text); }
.tag.shipped { color:var(--mint); }
.card-body h3 { font-weight:700; font-size:var(--t1); letter-spacing:-.015em; margin-bottom:8px; text-wrap:balance; }
.card--wide .card-body h3 { font-size:clamp(var(--t2),2.6vw,var(--t3)); }
.card-body p { color:var(--dim); font-size:var(--t0); line-height:1.5; max-width:52ch; margin-bottom:18px; text-wrap:pretty; }
.card--wide .card-body p { max-width:60ch; margin-bottom:0; }
.outcomes { display:flex; flex-wrap:wrap; align-items:center; gap:7px; }
.outcome {
  font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em;
  color:var(--bone); background:var(--panel-2); border:1px solid var(--line);
  border-radius:999px; padding:6px 12px;
}
.outcome.year { color:var(--faint-text); background:transparent; border:0; padding:0; text-transform:uppercase; }

/* ---------- how i work ---------- */
.approach { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:clamp(14px,1.6vw,22px); }
.acard {
  --mx:50%; --my:50%;
  position:relative; overflow:hidden; border-radius:var(--r);
  background:var(--panel); border:1px solid var(--line-2);
  padding:clamp(22px,2vw,30px); padding-top:clamp(64px,5.4vw,84px); min-height:270px;
  transition:border-color .4s linear, background .4s linear; will-change:transform;
}
.acard:hover { border-color:var(--line); background:var(--panel-2); }
.acard::after {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(420px circle at var(--mx) var(--my), rgba(237,234,227,.06), transparent 45%);
  opacity:0; transition:opacity .45s linear;
}
.acard:hover::after { opacity:1; }
.acard .idx {
  position:absolute; top:-30px; right:2px;
  font-family:var(--serif); font-style:italic; font-size:clamp(96px,9vw,140px); line-height:1;
  color:rgba(237,234,227,.055); transition:color .6s linear, transform .8s var(--ease);
}
.acard:hover .idx { color:rgba(237,234,227,.12); transform:translateY(-6px); }
.acard h3 { font-family:var(--font-body); font-weight:500; font-size:var(--t1); letter-spacing:-.01em; margin-bottom:10px; }
.acard p { color:var(--dim); font-size:var(--t0); line-height:1.5; text-wrap:pretty; }
.acard .rcpt { display:block; margin-top:14px; font-size:var(--t-2); color:var(--faint-text); letter-spacing:.12em; }

/* ---------- about ---------- */
.about-lede {
  font-family:var(--serif); font-weight:400;
  font-size:clamp(var(--t2),3vw,var(--t4)); line-height:1.22; letter-spacing:-.005em;
  max-width:30ch; margin-bottom:clamp(30px,4vw,52px); text-wrap:balance;
}
.about-lede em { font-style:italic; }
/* the words light as the paragraph enters the reading zone. Unlit words are a
   readable gray, not a ghost: the copy passes contrast before it lights. */
.about-lede em { filter:url(#ink-lg); } /* story.js soaks it in from wet the first time it's seen */
.about-body { max-width:60ch; margin-left:clamp(0px,24vw,340px); }
.about-body p { color:var(--dim); font-size:var(--t0); margin-bottom:18px; text-wrap:pretty; }
.about-body b { color:var(--bone); font-weight:600; }
.about-row { display:grid; grid-template-columns:clamp(0px,24vw,340px) minmax(0,60ch) clamp(32px,4.5vw,64px) clamp(150px,17vw,240px); align-items:start; }
.about-row .about-body { margin-left:0; grid-column:2; grid-row:1; }
.about-row .about-photo { grid-column:4; grid-row:1; }
.about-photo { position:relative; margin:6px 0 0; width:100%; aspect-ratio:2/3; border-radius:14px; background:var(--panel); }
.about-photo img { border-radius:14px; width:100%; height:100%; object-fit:cover; object-position:50% 22%; display:block; filter:saturate(.8) contrast(1.02); transition:filter .5s ease; }
.about-photo:hover img { filter:none; }
@media (max-width:1100px) { .about-row { grid-template-columns:clamp(0px,12vw,180px) minmax(0,1fr) 36px 170px; } }
@media (max-width:860px) { .about-row { grid-template-columns:1fr; } .about-row .about-body, .about-row .about-photo { grid-column:1; grid-row:auto; } .about-row .about-photo { width:200px; margin:0 0 24px; } }

/* experience index */
.xp { border-top:1px solid var(--line); margin-top:clamp(36px,5vw,60px); }
.xp-item {
  display:grid; grid-template-columns:110px 1fr auto; align-items:baseline; gap:20px;
  border-bottom:1px solid var(--line); padding:22px 8px;
}
.xp-item .co { color:var(--bone); font-weight:600; font-size:var(--t0); }
.xp-item .role { color:var(--dim); font-size:var(--t-1); text-align:right; }

/* ---------- contact strip ---------- */
.strip {
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  padding:clamp(46px,6.5vw,100px) clamp(24px,4.5vw,72px);
  border:1px solid var(--line-2);
}
.strip .bg { position:absolute; inset:0; }
.strip .bg img { position:absolute; inset:0; width:100%; height:112%; object-fit:cover; opacity:.6; filter:saturate(.75); will-change:transform; }
.strip .bg::after { content:''; position:absolute; inset:0; background:linear-gradient(115deg, rgba(8,8,10,.82) 25%, rgba(8,8,10,.3) 100%); }
.strip > *:not(.bg) { position:relative; z-index:1; }
.strip .fig { position:absolute; top:20px; right:24px; z-index:2; }
.strip h2 { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t2),3vw,var(--t4)); line-height:1.18; margin-bottom:clamp(22px,3vw,38px); max-width:30ch; text-wrap:balance; }
.strip h2 em { font-style:italic; }
.strip .em {
  display:inline-block; font-weight:900; letter-spacing:-.035em; line-height:1.1;
  font-size:clamp(19px,7vw,96px); white-space:nowrap;
  border-bottom:3px solid rgba(237,234,227,.25);
  transition:border-color .3s linear;
}
/* hover speaks ink (drawn stroke + blot below) — the printed rule stays put */
.strip .sub { margin-top:26px; color:var(--dim); font-size:var(--t0); line-height:1.5; }
.strip .sub a { border-bottom:1px solid var(--line); transition:color .3s linear; }
.strip .sub a:hover { color:var(--bone); }

footer {
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap;
  border-top:1px solid var(--line-2); padding:26px 0 34px;
}
footer b { color:var(--bone); font-weight:600; }
footer .clock { color:var(--faint-text); font-variant-numeric:tabular-nums; }
footer .f-links a { border-bottom:1px solid var(--line); transition:color .3s linear; }
footer .f-links a:hover { color:var(--bone); }

/* ---------- case study ---------- */
.cs-head { max-width:1100px; margin-bottom:clamp(36px,5vw,64px); }
.cs-kicker { display:flex; gap:4px 0; align-items:center; margin-bottom:22px; flex-wrap:wrap; }
.cs-title {
  font-family:var(--serif); font-weight:400;
  font-size:clamp(40px,6.2vw,92px); line-height:1.04; letter-spacing:-.01em;
  text-wrap:balance;
}
.cs-title em { font-style:italic; }
.cs-head .outcomes { margin-top:26px; }
.cover { position:relative; border-radius:var(--r-lg); overflow:hidden; height:clamp(300px,54vh,560px); margin-bottom:clamp(40px,5vw,70px); }
.cover img { position:absolute; inset:0; width:100%; height:118%; object-fit:cover; filter:saturate(.8); will-change:transform; }
.cover::after { content:''; position:absolute; inset:0; background:linear-gradient(to top, rgba(8,8,10,.55), transparent 55%); }
.cover .fig { position:absolute; top:20px; right:24px; z-index:2; }

/* letterpress specimen plates — custom case covers, no stock imagery.
   Dark paper built from gradients; the stat is printed in bone ink with a
   double-strike ghost, corners carry rust registration marks. */
.plate {
  position:relative; border-radius:var(--r-lg); overflow:hidden;
  height:clamp(300px,54vh,560px); margin-bottom:clamp(40px,5vw,70px);
  background:
    radial-gradient(120% 90% at 18% -4%, rgba(237,234,227,.07), transparent 55%),
    radial-gradient(90% 80% at 86% 112%, rgba(236,34,34,.05), transparent 60%),
    linear-gradient(165deg, #15130f 0%, #100f0c 48%, #0a0908 100%);
  border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(237,234,227,.09), inset 0 -60px 120px rgba(0,0,0,.42);
}
.plate::before {
  content:''; position:absolute; inset:0; opacity:.8; pointer-events:none;
  background:
    repeating-linear-gradient(0deg, rgba(237,234,227,.018) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(237,234,227,.012) 0 1px, transparent 1px 6px);
}
.plate .p-c { position:absolute; inset:16px; pointer-events:none; z-index:1; }
.plate .p-c i { position:absolute; width:14px; height:14px; border:0 solid rgba(236,34,34,.65); }
.plate .p-c i:nth-child(1) { top:0; left:0; border-top-width:1px; border-left-width:1px; }
.plate .p-c i:nth-child(2) { top:0; right:0; border-top-width:1px; border-right-width:1px; }
.plate .p-c i:nth-child(3) { bottom:0; left:0; border-bottom-width:1px; border-left-width:1px; }
.plate .p-c i:nth-child(4) { bottom:0; right:0; border-bottom-width:1px; border-right-width:1px; }
.plate .fig { position:absolute; top:20px; right:24px; z-index:2; }
.plate .p-meta { position:absolute; top:20px; left:24px; z-index:2; color:var(--dim); }
.plate .p-stat {
  position:absolute; left:clamp(18px,3vw,44px); bottom:clamp(0px,1vw,10px); z-index:1;
  font-family:var(--serif); font-weight:700; letter-spacing:-.02em; line-height:.95;
  font-size:clamp(110px,21vw,320px); white-space:nowrap;
  color:rgba(237,234,227,.9);
  text-shadow:.05em .035em 0 rgba(237,234,227,.13); /* double-strike ghost */
}
.plate .p-stat em { font-family:var(--serif); font-style:italic; font-weight:400; letter-spacing:0; font-size:.9em; }
.plate .p-sub {
  position:absolute; right:24px; bottom:24px; z-index:2; max-width:34ch; text-align:right;
  color:var(--faint-text); line-height:1.7;
}
@media (max-width:700px) {
  .plate .p-sub { left:24px; right:24px; text-align:left; max-width:none; bottom:18px; }
  .plate .p-stat { bottom:clamp(44px,15vw,80px); }
}

.meta {
  display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:18px;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  padding:26px 0; margin-bottom:clamp(56px,7vw,100px);
}
.meta div span { display:block; }
.meta .k { margin-bottom:8px; }
.meta .v { font-size:var(--t0); color:var(--bone); }

.cs-sec { display:grid; grid-template-columns:200px 1fr; gap:clamp(24px,4vw,64px); margin-bottom:clamp(60px,7vw,100px); }
.cs-sec .lab { position:sticky; top:110px; align-self:start; }
.cs-sec h2 { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t2),2.6vw,var(--t3)); margin-bottom:16px; text-wrap:balance; }
.cs-sec p { color:var(--dim); font-size:var(--t0); max-width:64ch; margin-bottom:16px; text-wrap:pretty; }
.cs-sec b { color:var(--bone); font-weight:600; }
.cs-fig { position:relative; border-radius:var(--r); overflow:hidden; margin:26px 0 8px; background:var(--panel); aspect-ratio:7/5; }
.cs-fig img { width:100%; height:100%; object-fit:cover; filter:saturate(.8); }
.cs-fig figcaption { position:absolute; top:14px; right:16px; color:rgba(237,234,227,.78); z-index:2; text-align:right; }
.cs-fig::after { content:''; position:absolute; inset:0; background:linear-gradient(to bottom, rgba(8,8,10,.45), transparent 40%); }

.pull {
  font-family:var(--serif); font-style:italic; font-weight:400;
  font-size:clamp(var(--t2),3vw,var(--t4)); line-height:1.22; max-width:28ch;
  border-left:2px solid rgba(237,234,227,.25); padding-left:clamp(18px,2.5vw,36px);
  margin:clamp(40px,5vw,70px) 0; text-wrap:balance;
}
.next {
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  border-top:1px solid var(--line); padding-top:34px;
}
.next a { font-family:var(--serif); font-weight:700; letter-spacing:-.01em; font-size:clamp(var(--t2),3.4vw,var(--t5)); display:inline-flex; align-items:baseline; flex-wrap:wrap; gap:18px; }
.next a em { font-style:italic; font-weight:400; letter-spacing:0; font-size:1.02em; }
.next a .go-arr { display:inline-block; transition:transform .4s var(--ease); }
.next a:hover .go-arr, .next a:focus-visible .go-arr { transform:translateX(12px); }

/* ---------- contact page ---------- */
.c-h1 {
  font-family:var(--serif); font-weight:400;
  font-size:clamp(38px,5.6vw,84px); line-height:1.08; max-width:20ch;
  margin-bottom:clamp(44px,6vw,80px); text-wrap:balance;
}
.c-h1 em { font-style:italic; }
.c-list { border-top:1px solid var(--line); margin-bottom:clamp(60px,8vw,110px); }
.c-item {
  display:grid; grid-template-columns:200px 1fr auto; align-items:center; gap:20px;
  border-bottom:1px solid var(--line); padding:clamp(22px,3vw,36px) 8px;
  transition:background .35s linear;
}
.c-item > * { transition:transform .5s var(--ease); }
.c-item:hover, .c-item:focus-visible { background:rgba(237,234,227,.03); }
.c-item:hover > *, .c-item:focus-visible > * { transform:translateX(14px); }
.c-item .v { font-weight:700; font-size:clamp(var(--t1),2.4vw,var(--t3)); letter-spacing:-.015em; position:relative; }
.c-item .arr { opacity:0; transform:translateX(-8px); transition:opacity .35s linear, transform .5s var(--ease); }
.c-item:hover .arr, .c-item:focus-visible .arr { opacity:1; transform:translateX(6px); }
.c-item .arr svg { width:22px; height:22px; stroke:var(--bone); }

/* ---------- drawn glyphs ----------
   The site writes its arrows rather than importing them. Erode has no arrow
   glyphs, so a typed → or ↗ silently fell back to another font: a thin wiry
   hairline next to heavy serif text, in a vocabulary nothing else on the page
   shared. These are the same hand as .hand-path (1.7 round stroke through
   #ink-line) with no draw-on dash, because they sit inline in link text and
   have to be there on first paint. Sized in em so they track the type. */
.gl { width:1em; height:1em; vertical-align:-.13em; flex:none; overflow:visible; }
/* #ink-line is tuned for long drawn strokes; on a 1em glyph its displacement is
   proportionally huge and the arrow frays into pieces. #ink-glyph is the same
   hand at a quarter of the push, and the stroke runs a little heavier so it
   holds up next to the serif at text size. */
.gl path { fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; filter:url(#ink-glyph); }
.sc-arrow .gl path { stroke-width:1.5; }
a .gl, .sc-lbl a .gl, .sc-open .gl { margin-left:.34em; }
.sc-arrow .gl { width:1.4em; height:1.4em; margin:0; }
.c-item .arr .gl { width:22px; height:22px; }
.card .go .gl { width:16px; height:16px; }
.card .go .gl path { stroke:var(--void); }

/* ---------- pressed-paper surface — shared by card media, strips, figure plates ---------- */
:root { --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.press {
  background:
    radial-gradient(130% 110% at 50% 50%, transparent 52%, rgba(0,0,0,.42) 100%),
    radial-gradient(60% 45% at 78% 18%, rgba(236,34,34,.11), transparent 70%),
    radial-gradient(110% 70% at 8% 96%, rgba(237,234,227,.075), transparent 62%),
    radial-gradient(38% 30% at 30% 40%, rgba(237,234,227,.035), transparent 70%),
    linear-gradient(165deg, #16140f 0%, #100f0c 48%, #0a0908 100%);
  isolation:isolate;
}
/* pressed paper: grain at two scales, the laid lines of the sheet, and a darker rim */
.press::before, .cs-fig.show::before {
  content:''; position:absolute; inset:0; pointer-events:none; z-index:0;
  background:
    var(--grain) 0 0 / 220px 220px,
    var(--grain) 60px 40px / 440px 440px,
    repeating-linear-gradient(0deg, rgba(237,234,227,.03) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(90deg, rgba(237,234,227,.014) 0 1px, transparent 1px 7px);
  opacity:.15; mix-blend-mode:screen;
}
.press > *, .cs-fig.show > * { position:relative; }
/* figure plates — printed slots where real screens will land */
.cs-fig.fplate { aspect-ratio:7/3; display:grid; place-items:center; border:1px solid var(--line); }
.cs-fig.fplate::after { content:none; }
.fp-num {
  font-family:var(--serif); font-style:italic; font-size:clamp(56px,7vw,110px); line-height:1;
  color:rgba(237,234,227,.82);
  text-shadow:.05em .035em 0 rgba(237,234,227,.12);
}

/* ---------- the phone ----------
   One device body for every screen on the site — the live prototype, the
   captured states, the showcase, the work-card frames. Sized in percent and
   container units so it scales from a card thumbnail to the 390px live frame.
   The frame draws its own status strip (time + glyphs) under a dynamic island;
   --sb / --sbc tint the strip to whatever the screen's own header color is. */
.ph {
  position:relative; aspect-ratio:390/844; border-radius:14% / 6.5%; container-type:inline-size;
  background:#0c0b0a; --sb:#fff; --sbc:#1c1b1e;
  box-shadow:0 24px 60px rgba(0,0,0,.55);
}
/* the frame is written, not machined: a bone ink line run through the bleed
   filter, with the letterpress double-strike ghost beside it; the island is a
   blot dropped on the strip, the buttons are dabs off the edge */
.ph .rim {
  position:absolute; inset:-1px; border-radius:inherit; pointer-events:none; z-index:4;
  border:clamp(1.5px, .75cqw, 3px) solid var(--bone); opacity:.94;
  filter:url(#ink-frame);
}
.ph .rim::after {
  content:''; position:absolute; inset:-4px; border-radius:inherit;
  border:1px solid rgba(237,234,227,.28); transform:translate(1.2cqw, 1cqw);
}
.ph::before, .ph::after { content:''; position:absolute; background:var(--bone); opacity:.9; filter:url(#ink-frame); }
.ph::before { left:-2.4%; top:19%; width:2.4%; height:15%; border-radius:3px 0 0 3px;
  background:linear-gradient(var(--bone) 0 43%, transparent 43% 57%, var(--bone) 57%); } /* volume */
.ph::after { right:-2.4%; top:24%; width:2.4%; height:9.5%; border-radius:0 3px 3px 0; }  /* power */
.ph .scr { position:absolute; inset:1.5% 3.2%; border-radius:11.4% / 5.3%; overflow:hidden; background:#fff; }
.ph .isl { position:absolute; top:1.3%; left:50%; width:32%; height:4.3%; transform:translateX(-50%);
  background:#000; border-radius:999px; z-index:3; box-shadow:inset 0 0 0 1px rgba(255,255,255,.05); } /* the island stays an island */
.ph .sb {
  position:absolute; top:0; left:0; right:0; height:5.4%; z-index:2;
  display:flex; align-items:center; justify-content:space-between; padding:0 7.5%;
  background:var(--sb); color:var(--sbc);
  font-family:var(--font-body); font-weight:700; font-size:3.7cqw; letter-spacing:-.01em;
}
.ph .sb svg { width:17cqw; height:auto; display:block; }
.ph .cap { position:absolute; top:5.4%; left:0; right:0; bottom:0; width:100%; height:94.6%; border:0; display:block; background:#fff; }
.ph img.cap, .ph video.cap { object-fit:cover; object-position:top; filter:saturate(.92); }
.ph .lab-in { position:absolute; left:0; right:0; bottom:0; z-index:2; padding:6% 7% 7%;
  background:linear-gradient(to top, rgba(12,11,10,.85), transparent); color:var(--bone);
  font-family:var(--font-mono); font-size:3cqw; letter-spacing:.12em; text-transform:uppercase; }

/* ---------- real screens ----------
   The 48% study runs on its own material, re-set in the site's language:
   research plates (.rp — the Fullstory evidence, the report, the annotated
   original), a showcase and a state strip from the current prototype, and
   the prototype itself, live in the phone. */
.cs-fig.rp, .cs-fig.show, .cs-fig.phones, .cs-fig.live, .cs-fig.ba, .cs-fig.dec {
  aspect-ratio:auto; display:block; border:1px solid var(--line);
  padding:clamp(48px,4.4vw,62px) clamp(16px,2.4vw,30px) clamp(16px,2.4vw,30px);
}
.cs-fig.rp::after, .cs-fig.show::after, .cs-fig.phones::after, .cs-fig.live::after, .cs-fig.ba::after, .cs-fig.dec::after { content:none; }
.cs-fig .p-c { position:absolute; inset:14px; pointer-events:none; z-index:1; }
.cs-fig .p-c i { position:absolute; width:12px; height:12px; border:0 solid rgba(236,34,34,.6); }
.cs-fig .p-c i:nth-child(1) { top:0; left:0; border-top-width:1px; border-left-width:1px; }
.cs-fig .p-c i:nth-child(2) { top:0; right:0; border-top-width:1px; border-right-width:1px; }
.cs-fig .p-c i:nth-child(3) { bottom:0; left:0; border-bottom-width:1px; border-left-width:1px; }
.cs-fig .p-c i:nth-child(4) { bottom:0; right:0; border-bottom-width:1px; border-right-width:1px; }
.cs-fig .rp-src { position:absolute; left:16px; top:14px; z-index:2; color:var(--faint-text); }

/* research plate innards */
.rp-head { display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:14px 28px; margin-bottom:clamp(18px,2.4vw,30px); }
.rp-title { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t1),2vw,var(--t2)); line-height:1.15; max-width:26ch; text-wrap:balance; }
.rp-title em { font-style:italic; }
.rp-stats { display:flex; gap:clamp(18px,3vw,44px); }
.rp-stat { font-family:var(--serif); font-weight:700; font-size:clamp(38px,4.6vw,66px); line-height:.9; letter-spacing:-.02em; color:var(--bone); }
.rp-stat em { font-family:var(--serif); font-style:italic; font-weight:400; font-size:.7em; letter-spacing:0; }
.rp-stat small { display:block; margin-top:8px; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text); }
.rp-row { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:clamp(10px,1.6vw,20px); }
.rp-row.six { grid-template-columns:repeat(6, minmax(0,1fr)); }
.rp-tile { min-width:0; }
.rp-tile img { width:100%; height:auto; aspect-ratio:5/6; object-fit:cover; object-position:top; display:block;
  border-radius:10px; border:1px solid var(--line-2); filter:saturate(.7) contrast(1.02); }
.rp-row.scroll .rp-tile img { aspect-ratio:11/20; }
.rp-tile .k { display:block; margin-top:9px; font-family:var(--serif); font-size:var(--t0); line-height:1.15; color:var(--bone); }
.rp-tile .k b { font-weight:700; }
.rp-tile .n { display:block; margin-top:5px; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.06em; line-height:1.5; color:var(--faint-text); }
.rp-sub { display:flex; align-items:baseline; gap:12px; margin:clamp(18px,2.4vw,30px) 0 12px; border-top:1px solid var(--line-2); padding-top:14px; }
.rp-sub .ch-n { font-family:var(--serif); font-style:italic; font-size:var(--t1); color:rgba(237,234,227,.7); }

/* the report — set as type, not screenshotted */
.rp-rep { display:grid; grid-template-columns:1.1fr 1fr; gap:clamp(20px,3vw,48px); }
.rp-rep .lead { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t1),1.8vw,var(--t2)); line-height:1.3; text-wrap:pretty; }
.rp-rep .lead b { font-weight:700; }
.rp-rep .lead em { font-style:italic; }
.rp-rep ol { list-style:none; display:flex; flex-direction:column; gap:9px; }
.rp-rep li { position:relative; padding-left:26px; font-family:var(--serif); font-size:var(--t-1); line-height:1.45; color:var(--dim); }
.rp-rep li::before { content:''; position:absolute; left:6px; top:.55em; width:7px; height:7px; border-radius:50%; background:var(--rust); box-shadow:0 0 8px rgba(236,34,34,.6); }
.rp-rep li b { color:var(--bone); font-weight:600; }

/* the annotated original: the screen that was live, with the critique re-set beside it */
.rp-before { display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.3fr); gap:clamp(20px,3.4vw,56px); align-items:start; }
.rp-before .ph { width:min(300px, 100%); }
.mk { position:absolute; z-index:4; width:22px; height:22px; border-radius:50%; background:var(--rust); color:var(--bone);
  display:grid; place-items:center; font-family:var(--font-mono); font-size:var(--t-2); font-weight:700;
  box-shadow:0 0 0 3px rgba(12,11,10,.7), 0 0 14px rgba(236,34,34,.7); }
.crit { list-style:none; display:flex; flex-direction:column; gap:clamp(12px,1.6vw,20px); counter-reset:crit; }
.crit li { display:grid; grid-template-columns:22px 1fr; gap:12px; align-items:start; }
.crit .no { width:22px; height:22px; border-radius:50%; background:var(--rust); color:var(--bone);
  display:grid; place-items:center; font-family:var(--font-mono); font-size:var(--t-2); font-weight:700; margin-top:2px; }
.crit b { display:block; font-family:var(--serif); font-weight:700; font-size:var(--t0); line-height:1.25; margin-bottom:3px; }
.crit p { font-family:var(--serif); font-size:var(--t-1); line-height:1.45; color:var(--dim); text-wrap:pretty; }
.crit li.also b { display:inline; font-size:inherit; margin:0; }
.crit li.also { display:block; grid-column:1 / -1; margin-top:8px; padding-top:14px; border-top:1px solid var(--line-2);
  font-family:var(--serif); font-size:var(--t-1); line-height:1.5; color:var(--faint-text); }
.rp-before .also b { color:var(--dim); font-weight:600; }

/* the showcase — three states of the current prototype, staged on the paper */
.cs-fig.show { padding-bottom:0; isolation:isolate; background:
  radial-gradient(70% 60% at 50% 100%, rgba(236,34,34,.12), transparent 70%),
  radial-gradient(120% 90% at 18% -4%, rgba(237,234,227,.07), transparent 55%),
  linear-gradient(165deg, #15130f 0%, #100f0c 48%, #0a0908 100%); }
.show-row { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); align-items:end; justify-items:center; max-width:1000px; margin:0 auto; padding:0 clamp(4px,3vw,40px); }
/* phones overflow their columns and overlap, so the plate stays tall at every width */
.show-row .ph { width:min(128%, 360px); max-width:none; margin-bottom:-12%; }
.show-row .ph:nth-child(2) { position:relative; z-index:2; }
.show-row .ph:nth-child(1) { transform:translateY(7%) rotate(-3deg); }
.show-row .ph:nth-child(3) { transform:translateY(7%) rotate(3deg); }
.show-row .ph:nth-child(2) { box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), inset 0 0 0 4px #17150f, 0 40px 90px rgba(0,0,0,.65); }

.phw { display:flex; flex-direction:column; gap:10px; min-width:0; }
.phw .lab, .cs-fig .hint { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text); }
.cs-fig.live { display:grid; place-items:center; gap:14px; }
.cs-fig.live .ph { width:min(390px, 100%); box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), inset 0 0 0 4px #17150f, 0 40px 90px rgba(0,0,0,.6); }
.cs-fig .open { position:absolute; left:16px; top:14px; z-index:2; color:var(--dim); transition:color .3s linear; }
.cs-fig .open:hover, .cs-fig .open:focus-visible { color:var(--bone); }
@media (max-width:860px) {
  .rp-row, .rp-row.six { grid-template-columns:repeat(3, minmax(0,1fr)); }
  .rp-rep, .rp-before { grid-template-columns:1fr; }
}
@media (max-width:700px) {
  .rp-row, .rp-row.six { grid-template-columns:repeat(2, minmax(0,1fr)); }
  .rp-stats { flex-wrap:wrap; }
}

/* the work cards: real screens in the same phone; the 48% card carries two */
.device .screen:has(.shot) { height:calc(100% - 24px); }
.card-media .ph { position:absolute; transition:transform .9s var(--ease); }
.card--wide .card-media .ph.pl { left:26%; width:19%; bottom:-16%; }
.card--wide .card-media .ph.pr { left:56%; width:19%; bottom:-34%; }
.card:hover .card-media .ph { transform:translateY(-10px); }
.card:hover .card-media .ph.pr { transform:translateY(-20px); }
@media (max-width:860px) {
  .card--wide .card-media .ph.pl { left:12%; width:36%; bottom:-30%; }
  .card--wide .card-media .ph.pr { left:53%; width:36%; bottom:-48%; }
}

/* per-project micro-diagrams — each device screen shows that project's mechanism */
.s-steps { display:flex; gap:5px; }
.s-steps i { flex:1; height:5px; border-radius:3px; background:rgba(237,234,227,.07); }
.s-steps i.on { background:rgba(237,234,227,.3); }
.s-steps i.cur { background:rgba(237,234,227,.55); }
.u-status .s-list i { height:18px; }
.s-stats i.pay { background:rgba(237,234,227,.14); border-color:rgba(237,234,227,.3); }
.s-sw { display:grid; grid-template-columns:repeat(6,1fr); gap:6px; }
.s-sw i { aspect-ratio:1; border-radius:5px; background:rgba(237,234,227,var(--a,.08)); border:1px solid rgba(237,234,227,.06); }
.s-comp { flex:1; display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.s-comp i { border:1px solid rgba(237,234,227,.12); border-radius:7px; background:rgba(237,234,227,.04); min-height:22px; }
.s-comp i.b { border-radius:999px; background:rgba(237,234,227,.16); border:0; }
.s-comp i.g { position:relative; }
.s-comp i.g::after { content:''; position:absolute; right:5px; top:50%; transform:translateY(-50%); width:10px; height:10px; border-radius:50%; background:rgba(237,234,227,.28); }
.s-pill { display:flex; gap:5px; }
.s-pill i { flex:1; height:16px; border-radius:999px; background:rgba(237,234,227,.05); border:1px solid rgba(237,234,227,.08); }
.s-pill i.on { background:rgba(237,234,227,.24); border-color:transparent; }
.s-cards { flex:1; display:flex; gap:7px; min-height:0; overflow:hidden; }
.s-cards i { flex:0 0 44%; border-radius:9px; background:rgba(237,234,227,.06); border:1px solid rgba(237,234,227,.07); position:relative; }
.s-cards i::after { content:''; position:absolute; left:7px; bottom:6px; width:46%; height:5px; border-radius:3px; background:rgba(237,234,227,.3); }
.s-cmp { display:flex; gap:7px; }
.s-cmp i { flex:1; height:26px; border-radius:7px; background:rgba(237,234,227,.13); border:1px solid rgba(237,234,227,.18); }
.s-rows { flex:1; display:flex; flex-direction:column; gap:6px; min-height:0; }
.s-rows i { flex:none; height:13px; border-radius:4px; background:rgba(237,234,227,.05); border:1px solid rgba(237,234,227,.05); }

/* the Freshworks card isn't a link yet — don't promise a click it can't keep */
.card:not(a) { cursor:default; }
.card:not(a):hover { transform:none; border-color:var(--line-2); }
.card:not(a)::after { content:none; }
.card:not(a):hover .device { transform:none; }

.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ---------- the ink bleed — display type only; UI text stays crisp ----------
   Filters are defined inline in each page's <svg class="ink-defs">.
   #ink-reveal is the hero's own copy of the pipeline so ink.js can animate
   it without re-rasterizing every other filtered element. On fine pointers
   ink.js swaps the hero to per-letter filters (.il spans, one pipeline each)
   so single letters can swell with ink under the cursor. */
.hero-name { filter:url(#ink-reveal); }
.plate .p-stat { filter:url(#ink-xl); }
.sec-head h2, .cs-title, .c-h1, .fp-num, .next a .nt { filter:url(#ink-lg); }
.hero-name .il { display:inline-block; will-change:transform; }
/* once the soak-in has dried, the name is one layer again: per-letter layers made the
   hero re-run every letter's filter on each frame of the scroll drift */
.hero-name.settled { will-change:transform; }
.hero-name.settled .il { will-change:auto; }
/* letters lift + bleed past the line box; nowrap — split letters are atomic
   inlines and would otherwise soft-wrap. ink.js fits HARRIS to the measure. */
.hero-name .line { overflow:visible; white-space:nowrap; }

/* tertiary CTAs speak the spine's grammar: hover writes an ink stroke under
   the link left-to-right, then a blot blooms where the pen lifts. Sized in em
   so the giant email gets a fist of ink and the footer links get a fine line. */
.c-item .v .w { display:inline-block; } /* shrink to the text so the stroke hugs it */
.c-item .v .w, .strip .em, .strip .sub a, .f-links a, .next a .nt { position:relative; }
.c-item .v .w::after, .strip .em::after, .strip .sub a::after, .f-links a::after, .next a .nt::after {
  content:''; position:absolute; left:-.03em; right:-.08em; bottom:-.1em;
  height:clamp(2.5px, .08em, 9px); border-radius:2px; background:var(--bone);
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform .45s var(--ease);
  filter:url(#ink-line); pointer-events:none;
}
.c-item .v .w::before, .strip .em::before, .strip .sub a::before, .f-links a::before, .next a .nt::before {
  content:''; position:absolute; right:-.36em; bottom:-.16em;
  width:clamp(5px, .19em, 20px); height:clamp(5px, .19em, 20px);
  border-radius:53% 47% 44% 56% / 49% 58% 42% 51%; background:var(--bone);
  transform:scale(0); transition:transform .4s var(--ease) .2s;
  filter:url(#ink-line); pointer-events:none;
}
.c-item:hover .v .w::after, .c-item:focus-visible .v .w::after,
.strip .em:hover::after, .strip .em:focus-visible::after,
.strip .sub a:hover::after, .strip .sub a:focus-visible::after,
.f-links a:hover::after, .f-links a:focus-visible::after,
.next a:hover .nt::after, .next a:focus-visible .nt::after { transform:scaleX(1); }
.c-item:hover .v .w::before, .c-item:focus-visible .v .w::before,
.strip .em:hover::before, .strip .em:focus-visible::before,
.strip .sub a:hover::before, .strip .sub a:focus-visible::before,
.f-links a:hover::before, .f-links a:focus-visible::before,
.next a:hover .nt::before, .next a:focus-visible .nt::before { transform:scale(1); }

/* ink-flood button: a full-size blot (sized to cover the pill from any corner, via
   --bd in app.js) grows from where the cursor came in and drains back out toward
   where it left. Only transform and color animate, on one curve. */
.btn {
  --flow:cubic-bezier(.16,1,.3,1);
  position:relative; overflow:hidden; isolation:isolate; border:1px solid transparent;
  transform:translateZ(0);
  transition:color .45s var(--flow), border-color .45s var(--flow);
}
.btn::after {
  content:''; position:absolute; z-index:0; pointer-events:none;
  left:var(--bx,50%); top:var(--by,50%); width:var(--bd,440px); height:var(--bd,440px);
  margin:calc(var(--bd,440px) / -2) 0 0 calc(var(--bd,440px) / -2);
  border-radius:50%; background:#0d0c0a;
  transform:scale(0); will-change:transform;
  transition:transform .55s var(--flow);
}
.btn:hover::after, .btn:focus-visible::after { transform:scale(1); transition-duration:.8s; }
/* keyboard focus is navigation, not a moment: fill fast from the center */
.btn:focus-visible:not(:hover)::after { left:50%; top:50%; transition-duration:.22s; }
.btn:focus-visible:not(:hover) { transition-duration:.2s; }
.btn .bl, .btn .go-arr { position:relative; z-index:1; }
.btn:hover, .btn:focus-visible { color:var(--bone); border-color:rgba(237,234,227,.3); }

/* ---------- the ink story — chapters + spine ----------
   The site reads as one story written in ink: chapter labels (.ch) carry the
   copy; story.js writes a live ink line down the left gutter that blooms into
   a blot as each chapter is reached and lights its label. */
.ch { display:inline-flex; align-items:center; gap:10px; letter-spacing:.16em; color:var(--rust); }
.ch.hi { color:inherit; }
.sec-head .ch { flex-basis:100%; order:-1; margin-bottom:2px; }
.strip .ch { margin-bottom:16px; }
.hero--full .ch { margin-bottom:clamp(12px,1.8vw,20px); }
.cs-sec .lab { transition:color .7s linear; }
.cs-sec .lab.lit { color:var(--bone); }

.spine { position:absolute; top:0; left:0; z-index:0; pointer-events:none; }
.spine path { fill:none; stroke-linecap:round; stroke-linejoin:round; }
.spine .sp-halo { stroke:rgba(237,234,227,.09); stroke-width:4.5; }
.spine .sp-main { stroke:rgba(237,234,227,.42); stroke-width:1.6; }
.spine .blot {
  fill:rgba(237,234,227,.6);
  transform:scale(0); transform-origin:center; transform-box:fill-box;
  transition:transform .8s var(--ease);
}
.spine .blot.on { transform:scale(1); }
.spine .tip { fill:#edeae3; opacity:0; transition:opacity .4s linear; }

/* ---------- reveals ---------- */
.js .rev { opacity:0; transform:translateY(10px); }
.js .rev.in { opacity:1; transform:none; transition:opacity .6s var(--ease), transform .6s var(--ease); }
/* the work cards keep their longer rise */
.js .card.rev { transform:translateY(30px); }
.js .card.rev.in { transition:opacity .95s var(--ease), transform .95s var(--ease); }
/* screenshots and the photo soak in from a blot, the same ink the cards use */
.js .about-photo.rev { opacity:1; transform:none; } /* the handwritten note sits outside the photo, so only the image soaks */
.js .sc-stage.rev, .js .about-photo.rev img { opacity:1; transform:none; --b:0%;
  -webkit-mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%));
  mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%)); }
.js .sc-stage.rev.in, .js .about-photo.rev.in img { --b:160%; transition:--b 1.5s var(--ease); }

/* ---------- responsive ---------- */
@media (max-width:960px) {
  .approach { grid-template-columns:repeat(2, minmax(0,1fr)); }
  .cs-sec { grid-template-columns:1fr; gap:14px; }
  .cs-sec .lab { position:static; }
  .meta { grid-template-columns:repeat(2, minmax(0,1fr)); }
  .card--wide .card-body { display:block; }
  .card--wide .card-body p { margin-bottom:18px; }
  .card--wide .card-body .outcomes { justify-content:flex-start; }
  .about-body { margin-left:clamp(0px,12vw,180px); }
}
@media (max-width:860px) {
  .grid { grid-template-columns:1fr; }
  .card--wide .card-media { aspect-ratio:4/2.9; }
  .card--wide .device { left:13%; right:13%; height:66%; }
  .card--wide .device.phone { left:33%; right:33%; height:74%; }
  .card--wide .card-body h3 { font-size:var(--t1); }
  .hero--full .hp-foot { flex-direction:column; align-items:flex-start; }
  .hero--full { min-height:min(calc(100svh - 108px), 900px); }
  .hero--full .fig { position:static; margin-top:4px; }
  .hero-facts { justify-content:flex-start; }
  .about-body { margin-left:0; }
  .c-item { grid-template-columns:1fr; gap:6px; }
  .c-item .arr { display:none; }
  .xp-item { grid-template-columns:84px 1fr; }
  .xp-item .role { grid-column:2; text-align:left; margin-top:2px; }
}
@media (max-width:700px) {
  .cs-title { line-height:1.12; }
  .about-lede { line-height:1.26; }
  .c-h1 { line-height:1.16; }
  .next { flex-direction:column; align-items:flex-start; gap:12px; }
}
@media (max-width:520px) {
  .approach { grid-template-columns:1fr; }
}
@media (max-width:400px) {
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior:auto; }
  .grain { animation:none; }
  .ink-canvas { display:none; }
  .js .rise { animation:none; }
  .js .rev { opacity:1; transform:none; }
  .js .sc-stage.rev, .js .about-photo.rev img { -webkit-mask-image:none; mask-image:none; }
  .js .sc-stage .pen > svg > * { stroke-dashoffset:0; }
  .js .sc-stage .pen::after { opacity:1; }
  .js .sc-stage .sc-pin > span { opacity:1; }
  *, *::before, *::after { transition-duration:.01ms !important; transition-delay:0s !important; }
}

/* ---------- case-study cover + data plates + before/after ---------- */
.cs-fig.cover { height:auto; margin:0 0 clamp(40px,5vw,70px); }
.rp-two { display:grid; grid-template-columns:1fr 1fr; gap:clamp(18px,3vw,44px); margin-bottom:clamp(18px,2.4vw,30px); }
.rp-h { display:block; margin-bottom:12px; }
.fr { display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) auto; align-items:center; gap:12px; padding:7px 0; border-bottom:1px solid var(--line-2); }
.fr:last-of-type { border-bottom:0; }
.fr .fl { font-family:var(--serif); font-size:var(--t-1); line-height:1.3; color:var(--dim); }
.fr .fl em { display:block; font-style:normal; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.1em; text-transform:uppercase; color:var(--faint-text); margin-top:2px; }
.fr .fb { position:relative; height:clamp(7px,.7vw,10px); }
.fr .fb i { position:absolute; left:0; top:0; height:100%; width:var(--w); background:var(--bone); border-radius:2px; filter:url(#ink-line); opacity:.85; }
.fr.hot .fb i { background:var(--rust); opacity:1; }
.fr .fv { font-family:var(--serif); font-weight:700; font-size:var(--t1); letter-spacing:-.01em; color:var(--bone); min-width:3.2ch; text-align:right; }
.fr.hot .fv { color:var(--rust); }
.rp-note { margin-top:12px; font-family:var(--serif); font-style:italic; font-size:var(--t-1); line-height:1.4; color:var(--faint-text); }
.rp-row.small { grid-template-columns:repeat(4, minmax(0,1fr)); max-width:720px; }
.rp-row.small .rp-tile img { aspect-ratio:11/20; }
.rp-row.small .rp-tile .k { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.1em; text-transform:uppercase; color:var(--faint-text); }
.cs-fig.ba { display:grid; place-items:center; gap:14px; }
.cs-fig.ba .hint { text-align:center; }
.ba-slide { display:flex; justify-content:center; width:100%; }
.ba-slide .ph { width:min(420px, 100%); touch-action:none; box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), inset 0 0 0 4px #17150f, 0 40px 90px rgba(0,0,0,.6); }
.ba-layer { position:absolute; inset:0; }
.ba-layer.before { clip-path:inset(0 calc(100% - var(--x)) 0 0); }
.ba-layer.after  { clip-path:inset(0 0 0 var(--x)); }
.ba-bar { position:absolute; top:0; bottom:0; left:var(--x); width:2px; margin-left:-1px; background:var(--bone); filter:url(#ink-line); z-index:4; pointer-events:none; }
.ba-knob { position:absolute; left:50%; top:50%; width:12cqw; height:12cqw; transform:translate(-50%,-50%); border-radius:50%;
  background:#0a0908; border:1.5px solid var(--bone); box-shadow:0 8px 22px rgba(0,0,0,.55); }
.ba-knob::before { content:'‹  ›'; position:absolute; inset:0; display:grid; place-items:center; font-family:var(--serif); font-size:6cqw; letter-spacing:-.02em; color:var(--bone); white-space:pre; }
.ba-tag { position:absolute; bottom:3.5%; z-index:4; padding:5px 9px; border-radius:999px; background:rgba(10,9,8,.78); color:var(--bone); font-size:2.6cqw; letter-spacing:.14em; pointer-events:none; }
.ba-tag.l { left:5%; } .ba-tag.r { right:5%; }
.ba-range { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:ew-resize; z-index:5; -webkit-appearance:none; appearance:none; }
.ba-range:focus-visible + * , .ba-slide:has(.ba-range:focus-visible) .ba-bar { background:var(--rust); }
.crit.two { display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,2vw,26px) clamp(18px,3vw,44px); margin-top:clamp(22px,3vw,40px); padding-top:clamp(18px,2.4vw,30px); border-top:1px solid var(--line-2); }
@media (max-width:860px) { .rp-two, .crit.two { grid-template-columns:1fr; } }


/* decisions: evidence, then the move */
.dec-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
.dec-list li { display:grid; grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr); gap:clamp(18px,3vw,48px); align-items:center; padding:clamp(22px,3vw,40px) 0; border-top:1px solid var(--line-2); }
.dec-list li:first-child { border-top:0; padding-top:0; }
.dec-list li:last-child { padding-bottom:0; }
.dec-list .st { display:block; font-family:var(--serif); font-weight:700; font-size:clamp(44px,5.6vw,84px); line-height:.95; letter-spacing:-.02em; color:var(--rust); }
.dec-list .sl { display:block; margin-top:8px; color:var(--dim); }
.dec-list p { margin-top:14px; font-family:var(--serif); font-size:var(--t0); line-height:1.45; color:var(--bone); text-wrap:pretty; max-width:34ch; }
.dec-list .dm { display:grid; grid-template-columns:1fr 1fr; gap:clamp(12px,1.6vw,22px); align-items:start; max-width:640px; width:100%; justify-self:end; }
.dec-list .dm figure { margin:0; min-width:0; }
.dec-list .dm .lbl { display:block; margin-bottom:8px; font-size:var(--t-2); letter-spacing:.16em; text-transform:uppercase; color:var(--dim); }
.dec-list .dm .now .lbl { color:var(--rust); }
.dec-list .dm img, .dec-list .dm video { display:block; width:100%; height:auto; border-radius:12px; background:#fff; filter:saturate(.92); box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), 0 24px 50px rgba(0,0,0,.5); }
.dec-list .dm .was img { filter:saturate(.55) contrast(.96); opacity:.86; }
.dec-list li:nth-child(even) { grid-template-columns:minmax(0,1.28fr) minmax(0,.72fr); }
.dec-list li:nth-child(even) .dm { justify-self:start; }
.dec-list li:nth-child(even) .dt { order:2; }
@media (max-width:860px) { .dec-list li, .dec-list li:nth-child(even) { grid-template-columns:1fr; } .dec-list li:nth-child(even) .dt { order:0; } .dec-list .dm { justify-self:start; max-width:560px; } }

/* validation: what the test would have measured */
.meas-lead { margin-top:18px; }
.meas { list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; }
.meas li { position:relative; padding:9px 0 9px 22px; border-top:1px solid var(--line-2); font-family:var(--serif); font-size:var(--t0); line-height:1.45; color:var(--dim); }
.meas li::before { content:""; position:absolute; left:2px; top:1.05em; width:7px; height:7px; border-radius:50%; background:var(--rust); }

/* ---- design system specimens (cs-system) ---- */
.cs-fig.spec { aspect-ratio:auto; display:block; border:1px solid var(--line);
  padding:clamp(48px,4.4vw,62px) clamp(16px,2.4vw,30px) clamp(16px,2.4vw,30px); }
.cs-fig.spec::after { content:none; }
.ds-canvas { display:block; width:100%; height:auto; border-radius:10px; border:1px solid var(--line-2);
  filter:saturate(.5) contrast(1.04); opacity:.94; }
.ds-arch { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(14px,2.4vw,34px);
  margin:clamp(18px,2.4vw,30px) 0 0; border-top:1px solid var(--line-2); padding-top:clamp(14px,1.8vw,22px); }
.ds-arch .n { display:block; font-family:var(--serif); font-weight:700; font-size:clamp(30px,3.6vw,52px);
  line-height:.95; letter-spacing:-.02em; color:var(--rust); }
.ds-arch .l { display:block; margin-top:7px; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em;
  text-transform:uppercase; color:var(--dim); }
.ds-arch p { margin-top:9px; font-family:var(--serif); font-size:var(--t-1); line-height:1.45; color:var(--faint-text); }
.ds-two { display:grid; grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr); gap:clamp(20px,3.4vw,56px); align-items:center; }
.ds-two .shot { margin:0; min-width:0; }
.ds-two .shot img { display:block; width:100%; height:auto; border-radius:10px; border:1px solid var(--line-2);
  filter:saturate(.6) contrast(1.02); }
.ds-two .notes { min-width:0; }
.ds-def { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:clamp(11px,1.5vw,18px); }
.ds-def li { border-top:1px solid var(--line-2); padding-top:11px; }
.ds-def b { display:block; font-family:var(--serif); font-weight:700; font-size:var(--t0); line-height:1.25; margin-bottom:4px; }
.ds-def span { display:block; font-family:var(--serif); font-size:var(--t-1); line-height:1.45; color:var(--dim); text-wrap:pretty; }
@media (max-width:860px) { .ds-arch { grid-template-columns:1fr; } .ds-two { grid-template-columns:1fr; } }
.ds-two .shot { position:relative; }
.ds-two .shot.cap img { max-height:clamp(380px,42vw,580px); object-fit:cover; object-position:top; }
.ds-two .shot.cap::after { content:''; position:absolute; left:1px; right:1px; bottom:1px; height:96px;
  border-radius:0 0 10px 10px; pointer-events:none;
  background:linear-gradient(to bottom, rgba(18,17,15,0), var(--panel) 88%); }
@media (max-width:860px) { .ds-two .shot { max-width:340px; } }

/* ---- plan comparison (cs-comparison) ---- */
.cmp-pair { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:clamp(20px,5vw,80px); justify-items:center; max-width:860px; margin:0 auto; padding:clamp(8px,1.4vw,18px) 0 clamp(20px,2.6vw,34px); }
.cmp-pair .phw { width:min(390px, 100%); align-items:center; }
.cmp-pair .ph { width:100%; box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), inset 0 0 0 4px #17150f, 0 40px 90px rgba(0,0,0,.6); }
.cmp-dir .cmp-pair .phw:nth-child(1) .ph { transform:rotate(-2deg); }
.cmp-dir .cmp-pair .phw:nth-child(2) .ph { transform:rotate(2deg); }
.cmp-pair .plab { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text);  text-align:center; margin-top:10px; }
.cmp-pair .plab a { color:var(--dim); margin-left:8px; white-space:nowrap; }
.cmp-pair .plab a:hover, .cmp-pair .plab a:focus-visible { color:var(--bone); }
.cmp-def { margin-top:clamp(22px,3vw,36px); display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); column-gap:clamp(20px,3.4vw,48px); }
.cs-fig.show.cmp-dir, .cs-fig.show.cmp-live { padding-bottom:clamp(16px,2vw,28px); }
@media (max-width:700px) { .cmp-pair { grid-template-columns:1fr; } .cmp-def { grid-template-columns:1fr; } }

/* ---- show-first case study (sc-) ----
   One claim, a few sentences, one big visual per section. The words sit in a
   sticky column so the visual can carry the scroll. */
.sc-head { max-width:1060px; margin-bottom:clamp(28px,3.4vw,44px); }
.sc-dek { margin-top:18px; max-width:58ch; font-family:var(--serif); font-size:var(--t1); line-height:1.45; color:var(--dim); text-wrap:pretty; }
/* the details: a spec ledger. Short facts share a row on wide screens; scope and
   the outcome run full width. Every cell sits on the same hairline grid. */
.sc-meta { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); column-gap:clamp(20px,2.6vw,40px); margin:clamp(28px,3vw,40px) 0 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.sc-meta div { display:flex; flex-direction:column; gap:8px; min-width:0; padding:16px 0 18px; }
.sc-meta .wd, .sc-meta .res { grid-column:1 / -1; border-top:1px solid var(--line); }
.sc-meta:has(> .wd:nth-child(4)) { grid-template-columns:repeat(3, minmax(0,1fr)); }
.sc-meta dt { font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--faint-text); }
.sc-meta dd { margin:0; font-size:var(--t-1); line-height:1.45; color:var(--bone); text-wrap:pretty; }
/* the outcome row: what happened after, read first by anyone screening */
.sc-meta .res dd { max-width:62ch; font-size:var(--t0); }
@media (max-width:700px) {
  .sc-meta { grid-template-columns:1fr; }
  .sc-meta div + div { border-top:1px solid var(--line); }
  .sc-meta div { display:grid; grid-template-columns:92px minmax(0,1fr); gap:16px; align-items:baseline; padding:13px 0 14px; }
  .sc-meta .res { grid-template-columns:1fr; gap:8px; padding-top:16px; }
}

.sc-stage { position:relative; margin:0; border:1px solid var(--line); border-radius:18px; overflow:hidden; isolation:isolate;
  padding:clamp(26px,3.4vw,52px) clamp(16px,3vw,48px);
  background:
    radial-gradient(70% 60% at 50% 100%, rgba(236,34,34,.13), transparent 70%),
    radial-gradient(120% 90% at 18% -4%, rgba(237,234,227,.06), transparent 55%),
    linear-gradient(165deg, #15130f 0%, #100f0c 48%, #0a0908 100%); }
.sc-stage .ph { box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), inset 0 0 0 4px #17150f, 0 40px 90px rgba(0,0,0,.6); }
.sc-lbl { display:block; text-align:center; margin-top:16px; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--faint-text); }
.sc-lbl a { color:var(--dim); margin-left:10px; white-space:nowrap; }
.sc-lbl a:hover, .sc-lbl a:focus-visible { color:var(--bone); }
.sc-lbl.on { color:var(--bone); }

/* hero: the whole story in three phones */
.sc-hero { padding-bottom:clamp(18px,2vw,26px); margin-bottom:clamp(90px,11vw,160px); }
.sc-trio { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(12px,4vw,64px); max-width:calc(1040 * var(--u)); margin:0 auto; }
.sc-col { display:flex; flex-direction:column; align-items:center; min-width:0; }
.sc-trio .ph { width:min(calc(290 * var(--u)), 100%); }
.sc-crop { width:100%; display:flex; justify-content:center; height:clamp(230px,31vw,calc(450 * var(--u))); overflow:hidden; padding-top:4px;
  -webkit-mask-image:linear-gradient(#000 72%, transparent); mask-image:linear-gradient(#000 72%, transparent); }
.sc-count { display:flex; align-items:baseline; gap:10px; margin:0 0 clamp(12px,1.6vw,22px); }
.sc-count b { font-family:var(--serif); font-weight:700; font-size:clamp(40px,5.4vw,84px); line-height:.9; color:var(--rust); letter-spacing:-.03em; }
.sc-count span { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.sc-hero .sc-col:last-child .sc-count b { color:var(--bone); }

/* sections */
.sc-sec { display:grid; grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr); gap:clamp(28px,5vw,88px); align-items:start; margin-bottom:clamp(90px,11vw,160px); }
.sc-txt { position:sticky; top:120px; }
.sc-txt .lab { display:block; font-size:var(--t-2); letter-spacing:.16em; text-transform:uppercase; color:var(--faint-text); margin-bottom:18px; transition:color .7s linear; }
.sc-txt .lab.lit { color:var(--rust); }
.sc-txt h2 { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t3),3.3vw,var(--t4)); line-height:1.06; letter-spacing:-.015em; margin-bottom:20px; text-wrap:balance; }
.sc-txt h2 em { font-style:italic; }
.sc-txt p { color:var(--dim); font-size:var(--t0); line-height:1.55; max-width:42ch; margin-bottom:14px; text-wrap:pretty; }
.sc-txt b { color:var(--bone); font-weight:600; }
.sc-txt .sc-quiet { font-size:var(--t-1); color:var(--faint-text); margin-top:22px; padding-top:16px; border-top:1px solid var(--line-2); }

.sc-one { display:flex; justify-content:center; }
.sc-one .ph { width:min(calc(390 * var(--u)), 100%); }
.sc-ba { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:clamp(16px,4vw,56px); max-width:calc(720 * var(--u)); margin:0 auto; }
.sc-ba .ph { width:min(calc(320 * var(--u)), 100%); }
.sc-ba .sc-col:first-child .ph { opacity:.72; filter:saturate(.6); }

/* a pin on a real screen */
.sc-pin { position:absolute; z-index:5; width:0; height:0; }
.sc-pin i { position:absolute; left:-9px; top:-9px; width:18px; height:18px; border-radius:50%; border:2px solid var(--rust);
  box-shadow:0 0 0 4px rgba(236,34,34,.25), 0 0 18px rgba(236,34,34,.6); }
.js .sc-pin > span { transition:opacity .5s var(--ease) 1.5s; }
.js .sc-stage.rev:not(.in) .sc-pin > span { opacity:0; }
.sc-pin span { position:absolute; left:26px; top:-9px; white-space:nowrap; font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase;
  color:var(--bone); background:var(--rust); padding:3px 8px 2px; border-radius:999px; }

/* the measurement: drawn, not described */
.sc-measure { display:flex; flex-direction:column; gap:clamp(34px,4vw,52px); justify-content:center; min-height:clamp(380px,38vw,560px); }
.m-k { display:block; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); margin-bottom:14px; }
.m-canvas { position:relative; height:clamp(96px,9vw,124px); }
.m-canvas > span { position:absolute; left:calc(var(--x) / 520 * 100%); width:calc(var(--w) / 520 * 100%); }
.m-screen { top:-10px; bottom:-10px; border:1.5px solid rgba(237,234,227,.55); border-radius:10px; }
.m-screen i { position:absolute; right:8px; top:-18px; font-style:normal; font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text); }
.m-cell { top:0; height:calc(100% - 30px); display:grid; place-items:center; text-align:center; padding:4px 6px; border-radius:6px;
  background:#f5f4f0; color:#1d2329; font-family:var(--font-body); font-size:clamp(9.5px,.85vw,12px); line-height:1.25; font-weight:500;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.08); }
.m-cell.lbl { background:transparent; color:var(--bone); box-shadow:none; justify-items:start; text-align:left; }
.m-cell.ghost { background:transparent; color:var(--rust); border:1.5px dashed var(--rust); box-shadow:none; }
.m-dim { bottom:0; height:18px; display:flex; align-items:center; justify-content:center; font-size:var(--t-2); letter-spacing:.06em; color:var(--dim);
  border-top:1px solid var(--line); }
.m-dim.over { color:var(--rust); border-top-color:rgba(236,34,34,.6); }
.m-dim.fit { color:var(--bone); }

@media (max-width:900px) {
  .sc-sec { grid-template-columns:1fr; gap:26px; }
  .sc-txt { position:static; }
  .sc-txt p { max-width:60ch; }
}
@media (max-width:560px) {
  .sc-count { flex-direction:column; gap:4px; align-items:center; }
  .sc-count span { font-size:11px; text-align:center; }
  .sc-pin span { display:none; }
}

/* ---- show-first components, second batch ---- */
.sc-hero .sc-col .sc-lbl { margin-top:clamp(10px,1.2vw,16px); }
.sc-canvas { padding:clamp(16px,2.4vw,34px); }
.sc-canvas > img { display:block; width:100%; height:auto; border-radius:10px; border:1px solid var(--line-2); filter:saturate(.55) contrast(1.04); }
.sc-stats { display:flex; justify-content:center; flex-wrap:wrap; gap:clamp(20px,6vw,96px); margin-top:clamp(18px,2.4vw,30px); }
.sc-stats .sc-count { margin:0; }

/* before / after: a still of the old page beside a clip of the new one */
.sc-pair { display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,2vw,28px); align-items:start; max-width:640px; margin:0 auto; }
.sc-pair figure { margin:0; min-width:0; }
.sc-pair .lbl { display:block; margin-bottom:10px; font-size:var(--t-2); letter-spacing:.16em; text-transform:uppercase; color:var(--dim); }
.sc-pair .now .lbl { color:var(--rust); }
.sc-pair img, .sc-pair video { display:block; width:100%; height:auto; border-radius:12px; background:#fff;
  box-shadow:inset 0 0 0 1px rgba(237,234,227,.22), 0 24px 50px rgba(0,0,0,.5); }
.sc-pair .was img { filter:saturate(.55) contrast(.96); opacity:.86; }

/* scroll-depth evidence */
.sc-funnel { max-width:640px; margin:0 auto; }
.sc-funnel .rp-row.small { margin-top:clamp(20px,2.6vw,32px); max-width:none; }

/* the architecture, drawn */
.sc-tree { max-width:680px; margin:0 auto; }
.t-node { position:relative; border:1px solid var(--line); border-radius:14px; padding:clamp(14px,1.6vw,20px); background:rgba(237,234,227,.03); }
.t-node > b { display:block; font-family:var(--serif); font-weight:700; font-size:clamp(34px,3.6vw,54px); line-height:.9; color:var(--rust); letter-spacing:-.02em; }
.t-node.root > b { color:var(--bone); }
.t-node .l { display:block; margin-top:8px; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.t-chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:12px; }
.t-chips i { font-style:normal; font-size:var(--t-1); color:var(--bone); border:1px solid var(--line); border-radius:999px; padding:3px 10px; }
.t-node.root { max-width:440px; margin:0 auto; text-align:center; }
.t-node.root .t-chips { justify-content:center; }
.t-branches { position:relative; display:grid; grid-template-columns:1fr 1fr; gap:clamp(12px,2vw,24px); padding-top:48px; }
.t-branches::before { content:''; position:absolute; left:50%; top:0; height:24px; border-left:1.5px solid rgba(237,234,227,.35); }
.t-branches::after { content:''; position:absolute; left:25%; right:25%; top:24px; border-top:1.5px solid rgba(237,234,227,.35); }
.t-branches .t-node::before { content:''; position:absolute; left:50%; top:-24px; height:24px; border-left:1.5px solid rgba(237,234,227,.35); }

/* page specimens, kept small on purpose */
.sc-tiles { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(12px,2vw,24px); max-width:calc(620 * var(--u)); margin:0 auto; }
.sc-tiles figure { margin:0; min-width:0; }
.sc-tiles img { display:block; width:100%; aspect-ratio:5/6; object-fit:cover; object-position:top; border-radius:10px; border:1px solid var(--line-2); filter:saturate(.6); }
.sc-tiles.tall img { aspect-ratio:11/20; }
.sc-tiles figcaption { margin-top:9px; font-family:var(--serif); font-size:var(--t0); color:var(--bone); }
.sc-shot { display:flex; justify-content:center; }
.sc-shot span { position:relative; display:block; width:min(calc(340 * var(--u)), 100%); }
.sc-shot img { display:block; width:100%; max-height:clamp(420px,44vw,600px); object-fit:cover; object-position:top; border-radius:10px; border:1px solid var(--line-2); filter:saturate(.6); }
.sc-shot span::after { content:''; position:absolute; left:1px; right:1px; bottom:1px; height:110px; border-radius:0 0 10px 10px; pointer-events:none;
  background:linear-gradient(to bottom, rgba(16,15,12,0), #100f0c 90%); }

/* a closing number */
.sc-big { display:grid; place-items:center; min-height:clamp(300px,32vw,460px); text-align:center; }
.sc-big .sc-count { flex-direction:column; align-items:center; gap:14px; margin:0; }
.sc-big .sc-count b { font-size:clamp(90px,13vw,200px); color:var(--bone); }

@media (max-width:560px) {
  .sc-tiles { grid-template-columns:repeat(2, minmax(0,1fr)); }
  .t-branches { grid-template-columns:1fr; padding-top:24px; }
  .t-branches::before, .t-branches::after, .t-branches .t-node::before { display:none; }
  .sc-pair { gap:10px; }
}

/* design-system hero: real pages fanned on the stage, cut off at the bottom */
.sc-pages { display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); gap:clamp(10px,1.6vw,22px); align-items:start;
  max-width:calc(1120 * var(--u)); margin:0 auto; height:clamp(220px,28vw,calc(400 * var(--u))); overflow:hidden; padding:10px 6px 0;
  -webkit-mask-image:linear-gradient(#000 62%, transparent); mask-image:linear-gradient(#000 62%, transparent); }
.sc-pages img { display:block; width:100%; aspect-ratio:5/7; object-fit:cover; object-position:top; border-radius:10px;
  border:1px solid var(--line-2); filter:saturate(.65); box-shadow:0 24px 60px rgba(0,0,0,.55); }
.sc-pages img:nth-child(1) { transform:translateY(8%) rotate(-3deg); }
.sc-pages img:nth-child(2) { transform:translateY(3%) rotate(-1.5deg); }
.sc-pages img:nth-child(3) { transform:none; position:relative; z-index:1; }
.sc-pages img:nth-child(4) { transform:translateY(3%) rotate(1.5deg); }
.sc-pages img:nth-child(5) { transform:translateY(8%) rotate(3deg); }
.sc-hero .sc-stats { margin-top:clamp(6px,1vw,14px); }

/* a number laid over the whole canvas */
.sc-over { display:grid; }
.sc-over > * { grid-area:1 / 1; }
.sc-over > img { opacity:.55; }
.sc-over .sc-count { align-self:center; justify-self:center; flex-direction:column; align-items:center; gap:12px; margin:0; text-align:center;
  padding:clamp(18px,2.4vw,30px) clamp(24px,3.4vw,48px); border-radius:16px; background:rgba(10,9,8,.82); box-shadow:0 30px 80px rgba(0,0,0,.6); }
.sc-over .sc-count b { font-size:clamp(64px,8vw,128px); color:var(--bone); }
@media (max-width:560px) { .sc-pages { grid-template-columns:repeat(3, minmax(0,1fr)); } .sc-pages img:nth-child(n+4) { display:none; } }
/* the canvas carries a filter, which paints it above unpositioned siblings; lift the number back over it */
.sc-over .sc-count { position:relative; z-index:1; }

/* the research report, set as the document it was */
.sc-doc { max-width:500px; margin:0 auto; padding:clamp(24px,3vw,42px); border-radius:6px; background:#edeae3; color:#1a1815;
  transform:rotate(-1.2deg); box-shadow:0 40px 90px rgba(0,0,0,.6), inset 0 0 0 1px rgba(0,0,0,.06); font-family:var(--serif); }
.sc-doc .d-k { display:block; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:#6b645a; }
.sc-doc h3 { margin:8px 0 16px; font-weight:700; font-size:clamp(var(--t1),2.4vw,var(--t3)); line-height:1.1; letter-spacing:-.01em; }
.sc-doc .d-find { margin:0 0 24px; padding-left:14px; border-left:3px solid var(--rust); font-size:var(--t0); line-height:1.5; }
.sc-doc .d-find b { font-weight:700; }
.sc-doc ol { list-style:none; margin:10px 0 0; padding:0; counter-reset:rec; }
.sc-doc li { position:relative; counter-increment:rec; padding:11px 0 11px 36px; border-top:1px solid rgba(0,0,0,.12); font-size:var(--t-1); line-height:1.4; }
.sc-doc li::before { content:counter(rec); position:absolute; left:0; top:10px; width:22px; height:22px; border-radius:50%; border:1px solid #1a1815;
  display:grid; place-items:center; font-family:var(--font-mono); font-size:var(--t-2); }
.sc-doc li.hi { font-weight:700; }
.sc-doc li.hi::before { background:var(--rust); border-color:var(--rust); color:#edeae3; }

/* before / after phones where the before carries a pin: dim the screen, not the pin */
.sc-ba.pinned .sc-col:first-child .ph { opacity:1; filter:none; }
.sc-ba.pinned .sc-col:first-child .ph .cap { filter:saturate(.55); opacity:.82; }
.sc-pin.below span { left:0; top:16px; transform:translateX(-50%); }
@media (max-width:560px) { .sc-pin.below span { display:block; font-size:11px; padding:2px 6px 1px; } }
.sc-pin.above span { left:0; top:auto; bottom:16px; transform:translateX(-50%); }
@media (max-width:560px) { .sc-pin.above span { display:block; font-size:11px; padding:2px 6px 1px; } }

/* an outline around the part of an old screen a section is about; the words go in the caption, not on the screen */
.sc-mark { position:absolute; z-index:5; border:2px solid var(--rust); border-radius:9px; pointer-events:none;
  box-shadow:0 0 0 3px rgba(236,34,34,.22), 0 0 22px rgba(236,34,34,.45); }
/* the pin ring and the outline are traced once with the spine's pen, after the
   screen has soaked in; the glow settles after the stroke closes, then all of it stays still */
.pen { border-color:transparent !important; box-shadow:none !important; }
.pen > svg { position:absolute; inset:-2px; width:calc(100% + 4px); height:calc(100% + 4px); overflow:visible; }
.pen > svg > * { fill:none; stroke:var(--rust); stroke-width:2.2; stroke-linecap:round; stroke-dasharray:1; stroke-dashoffset:0; }
.sc-mark.pen > svg > rect { x:2px; y:2px; width:calc(100% - 4px); height:calc(100% - 4px); rx:8px; }
.sc-web .sc-mark.pen > svg > rect { rx:5px; }
.sc-pin i.pen > svg > circle { cx:11px; cy:11px; r:9px; }
.pen::after { content:''; position:absolute; inset:-2px; border-radius:inherit; pointer-events:none;
  box-shadow:0 0 0 3px rgba(236,34,34,.22), 0 0 22px rgba(236,34,34,.45); }
.sc-pin i.pen::after { box-shadow:0 0 0 4px rgba(236,34,34,.25), 0 0 18px rgba(236,34,34,.6); }
.js .pen > svg > * { transition:stroke-dashoffset 1.1s cubic-bezier(.45,0,.2,1) .7s; }
.js .sc-pin i.pen > svg > * { transition-duration:.7s; }
.js .pen::after { transition:opacity .6s linear 1.6s; }
.js .sc-stage.rev:not(.in) .pen > svg > * { stroke-dashoffset:1; }
.js .sc-stage.rev:not(.in) .pen::after { opacity:0; }
.sc-ba.pinned .sc-col:first-child .sc-lbl { color:var(--dim); }
/* the crop box has a fixed height; without this the flex row stretched every phone to it and squashed the screens */
.sc-crop { align-items:flex-start; }
.sc-crop .ph { flex:none; }

/* hero as a before → after */
.sc-duo { display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); align-items:center; gap:clamp(10px,3vw,48px); max-width:calc(860 * var(--u)); margin:0 auto; }
.sc-duo .ph { width:min(calc(300 * var(--u)), 100%); }
.sc-duo .sc-col:first-child .ph .cap { filter:saturate(.55); opacity:.82; }
.sc-arrow { font-family:var(--serif); font-size:clamp(30px,4vw,60px); line-height:1; color:var(--rust); }
.sc-hero .sc-duo .sc-lbl.on { color:var(--bone); }

/* the drop: two bars and the gap between them */
.sc-drop { max-width:560px; margin:0 auto; display:flex; flex-direction:column; justify-content:center; min-height:clamp(260px,26vw,380px); }
.sc-drop .fr { padding:14px 0; }
.sc-drop .fr .fl { font-size:var(--t0); }
.sc-drop .fr .fb { height:clamp(12px,1.1vw,16px); }
.sc-gap { display:flex; align-items:baseline; gap:12px; margin-top:clamp(16px,2vw,26px); }
.sc-gap b { font-family:var(--serif); font-weight:700; font-size:clamp(52px,6vw,92px); line-height:.9; color:var(--rust); letter-spacing:-.03em; }
.sc-gap span { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }

/* three places become one */
.sc-flow { display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); align-items:center; gap:clamp(12px,2.4vw,32px); max-width:720px; margin:0 auto; }
.f-col { display:flex; flex-direction:column; gap:10px; min-width:0; }
.f-k { font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); margin-bottom:2px; }
.f-box { border:1px solid var(--line); border-radius:12px; padding:12px 14px; background:rgba(237,234,227,.03); }
.f-box b { display:block; font-family:var(--serif); font-weight:700; font-size:var(--t0); color:var(--bone); }
.f-box > span { display:block; margin-top:3px; font-size:var(--t-1); line-height:1.4; color:var(--dim); }
.f-box.warn { border-style:dashed; border-color:rgba(236,34,34,.75); }
.f-box.warn b { color:var(--rust); }
.f-box.one { border-color:rgba(237,234,227,.4); padding:18px; box-shadow:0 30px 70px rgba(0,0,0,.45); }
.f-box.one ul { list-style:none; margin:12px 0 0; padding:0; display:flex; flex-direction:column; gap:10px; }
.f-box.one li { position:relative; padding-left:18px; font-size:var(--t-1); color:var(--bone); }
.f-box.one li::before { content:''; position:absolute; left:0; top:.5em; width:8px; height:8px; border-radius:50%; background:var(--rust); }

@media (max-width:640px) {
  .sc-flow { grid-template-columns:1fr; }
  .sc-flow .sc-arrow { transform:rotate(90deg); justify-self:center; }
  .sc-duo { gap:8px; }
  .sc-duo .sc-arrow { font-size:24px; }
}

/* ---------- the limit, animated: 2022 cells shrink to values and the third plan slides in ---------- */
.sc-morph { gap:22px; }
.sc-morph .m-canvas { container-type:inline-size; } /* keeps the width change inside the diagram */
.sc-morph .m-canvas > span { transition:translate .9s var(--ease), width .9s var(--ease), opacity .6s var(--ease), color .6s var(--ease), background-color .6s var(--ease), border-color .6s var(--ease); }
.sc-morph.is-b .m-canvas > span { translate:calc((var(--x2, var(--x)) - var(--x)) / 520 * 100cqw) 0; width:calc(var(--w2, var(--w)) / 520 * 100%); }
.sc-morph .m-cell { overflow:hidden; }
.sc-morph .m-cell .a, .sc-morph .m-cell .b, .sc-morph .m-k .a, .sc-morph .m-k .b,
.sc-morph .m-dim .a, .sc-morph .m-dim .b { grid-area:1/1; transition:opacity .45s var(--ease); }
.sc-morph .m-k { display:grid; }
.sc-morph .m-dim { display:grid; place-items:center; }
.sc-morph .b { opacity:0; }
.sc-morph.is-b .a { opacity:0; }
.sc-morph.is-b .b { opacity:1; transition-delay:.35s; }
.sc-morph .m-cell.lbl { opacity:0; }
.sc-morph.is-b .m-cell.lbl { opacity:1; transition-delay:.3s; }
.sc-morph.is-b .m-cell.ghost { background:#f5f4f0; color:#1d2329; border-color:transparent; box-shadow:inset 0 0 0 1px rgba(0,0,0,.08); }
.sc-morph.is-b .m-dim.over { color:var(--bone); border-top-color:var(--line); }
.m-ctl { display:flex; gap:6px; justify-content:center; }
.m-ctl button { font:inherit; font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--dim); background:none;
  border:1px solid var(--line); border-radius:999px; padding:7px 13px; cursor:pointer; transition:color .3s, border-color .3s, background-color .3s; }
.m-ctl button[aria-pressed="true"] { color:var(--ink, #111); background:var(--bone); border-color:var(--bone); }
.m-ctl button:focus-visible { outline:2px solid var(--rust); outline-offset:2px; }
@media (prefers-reduced-motion:reduce) { .sc-morph .m-canvas > span, .sc-morph .a, .sc-morph .b { transition:none; } }
.sc-morph .m-k { margin-bottom:30px; }
.sc-morph .m-screen i { display:grid; }
.sc-morph .m-screen i > span { grid-area:1/1; justify-self:end; transition:opacity .45s var(--ease); }

/* ---------- phones: no phone-in-a-phone pairs, no scroll-trapping embeds ---------- */
.sc-flip, .sc-open, .m-only { display:none; }
@media (max-width:640px) {
  /* before / after share one spot; a switch flips between them, opening on After */
  .sc-flip { display:flex; gap:2px; width:max-content; margin:0 auto 18px; padding:3px; border:1px solid var(--line); border-radius:999px; }
  .sc-flip button { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim);
    background:none; border:0; border-radius:999px; min-height:36px; padding:0 18px; cursor:pointer; transition:color .3s, background-color .3s; }
  .sc-flip button[aria-pressed="true"] { background:var(--bone); color:#141210; }
  .sc-flip button:focus-visible { outline:2px solid var(--rust); outline-offset:2px; }
  .sc-ba { grid-template-columns:1fr; gap:0; }
  .sc-ba > .sc-col { grid-area:1/1; transition:opacity .35s var(--ease), visibility 0s; }
  .sc-ba[data-show="after"] > .sc-col:first-child, .sc-ba[data-show="before"] > .sc-col:last-child {
    opacity:0; visibility:hidden; pointer-events:none; transition:opacity .35s var(--ease), visibility 0s .35s; }
  .sc-ba .ph, .sc-one .ph { width:min(300px, 88%); }

  /* live prototypes open full screen instead of scrolling inside the page */
  .ph .scr > iframe.cap { display:none; }
  .sc-open { display:block; position:absolute; top:5.4%; left:0; right:0; bottom:0; z-index:3; background:#fff; color:#141210; text-decoration:none; }
  .sc-open img { width:100%; height:100%; object-fit:cover; object-position:top; display:block; }
  .sc-open::before { content:""; position:absolute; inset:45% 0 0; background:linear-gradient(to bottom, rgba(20,18,16,0), rgba(20,18,16,.72)); }
  .sc-open span { position:absolute; left:50%; bottom:9%; transform:translateX(-50%); white-space:nowrap; font-size:var(--t-2); letter-spacing:.14em;
    text-transform:uppercase; background:var(--bone); color:#141210; border-radius:999px; padding:13px 20px; box-shadow:0 10px 30px rgba(0,0,0,.35); }
  .d-only { display:none; }
  .m-only { display:inline; }

  /* heroes swipe sideways, the next phone peeking in */
  .sc-trio, .sc-duo { display:flex; gap:14px; overflow-x:auto; scroll-snap-type:x mandatory; padding:0 12% 4px; scrollbar-width:none; max-width:none; align-items:flex-start; }
  .sc-trio::-webkit-scrollbar, .sc-duo::-webkit-scrollbar { display:none; }
  .sc-trio > .sc-col, .sc-duo > .sc-col { flex:0 0 76%; scroll-snap-align:center; }
  .sc-duo > .sc-arrow { display:none; }
  .sc-trio .ph, .sc-duo .ph { width:100%; }
  .sc-hero .sc-crop { height:clamp(360px, 108vw, 460px); }
  .sc-count { flex-direction:row; gap:10px; align-items:baseline; }
  .sc-count span { font-size:var(--t-2); text-align:left; }
}


/* ---------- the length of a section, drawn to scale: each column draws in, the long one takes longer ---------- */
.sc-len { display:grid; grid-template-columns:repeat(2, minmax(0,calc(140 * var(--u)))); justify-content:center; align-items:start; gap:clamp(28px,7vw,96px); }
.sc-len .l-col { display:flex; flex-direction:column; gap:12px; min-width:0; }
.sc-len .l-k { display:flex; flex-direction:column; gap:4px; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.sc-len .l-k b { font-family:var(--serif); font-weight:700; font-size:clamp(var(--t2),2.6vw,var(--t3)); line-height:1; letter-spacing:-.02em; text-transform:none; color:var(--bone); }
.sc-len .l-col.hot .l-k b { color:var(--rust); }
.sc-len img { display:block; width:100%; height:auto; border-radius:8px; box-shadow:0 0 0 1px rgba(237,234,227,.18), 0 30px 70px rgba(0,0,0,.5); }
.js .sc-len img { clip-path:inset(0 0 100% 0 round 8px); transition:clip-path .9s var(--ease) .2s; }
.js .sc-len .l-col.hot img { transition-duration:2.4s; }
.js .sc-len.drawn img { clip-path:inset(0 0 0 0 round 8px); }
@media (prefers-reduced-motion:reduce) { .js .sc-len img { clip-path:none; transition:none; } }

/* ---------- desktop screens: a quiet browser frame, sized to 16:10 ---------- */
.sc-web { position:relative; margin:0 auto; width:min(calc(980 * var(--u)), 100%); border-radius:12px; overflow:hidden; background:#0d0d10;
  box-shadow:inset 0 0 0 1px rgba(237,234,227,.18), 0 40px 90px rgba(0,0,0,.6); }
.sc-web .bar { position:relative; display:flex; align-items:center; gap:6px; height:30px; padding:0 12px; background:#19191d; border-bottom:1px solid rgba(237,234,227,.08); }
.sc-web .bar i { width:9px; height:9px; border-radius:50%; background:rgba(237,234,227,.18); }
.sc-web .bar span { position:absolute; left:50%; transform:translateX(-50%); font-family:var(--font-mono); font-size:12px; letter-spacing:.04em;
  color:var(--dim); background:rgba(237,234,227,.06); border-radius:6px; padding:3px 14px; white-space:nowrap; max-width:70%; overflow:hidden; text-overflow:ellipsis; }
.sc-web .view { position:relative; aspect-ratio:16 / 10; overflow:hidden; background:#fff; }
.sc-web .view > img, .sc-web .view > video { display:block; width:100%; height:100%; object-fit:cover; object-position:top; }
.sc-web.tall .view { aspect-ratio:auto; }
.sc-web.tall .view > img { height:auto; }
.sc-web .sc-mark { border-radius:6px; }

/* hero: the live page on a desktop, with the phone in front of it */
.sc-webduo { position:relative; max-width:calc(1060 * var(--u)); margin:0 auto; padding-bottom:clamp(24px, 4vw, 56px); }
.sc-webduo .sc-web { width:86%; margin:0; }
.sc-webduo .ph { position:absolute; right:0; bottom:0; width:min(calc(250 * var(--u)), 24%); }

/* three directions, the chosen one lit */
.sc-dirs { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(12px, 2vw, 24px); align-items:start; }
.sc-dirs .sc-web { width:100%; border-radius:8px; opacity:.6; filter:saturate(.55); transition:opacity .4s var(--ease), filter .4s var(--ease); }
.sc-dirs .sc-web .bar { height:16px; padding:0 7px; gap:4px; } .sc-dirs .sc-web .bar i { width:5px; height:5px; } .sc-dirs .sc-web .bar span { display:none; }
.sc-dirs .sc-web .view { aspect-ratio:2 / 1; }
.sc-dirs .pick .sc-web { opacity:1; filter:none; box-shadow:0 0 0 2px var(--rust), 0 30px 70px rgba(0,0,0,.55); }
.sc-dirs .sc-lbl { margin-top:12px; }

/* outcome: the prototype behind, the live page in front */
.sc-cascade { position:relative; padding-bottom:clamp(90px, 14vw, 180px); }
.sc-cascade .sc-web { width:80%; margin:0; }
.sc-cascade .sc-web:first-child { opacity:.7; }
.sc-cascade .sc-web + .sc-web { position:absolute; right:0; bottom:0; }

@media (max-width:640px) {
  .sc-webduo .sc-web { width:100%; }
  .sc-webduo .ph { position:relative; width:48%; margin:-34% 0 0 auto; }
  .sc-dirs { grid-template-columns:1fr; }
  .sc-web .bar span { font-size:11px; }
}
/* hero: keep the phone off the live page's pitch; it overlaps only the empty lower-right corner */
.sc-webduo { padding-bottom:22%; }
.sc-webduo .sc-web { width:84%; }
.sc-webduo .ph { width:20%; }
@media (max-width:640px) {
  .sc-webduo { padding-bottom:0; }
  .sc-webduo .sc-web { width:100%; }
  .sc-webduo .ph { width:48%; }
}

/* ---------- how I worked: the loop steps through Figma, Claude Code, a working page and my call ---------- */
.sc-loop { max-width:880px; margin:0 auto; }
.sc-loop ol { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:clamp(10px, 1.6vw, 20px); position:relative; }
.sc-loop li { position:relative; border:1px solid var(--line); border-radius:14px; padding:clamp(14px,1.6vw,20px); background:rgba(237,234,227,.03);
  transition:border-color .5s var(--ease), background-color .5s var(--ease), box-shadow .5s var(--ease), transform .5s var(--ease); }
.sc-loop li + li::before { content:''; position:absolute; top:50%; right:100%; width:clamp(10px, 1.6vw, 20px); height:1px; background:var(--line); }
.sc-loop li .k { display:block; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); margin-bottom:22px; transition:color .5s var(--ease); }
.sc-loop li b { display:block; font-family:var(--serif); font-weight:700; font-size:var(--t0); color:var(--bone); }
.sc-loop li span:last-child { display:block; margin-top:6px; font-size:var(--t-1); line-height:1.4; color:var(--dim); }
.sc-loop li.on { border-color:rgba(236,34,34,.9); background:rgba(236,34,34,.08); box-shadow:0 0 0 3px rgba(236,34,34,.16), 0 24px 60px rgba(0,0,0,.45); transform:translateY(-4px); }
.sc-loop li.on .k { color:var(--rust); }
.sc-loop .l-back { position:relative; margin:22px 4% 26px; height:28px; border:1px dashed var(--line); border-top:0; border-radius:0 0 14px 14px; }
.sc-loop .l-back span { position:absolute; left:50%; bottom:-22px; transform:translateX(-50%); padding:0 10px; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--dim); white-space:nowrap; }
.sc-loop .l-back::after { content:''; position:absolute; left:-4px; top:-5px; width:8px; height:8px; border-radius:50%; background:var(--rust); opacity:0; }
.sc-loop.back .l-back { border-color:rgba(236,34,34,.7); }
.sc-loop.back .l-back span { color:var(--rust); }
@media (max-width:640px) {
  .sc-loop ol { grid-template-columns:1fr 1fr; }
  .sc-loop li + li::before { display:none; }
  .sc-loop li .k { margin-bottom:10px; }
}
@media (prefers-reduced-motion:reduce) { .sc-loop li { transition:none; transform:none!important; } }

/* ---------- two handoffs: 27 spec sheets fold away, one link and six widths arrive ---------- */
.sc-hand { max-width:720px; margin:0 auto; display:flex; flex-direction:column; gap:22px; }
.sc-hand .h-stage { display:grid; border:1px solid var(--line); border-radius:16px; padding:clamp(18px,3vw,34px); background:rgba(237,234,227,.02); }
.sc-hand .h-a, .sc-hand .h-b { grid-area:1/1; display:flex; flex-direction:column; gap:18px; transition:opacity .5s var(--ease); }
.sc-hand .h-cap b { display:block; font-family:var(--serif); font-weight:700; font-size:var(--t1); color:var(--bone); }
.sc-hand .h-cap span { display:block; margin-top:4px; font-size:var(--t-1); color:var(--dim); }
.sc-hand .h-sheets { display:grid; grid-template-columns:repeat(9, minmax(0,1fr)); gap:6px; }
.sc-hand .h-sheets i { aspect-ratio:3 / 4; border-radius:3px; background:repeating-linear-gradient(180deg, rgba(237,234,227,.16) 0 2px, transparent 2px 7px) 18% 22% / 64% 60% no-repeat, rgba(237,234,227,.05);
  box-shadow:inset 0 0 0 1px rgba(236,34,34,.45); transition:transform .5s var(--ease), opacity .45s var(--ease); transition-delay:calc(var(--i) * 14ms); }
.sc-hand .h-link { display:flex; align-items:center; gap:10px; width:max-content; max-width:100%; padding:10px 16px; border-radius:999px; border:1px solid rgba(236,34,34,.9);
  box-shadow:0 0 0 3px rgba(236,34,34,.16); font-family:var(--font-mono); font-size:var(--t-1); color:var(--bone); transition:transform .6s var(--ease), opacity .5s var(--ease); }
.sc-hand .h-link i { width:8px; height:8px; border-radius:50%; background:var(--rust); }
.sc-hand .h-bps { display:flex; flex-direction:column; gap:7px; }
.sc-hand .h-bps span { display:flex; align-items:center; height:22px; width:var(--w); padding-left:9px; border-radius:5px; background:rgba(237,234,227,.07); box-shadow:inset 0 0 0 1px rgba(237,234,227,.16);
  font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.06em; color:var(--dim); transform-origin:left; transition:transform .6s var(--ease), opacity .4s var(--ease); transition-delay:calc(.25s + var(--i) * 70ms); }
.sc-hand .h-b { opacity:0; pointer-events:none; }
.sc-hand .h-b .h-link { transform:translateY(10px); opacity:0; }
.sc-hand .h-b .h-bps span { transform:scaleX(.15); opacity:0; }
.sc-hand.is-b .h-a { opacity:0; transition-delay:.3s; }
.sc-hand.is-b .h-a .h-sheets i { transform:scale(.2); opacity:0; }
.sc-hand.is-b .h-b { opacity:1; pointer-events:auto; }
.sc-hand.is-b .h-b .h-link { transform:none; opacity:1; transition-delay:.2s; }
.sc-hand.is-b .h-b .h-bps span { transform:none; opacity:1; }
@media (max-width:640px) { .sc-hand .h-sheets { grid-template-columns:repeat(9, minmax(0,1fr)); gap:4px; } }
@media (prefers-reduced-motion:reduce) { .sc-hand *, .sc-hand .h-a, .sc-hand .h-b { transition:none!important; } }

/* ---------- how the work moved: four steps ---------- */
.sc-steps { max-width:880px; margin:0 auto; }
.sc-steps ol { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:clamp(10px, 1.6vw, 18px); counter-reset:step; }
.sc-steps li { position:relative; display:flex; flex-direction:column; border:1px solid var(--line); border-radius:14px; padding:clamp(14px,1.6vw,20px); background:rgba(237,234,227,.03);
  transition:border-color .5s var(--ease), background-color .5s var(--ease), box-shadow .5s var(--ease), transform .5s var(--ease); }
.sc-steps li .k { font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); transition:color .5s var(--ease); }
.sc-steps li b { display:block; margin-top:14px; font-family:var(--serif); font-weight:700; font-size:var(--t0); color:var(--bone); }
.sc-steps li .d { display:block; margin:5px 0 4px; font-size:var(--t-1); line-height:1.4; color:var(--dim); }
.sc-steps .who { margin-top:auto; align-self:flex-start; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; padding:4px 9px; border-radius:999px; border:1px solid var(--line); color:var(--dim); }
.sc-steps .who.ai { border-color:rgba(236,34,34,.55); color:#f36a60; background:rgba(236,34,34,.08); }
.sc-steps .who.me { border-color:rgba(237,234,227,.35); color:var(--bone); }
.sc-steps li.on { border-color:rgba(236,34,34,.9); background:rgba(236,34,34,.08); box-shadow:0 0 0 3px rgba(236,34,34,.16), 0 24px 60px rgba(0,0,0,.45); transform:translateY(-4px); }
.sc-steps li.on .k { color:var(--rust); }
.sc-steps .s-key { display:flex; gap:14px; justify-content:center; margin-top:20px; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.12em; text-transform:uppercase; color:var(--dim); }
@media (max-width:640px) { .sc-steps ol { grid-template-columns:1fr 1fr; } }
@media (prefers-reduced-motion:reduce) { .sc-steps li { transition:none; transform:none!important; } }
/* ownership: every step is mine; Claude Code shows only as the tool on the steps it sped up */
.sc-steps .whos { margin-top:auto; display:flex; flex-wrap:wrap; gap:6px; }
.sc-steps .whos .who { margin-top:0; }
.sc-steps .who { white-space:nowrap; }
@media (max-width:640px) { .sc-steps .who { font-size:11px; letter-spacing:.08em; padding:4px 8px; } }

/* ---------- one big frame at a time: directions and handover views cycle, buttons pick ---------- */
.sc-tabs { max-width:calc(980 * var(--u)); margin:0 auto; display:flex; flex-direction:column; gap:18px; }
.sc-tabs .t-stage { display:grid; }
.sc-tabs .t-stage > .sc-web { grid-area:1/1; width:100%; opacity:0; visibility:hidden; transition:opacity .6s var(--ease), visibility 0s .6s; }
.sc-tabs .t-stage > .sc-web.on { opacity:1; visibility:visible; transition:opacity .6s var(--ease), visibility 0s; }
.sc-tabs.wide .sc-web .view { aspect-ratio:1400 / 715; }
.sc-tabs.fit .sc-web .view { background:#2a2a2d; }
.sc-tabs.fit .sc-web .view > img { object-fit:contain; object-position:center; }
.sc-tabs .m-ctl { flex-wrap:wrap; }
@media (prefers-reduced-motion:reduce) { .sc-tabs .t-stage > .sc-web { transition:none; } }

/* =====================================================================
   Homepage personality: handwriting, real screens that bleed in
   ===================================================================== */
@property --b { syntax:'<length-percentage>'; inherits:false; initial-value:0%; }

/* hero: a handwritten hello with a drawn arrow down into the name */
.hero--full .ch.hi { font-family:var(--serif); font-style:italic; font-size:clamp(var(--t1),2vw,var(--t2)); letter-spacing:0; text-transform:none; color:var(--bone); gap:0; position:relative; filter:url(#ink-lg); }
.ch.hi .hi-arr { position:absolute; left:calc(100% + 6px); top:.2em; width:clamp(60px,6vw,96px); height:auto; overflow:visible; }

/* hand-drawn strokes draw in once seen */
.hand-path { fill:none; stroke:var(--bone); stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; filter:url(#ink-line);
  stroke-dasharray:var(--len, 240); stroke-dashoffset:0; }
.js .hand-path { stroke-dashoffset:var(--len, 240); transition:stroke-dashoffset 1.1s var(--ease) .25s; }
.js .drawn .hand-path { stroke-dashoffset:0; }


/* cards: real screens soak in from a blot the first time they're seen */
.card-media > .device, .card-media > .ph { -webkit-mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%)); mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%)); --b:160%; }
.js .card-media > .device, .js .card-media > .ph { --b:0%; transition:--b 1.5s var(--ease) .1s, transform .9s var(--ease); }
.js .card-media.bled > .device, .js .card-media.bled > .ph { --b:160%; }
.js .card-media.bled > .ph.pr { transition-delay:.35s, 0s; }
@media (prefers-reduced-motion:reduce) { .js .card-media > .device, .js .card-media > .ph { --b:160%; transition:none; } .js .hand-path { stroke-dashoffset:0; transition:none; } }

/* handwritten margin notes on the work */
.card-media .note { position:absolute; z-index:4; left:clamp(16px,3vw,44px); top:clamp(40px,5vw,64px); max-width:15ch; pointer-events:none;
  font-family:var(--serif); font-style:italic; font-size:var(--t1); line-height:1.15; color:var(--bone); transform:rotate(-4deg); }
.card-media .note > span { display:block; filter:url(#ink-lg); }
.card-media .note svg { display:block; width:clamp(70px,7vw,110px); height:auto; margin:6px 0 0 34%; overflow:visible; }
.card-media .note.r { left:auto; right:clamp(16px,3vw,44px); text-align:right; transform:rotate(3deg); }
.card-media .note.r svg { margin:6px 34% 0 auto; transform:scaleX(-1); }
@media (max-width:640px) { .card-media .note { font-size:15px; top:18px; left:14px; } .card-media .note svg { width:54px; } .card-media .note.r { right:14px; } }

/* card 05: two phones, like card 01 */
.card--wide .card-media .ph.pl.cmp { left:28%; } .card--wide .card-media .ph.pr.cmp { left:54%; }
/* small handwriting needs the fine line texture; the heavy one eats them */
.hero--full .ch.hi, .card-media .note > span { filter:url(#ink-line); }

/* card 04: guide pages laid out like printed sheets */
.card-media > .sheets { position:absolute; inset:0; z-index:2; -webkit-mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%)); mask-image:radial-gradient(circle at 50% 62%, #000 var(--b), transparent calc(var(--b) + 14%)); --b:160%; }
.js .card-media > .sheets { --b:0%; transition:--b 1.5s var(--ease) .1s; }
.js .card-media.bled > .sheets { --b:160%; }
.sheets img { position:absolute; top:12%; width:24%; border-radius:6px; box-shadow:0 0 0 1px rgba(0,0,0,.08), 0 30px 60px rgba(0,0,0,.55); transition:transform .9s var(--ease); background:#fff; }
.sheets img:nth-child(1) { left:14%; transform:rotate(-5deg); }
.sheets img:nth-child(2) { left:38%; top:8%; transform:rotate(1.5deg); z-index:1; }
.sheets img:nth-child(3) { left:62%; top:16%; width:22%; transform:rotate(6deg); }
.card:hover .sheets img:nth-child(1) { transform:rotate(-7deg) translateY(-10px); }
.card:hover .sheets img:nth-child(2) { transform:rotate(0deg) translateY(-16px); }
.card:hover .sheets img:nth-child(3) { transform:rotate(8deg) translateY(-10px); }
@media (max-width:640px) { .sheets img { width:30%; } .sheets img:nth-child(1) { left:4%; } .sheets img:nth-child(2) { left:35%; } .sheets img:nth-child(3) { left:66%; width:28%; } }
/* phones: the margin notes collide with the card numbers, so they stay a desktop detail */
@media (max-width:640px) { .card-media .note { display:none; } }

/* ---------- the AJ mark: bone letterform, star in the accent ---------- */
.nav .logo .lg-mark { fill:var(--bone); }
.nav .logo .lg-star { fill:var(--rust); transform-box:fill-box; transform-origin:center; transition:transform .9s var(--ease); }
.nav a.name:hover .logo .lg-star { transform:rotate(90deg) scale(1.12); }
@media (prefers-reduced-motion:reduce) { .nav .logo .lg-star { transition:none; } }

/* card 03 at full width: the live page in a narrower browser, the phone beside it */
.card--wide .card-media.dhw .device { left:12%; right:30%; height:88%; }
.card--wide .card-media.dhw .ph.pr.dh { left:66%; width:17%; bottom:-22%; }
@media (max-width:640px) {
  .card--wide .card-media.dhw .device { left:5%; right:28%; height:86%; }
  .card--wide .card-media.dhw .ph.pr.dh { left:64%; width:32%; bottom:-40%; }
}
.card--wide .card-media.dhw .device { width:auto; }
/* .press > * forces position:relative; the paired frame on card 03 has to stay absolute */
.card--wide .card-media.dhw.press > .device { position:absolute; }


/* ---------- how I work: quiet columns that match the rest of the page, no cards, no ghost numbers ---------- */
.approach { gap:clamp(20px,3vw,44px); }
.acard { background:none; border:0; border-top:1px solid var(--line); border-radius:0; padding:20px 0 0; transform:none!important; }
.acard:hover { background:none; border-color:var(--line); }
.acard::after { display:none; }
.acard .idx { position:static; display:block; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.14em; color:var(--faint-text); margin-bottom:14px; transform:none; }
.acard:hover .idx { color:var(--faint-text); transform:none; }
.acard h3 { font-family:var(--serif); font-weight:700; font-size:var(--t1); }
@media (max-width:900px) { .approach { grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width:520px) { .approach { grid-template-columns:1fr; } }

/* nav: logo stands alone */

/* other work: two quieter pieces under the cards */
.others { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:clamp(20px,3vw,40px); }
.other { margin:0; display:flex; flex-direction:column; gap:22px; }
.o-media { position:relative; aspect-ratio:16/10; border-radius:18px; overflow:hidden; border:1px solid var(--line); background:#0a0a0d; }
.o-murm .o-clip { width:100%; height:100%; object-fit:cover; display:block; transform:scale(1.18); }
.other figcaption { display:flex; flex-direction:column; align-items:flex-start; gap:12px; }
.other figcaption h3 { font-family:var(--serif); font-weight:700; font-size:clamp(var(--t1),2vw,var(--t2)); margin:0; }
.other figcaption p { margin:0; max-width:52ch; }
@media (max-width:760px) { .others { grid-template-columns:1fr; } }

/* how i work: cards again, redrawn */
.approach { gap:clamp(14px,1.6vw,22px); }
.acard { position:relative; display:flex; flex-direction:column; min-height:300px; overflow:hidden;
  background:var(--panel); border:1px solid var(--line-2); border-radius:var(--r); padding:clamp(22px,2vw,28px);
  transition:border-color .4s linear, background .4s linear; }
.acard:hover { background:var(--panel-2); border-color:var(--line); }
.acard::after { display:block; }
.acard .a-top { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:auto; padding-bottom:36px; }
.acard .a-glyph { width:80px; height:48px; overflow:visible; }
.acard .a-glyph .hand-path { transition:stroke-dashoffset 1.1s var(--ease) .25s, stroke .4s linear; }
.acard:hover .a-glyph .hand-path { stroke:var(--rust); }
.acard .idx { margin:0; }
.acard h3 { margin-bottom:10px; }
@media (max-width:900px) { .acard { min-height:250px; } }
@media (max-width:520px) { .acard { min-height:0; } .acard .a-top { padding-bottom:28px; } }
.acard .a-top { margin-bottom:0; padding-bottom:clamp(56px,6vw,84px); }
.acard .a-glyph { width:96px; height:58px; }

/* migration case study */
.mg-ba .mg-ba-view { position:relative; aspect-ratio:1600/1000; overflow:hidden; }
.mg-ba .mg-ba-view img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:top; }
.mg-ba .mg-before { clip-path:inset(0 calc(100% - var(--x)) 0 0); }
.mg-bar { position:absolute; top:0; bottom:0; left:var(--x); width:2px; margin-left:-1px; background:var(--bone); box-shadow:0 0 0 1px rgba(0,0,0,.25); z-index:3; pointer-events:none; }
.mg-knob { position:absolute; left:50%; top:50%; width:44px; height:44px; transform:translate(-50%,-50%); border-radius:50%; background:#0a0908; border:1.5px solid var(--bone); box-shadow:0 8px 22px rgba(0,0,0,.5); }
.mg-knob::before { content:'‹ ›'; position:absolute; inset:0; display:grid; place-items:center; color:var(--bone); font-size:17px; }
.mg-tag { position:absolute; bottom:14px; z-index:3; padding:5px 10px; border-radius:999px; background:rgba(10,9,8,.8); color:var(--bone); font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; pointer-events:none; }
.mg-tag.l { left:14px; } .mg-tag.r { right:14px; }
.mg-range { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:ew-resize; z-index:4; -webkit-appearance:none; appearance:none; }
.mg-ba:has(.mg-range:focus-visible) .mg-knob { border-color:var(--rust); }

.mg-wall { display:flex; flex-direction:column; gap:12px; padding:clamp(18px,3vw,34px) 0; overflow:hidden; border:1px solid var(--line-2); border-radius:18px; background:var(--panel);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent); mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent); }
.mg-row { display:flex; gap:10px; width:max-content; animation:mg-slide 60s linear infinite; }
.mg-row.rev-dir { animation-direction:reverse; animation-duration:72s; }
.mg-row span { white-space:nowrap; padding:10px 16px; border-radius:999px; border:1px solid var(--line); color:var(--bone); font-size:var(--t-1); background:var(--panel-2); }
.mg-row span:nth-child(5n+2) { border-color:rgba(236,34,34,.45); }
@keyframes mg-slide { to { transform:translateX(-50%); } }
.mg-wall:hover .mg-row { animation-play-state:paused; }

.mg-map { display:flex; justify-content:center; padding:clamp(18px,3vw,34px); border:1px solid var(--line-2); border-radius:18px; background:var(--panel); }
.mg-sheet { position:relative; width:min(calc(340 * var(--u)),70%); border-radius:6px; overflow:hidden; box-shadow:0 30px 70px rgba(0,0,0,.5); }
.mg-sheet img { display:block; width:100%; }
.mg-sheet .band { position:absolute; left:0; right:0; border:1.5px solid transparent; background:transparent; transition:background .35s linear, border-color .35s linear; }
.mg-sheet .band b { position:absolute; left:calc(100% + 14px); top:50%; transform:translateY(-50%); white-space:nowrap; font-size:var(--t-2); font-weight:400; letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text); opacity:0; transition:opacity .35s linear; }
.mg-sheet { overflow:visible; }
.mg-sheet img { border-radius:6px; }
.mg-sheet .band.on { border-color:var(--rust); background:rgba(236,34,34,.12); }
.mg-sheet .band.on b { opacity:1; color:var(--bone); }

.mg-duo { display:grid; grid-template-columns:1fr 1fr; gap:clamp(12px,2vw,24px); align-items:start; }
.mg-duo .view { max-height:560px; overflow:hidden; }
@media (max-width:640px) { .mg-duo { grid-template-columns:1fr; } .mg-duo .sc-web + .sc-web { display:none; } .mg-sheet { width:62%; margin-right:30%; } .mg-row span { font-size:13px; } }
@media (prefers-reduced-motion:reduce) { .mg-row { animation:none; } }
.mg-map { height:clamp(420px,46vw,580px); overflow:hidden; align-items:flex-start; position:relative; }
.mg-sheet { transform:translateY(var(--ty,0px)); transition:transform 1s var(--ease); margin-top:clamp(18px,3vw,34px); }
@media (max-width:640px) { .mg-map { height:460px; } }
.mg-duo .view { aspect-ratio:auto; height:clamp(360px,40vw,540px); max-height:none; overflow:hidden; }
.mg-duo .view img { width:100%; height:auto; display:block; }
@media (max-width:640px) { .mg-duo .view { height:420px; } }

/* other work: each piece is a row, media first */
.others { grid-template-columns:1fr; gap:clamp(40px,6vw,88px); }
.other.row { display:grid; grid-template-columns:minmax(0,1.55fr) minmax(0,1fr); gap:clamp(22px,3.5vw,56px); align-items:center; }
.o-objs { aspect-ratio:auto; display:grid; grid-template-columns:1fr 1fr; gap:6px; padding:6px; background:var(--panel); }
.o-objs .o-clip { width:100%; aspect-ratio:1500/1060; object-fit:cover; display:block; border-radius:12px; transform:none; background:#1d1d1f; }
@media (max-width:860px) { .other.row { grid-template-columns:1fr; } }
.o-f1 { background:#000; aspect-ratio:1400/760; }
.o-f1 .o-clip { width:100%; height:100%; object-fit:cover; display:block; transform:none; }
.o-flow { background:#f7f5f2; aspect-ratio:16/9; }
.o-flow .o-clip { width:100%; height:100%; object-fit:cover; display:block; transform:none; }

/* migration card: the 2024 page behind, the live page in front */
.card-media.mgw.press > .device { position:absolute; height:auto; aspect-ratio:1600/1024; }
.card-media.mgw .device.before { left:7%; top:9%; width:52%; right:auto; opacity:.8; }
.card-media.mgw .device.after { left:38%; top:24%; width:55%; right:auto; z-index:2; box-shadow:0 40px 80px rgba(0,0,0,.6); }
.card-media.mgw .device .shot { filter:none; }
.card-media.mgw .device .bar { position:relative; }
.card-media.mgw .device .bar span { position:absolute; left:50%; transform:translateX(-50%); font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint-text); }
.card:hover .card-media.mgw .device.before { transform:translate(-8px,-8px); }
.card:hover .card-media.mgw .device.after { transform:translate(6px,-12px); }
@media (max-width:640px) { .card-media.mgw .device.before { left:4%; width:60%; } .card-media.mgw .device.after { left:34%; width:62%; top:30%; } }
.card-media.mgw .device.before { left:13%; top:17%; width:50%; }
.card-media.mgw .device.after { left:40%; top:37%; width:53%; }
@media (max-width:640px) { .card-media.mgw .device.before { left:6%; top:20%; width:62%; } .card-media.mgw .device.after { left:32%; top:42%; width:64%; } }
@media (min-width:1000px) {
  .card--wide .card-media.mgw .device.before { left:15%; top:12%; width:39%; }
  .card--wide .card-media.mgw .device.after { left:43%; top:27%; width:41%; }
}

/* flow row: the hero prototype inside a browser frame */
.o-flow { aspect-ratio:auto; background:var(--panel); padding:clamp(10px,1.4vw,18px); }
.o-web { border-radius:10px; overflow:hidden; background:#f7f5f2; box-shadow:0 30px 70px rgba(0,0,0,.45); }
.o-web .bar { height:26px; display:flex; align-items:center; gap:5px; padding:0 11px; background:#1d1c1a; position:relative; }
.o-web .bar i { width:7px; height:7px; border-radius:50%; background:rgba(237,234,227,.22); }
.o-web .bar span { position:absolute; left:50%; transform:translateX(-50%); font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--faint-text); white-space:nowrap; }
.o-flow .o-clip { width:100%; height:auto; aspect-ratio:16/9; object-fit:cover; display:block; }

/* homepage cards, one system: screens rise out of the bottom edge, nothing covered, the front screen lifts more on hover */
.card--wide .card-media.dhw.press > .device { top:13%; bottom:-10%; height:auto; left:13%; right:auto; width:52%; }
.card--wide .card-media.dhw .ph.pr.dh { left:69%; width:17%; bottom:-30%; }
.card:hover .card-media.dhw > .device { transform:translateY(-10px); }
.card:hover .card-media.dhw > .ph.pr.dh { transform:translateY(-20px); }
.card-media.mgw.press > .device { aspect-ratio:auto; height:auto; right:auto; opacity:1; }
.card--wide .card-media.mgw .device.before { left:12%; width:44%; top:22%; bottom:-12%; }
.card--wide .card-media.mgw .device.after { left:44%; width:44%; top:11%; bottom:-12%; }
.card-media.mgw .device.before .shot { filter:brightness(.82) saturate(.85); }
.card:hover .card-media.mgw .device.before { transform:translateY(-10px); }
.card:hover .card-media.mgw .device.after { transform:translateY(-20px); }
@media (max-width:1100px) {
  .card--wide .card-media.dhw.press > .device { left:6%; width:60%; top:14%; }
  .card--wide .card-media.dhw .ph.pr.dh { left:68%; width:28%; bottom:-46%; }
  .card--wide .card-media.mgw .device.before { left:5%; width:58%; top:24%; }
  .card--wide .card-media.mgw .device.after { left:37%; width:58%; top:12%; }
}
/* screens inside card windows: full width, anchored to the top, running off the bottom edge */
.card-media.dhw .device .screen, .card-media.mgw .device .screen { overflow:hidden; background:#0f0f10; }
.card-media.dhw .device .shot, .card-media.mgw .device .shot { width:100%; height:auto; object-fit:initial; display:block; }
/* demo hub window: fill the frame when the card gets taller than the screenshot */
.card-media.dhw .device .shot { height:100%; object-fit:cover; object-position:top left; }
/* the window screens wear their clip's first frame: any frame the video can't
   paint (the poster handing over on play, the loop seam, a layer rebuilt on iOS)
   is then a held frame, not the screen's own color */
.card-media.dhw .device .screen { background:#0f0f10 url(img/dh/clip-lspot-card.webp) top left / cover no-repeat; }
.card-media.galw .device.after .screen { background:#0f0f10 url(img/dev/clip-gal.webp) top left / cover no-repeat; }
/* design system sheets: same language as the other cards, upright and rising out of the bottom edge */
.sheets img { top:auto; bottom:-18%; width:25%; transform:none; }
.sheets img:nth-child(1) { left:13%; transform:none; bottom:-30%; }
.sheets img:nth-child(2) { left:39%; transform:none; bottom:-12%; }
.sheets img:nth-child(3) { left:65%; width:25%; transform:none; bottom:-26%; }
.card:hover .sheets img:nth-child(1), .card:hover .sheets img:nth-child(3) { transform:translateY(-10px); }
.card:hover .sheets img:nth-child(2) { transform:translateY(-20px); }
@media (max-width:1100px) { .sheets img { width:30%; } .sheets img:nth-child(1) { left:4%; } .sheets img:nth-child(2) { left:35%; } .sheets img:nth-child(3) { left:66%; width:30%; } }
/* sheets anchored from the top so they load (a lazy image parked below the frame never does), each a full-height page running off the bottom */
.sheets img, .sheets img:nth-child(1), .sheets img:nth-child(2), .sheets img:nth-child(3) { bottom:auto; height:125%; object-fit:contain; object-position:top; background:#fff; }
.sheets img:nth-child(1) { top:24%; }
.sheets img:nth-child(2) { top:10%; }
.sheets img:nth-child(3) { top:20%; }


/* ---------- device swatch demo (cs-device) ----------
   The swatch row is real markup, not a screenshot: the Framer export was a
   palette PNG with a transparent background, so its dark label rendered dark
   on the dark page. Built live it also animates, and section 02 can push the
   same card through real color-vision filters. Neutral sans on white so it
   reads as the product, not as this site. */
.dv-demo { width:100%; display:flex; flex-direction:column; gap:14px; align-items:center; }
.dv-sw { width:100%; max-width:430px; background:#fff; border:1px solid #d7dade; border-radius:10px;
  padding:clamp(15px,2.2vw,22px) clamp(16px,2.4vw,24px); font-family:"Helvetica Neue",Helvetica,Arial,sans-serif; }
.dv-lbl { margin:0 0 14px; font-size:clamp(14px,1.15vw,16px); color:#1e242b; letter-spacing:0; }
.dv-lbl b { font-weight:700; }
.dv-row { display:flex; gap:clamp(10px,1.4vw,16px); }
.dv-dot { width:clamp(34px,3.2vw,44px); aspect-ratio:1; border-radius:50%; border:0; padding:0; cursor:pointer;
  background:var(--c); box-shadow:none; transition:box-shadow .32s var(--ease), transform .32s var(--ease); }
.dv-dot:focus-visible { outline:2px solid #0057b8; outline-offset:4px; }
/* the design: a ring on every swatch, plus an inner shadow so pale finishes read as objects. The selection ring is AT&T blue #0057b8, sampled from the live page */
.dv-demo[data-ring="1"] .dv-dot { box-shadow:inset 0 2px 5px rgba(0,0,0,.17), 0 0 0 1px #878c94; }
.dv-demo[data-ring="1"] .dv-dot[aria-current="true"] { box-shadow:inset 0 2px 5px rgba(0,0,0,.17), 0 0 0 2px #fff, 0 0 0 3px #0057b8; }
.dv-demo[data-ring="0"] .dv-dot[aria-current="true"] { box-shadow:0 0 0 2px #fff, 0 0 0 4px #454b52; }
.dv-ctl { display:flex; gap:8px; }

/* section 02: the same card, twice, under a color-vision filter */
.dv-cvd { width:100%; display:flex; flex-direction:column; gap:16px; align-items:center; }
.dv-pair { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:clamp(12px,1.6vw,22px); width:100%; }
.dv-pair > div { display:flex; flex-direction:column; gap:9px; min-width:0; }
.dv-pair .dv-sw { max-width:none; filter:var(--vf,none); }
.dv-pair .mono { font-size:var(--t-2); color:var(--dim); }
@media (max-width:640px){ .dv-pair { grid-template-columns:1fr; } }

/* ---------- working gallery (cs-device 03) ---------- */
.gv { position:absolute; inset:0; display:flex; flex-direction:column; gap:12px; padding:18px 18px 16px; background:#fff; color:#1d2329; }
.gv-stage, .gl-stage { position:relative; flex:1; min-height:0; }
.gv-stage > img, .gl-stage > img { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; opacity:0; transform:scale(.985);
  transition:opacity .45s var(--ease), transform .6s var(--ease); user-select:none; }
.gv-stage > img.on, .gl-stage > img.on { opacity:1; transform:none; }
.gv-nav, .gv-exp, .gv-x { position:absolute; display:grid; place-items:center; width:40px; height:40px; border-radius:50%; border:1px solid #d7dade;
  background:#fff; color:#1d2329; cursor:pointer; padding:0; transition:border-color .2s, transform .2s var(--ease); }
.gv-nav:hover, .gv-exp:hover, .gv-x:hover { border-color:#0057b8; color:#0057b8; }
.gv-nav:active, .gv-exp:active, .gv-x:active { transform:scale(.94); }
.gv-nav .gl, .gv-exp .gl, .gv-x .gl { width:20px; height:20px; filter:none; }
.gv-prev { left:0; top:50%; margin-top:-20px; } .gv-next { right:0; top:50%; margin-top:-20px; }
.gv-exp { right:0; top:0; }
.gv-count { position:absolute; left:0; top:10px; font-size:12px; letter-spacing:.08em; color:#6b7178; }
.gv-count b { color:#1d2329; font-weight:400; }
.gv-strip { display:flex; gap:8px; justify-content:flex-start; overflow-x:auto; scrollbar-width:none; padding:3px; flex:none; }
.gv-strip::-webkit-scrollbar { display:none; }
.gv-th { flex:none; width:56px; height:56px; padding:4px; border-radius:6px; border:1px solid #d7dade; background:#fff; cursor:pointer; transition:box-shadow .25s, border-color .25s; }
.gv-th img { width:100%; height:100%; object-fit:contain; display:block; }
.gv-th[aria-current="true"] { border-color:transparent; box-shadow:0 0 0 2px #0057b8; }
.gv button:focus-visible, .gv-box button:focus-visible { outline:2px solid #0057b8; outline-offset:3px; }
.gv-box { position:fixed; inset:0; z-index:200; display:grid; place-items:center; padding:clamp(12px,4vw,48px);
  background:rgba(10,9,8,.72); opacity:0; transition:opacity .4s var(--ease); }
.gv-box.open { opacity:1; }
.gv-sheet { position:relative; width:min(1100px,100%); height:min(820px,100%); background:#fff; border-radius:14px; display:flex; flex-direction:column; gap:14px;
  padding:64px clamp(12px,3vw,40px) 20px; color:#1d2329; transform:translateY(18px) scale(.97); transition:transform .5s var(--ease); }
.gv-box.open .gv-sheet { transform:none; }
.gv-x { right:16px; top:14px; }
.gv-sheet .gv-th { width:64px; height:64px; }
@media (max-width:640px) {
  .gv { padding:12px 10px 10px; gap:8px; }
  .gv-th { width:40px; height:40px; padding:3px; }
  .gv-nav, .gv-exp { width:32px; height:32px; } .gv-prev, .gv-next { margin-top:-16px; }
  .gv-sheet .gv-th { width:46px; height:46px; }
}
@media (prefers-reduced-motion: reduce) { .gv-stage > img, .gl-stage > img, .gv-box, .gv-sheet { transition:none; } }
.gv .gl path, .gv-box .gl path { filter:none; }
.gv-strip > :first-child { margin-left:auto; } .gv-strip > :last-child { margin-right:auto; }
.gv, .gv-box, .gv-sheet, .gv-th { box-sizing:border-box; }
.gv-box { grid-template-columns:minmax(0,1fr); grid-template-rows:minmax(0,1fr); } .gv-sheet { justify-self:center; min-width:0; } .gv-strip { min-width:0; max-width:100%; }

/* ---------- 404: the ink ran off ---------- */
.nf { min-height:calc(100svh - 220px); display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:18px; padding:60px 0 40px; }
.nf-ink { position:relative; filter:url(#nf-goo); padding:0 24px 15vh; margin-bottom:-12vh; color:var(--bone); line-height:.8; }
.nf-num { display:block; font-family:var(--font-display, 'Erode'), serif; font-weight:700; font-size:clamp(150px, 30vw, 380px); letter-spacing:-.02em; }
.nf-drop { position:absolute; top:calc(clamp(150px, 30vw, 380px) * .74); left:25%; width:clamp(14px, 2.4vw, 30px); aspect-ratio:1; margin-left:calc(clamp(14px, 2.4vw, 30px) / -2);
  border-radius:50%; background:currentColor; transform:translateY(0) scale(.2); animation:nf-drip 5.2s cubic-bezier(.55,0,.8,.45) infinite; }
.nf-drop.d2 { left:84%; animation-delay:2.1s; animation-duration:6.4s; }
.nf-drop.d3 { left:52%; animation-delay:3.7s; animation-duration:7.2s; width:clamp(10px,1.8vw,22px); }
@keyframes nf-drip {
  0%   { transform:translateY(0) scale(.2, .2); }
  35%  { transform:translateY(4px) scale(1, 1); }
  55%  { transform:translateY(22px) scale(.8, 1.35); }
  88%  { transform:translateY(7vh) scale(.55, .9); }
  100% { transform:translateY(8.5vh) scale(0, 0); }
}
.nf-h { font-size:clamp(34px, 5vw, 60px); line-height:1; margin:0; }
.nf-p { color:var(--dim); max-width:40ch; margin:0 0 10px; }
@media (prefers-reduced-motion: reduce) { .nf-drop { animation:none; transform:scale(.8); } }
@media (max-width:640px) { .nf-ink { filter:url(#nf-goo-s); } }

/* ---------- the photo's note: same hand as the hero's "Hi, I'm" ---------- */
.ap-note { position:absolute; left:14%; top:calc(100% - 6px); display:flex; align-items:flex-end; gap:2px; pointer-events:none; }
.ap-arr { width:46px; height:auto; overflow:visible; flex:none; }
.ap-note span { font-family:var(--serif); font-style:italic; font-size:var(--t1); color:var(--bone); white-space:nowrap; transform:translateY(8px);
  filter:url(#ink-line); clip-path:inset(-20% 100% -20% 0); transition:clip-path .7s var(--ease) .55s; }
.js .about-photo .hand-path { transition:stroke-dashoffset .7s var(--ease); }
.about-photo:not(.drawn) .ap-note span { transition-delay:0s; transition-duration:.35s; }
.about-photo.drawn .ap-note span { clip-path:inset(-20% -10% -20% 0); }
@media (max-width:860px) {
  .ap-note { left:calc(100% + 8px); top:auto; bottom:22%; }
  .ap-note { align-items:center; } .ap-arr { transform:rotate(-90deg) scaleX(-1); }
}
@media (prefers-reduced-motion: reduce) { .ap-note span { transition:none; } }

/* phones: a tapped bead of ink, inside the name's filter so it merges */

/* the name waits for Erode. Measured in the fallback serif it jumped 25% when
   the face landed mid-entrance on a cold load. ink.js adds .up on arrival; the
   animation is the no-matter-what fallback, so the word can never stay hidden.
   Reduced motion never hides it (ink.js bails before it could reveal). */
@media (prefers-reduced-motion: no-preference) {
  .js .hero-name { opacity:0; animation:hero-up .3s linear 1.9s forwards; }
  .js .hero-name.up { opacity:1; animation:none; transition:opacity .3s linear; }
}
@keyframes hero-up { to { opacity:1; } }

/* the work cards play the work: the same prototype and live-page clips the
   case studies use, in the same frames, started in view (index inline script) */
.device .screen video.shot { display:block; width:100%; height:100%; object-fit:cover; object-position:top; }

/* ---------- solo composition: one screen per card, bigger than the frame, in perspective, with depth behind it ---------- */
.card-media.solo { perspective:1500px; }
.card-media.solo .echo { position:absolute; z-index:1; overflow:hidden; pointer-events:none; opacity:.4;
  background:#0c0b0a; box-shadow:0 30px 70px rgba(0,0,0,.5);
  /* the blur, desaturation and dimming are baked into the *-echo images: a live
     blur here costs phones a filter pass, and next to a playing video it broke
     the page-transition snapshot on phones */
  transition:transform .9s var(--ease); transform-style:preserve-3d; }
.card-media.solo .echo img { display:block; width:100%; height:100%; object-fit:cover; object-position:top; }
/* the phone card: tilted like a phone held toward you, its foot running off the bottom edge */
.card--wide .card-media.solo .ph.pl { left:auto; right:16%; top:7%; bottom:auto; width:31%; z-index:3; transform-origin:50% 45%;
  --py:0px; transform:translateY(var(--py)) rotateY(18deg) rotateX(7deg) rotateZ(-6deg);
  box-shadow:-40px 60px 100px rgba(0,0,0,.62), 0 0 0 1px rgba(0,0,0,.4); }
.card--wide .card-media.solo .echo.e-ph { left:24%; top:18%; width:30%; aspect-ratio:390/844; border-radius:14% / 6.5%;
  transform:rotateY(24deg) rotateX(8deg) rotateZ(-11deg) scale(.94); }
.card:hover .card-media.solo .ph.pl { transform:translateY(calc(var(--py) - 10px)) rotateY(13deg) rotateX(5deg) rotateZ(-5deg); }
.card:hover .card-media.solo .echo.e-ph { transform:rotateY(20deg) rotateX(7deg) rotateZ(-10deg) scale(.94) translateY(-4px); }
/* the desktop card: the window leans back and runs off the bottom right corner */
.card--wide .card-media.dhw.solo.press > .device { left:22%; right:auto; width:84%; top:11%; bottom:-24%; height:auto; z-index:3; transform-origin:0 50%;
  --py:0px; transform:translateY(var(--py)) rotateY(-14deg) rotateX(6deg) rotateZ(2deg); border-radius:14px; border-bottom:1px solid rgba(237,234,227,.16);
  box-shadow:-30px 60px 110px rgba(0,0,0,.65); }
.card--wide .card-media.dhw.solo .echo.e-ph { left:7%; top:16%; width:20%; aspect-ratio:390/844; border-radius:14% / 6.5%;
  transform:rotateY(22deg) rotateX(6deg) rotateZ(-8deg); }
.card:hover .card-media.dhw.solo > .device { transform:translateY(calc(var(--py) - 10px)) rotateY(-10deg) rotateX(4deg) rotateZ(1.5deg); }
.card-media.dhw.solo .device .shot { object-position:top left; }
@media (max-width:860px) {
  .card--wide .card-media.solo .ph.pl { right:8%; top:6%; width:58%; }
  .card--wide .card-media.solo .echo.e-ph { left:6%; top:22%; width:52%; }
  .card--wide .card-media.dhw.solo.press > .device { left:14%; width:110%; top:14%; }
  .card--wide .card-media.dhw.solo .echo.e-ph { left:-2%; width:32%; }
}
/* card 02: the window keeps the page's own aspect so the whole hub shows, and runs off the right edge only a little */
.card--wide .card-media.dhw.solo.press > .device { left:17%; width:92%; top:12%; bottom:auto; aspect-ratio:1440/924; transform:translateY(var(--py)) rotateY(-11deg) rotateX(5deg) rotateZ(1.5deg); }
.card-media.dhw.solo .device .screen:has(.shot) { height:auto; }
.card-media.dhw.solo .device .shot { height:auto; object-fit:initial; }
@media (max-width:860px) { .card--wide .card-media.dhw.solo.press > .device { left:8%; width:120%; top:14%; } }
.card--wide .card-media.dsw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { position:absolute; }

/* solo, rolled out: 03 pans the live page, 04 drifts over the Figma canvas, 05 plays the gallery */
.card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.dsw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after {
  position:absolute; left:17%; width:92%; top:12%; bottom:auto; right:auto; aspect-ratio:1440/924; height:auto; z-index:3; transform-origin:0 50%; opacity:1;
  --py:0px; transform:translateY(var(--py)) rotateY(-11deg) rotateX(5deg) rotateZ(1.5deg); border-radius:14px; border-bottom:1px solid rgba(237,234,227,.16);
  box-shadow:-30px 60px 110px rgba(0,0,0,.65); }
.card:hover .card-media.mgw.solo > .device.after, .card:hover .card-media.dsw.solo > .device.after, .card:hover .card-media.galw.solo > .device.after { transform:translateY(calc(var(--py) - 10px)) rotateY(-8deg) rotateX(4deg) rotateZ(1deg); }
.card-media.solo .device .screen.drift { position:relative; height:calc(100% - 24px); overflow:hidden; background:#fff; padding:0; display:block; }
/* no CSS filter on a playing video: iOS takes the clip off the hardware path for it.
   The card's window clip carries its desaturation baked in (clip-lspot-card.mp4) */
.card-media.dhw .device video.shot { filter:none; }
.ph video.cap { filter:none; }
.card-media.solo .device .screen.drift .shot { display:block; width:100%; height:auto; object-fit:initial; filter:none; will-change:transform; transform-origin:50% 50%; animation:canvas-drift 44s cubic-bezier(.45,0,.55,1) infinite alternate; }
.card-media.solo .echo.e-web { aspect-ratio:5/6; border-radius:8px; }
.card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.dsw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { left:4%; top:14%; width:30%; transform:rotateY(22deg) rotateX(6deg) rotateZ(-6deg); }
.card-media.mgw.solo .device.after .shot, .card-media.galw.solo .device .shot { filter:none; }
/* 05: the gallery clip keeps its own aspect */
.card--wide .card-media.galw.solo.press > .device.after { aspect-ratio:1348/866; }
.card-media.galw.solo .device .screen:has(.shot) { height:auto; }
.card-media.galw.solo .device video.shot { display:block; height:auto; width:100%; object-fit:initial; }
@media (prefers-reduced-motion:reduce) { .card-media.solo .device .screen.drift .shot { animation:none; } }
.card:hover .screen.drift .shot, .card:focus-visible .screen.drift .shot { animation-play-state:paused; }
/* set by app.js while a loop is off screen */
.rest { animation-play-state:paused !important; }
@media (max-width:860px) {
  .card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.dsw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { left:8%; width:120%; top:14%; }
  .card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.dsw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { left:-4%; width:34%; }
}
/* desktop cards alternate: 02 and 04 lean off the right edge, 03 and 05 off the left */
.card--wide .card-media.dhw.solo.press > .device, .card--wide .card-media.dsw.solo.press > .device.after { left:19%; width:88%; top:13%; }
.card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { left:auto; right:19%; width:88%; top:13%; transform-origin:100% 50%;
  transform:translateY(var(--py)) rotateY(11deg) rotateX(5deg) rotateZ(-1.5deg); box-shadow:30px 60px 110px rgba(0,0,0,.65); }
.card:hover .card-media.mgw.solo > .device.after, .card:hover .card-media.galw.solo > .device.after { transform:translateY(calc(var(--py) - 10px)) rotateY(8deg) rotateX(4deg) rotateZ(-1deg); }
.card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { left:auto; right:4%; transform:rotateY(-22deg) rotateX(6deg) rotateZ(6deg); }
@media (max-width:860px) {
  .card--wide .card-media.dhw.solo.press > .device, .card--wide .card-media.dsw.solo.press > .device.after { left:8%; width:120%; top:14%; }
  .card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { left:auto; right:8%; width:120%; top:14%; }
  .card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { left:auto; right:-4%; }
}
/* the media is a wide strip (4:2.9), so desktop windows are sized to show most of a page, not just its header */
.card--wide .card-media.dhw.solo.press > .device, .card--wide .card-media.dsw.solo.press > .device.after { left:34%; width:70%; top:8%; }
.card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { right:34%; width:70%; top:8%; }
.card--wide .card-media.galw.solo.press > .device.after { width:62%; right:36%; }
.card--wide .card-media.dhw.solo .echo.e-ph { left:9%; top:12%; width:19%; }
.card--wide .card-media.dsw.solo .echo.e-web { left:6%; top:10%; width:26%; }
.card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { right:6%; top:10%; width:26%; }
@media (max-width:860px) {
  .card--wide .card-media.dhw.solo.press > .device, .card--wide .card-media.dsw.solo.press > .device.after { left:10%; width:94%; top:10%; }
  .card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { left:auto; right:10%; width:94%; top:10%; }
  .card-media.dhw.solo .echo, .card-media.dsw.solo .echo, .card-media.mgw.solo .echo, .card-media.galw.solo .echo { display:none; }
}
.card-media .device .bar span, .o-web .bar span { white-space:nowrap; }

/* desktop strip made taller (16:9) so the window fills the frame the way it does on mobile */
.card--wide .card-media.solo { aspect-ratio:16/9; }
.card--wide .card-media.solo .ph.pl { right:20%; top:5%; width:27%; }
.card--wide .card-media.solo .echo.e-ph { left:26%; top:10%; width:26%; }
.card--wide .card-media.dhw.solo.press > .device, .card--wide .card-media.dsw.solo.press > .device.after { left:20%; width:88%; top:7%; }
.card--wide .card-media.mgw.solo.press > .device.after, .card--wide .card-media.galw.solo.press > .device.after { right:20%; width:88%; top:7%; }
.card--wide .card-media.galw.solo.press > .device.after { width:84%; right:22%; top:5%; }
.card--wide .card-media.dhw.solo .echo.e-ph { left:5%; top:10%; width:16%; }
.card--wide .card-media.dsw.solo .echo.e-web { left:3%; top:8%; width:22%; }
.card--wide .card-media.mgw.solo .echo.e-web, .card--wide .card-media.galw.solo .echo.e-web { right:3%; top:8%; width:22%; }
@media (max-width:860px) {
  .card--wide .card-media.solo { aspect-ratio:4/2.9; }
  .card--wide .card-media.solo .ph.pl { right:8%; top:6%; width:58%; }
  .card--wide .card-media.solo .echo.e-ph { left:6%; top:22%; width:52%; }
  .card--wide .card-media.dhw.solo .echo.e-ph { left:-2%; width:32%; }
}

/* Other work: flat framed screenshots (device fixes, migration) */
.o-flat { perspective:none; background:#0a0a0d; }
.o-flat .o-web { position:absolute; inset:0; width:auto; left:0; top:0; transform:none; box-shadow:none; border-radius:0; display:flex; flex-direction:column; }
.o-flat .o-web .o-shot { display:block; width:100%; flex:1; min-height:0; object-fit:cover; object-position:top; }
.o-flat .o-phone { display:none; }
.other figcaption h3 a { color:inherit; text-decoration:none; }
.other figcaption h3 a:hover { text-decoration:underline; text-underline-offset:.14em; }

/* 04: drift along the Azure row. The canvas is a sharp 6000px render, and the zoom stays
   low enough that spec text lands around 2-3 device pixels: crisp, never readable */
/* laid out at its shown size (not scaled up), so the browser paints the sharp source instead of enlarging a small bitmap */
.card-media.solo .device .screen.drift:not(.strip) .shot { width:180%; max-width:none; margin:-28.4% 0 0 -40%; }
@keyframes canvas-drift { from { transform:translate(20%, -14%); } to { transform:translate(-20%, -14%); } }
/* 05: a strip of real Brightspeed spec sheets pans end to end at a scale that keeps the spec text unreadable */
.card-media.solo .device .screen.drift.strip { container-type:size; background:#5e5e5e; }
.card-media.solo .device .screen.drift.strip .shot { width:auto; height:100%; max-width:none; transform-origin:0 50%; animation-name:strip-pan; }
@keyframes strip-pan { from { transform:translateX(0); } to { transform:translateX(calc(100cqw - 100%)); } }

/* ---------- motion pass: one choreography ----------
   1) card entrance: the subject settles up from below while its ghost drifts
      back, so depth reads the moment the card is seen (keyed off .bled, which
      the in-view observer already sets). Individual transform properties
      compose with the 3D transforms above, so nothing there is rewritten.
   2) the card copy follows its media a beat later.
   3) section heads: the chapter mark lights, then the heading settles.
   4) the hero name and foot move at different rates as you leave the hero. */
@media (prefers-reduced-motion: no-preference) {
  .js .card-media.solo > .device, .js .card-media.solo > .ph.pl { translate:0 64px; scale:.965; opacity:0;
    transition:--b 1.5s var(--ease) .1s, transform .9s var(--ease), translate 1.3s var(--ease), scale 1.3s var(--ease), opacity .7s linear; }
  .js .card-media.solo.bled > .device, .js .card-media.solo.bled > .ph.pl { translate:0 0; scale:1; opacity:1; }
  .js .card-media.solo > .echo { translate:0 -18px; scale:1.06; opacity:0;
    transition:transform .9s var(--ease), translate 1.6s var(--ease) .12s, scale 1.6s var(--ease) .12s, opacity 1s linear .12s; }
  .js .card-media.solo.bled > .echo { translate:0 0; scale:1; opacity:.4; }
  .js .card.rev .card-body { opacity:0; translate:0 18px; }
  .js .card.rev.in .card-body { opacity:1; translate:0 0; transition:opacity .7s linear .18s, translate .75s var(--ease) .18s; }
  .js .sec-head h2, .js .sec-head > .mono:not(.ch) { opacity:0; translate:0 22px; transition:opacity .8s linear, translate .95s var(--ease); }
  .js .sec-head.in h2 { opacity:1; translate:0 0; transition-delay:.16s; }
  .js .sec-head.in > .mono:not(.ch) { opacity:1; translate:0 0; transition-delay:.34s; }
  /* 4) leaving the hero. Where the browser can read the scroll position itself
     (Chrome, Safari 26) the drift is a scroll-driven animation: it runs on the
     compositor, in step with the scroll, and never waits on a scroll event.
     app.js writes --hs only where that isn't available, and only for a mouse:
     on a phone a JS parallax always lands a frame behind the thumb. */
  .hero--full { --hs:0; }
  .hero--full .hero-mid { translate:0 calc(var(--hs) * 110px); }
  .hero--full .hero-meta { translate:0 calc(var(--hs) * 40px); }
  .hero--full .hp-foot { translate:0 calc(var(--hs) * -30px); }
  @supports (animation-timeline: view()) {
    .hero--full { view-timeline:--hero block; }
    /* the timeline comes after each shorthand: `animation:` resets it to auto */
    .hero--full .hero-mid, .hero--full .hero-meta, .hero--full .hp-foot { translate:none; }
    .hero--full .hero-mid { animation:hs-mid linear both; animation-timeline:--hero; animation-range:exit 0% exit 100%; }
    .hero--full .hero-meta { animation:hs-meta linear both; animation-timeline:--hero; animation-range:exit 0% exit 100%; }
    .hero--full .hp-foot { animation:hs-foot linear both; animation-timeline:--hero; animation-range:exit 0% exit 100%; }
    /* the entrance (riseIn, transform + opacity) and the drift (translate) share the element */
    .js .hero--full .hero-meta.rise { animation:riseIn .9s var(--ease) both, hs-meta linear both; animation-timeline:auto, --hero; animation-range:normal, exit 0% exit 100%; }
    .js .hero--full .hp-foot.rise { animation:riseIn .9s var(--ease) .44s both, hs-foot linear both; animation-timeline:auto, --hero; animation-range:normal, exit 0% exit 100%; }
  }
}
@keyframes hs-mid { to { translate:0 110px; } }
@keyframes hs-meta { to { translate:0 40px; } }
@keyframes hs-foot { to { translate:0 -30px; } }

/* ---- Where I stand: the one red panel on the page ---- */
.stand { position:relative; isolation:isolate; overflow:hidden; border-radius:var(--r-lg); color:var(--bone);
  padding:clamp(40px,5.5vw,84px) clamp(24px,4.5vw,72px) clamp(44px,6vw,92px);
  background:radial-gradient(120% 110% at 8% 0%, #f5352a 0%, var(--rust) 42%, #c41616 100%); }
.stand::after { content:''; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:.22; mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.stand .sec-head { border-top-color:rgba(237,234,227,.28); }
.stand .sec-head .mono, .stand .mono { color:rgba(237,234,227,.72); }
.stand-lede { font-family:var(--serif); font-weight:400; font-size:clamp(var(--t2),3.1vw,var(--t4)); line-height:1.16; letter-spacing:-.01em;
  max-width:26ch; text-wrap:pretty; margin-bottom:clamp(40px,6vw,88px); }
.stand-pts { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(24px,3.5vw,56px); }
.stand-pts li { border-top:1px solid rgba(237,234,227,.34); padding-top:18px; }
.stand-pts h3 { font-family:var(--serif); font-weight:700; font-size:var(--t1); line-height:1.15; margin-bottom:10px; text-wrap:balance; }
.stand-pts p { color:rgba(237,234,227,.86); font-size:var(--t0); line-height:1.5; text-wrap:pretty; max-width:34ch; }
.stand ::selection { background:var(--bone); color:var(--rust); }
@media (max-width:900px) { .stand-pts { grid-template-columns:1fr; gap:26px; } .stand-lede { max-width:none; } }

/* ---- About: the photo gets room ---- */
.about-row { grid-template-columns:minmax(0,1fr) clamp(240px,26vw,380px); column-gap:clamp(32px,6vw,96px); }
.about-row .about-body { grid-column:1; max-width:60ch; }
.about-row .about-photo { grid-column:2; margin-top:0; }
@media (max-width:860px) { .about-row { grid-template-columns:1fr; } .about-row .about-body, .about-row .about-photo { grid-column:1; } .about-row .about-photo { width:min(100%,320px); margin:0 0 28px; } }

/* ---------- phones: keep load and scroll on the compositor ----------
   iOS Safari renders SVG filters and masks on the CPU, so anything that changes
   underneath one (a stroke drawing in, a mask growing) re-runs it every frame.
   On touch those pieces start in their settled state; the entrances that stay
   (rise, card settle) are transform and opacity only. */
@media (pointer: coarse) {
  .js .hand-path { stroke-dashoffset:0; transition:none; }
  .card-media > .device, .card-media > .ph, .card-media > .sheets { -webkit-mask-image:none; mask-image:none; }
  .js .card-media > .device, .js .card-media > .ph, .js .card-media > .sheets { --b:160% !important; }
  .hero--full .hero-mid { will-change:transform; }
  .hero--full .hero-name { mix-blend-mode:normal; }
  /* the glass nav: its background switch used to tween for .4s, which repaints a
     backdrop-filtered layer for 24 frames right as the first scroll starts */
  .nav { transition:transform .35s var(--ease), opacity .35s var(--ease); }
  /* the glow never moves on touch (it follows a pointer), and a live 46px blur on
     a fixed layer is re-run by the compositor every frame; the gradient is soft already */
  .glow { filter:none; }
  /* the card entrances stay transform-only around a playing clip. iOS gives a card
     its own layer for the fade-and-rise and tears it down when the transition ends,
     about a second after the clip has started underneath; the window's own fade
     ends the same way. Each teardown could paint a frame of the panel through the
     window. The window still settles up from below; the copy still rises. */
  .js .card.rev { opacity:1; transform:none; }
  .js .card-media.solo > .device, .js .card-media.solo > .ph.pl { opacity:1; }
}

/* ---------- scale and weight: the headings set like a 90s record cover ----------
   Heavy serif capitals were the era's lettering (Death Row, The Chronic, All Eyez
   on Me), and that's Erode Bold's register, so the homepage heads carry the
   hero's weight instead of whispering under it. Numbers get the same treatment. */
.sec-head h2 { flex-basis:100%; font-size:clamp(46px,11.6vw,176px); line-height:.84; letter-spacing:-.022em;
  text-transform:uppercase; text-wrap:balance; margin:4px 0 0 -.03em; }
.sec-head h2 em { font-style:italic; font-weight:700; font-size:1em; letter-spacing:-.03em; }
.sec-head > .mono:not(.ch) { margin-left:auto; }
.stand-pts { grid-template-columns:repeat(4, minmax(0,1fr)); }
@media (max-width:1100px) { .stand-pts { grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width:640px) { .stand-pts { grid-template-columns:1fr; } }
@media (max-width:640px) { .sec-head h2 { font-size:clamp(46px,15vw,72px); line-height:.86; } }

/* ---------- accessibility pass (axe, WCAG 2.2 AA) ----------
   Window titles in the mock browser bars are decorative but still read by the
   contrast check; the galleries that scroll sideways on phones take focus so a
   keyboard can move them. */
.o-web .bar span { color:var(--dim); }
.sc-web .bar span { color:rgba(237,234,227,.82); }
.sc-duo:focus-visible, .sc-trio:focus-visible { outline:2px solid var(--bone); outline-offset:8px; border-radius:8px; }

/* event pages card and the other-work additions */
.card-media.t2w .device .screen { background:#0a0a0d url(img/t2/card.webp) top left / cover no-repeat; }
/* the two phone clips in Other work use the same device as the cards above, not a
   bare border: the ink rim, the island and the status bar all come from .ph, and the
   clips are recorded at 390x798 so they fill .cap exactly. Sized by height so the
   phone always fits the panel instead of running off the bottom. */
.o-cmp, .o-bs { background:var(--panel); }
.o-cmp .ph, .o-bs .ph { position:absolute; left:50%; top:50%; height:90%; width:auto; transform:translate(-50%,-50%); }

/* one section per study opens up: the words sit in a row across the top and
   the figure takes the whole measure, so the page changes scale at least once */
@media (min-width:901px) {
  .sc-sec.full { row-gap:clamp(30px,3.4vw,52px); }
  .sc-sec.full > .sc-txt { position:static; grid-column:1 / -1; display:grid; grid-template-columns:inherit;
    grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr); column-gap:clamp(28px,5vw,88px); align-items:start; }
  .sc-sec.full > .sc-txt > .lab { grid-column:1; grid-row:1; }
  .sc-sec.full > .sc-txt > h2 { grid-column:1; grid-row:2 / span 4; margin-bottom:0; }
  .sc-sec.full > .sc-txt > p { grid-column:2; max-width:52ch; }
  .sc-sec.full > .sc-txt > p:nth-of-type(1) { grid-row:2; }
  .sc-sec.full > .sc-txt > p:nth-of-type(2) { grid-row:3; }
  .sc-sec.full > .sc-txt > p:nth-of-type(3) { grid-row:4; }
  .sc-sec.full > .sc-txt > p:nth-of-type(4) { grid-row:5; }
  .sc-sec.full > .sc-stage, .sc-sec.full > figure { grid-column:1 / -1; }
}
@media (min-width:901px) { .sc-sec.full .sc-tabs { max-width:calc(1180 * var(--u)); } }

/* ---------- nav — three floating tiles ----------
   Logo tile left, an index of numbered links in the middle, and Contact as the
   one bone tile on the right. Under 861px the index and Contact fold into a
   Menu tile that opens a full-screen ink panel. */
.nav {
  position:fixed; z-index:60; top:16px; left:0; right:0;
  max-width:calc(1440 * var(--u)); margin:0 auto; padding:0 clamp(18px,3.4vw,48px);
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  pointer-events:none; transition:transform .35s var(--ease), opacity .35s var(--ease);
}
.nav > * { pointer-events:auto; }
.nav .name, .nav-links, .nav-menu {
  height:54px; border-radius:18px;
  /* solid, not frosted: a live backdrop blur re-ran the ink filters under the nav on every scroll frame */
  background:rgba(14,14,17,.9); border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(237,234,227,.05);
  transition:background .4s linear, border-color .4s linear, box-shadow .4s linear;
}
.nav.scrolled .name, .nav.scrolled .nav-links, .nav.scrolled .nav-menu {
  background:rgba(11,11,14,.94); border-color:rgba(237,234,227,.14);
  box-shadow:inset 0 1px 0 rgba(237,234,227,.05), 0 14px 40px rgba(0,0,0,.42);
}
.nav a.name { display:grid; place-items:center; width:54px; padding:0; color:var(--bone); }
.nav .logo { width:auto; height:26px; flex:none; overflow:visible; }

/* the index: mono numerals in red, Erode words, an ink stroke under the current page */
.nav-links {
  position:absolute; left:50%; top:0; translate:-50% 0;
  display:flex; align-items:center; gap:2px; padding:0 6px;
}
.nav-hl {
  position:absolute; top:6px; left:0; right:0; height:calc(100% - 12px); border-radius:13px;
  background:rgba(237,234,227,.07); opacity:0; pointer-events:none; clip-path:inset(0 100% 0 0 round 13px);
  transition:clip-path .45s var(--ease), opacity .25s linear;
}
.nav-links a, .menu-list a { position:relative; z-index:1; display:inline-flex; align-items:baseline; white-space:nowrap; color:var(--dim); transition:color .3s linear; }
.nav-links a { padding:10px 17px 11px; font-size:var(--t-1); }
.nav .w, .menu .w { position:relative; display:inline-block; }
.nav-links a:hover, .nav-links a:focus-visible, .nav-links a[aria-current] { color:var(--bone); }
.nav .w::after, .menu .w::after {
  content:''; position:absolute; left:0; right:-.05em; bottom:-.2em; height:2px; border-radius:1px;
  background:var(--bone); transform:scaleX(0); transform-origin:0 50%; transition:transform .45s var(--ease);
  filter:url(#ink-line); pointer-events:none;
}
.nav-links a[aria-current] .w::after, .menu a[aria-current] .w::after { background:var(--rust); transform:scaleX(1); }
.nav-links a:hover .w::after, .nav-links a:focus-visible .w::after { transform:scaleX(1); }

/* buttons: a bone pill with the arrow set in its own ink cap. On hover ink
   floods in from the cursor, the cap flips to bone and a fresh arrow slides in. */
.btn { gap:14px; padding:7px 7px 7px 22px; }
.btn .go-arr {
  position:relative; z-index:1; display:grid; place-items:center; overflow:hidden; flex:none;
  width:38px; height:38px; border-radius:50%; background:var(--void); color:var(--bone);
  transition:background .45s var(--flow), color .45s var(--flow);
}
.btn .go-arr .gl { grid-area:1/1; width:17px; height:17px; margin:0; transition:transform .7s var(--flow); will-change:transform; }
.btn .go-arr .g2 { transform:translateX(-26px); }
.btn:hover .go-arr, .btn:focus-visible .go-arr { background:var(--bone); color:var(--void); }
.btn:hover .go-arr .gl, .btn:focus-visible .go-arr .gl { transform:translateX(26px); }
.btn:hover .go-arr .g2, .btn:focus-visible .go-arr .g2 { transform:none; }
.btn .go-arr .gl path { stroke-width:2.2; }

.nav .nav-cta { height:54px; border-radius:18px; padding:0 8px 0 20px; gap:14px; font-size:var(--t-1); box-shadow:0 10px 30px rgba(0,0,0,.35); }
.nav .nav-cta .go-arr { width:38px; height:38px; border-radius:12px; }
.nav .nav-cta:hover, .nav .nav-cta:focus-visible { transform:none; }
.nav .nav-cta[aria-current] { background:var(--panel-2); color:var(--bone); border-color:rgba(237,234,227,.2); }
.nav .nav-cta[aria-current] .go-arr { background:var(--rust); }

/* the menu tile + panel (phones and small tablets) */
.nav-menu {
  display:none; align-items:center; gap:12px; padding:0 16px 0 18px; cursor:pointer;
  font:inherit; font-family:var(--font-mono); font-size:var(--t-2); letter-spacing:.16em; text-transform:uppercase; color:var(--bone);
}
.nav-menu .mb-ic { position:relative; width:22px; height:12px; }
.nav-menu .mb-ic i { position:absolute; left:0; right:0; top:5px; height:2px; border-radius:2px; background:var(--bone); transition:translate .5s var(--ease), rotate .5s var(--ease), scale .5s var(--ease); }
.nav-menu .mb-ic i:first-child { translate:0 -5px; }
.nav-menu .mb-ic i:last-child { translate:4px 5px; scale:.636 1; } /* a 14px bar, right-aligned */
.nav-menu[aria-expanded="true"] .mb-ic i:first-child { translate:0 0; rotate:45deg; }
.nav-menu[aria-expanded="true"] .mb-ic i:last-child { translate:0 0; scale:1; rotate:-45deg; }
.nav-menu:focus-visible { outline:2px solid var(--bone); outline-offset:3px; }

.menu {
  position:fixed; inset:0; z-index:59; display:flex; flex-direction:column; justify-content:flex-end;
  padding:110px clamp(18px,5vw,40px) calc(28px + env(safe-area-inset-bottom));
  background:radial-gradient(130% 70% at 100% 0%, #1b1815 0%, var(--void) 60%);
  clip-path:circle(0 at calc(100% - 52px) 43px); visibility:hidden;
  transition:clip-path .75s cubic-bezier(.7,0,.2,1), visibility 0s linear .75s;
}
.menu[hidden] { display:none; }
.menu.open { clip-path:circle(150% at calc(100% - 52px) 43px); visibility:visible; transition:clip-path .75s cubic-bezier(.7,0,.2,1); }
.menu-list { list-style:none; margin:0 0 auto; padding:0; display:flex; flex-direction:column; justify-content:center; flex:1; }
.menu-list li { border-top:1px solid var(--line); overflow:hidden; }
.menu-list li:last-child { border-bottom:1px solid var(--line); }
.menu-list a {
  display:flex; align-items:baseline; gap:16px; width:100%; padding:14px 0 12px;
  font-family:var(--serif); font-size:clamp(40px,12vw,64px); line-height:1.05; letter-spacing:-.02em; color:var(--bone);
  translate:0 105%; transition:translate .7s var(--ease), color .3s linear;
}
.menu-list .w { filter:url(#ink-lg); }
.menu-list .w::after { filter:none; }
.menu.open .menu-list a { translate:0 0; }
.menu.open .menu-list li:nth-child(1) a { transition-delay:.22s; }
.menu.open .menu-list li:nth-child(2) a { transition-delay:.28s; }
.menu.open .menu-list li:nth-child(3) a { transition-delay:.34s; }
.menu.open .menu-list li:nth-child(4) a { transition-delay:.4s; }
.menu a[aria-current] .w::after { height:.06em; bottom:-.02em; }
.menu-foot { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:14px; padding-top:22px;
  opacity:0; transition:opacity .4s linear; }
.menu.open .menu-foot { opacity:1; transition-delay:.45s; }
.menu-foot .mono a { color:var(--bone); }
html.menu-open { overflow:hidden; }

@media (max-width:860px) {
  .nav { top:12px; }
  .nav-links, .nav .nav-cta { display:none; }
  .nav-menu { display:inline-flex; }
  .nav .name, .nav-menu { height:50px; border-radius:16px; }
  .nav a.name { width:50px; }
  .nav .logo { height:23px; }
  /* phones: the nav slides away while reading down, back on any scroll up */
  .nav.nav-hide { transform:translateY(calc(-100% - 20px)); opacity:0; }
  .nav.nav-hide > * { pointer-events:none; }
}
@media (min-width:861px) { .menu { display:none !important; } }
@media (prefers-reduced-motion:reduce) {
  .menu, .menu.open { transition:none; }
  .menu-list a, .menu-foot { transition:none; }
  .btn .go-arr, .btn .go-arr .gl { transition:none; }
  .nav.nav-hide { transform:none; opacity:1; }
}

/* logo tile: bone ink floods in from the cursor and the mark flips to ink,
   on the same curve as the buttons; the red star keeps its quarter turn */
.nav a.name { position:relative; overflow:hidden; isolation:isolate; --flow:cubic-bezier(.16,1,.3,1); }
.nav a.name::after {
  content:''; position:absolute; z-index:0; pointer-events:none;
  left:var(--bx,50%); top:var(--by,50%); width:var(--bd,160px); height:var(--bd,160px);
  margin:calc(var(--bd,160px) / -2) 0 0 calc(var(--bd,160px) / -2);
  border-radius:50%; background:var(--bone);
  transform:scale(0); will-change:transform; transition:transform .9s var(--flow);
}
.nav a.name:hover::after, .nav a.name:focus-visible::after { transform:scale(1); transition-duration:1.4s; }
.nav a.name:focus-visible:not(:hover)::after { left:50%; top:50%; transition-duration:.22s; }
.nav a.name:focus-visible:not(:hover) .logo .lg-mark { transition-duration:.2s; }
.nav a.name .logo { position:relative; z-index:1; }
.nav .logo .lg-mark { transition:fill .8s var(--flow); }
.nav a.name:hover .logo .lg-mark, .nav a.name:focus-visible .logo .lg-mark { fill:var(--void); }
.nav a.name:hover, .nav a.name:focus-visible { border-color:rgba(237,234,227,.3); }
@media (prefers-reduced-motion:reduce) { .nav a.name::after, .nav .logo .lg-mark { transition:none; } }

/* ---------- other work: before and after in one panel ----------
   Three smaller studies no longer have pages of their own; the row shows the change
   instead. Before on the left in rust, after on the right, same scale, same frame. */
.o-ba { background:var(--panel); display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:clamp(14px,2.4vw,36px);
  padding:clamp(16px,2.4vw,30px) clamp(18px,3vw,40px) 0; aspect-ratio:16/10.5; }
.ba-col { min-width:0; min-height:0; display:grid; grid-template-rows:auto minmax(0,1fr); justify-items:center; gap:clamp(10px,1.2vw,16px); }
.ba-k { display:flex; flex-direction:column; align-items:center; gap:3px; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--dim); text-align:center; }
.ba-k b { font-family:var(--serif); font-weight:700; font-size:clamp(var(--t1),2.1vw,var(--t2)); line-height:1; letter-spacing:-.02em; text-transform:none; color:var(--bone); }
.ba-k.hot b { color:var(--rust); }

/* phones: sized by the height left under the label, cut off by the panel's bottom edge like a hand holding it */
.o-ba-ph { container-type:size; }
/* height-led on wide panels, but never wider than its own column, so the pair never overlaps on a phone */
.o-ba-ph .ph { height:auto; width:min(100%, calc((100cqh - clamp(60px,6vw,86px)) * 1.12 * 390 / 844)); align-self:start; }
.o-ba-ph .ph img.cap { object-fit:cover; object-position:top; }

/* swatches: the two product cards stacked full width, big enough that the pale finishes visibly vanish */
.o-ba-sw { grid-template-columns:1fr; grid-template-rows:1fr 1fr; padding-bottom:clamp(16px,2.4vw,30px); row-gap:clamp(10px,1.4vw,18px); }
.o-ba-sw .ba-col { grid-template-rows:none; grid-template-columns:minmax(0,.7fr) minmax(0,1.3fr); align-items:center; justify-items:stretch; }
.o-ba-sw .ba-k { align-items:flex-start; text-align:left; }
.o-ba-sw .ba-k b { white-space:nowrap; font-size:clamp(var(--t0),1.7vw,var(--t1)); }
.o-ba-sw .dv-demo { width:100%; }
.o-ba-sw .dv-sw { max-width:none; }
.o-ba-sw .dv-lbl { margin-bottom:clamp(8px,1vw,12px); }
.o-ba-sw .dv-row { gap:clamp(8px,1.3vw,16px); }
.o-ba-sw .dv-dot { width:auto; flex:1 1 0; max-width:54px; cursor:default; }
.o-ba-sw .dv-demo[data-ring="1"] .dv-dot.on { box-shadow:inset 0 2px 5px rgba(0,0,0,.17), 0 0 0 2px #fff, 0 0 0 3px #0057b8; }
.o-ba-sw .dv-demo[data-ring="0"] .dv-dot.on { box-shadow:0 0 0 2px #fff, 0 0 0 4px #454b52; }

/* length: both sections at one scale; the live one runs out of the panel, the 2024 one ends */
.o-ba-len.sc-len { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); justify-content:stretch; align-items:stretch; gap:clamp(14px,2.4vw,36px); }
.o-ba-len .ba-col { display:grid; }
.o-ba-len { container-type:size; }
/* sized off the panel height so the 894px section ends inside it with room to spare */
.o-ba-len .ba-run { width:min(100%, calc((100cqh - clamp(90px,9vw,120px)) * .4)); min-height:0; overflow:hidden; }
.o-ba-len .l-col.hot .ba-run { -webkit-mask:linear-gradient(#000 78%, transparent); mask:linear-gradient(#000 78%, transparent); }
.o-ba-len.sc-len img { width:100%; }
.o-ba-len .ba-k { font-size:var(--t-2); }

@media (max-width:560px) {
  .o-ba-ph { aspect-ratio:1/1.2; }
  .o-ba-len { aspect-ratio:4/5; }
  .o-ba-sw { aspect-ratio:auto; }
  .o-ba-sw .ba-col { grid-template-columns:1fr; justify-items:start; }
}
.o-try { display:inline-flex; align-items:center; gap:6px; font-size:var(--t-2); letter-spacing:.14em; text-transform:uppercase; color:var(--bone); text-decoration:none; }
.o-try .gl { width:14px; height:14px; }
.o-try:hover { color:var(--rust); }

/* ---------- the card mockups drift against their cards, tied to scroll by the browser ----------
   Same travel the old per-frame script gave (46px either side of centre, across the card's
   pass through the viewport), but on the compositor, so it can't lag the page. The
   individual translate property stacks with the tilted transform and the hover lift. */
@keyframes card-drift { from { translate:0 45px; } to { translate:0 -45px; } }
@supports (animation-timeline: view()) {
  @media (pointer:fine) and (prefers-reduced-motion:no-preference) {
    .card-media.drift-tl { view-timeline:--card block; }
    .card-media.drift-tl .drifts { animation:card-drift linear both; animation-timeline:--card; animation-range:cover 0% cover 100%; }
  }
}

/* ---------- other work, compact ----------
   Extra pieces, so they sit smaller than the featured cards: a quieter heading and a grid
   instead of full-width rows. The two prototypes share the top row; the rest go three across. */
#more .sec-head h2 { font-size:clamp(40px,6.4vw,96px); }
@media (min-width:861px) {
  #more .others { grid-template-columns:repeat(6,minmax(0,1fr)); gap:clamp(40px,4.4vw,64px) clamp(20px,2.4vw,36px); align-items:start; }
  #more .other.row { grid-column:span 2; display:flex; flex-direction:column; align-items:stretch; gap:18px; }
  #more .other.row:nth-child(-n+2) { grid-column:span 3; }
  #more .other .o-media { width:100%; }
  #more .other.row:nth-child(-n+2) .o-media { aspect-ratio:4/3; }
  #more .other.row:nth-child(n+3) .o-media { aspect-ratio:16/10.5; }
  #more .other figcaption { gap:10px; }
  #more .other figcaption h3 { font-size:clamp(var(--t1),1.6vw,var(--t2)); }
  #more .other figcaption p { font-size:var(--t-1); }
  /* the swatch pair sizes to its two cards instead of the panel ratio, so before and after never overlap */
  #more .other.row .o-ba-sw { aspect-ratio:auto; padding-top:clamp(16px,1.8vw,24px); }
  #more .o-ba-sw .ba-col { grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr); column-gap:12px; }
  #more .o-ba-sw .dv-sw { padding:12px 14px; }
  #more .o-ba-sw .dv-lbl { font-size:13px; margin-bottom:8px; }
  #more .o-ba-sw .ba-k b { white-space:normal; font-size:clamp(17px,1.5vw,var(--t1)); }
}
@media (min-width:861px) and (max-width:1099px) {
  #more .others { grid-template-columns:repeat(2,minmax(0,1fr)); }
  #more .other.row, #more .other.row:nth-child(-n+2) { grid-column:span 1; }
  /* the odd one out sits as a row across both columns, media at the same size as its neighbors */
  #more .other.row:last-child { grid-column:1 / -1; display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:clamp(20px,2.4vw,36px); align-items:center; }
}

/* ---------- smooth scroll (smooth.js, Lenis) ---------- */
html.lenis, html.lenis body { height:auto; }
html.lenis.lenis-smooth { scroll-behavior:auto !important; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow:clip; }
.lenis [data-lenis-prevent] { overscroll-behavior:contain; }
/* a live prototype under the cursor doesn't catch the wheel mid-glide */
.lenis.lenis-smooth iframe { pointer-events:none; }
