:root {
  --bg:#000; --fg:#fff; --dim:#8c8c8c; --faint:#4a4a4a; --line:rgba(255,255,255,.14);
  --font:"Instrument Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
  --gutter:9.5vw;                          /* shared left/right edge: nav, deck, sections */
  --nav-h:clamp(56px,5.4vw,88px);
  --ease:cubic-bezier(.22,.61,.36,1);
}
@media (max-width:760px) { :root { --gutter:16px; --nav-h:84px; } }

* { box-sizing:border-box; }
html { background:var(--bg); scroll-behavior:smooth; -webkit-text-size-adjust:100%; }
body { margin:0; background:var(--bg); color:var(--fg); font-family:var(--font); font-size:16px; line-height:1.5;
  -webkit-font-smoothing:antialiased; }
a { color:inherit; text-decoration:none; }
button { font:inherit; color:inherit; }
img, video, canvas { display:block; max-width:100%; }
.eyebrow { margin:0 0 18px; font-size:11px; font-weight:500; letter-spacing:.32em; text-transform:uppercase; color:var(--dim); }

/* ---------- Nav: full-width black bar, wide-tracked caps ---------- */
.nav { position:fixed; top:0; left:0; right:0; z-index:30; background:#000; display:flex; align-items:center;
  height:calc(var(--nav-h) + env(safe-area-inset-top,0px)); padding:env(safe-area-inset-top,0px) var(--gutter) 0; }
.nav ul { list-style:none; margin:0; padding:0; width:100%; display:flex; justify-content:space-between; align-items:center; gap:24px; }
.nav a { --track:.62em; position:relative; display:inline-block; font-size:clamp(13px,1.45vw,24px); font-weight:600; line-height:1;
  letter-spacing:var(--track); margin-right:calc(-1 * var(--track)); /* cancel trailing tracking so the last letter lines up with the edge */
  text-transform:uppercase; white-space:nowrap; transition:opacity .2s; }
/* Hover underline: sweeps in from the left, out to the right. Stops short of the trailing tracking
   so it ends under the last letter. */
.nav a::after { content:""; position:absolute; left:0; right:var(--track); bottom:-.45em; height:1px; background:currentColor;
  transform:scaleX(0); transform-origin:right; transition:transform .45s var(--ease); }
.nav a:focus-visible::after { transform:scaleX(1); transform-origin:left; }
@media (hover:hover) { .nav a:hover::after { transform:scaleX(1); transform-origin:left; } }
@media (max-width:760px) {
  .nav ul { flex-wrap:wrap; row-gap:12px; column-gap:0; }
  .nav .nav-name { flex-basis:100%; text-align:center; }
  .nav a { --track:.4em; font-size:12px; }
  .nav li:not(.nav-name) { flex:1; text-align:center; }
}

/* ---------- Stage sequence: media grid -> pull back out of the LED screen -> whole stage ----------
   The section is scroll length; .stage-pin holds the window while it passes (js/intro.js gives the
   progress, js/hero.js moves the camera). Stacking inside the pin: the grid at the back, the 3D
   canvas over it with a see-through hole where the LED screen is (so the booth, trusses and beams
   draw in front of the grid), then the deck. */
.stage-seq { position:relative; --zoom-len:170vh; height:calc(100vh + var(--zoom-len)); height:calc(100svh + var(--zoom-len)); }
.stage-pin { position:sticky; top:0; height:100vh; height:100svh; overflow:hidden; background:#000; }
#wrap { position:absolute; inset:0; z-index:2; pointer-events:none; }   /* clicks go through to the grid */
#wrap canvas { width:100%; height:100%; }
#status { position:absolute; z-index:3; left:var(--gutter); top:calc(var(--nav-h) + env(safe-area-inset-top,0px) + 12px);
  font-size:11px; letter-spacing:.08em; color:var(--dim); pointer-events:none; }
@media (max-width:760px) { .stage-seq { --zoom-len:130vh; } }

/* ---------- Stage controls: road-case panels over the stage (js/stage-ui.js) ----------
   Road cases: black laminate, aluminium edge extrusion, chrome ball corners. Faux-3D after the
   Mausoleum "Provoker" cover: chrome lettering, glossy arcade button, chrome-ball knobs, a little
   recessed screen. Everything picks up the stage light: --scene (the light colour) tints the
   sheen and glows, --beat (the music level) breathes it, --mx (cursor x) moves a glint along it. */
.stage-ui { position:absolute; inset:0; z-index:3; pointer-events:none; opacity:0; transition:opacity .6s var(--ease);
  --scene:hsl(130 85% 58%); --beat:0; --silver:linear-gradient(135deg,#f6f7f9,#8a8e95 22%,#e3e6ea 46%,#5d6066 72%,#cdd0d5); }
.stage-ui.is-live { opacity:1; }
.stage-ui.is-live .hotspot, .stage-ui.is-live .rc.is-open { pointer-events:auto; }

/* Invisible buttons laid over the light bar, the booth and the speaker column. */
.hotspot { position:absolute; left:0; top:0; width:0; height:0; padding:0; border:0; background:none; cursor:pointer;
  touch-action:none; -webkit-tap-highlight-color:transparent; }
.hotspot--lights { cursor:ew-resize; }
.hotspot:focus-visible { outline:1px dashed rgba(255,255,255,.7); outline-offset:6px; }

/* The case */
.rc { position:absolute; left:0; top:0; opacity:0; pointer-events:none; padding:12px 16px; color:#e9ebee;
  font-size:9px; font-weight:600; letter-spacing:.26em; text-transform:uppercase; white-space:nowrap;
  border:3px solid; border-image:var(--silver) 1;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.022) 0 1px, transparent 1px 3px),   /* laminate grain */
    linear-gradient(180deg, #1a1b1e, #09090a);
  box-shadow:0 18px 40px rgba(0,0,0,.7), 0 0 26px -6px color-mix(in srgb, var(--scene) 55%, transparent),
    inset 0 1px 0 rgba(255,255,255,.07), inset 0 0 0 1px rgba(0,0,0,.7);
  transition:opacity .3s var(--ease), filter .3s var(--ease); filter:blur(3px); }
.rc.is-open { opacity:1; filter:none; }
/* chrome ball corners */
.rc::before { content:""; position:absolute; inset:-9px; pointer-events:none;
  --ball:radial-gradient(circle 7px at 6.5px 6.5px, #fff 0 1px, #e3e6ea 2.2px, #8d9198 4.2px, #2b2d31 6.3px, transparent 7px);
  background:var(--ball) 0 0 / 15px 15px no-repeat, var(--ball) 100% 0 / 15px 15px no-repeat,
    var(--ball) 0 100% / 15px 15px no-repeat, var(--ball) 100% 100% / 15px 15px no-repeat; }
/* the stage light reflected in the case: a coloured sheen that follows the cursor and the beat */
.rc::after { content:""; position:absolute; inset:0; pointer-events:none; mix-blend-mode:screen;
  background:linear-gradient(105deg, transparent 32%, color-mix(in srgb, var(--scene) 20%, transparent) 45%,
    rgba(255,255,255,.12) 50%, color-mix(in srgb, var(--scene) 16%, transparent) 55%, transparent 68%) no-repeat;
  background-size:260% 100%; background-position:calc((1 - var(--mx, .5)) * 100%) 0;
  opacity:calc(.55 + var(--beat) * .45); transition:background-position .25s; }

/* Chrome lettering */
.rc-chrome { display:inline-block; font-weight:700; letter-spacing:.28em;
  background:linear-gradient(180deg,#fff 0%,#e6e8ec 38%,#7a7e86 52%,#f2f4f6 70%,#9da1a8 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent; filter:drop-shadow(0 1px 0 rgba(0,0,0,.9)); }

/* Sliders: a recessed slot, a scene-coloured fill and a chrome-ball knob */
.rc-slider { position:relative; width:120px; height:20px; cursor:pointer; touch-action:none; }
.rc-track { position:absolute; left:0; right:0; top:50%; height:6px; margin-top:-3px; border-radius:3px; overflow:hidden;
  background:linear-gradient(180deg,#000,#1b1c1f); box-shadow:inset 0 1px 3px #000, 0 1px 0 rgba(255,255,255,.14); }
.rc-fill { position:absolute; left:0; top:0; bottom:0; width:50%;
  background:linear-gradient(90deg, color-mix(in srgb, var(--scene) 35%, #000), var(--scene)); box-shadow:0 0 8px var(--scene); }
.rc-knob { position:absolute; top:50%; left:50%; width:18px; height:18px; margin:-9px 0 0 -9px; border-radius:50%; pointer-events:none;
  background:radial-gradient(circle at 36% 30%, #fff 0 9%, #e8ebef 20%, #9ba0a7 46%, #3b3e43 76%, #18191c 100%);
  box-shadow:0 3px 5px rgba(0,0,0,.75), 0 0 10px -2px var(--scene); }
.rc-slider--v { width:22px; height:110px; }
.rc-slider--v .rc-track { left:50%; right:auto; top:0; bottom:0; width:6px; height:auto; margin:0 0 0 -3px; }
.rc-slider--v .rc-fill { top:auto; right:0; width:auto; height:50%; background:linear-gradient(0deg, color-mix(in srgb, var(--scene) 35%, #000), var(--scene)); }
.rc-slider--v .rc-knob { top:auto; left:50%; bottom:50%; margin:0 0 -9px -9px; }
.rc-slider:focus-visible, .rc-rail:focus-visible { outline:1px dashed rgba(255,255,255,.7); outline-offset:5px; }

/* Light bar: a slim colour rail under the bar, then a dim/bright module */
.rc-lights { display:flex; flex-direction:column; align-items:center; gap:10px; padding:10px 14px; }
.rc-rail { position:relative; width:var(--rail-w, 520px); height:12px; cursor:ew-resize; touch-action:none; border-radius:6px;
  box-shadow:0 0 0 2px #1a1b1e, 0 0 0 3px #a6aab0, 0 4px 10px rgba(0,0,0,.6); }
.rc-rail-grad { position:absolute; inset:0; border-radius:6px; opacity:.85;
  background:linear-gradient(90deg, hsl(0 85% 55%), hsl(60 85% 55%), hsl(120 85% 52%), hsl(180 85% 52%), hsl(240 85% 60%), hsl(300 85% 58%), hsl(360 85% 55%));
  box-shadow:inset 0 2px 3px rgba(0,0,0,.55), inset 0 -1px 0 rgba(255,255,255,.3); }
.rc-rail .rc-knob { width:20px; height:20px; margin:-10px 0 0 -10px; }
.rc-mod { display:flex; align-items:center; gap:12px; }

/* DJ booth: a small recessed screen, like the arcade PLAY! display */
.rc-booth { display:flex; flex-direction:column; align-items:center; gap:8px; }
.rc-title { font-size:8px; }
.rc-lcd { position:relative; min-width:220px; max-width:320px; padding:7px 12px; overflow:hidden; text-align:center; border-radius:3px;
  font:600 12px/1.2 "Courier New", ui-monospace, monospace; letter-spacing:.16em; color:var(--scene); text-shadow:0 0 6px var(--scene);
  background:radial-gradient(120% 160% at 50% 0%, color-mix(in srgb, var(--scene) 14%, #04070a), #020304);
  box-shadow:inset 0 2px 7px #000, inset 0 0 0 1px rgba(255,255,255,.06), 0 0 0 2px #232528, 0 0 0 3px #8f9399; }
.rc-lcd::after { content:""; position:absolute; inset:0; pointer-events:none;   /* scanlines */
  background:repeating-linear-gradient(0deg, rgba(0,0,0,.35) 0 1px, transparent 1px 3px); }
.rc-lcd-text { display:inline-block; }
.rc-lcd.is-swap .rc-lcd-text { animation:rc-swap .45s steps(6) both; }
@keyframes rc-swap { 0% { opacity:1; } 40% { opacity:0; transform:translateY(-3px); } 60% { opacity:0; transform:translateY(3px); } 100% { opacity:1; transform:none; } }
.rc-hint { font-size:8px; letter-spacing:.24em; color:#8f949b; }

/* Speakers: vertical fader + glossy arcade mute button */
.rc-speaker { display:flex; flex-direction:column; align-items:center; gap:10px; padding:12px 12px 10px; }
.rc-btn { position:relative; width:34px; height:34px; padding:0; border:0; border-radius:50%; cursor:pointer; --btn:#d9dce1;
  background:radial-gradient(circle at 38% 30%, #fff 0 7%, var(--btn) 24%, color-mix(in srgb, var(--btn) 50%, #000) 70%, #0d0d0f 100%);
  box-shadow:0 0 0 3px #17181b, 0 0 0 4px #9da1a7, 0 4px 7px rgba(0,0,0,.75); transition:transform .12s; }
.rc-btn:active { transform:translateY(1px) scale(.96); }
.rc-btn.is-on { --btn:#e3242b; box-shadow:0 0 0 3px #17181b, 0 0 0 4px #9da1a7, 0 4px 7px rgba(0,0,0,.75), 0 0 16px rgba(227,36,43,.7); }
.rc-btn:focus-visible { outline:1px dashed rgba(255,255,255,.7); outline-offset:6px; }
.rc-btn-label { font-size:8px; }

@media (max-width:760px) {
  .rc { padding:9px 11px; }
  .rc-lcd { min-width:180px; font-size:11px; }
  .rc-slider { width:96px; }
}
@media (prefers-reduced-motion:reduce) { .rc, .rc::after { transition:none; } .rc-lcd.is-swap .rc-lcd-text { animation:none; } }

/* ---------- About ---------- */
/* The about section rides up over the bottom of the stage view (--overlap) instead of starting
   after it, with a gradient behind it that fades the stage into black, so there's no hard cut from
   the scene to the page. Its transparent top must not block the stage controls underneath, so only
   its content takes clicks. */
.about { --overlap:30vh; position:relative; z-index:4; margin-top:calc(-1 * var(--overlap)); pointer-events:none;
  display:grid; grid-template-columns:minmax(0,5fr) minmax(0,7fr); gap:clamp(40px,7vw,120px); align-items:center;
  padding:calc(var(--overlap) * .45) var(--gutter) clamp(96px,12vw,180px);
  background:linear-gradient(180deg, rgba(0,0,0,0) 0, rgba(0,0,0,.55) calc(var(--overlap) * .45), rgba(0,0,0,.9) calc(var(--overlap) * .8), #000 var(--overlap)); }
.about > * { pointer-events:auto; }
.portrait { --sun:#fff64f; position:relative; margin:0; aspect-ratio:1; max-width:560px; width:100%; justify-self:center;
  border-radius:50%; background:var(--sun); touch-action:pan-y; }
.portrait::after { content:"Portrait"; position:absolute; left:0; right:0; bottom:18%; text-align:center; font-size:10px;
  letter-spacing:.3em; text-transform:uppercase; color:rgba(0,0,0,.35); }
.pixel-trail { position:absolute; inset:0; width:100%; height:100%; border-radius:50%; image-rendering:pixelated; }
/* Taller than the disc and open at the top: only the bottom is rounded to the circle (radius = half
   the width, i.e. 50% / (116% height) = 43.1% vertically), so the head can rise past the rim. */
.portrait .cutout { position:absolute; left:0; right:0; bottom:0; top:-16%; z-index:1; overflow:hidden;
  border-radius:0 0 50% 50% / 0 0 43.1% 43.1%; pointer-events:none; }
.portrait img { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; object-position:50% 100%; }
.about h2 { margin:0 0 28px; font-size:clamp(34px,4.2vw,64px); font-weight:600; line-height:1.02; letter-spacing:-.01em; }
.about h2 .wave { display:inline-block; transform-origin:70% 80%; }
.about:hover h2 .wave { animation:wave 1.2s ease-in-out; }
@keyframes wave { 0%,100%{transform:rotate(0)} 20%{transform:rotate(16deg)} 40%{transform:rotate(-8deg)} 60%{transform:rotate(14deg)} 80%{transform:rotate(-4deg)} }
.about .lead { margin:0 0 20px; font-size:clamp(19px,1.7vw,26px); line-height:1.3; max-width:26ch; }
.about .lead em { font-style:italic; font-weight:600; }
/* Pixel words (js/pixel-trail.js): a lit letter becomes a solid block of colour the size of its box. */
.px-ch.is-px { color:transparent; }
.about .body { margin:0 0 36px; color:var(--dim); max-width:46ch; }
.links { display:flex; flex-wrap:wrap; gap:12px 32px; font-size:12px; letter-spacing:.24em; text-transform:uppercase; }
.links a { position:relative; padding-bottom:6px; }
.links a::after { content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:currentColor; transform-origin:left; transition:transform .4s var(--ease); }
.links a:hover::after { transform:scaleX(.3); }
/* Four to a row; a fifth link starts a new row. Each tile carries a running index. */
.socials { list-style:none; margin:clamp(48px,6vw,96px) 0 0; padding:0; max-width:600px; counter-reset:soc;
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:clamp(10px,1.6vw,24px); }
.socials a { counter-increment:soc; position:relative; display:grid; place-items:center; aspect-ratio:1;
  border:1px solid var(--line); background:rgba(255,255,255,.03); color:var(--fg);
  transition:background-color .35s var(--ease), border-color .35s var(--ease), color .35s var(--ease); }
.socials a::before { content:counter(soc,decimal-leading-zero); position:absolute; top:9px; right:10px;
  font-size:10px; letter-spacing:.12em; color:var(--faint); transition:color .35s var(--ease); }
.socials svg { width:30%; height:30%; fill:none; stroke:currentColor; stroke-width:1.5; stroke-linejoin:round; stroke-linecap:round;
  transition:transform .45s var(--ease); }
.socials span { position:absolute; left:10px; bottom:9px; font-size:9px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--dim); transition:color .35s var(--ease); }
.socials a:hover, .socials a:focus-visible { background:#fff64f; border-color:#fff64f; color:#000; }
.socials a:hover::before, .socials a:hover span, .socials a:focus-visible::before, .socials a:focus-visible span { color:rgba(0,0,0,.6); }
.socials a:hover svg { transform:scale(1.08); }
.socials a:focus-visible { outline:1px solid #fff; outline-offset:3px; }
@media (max-width:760px) {
  .about { grid-template-columns:1fr; }
  .portrait { max-width:84%; margin-top:12%; }
}
@media (max-width:520px) {
  /* Tiles get too small for a label: keep it for screen readers only. */
  .socials span { width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
}

.rule { height:1px; margin:0; border:0; background:var(--line); }

/* ---------- Selected works ---------- */
.works { padding:clamp(96px,10vw,160px) var(--gutter) clamp(80px,8vw,120px); }
.works-head { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:clamp(36px,4vw,56px); }
.works-head h2 { margin:0; font-size:clamp(18px,1.6vw,24px); font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
.works-head span { font-size:11px; letter-spacing:.3em; text-transform:uppercase; color:var(--dim); }
.projects { display:grid; gap:clamp(48px,6vw,96px); }
.project { display:block; }
.cover { position:relative; aspect-ratio:16 / 9; overflow:hidden; background:#0b0b0b; }
.cover .art, .cover img, .cover video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1.1s var(--ease); }
.cover img, .cover video { z-index:1; }
.project:hover .art, .project:hover .cover img, .project:hover .cover video { transform:scale(1.035); }
.cover::after { content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:linear-gradient(250deg,rgba(0,0,0,.62) 0%,rgba(0,0,0,0) 46%); }
.cover-title { position:absolute; z-index:3; top:clamp(18px,3vw,44px); right:clamp(18px,3vw,44px); text-align:right; }
.cover-title h3 { margin:0; font-size:clamp(24px,3.4vw,52px); line-height:1; letter-spacing:-.01em; text-transform:uppercase; }
.cover-title h3 b { display:block; font-weight:700; }
.cover-title h3 span { display:block; font-weight:400; }
.cover-title p { margin:clamp(12px,1.6vw,22px) 0 0; font-size:clamp(12px,1vw,15px); line-height:1.35; }
.cover-title p span { display:block; color:rgba(255,255,255,.7); }
.project-meta { display:flex; justify-content:space-between; gap:24px; padding-top:16px; font-size:11px; letter-spacing:.28em;
  text-transform:uppercase; color:var(--dim); }
.project-meta .go { color:#fff; transition:transform .4s var(--ease); }
.project:hover .project-meta .go { transform:translateX(6px); }

/* Placeholder cover art: an <img> or <video> in the same .cover sits on top of it (and is removed if the file is missing) */
.art-boiler { background:
  repeating-linear-gradient(0deg,rgba(0,0,0,.55) 0 2px,transparent 2px 5px),
  radial-gradient(40% 70% at 30% 60%,#ff3b1f 0%,rgba(255,59,31,0) 70%),
  radial-gradient(35% 60% at 72% 40%,#ff9d2e 0%,rgba(255,157,46,0) 70%),
  linear-gradient(180deg,#140303,#000); }
.art-fashion { background:
  repeating-linear-gradient(90deg,rgba(0,0,0,.35) 0 3px,transparent 3px 7px),
  repeating-linear-gradient(0deg,rgba(0,0,0,.35) 0 3px,transparent 3px 7px),
  conic-gradient(from 200deg at 45% 55%,#ff2e63,#ffd60a,#2ec4ff,#7b2eff,#ff2e63); }
.art-reel { background:
  radial-gradient(60% 80% at 50% 50%,rgba(70,90,255,.55) 0%,rgba(0,0,0,0) 70%),
  repeating-radial-gradient(circle at 50% 50%,rgba(255,255,255,.12) 0 1px,transparent 1px 22px),
  linear-gradient(135deg,#05051a,#000 60%); }
.art-etch { background:
  radial-gradient(14% 24% at 30% 50%,#000 0 40%,rgba(0,0,0,0) 41%),
  conic-gradient(from 0deg at 30% 50%,#ff5d5d,#ffd1a1,#55c1ff,#c45bff,#36ffb0,#ff5d5d);
  -webkit-mask:radial-gradient(70% 120% at 30% 50%,#000 30%,rgba(0,0,0,.15) 75%);
  mask:radial-gradient(70% 120% at 30% 50%,#000 30%,rgba(0,0,0,.15) 75%); }

/* ---------- Footer ---------- */
footer { border-top:1px solid var(--line); padding:56px var(--gutter) calc(44px + env(safe-area-inset-bottom,0px));
  display:flex; flex-wrap:wrap; justify-content:space-between; gap:32px; font-size:13px; color:var(--dim); }
footer h4 { margin:0 0 14px; font-size:10px; font-weight:500; letter-spacing:.3em; text-transform:uppercase; color:var(--fg); }
footer a { display:block; margin-bottom:8px; transition:color .2s; }
footer a:hover { color:#fff; }
footer .brand { font-size:13px; font-weight:600; letter-spacing:.3em; text-transform:uppercase; color:var(--fg); }
footer .credit { display:block; margin-top:10px; font-size:11px; color:var(--faint); max-width:34ch; }
footer .credit a { display:inline; margin:0; text-decoration:underline; text-underline-offset:2px; }

/* ---------- Case study pages (work/*.html) ---------- */
.case main { padding-top:calc(var(--nav-h) + env(safe-area-inset-top,0px)); }
.cs-head { padding:clamp(72px,9vw,140px) var(--gutter) clamp(48px,5vw,72px); text-align:center; }
.cs-head h1 { margin:0 0 clamp(44px,5vw,76px); font-size:clamp(40px,6.4vw,104px); font-weight:600; line-height:1; letter-spacing:-.02em; }
.cs-facts { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:24px; margin:0; padding-top:20px; border-top:1px solid var(--line); text-align:left; }
.cs-facts dt { margin-bottom:6px; font-size:10px; font-weight:500; letter-spacing:.3em; text-transform:uppercase; color:var(--dim); }
.cs-facts dd { margin:0; font-size:15px; }
/* Media frames hold their aspect ratio (--ar) while loading; until a file exists they show a labelled placeholder. */
.cs-hero, .cs-media { position:relative; margin:0; aspect-ratio:var(--ar,16 / 9); overflow:hidden;
  background:repeating-linear-gradient(135deg,#0e0e0e 0 2px,#070707 2px 14px); }
.cs-hero { margin:0 var(--gutter) clamp(80px,10vw,150px); }
.cs-hero img, .cs-hero video, .cs-media img, .cs-media video { position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:cover; }
.cs-media--light { background:#e8e8e6; }
.cs-media--light img { object-fit:contain; }
/* A diagram in a photo frame (e.g. a floor plan): shown complete on a light background, not cropped. */
.cs-media img.is-whole { object-fit:contain; background:#ececec; }
/* Carousels (js/carousel.js): images crossfade, the visible one drifts in very slightly, and a thin
   bar along the bottom fills up until the next one arrives. */
.cs-media.is-carousel { cursor:pointer; }
.cs-media.is-carousel img, .cs-media.is-carousel video { opacity:0; transition:opacity 1.4s var(--ease); }
.cs-media.is-carousel img.is-on, .cs-media.is-carousel video.is-on { opacity:1; z-index:2; animation:cs-drift calc(var(--slide,6s) + 1.4s) linear both; }
@keyframes cs-drift { from { transform:scale(1.04); } to { transform:scale(1); } }
.cs-progress { position:absolute; z-index:3; left:0; right:0; bottom:0; height:2px; background:rgba(255,255,255,.14); pointer-events:none; }
.cs-progress i { display:block; height:100%; background:rgba(255,255,255,.7); transform-origin:left; transform:scaleX(0);
  animation:cs-fill var(--slide,6s) linear forwards; }
@keyframes cs-fill { to { transform:scaleX(1); } }
.cs-media--light .cs-progress { background:rgba(0,0,0,.1); }
.cs-media--light .cs-progress i { background:rgba(0,0,0,.45); }
.cs-media.is-paused .cs-progress i, .cs-media.is-paused .is-on { animation-play-state:paused; }
@media (prefers-reduced-motion:reduce) { .cs-media.is-carousel .is-on { animation:none; } .cs-progress { display:none; } }
.ph-label { position:absolute; left:16px; bottom:14px; font-size:10px; letter-spacing:.2em; text-transform:uppercase; color:var(--faint); }
.cs-media--light .ph-label { color:#9a9a9a; }
/* Rows: media bleeds to the left edge, text sits in the right column; hairlines between rows. */
.cs-row { display:grid; grid-template-columns:minmax(0,7fr) minmax(0,5fr); border-top:1px solid var(--line); }
.cs-row:last-of-type { border-bottom:1px solid var(--line); }
.cs-text { align-self:start; padding:clamp(36px,4.5vw,72px) var(--gutter) clamp(40px,4vw,64px) clamp(32px,4.5vw,80px); }
.cs-num { display:block; margin-bottom:14px; font-size:11px; letter-spacing:.3em; color:var(--dim); }
.cs-text h2 { margin:0 0 14px; font-size:clamp(20px,1.7vw,26px); font-weight:600; letter-spacing:-.005em; }
.cs-text p { margin:0 0 1em; max-width:40ch; color:#c9c9c9; }
.next-case { display:block; padding:clamp(88px,11vw,170px) var(--gutter); }
.next-case .eyebrow { display:block; }
.next-title { display:block; font-size:clamp(34px,5.6vw,88px); font-weight:600; line-height:1; letter-spacing:-.02em; }
.next-title span { display:inline-block; transition:transform .5s var(--ease); }
.next-case:hover .next-title span { transform:translateX(.25em); }
@media (max-width:760px) {
  .cs-facts { grid-template-columns:repeat(2,minmax(0,1fr)); row-gap:20px; }
  .cs-row { grid-template-columns:1fr; }
  .cs-text { padding:32px var(--gutter) 48px; }
}

/* ---------- Scroll reveals ---------- */
/* Uses the separate `translate` property, so `transform` stays free for the cursor tilt (.tilt). */
.reveal { opacity:0; translate:0 24px; transition:opacity 1s var(--ease), translate 1s var(--ease); }
.reveal.is-in { opacity:1; translate:none; }

/* ---------- Intro: modular media grid = the stage's LED screen (js/intro.js, js/hero.js) ---------- */
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
/* Laid out at the size of the window; js/hero.js warps it onto the 3D screen with a matrix3d
   transform from its top-left corner. The 6px padding reads as the screen's bezel. */
.intro-frame { position:absolute; z-index:1; left:0; top:0; width:100%; height:100%; padding:6px; overflow:hidden;
  background:#000; transform-origin:0 0; will-change:transform; }
/* will-change: the grid is drawn once at full size and then only scaled while the camera moves.
   Without it Chrome re-drew every tile at each new size, every frame (measured on a 2x screen:
   ~45 dropped frames per pull-back). */
.intro-grid { display:grid; gap:6px; width:100%; height:100%; contain:strict; }
.tile { position:relative; display:block; min-width:0; min-height:0; overflow:hidden; background:#0b0b0b;
  opacity:0; transform:scale(.97); transition:opacity .9s var(--ease) var(--d,0ms), transform .9s var(--ease) var(--d,0ms); }
.intro.is-built .tile { opacity:1; transform:none; }
.tile > img, .tile > video, .tile > canvas, .tile > .art { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transition:transform 1.2s var(--ease); }
.tile.is-focus > img, .tile.is-focus > video, .tile.is-focus > canvas, .tile.is-focus > .art { transform:scale(1.05); }
/* A piece whose shape is too far from its tile's (js/intro.js guardFit) is shown whole, not cropped. */
.tile--fit > img, .tile--fit > video, .tile--fit > canvas { object-fit:contain; }
.tile-cap { position:absolute; left:12px; bottom:10px; right:12px; font-size:10px; font-weight:500; letter-spacing:.24em; text-transform:uppercase;
  color:#fff; mix-blend-mode:difference; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  opacity:0; transform:translateY(6px); transition:opacity .4s, transform .4s var(--ease); }
.tile.is-focus .tile-cap { opacity:1; transform:none; }
/* The one place the name appears: a quiet tile with socials and (optionally) a portrait. */
.tile--text { display:flex; flex-direction:column; justify-content:space-between; gap:12px; background:#000;
  padding:clamp(12px,1.3vw,22px); outline:1px solid var(--line); outline-offset:-1px; }
.tile--text > div { position:relative; z-index:1; }
.tile--text p { margin:0; }
.tile--text .ic-photo { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1.2s var(--ease); }
.tile--text.is-focus .ic-photo { transform:scale(1.05); }
.tile--text.has-photo::before { content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,0) 38%,rgba(0,0,0,0) 55%,rgba(0,0,0,.7) 100%); }
.ic-name { font-size:12px; font-weight:600; letter-spacing:.3em; text-transform:uppercase; white-space:nowrap; }
/* The name tile can land anywhere, at any size: tighten the type when it is narrow. */
.tile--text { container-type:inline-size; }
@container (max-width:220px) { .ic-name { font-size:11px; letter-spacing:.14em; } .ic-role, .ic-links, .ic-scroll { letter-spacing:.12em; } }
.ic-role { margin-top:6px !important; font-size:10px; letter-spacing:.22em; text-transform:uppercase; color:var(--dim); }
.tile--text.has-photo .ic-role, .tile--text.has-photo .ic-links a, .tile--text.has-photo .ic-scroll { color:rgba(255,255,255,.8); }
.ic-foot { display:flex; flex-direction:column; gap:10px; }
.ic-links { display:flex; flex-wrap:wrap; gap:6px 16px; font-size:10px; font-weight:500; letter-spacing:.22em; text-transform:uppercase; }
.ic-links a, .ic-scroll { color:var(--dim); transition:color .2s; }
.ic-links a:hover, .ic-scroll:hover { color:#fff; }
.ic-scroll { font-size:10px; letter-spacing:.22em; text-transform:uppercase; }
/* Homepage: the nav is hidden while the grid fills the window (the name tile says who this is) and
   fades in as the camera pulls back to the stage (--nav-a, js/intro.js). It stays from then on. */
html.has-seq .nav { opacity:var(--nav-a,0); }
html.has-seq .nav.is-off { pointer-events:none; visibility:hidden; }
/* Layout picker badge: local preview only, while no layout is locked (js/intro.js). */
.seed-badge { position:fixed; z-index:40; right:12px; bottom:12px; padding:7px 11px; border:1px solid var(--line); border-radius:999px;
  background:rgba(0,0,0,.75); color:#fff; font-size:11px; letter-spacing:.06em; cursor:pointer; }

@media (prefers-reduced-motion:reduce) {
  html { scroll-behavior:auto; }
  .tile, .tile > img, .tile > video, .tile > .art, .tile-cap { transition:none; }
  .tile.is-focus > img, .tile.is-focus > video, .tile.is-focus > .art { transform:none; }
  .reveal { opacity:1; translate:none; transition:none; }
  .project:hover .art, .project:hover .cover img { transform:none; }
}

/* ---------- Sound on/off (pages with their own music, js/page-audio.js) ---------- */
.sound-toggle { position:fixed; z-index:40; right:clamp(12px,2vw,24px); bottom:clamp(12px,2vw,24px); display:flex; align-items:center; gap:10px;
  padding:9px 14px; border:2px solid; border-image:linear-gradient(135deg,#f6f7f9,#8a8e95 22%,#e3e6ea 46%,#5d6066 72%,#cdd0d5) 1;
  background:linear-gradient(180deg,#1a1b1e,#09090a); color:#e9ebee; font:600 9px/1 var(--font); letter-spacing:.26em; text-transform:uppercase; cursor:pointer;
  box-shadow:0 8px 20px rgba(0,0,0,.6); }
.sound-toggle:focus-visible { outline:1px dashed rgba(255,255,255,.7); outline-offset:4px; }
.sound-bars { display:flex; align-items:flex-end; gap:2px; height:10px; }
.sound-bars i { width:2px; height:100%; background:currentColor; transform-origin:bottom; animation:sound-bar .9s ease-in-out infinite alternate; }
.sound-bars i:nth-child(2) { animation-delay:-.3s; } .sound-bars i:nth-child(3) { animation-delay:-.6s; }
@keyframes sound-bar { from { transform:scaleY(.25); } to { transform:scaleY(1); } }
.sound-toggle.is-muted .sound-bars i { animation:none; transform:scaleY(.2); }
@media (prefers-reduced-motion:reduce) { .sound-bars i { animation:none; transform:scaleY(.6); } }

/* ---------- Cursor tilt below the stage (js/tilt.js) ----------
   The sections under the stage lean toward the cursor and drift a little, each by its own depth
   (--d), the same way the stage camera sways, so the page reads as one space. Only a transform:
   handled by the compositor, no layout. Off for touch screens and reduced motion. */
.tilt { transform:perspective(1400px) translate3d(calc(var(--tx,0) * 1px), calc(var(--ty,0) * 1px), 0)
  rotateX(calc(var(--rx,0) * 1deg)) rotateY(calc(var(--ry,0) * 1deg)); will-change:transform; }

/* ---------- Case study: format grid + spec sheet (work/boiler-room.html) ---------- */
/* Format grid: a full-width piece on top, then a row where every piece is the same height
   whatever its shape (each grows by its width/height ratio --r). Small spec labels, tech-rider style. */
.fmt, .cs-spec { padding:clamp(56px,7vw,110px) var(--gutter); border-top:1px solid var(--line); }
.fmt-head { display:grid; grid-template-columns:auto 1fr; align-items:baseline; column-gap:24px; margin-bottom:clamp(28px,3.5vw,52px); }
.fmt-head .cs-num { margin:0; }
.fmt-head h2 { margin:0; font-size:clamp(24px,2.4vw,40px); font-weight:600; letter-spacing:-.01em; }
.fmt-head p { grid-column:2; margin:10px 0 0; color:var(--dim); max-width:46ch; }
.fmt-item { margin:0; }
.fmt-item--wide { margin-bottom:12px; }
.fmt-row { display:flex; gap:12px; }
.fmt-row .fmt-item { flex:calc(var(--r)) 1 0; min-width:0; }
.fmt-cap { position:absolute; z-index:3; left:0; right:0; bottom:0; display:flex; align-items:baseline; gap:10px; padding:28px 12px 10px;
  font-size:10px; font-weight:500; letter-spacing:.24em; text-transform:uppercase; color:#fff; pointer-events:none;
  background:linear-gradient(180deg, rgba(0,0,0,0), rgba(0,0,0,.65)); }
.fmt-cap b { font-weight:600; color:rgba(255,255,255,.55); }
.fmt-cap span { margin-left:auto; letter-spacing:.14em; color:rgba(255,255,255,.7); white-space:nowrap; }

/* Spec sheet: three columns under one rule */
.cs-spec-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(24px,3vw,48px); padding-top:22px; border-top:1px solid var(--line); }
.cs-spec-grid h3 { margin:0 0 14px; font-size:10px; font-weight:500; letter-spacing:.3em; text-transform:uppercase; color:var(--dim); }
.cs-spec-grid p { margin:0 0 1em; max-width:38ch; color:#c9c9c9; }
.cs-list { list-style:none; margin:0; padding:0; }
.cs-list li { display:flex; justify-content:space-between; gap:16px; padding:10px 0; border-bottom:1px solid var(--line); }
.cs-list li:first-child { padding-top:0; }
.cs-list li span { font-size:13px; color:var(--dim); white-space:nowrap; }
/* A list whose rows are links (e.g. artists → Spotify): the whole row is the link. */
.cs-list--links a { display:flex; flex:1; justify-content:space-between; gap:16px; color:inherit; text-decoration:none; }
.cs-list--links a span { transition:color .3s var(--ease); }
.cs-list--links a:hover span, .cs-list--links a:focus-visible span { color:#fff; }

@media (max-width:760px) {
  .fmt-head { grid-template-columns:1fr; } .fmt-head p { grid-column:1; }
  .fmt-row { gap:8px; } .fmt-cap span { display:none; }
  .cs-spec-grid { grid-template-columns:1fr; }
}

/* ---------- Sound-on-hover badge (js/hover-audio.js) ---------- */
/* Top-right of each video: quiet until hovered, then says what's happening. */
[data-hover-audio] { cursor:pointer; }
.hover-sound { position:absolute; z-index:4; top:10px; right:10px; display:flex; align-items:center; gap:8px; padding:6px 10px;
  font-size:9px; font-weight:600; letter-spacing:.24em; text-transform:uppercase; color:#fff; pointer-events:none;
  background:rgba(0,0,0,.55); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  opacity:0; transform:translateY(-4px); transition:opacity .3s var(--ease), transform .3s var(--ease); }
[data-hover-audio]:hover .hover-sound, .has-sound .hover-sound, .needs-click .hover-sound, .is-touch .hover-sound { opacity:1; transform:none; }
.hover-sound .sound-bars i { animation-play-state:paused; transform:scaleY(.25); }
.has-sound .hover-sound .sound-bars i { animation-play-state:running; }
.hover-sound .hs-label::after { content:"Sound on hover"; }
.has-sound .hover-sound .hs-label::after { content:"Sound on"; }
.needs-click .hover-sound .hs-label::after { content:"Click for sound"; }
.is-muted-pref .hover-sound .hs-label::after { content:"Sound is muted"; }
.is-touch .hover-sound .hs-label::after { content:"Tap to play with sound"; }
.is-touch.has-sound .hover-sound .hs-label::after { content:"Tap to mute"; }
.is-touch .hover-sound { opacity:.85; }

/* ---------- Stage controls: size scale ----------
   Every panel dimension comes from --u, which steps down on smaller screens so the road cases
   don't crowd the stage. (Overrides the fixed sizes in "Stage controls" above.) */
.stage-ui { --u:1; }
@media (max-width:1280px) { .stage-ui { --u:.88; } }
@media (max-width:1000px) { .stage-ui { --u:.78; } }
@media (max-width:760px)  { .stage-ui { --u:.7; } }
.rc { padding:calc(12px * var(--u)) calc(16px * var(--u)); font-size:max(7px, calc(9px * var(--u))); border-width:max(2px, calc(3px * var(--u))); }
.rc::before { inset:calc(-9px * var(--u));
  --ball:radial-gradient(circle closest-side at 47% 45%, #fff 0 12%, #e3e6ea 30%, #8d9198 58%, #2b2d31 88%, transparent 97%);
  background-size:calc(15px * var(--u)) calc(15px * var(--u)); }
.rc-slider { width:calc(120px * var(--u)); height:calc(20px * var(--u)); }
.rc-track { height:max(4px, calc(6px * var(--u))); margin-top:calc(max(4px, calc(6px * var(--u))) / -2); }
.rc-knob { width:calc(18px * var(--u)); height:calc(18px * var(--u)); margin:calc(-9px * var(--u)) 0 0 calc(-9px * var(--u)); }
.rc-slider--v { width:calc(22px * var(--u)); height:calc(110px * var(--u)); }
.rc-slider--v .rc-track { width:max(4px, calc(6px * var(--u))); height:auto; margin:0 0 0 calc(max(4px, calc(6px * var(--u))) / -2); }
.rc-slider--v .rc-knob { margin:0 0 calc(-9px * var(--u)) calc(-9px * var(--u)); }
.rc-lights { gap:calc(10px * var(--u)); padding:calc(10px * var(--u)) calc(14px * var(--u)); }
.rc-rail { height:calc(12px * var(--u)); }
.rc-rail .rc-knob { width:calc(20px * var(--u)); height:calc(20px * var(--u)); margin:calc(-10px * var(--u)) 0 0 calc(-10px * var(--u)); }
.rc-mod { gap:calc(12px * var(--u)); }
.rc-booth { gap:calc(8px * var(--u)); }
.rc-title, .rc-hint, .rc-btn-label { font-size:max(7px, calc(8px * var(--u))); }
.rc-lcd { min-width:calc(220px * var(--u)); max-width:calc(320px * var(--u)); padding:calc(7px * var(--u)) calc(12px * var(--u)); font-size:max(9px, calc(12px * var(--u))); }
.rc-speaker { gap:calc(10px * var(--u)); padding:calc(12px * var(--u)) calc(12px * var(--u)) calc(10px * var(--u)); }
.rc-btn { width:calc(34px * var(--u)); height:calc(34px * var(--u)); }

/* ---------- Focus view (js/lightbox.js) ----------
   Click a photo/video on a case page: it grows from its spot to ~78% of the screen, the page dims
   and softens behind it. The frame's size/position is animated by the script. */
.lb-able { cursor:zoom-in; }
.lb-able:focus-visible { outline:1px solid rgba(255,255,255,.7); outline-offset:4px; }
.is-lb-source > img { visibility:hidden; }
html.lb-lock, html.lb-lock body { overflow:hidden; }
.lb { position:fixed; inset:0; z-index:200; cursor:zoom-out; }
.lb[hidden] { display:none; }
.lb-back { position:absolute; inset:0; background:rgba(4,4,4,.86); opacity:0;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); transition:opacity .5s var(--ease); }
.lb-frame { position:fixed; overflow:hidden; background:#000; box-shadow:0 30px 120px rgba(0,0,0,.6); }
.lb-frame > img, .lb-frame > video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.lb-frame.is-whole { background:#ececec; }
.lb-frame.is-whole > img { object-fit:contain; }
.lb-cap { position:fixed; left:0; right:0; bottom:max(14px, 4.5vh); margin:0; padding:0 var(--gutter); text-align:center;
  font-size:10px; letter-spacing:.24em; text-transform:uppercase; color:rgba(255,255,255,.7);
  opacity:0; transform:translateY(6px); transition:opacity .4s var(--ease), transform .4s var(--ease); }
.lb-close { position:fixed; top:max(14px, 3vh); right:max(14px, 3vw); width:44px; height:44px; border:1px solid rgba(255,255,255,.25);
  border-radius:50%; background:rgba(0,0,0,.4); color:#fff; font-family:inherit; font-size:24px; font-weight:300; line-height:1; cursor:pointer;
  opacity:0; transition:opacity .4s var(--ease), border-color .3s var(--ease); }
.lb-close:hover, .lb-close:focus-visible { border-color:#fff; outline:none; }
.lb.is-open .lb-back, .lb.is-open .lb-close { opacity:1; }
.lb.is-open .lb-cap { opacity:1; transform:none; transition-delay:.25s; }
@media (prefers-reduced-motion:reduce) { .lb-back, .lb-cap, .lb-close { transition-duration:.01s; } }

/* A large figure under the spec sheet (e.g. the TouchDesigner program). */
.cs-figure { margin:clamp(40px,5vw,72px) 0 0; }
.cs-figure .cs-media { background:#000; }
.cs-figure figcaption { margin-top:14px; font-size:10px; letter-spacing:.24em; text-transform:uppercase; color:var(--dim); }
