@font-face{font-family:'apfel-grotezk';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/apfel-grotezk-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'apfel-grotezk';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/apfel-grotezk-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'outfit';font-style:normal;font-weight:300;font-display:swap;src:url('fonts/outfit-latin-300-normal.woff2') format('woff2')}
@font-face{font-family:'outfit';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/outfit-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'outfit';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/outfit-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'outfit';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/outfit-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'outfit';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/outfit-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'schibsted-grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/schibsted-grotesk-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'schibsted-grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/schibsted-grotesk-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'schibsted-grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/schibsted-grotesk-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'schibsted-grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/schibsted-grotesk-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'figtree';font-style:normal;font-weight:300;font-display:swap;src:url('fonts/figtree-latin-300-normal.woff2') format('woff2')}
@font-face{font-family:'figtree';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/figtree-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'figtree';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/figtree-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'figtree';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/figtree-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'figtree';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/figtree-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'instrument-sans';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/instrument-sans-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'instrument-sans';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/instrument-sans-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'instrument-sans';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/instrument-sans-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'instrument-sans';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/instrument-sans-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'space-grotesk';font-style:normal;font-weight:300;font-display:swap;src:url('fonts/space-grotesk-latin-300-normal.woff2') format('woff2')}
@font-face{font-family:'space-grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/space-grotesk-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'space-grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/space-grotesk-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'space-grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/space-grotesk-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'space-grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/space-grotesk-latin-700-normal.woff2') format('woff2')}

:root{
  /* Dark theme: charcoal page, light type. --accent stays the same red;
     it reads hotter on charcoal, which is what the awards line wants. */
  --bg:#17181a; --ink:#f2f1ef; --ink2:#a5a29d; --ink3:#7a7772;
  --line:rgba(255,255,255,.15); --accent:#ef6a44;
  --f:'apfel-grotezk','outfit',system-ui,-apple-system,sans-serif;
  --pad:var(--edge); --maxw:none;
  --meta:15.5px; /* every caption, credit and description uses this */
  /* All-caps micro-labels: one token, so they stay in step with each other.
     Wide kerning is the point of them, so the tracking stays generous. */
  --caps:clamp(11.5px,.72vw,13.5px);
  --capsls:.16em;
  /* The reference site sets 152 of its text nodes at one size: 58.08px on a 1936px
     viewport, line-height exactly 1.0, weight 400, letter-spacing -0.04em. That is
     3vw. Everything here is built on it. */
  --t:clamp(21px,3vw,58px);          /* big: disciplines, work titles, gallery labels */
  --head:var(--t);                   /* back to ONE size: header, menu, the
                                        three columns, recognition, footer */
  --small:clamp(11px,.82vw,15px);    /* copyright line only — left as it was */
  --lh:1.0;
  --ls:-.04em;
  --gap:clamp(14px,1.98vw,38px);   /* their column gap */
  --edge:clamp(18px,1.4vw,32px);   /* near full bleed, with a little air */
  --textpad:clamp(10px,1.5vw,30px);/* extra left inset on reading columns */
  --ease:cubic-bezier(.62,0,.2,1);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);font:400 16px/1.6 var(--f);
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;font-weight:400;letter-spacing:-.04em;line-height:1}
.skip{position:absolute;left:-9999px}
.skip:focus{left:14px;top:14px;z-index:99;background:var(--accent);color:#fff;padding:10px 16px}
/* The small caps label above project titles, on the resume sidebar and on the
   contact page. Restored: the regex that stripped the .lb* lightbox rules also
   matched .lbl and deleted this, which left every label unstyled inline text. */
.lbl{font-size:var(--caps);font-weight:600;letter-spacing:var(--capsls);
  text-transform:uppercase;color:var(--ink2);margin:0 0 12px;display:block}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}


/* ============ TEXT BEHAVIOUR, SITE-WIDE ============
   .fx is the generic version of what the work list does: the inner span is what
   scrambles in, and what flips on hover. The mask's padding keeps ascenders and
   descenders from being clipped. */
.fx{display:inline-block;vertical-align:top;margin:-.1em 0;padding:.1em .1em .1em 0;
  overflow:hidden;max-width:100%}
.fx>span{display:inline-block;backface-visibility:visible;transform-origin:center center;
  transition:transform .3s ease}
@media(hover:hover){
  /* Only things you can actually click flip, and only their WORDS - never a
     picture frame. .tile-f and .tile-o are spans that wrap imagery and layout,
     so they are excluded; plain copy (the three columns, recognition, the
     disciplines list, the footer strapline) never flips at all. */
  /* Whitelist, not blacklist: only text that JS has wrapped in .fx flips, plus
     the .flipa / .flipword / .wr-t containers that carry their own rules. A bare
     "a:hover > span" would also turn picture frames, the work-list credits panel
     and the burger bars upside down. */
  a:hover .fx > span,
  button:hover .fx > span{transform:rotateX(180deg)}
  /* ...except the gallery caption, which stays the right way up */
  .tile:hover .tile-t .fx > span,
  .tile:hover .tile-c .fx > span,
  .tile:hover .tile-t > span,
  .tile:hover .tile-c > span{transform:none}
  .tile:hover .tile-f,
  .tile:hover .tile-o{transform:none!important}
}
@media(prefers-reduced-motion:reduce){.fx>span{transition:none}.fx:hover>span{transform:none}}
/* the three columns and the tile labels flip as whole lines */
.col li,.col h2{display:block}
.col li .fx,.col h2 .fx{max-width:100%}

/* ============ THE FLIP ============
   rotateX(180deg) flips about the horizontal axis: the word mirrors vertically
   and keeps its left-to-right letter order. The negative margin plus matching
   padding gives the mask room, so ascenders and descenders are not clipped
   while the overflow still hides the flip's edges. */
.flipa,.flipword{display:inline-block;vertical-align:top;
  margin:-.1em 0;padding:.1em .1em .1em 0;overflow:hidden}
.flipa>span,.flipword>span{display:inline-block;backface-visibility:visible;
  transform-origin:center center;transition:transform .3s ease}
@media(hover:hover){
  .flipa:hover>span,.flipword:hover>span{transform:rotateX(180deg)}
}

/* ============ HEADER ============ */
.hd{position:absolute;inset:0 0 auto;z-index:30;display:flex;align-items:flex-start;
  justify-content:space-between;gap:24px;padding:clamp(20px,3vw,36px) var(--pad)}
.pg .hd,body>.hd{position:sticky;top:0;background:color-mix(in srgb,var(--bg) 92%,transparent);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.brand{font-size:var(--head);font-weight:400;line-height:1.15;letter-spacing:-.025em;
  display:block}
.brand-n{display:block;font-weight:400;text-transform:uppercase;letter-spacing:-.02em;
  color:var(--ink)}
.brand-r{display:block;font-weight:400;color:var(--ink2);letter-spacing:-.025em}
.nv{display:flex;flex-direction:column;align-items:flex-end;gap:1px}
.nv a{font-size:var(--head);font-weight:400;letter-spacing:-.025em;padding:0;line-height:1.15}
.nv a.on>span{color:var(--accent)}
.nv a.ext{font-size:.82em;color:var(--ink2)}
.burger{display:none;background:none;border:0;padding:9px;cursor:pointer}
.burger span{display:block;width:23px;height:1.6px;background:var(--ink);margin:5px 0;transition:.3s}
.burger[aria-expanded=true] span:nth-child(1){transform:translateY(3.3px) rotate(45deg)}
.burger[aria-expanded=true] span:nth-child(2){transform:translateY(-3.3px) rotate(-45deg)}

/* ============ INTRO / CLIENTS ============ */
.intro{max-width:var(--maxw);margin:auto;padding:clamp(56px,9vw,130px) var(--pad) clamp(30px,5vw,60px)}
.intro p{max-width:46ch;font-size:var(--t);font-weight:400;letter-spacing:-.025em;
  line-height:1.35;margin:0 0 26px}
.lnk{font-size:var(--t);font-weight:500;border-bottom:1.5px solid var(--line);padding-bottom:2px}
.clients ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.clients li{border:1px solid var(--line);border-radius:99px;padding:8px 15px;font-size:var(--meta);color:var(--ink2)}



/* ============ THE GRID ============
   Nine base columns with a 38px gutter, as measured on the reference. Content
   blocks span three of them, which is what gives the page its 3-column reading. */
.g9{display:grid;grid-template-columns:repeat(9,1fr);gap:var(--gap)}
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}

/* ============ COVER — full-bleed reel, list over its right third ============ */
.cv{position:relative;min-height:100svh;display:flex;flex-direction:column;
  padding:var(--edge);gap:var(--gap)}
.cv-top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--gap)}
.cv-tl{margin:0;font-size:var(--head);font-weight:400;line-height:var(--lh);
  letter-spacing:var(--ls);max-width:none}
.cv-name{display:block;font-weight:400;text-transform:uppercase;letter-spacing:-.02em}
.cv-role{display:block;font-weight:400;color:var(--ink2);letter-spacing:var(--ls)}
.cv-nav{display:flex;flex-direction:column;align-items:flex-end;gap:0;flex:none;padding-top:.1em}
.cv-nav a{font-size:var(--head);font-weight:400;letter-spacing:var(--ls);line-height:var(--lh)}
.cv-stage{position:relative;flex:1;min-height:0;display:flex}
.cv-reel{position:relative;flex:1;min-height:60vh;overflow:hidden;
  border-radius:2px;background:#0b0b0c}
/* The still is only a fallback. The iframe is oversized so the 16:9 player always
   covers the box — otherwise the poster shows as a sliver along the top and bottom. */
.cv-reel .reel-still{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;z-index:0}
.cv-reel .reel{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:100%;height:56.25vw;min-height:100%;min-width:177.78%;border:0;display:block;z-index:1}
/* the list sits in the right third, vertically centred */
.cv-words{position:absolute;z-index:5;top:50%;transform:translateY(-50%);
  left:66.666%;right:var(--gap);
  display:flex;flex-direction:column;align-items:flex-start;
  mix-blend-mode:difference;perspective:900px;perspective-origin:left center}
.dw{font-size:var(--t);font-weight:400;letter-spacing:var(--ls);line-height:var(--lh);
  white-space:nowrap;color:var(--ink);opacity:calc(1 - var(--i) * 0.045);
  transform-style:preserve-3d;transition:opacity .3s}
.dw:nth-child(-n+2){opacity:1}
.dw:hover{opacity:1}
@supports not (mix-blend-mode:difference){.cv-words{mix-blend-mode:normal}.dw{color:var(--ink)}}

/* ============ GALLERY — scattered squares that radiate in ============ */
.gal{padding:calc(var(--t) * 2) var(--edge) calc(var(--t) * 1.4)}
/* The gallery sits on a real column lattice, the way the reference site does it:
   fixed columns, square tiles snapped to the grid, and whole cells left empty to
   make the voids. gridpack.py solves the gap and row count for 35% imagery. */
.gal-plane{display:grid;grid-template-columns:repeat(var(--cols),1fr);
  grid-auto-rows:var(--cell);gap:var(--gg);align-content:start}
/* Tiles bubble-pop: they blow up from a dot with a springy overshoot, fast.
   The base rule is the OUT state and also carries the exit timing (quick, no
   bounce); .tile.in carries the entry timing. Because the observer toggles .in
   rather than latching it, this replays every time a tile enters the viewport,
   and the tiles deflate again as they leave. */
.tile{grid-column:var(--c) / span var(--s);grid-row:var(--r) / span var(--s);
  display:block;text-decoration:none;transform-origin:center center;
  opacity:0;transform:translateX(var(--dx,0)) scale(.32);
  transition:opacity .2s ease,transform .28s cubic-bezier(.4,0,.7,.4);
  will-change:transform,opacity}
.tile.in{opacity:1;transform:none;
  transition:opacity .19s ease var(--td,0ms),
             transform .46s cubic-bezier(.34,1.66,.44,1) var(--td,0ms)}
.tile-f{position:relative;display:block;aspect-ratio:1/1;overflow:hidden;
  background:#111214;border-radius:2px}
.tile-f img{width:100%;height:100%;object-fit:cover;display:block;opacity:.94;
  transition:transform .8s cubic-bezier(.2,.7,.3,1),opacity .35s}
.tile:hover .tile-f img{transform:scale(1.05);opacity:1}
.tile-o{position:absolute;inset:auto 0 0;display:block;padding:.75em .7em .65em;
  background:linear-gradient(to top,rgba(8,8,9,.94),rgba(8,8,9,.45) 72%,transparent);
  opacity:0;transform:translateY(.2em);
  transition:opacity .3s ease,transform .4s cubic-bezier(.2,.7,.3,1)}
.tile-t{display:block;font-size:calc(var(--head) * .78);letter-spacing:var(--ls);
  line-height:1.06;color:#fff}
.tile-c{display:block;margin-top:.45em;font-size:var(--caps);font-weight:700;
  letter-spacing:var(--capsls);text-transform:uppercase;color:rgba(255,255,255,.72)}
.tile-c:empty{display:none}
.tile:hover .tile-o,.tile:focus-visible .tile-o{opacity:1;transform:none}
@media(hover:none){.tile-o{opacity:1;transform:none}}
.gal-all{display:inline-block;margin-top:calc(var(--t) * 2);font-size:var(--head);
  letter-spacing:var(--ls);line-height:var(--lh)}
@media(prefers-reduced-motion:reduce){
  .tile{opacity:1;transform:none;filter:none;transition:none}
}

/* ============ FOOTER — three columns, same size ============ */
.ft-in{max-width:none;padding:calc(var(--t) * 1.2) var(--edge) calc(var(--t) * .9);
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap);
  /* a step down from the page size so the three columns sit on one line each */
  font-size:calc(var(--t) * .62);letter-spacing:var(--ls);line-height:1.16}
.ft-n{font-weight:400;color:#fff}
.ft-r{color:rgba(255,255,255,.62);margin-top:0}
.ft-c,.ft-nav{display:flex;flex-direction:column;gap:0}
.ft-c a,.ft-nav a{color:rgba(255,255,255,.62);transition:color .25s}
.ft-c a:hover{color:var(--accent)}
.ft-nav a:hover{color:#fff}
.ft-b{border-top:1px solid var(--line);padding:calc(var(--t) * .5) var(--edge);
  text-align:left;color:var(--ink3);font-size:var(--t);letter-spacing:var(--ls);line-height:1.12}

@media(max-width:1100px){
  /* higher specificity than the desktop .wbar rule further down the file, so
     the pills stay flush left with the list on narrow screens */
  .wpg .wlist,.wpg .wbar{padding-left:var(--pad);padding-right:var(--pad)}
  .wr-th,.wr-dt{display:none}
  .p-b{grid-template-columns:1fr;padding-right:var(--pad);padding-left:var(--pad)}
  .p-h,.pgr{padding-left:var(--pad)}
  .p-hero,.vid{border-radius:2px}
  .ft-in{grid-template-columns:1fr;gap:calc(var(--t) * .5)}
  .cv-words{left:auto;right:var(--gap);top:auto;bottom:var(--gap);transform:none}
  .gal-plane{grid-template-columns:repeat(2,1fr);grid-auto-rows:auto;gap:var(--gap)}
  .tile{grid-column:auto / span 1;grid-row:auto}
  .blk{grid-template-columns:1fr}
  .blk>h2,.blk-b{grid-column:1}
  .cnames,.recog,.flds,.vals{grid-template-columns:repeat(2,1fr)}
  }
@media(max-width:600px){
  .cnames,.recog,.flds,.vals{grid-template-columns:1fr}
  .gal-plane{grid-template-columns:1fr}
  .cv-words{position:static;transform:none;mix-blend-mode:normal;margin-top:var(--gap)}
  .dw{color:var(--ink)}
}

/* ============ PAGE HEAD ============ */
/* the same band the project pages use: symmetrical air, a hairline under it,
   and the reading inset from the left */
.pg-h{max-width:var(--maxw);margin:auto;
  padding:clamp(26px,2.55vw,62px) var(--pad) clamp(26px,2.55vw,62px) calc(var(--pad) + var(--textpad));
  border-bottom:1px solid var(--line)}
.pg-h h1{font-size:clamp(30px,5.4vw,72px);letter-spacing:-.04em;line-height:1.07;padding-bottom:.04em}
.pg-h p{color:var(--ink2);max-width:60ch;margin:clamp(10px,.9vw,20px) 0 0;
  font-size:calc(var(--t) * .42);letter-spacing:var(--ls);line-height:1.25}
.pg-h .rq{margin-top:24px}
.btn{border:1px solid var(--line);border-radius:99px;padding:12px 24px;font-size:13.5px;font-weight:500}
.btn:hover{border-color:var(--ink)}
.jump{display:flex;flex-wrap:wrap;gap:6px;margin-top:28px}
.jump a{font-size:var(--caps);font-weight:600;letter-spacing:var(--capsls);text-transform:uppercase;
  border:1px solid var(--line);border-radius:99px;padding:9px 15px;color:var(--ink2)}
.jump a:hover{border-color:var(--ink);color:var(--ink)}

/* ============ WORK — tight list, thumb slides left, details slide right ============ */
/* Column geometry, straight off the layout: the list occupies the left half,
   the thumbnail sits immediately to its right, and the credits sit right of
   that, ending just inside the page edge. */
.wpg{--thumbw:clamp(200px,24.6vw,640px);--detw:clamp(140px,13vw,340px);
  --lpad:clamp(20px,9.2vw,240px);--g1:clamp(10px,1.4vw,28px);--g2:clamp(10px,1.6vw,34px);
  --colr:calc(var(--thumbw) + var(--detw) + var(--g1) + var(--g2) + var(--edge))}
.wh h1{margin-bottom:0}
/* Equal air above and below the pills, so the band reads centred between the two
   rules. The row is NOT held to the list's right gutter — the pills run on in one
   line at their natural widths. */
.wbar{max-width:var(--maxw);margin:auto;
  padding:clamp(18px,1.7vw,42px) var(--pad) clamp(18px,1.7vw,42px) var(--lpad);
  border-bottom:1px solid var(--line)}
.fls{display:flex;justify-content:flex-start;align-items:center;
  column-gap:clamp(8px,.62vw,15px);row-gap:clamp(8px,.62vw,15px);flex-wrap:wrap}
.fl{flex:0 0 auto;white-space:nowrap}
.fl{font:inherit;font-family:var(--f);font-size:var(--caps);font-weight:700;letter-spacing:var(--capsls);
  text-transform:uppercase;background:none;border:1px solid var(--line);border-radius:99px;
  color:var(--ink2);padding:clamp(8px,.46vw,11px) clamp(13px,.95vw,23px);
  cursor:pointer;transition:.2s;display:inline-flex;
  align-items:center;gap:7px}
.fl i{font-style:normal;font-size:calc(var(--caps) - 1.5px);font-weight:700;color:var(--ink3);letter-spacing:.06em}
.fl.on i{color:rgba(255,255,255,.75)}
.fl:hover{border-color:var(--ink);color:var(--ink)}
.fl.on{background:rgba(242,241,239,.26);color:var(--ink);border-color:transparent}
.wct{font-size:var(--caps);color:var(--ink3);letter-spacing:var(--capsls);text-transform:uppercase}
.wct b{color:var(--ink2);font-weight:600}

/* the list sits in the middle column; the outer columns are empty gutters
   that the thumbnail and the details animate into */
.wlist{max-width:var(--maxw);margin:auto;
  padding:clamp(40px,4.4vw,74px) var(--colr) clamp(50px,8vw,110px) var(--lpad)}
.wr{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:baseline;gap:0 var(--pad);padding:clamp(2px,.28vw,6px) 0;
  transition:opacity .3s}
.wr-t{font-size:var(--t);font-weight:400;letter-spacing:-.04em;line-height:1;
  min-width:0;display:inline-block;vertical-align:top;
  /* mask for the hover flip; the padding keeps ascenders and descenders uncropped */
  margin:-.1em 0;padding:.1em .1em .1em 0;overflow:hidden;
  transition:opacity .25s,transform .45s var(--ease)}
.wr-t>span{display:inline-block;backface-visibility:visible;transform-origin:center center;
  transition:transform .3s ease}
.wr:hover .wr-t>span{transform:rotateX(180deg)}
.wr:hover .wr-y>span,.wr:hover .wr-y{transform:rotateX(180deg)}
/* the hovered row goes accent red as it turns */
.wr:hover .wr-t,.wr:hover .wr-t>span,.wr:hover .wr-y{color:var(--accent)}
@media(hover:none){.wr:hover .wr-t>span,.wr:hover .wr-y{transform:none}}
.wr-y{font-size:var(--t);font-weight:400;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;line-height:1;white-space:nowrap;
  display:inline-block;vertical-align:top;margin:-.1em 0;padding:.1em .1em .1em 0;
  overflow:hidden;backface-visibility:visible;transform-origin:center center;
  transition:color .25s,transform .3s ease}
.wr.has{cursor:pointer}
/* Proximity falloff instead of a hard dim. The list rests at a soft grey; when
   the pointer is inside it, rows brighten toward the cursor and fall away with
   distance, so the eye is led to the row you are on (which also goes red).
   --lvl is set per row by site.js; the 1 default keeps the list fully legible
   with JS off. */
.wr{opacity:var(--lvl,1);transition:opacity .26s ease}
@media(prefers-reduced-motion:reduce){.wr{opacity:1!important;transition:none}}
.wr.has:hover .wr-t{transform:translateX(8px)}
/* the list reads at full strength, the same near-white as the 'Clients'
   heading on the homepage; hover still takes a row to the accent red */
.wr-t,.wr-y{color:var(--ink)}

/* thumbnail — slides out to the LEFT */
.wr-th{position:absolute;left:100%;margin-left:var(--g1);top:0;
  width:var(--thumbw);aspect-ratio:7/5;overflow:hidden;border-radius:2px;
  pointer-events:none;opacity:0;
  transform:translateX(-18px);
  transition:opacity .3s ease,transform .48s var(--ease);
  box-shadow:0 18px 44px rgba(0,0,0,.55);z-index:5}
.wr-th img{width:100%;height:100%;object-fit:cover}
.wr.has:hover .wr-th{opacity:1;transform:translateX(0)}

/* details — slide out to the RIGHT */
.wr-dt{position:absolute;left:calc(100% + var(--thumbw) + var(--g1) + var(--g2));top:0;
  width:var(--detw);pointer-events:none;opacity:0;
  transform:translateX(18px);
  transition:opacity .3s ease,transform .48s var(--ease);z-index:5}
.wr:hover .wr-dt{opacity:1;transform:translateX(0)}
.wr-dt b,.wr-dt i,.wr-dt u,.wr-dt s,.wr-dt em{display:block;font-style:normal;text-decoration:none;
  font-size:clamp(14px,.8vw,20px);line-height:1.45}
.wr-dt b{color:var(--ink);font-weight:700}
.wr-dt i{color:var(--ink2);margin-top:2px}
.wr-dt u{color:var(--ink2);margin-top:6px}
.wr-dt s{color:var(--accent);font-weight:700;margin-top:6px}
.wr-dt em{color:var(--ink3);margin-top:10px;font-size:var(--caps);
  letter-spacing:var(--capsls);text-transform:uppercase}
.wr.hid{display:none}


/* ============ WORK LIST — titles write on as the page loads ============
   Each title is wiped in from the left, staggered down the list, so the page
   appears to write itself out. Driven by a class JS adds, so with JS off (or
   reduced motion on) everything is simply visible from the start. */
.js-reveal .wr-t,
.js-reveal .wr-y{
  clip-path:inset(0 100% -.25em 0);
  opacity:.001;
}
.js-reveal .wr.lit .wr-t{
  animation:writeOn .62s cubic-bezier(.22,.75,.2,1) forwards;
  animation-delay:var(--d,0ms);
}
.js-reveal .wr.lit .wr-y{
  animation:writeOn .5s cubic-bezier(.22,.75,.2,1) forwards;
  animation-delay:calc(var(--d,0ms) + 120ms);
}
@keyframes writeOn{
  from{clip-path:inset(0 100% -.25em 0);opacity:1}
  to  {clip-path:inset(0 0 -.25em 0);   opacity:1}
}
@media(prefers-reduced-motion:reduce){
  .js-reveal .wr-t,.js-reveal .wr-y{clip-path:none;opacity:1;animation:none!important}
}


/* ---- alternative intro: titles flip into place instead of wiping ----
   Add ?intro=flip to the URL to try it; ?intro=wipe forces the other one.
   To make one permanent, change INTRO_DEFAULT at the top of site.js. */
.js-reveal.intro-flip .wr-t,
.js-reveal.intro-flip .wr-y{clip-path:none;opacity:.001}
.js-reveal.intro-flip .wlist{perspective:1400px;perspective-origin:30% 50%}
.js-reveal.intro-flip .wr.lit .wr-t{
  animation:flipOn .62s cubic-bezier(.2,.7,.2,1) forwards;
  animation-delay:var(--d,0ms);transform-origin:center center}
.js-reveal.intro-flip .wr.lit .wr-y{
  animation:flipOn .52s cubic-bezier(.2,.7,.2,1) forwards;
  animation-delay:calc(var(--d,0ms) + 90ms);transform-origin:center center}
@keyframes flipOn{
  from{transform:rotateX(-92deg);opacity:0}
  60% {opacity:1}
  to  {transform:rotateX(0deg);  opacity:1}
}
@media(prefers-reduced-motion:reduce){
  .js-reveal.intro-flip .wr-t,.js-reveal.intro-flip .wr-y{opacity:1;animation:none!important;transform:none}
}

/* ============ PROJECT PAGE ============ */
.proj{padding-top:0}
.p-h{max-width:var(--maxw);margin:auto;
  /* symmetrical padding centres the label + title block inside the band */
  padding:clamp(26px,2.55vw,62px) var(--pad) clamp(26px,2.55vw,62px) calc(var(--pad) + var(--textpad));
  border-bottom:1px solid var(--line)}
.p-h .lbl{margin-bottom:clamp(10px,.9vw,22px)}
.p-h h1{font-size:clamp(30px,5.4vw,72px);letter-spacing:-.04em;line-height:1.07;padding-bottom:.04em}
/* The imagery runs hard to the right edge with no padding at all; the reading
   column is inset from the left instead. The media column is ~10% narrower than
   it was, and that width goes to the text. */
.p-b{max-width:var(--maxw);margin:auto;
  padding:clamp(34px,3.8vw,92px) 0 clamp(30px,4.6vw,64px) calc(var(--pad) + var(--textpad));
  display:grid;gap:clamp(26px,4vw,58px);
  grid-template-columns:minmax(220px,1fr) minmax(0,3.15fr);align-items:start}
.p-x{position:sticky;top:110px}
.p-x p{color:var(--ink2);font-size:16px;margin:0 0 15px}
/* inline-block so the box shrinks to the word itself; the rule then spans 100%
   of it, less the trailing letter-space that uppercase tracking adds after the
   final S — so it measures the word, not the word plus a gap. */
.p-x .lbl{display:inline-block;margin-top:clamp(24px,1.9vw,46px);
  padding-top:clamp(14px,.95vw,24px);position:relative}
.p-x .lbl::before{content:'';position:absolute;top:0;left:0;height:1px;
  width:calc(100% - var(--capsls));background:var(--ink3);opacity:.75}
.cr{font-size:var(--meta);line-height:1.85;color:var(--ink2)}
/* .p-x p sets a grey on every paragraph in the sidebar, and it out-specifies a
   bare .aw2 — which is why the award line was rendering grey on project pages. */
.aw2,.p-x p.aw2{color:var(--accent);font-size:var(--meta);font-weight:700}
.p-hero{overflow:hidden;border-radius:2px 0 0 2px;margin-bottom:clamp(16px,2.2vw,30px)}
.vid{position:relative;aspect-ratio:16/9;background:#000;border-radius:2px 0 0 2px;overflow:hidden;
  margin-bottom:clamp(16px,2.2vw,30px)}
.vid iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
/* The watch label sits on the video rather than above it. pointer-events:none so
   it never intercepts a click meant for the player, and it fades out on hover so
   it is out of the way once you are actually watching. */
.vid-l{position:absolute;left:0;bottom:0;z-index:2;pointer-events:none;
  padding:clamp(12px,1.2vw,22px) clamp(14px,1.4vw,26px);
  font-size:var(--caps);font-weight:700;letter-spacing:var(--capsls);
  text-transform:uppercase;color:#fff;
  text-shadow:0 1px 14px rgba(0,0,0,.85),0 1px 3px rgba(0,0,0,.9);
  transition:opacity .3s ease}
.vid:hover .vid-l{opacity:0}
@media(hover:none){.vid:hover .vid-l{opacity:1}}
.shs{columns:2;column-gap:clamp(12px,1.5vw,20px)}
.sh{margin:0 0 clamp(12px,1.5vw,20px);break-inside:avoid}
.sh a{display:block;overflow:hidden;border-radius:2px}
.sh img{width:100%;transition:transform .6s var(--ease),opacity .3s}
.sh a:hover img{transform:scale(1.03);opacity:.93}
.sh figcaption{font-size:var(--meta);color:var(--ink3);margin-top:7px}
.pgr{max-width:var(--maxw);margin:auto;
  padding:clamp(26px,3.6vw,50px) var(--pad) clamp(50px,7vw,96px) calc(var(--pad) + var(--textpad));
  display:flex;align-items:flex-start;justify-content:space-between;gap:18px;
  border-top:1px solid var(--line);flex-wrap:wrap}
.pgr a{display:flex;flex-direction:column;gap:5px;max-width:38%;min-width:0}
.pgr a.nx{text-align:right;align-items:flex-end}
.pgr em{font-style:normal;font-size:var(--caps);font-weight:600;letter-spacing:var(--capsls);text-transform:uppercase;
  color:var(--ink3)}
.pgr a>span{font-size:clamp(15px,1.8vw,22px);font-weight:500;letter-spacing:-.02em}
.allw{max-width:none!important;border:1px solid var(--line);border-radius:99px;padding:11px 20px;
  font-size:13px;font-weight:500}
.allw:hover{border-color:var(--ink)}

/* ============ RESUME ============ */
.rgrid{max-width:var(--maxw);margin:auto;
  padding:clamp(24px,2.4vw,52px) var(--pad) clamp(50px,7vw,100px) calc(var(--pad) + var(--textpad));
  display:grid;gap:clamp(26px,3.4vw,58px);
  grid-template-columns:minmax(0,1fr) minmax(0,clamp(200px,17vw,300px))}
/* each discipline heading is a caps label with a rule over it, like CREDITS */
/* One token sets the air around a discipline heading. The rule belongs to the
   heading, so the space ABOVE it is the section's margin plus the last entry's
   own padding — subtracting that padding is what keeps the rule optically
   centred in the break instead of riding low. */
.rs{--secgap:clamp(30px,3.4vw,64px);
  margin-bottom:calc(var(--secgap) - clamp(8px,.66vw,15px))}
.rs .d-h{padding:var(--secgap) 0 0;margin:0 0 clamp(12px,1.1vw,24px);
  /* back to the page's own type rather than a micro-label: big enough to read as
     a real section break, in the site's white with its normal tracking */
  font-size:clamp(21px,1.75vw,34px);font-weight:400;letter-spacing:var(--ls);
  line-height:1.1;text-transform:none;color:var(--ink);
  border-top:1px solid var(--line)}
.rs:first-child .d-h{padding-top:0;border-top:0}
.crd{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.crd li{display:grid;grid-template-columns:clamp(46px,3.2vw,68px) minmax(0,1fr);
  gap:clamp(12px,1.1vw,24px);
  padding:clamp(8px,.66vw,15px) 0;border-bottom:1px solid var(--line)}
.crd li:last-child{border-bottom:0}
.c-y{font-size:var(--caps);font-weight:600;color:var(--ink3);
  font-variant-numeric:tabular-nums;padding-top:.35em;letter-spacing:.02em}
.c-b{display:flex;flex-direction:column;gap:clamp(2px,.22vw,5px)}
.c-l{display:block;line-height:1.2}
.c-r{display:block;font-size:var(--caps);font-weight:600;letter-spacing:var(--capsls);
  text-transform:uppercase;color:var(--ink3);margin:0;line-height:1.25}
.c-w{font-size:clamp(17px,1.35vw,26px);font-weight:400;letter-spacing:-.03em;color:var(--ink)}
.c-w a{border-bottom:1.5px solid var(--accent);transition:color .2s}
.c-w a:hover{color:var(--accent)}
.c-k{font-size:var(--meta);color:var(--ink);line-height:1.25;
  margin-left:clamp(8px,.85vw,20px)}
.c-m{display:block;font-size:var(--meta);color:var(--ink);margin:0;line-height:1.25}
.c-a{display:block;font-size:var(--meta);color:var(--accent);font-weight:700;margin:0;line-height:1.25}
.rside{position:sticky;top:clamp(90px,9vw,150px);align-self:start}
.rside section{margin-bottom:clamp(20px,1.9vw,38px)}
.sk{list-style:none;margin:0;padding:0;font-size:var(--meta);color:var(--ink);
  display:flex;flex-direction:column}
.sk li{padding:3px 0;border-bottom:1px solid var(--line)}
.edu{font-size:var(--meta);color:var(--ink);margin:0;line-height:1.6}
.edu b{color:var(--ink);font-weight:600}
.edu a:hover{color:var(--accent)}

/* ============ CONTACT — one left-aligned column, no boxes ============ */
.pg-h.nolinebelow{border-bottom:0}
.cts{max-width:var(--maxw);margin:auto;
  padding:clamp(20px,2vw,44px) var(--pad) clamp(56px,9vw,120px) calc(var(--pad) + var(--textpad));
  display:block}
/* a clear break between the two blocks, no rules and no boxes */
.ct{border:0;padding:0}
.ct + .ct{margin-top:clamp(40px,4.4vw,86px)}
.ct .lbl{color:var(--ink2);margin-bottom:clamp(10px,.9vw,20px)}
/* one size for every line under a heading: the address, the phone, the location
   and the outbound link all read the same */
.ct .big{font-size:clamp(18px,1.5vw,29px);font-weight:400;letter-spacing:-.03em;
  line-height:1.32;margin:0;color:var(--ink)}
.ct .big a{color:inherit}
.ct .big a:hover{color:var(--accent)}
.ct .sub{font-size:var(--meta);color:var(--ink);margin:clamp(6px,.5vw,12px) 0 0}
.mut{color:var(--ink3);font-size:var(--meta)}

/* ============ CLIENTS / FIELDS / VALUES — three columns, white ground ============ */
.info{background:#1d1e21;border-top:1px solid var(--line)}
.info-in{padding:calc(var(--t) * 1.4) var(--edge) calc(var(--t) * 2)}
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.col h2{font-size:var(--head);font-weight:400;letter-spacing:var(--ls);line-height:1.1;
  margin:0 0 1.4em;color:var(--ink)}
.col ul,.col ol{list-style:none;list-style-type:none;margin:0;padding:0}
.col li{list-style:none}
.col li::marker{content:''}
.col li{font-size:var(--head);letter-spacing:var(--ls);line-height:1.28;color:var(--ink2)}
.recog{margin-top:calc(var(--t) * 1.2);padding-top:calc(var(--t) * .8);
  border-top:1px solid var(--line)}
.recog h2{font-size:var(--head);font-weight:400;letter-spacing:var(--ls);line-height:1.1;
  margin:0 0 1.4em;color:var(--ink)}
.recog ul{list-style:none;margin:0;padding:0}
.recog li{font-size:var(--head);letter-spacing:var(--ls);line-height:1.28;
  color:var(--accent)}          /* the red already used for awards elsewhere */

@media(max-width:760px){.cols3{grid-template-columns:1fr;gap:calc(var(--t) * .9)}}

/* ============ FOOTER — black ground, one small line ============ */
.ft{background:#0f1012;border-top:0}
.ft-b{padding:calc(var(--t) * .7) var(--edge);text-align:left;border-top:1px solid rgba(255,255,255,.14);
  color:rgba(255,255,255,.62);font-size:var(--small);letter-spacing:.02em;line-height:1.2}

/* ============ LIGHTBOX ============ */

/* ============ RESPONSIVE ============ */
@media(max-width:1180px){
  .wpg{--thumbw:clamp(132px,15.6vw,216px);--detw:clamp(115px,13vw,170px)}
}
@media(max-width:900px){
  .wlist{padding-left:var(--pad);padding-right:var(--pad)}
  .wr-th,.wr-dt{display:none}
  .wr{padding:7px 0;border-bottom:1px solid var(--line)}
  .wr-t{font-size:clamp(19px,5.6vw,30px)}
}
@media(max-width:1100px){
  .cv-reel{width:min(78%,900px)}
  .cv-words{left:auto;right:0}
}
@media(max-width:820px){
  .cv{gap:22px;padding-bottom:26px}
  .cv-nav{position:static;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;
    gap:4px 16px;margin-top:14px}
  .cv-nav a{font-size:15px}
  .cv-stage{display:block}
  .cv-reel{width:100%;margin:0 0 20px}
  .cv-words{position:static;transform:none;mix-blend-mode:normal;filter:none;
    display:flex;flex-wrap:wrap;flex-direction:row;gap:2px 16px}
  .dw{font-size:16px;color:var(--ink2)}
  .dw:nth-child(-n+2){color:var(--ink)}
  }
@media(max-width:980px){
  .p-b,.rgrid{grid-template-columns:1fr}
  .p-x,.rside{position:static}
}
@media(max-width:820px){
  .burger{display:block}
  .nv{position:fixed;inset:0 0 auto;padding:92px 26px 34px;flex-direction:column;align-items:flex-start;
    gap:2px;background:var(--bg);height:100svh;transform:translateY(-101%);
    transition:transform .42s var(--ease);overflow-y:auto;z-index:40}
  .nv.open{transform:none}
  .nv a{font-size:22px;padding:11px 0}
}
@media(max-width:900px){
  .r-t,.r-m{max-width:100%}
}
@media(max-width:620px){
  .shs{columns:1}
  .pgr a{max-width:100%}
  .allw{order:3;width:100%;text-align:center}
  .cv li{grid-template-columns:1fr;gap:5px}
  .c-y{padding-top:0}
  .reel-flag{position:static;margin:0 var(--pad) 20px;max-width:none}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .cv-reel .reel{display:none}
  html{scroll-behavior:auto}
  .flipa:hover>span,.flipword:hover>span,.row.has:hover .r-in{transform:none!important}
}
@media print{
  .hd,.ft,.cover,.peek,.pgr,.jump{display:none}
  body{background:var(--bg)}
  .rgrid{grid-template-columns:1fr 1fr}
}

/* ============ LIGHTBOX — full-screen image viewer ============ */
.sh a{display:block;overflow:hidden;border-radius:2px;cursor:zoom-in}
.lb{position:fixed;inset:0;z-index:100;background:rgba(12,12,13,.97);display:none;
  align-items:center;justify-content:center;padding:clamp(20px,4vw,64px)}
.lb.on{display:flex}
.lb img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
  border-radius:2px;box-shadow:0 30px 90px rgba(0,0,0,.6)}
.lb-c{position:absolute;left:0;right:0;bottom:clamp(12px,1.6vw,26px);text-align:center;
  font-size:var(--caps);letter-spacing:var(--capsls);text-transform:uppercase;
  color:rgba(242,241,239,.62)}
.lb-x,.lb-p,.lb-n{position:absolute;background:none;border:1px solid rgba(255,255,255,.22);
  color:var(--ink);width:clamp(38px,3vw,52px);height:clamp(38px,3vw,52px);border-radius:99px;
  font-size:clamp(15px,1.2vw,20px);line-height:1;cursor:pointer;display:flex;
  align-items:center;justify-content:center;transition:.2s;padding:0}
.lb-x:hover,.lb-p:hover,.lb-n:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.lb-x{top:clamp(14px,1.6vw,26px);right:clamp(14px,1.6vw,26px)}
.lb-p{left:clamp(10px,1.4vw,26px);top:50%;transform:translateY(-50%)}
.lb-n{right:clamp(10px,1.4vw,26px);top:50%;transform:translateY(-50%)}
@media(max-width:600px){.lb-p,.lb-n{display:none}}
