/* ================================================== typeface ==
   Self-hosted. Google Fonts costs two extra DNS lookups, two TLS
   handshakes and a render-blocking stylesheet before a word appears.
   Same variable font, served from our own origin, latin only. */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 200;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 200;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display:swap;
  src: url(fonts/bricolage-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   ESID — shared system
   One light, one typeface, one rail. Every page is lit by the same source and
   sits on the same grid, so moving between them reads as one journey.
   ========================================================================== */

@view-transition { navigation: auto; }

:root{
  --ink:#0a0b0d;
  --raise:#111316;
  --line:rgba(244,241,236,.10);
  --line-soft:rgba(244,241,236,.05);
  --white:#f4f1ec;
  --grey:#b3aea6;          /* 8.8:1 on --ink */
  --mute:#8b8780;          /* 5.4:1 on --ink */
  --pearl-ink:#11121a;     /* text that sits on a pearl fill */

  /* Accent hues. Light and luminous rather than saturated, so they read as
     tinted light in the ambient glow and stay legible as text on the ink.
     --accent colours the page furniture; --glow-rgb tints the atmosphere.
     A page opts in with data-accent on <body>; everything else stays amber. */
  --accent:#ffb88f;
  --glow-rgb:186,172,255;
  --accent-grad:linear-gradient(133deg,#ffb877 0%,#ff9ecb 19%,#bf9dff 38%,#8fc9ff 56%,#8ae8c6 74%,#ffc48a 92%,#ff9f62 100%);
  --face:"Bricolage Grotesque",-apple-system,"Helvetica Neue",Arial,sans-serif;
  --wrap:1340px;
  --gut:clamp(20px,4.5vw,70px);
  --rail:clamp(96px,13vw,190px);
  --ease:cubic-bezier(.16,1,.3,1);
  --slow:cubic-bezier(.22,1,.28,1);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:92px}
body{
  margin:0;background:var(--ink);color:var(--white);
  font-family:var(--face);font-weight:300;line-height:1.6;
  font-size:17px;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
::selection{background:#d5c6ff;color:var(--pearl-ink)}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:5px;border-radius:3px}
img{display:block;max-width:100%}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut)}
.skip{position:absolute;left:-9999px;top:0;z-index:99;background:var(--accent);
  color:var(--pearl-ink);padding:12px 20px;border-radius:0 0 8px 0}
.skip:focus{left:0}

/* ---------------------------------------------------------------- light -- */
/* ------------------------------------------------------------- accents --
   One hue per project, so a case page carries the colour of the work rather
   than the house orange. Set on <body data-accent="...">. */
[data-accent="blue"]  {--accent:#7fb0ff;--glow-rgb:127,176,255;--accent-grad:linear-gradient(133deg,#ffb88a 0%,#bda6ff 24%,#7db6ff 46%,#86dcf2 68%,#ffb89a 100%)}
[data-accent="pink"]  {--accent:#ff9ec0;--glow-rgb:255,158,192;--accent-grad:linear-gradient(133deg,#ffab72 0%,#ff8dc0 24%,#cf92ff 48%,#a8b6ff 70%,#ffb996 100%)}
[data-accent="purple"]{--accent:#b79bff;--glow-rgb:183,155,255;--accent-grad:linear-gradient(133deg,#ffb27e 0%,#cf9cff 26%,#9b82ff 50%,#93a8ff 72%,#ffb894 100%)}
[data-accent="green"] {--accent:#85dcae;--glow-rgb:133,220,174;--accent-grad:linear-gradient(133deg,#ffb87e 0%,#b8a8ff 24%,#6fd9b0 50%,#a8e695 72%,#ffc48e 100%)}
[data-accent="grey"]  {--accent:#aebcca;--glow-rgb:174,188,202;--accent-grad:linear-gradient(133deg,#e8bf9c 0%,#b8b2d6 28%,#a8bcd0 52%,#c2cdd6 74%,#e8c4a4 100%)}
[data-accent="warm"]  {--accent:#f3d8c4;--glow-rgb:255,196,150;--accent-grad:linear-gradient(133deg,#ff9f5c 0%,#ffb894 18%,#ffa8c4 38%,#c9a6f0 60%,#ffc08a 82%,#ff8f45 100%)}

/* ------------------------------------------------------------ luminance --
   Large accent text is painted with a light-to-hue gradient so it reads as
   lit rather than filled. The colour is set first and the clip applied only
   where it is supported -- if background-clip ever fails the text stays
   visible in flat accent instead of vanishing. */
.cyc .w,.cyc .ghost,.stmt p .acc,.stat b,.next em,.pstat b,
.eyebrow,.mark span,.forme-prototype-link,.protoembed figcaption a,
.article a,.fnote a{color:var(--accent)}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .cyc .w,.stmt p .acc,.stat b,.next em,.pstat b,
  .eyebrow,.mark span,.forme-prototype-link,.protoembed figcaption a{
    background-image:var(--accent-grad);
    background-size:330% 330%;background-position:0% 0%;
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;color:transparent;
    animation:pearl 9s linear infinite}
  .eyebrow,.mark span,.forme-prototype-link,.protoembed figcaption a{
    background-size:300% 300%;animation:pearl 22s linear infinite}
}
@keyframes pearl{0%{background-position:0% 0%}100%{background-position:100% 100%}}
@media (prefers-reduced-motion:reduce){
  .cyc .w,.stmt p .acc,.stat b,.next em,.pstat b{animation:none}
}

#glow{position:fixed;inset:-8%;z-index:0;pointer-events:none;overflow:hidden;
  transition:transform .7s cubic-bezier(.22,1,.28,1);will-change:transform}
/* An aurora, not a spotlight. Several pastel hues sit on top of each other and
   add their light rather than painting over it, so the ground stays near-black
   and the colour reads as sheen -- the iridescence of pearl, not a wash. The
   page accent leads; the others support it. Each drifts on its own slow clock
   so the field never repeats. */
#glow b{position:absolute;display:block;border-radius:50%;
  mix-blend-mode:screen;will-change:transform}
#g1{width:min(1150px,140vw);aspect-ratio:1;left:74%;top:-28%;
  background:radial-gradient(closest-side,
    rgba(var(--glow-rgb),.30),rgba(var(--glow-rgb),.12) 38%,transparent 74%);
  animation:drift1 9s ease-in-out infinite}
#g2{width:min(880px,108vw);aspect-ratio:1;left:4%;top:52%;
  background:radial-gradient(closest-side,
    rgba(183,155,255,.20),rgba(183,155,255,.07) 40%,transparent 74%);
  animation:drift2 12.5s ease-in-out infinite}
#g3{width:min(760px,96vw);aspect-ratio:1;left:58%;top:64%;
  background:radial-gradient(closest-side,
    rgba(127,176,255,.17),rgba(127,176,255,.06) 40%,transparent 74%);
  animation:drift3 14s ease-in-out infinite}
#g4{width:min(680px,88vw);aspect-ratio:1;left:22%;top:10%;
  background:radial-gradient(closest-side,
    rgba(133,220,174,.13),rgba(255,158,192,.05) 44%,transparent 74%);
  animation:drift4 10.5s ease-in-out infinite}
/* The field has to be seen to move. Wide travel and a real scale range, on
   four clocks that never line up, so the colour genuinely drifts across the
   page rather than sitting still. Opacity breathes between .55 and 1 -- never
   to zero, so a stalled animation can never blank the light. */
@keyframes drift1{
  0%,100%{transform:translate(-50%,0) scale(1);opacity:.92}
  33%{transform:translate(-72%,13%) scale(1.26);opacity:1}
  66%{transform:translate(-38%,6%) scale(.88);opacity:.7}}
@keyframes drift2{
  0%,100%{transform:translate(0,0) scale(1);opacity:.68}
  40%{transform:translate(26%,-17%) scale(1.3);opacity:1}
  70%{transform:translate(-11%,9%) scale(.86);opacity:.58}}
@keyframes drift3{
  0%,100%{transform:translate(0,0) scale(1.04);opacity:.8}
  45%{transform:translate(-24%,-15%) scale(.84);opacity:1}
  75%{transform:translate(14%,11%) scale(1.22);opacity:.62}}
@keyframes drift4{
  0%,100%{transform:translate(0,0) scale(.96);opacity:.74}
  38%{transform:translate(19%,20%) scale(1.28);opacity:1}
  72%{transform:translate(-15%,-8%) scale(.9);opacity:.6}}
@media (prefers-reduced-motion:reduce){
  #glow b{animation:none}
}
#grain{position:fixed;inset:0;z-index:60;pointer-events:none;opacity:.13;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")}
#page{position:relative;z-index:2}

/* -------------------------------------------------------------- progress - */
#bar{position:fixed;left:0;top:0;height:2px;width:100%;z-index:50;
  transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,var(--accent),rgba(var(--glow-rgb),.35))}

/* --------------------------------------------------------------- reveal -- */
/* Enhancement only: .js is set by script, so with it off nothing is hidden. */
.js .up{opacity:0;transform:translateY(26px) scale(.992);
  transition:opacity .9s var(--ease) var(--d,0s),transform 1.1s var(--slow) var(--d,0s)}
.js .up.seen{opacity:1;transform:none}
.js .t1{--d:.08s} .js .t2{--d:.16s} .js .t3{--d:.24s} .js .t4{--d:.32s}

/* a headline arrives line by line, out from behind its own baseline */
.ln{display:block;overflow:hidden;padding-bottom:.38em;margin-bottom:-.38em}
.js .ln > b{display:block;font-weight:inherit}
/* Lines that were not split into words still rise as a whole. */
.js .ln > b:not(:has(.wd)){transform:translateY(108%);
  transition:transform 1s var(--slow) var(--d,0s)}
.js .in .ln > b:not(:has(.wd)){transform:none}

/* The hero headline arrives a word at a time, each word rising out of a mask
   of its own. Per-word clipping is the whole point: a word cannot travel
   through the line above it, because it is only ever visible inside its own
   box. No blur, no rotation -- those inflate the bounding box mid-flight and
   make neighbouring lines collide. Transform only, so a stalled transition
   can never leave a word invisible. */
.js .wm{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.4em;margin-bottom:-.4em}
.js .wd{display:inline-block;
  transform:translateY(106%);
  transition:transform .95s cubic-bezier(.16,1,.3,1) calc(var(--i,0) * .08s)}
.js .in .wd{transform:none}
@media (prefers-reduced-motion:reduce){
  .js .wd{transform:none;transition:none}
}
.ln:nth-child(2){--d:.09s} .ln:nth-child(3){--d:.18s}

/* --------------------------------------------------------------- header -- */
header{position:sticky;top:0;z-index:40;border-bottom:1px solid transparent;
  transition:border-color .5s ease,background .5s ease;
  background:linear-gradient(to bottom,rgba(10,11,13,.93),rgba(10,11,13,.6) 66%,transparent);
  backdrop-filter:blur(11px);-webkit-backdrop-filter:blur(11px)}
/* .wrap supplies the side gutter; using the padding shorthand here would
   reset it to zero and push the logo against the screen edge. */
.bar{display:flex;align-items:center;justify-content:space-between;gap:14px 20px;
  padding-block:17px;flex-wrap:wrap;transition:padding .5s var(--ease)}
header.tight{border-bottom-color:var(--line-soft);
  background:rgba(10,11,13,.97);backdrop-filter:none;-webkit-backdrop-filter:none}
header.tight .bar{padding-block:11px}
.mark{font-size:21px;font-weight:400;letter-spacing:-.045em;view-transition-name:mark}
.mark span{color:var(--accent)}
.nav{display:flex;gap:clamp(18px,2.4vw,32px)}
.nav a{position:relative;font-size:15px;color:var(--grey);transition:color .25s}
.nav a::after{content:"";position:absolute;left:0;right:0;bottom:-5px;height:1px;
  background:var(--accent-grad);transform:scaleX(0);transform-origin:0 50%;
  transition:transform .4s var(--ease)}
.nav a.here{color:var(--white)}

/* A holographic surface, not a gradient fill. Foil looks the way it does
   because several hue bands sit at different angles and a hard specular
   highlight travels across them -- one smooth gradient just looks like a
   gradient. Three layers: an angled counter-sweep, the pearl itself, and a
   narrow bright band that moves. */
/* Glass on a dark page means letting the ground through, not laying a pale
   pill on top of it. The hue comes from thin iridescent bands and a lit rim;
   the body stays dark enough for the label to read. */
.btn{position:relative;display:inline-block;overflow:hidden;font-size:14.5px;
  font-weight:400;padding:11px 22px;border-radius:100px;
  background:
    linear-gradient(128deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,0) 22%,
      rgba(255,196,150,.26) 36%,rgba(231,196,255,.26) 52%,
      rgba(168,222,255,.24) 74%,rgba(255,200,160,.24) 100%),
    rgba(255,255,255,.055);
  background-size:280% 280%, auto;
  -webkit-backdrop-filter:blur(18px) saturate(190%);
  backdrop-filter:blur(18px) saturate(190%);
  border:1px solid rgba(255,255,255,.26);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.34),
             inset 0 -12px 22px -12px rgba(210,180,255,.30),
             0 10px 30px rgba(0,0,0,.4);
  animation:pearl 9s linear infinite;
  color:var(--white);transition:transform .3s var(--ease),border-color .3s}
/* the travelling highlight */
.btn::after{content:"";position:absolute;top:-60%;bottom:-60%;width:26%;left:-30%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);
  transform:skewX(-18deg);mix-blend-mode:overlay;pointer-events:none;
  animation:foil 5.5s var(--slow) infinite}
@keyframes foil{0%{left:-30%}55%,100%{left:118%}}
.btn::before{content:"";position:absolute;inset:0;background:#fff;opacity:0;
  transition:opacity .3s}
.btn span{position:relative;z-index:2}
@media (prefers-reduced-motion:reduce){
  .btn{animation:none}.btn::after{animation:none;opacity:.35;left:30%}
}
.btn.lg{font-size:16.5px;padding:15px 32px}
/* the header's CTA stays out of the way until the reader is deep enough in */
.js header .bar > .btn{opacity:0;pointer-events:none;transform:translateY(-8px);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.js header.deep .bar > .btn{opacity:1;pointer-events:auto;transform:none}
body[data-page="contact"] header .btn{display:none}
.btn.ghost{background:transparent;animation:none;box-shadow:none;color:var(--white);
  box-shadow:inset 0 0 0 1px var(--line)}
.btn.ghost::before{background:var(--accent);}
.btn.ghost::after{display:none}

#burger{display:none;flex-direction:column;gap:5px;background:none;border:0;
  padding:9px;cursor:pointer}
#burger i{display:block;width:22px;height:1.5px;background:var(--white);
  transition:transform .35s var(--ease)}
#burger[aria-expanded="true"] i:nth-child(1){transform:translateY(3.25px) rotate(45deg)}
#burger[aria-expanded="true"] i:nth-child(2){transform:translateY(-3.25px) rotate(-45deg)}
#sheet{position:fixed;inset:0;z-index:39;display:none;flex-direction:column;
  justify-content:center;gap:0;background:#08090b;
  padding:0 var(--gut);overflow-y:auto;overscroll-behavior:contain}
#sheet .sgroup{margin:0 0 4px;font-size:11.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--mute)}
#sheet .srule{margin:22px 0;border:0;border-top:1px solid var(--line-soft)}
#sheet a{display:block;font-size:clamp(26px,7.2vw,34px);font-weight:200;
  letter-spacing:-.04em;padding:7px 0;color:var(--cream);
  opacity:0;transform:translateY(14px);
  transition:opacity .45s var(--ease),transform .5s var(--ease)}
#sheet a.ssub{font-size:clamp(20px,5.4vw,25px);color:var(--grey);padding:5px 0}
#sheet .sgroup,#sheet .srule{opacity:0;transform:translateY(14px);
  transition:opacity .45s var(--ease),transform .5s var(--ease)}
#sheet.open a,#sheet.open .sgroup,#sheet.open .srule{opacity:1;transform:none}
#sheet.open > *:nth-child(1){transition-delay:.02s}
#sheet.open > *:nth-child(2){transition-delay:.05s}
#sheet.open > *:nth-child(3){transition-delay:.08s}
#sheet.open > *:nth-child(4){transition-delay:.11s}
#sheet.open > *:nth-child(5){transition-delay:.14s}
#sheet.open > *:nth-child(6){transition-delay:.17s}
#sheet.open > *:nth-child(7){transition-delay:.20s}
#sheet.open > *:nth-child(8){transition-delay:.23s}
#sheet.open > *:nth-child(9){transition-delay:.26s}
#sheet.open > *:nth-child(10){transition-delay:.29s}
/* #sheet a wins on specificity over .btn.lg, so the pill needs its
   padding restating or the label sits on the edge of the button. */
#sheet .btn{align-self:flex-start;margin-top:28px;font-size:16px;
  padding:14px 30px}

/* ----------------------------------------------------------------- type -- */
h1{font-size:clamp(42px,8.6vw,124px);font-weight:200;line-height:.94;
  letter-spacing:-.055em;margin:0}
h2{font-size:clamp(29px,4.4vw,62px);font-weight:200;line-height:1.02;
  letter-spacing:-.05em;margin:0 0 clamp(18px,2.2vw,28px);max-width:17ch;
  text-wrap:balance}
h2 .dim,h1 .dim{color:var(--mute)}
.lede{font-size:clamp(17px,1.55vw,21px);color:var(--grey);margin:0;
  max-width:46ch;line-height:1.5}
.body{font-size:clamp(16px,1.35vw,19px);color:var(--grey);margin:0 0 15px;max-width:54ch}
.body:last-child{margin-bottom:0}
.body strong{color:var(--white);font-weight:400}

/* the slogan rolls inside its own line mask */
.cyc{position:relative;display:inline-block;color:var(--accent)}
.cyc .ghost{visibility:hidden}
.cyc .w{position:absolute;left:0;top:0;white-space:nowrap;
  transform:translateY(168%);transition:transform .58s var(--slow)}
.cyc .w.on{transform:none}
.cyc .w.out{transform:translateY(-168%)}

/* -------------------------------------------------------------- sections - */
section{padding:clamp(56px,7.6vw,112px) 0}
section.ground{background:linear-gradient(to bottom,
  transparent,rgba(244,241,236,.036) 13%,rgba(244,241,236,.036) 87%,transparent)}
section.ruled{border-top:1px solid var(--line-soft)}
.sec{display:block}
.rail{position:static;margin-bottom:clamp(16px,2vw,24px)}
.eyebrow{font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);margin:.55em 0 0;font-weight:400;line-height:1.5}
.col{min-width:0}

/* heading band: the statement holds the left, its support the right, and the
   pair spans the page instead of stacking in a column */
/* page header: title left, its lede right */
.phd{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:clamp(26px,5vw,92px);align-items:end}
/* a page title is not the home hero; it sits a step down the scale */
.phd h1{margin:0;font-size:clamp(38px,5.2vw,76px);max-width:none!important}
.phd .lede{margin:0!important;max-width:44ch}
@media (max-width:900px){.phd{grid-template-columns:1fr;gap:22px}}
/* every chapter opens with the same beat: the container holds still, the
   heading wipes up out of nothing, the supporting line follows it */
.js .hd.up{opacity:1;transform:none}
.js .hd h2{clip-path:inset(0 -6% 104% -6%);transition:clip-path 1.15s var(--slow)}
.js .hd.seen h2{clip-path:inset(-14% -6% -8% -6%)}
.js .hd .body{opacity:0;transform:translateY(18px);
  transition:opacity .85s var(--ease) .28s,transform .95s var(--ease) .28s}
.js .hd.seen .body{opacity:1;transform:none}
.hd{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:clamp(26px,5vw,92px);align-items:end;margin-bottom:clamp(36px,5vw,74px)}
.hd h2{margin:0;max-width:15ch}
.hd .body{margin:0;max-width:46ch}
@media (max-width:900px){.hd{grid-template-columns:1fr;gap:20px}}

/* --------------------------------------------------------------- marquee - */
.mq{overflow:hidden;border-top:1px solid var(--line-soft);
  border-bottom:1px solid var(--line-soft);padding:clamp(16px,2vw,24px) 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.mqi{display:flex;width:max-content;animation:mqRun 42s linear infinite}
.mqi span{display:flex;align-items:center;gap:clamp(28px,4vw,58px);
  padding-right:clamp(28px,4vw,58px);font-size:clamp(17px,1.7vw,23px);
  font-weight:200;letter-spacing:-.035em;color:var(--grey);white-space:nowrap}
.mqi em{font-style:normal;color:var(--accent);font-size:.62em}
@keyframes mqRun{to{transform:translateX(-50%)}}

/* ----------------------------------------------------------------- rows -- */
.rows{border-top:1px solid var(--line)}
.row{position:relative;display:grid;
  grid-template-columns:38% minmax(0,1fr) 2.2em;
  gap:clamp(16px,3vw,44px);align-items:center;
  padding:clamp(18px,2.3vw,30px) 0;border-bottom:1px solid var(--line);
  transition:padding-left .5s var(--ease)}
.row::before{content:"";position:absolute;inset:-1px 0;pointer-events:none;
  background:linear-gradient(90deg,rgba(var(--glow-rgb),.13),rgba(var(--glow-rgb),.02) 42%,transparent 68%);
  opacity:0;transition:opacity .45s ease}
.row h3{position:relative;font-size:clamp(27px,4.1vw,58px);font-weight:200;
  letter-spacing:-.05em;margin:0;line-height:1}
.row p{position:relative;margin:0;font-size:16.5px;color:var(--grey);
  transition:color .3s;line-height:1.5;max-width:36ch}
.row .go{position:relative;justify-self:end;font-size:19px;color:var(--accent);
  opacity:0;transform:translateX(-10px);
  transition:opacity .35s,transform .45s var(--ease)}

/* ---------------------------------------------------------------- plates - */
/* Stand-ins for the real 9:16 work. Swap each .stage for an <img> and the
   layout does not change. */
.stage{position:relative;aspect-ratio:9/16;border-radius:12px;overflow:hidden;
  background:var(--raise);box-shadow:inset 0 0 0 1px var(--line)}
.stage span{position:absolute;inset:0;opacity:0;transition:opacity .55s ease;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(17px,1.7vw,25px)}
.stage span.on{opacity:1}
.stage span::before{content:attr(data-n);position:absolute;top:clamp(17px,1.7vw,25px);
  left:clamp(17px,1.7vw,25px);font-size:11.5px;letter-spacing:.16em;
  color:rgba(244,241,236,.42)}
.stage em{position:relative;font-style:normal;font-size:clamp(21px,2.3vw,31px);
  font-weight:200;letter-spacing:-.05em;line-height:1;color:var(--white);
  border-top:1px solid rgba(244,241,236,.16);padding-top:17px}
.stage small{position:relative;font-size:12.5px;line-height:1.5;color:var(--grey);
  margin-top:10px;max-width:22ch}
/* a caption with no title above it carries the rule itself */
.stage span > small:first-child{margin-top:0;padding-top:16px;max-width:26ch;
  border-top:1px solid rgba(244,241,236,.16);max-width:100%}
.k1{background:radial-gradient(58% 36% at 62% 22%,rgba(var(--glow-rgb),.44),transparent 68%),radial-gradient(70% 44% at 24% 88%,rgba(120,150,190,.16),transparent 72%),linear-gradient(168deg,#242932,#0d0f13 66%)}
.k2{background:radial-gradient(64% 40% at 30% 74%,rgba(var(--glow-rgb),.36),transparent 72%),linear-gradient(152deg,#2c211a,#0c0e11 68%)}
.k3{background:radial-gradient(52% 32% at 74% 58%,rgba(150,176,214,.34),transparent 70%),linear-gradient(178deg,#1c2129,#0b0d10 64%)}
.k4{background:radial-gradient(60% 42% at 40% 28%,rgba(var(--glow-rgb),.30),transparent 70%),linear-gradient(140deg,#212320,#0c0e11 66%)}
.k5{background:radial-gradient(56% 34% at 50% 80%,rgba(var(--glow-rgb),.42),transparent 72%),linear-gradient(160deg,#2e1d16,#0d0f12 64%)}
.k6{background:radial-gradient(62% 40% at 26% 20%,rgba(130,162,196,.32),transparent 70%),linear-gradient(172deg,#1a1f26,#0b0d10 66%)}
.k7{background:radial-gradient(54% 38% at 68% 76%,rgba(var(--glow-rgb),.34),transparent 70%),linear-gradient(146deg,#26221b,#0c0e11 66%)}
.k8{background:radial-gradient(58% 36% at 34% 26%,rgba(160,178,206,.28),transparent 70%),linear-gradient(184deg,#1d2228,#0b0d10 64%)}
.k9{background:radial-gradient(56% 38% at 70% 30%,rgba(138,168,204,.30),transparent 70%),linear-gradient(158deg,#1b2028,#0b0d10 66%)}
.k10{background:radial-gradient(62% 40% at 36% 72%,rgba(var(--glow-rgb),.38),transparent 72%),linear-gradient(144deg,#2a1f18,#0c0e11 66%)}
.k11{background:radial-gradient(58% 34% at 58% 24%,rgba(var(--glow-rgb),.28),transparent 70%),linear-gradient(174deg,#232620,#0b0d10 64%)}
.k12{background:radial-gradient(54% 36% at 28% 80%,rgba(150,176,214,.30),transparent 70%),linear-gradient(150deg,#1e232a,#0c0e11 66%)}

/* ------------------------------------------------------------- work list - */
.index{border-top:1px solid var(--line)}
.item{display:flex;align-items:baseline;justify-content:space-between;gap:24px;
  padding:clamp(15px,1.9vw,25px) 0;border-bottom:1px solid var(--line);
  transition:padding-left .5s var(--ease),opacity .35s}
.item b{font-size:clamp(24px,3.2vw,44px);font-weight:200;letter-spacing:-.05em;
  line-height:1.04}
.item i{font-style:normal;font-size:12.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mute);white-space:nowrap}

.workwrap{display:grid;grid-template-columns:minmax(0,1fr) clamp(240px,32%,340px);
  gap:clamp(28px,4vw,60px);align-items:start}
.plate{margin:0;position:sticky;top:104px}
.plate figcaption{margin-top:14px;font-size:12.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--mute)}

/* --------------------------------------------------------------- gallery - */
.gal{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,2.6vw,38px) clamp(18px,2.2vw,32px)}
.card{display:block;transition:opacity .4s ease,transform .5s var(--ease)}
.card .stage{transition:transform .7s var(--slow),box-shadow .5s}
.gal .stage em,.gal .stage small{display:none}
.card h3{margin:16px 0 5px;font-size:clamp(18px,1.7vw,24px);font-weight:300;
  letter-spacing:-.04em}
.card p{margin:0;font-size:12.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mute)}
.card.off{opacity:0;transform:scale(.97);pointer-events:none}
.card.gone{display:none}
.gal .card:nth-child(2n){margin-top:clamp(20px,3.2vw,52px)}

.filters{display:flex;gap:9px;flex-wrap:wrap;margin:clamp(26px,3.4vw,42px) 0 clamp(30px,4vw,52px)}
.filters button{font:inherit;font-size:14.5px;color:var(--grey);cursor:pointer;
  background:none;border:1px solid var(--line);border-radius:100px;
  padding:9px 19px;transition:color .25s,border-color .25s,background .25s}
.filters button[aria-pressed="true"]{color:var(--pearl-ink);background:var(--accent-grad);
  border-color:var(--accent)}

/* ----------------------------------------------------------------- steps - */
.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,3.4vw,52px);margin-top:clamp(34px,4.4vw,58px);
  position:relative;padding-top:34px}
.steps::before{content:"";position:absolute;left:0;right:0;top:5px;height:1px;
  background:linear-gradient(90deg,var(--accent),rgba(var(--glow-rgb),.16) 62%,var(--line-soft))}
.step{position:relative}
.step::before{content:"";position:absolute;left:0;top:-32px;width:9px;height:9px;
  border-radius:50%;background:var(--accent)}
.step:nth-child(2)::before{opacity:.6}
.step:nth-child(3)::before{opacity:.32}
.step b{display:block;font-size:12.5px;letter-spacing:.16em;color:var(--accent);
  font-weight:400;margin-bottom:11px}
.step h3{font-size:clamp(20px,2.1vw,28px);font-weight:300;letter-spacing:-.035em;
  margin:0 0 9px}
.step p{margin:0;font-size:15.5px;color:var(--grey);line-height:1.55}

/* ------------------------------------------------------------- next / cta - */
.next{display:block;border-top:1px solid var(--line);position:relative;
  overflow:hidden;padding:clamp(46px,7vw,104px) 0}
.next::before{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(var(--glow-rgb),.14),rgba(var(--glow-rgb),.02) 46%,transparent 72%);
  opacity:0;transition:opacity .5s ease}
.next .wrap{position:relative;display:flex;align-items:baseline;
  justify-content:space-between;gap:20px;flex-wrap:wrap}
.next small{display:block;font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);margin-bottom:16px}
.next em{font-style:normal;font-size:clamp(34px,6.6vw,92px);font-weight:200;
  letter-spacing:-.055em;line-height:1;display:block}
.next .arw{font-size:clamp(26px,3.4vw,46px);color:var(--accent);
  transition:transform .6s var(--slow)}

.mailto{display:inline-block;font-size:clamp(23px,3.4vw,50px);font-weight:200;
  letter-spacing:-.05em;
  background-image:linear-gradient(var(--accent),var(--accent));
  background-repeat:no-repeat;background-position:0 100%;background-size:0% 1px;
  transition:background-size .55s var(--ease),color .3s}

/* ---------------------------------------------------------------- footer - */
footer{border-top:1px solid var(--line-soft);padding:34px 0 58px}
footer .wrap{display:flex;justify-content:space-between;align-items:baseline;
  gap:18px;flex-wrap:wrap;font-size:14px;color:var(--mute)}
footer nav{display:flex;gap:22px;flex-wrap:wrap}
footer em{font-style:normal;color:var(--accent)}
footer a{transition:color .2s}

/* --------------------------------------------------------------- mobile -- */
@media (max-width:900px){
  .js .nav,.js .bar .btn{display:none}
  .js #burger{display:flex}
  .js #sheet.open{display:flex}
  .nav{gap:16px;font-size:14px;order:3;width:100%;padding-bottom:2px}
  .sec{grid-template-columns:1fr;gap:0}
  .rail{position:static;margin-bottom:18px}
    .col{grid-column:1}
  .row{grid-template-columns:1fr;gap:8px;align-items:start}
  .row .go{display:none}
  .row:hover{padding-left:0}
  .row:hover::before{opacity:0}
  .item:hover{padding-left:0}
  .index:hover .item{opacity:1}
  .workwrap{display:flex;flex-direction:column}
  .plate{order:-1;position:static;width:min(280px,72%);margin-bottom:26px}
  .gal{grid-template-columns:repeat(2,minmax(0,1fr))}
  .steps{grid-template-columns:1fr;gap:30px;padding-top:0}
  .steps::before{display:none}
  .step{padding-top:22px}
  .step::before{top:0;left:0}
}
@media (max-width:560px){
  /* eight full-width 9:16 frames is a 7,500px phone page; two up stays scannable */
  .gal{gap:clamp(12px,3vw,20px)}
  .card h3{font-size:16px;margin-top:12px}
  .card p{font-size:11px}
}

/* ------------------------------------------------- page transition + a11y - */
::view-transition-old(root){animation:vtOut .3s ease both}
::view-transition-new(root){animation:vtIn .48s .04s var(--ease) both}
@keyframes vtOut{to{opacity:0;transform:translateY(-10px)}}
@keyframes vtIn{from{transform:translateY(18px)}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .drop,#sheet.open a,.qa[open] .ans,.wall{animation:none}
  .cue i::after{animation:none;transform:none;opacity:.5}
  .js .up{opacity:1;transform:none;transition:none}
  .js .ln > b{transform:none;transition:none}
  .cyc .w,.row,.item,.btn,.card,.card .stage,.mailto,.next .arw{transition:none}
  .mqi{animation:none}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}


/* ==========================================================================
   MEDIA
   The work is 9:16, so "big" means a band of verticals across the full width
   rather than one letterboxed image. Every .shot is an image slot: replace the
   inner .fill with an <img> and nothing else changes.
   ========================================================================== */
.shot{margin:0;position:relative;aspect-ratio:9/16;overflow:hidden;border-radius:10px;
  background:var(--raise);box-shadow:inset 0 0 0 1px var(--line)}
.shot .fill{position:absolute;left:0;right:0;top:-7%;bottom:-7%}
.shot img.fill{width:100%;height:114%;object-fit:cover}
/* light falling across the frame, so a still reads as photographed */
.shot::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(46% 30% at 50% 34%,rgba(0,0,0,.30),transparent 72%),
    linear-gradient(to top,rgba(0,0,0,.46),rgba(0,0,0,.06) 42%,transparent 68%)}
.shot b{position:absolute;left:clamp(13px,1.2vw,18px);top:clamp(13px,1.2vw,18px);
  z-index:2;font-size:11px;letter-spacing:.16em;font-weight:400;
  color:rgba(244,241,236,.5)}
.shot figcaption{position:absolute;left:clamp(13px,1.2vw,18px);
  right:clamp(13px,1.2vw,18px);bottom:clamp(13px,1.2vw,18px);z-index:2;
  font-size:12.5px;line-height:1.45;color:rgba(244,241,236,.82)}

.band{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(9px,1.1vw,16px)}
.band.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.band.four{grid-template-columns:repeat(4,minmax(0,1fr))}
.band .shot:nth-child(2){margin-top:clamp(14px,2.6vw,44px)}
.band.flat .shot:nth-child(2){margin-top:0}
.band .shot:nth-child(1){--d:0s}
.band .shot:nth-child(2){--d:.09s}
.band .shot:nth-child(3){--d:.18s}

/* --------------------------------------------------------- featured case - */
.feat{padding:clamp(44px,6.5vw,96px) 0}
.feat > a.wrap{display:flex;flex-direction:column;align-items:flex-start}
.feat .head,.feat .band{width:100%}
.feat.flip > a.wrap{align-items:flex-end}
.feat.flip .head{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr)}
.feat.flip .head > div{order:2;text-align:right}
.feat.flip .head .say{order:1}
.feat.flip .band .shot:nth-child(2){margin-top:0}
.feat.flip .band .shot:nth-child(3){margin-top:clamp(14px,2.6vw,44px)}
.feat .head{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);
  gap:clamp(20px,4vw,64px);align-items:end;margin-bottom:clamp(24px,3vw,40px)}
.feat .head p.eyebrow{margin:0 0 14px}
.feat h3{font-size:clamp(38px,8.2vw,120px);font-weight:200;letter-spacing:-.055em;
  line-height:.92;margin:0}
.feat .head .say{max-width:34ch;font-size:clamp(16px,1.4vw,19px);color:var(--grey);
  margin:0}
.feat .more{display:inline-flex;align-items:center;gap:12px;margin-top:clamp(22px,2.6vw,34px);
  font-size:15.5px;color:var(--accent)}
.feat .more span{width:26px;height:1px;background:var(--accent-grad);
  transition:width .5s var(--slow)}

/* ------------------------------------------------------------------ reel - */
/* Vertical scroll drives the row sideways, so eight pieces get the whole
   width instead of eight rows of it. */
/* ================================================================ hero ===
   The hero is made of the work itself: columns of frames drifting at
   different speeds behind the line. Swap each .fr for an <img> and it becomes
   a real wall. */
.hero{position:relative;display:flex;align-items:center;
  min-height:calc(100svh - 74px);overflow:hidden;
  padding:clamp(56px,8vh,96px) 0 clamp(70px,10vh,120px)}

.wall{position:absolute;inset:-9% -1%;z-index:0;opacity:.85;
  animation:wallIn 1.9s var(--slow) .1s both}
@keyframes wallIn{from{transform:scale(1.06)}}
/* inner layer: owns the scroll-driven dissolve, so the intro animation and
   the hand-off to the next section never fight over one transform */
.wallin{position:absolute;inset:0;display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(8px,.85vw,14px);
  transform-origin:50% 38%;will-change:transform,opacity}
/* the plate classes use the background shorthand, which clears the colour;
   this outranks them for that one property so each frame has a body */
.wallin .wcol > span{background-color:#171c24}
/* plates are stand-ins and need the old lift; real images must not get it */
.wallin .fr:not(:has(img)){filter:brightness(1.12) saturate(1.02)}
.wallin .fr::after{background:linear-gradient(to top,rgba(0,0,0,.34),transparent 56%);
  opacity:1;transition:opacity .6s var(--slow)}
.wallin .wcol{display:grid;gap:clamp(8px,.85vw,14px);align-content:start;
  will-change:transform;transform:translate3d(0,0,0)}
.fr{position:relative;aspect-ratio:9/16;border-radius:10px;overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(244,241,236,.07)}
.fr::after{content:"";position:absolute;inset:0;
  background:radial-gradient(52% 34% at 50% 36%,rgba(0,0,0,.26),transparent 74%),
             linear-gradient(to top,rgba(0,0,0,.42),transparent 52%)}
.fr img{width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(.72) brightness(.19);
  transition:filter .6s var(--slow),transform .6s var(--slow)}
/* the frames sit behind the headline, which would otherwise eat the hover */
.heroin{pointer-events:none}
/* no hover on touch, so the work shows in colour there */
@media (hover:none){.fr img{filter:grayscale(1) contrast(.8) brightness(.30)}}

/* the ground the words stand on */
.veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(101deg,
      rgba(10,11,13,.985) 0%,rgba(10,11,13,.95) 27%,rgba(10,11,13,.63) 45%,
      rgba(10,11,13,.18) 68%,rgba(10,11,13,.02) 100%),
    linear-gradient(to bottom,rgba(10,11,13,.92),rgba(10,11,13,0) 15%,
      rgba(10,11,13,0) 72%,rgba(10,11,13,.97))}

.heroin{position:relative;z-index:2;width:100%}
/* The wall starts around the middle of the screen, so the headline is
   bounded by the viewport as well as by character count -- a ch limit
   alone lets the longest rotating word run under the first frame. */
.hero h1{font-size:clamp(46px,7.6vw,124px);max-width:min(12.6ch,42vw);line-height:1}
.hero .lede{max-width:38ch;font-size:clamp(18px,1.75vw,24px);color:var(--grey)}

.cue{position:absolute;left:var(--gut);bottom:clamp(24px,5vh,52px);z-index:2;
  display:flex;align-items:center;gap:18px;font-size:12.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--grey)}
.cue i{display:block;width:92px;height:1px;background:var(--line);
  position:relative;overflow:hidden}
.cue i::after{content:"";position:absolute;inset:0;background:var(--accent);
  transform:translateX(-101%);animation:cueRun 2.6s var(--ease) infinite}
@keyframes cueRun{0%{transform:translateX(-101%)}
  55%{transform:translateX(101%)}100%{transform:translateX(101%)}}

/* the wall is one row of columns; when the grid narrows, drop the trailing
   columns rather than letting them wrap onto a second, clipped row */
@media (max-width:1000px){
  .wallin{grid-template-columns:repeat(3,minmax(0,1fr))}
  .wallin .wcol:nth-child(4){display:none}
}
/* ------------------------------------------------------------- phone ----
   A phone is not a narrow desktop. The hero stops being a wide stage with
   type pinned left and becomes a centred title card; the wall goes denser so
   it reads as texture rather than two big lonely tiles; and the vertical
   rhythm tightens, because 112px of air between sections is a third of the
   screen here. */
@media (max-width:760px){
  .wallin{grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}
  .wallin .wcol:nth-child(4){display:none}
  .wallin .wcol{gap:7px}
  .wall{opacity:.85}
  .veil{background:
    linear-gradient(to bottom,rgba(10,11,13,.92),rgba(10,11,13,.55) 26%,
      rgba(10,11,13,.58) 68%,rgba(10,11,13,.97))}

  .hero{min-height:78svh;padding:clamp(28px,6vh,52px) 0 clamp(34px,7vh,58px);
    text-align:center}
  .hero h1{font-size:clamp(42px,12.5vw,74px);max-width:11ch;margin-inline:auto}
  .hero .lede{margin-inline:auto}
  .cue{display:none}

  section{padding:clamp(38px,9vw,58px) 0}
  .stmt{padding:clamp(48px,12vw,72px) 0}
  .stmt p{max-width:15ch}
  .logos{padding:clamp(18px,4.4vw,26px) 0}
  .next{padding:clamp(34px,8vw,52px) 0}
}
@media (prefers-reduced-motion:reduce){
  .fr img{transition:none}
  .fr:hover img{transform:none}
  .wallin .fr::after{transition:none}
  .wall{animation:none;opacity:.92}
  .wallin{transform:none !important}
  .wall .wcol{transform:none !important}
  .cue i::after{animation:none;transform:none;opacity:.5}
}

.reel{position:relative;height:230vh}
.reel .stick{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;
  justify-content:center;overflow:hidden}
.reel .track{display:flex;gap:clamp(12px,1.3vw,20px);padding:0 var(--gut);
  width:max-content;will-change:transform}
.reel .track .shot{flex:none;height:min(70vh,660px);width:auto;aspect-ratio:9/16}
.reel .rhead{padding:0 var(--gut);margin-bottom:clamp(20px,2.6vw,34px);
  display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap}
.reel .rhead h2{margin:0;max-width:20ch}
.reel .count{font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mute)}
.reel .cardname{margin-top:14px;display:flex;justify-content:space-between;
  align-items:baseline;gap:14px}
.reel .cardname b{font-size:17px;font-weight:300;letter-spacing:-.03em}
.reel .cardname i{font-style:normal;font-size:11.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--mute)}
.reel .piece{flex:none;display:block}

/* ------------------------------------------------------------ case study - */
.spread{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(26px,5vw,80px);align-items:center;padding:clamp(40px,6vw,88px) 0}
.spread.flip > div:first-child{order:2}
.spread .say h3{font-size:clamp(24px,3.2vw,44px);font-weight:200;letter-spacing:-.05em;
  line-height:1.04;margin:0 0 18px;max-width:15ch}
.spread .say p.eyebrow{margin:0 0 16px}
.quote{padding:clamp(46px,7vw,104px) 0;font-size:clamp(24px,3.6vw,50px);
  font-weight:200;line-height:1.16;letter-spacing:-.045em;max-width:20ch;margin:0}
.quote cite{display:block;font-style:normal;font-size:14px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--mute);margin-top:clamp(20px,2.4vw,30px)}

/* ---------------------------------------------------------- work gallery - */
.gal .card .shot{margin:0}
.gal .card .shot{transition:transform .7s var(--slow)}

@media (max-width:900px){
  .band,.band.four{grid-template-columns:repeat(2,minmax(0,1fr))}
  .band .shot:nth-child(2){transform:none}
  .reel{height:auto}
  .reel .stick{position:static;height:auto;overflow-x:auto;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch}
  .reel .track{transform:none !important;padding-bottom:8px}
  .reel .track .shot{height:min(62vh,460px)}
  .reel .piece{scroll-snap-align:center}
  .spread{grid-template-columns:1fr;gap:24px;padding:clamp(30px,7vw,50px) 0}
  .spread.flip > div:first-child{order:0}
  .feat h3{font-size:clamp(34px,10vw,62px)}
  .feat .head,.feat.flip .head{grid-template-columns:1fr;gap:18px}
  .feat.flip .head > div{order:0;text-align:left}
  .feat.flip .head .say{order:1}
  .feat.flip > a.wrap{align-items:flex-start}
  .feat.flip .head > div{text-align:left}
}
@media (max-width:560px){
  .band.four{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (prefers-reduced-motion:reduce){
  .shot .fill{transform:none !important}
  .reel{height:auto}
  .reel .stick{position:static;height:auto;overflow-x:auto}
  .reel .track{transform:none !important}
  .feat .more span{transition:none}
}


/* ============================================================= argument ===
   Four suppliers, four different outputs, read as a list. No pin and no
   moving parts — the point should land in one look. */
.roles{margin-top:clamp(30px,4vw,52px);border-top:1px solid var(--line)}
.role{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(16px,3vw,48px);align-items:baseline;
  padding:clamp(18px,2.4vw,30px) 0;border-bottom:1px solid var(--line)}
.role b{font-size:clamp(20px,2.4vw,32px);font-weight:200;letter-spacing:-.045em;
  line-height:1.1}
.role span{font-size:clamp(16px,1.5vw,19px);color:var(--grey);line-height:1.5}
.verdict{margin:clamp(38px,5vw,72px) 0 0;max-width:24ch;
  font-size:clamp(24px,3.4vw,48px);font-weight:200;line-height:1.14;
  letter-spacing:-.045em}
.verdict em{font-style:normal;color:var(--accent)}

/* ============================================================= statement ==
   A held pause after the hero. One sentence, nothing else on the screen. */
.stmt{padding:clamp(84px,12vw,176px) 0;text-align:center;
  background:radial-gradient(72% 60% at 50% 50%,rgba(244,241,236,.03),transparent 72%)}
.stmt p{margin:0 auto;max-width:17ch;font-size:clamp(34px,6.6vw,98px);font-weight:200;
  line-height:1.02;letter-spacing:-.055em;text-wrap:balance}
.stmt p .acc{color:var(--accent)}

/* ================================================================== fit ==
   A reader who has never heard of the four disciplines can still place
   themselves: pick what is going wrong and see which of them it belongs to,
   and what a first step looks like. A lookup, not an invented statistic. */
.fit{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(28px,4.5vw,80px);margin-top:clamp(30px,4vw,52px);align-items:start}
.symptoms{display:grid;gap:10px}
.sym{display:flex;align-items:flex-start;gap:14px;width:100%;text-align:left;
  background:none;border:1px solid var(--line);border-radius:12px;color:inherit;
  font:inherit;font-size:16.5px;line-height:1.45;cursor:pointer;
  padding:clamp(15px,1.8vw,21px) clamp(16px,2vw,22px);
  transition:border-color .3s,background .3s}
.sym i{flex:none;width:17px;height:17px;border-radius:5px;margin-top:2px;
  box-shadow:inset 0 0 0 1px var(--line);position:relative;transition:box-shadow .3s}
.sym i::after{content:"";position:absolute;inset:3px;border-radius:2px;
  background:var(--accent);opacity:0;transform:scale(.5);
  transition:opacity .25s,transform .35s var(--ease)}
.sym[aria-pressed="true"]{border-color:rgba(var(--glow-rgb),.42);
  background:rgba(var(--glow-rgb),.055)}
.sym[aria-pressed="true"] i{box-shadow:inset 0 0 0 1px var(--accent)}
.sym[aria-pressed="true"] i::after{opacity:1;transform:none}

.readout{position:sticky;top:104px;border:1px solid var(--line);border-radius:14px;
  padding:clamp(22px,2.8vw,34px);background:rgba(244,241,236,.02)}
.readout > p:first-child{margin:0 0 clamp(18px,2.2vw,26px);font-size:12.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.discs{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:10px;overflow:hidden}
.disc{display:flex;align-items:center;justify-content:space-between;gap:14px;
  background:var(--ink);padding:14px 16px;transition:background .35s}
.disc b{font-size:17px;font-weight:300;letter-spacing:-.03em;color:var(--mute);
  transition:color .35s}
.disc s{text-decoration:none;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute);opacity:0;transition:opacity .35s}
.disc.on{background:rgba(var(--glow-rgb),.09)}
.disc.on b{color:var(--white)}
.disc.on s{opacity:1;color:var(--accent)}
.stepout{margin:clamp(20px,2.4vw,28px) 0 0;padding-top:clamp(18px,2.2vw,24px);
  border-top:1px solid var(--line);font-size:16.5px;color:var(--grey);min-height:4em}
.stepout b{display:block;color:var(--white);font-weight:300;
  font-size:clamp(19px,2.1vw,26px);letter-spacing:-.035em;margin-bottom:9px}

/* ============================================================== timeline ==
   Three phases, one line that fills as the section passes. */
.tl{margin-top:clamp(40px,5.4vw,72px);position:relative;
  padding-top:clamp(34px,4vw,54px)}
.tl .rule{position:absolute;left:0;right:0;top:5px;height:1px;background:var(--line)}
.tl .rule i{position:absolute;inset:0;background:linear-gradient(90deg,var(--accent),
  rgba(var(--glow-rgb),.4));transform-origin:0 50%;transform:scaleX(var(--p,0))}
.phases{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(26px,4.4vw,64px)}
.ph{position:relative}
.ph::before{content:"";position:absolute;left:0;top:calc(-1 * clamp(34px,4vw,54px) + 1px);
  width:9px;height:9px;border-radius:50%;background:var(--line);
  transition:background .5s}
.ph.lit::before{background:var(--accent)}
.ph .when{font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);margin:0 0 12px}
.ph h3{font-size:clamp(21px,2.3vw,30px);font-weight:300;letter-spacing:-.04em;margin:0 0 12px}
.ph p{margin:0 0 16px;font-size:15.5px;color:var(--grey);line-height:1.6}
.ph .out{margin:0;padding:14px 0 0;border-top:1px solid var(--line-soft);
  font-size:14px;color:var(--mute)}
.ph .out b{display:block;color:var(--white);font-weight:400;font-size:15px;margin-bottom:5px}

/* =============================================================== contact ==
   The reassurance belongs beside the commitment, not seven hundred pixels
   under it. */
.cform{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
  gap:clamp(30px,5vw,92px);align-items:start}
.aside{position:sticky;top:104px;border-left:1px solid var(--line);
  padding-left:clamp(22px,3vw,42px);display:grid;gap:clamp(22px,2.6vw,32px)}
.aside .bit p:first-child{margin:0 0 9px;font-size:12.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.aside .bit p:last-child{margin:0;font-size:16.5px;color:var(--grey);line-height:1.55}
.aside .mailto{font-size:clamp(19px,1.9vw,25px);margin-top:4px}
@media (max-width:900px){
  .cform{grid-template-columns:1fr;gap:40px}
  .aside{position:static;border-left:0;padding-left:0;border-top:1px solid var(--line);
    padding-top:30px}
}

/* ================================================================ models ==*/
.models{margin-top:clamp(36px,5vw,64px);border-top:1px solid var(--line)}
.model{display:grid;grid-template-columns:clamp(150px,16vw,230px) minmax(0,1fr) auto;
  gap:clamp(18px,3vw,48px);align-items:start;padding:clamp(24px,3.4vw,44px) 0;
  border-bottom:1px solid var(--line)}
.model h3{font-size:clamp(20px,2.2vw,28px);font-weight:300;letter-spacing:-.04em;margin:0}
.model p{margin:0;color:var(--grey);font-size:16px;max-width:48ch}
.model .meta{text-align:right;font-size:13px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mute);white-space:nowrap}

/* =================================================================== faq ==*/
.faq{margin-top:clamp(30px,4vw,52px);border-top:1px solid var(--line);max-width:none}
.qa{border-bottom:1px solid var(--line)}
.qa summary{width:100%;display:flex;align-items:center;justify-content:space-between;
  list-style:none;
  gap:24px;background:none;border:0;color:inherit;font:inherit;cursor:pointer;
  text-align:left;padding:clamp(20px,2.6vw,30px) 0;
  font-size:clamp(17px,1.8vw,23px);font-weight:300;letter-spacing:-.03em;
  transition:color .3s}
.qa summary::-webkit-details-marker{display:none}
.qa .sign{position:relative;flex:none;width:14px;height:14px}
.qa .sign::before,.qa .sign::after{content:"";position:absolute;inset:50% 0 auto 0;
  height:1px;background:currentColor;transition:transform .45s var(--ease)}
.qa .sign::after{transform:rotate(90deg)}
.qa[open] .sign::after{transform:rotate(0)}
.qa[open] .ans{animation:ansIn .5s var(--ease) both}
@keyframes ansIn{from{transform:translateY(-8px)}}
.qa .ans p{margin:0 0 clamp(22px,2.6vw,32px);color:var(--grey);max-width:64ch;
  font-size:16.5px;padding-left:clamp(0px,14vw,240px)}

@media (max-width:900px){
  .qa .ans p{padding-left:0}
  .phases{grid-template-columns:1fr;gap:34px}
  .tl{padding-top:0}
  .tl .rule{display:none}
  .ph{padding-top:22px}
  .ph::before{top:0}
  .model{grid-template-columns:1fr;gap:10px}
  .model .meta{text-align:left}
  .fit{grid-template-columns:1fr;gap:26px}
  .readout{position:static}
}


/* ============================================================== mid CTA ===
   The first and only exit before the foot of the page, placed after the
   argument, the answer and the proof have all been made. */
.mid{padding:clamp(80px,12vw,180px) 0;text-align:center}
.mid p{margin:0 auto clamp(28px,3.6vw,46px);max-width:20ch;
  font-size:clamp(26px,4.2vw,58px);font-weight:200;line-height:1.06;
  letter-spacing:-.05em;text-wrap:balance}
.mid p em{font-style:normal;color:var(--accent)}

/* chapter numbering — the page is a sequence, so it is numbered like one */
.eyebrow b{font-weight:400;color:var(--mute);margin-right:.7em}


/* ============================================================== chapter ===
   Ticks over as each boundary is crossed, so the seams read as a sequence
   rather than the page merely continuing. */
#chap{position:fixed;right:var(--gut);bottom:clamp(20px,4vh,42px);z-index:45;
  display:flex;align-items:baseline;gap:8px;font-size:12px;letter-spacing:.18em;
  color:var(--mute);opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
#chap.on{opacity:1;transform:none}
#chap b{font-weight:400;color:var(--white);font-variant-numeric:tabular-nums;
  transition:opacity .28s ease}
#chap.flip b{opacity:0}
@media (max-width:900px){ #chap{display:none} }
@media (prefers-reduced-motion:reduce){
  .js .hd h2{clip-path:none;transition:none}
  .js .hd .body{opacity:1;transform:none;transition:none}
  .wallin{transform:none!important}
}


/* ==========================================================================
   CARDS  — the shape the reference sites are built from: a bordered, rounded
   surface that lifts on hover, with an icon badge, a title and a line.
   ========================================================================== */
.crd{position:relative;border:1px solid var(--line);border-radius:15px;
  background:rgba(244,241,236,.022);padding:clamp(22px,2.5vw,32px);
  transition:border-color .4s,background .4s,transform .55s var(--ease)}
a.crd,button.crd{display:block;text-align:left;color:inherit;font:inherit;cursor:pointer}
.ico{width:clamp(38px,3.4vw,46px);aspect-ratio:1;border-radius:12px;display:grid;
  place-items:center;box-shadow:inset 0 0 0 1px var(--line);
  background:rgba(var(--glow-rgb),.07);margin-bottom:clamp(18px,2.2vw,26px)}
.ico svg{width:46%;height:46%;fill:none;stroke:var(--accent);stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.crd h3{margin:0 0 10px;font-size:clamp(18px,1.8vw,23px);font-weight:400;
  letter-spacing:-.03em}
.crd p{margin:0;font-size:15.5px;color:var(--grey);line-height:1.55}
.tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:clamp(16px,2vw,22px)}
.tags span{font-size:11.5px;letter-spacing:.08em;color:var(--mute);
  border:1px solid var(--line);border-radius:100px;padding:5px 11px}

/* ------------------------------------------------------------ logo strip -*/
.logos{padding:clamp(26px,3.4vw,44px) 0;border-top:1px solid var(--line-soft);
  border-bottom:1px solid var(--line-soft)}
.logos p{margin:0 0 clamp(14px,1.8vw,22px);font-size:11px;text-align:center;font-size:12.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--mute)}
/* One continuous roll. The track holds the list twice, so translating it by
   half its width lands exactly back where it started. Transform only -- a
   stalled animation must never leave a logo stuck at opacity zero. */
.roll{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.roll .track{display:flex;width:max-content;animation:roll 68s linear infinite}
.roll ul{margin:0;padding:0;list-style:none;display:flex;flex:none;
  align-items:center;gap:clamp(30px,4.6vw,66px);padding-right:clamp(30px,4.6vw,66px)}
.roll li{flex:none;display:flex;align-items:center}
/* every mark is exported trimmed to one common height, so a single CSS height
   lines them all up on the same baseline and width just follows */
.roll img{height:clamp(19px,1.95vw,26px);width:auto;display:block;
  opacity:.46;transition:opacity .4s var(--slow)}
@keyframes roll{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
@media (prefers-reduced-motion:reduce){
  .roll{-webkit-mask-image:none;mask-image:none}
  .roll .track{animation:none;width:100%}
  .roll ul{flex-wrap:wrap;justify-content:center;row-gap:clamp(18px,2.4vw,28px)}
  .roll ul[aria-hidden="true"]{display:none}
}

/* ---------------------------------------------------------------- stats --*/
.stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(22px,3.4vw,54px);margin-top:clamp(30px,4vw,52px)}
.stat b{display:block;font-size:clamp(44px,6.4vw,96px);font-weight:200;
  letter-spacing:-.05em;line-height:1;color:var(--accent)}
.stat span{display:block;margin-top:clamp(12px,1.5vw,18px);font-size:15.5px;
  color:var(--grey);max-width:24ch;line-height:1.5}

/* ------------------------------------------------------ discipline cards -*/
.dcards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(14px,1.6vw,22px);margin-top:clamp(30px,4vw,52px)}
.dcards .crd{display:block;padding:clamp(24px,2.6vw,34px)}
.dcards h3{margin-bottom:12px;font-size:clamp(21px,2.2vw,28px);font-weight:300;
  letter-spacing:-.04em}
.dcards .lede2{margin:0 0 clamp(20px,2.4vw,28px);font-size:16.5px;color:var(--white);
  line-height:1.5;font-weight:300}
.dcards .when2{margin:clamp(16px,2vw,22px) 0 0;
  padding-top:clamp(14px,1.8vw,18px);border-top:1px solid var(--line-soft);
  font-size:15px;color:var(--grey);line-height:1.5}
.dcards .when2 b{display:block;color:var(--accent);font-size:11px;font-weight:400;
  letter-spacing:.16em;text-transform:uppercase;margin-bottom:7px}
.dcards ul{margin:0;padding:clamp(18px,2.2vw,24px) 0 0;list-style:none;
  display:grid;gap:10px;border-top:1px solid var(--line)}
.dcards li{position:relative;padding-left:19px;font-size:15px;color:var(--grey);
  line-height:1.5}
.dcards li::before{content:"";position:absolute;left:0;top:.62em;width:8px;height:1px;
  background:var(--accent)}

/* ----------------------------------------------------------- work cards --*/
.wcards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(16px,2vw,28px);margin-top:clamp(30px,4vw,52px)}
.wcard{display:block}
.case-studies-intro{max-width:59ch;margin:0;color:var(--grey);font-size:clamp(17px,1.5vw,21px);line-height:1.55}
.wcard .shot{border-radius:14px;transition:transform .6s var(--slow)}
.wcard .meta{display:flex;align-items:baseline;justify-content:space-between;
  gap:16px;margin-top:clamp(14px,1.8vw,20px)}
.wcard .meta b{font-size:clamp(17px,1.7vw,22px);font-weight:400;letter-spacing:-.03em}
.wcard .meta i{font-style:normal;font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute)}
.wcard .arw2{display:grid;place-items:center;width:34px;height:34px;flex:none;
  border-radius:50%;box-shadow:inset 0 0 0 1px var(--line);color:var(--accent);
  font-size:14px;transition:background .35s,transform .5s var(--ease)}

/* ----------------------------------------------------------- quotes ------*/
.quotes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px);margin-top:clamp(30px,4vw,52px)}
.stars{display:flex;gap:4px;margin-bottom:clamp(16px,2vw,22px)}
.stars i{width:12px;height:12px;background:var(--accent);
  clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
.quote-b{margin:0 0 clamp(20px,2.4vw,28px);font-size:16px;color:var(--grey);
  line-height:1.6}
.who{display:flex;align-items:center;gap:13px;padding-top:clamp(16px,2vw,22px);
  border-top:1px solid var(--line)}
.who .av{width:40px;height:40px;border-radius:50%;flex:none;
  background:radial-gradient(70% 70% at 35% 30%,rgba(var(--glow-rgb),.5),rgba(30,34,42,1));
  box-shadow:inset 0 0 0 1px var(--line)}
.who b{display:block;font-size:15px;font-weight:400;letter-spacing:-.02em}
.who span{display:block;font-size:12.5px;color:var(--mute);margin-top:3px}

/* ------------------------------------------------------------- plans -----*/
.plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px);margin-top:clamp(30px,4vw,52px);align-items:start}
.plan{display:flex;flex-direction:column;height:100%}
.plan .tier{font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mute);margin:0 0 clamp(14px,1.8vw,20px)}
.plan h3{font-size:clamp(24px,2.8vw,36px);font-weight:200;letter-spacing:-.045em;
  margin:0 0 8px}
.plan .dur{margin:0 0 clamp(20px,2.4vw,28px);font-size:15px;color:var(--grey)}
.plan ul{margin:0 0 clamp(22px,2.6vw,30px);padding:clamp(20px,2.4vw,26px) 0 0;
  list-style:none;display:grid;gap:11px;border-top:1px solid var(--line)}
.plan li{position:relative;padding-left:24px;font-size:15px;color:var(--grey);
  line-height:1.5}
.plan li::before{content:"";position:absolute;left:0;top:.36em;width:13px;height:7px;
  border-left:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);
  transform:rotate(-45deg)}
.plan .btn{margin-top:auto;text-align:center}
.plan.lead{border-color:rgba(var(--glow-rgb),.42);background:rgba(var(--glow-rgb),.06)}
.plan.lead .tier{color:var(--accent)}

/* --------------------------------------------------------- closing band --*/
.endcta{position:relative;overflow:hidden;padding:clamp(84px,13vw,190px) 0;
  text-align:center;border-top:1px solid var(--line)}
.endcta::before{content:"";position:absolute;left:50%;top:50%;
  width:min(1100px,120vw);aspect-ratio:1;transform:translate(-50%,-50%);
  background:radial-gradient(closest-side,rgba(var(--glow-rgb),.16),transparent 70%)}
.endcta .wrap{position:relative}
.endcta p{margin:0 auto clamp(28px,3.6vw,46px);max-width:18ch;
  font-size:clamp(30px,5.2vw,74px);font-weight:200;line-height:1.04;
  letter-spacing:-.05em;text-wrap:balance}
.endcta p em{font-style:normal;color:var(--accent)}

@media (max-width:1180px){
  .dcards,.wcards{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:700px){
  .dcards .crd{padding:22px}
}
@media (max-width:900px){
  .wcards,.quotes,.plans,.stats{grid-template-columns:1fr}
  .logos ul{justify-content:flex-start;gap:18px 26px}
}



/* =============================================================== who for ==*/
.forwho{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;margin-top:clamp(28px,3.6vw,46px)}
.forwho div{background:var(--ink);padding:clamp(20px,2.4vw,30px);
  transition:background .35s}
.forwho b{display:block;font-size:clamp(17px,1.8vw,22px);font-weight:300;
  letter-spacing:-.03em;margin-bottom:9px}
.forwho span{font-size:15px;color:var(--grey);line-height:1.5}

/* --------------------------------------------------------- what it joins -*/
.joins{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(12px,1.4vw,18px);margin-top:clamp(28px,3.6vw,46px)}
.join{border:1px solid var(--line);border-radius:12px;
  padding:clamp(16px,1.9vw,22px);font-size:15.5px;color:var(--grey);
  line-height:1.45;position:relative;transition:border-color .35s,color .35s}
.join b{display:block;font-size:11px;letter-spacing:.16em;color:var(--mute);
  margin-bottom:10px;font-weight:400}

/* ------------------------------------------------------------- outcomes --*/
.outs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 clamp(28px,5vw,80px);margin-top:clamp(28px,3.6vw,46px)}
.outs div{display:flex;gap:16px;align-items:baseline;
  padding:clamp(15px,1.8vw,21px) 0;border-bottom:1px solid var(--line)}
.outs i{font-style:normal;font-size:11.5px;letter-spacing:.1em;color:var(--accent);
  flex:none;width:2em}
.outs span{font-size:clamp(16px,1.5vw,19px);color:var(--white);font-weight:300;
  line-height:1.45;letter-spacing:-.02em}

@media (max-width:900px){
  .forwho,.joins{grid-template-columns:repeat(2,minmax(0,1fr))}
  .outs{grid-template-columns:1fr}
  .phases{grid-template-columns:1fr}
}
@media (max-width:560px){
  .forwho,.joins{grid-template-columns:1fr}
}


/* ---- statements set as type, since these sections carry no components ---- */
.big{margin:clamp(26px,3.4vw,44px) 0 0;max-width:24ch;
  font-size:clamp(26px,3.8vw,54px);font-weight:200;line-height:1.12;
  letter-spacing:-.045em;text-wrap:balance}
.big em{font-style:normal;color:var(--accent)}
.scope{margin:clamp(18px,2.2vw,26px) 0 0;padding-top:clamp(16px,2vw,22px);
  border-top:1px solid var(--line);font-size:15px;color:var(--grey);line-height:1.55}
.endcta .sub{margin:clamp(-6px,-.4vw,0px) auto clamp(28px,3.4vw,44px);max-width:44ch;
  font-size:clamp(16px,1.5vw,19px);font-weight:300;letter-spacing:normal;
  line-height:1.55;color:var(--grey)}


/* ---- brand line: the slogan, small, above the headline ------------------ */
.brandline{margin:0 0 clamp(20px,2.4vw,30px);font-size:13px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--grey);font-weight:400}
.brandline .cyc{overflow:hidden;vertical-align:bottom;color:var(--accent)}
.brandline .w{color:var(--accent)}
.brandline .ghost{color:var(--accent)}

@media (max-width:620px){ .dcards,.wcards{grid-template-columns:1fr} }


/* ---- the line the hero no longer carries ------------------------------- */
.oneline{padding:clamp(56px,8vw,120px) 0 clamp(46px,6vw,88px)}
.oneline p{margin:0;max-width:24ch;font-size:clamp(24px,3.4vw,46px);font-weight:200;
  line-height:1.14;letter-spacing:-.045em;text-wrap:balance}
.oneline em{font-style:normal;color:var(--accent)}


/* ========================================================== proof block ===
   A claim is followed by the case that proves it. Image one side, the story
   and the number on the other; sides alternate down the page. */
.proof{display:grid;grid-template-columns:clamp(240px,30%,380px) minmax(0,1fr);
  gap:clamp(28px,5vw,80px);align-items:center;
  padding:clamp(40px,6vw,88px) 0;border-top:1px solid var(--line)}
.proof.flip{grid-template-columns:minmax(0,1fr) clamp(240px,30%,380px)}
.proof.flip .pshot{order:2}
.proof .pshot{margin:0}
.proof .pshot .shot{border-radius:14px;transition:transform .7s var(--slow)}
.proof .ptxt p.eyebrow{margin:0 0 clamp(16px,2vw,22px)}
.proof h3{margin:0 0 clamp(16px,2vw,24px);font-size:clamp(24px,3.2vw,44px);
  font-weight:200;letter-spacing:-.05em;line-height:1.06;max-width:18ch}
.proof .ptxt > p{margin:0 0 clamp(22px,2.6vw,32px);font-size:16.5px;color:var(--grey);
  line-height:1.6;max-width:52ch}
.pstats{display:flex;gap:clamp(24px,4vw,60px);flex-wrap:wrap;
  padding-top:clamp(20px,2.4vw,28px);border-top:1px solid var(--line)}
.pstat b{display:block;font-size:clamp(28px,3.6vw,50px);font-weight:200;
  letter-spacing:-.05em;line-height:1;color:var(--accent)}
.pstat span{display:block;margin-top:10px;font-size:13.5px;color:var(--mute);
  max-width:18ch;line-height:1.45}
.proof .more2{display:inline-flex;align-items:center;gap:12px;
  margin-top:clamp(22px,2.6vw,32px);font-size:15.5px;color:var(--accent)}
.proof .more2 i{font-style:normal;display:block;width:26px;height:1px;
  background:var(--accent);transition:width .5s var(--slow)}

/* ------------------------------------------------- disciplines as rows --- */
.drows{border-top:1px solid var(--line)}
.drow{display:grid;grid-template-columns:3.4em minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(16px,3vw,44px);align-items:baseline;
  padding:clamp(22px,2.8vw,36px) 0;border-bottom:1px solid var(--line);
  transition:padding-left .5s var(--ease)}
.drow > i{font-style:normal;font-size:11.5px;letter-spacing:.16em;color:var(--mute)}
.drow h3{margin:0;font-size:clamp(24px,3.4vw,46px);font-weight:200;
  letter-spacing:-.05em;line-height:1}
.drow h3 span{display:block;margin-top:12px;font-size:clamp(15px,1.4vw,18px);
  color:var(--white);font-weight:300;letter-spacing:-.02em}
.drow p{margin:0;font-size:15.5px;color:var(--grey);line-height:1.6}

/* ------------------------------------------------------------ way cards - */
.waycards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px)}
.way{border:1px solid var(--line);border-radius:15px;
  padding:clamp(24px,2.8vw,36px);background:rgba(244,241,236,.022);
  transition:border-color .4s,background .4s,transform .55s var(--ease)}
.way i{font-style:normal;font-size:11.5px;letter-spacing:.16em;color:var(--accent);
  display:block;margin-bottom:clamp(18px,2.2vw,26px)}
.way h3{margin:0 0 12px;font-size:clamp(20px,2.1vw,27px);font-weight:300;
  letter-spacing:-.04em}
.way p{margin:0;font-size:15.5px;color:var(--grey);line-height:1.6}

/* -------------------------------------------------------- steps as rows - */
.steprows{border-top:1px solid var(--line)}
.steprow{display:grid;grid-template-columns:clamp(70px,9vw,130px) minmax(0,1fr) minmax(0,1.1fr);
  gap:clamp(16px,3vw,44px);align-items:baseline;
  padding:clamp(22px,2.8vw,36px) 0;border-bottom:1px solid var(--line)}
.steprow b{font-size:clamp(30px,4vw,58px);font-weight:200;letter-spacing:-.05em;
  line-height:1;color:var(--accent);opacity:.55}
.steprow h3{margin:0;font-size:clamp(21px,2.4vw,32px);font-weight:300;
  letter-spacing:-.04em;line-height:1.1}
.steprow p{margin:0;font-size:15.5px;color:var(--grey);line-height:1.6}

@media (max-width:900px){
  .proof,.proof.flip{grid-template-columns:1fr;gap:24px}
  .proof.flip .pshot{order:0}
  .proof .pshot{width:min(260px,70%)}
  .drow,.steprow{grid-template-columns:1fr;gap:10px}
  .waycards{grid-template-columns:1fr}
}


/* ============================================================== dropdown ==*/
.nav .has{position:relative}
.nav .has::after{content:"";position:absolute;left:-14px;right:-14px;top:100%;
  height:20px;display:none}
.nav .has[data-open="true"]::after{display:block}
.nav .has > button{font:inherit;font-size:15px;color:var(--grey);background:none;
  border:0;padding:0;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  transition:color .25s}
.nav .has > button svg{width:9px;height:9px;fill:none;stroke:currentColor;
  stroke-width:1.8;transition:transform .35s var(--ease)}
.nav .has[data-open="true"] > button svg{transform:rotate(180deg)}
.drop{position:absolute;left:50%;top:calc(100% + 16px);transform:translateX(-50%);
  min-width:230px;display:none;gap:2px;padding:8px;border-radius:14px;
  background:rgba(14,16,19,.97);box-shadow:inset 0 0 0 1px var(--line),0 24px 60px rgba(0,0,0,.5);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.nav .has[data-open="true"] .drop{display:grid;animation:dropIn .3s var(--ease)}
@keyframes dropIn{from{transform:translateX(-50%) translateY(-9px)}}
.drop a{display:block;padding:11px 14px;border-radius:9px;font-size:15px;
  color:var(--grey);transition:background .25s,color .25s}
.drop a::after{display:none}
.drop a b{display:block;font-weight:400;color:inherit}
.drop a span{display:block;margin-top:3px;font-size:12.5px;color:var(--mute)}
@media (max-width:900px){
  .nav .has{width:100%}
  .drop{position:static;transform:none;display:grid;animation:none;background:none;
    box-shadow:none;backdrop-filter:none;padding:6px 0 0;min-width:0}
}

/* ================================================================= blog ===*/
.posts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(18px,2.4vw,34px);margin-top:clamp(30px,4vw,52px)}
.post{display:block}
.post .thumb{aspect-ratio:16/10;border-radius:13px;overflow:hidden;position:relative;
  box-shadow:inset 0 0 0 1px var(--line);transition:transform .6s var(--slow)}
.post .thumb::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(0,0,0,.4),transparent 60%)}
.post i{font-style:normal;display:block;margin:clamp(16px,2vw,22px) 0 9px;
  font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--mute)}
.post h3{margin:0;font-size:clamp(18px,1.9vw,24px);font-weight:300;letter-spacing:-.035em;
  line-height:1.25}
.article{max-width:70ch}
.article h2{font-size:clamp(24px,2.8vw,36px);margin:clamp(38px,4.4vw,58px) 0 clamp(16px,2vw,22px);
  max-width:22ch}
.article p{font-size:clamp(17px,1.5vw,19px);color:var(--grey);line-height:1.75;
  margin:0 0 clamp(20px,2.2vw,26px)}
@media (max-width:900px){ .posts{grid-template-columns:1fr} }


/* ------------------------------------- components the service pages need - */
.cadence{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px);margin-top:clamp(28px,3.6vw,46px)}
.cad{border:1px solid var(--line);border-radius:15px;padding:clamp(22px,2.6vw,32px);
  background:rgba(244,241,236,.022)}
.cad b{display:block;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);margin-bottom:clamp(16px,2vw,22px)}
.cad ul{margin:0;padding:0;list-style:none;display:grid;gap:10px}
.cad li{position:relative;padding-left:19px;font-size:15.5px;color:var(--grey);line-height:1.5}
.cad li::before{content:"";position:absolute;left:0;top:.62em;width:8px;height:1px;background:var(--accent)}

.ba{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(16px,2.4vw,34px);margin-top:clamp(28px,3.6vw,46px)}
.ba > div{border:1px solid var(--line);border-radius:15px;padding:clamp(22px,2.6vw,32px)}
.ba > div:last-child{border-color:rgba(var(--glow-rgb),.34);background:rgba(var(--glow-rgb),.05)}
.ba b{display:block;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mute);margin-bottom:clamp(16px,2vw,22px)}
.ba > div:last-child b{color:var(--accent)}
.ba ul{margin:0;padding:0;list-style:none;display:grid;gap:11px}
.ba li{font-size:15.5px;color:var(--grey);line-height:1.5}
.ba > div:last-child li{color:var(--white)}

.imgwall{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(10px,1.2vw,16px);margin-top:clamp(28px,3.6vw,46px)}
.imgwall .shot:nth-child(2),.imgwall .shot:nth-child(5){margin-top:clamp(14px,2.4vw,40px)}

@media (max-width:900px){
  .cadence,.ba{grid-template-columns:1fr}
  .imgwall{grid-template-columns:repeat(2,minmax(0,1fr))}
  .imgwall .shot:nth-child(2),.imgwall .shot:nth-child(5){margin-top:0}
}

/* Art-directed project covers, linked through every placement. */
.wcards.published-work,.gal.published-work{grid-template-columns:repeat(4,minmax(0,1fr))}
.shot.project-shot{aspect-ratio:4/5;padding:0;isolation:isolate;border:1px solid #ffffff0d;box-shadow:none;container-type:inline-size}
.shot.project-shot::after{display:none}
.shot.project-dewi img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .7s var(--slow)}
.shot.project-kado{background:#d9d3c9}
.shot.project-kado img{display:block;width:100%;height:100%;object-fit:contain;transition:transform .7s var(--slow)}
.shot.project-acre{background:#292927}
.shot.project-acre img{display:block;width:100%;height:100%;object-fit:contain}
.wcards.published-work.home-work{grid-template-columns:repeat(5,minmax(0,1fr))}
.shot.project-forme{background:radial-gradient(ellipse at 85% 80%,#799387 0%,#354b40 40%,#152820 85%);color:#f0eee5}
.cover-brand{position:absolute;left:8%;top:7%;font-size:4cqw;letter-spacing:.22em}
.cover-line{position:absolute;left:8%;top:16%;font-size:8.6cqw;line-height:1.02;letter-spacing:-.055em;font-weight:300}
.cover-device{position:absolute;left:8%;top:40%;width:112%;padding:1.5%;background:#222927;border:1px solid #85938b;border-radius:3cqw;transform:rotate(-9deg);box-shadow:-12px 30px 50px #0007;transition:transform .7s var(--slow)}
.cover-device img{display:block;width:100%;height:auto;border-radius:1.8cqw}
.cover-type{position:absolute;bottom:5%;left:8%;font-size:1.8cqw;letter-spacing:.18em;color:#e3e9e0}
.project-link{display:block;border-radius:10px}
.project-link:focus-visible,.wcard:focus-visible,.card:focus-visible{outline:2px solid var(--accent);outline-offset:6px}
.pstat b{overflow-wrap:anywhere}
@media(max-width:1180px){.wcards.published-work,.wcards.published-work.home-work,.gal.published-work{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* Two up is the floor. Dropping to a single column turns four projects into a
   very long scroll on a phone for no gain -- a 2x2 reads the whole set at once.
   The stagger is a two-column device, so it goes once the grid stops being wide. */
@media(max-width:860px){
  .wcards.published-work,.wcards.published-work.home-work,.gal.published-work{grid-template-columns:repeat(2,minmax(0,1fr));
    gap:clamp(14px,3.4vw,24px)}
  .gal.published-work .card:nth-child(2n){margin-top:0}
  .gal.published-work .card h3,.wcards.published-work .wcard h3{font-size:clamp(14px,3.5vw,18px)}
  .gal.published-work .card p,.wcards.published-work .wcard p{font-size:clamp(11px,2.7vw,13px)}
}
@media(prefers-reduced-motion:reduce){.cover-device,.shot.project-dewi img{transition:none}}

/* HUSK: an original hospitality image, presented as an archive cover. */
.shot.project-husk{background:#142120}
.shot.project-husk>img{position:absolute;top:0;left:50%;height:235%;width:auto;max-width:none;transform:translateX(-50%)}
.shot.project-husk::after{display:block;position:absolute;inset:0;background:linear-gradient(0deg,#07100fe6,transparent 75%)}
.husk-cover-name{position:absolute;z-index:2;bottom:12%;left:9%;color:#f5f2e9;font-family:Arial,sans-serif;font-size:8cqw;font-weight:300;letter-spacing:.27em}
.husk-cover-name small{display:block;margin-top:14px;font-size:1.8cqw;letter-spacing:.18em}

.shot.project-husk>img{width:100%;height:100%;object-fit:cover;object-position:56% center;left:0;transform:none}

/* SEN campaign cover: actual editable Canva exports. */
.shot.project-sen{background:#d9d5ca;overflow:hidden}.sen-cover-brand{position:absolute;left:9%;top:7%;color:#292c26;font:400 11cqw Georgia,serif;letter-spacing:.18em}.sen-cover-brand small{display:block;font:2cqw monospace;letter-spacing:.08em;margin-top:7px}.sen-cover-post{position:absolute;left:8%;top:27%;width:68%;transform:rotate(-7deg);box-shadow:0 14px 24px #2226}.sen-cover-post.second{left:38%;top:54%;width:62%;transform:rotate(7deg)}.sen-cover-post img{position:static!important;width:100%!important;height:auto!important;object-fit:contain!important;transform:none!important;display:block}.sen-cover-post.second img{opacity:1}

/* ==================================================== pointer guard ==
   Hover is a mouse idea. On a touch screen a tap leaves :hover latched,
   so one wall frame would sit lit in full colour while the rest stayed
   dark. Everything hover-driven lives behind a real pointer. */
@media (hover:hover) and (pointer:fine){
  .protobar .pback:hover span{transform:translateX(-4px)}
  .protobar .popen:hover{color:var(--cream)}
  .nav a:hover{color:var(--white)}
  .nav a:hover::after,.nav a.here::after{transform:none}
  .btn:hover{transform:translateY(-2px)}
  .btn:hover::before{opacity:.16}
  .btn.ghost:hover::before{opacity:.14}
  .mq:hover .mqi{animation-play-state:paused}
  .row:hover::before{opacity:1}
  .row:hover{padding-left:16px}
  .row:hover p{color:var(--white)}
  .row:hover .go{opacity:1;transform:none}
  .item:hover{padding-left:16px}
  .index:hover .item{opacity:.35}
  .index:hover .item:hover{opacity:1}
  .card:hover .stage{transform:translateY(-8px);
    box-shadow:inset 0 0 0 1px rgba(244,241,236,.2),0 34px 60px rgba(0,0,0,.5)}
  .filters button:hover{color:var(--white);border-color:rgba(244,241,236,.26)}
  .next:hover::before{opacity:1}
  .next:hover .arw{transform:translateX(18px)}
  .mailto:hover{background-size:100% 1px;color:var(--accent)}
  footer a:hover{color:var(--white)}
  .feat a.band-link:hover .more span,.feat .more:hover span{width:46px}
  .wallin .fr:hover::after{opacity:0}
  .fr:hover img{filter:grayscale(0) brightness(1) contrast(1);transform:scale(1.03)}
  .gal .card:hover .shot{transform:translateY(-8px)}
  .sym:hover{border-color:rgba(244,241,236,.26)}
  .qa summary:hover{color:var(--accent)}
  .crd:hover{border-color:rgba(var(--glow-rgb),.34);background:rgba(var(--glow-rgb),.035);
    transform:translateY(-5px)}
  .roll:hover .track{animation-play-state:paused}
  .roll li:hover img{opacity:.92}
  .wcard:hover .shot{transform:translateY(-6px)}
  .wcard:hover .arw2{background:rgba(var(--glow-rgb),.12);transform:translate(3px,-3px)}
  .forwho div:hover{background:rgba(var(--glow-rgb),.05)}
  .join:hover{border-color:rgba(var(--glow-rgb),.34);color:var(--white)}
  .proof:hover .pshot .shot{transform:translateY(-6px)}
  .proof:hover .more2 i{width:46px}
  .drow:hover{padding-left:14px}
  .way:hover{border-color:rgba(var(--glow-rgb),.34);background:rgba(var(--glow-rgb),.035);
    transform:translateY(-5px)}
  .nav .has > button:hover,.nav .has[data-open="true"] > button{color:var(--white)}
  .drop a:hover,.drop a:focus-visible{background:rgba(var(--glow-rgb),.1);color:var(--white)}
  .post:hover .thumb{transform:translateY(-6px)}
  .project-link:hover .project-dewi img,.wcard:hover .project-dewi img,.card:hover .project-dewi img{transform:scale(1.025)}
  .project-link:hover .cover-device,.wcard:hover .cover-device,.card:hover .cover-device{transform:rotate(-7deg) translateY(-3px)}
}

/* ================================================== live prototypes ==
   A prototype is a page of its own, but it should not feel like leaving.
   The site header stays; a slim bar under it says where you are and how to
   get back, and the prototype fills what is left of the screen. */
.protobar{display:flex;align-items:center;gap:clamp(12px,2vw,26px);
  padding:clamp(10px,1.4vw,15px) var(--gut);
  border-bottom:1px solid var(--line-soft);background:rgba(10,11,13,.72)}
.protobar .pback{display:inline-flex;align-items:center;gap:.5em;
  font-size:14px;color:var(--cream);text-decoration:none;white-space:nowrap}
.protobar .pback span{transition:transform .3s var(--slow);display:inline-block}
.protobar .ptitle{margin:0 auto 0 0;font-size:12px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--mute)}
.protobar .popen{font-size:13px;color:var(--mute);text-decoration:none;white-space:nowrap}
.protoframe{height:calc(100svh - 74px - 46px);background:#fff}
.protoframe iframe{display:block;width:100%;height:100%;border:0}
@media (max-width:760px){
  .protobar{gap:12px;padding:10px var(--gut)}
  .protobar .ptitle{display:none}
  .protoframe{height:calc(100svh - 62px - 42px)}
}

/* ============================================ embedded prototype ==
   The prototype runs on the case page itself, high up, before any of the
   write-up. It is the evidence; the words underneath explain it. Lazy, so
   it costs nothing until the reader reaches it. */
.protoembed{margin:clamp(26px,4vw,46px) 0 0}
.protoembed .pframe{position:relative;aspect-ratio:16/10;border-radius:12px;
  overflow:hidden;background:#fff;
  box-shadow:inset 0 0 0 1px rgba(244,241,236,.12),0 30px 70px rgba(0,0,0,.45)}
.protoembed iframe{display:block;width:100%;height:100%;border:0}
.protoembed figcaption{display:flex;flex-wrap:wrap;gap:8px 18px;align-items:baseline;
  margin-top:14px;font-size:13.5px;color:var(--mute)}
.protoembed figcaption b{font-weight:400;color:var(--cream)}
.protoembed figcaption a{margin-left:auto;color:var(--accent);text-decoration:none;
  white-space:nowrap}
@media (max-width:760px){.protoembed .pframe{aspect-ratio:4/3}}

/* the spam trap must be gone for people but present for bots */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.fnote{margin:4px 0 0;font-size:15px;line-height:1.5;min-height:1px}
.fnote.ok{color:var(--cream)}
.fnote.bad{color:#ff8a6b}
.fnote a{color:var(--accent)}

/* Five projects, not four. Hiding the fifth behind "See all work" kept the
   homepage short but cost a phone visitor a whole case -- and it was always
   the same one. Two rows of two and then a wide one reads as a deliberate
   shape rather than a row that ran out, and costs about 260px of scroll.
   Six or more would be three rows to get past before the page gets going
   again, so that is still where the line sits. */
@media (max-width:860px){
  .wcards.published-work > *:nth-child(n+6){display:none}
}

/* ================================================ mobile-first sweep ==
   Three things that only go wrong once the viewport is small. */

/* 1. The project covers size their type in cqw, which is right on a wide
   card and unreadable on a narrow one -- 1.8cqw is 3px at phone width.
   Below a legible container, the micro-labels go and the brand name gets
   a floor in px so it stays readable at any card size. */
@container (max-width:280px){
  .cover-type,.husk-cover-name small,.sen-cover-brand small{display:none}
}
.cover-brand{font-size:max(9px,4cqw)}
.cover-line{font-size:max(15px,8.6cqw)}
.cover-type{font-size:max(7px,1.8cqw)}
.husk-cover-name{font-size:max(15px,8cqw)}
.husk-cover-name small{font-size:max(7px,1.8cqw)}
.sen-cover-brand{font-size:max(17px,11cqw)}
.sen-cover-brand small{font-size:max(7px,2cqw)}

@media (max-width:860px){
  /* 2. Touch targets. A finger is about 9mm; 26px of burger is a miss
     waiting to happen. Padding does the work so nothing moves visually. */
  #burger{padding:13px;margin-right:-13px}
  .mark{display:inline-flex;align-items:center;min-height:44px}
  footer nav{gap:10px 22px}
  footer nav a{padding:9px 0;display:inline-block}
  .forme-prototype-link,.protobar .pback,.protobar .popen,
  .fnote a,.article a{padding-block:8px;display:inline-block}
  .protobar{padding-block:6px}

  /* 3. Nothing readable drops below 12px on a phone. */
  .article p,.article li,figcaption,dd,dt,.card p,.wcard p,
  .forme-meta dd,.forme-meta dt{font-size:max(12.5px,1em)}
  figcaption,.forme-meta dt,dt{font-size:12.5px}
  .eyebrow{font-size:12px}
}

/* The case-study stylesheets load after this file, so a plain rule here loses
   on cascade order. A legibility floor on a phone is worth the !important --
   these set a minimum, they never shrink anything. */
@media (max-width:860px){
  #burger{min-height:44px;min-width:44px;justify-content:center}
  .eyebrow,p.eyebrow{font-size:12.5px!important}
  figcaption,figcaption b,figcaption a,dt,dd,
  .forme-meta dt,.forme-meta dd,.acre-view,.kado-image-action,
  .card p,.wcard p,.post i{font-size:12.5px!important;line-height:1.5}
  .more2,.popen,.pback,a.mailto,.acre-view,.kado-image-action,
  .protoembed figcaption a{padding-block:10px;display:inline-block}
}

/* ======================================================= arrival ==
   Nothing lands flat. Items inside a revealed group come in one after
   another rather than the whole block appearing at once.
   Transform only, and the resting state is the element's own -- if an
   animation never runs, the item is simply there, 12px low at worst.
   No opacity, so nothing can be left invisible. */
@keyframes riseIn{from{transform:translateY(12px)}}
@keyframes riseInSm{from{transform:translateY(7px)}}

.js .up.seen > *:not(.up):not(.rev){animation:riseIn .8s var(--ease) both}
.js .up.seen > *:not(.up):not(.rev):nth-child(1){animation-delay:.02s}
.js .up.seen > *:not(.up):not(.rev):nth-child(2){animation-delay:.07s}
.js .up.seen > *:not(.up):not(.rev):nth-child(3){animation-delay:.12s}
.js .up.seen > *:not(.up):not(.rev):nth-child(4){animation-delay:.17s}
.js .up.seen > *:not(.up):not(.rev):nth-child(5){animation-delay:.22s}
.js .up.seen > *:not(.up):not(.rev):nth-child(6){animation-delay:.27s}
.js .up.seen > *:not(.up):not(.rev):nth-child(7){animation-delay:.31s}
.js .up.seen > *:not(.up):not(.rev):nth-child(n+8){animation-delay:.35s}
/* the marquee and the headline run their own timing */
.js .up.seen .track > *, .js .up.seen .ln, .js .up.seen .wm{animation:none}

/* single blocks get the smaller move, no stagger needed */
.js .seen > p, .js .seen > h2, .js .seen > h3,
.js .seen figure, .js .seen blockquote, .js .seen dl{
  animation:riseInSm .7s var(--ease) both}

@media (prefers-reduced-motion:reduce){
  .js .seen *{animation:none!important}
}

/* Media is cut oversize so it can drift against the scroll without ever
   showing an edge inside its frame. Only with JS -- without it the image
   simply fills the frame as before. */
.js .shot > img,.js .stage img,.js .gal .card .shot img{
  height:122%;margin-top:-11%;will-change:transform}
@media (prefers-reduced-motion:reduce){
  .js .shot > img,.js .stage img,.js .gal .card .shot img{
    height:100%;margin-top:0;transform:none!important}
}

/* Cards carry their own reveal, with more travel than body copy so they
   arrive with some weight. Transform only; if the class never lands the
   card is still fully visible, just 34px low. */
/* Cards arrive from the edges rather than from below -- odd columns swing in
   from the left, even from the right, so the row assembles itself. */
.js .wcard.up,.js .card.up{transform:translateX(-64px) scale(.97)}
.js .wcards > *:nth-child(even).up,.js .gal > *:nth-child(even).up{
  transform:translateX(64px) scale(.97)}
.js .wcard.up.seen,.js .card.up.seen,
.js .wcards > *:nth-child(even).up.seen,.js .gal > *:nth-child(even).up.seen{
  transform:none}
.js .wcard.up,.js .card.up{
  transition:opacity .7s var(--ease) var(--d,0s),
             transform 1.05s var(--ease) var(--d,0s)}
.js .wcards > *:nth-child(2),.js .gal > *:nth-child(2){--d:.07s}
.js .wcards > *:nth-child(3),.js .gal > *:nth-child(3){--d:.14s}
.js .wcards > *:nth-child(4),.js .gal > *:nth-child(4){--d:.21s}
.js .wcards > *:nth-child(n+5),.js .gal > *:nth-child(n+5){--d:.26s}
/* the generic child stagger must not double up on cards */
.js .up.seen > .wcard,.js .up.seen > .card{animation:none}

/* ===================================================== blog thumbnails ==
   The gradient plate stays on the wrapper and acts as the ground; the real
   frame sits on top of it. A slow connection shows the plate, and a missing
   file is never a white hole. */
/* The plate is a <span>, so it was inline -- zero width, zero height, and
   an aspect-ratio that does not apply to a non-replaced inline box. The
   thumbnails on this page have never once drawn. */
.post .thumb{display:block;aspect-ratio:4/3}
.post .thumb img{position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:cover;object-position:center 42%;
  filter:saturate(.88) brightness(.93);
  transition:transform 1s var(--slow),filter .7s var(--slow)}

/* Six articles in one column is a very long thumb-scroll. Two up as soon as
   there is room for two readable headlines, one only on the narrowest phones. */
@media (max-width:900px){ .posts{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){ .posts{grid-template-columns:1fr} }

/* ================================================================ 404 ==
   A dead link is the one moment a visitor is certain something is broken.
   Say what happened in a line, then hand back the four ways on. */
.gone{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(10px,1.3vw,16px);margin-top:clamp(32px,4.4vw,56px);max-width:860px}
.gone a{display:block;padding:clamp(17px,1.9vw,25px);border-radius:15px;
  background:rgba(255,255,255,.028);box-shadow:inset 0 0 0 1px var(--line);
  transition:transform .5s var(--slow),background .5s var(--slow),
             box-shadow .5s var(--slow)}
.gone b{display:block;font-weight:400;font-size:clamp(17px,1.7vw,21px);
  letter-spacing:-.025em;margin-bottom:6px}
.gone span{display:block;font-size:13.5px;line-height:1.5;color:var(--mute)}
@media (max-width:560px){ .gone{grid-template-columns:1fr} }

/* ==================================================== low-power devices ==
   A budget Android cannot paint four blurred aurora layers, two backdrop
   filters, a grain overlay and a parallax pass inside 16ms. `.lite` is set by
   the script from the device's own report of itself. It keeps the light and
   the entrance animations -- what it drops is the per-frame cost. */
.lite #glow b{animation:none}
.lite #grain{opacity:.07}
.lite .btn,.lite .btn.lg,.lite .drop,.lite #sheet{
  backdrop-filter:none;-webkit-backdrop-filter:none}
.lite .btn,.lite .btn.lg{background:rgba(24,26,31,.9)}
.lite .fr img,.lite .shot img,.lite .stage img{transform:none!important}

@media (hover:hover) and (pointer:fine){
  .post:hover .thumb img{transform:scale(1.05);filter:none}
  .gone a:hover{transform:translateY(-3px);background:rgba(255,255,255,.055);
    box-shadow:inset 0 0 0 1px rgba(var(--glow-rgb),.34)}
}

/* Cards enter from 64px outside their own column, so until they arrive the
   row is 64px wider than the page. On a phone that is a sideways scroll on
   a site that has nothing to scroll sideways to. Clip the horizontal only:
   `clip` rather than `hidden` leaves the vertical alone, so the hover lift
   and the shadows still fall outside the box. */
.wcards,.gal,.cards,.posts,.gone{overflow-x:clip}

/* ======================================================= phone hero v2 ==
   A wall of work with a headline printed on top of it is a desktop idea. On
   a phone there is not enough width for both: three columns put a frame at
   125px across, which is too small to read as work, and keeping a headline
   legible over it means holding the whole wall at 30% brightness -- so the
   work becomes texture and the texture becomes mud.

   So the phone gets a title card instead. The line takes the top third on
   clean ground. The work takes the bottom, two columns wide, at roughly
   200px a frame and twice the brightness, because nothing is printed over
   it any more. It runs off the bottom edge on purpose: there is obviously
   more below, which is the one job a hero has. */
@media (max-width:760px){
  /* The wall fills the screen and the line sits in the middle of it. That is
     the desktop composition; it just has to centre here, because there is no
     room to set type beside a wall 390px wide.

     What changes on a phone is the movement. Column drift at this size reads
     as noise rather than motion, so it stops (see the `phone` guard in the
     loop) and one frame at a time comes up to full colour instead. The work
     introduces itself, a piece at a time, and the scrim can stay dark enough
     for the headline without the whole wall turning to mud. */
  .hero{min-height:calc(100svh - 62px);align-items:center;
    padding:clamp(30px,7vh,60px) 0 clamp(34px,7vh,58px);text-align:center}
  .hero h1{font-size:clamp(46px,15vw,84px);max-width:11ch;margin-inline:auto}

  .wall{inset:-9% -1%;height:auto;opacity:1;overflow:hidden}
  .wallin{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;
    transform-origin:50% 42%}
  .wallin .wcol{gap:10px}
  .wallin .wcol:nth-child(1),.wallin .wcol:nth-child(4){display:none}
  .wallin .wcol:nth-child(2),.wallin .wcol:nth-child(3){display:grid}
  .fr{border-radius:13px}
  .fr img{filter:grayscale(1) contrast(.8) brightness(.3)}

  /* Darkest where the words are, open at the top and bottom -- which is also
     where the script is allowed to light a frame, so the light always lands
     somewhere it can be seen. */
  .veil{background:
    radial-gradient(120% 40% at 50% 47%,rgba(10,11,13,.95) 0%,
      rgba(10,11,13,.9) 30%,rgba(10,11,13,.5) 66%,rgba(10,11,13,.1) 88%),
    linear-gradient(to bottom,rgba(10,11,13,.88),rgba(10,11,13,.1) 20%,
      rgba(10,11,13,.1) 76%,rgba(10,11,13,.94))}
}
@media (hover:none) and (max-width:760px){
  .fr img{filter:grayscale(1) contrast(.8) brightness(.3)}
}
/* A lit frame has to come through the scrim, so on a phone it overdrives
   rather than merely returning to normal. */
@media (max-width:760px){
  .fr.lit img{filter:grayscale(0) contrast(1.04) brightness(1.18);
    transform:scale(1.03)}
  .wallin .fr.lit{box-shadow:inset 0 0 0 1px rgba(var(--glow-rgb),.4),
    0 18px 44px rgba(0,0,0,.5)}
}

/* A large phone held in landscape, or a small tablet, is wide enough for
   three columns -- at two the frames grow to 400px and the wall stops being
   a wall. The headline also reaches its ceiling size here, so the band it
   stands on needs a little more room. */
@media (min-width:521px) and (max-width:760px){
  .wallin{grid-template-columns:repeat(3,minmax(0,1fr))}
  .wallin .wcol:nth-child(1){display:grid}
  .wallin .wcol:nth-child(4){display:none}
}

/* ======================================================= touch states ==
   The mouse equivalents of these all live in the (hover:hover) block. These
   are the same reactions, driven by a class the script puts on for a beat
   after a tap -- see the touch section at the foot of site.js. They are not
   inside a (hover:none) query on purpose: the class is only ever applied on
   a device without a fine pointer, and a media query here would also catch
   a laptop with a touchscreen, where both should work. */
.wallin .fr.lit::after{opacity:0}
.fr.lit img{filter:grayscale(0) brightness(1) contrast(1);transform:scale(1.04)}
.wcard.tap .shot{transform:translateY(-6px)}
.wcard.tap .arw2{background:rgba(var(--glow-rgb),.12);transform:translate(3px,-3px)}
.wcard.tap .project-dewi img,.card.tap .project-dewi img{transform:scale(1.025)}
.wcard.tap .cover-device,.card.tap .cover-device{transform:rotate(-7deg) translateY(-3px)}
.card.tap .stage{transform:translateY(-8px);
  box-shadow:inset 0 0 0 1px rgba(244,241,236,.2),0 34px 60px rgba(0,0,0,.5)}
.post.tap .thumb{transform:translateY(-6px)}
.post.tap .thumb img{transform:scale(1.05);filter:none}
.gone a.tap{transform:translateY(-3px);background:rgba(255,255,255,.055);
  box-shadow:inset 0 0 0 1px rgba(var(--glow-rgb),.34)}
.crd.tap,.way.tap{border-color:rgba(var(--glow-rgb),.34);
  background:rgba(var(--glow-rgb),.035);transform:translateY(-5px)}
.btn.tap{transform:translateY(-2px)}
.btn.tap::before{opacity:.16}
.row.tap{padding-left:16px}
.row.tap p{color:var(--white)}
.row.tap .go{opacity:1;transform:none}
.row.tap::before{opacity:1}
.drow.tap{padding-left:14px}
.item.tap{padding-left:16px}
.next.tap::before{opacity:1}
.next.tap .arw{transform:translateX(18px)}
.proof.tap .pshot .shot{transform:translateY(-6px)}
.proof.tap .more2 i{width:46px}
.join.tap{border-color:rgba(var(--glow-rgb),.34);color:var(--white)}
.sym.tap{border-color:rgba(244,241,236,.26)}
.filters button.tap{color:var(--white);border-color:rgba(244,241,236,.26)}

/* The prototype bar's two controls were 34-37px tall. On the page whose
   entire job is "open the prototype", those are the two things a thumb must
   not miss. */
@media (max-width:760px){
  .protobar .pback,.protobar .popen{min-height:44px;display:inline-flex;
    align-items:center}
}

/* Five projects in a two-column grid leaves the fifth one on its own, which
   reads as a gap rather than as a card. On a phone it takes the full width
   instead, and drops to a landscape crop so a full-width 9:16 frame does not
   swallow the screen. */
@media (max-width:760px){
  .gal.published-work > :last-child:nth-child(odd),
  .wcards.published-work > :last-child:nth-child(odd){grid-column:1 / -1}
  .gal.published-work > :last-child:nth-child(odd) .shot,
  .wcards.published-work > :last-child:nth-child(odd) .shot{aspect-ratio:4/3}
}
