
@font-face{font-family:"Overused Grotesk";
  src:url("/t/OverusedGrotesk-VF.woff2") format("woff2-variations");
  font-weight:300 900;font-style:normal;font-display:swap}

:root{
  --paper:#050505; --ink:#f2f1ee;
  --mute:color-mix(in srgb,var(--ink) 46%,transparent);
  --rule:color-mix(in srgb,var(--ink) 14%,transparent);
  --measure:44rem; --body:15.5px;
}
:root[data-read="m"]{--body:17px}
:root[data-read="l"]{--body:18.5px}
:root[data-measure="n"]{--measure:36rem}
:root[data-measure="w"]{--measure:52rem}
:root[data-theme="light"]{--paper:#f4f3f0;--ink:#0e0e0d}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--paper);color:var(--ink);font-size:var(--body);line-height:1.62;
  font-family:"Overused Grotesk",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  letter-spacing:-.011em;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.22em;
  text-decoration-color:color-mix(in srgb,currentColor 22%,transparent);
  transition:text-decoration-color .18s ease,opacity .18s ease}
a:hover{text-decoration-color:color-mix(in srgb,currentColor 55%,transparent)}
:focus-visible{outline:1px solid currentColor;outline-offset:3px}

.page{max-width:var(--measure);margin:0 auto;padding:96px 26px 110px}
header.id{display:flex;gap:14px;align-items:flex-start;margin:0 0 30px}
header.id .av{width:42px;height:42px;border-radius:50%;flex:0 0 auto;object-fit:cover;
  background:color-mix(in srgb,var(--ink) 12%,transparent)}
header.id h1{margin:0;font-size:1em;font-weight:400;letter-spacing:-.015em}
header.id p{margin:1px 0 0;font-size:.88em;color:var(--mute)}
.intro p{margin:0 0 17px}
.intro p:last-child{margin-bottom:0}

nav.pages{display:flex;flex-wrap:wrap;gap:0 18px;margin:34px 0 0;font-size:.88em}
nav.pages a{border:0;color:var(--mute)}
nav.pages a:hover{color:var(--ink)}

section{margin-top:54px}
h2{font-size:.72em;letter-spacing:.14em;text-transform:uppercase;font-weight:500;
  color:var(--mute);margin:0 0 16px}
.list{display:flex;flex-direction:column}
.item{display:grid;grid-template-columns:1fr auto;gap:4px 18px;padding:13px 0;
  align-items:baseline}
.item .t{font-size:1em;font-weight:500}
.item .d{grid-column:1;font-size:.86em;color:var(--mute);line-height:1.45}
.item .y{font-size:.78em;color:var(--mute);font-variant-numeric:tabular-nums;
  grid-row:1;grid-column:2}
a.item{border:0}
a.item:hover .t{border-bottom:1px solid currentColor}
.more{margin-top:16px;font-size:.88em;color:var(--mute)}
.more a{color:var(--ink)}

footer{margin-top:72px;padding-top:22px;
  border-top:1px solid color-mix(in srgb,var(--ink) 7%,transparent);
  display:flex;flex-wrap:wrap;gap:6px 18px;font-size:.8em;color:var(--mute)}
footer a{border:0}
footer a:hover{border-bottom:1px solid currentColor}
footer .sp{margin-left:auto}

/* the CV is one continuous document with a jump index: no tabs, so nothing is
   hidden from a scan, from Ctrl+F, from a deep link or from print */
/* the masthead is fixed at top:0, so the page starts below it and the jump
   index sticks below that rather than underneath it */
/* The masthead is fixed and unpainted, so on a document page the text scrolled
   visibly through the strip above the index. This paints that strip, under the
   masthead and over the page. */
body.doc:before{content:"";position:fixed;top:0;left:0;right:0;height:46px;
  z-index:890;background:var(--paper)}
/* On a wide screen the index sits on the masthead's own line: the name is hard
   left, the nav hard right, and the middle is empty, so the tabs cost no
   vertical space at all. It has to clear the band above it, hence the z-index.
   A phone has no empty middle, so there it drops below and keeps its distance. */
.jump{position:sticky;top:0;z-index:895;display:flex;gap:16px;flex-wrap:nowrap;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  padding:15px 0 14px;margin:0 0 30px;background:var(--paper);font-size:.8em}
.jump::-webkit-scrollbar{display:none}
.jump a{border:0;color:var(--mute);flex:0 0 auto;white-space:nowrap}
.jump a:hover,.jump a.here{color:var(--ink)}
section[id]{scroll-margin-top:66px}
@media(max-width:900px){
  /* Wrapping costs a line; clipping costs a section nobody can see. At Wide
     the measure grows and the fifth tab fell off the edge of the phone with
     nothing to say it was still there. */
  .jump{top:46px;padding:12px 0 14px;flex-wrap:wrap;gap:12px 16px;
    overflow-x:visible}
  section[id]{scroll-margin-top:124px}
}
.cards{display:grid;grid-template-columns:1fr 1fr;gap:34px 40px;margin:0 0 10px}
.card{display:block;padding:0}
.card .t{display:block;font-weight:500;letter-spacing:-.015em;margin:0 0 5px}
.card .tags{display:flex;flex-wrap:wrap;gap:5px;margin:0 0 8px}
.card .tags span{font-size:.76em;letter-spacing:.01em;color:var(--mute)}
.card .tags span+span:before{content:"·";margin-right:5px;opacity:.5}
.card p{margin:0;font-size:.9em;color:color-mix(in srgb,var(--ink) 78%,transparent)}
.rows{margin:0}
.rows .r{display:grid;grid-template-columns:190px 1fr;gap:18px;padding:7px 0;
  font-size:.92em}
.rows .r b{font-weight:500}
.rows .r span{color:var(--mute)}
@media(max-width:640px){.cards{grid-template-columns:1fr}
  .rows .r{grid-template-columns:1fr;gap:2px}}
.hero{display:block;margin:0 0 60px;text-decoration:none;position:relative}
.hero .frame{position:relative;overflow:hidden;aspect-ratio:16/9;
  background:color-mix(in srgb,var(--ink) 6%,transparent)}
.hero img,.hero video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.hero video{opacity:0;transition:opacity .5s ease}
.hero.live video{opacity:1}
.hero .play{position:absolute;left:16px;bottom:16px;z-index:2;
  background:color-mix(in srgb,var(--paper) 80%,#000);color:var(--ink);
  padding:7px 13px;font-size:.78em;backdrop-filter:blur(6px);
  opacity:.9;transition:opacity .2s ease}
.hero:hover .play{opacity:1}
.hero.playing .play{opacity:0;pointer-events:none}
.hero.playing video{pointer-events:auto}
.hero{cursor:pointer}
.hero .cap{display:flex;gap:10px;align-items:baseline;margin:10px 0 0;font-size:.9em}
.hero .cap b{font-weight:500}
.hero .cap span{color:var(--mute);font-size:.9em}
.lede-s{margin:0 0 20px;max-width:56ch;color:color-mix(in srgb,var(--ink) 78%,transparent)}
/* the list stays compact; the screenshot lives in a card that follows the
   pointer, so eight sites cost eight lines instead of eight full-bleed images */
/* two-up for the areas list */
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:30px 40px}
.grid2 .entry{padding:0}
/* About uses the Clients grid exactly, so the two read as one system */
.about .g{display:grid;grid-template-columns:190px 1fr;gap:18px;padding:7px 0 22px;
  font-size:.92em;align-items:baseline}
.about .g:last-child{padding-bottom:0}
.about h3{margin:0;font-size:1em;font-weight:500;color:var(--ink);
  letter-spacing:normal;text-transform:none}
.about p{margin:0 0 10px;color:var(--mute);max-width:60ch}
.about p:last-child{margin-bottom:0}
@media(max-width:640px){.grid2{grid-template-columns:1fr;gap:24px}
  .about .g{grid-template-columns:1fr;gap:4px}}
.sites .r{display:grid;grid-template-columns:190px 1fr auto;gap:18px;padding:7px 0;
  font-size:.92em;align-items:baseline;text-decoration:none}
.sites .r b{font-weight:500}
.sites .r .d{color:var(--mute)}
.sites .r .go{color:var(--mute);font-size:.86em;opacity:0;transition:opacity .18s ease}
.sites .r:hover .go{opacity:1}
#peek{position:fixed;z-index:800;pointer-events:none;width:290px;
  opacity:0;transform:translateY(6px) scale(.985);transform-origin:top left;
  transition:opacity .18s ease,transform .24s cubic-bezier(.2,.8,.2,1);
  background:color-mix(in srgb,var(--paper) 88%,#000);
  box-shadow:0 18px 50px rgba(0,0,0,.32);overflow:hidden}
#peek.on{opacity:1;transform:none}
#peek img{width:100%;aspect-ratio:16/10;object-fit:cover;display:block}
#peek .m{padding:9px 11px;font-size:11.5px;line-height:1.35;color:var(--ink)}
#peek .m i{display:block;font-style:normal;opacity:.45;margin-top:1px}
@media(max-width:640px){.sites .r{grid-template-columns:1fr;gap:2px}#peek{display:none}}
.entry{display:block;padding:0 0 26px;text-decoration:none}
.entry:last-of-type{padding-bottom:6px}
a.entry:hover .t{text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.22em}
.entry .hd{display:flex;align-items:baseline;gap:14px;justify-content:space-between}
.entry .t{font-size:1.02em;font-weight:500;letter-spacing:-.012em}
.entry .m{font-size:.74em;color:var(--mute);white-space:nowrap;font-variant-numeric:tabular-nums;
  flex:0 0 auto}
.entry .b{margin:5px 0 0;font-size:.88em;color:var(--mute);line-height:1.55;max-width:58ch}
.frame p{margin:0 0 14px;max-width:58ch}
.frame p:last-child{margin-bottom:0}
p.creditline{margin:0 0 12px;font-size:.88em;color:var(--mute);line-height:1.65;max-width:60ch}
p.creditline:last-child{margin-bottom:0}
h1.lede-h{font-size:1.72em;line-height:1.16;letter-spacing:-.026em;font-weight:400;
  margin:26px 0 12px;max-width:19ch}
p.lede{font-size:1.02em;line-height:1.55;color:var(--mute);margin:0 0 14px;max-width:58ch}
h1{margin:0;font-size:1em;font-weight:400;letter-spacing:-.015em}
.who{margin:0;font-size:1em;font-weight:400;letter-spacing:-.015em}
.who a{border:0}
.can{margin:26px 0 0;padding:20px 0 0;border-top:1px solid var(--rule)}
.can p{margin:0 0 5px;font-size:1.02em;letter-spacing:-.014em}
.can p:last-child{margin-bottom:0;color:var(--mute)}
p.clients{margin:0;line-height:1.85;font-size:.94em;color:var(--mute)}
p.note{margin:-6px 0 16px;font-size:.84em;color:var(--mute);max-width:52ch}
p.ask{margin:0;max-width:46ch}
nav.pages a[aria-current]{color:var(--ink)}

@media (max-width:640px){
  .entry .hd{flex-direction:column;gap:1px;align-items:flex-start}
  .entry .m{white-space:normal}
  h1.lede-h{font-size:1.5em;max-width:none}
  .page{padding:64px 18px 104px}
  footer .sp{margin-left:0;width:100%}
}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important}}
@view-transition{navigation:auto}
::view-transition-old(root){animation:140ms ease both fo}
::view-transition-new(root){animation:240ms ease both fi}
@keyframes fo{to{opacity:0}} @keyframes fi{from{opacity:0}}
:root[data-ground="rose"]{--paper:#150d0d;--ink:#f2e7e4}:root[data-theme="light"][data-ground="rose"]{--paper:#f3e8e4;--ink:#1c1211}:root[data-ground="bone"]{--paper:#11100e;--ink:#efece4}:root[data-theme="light"][data-ground="bone"]{--paper:#eae5da;--ink:#17150f}
.mos{position:fixed;inset:0;overflow:hidden;cursor:grab;touch-action:none;
  background:var(--paper);z-index:1}
.mos.drag{cursor:grabbing}
.mos .wrap{position:absolute;top:0;left:0;will-change:transform}
.mos .plane{position:absolute;top:0;left:0}
.mos .t{position:absolute;display:block;border:0;line-height:0;
  transition:opacity .5s ease}
.mos .t img{width:100%;height:100%;object-fit:cover;display:block;
  background:color-mix(in srgb,var(--ink) 7%,transparent)}
.mos .t video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;opacity:0;transition:opacity .25s ease}
.mos .t:hover video{opacity:1}
.mos .t .cap{position:absolute;left:0;top:calc(100% + 7px);white-space:nowrap;
  font-size:11px;letter-spacing:.02em;line-height:1;color:var(--ink);
  opacity:0;transition:opacity .18s ease;pointer-events:none}
.mos .t:hover .cap{opacity:.62}
.mos.anytile .t{opacity:.42}
.mos.anytile .t:hover{opacity:1}
.mos .hint{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:5;
  font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);
  opacity:.3;pointer-events:none;transition:opacity .4s ease}
.mos .hint.gone{opacity:0}
.mid{position:fixed;left:0;right:0;top:0;z-index:6;display:flex;gap:18px;
  align-items:baseline;padding:16px 20px;pointer-events:none;
  font-size:13px;letter-spacing:-.01em}
.mid .nm{font-weight:400}
.mid nav{display:flex;gap:14px;margin-left:auto;pointer-events:auto}
.mid a{border:0;opacity:.55}
.mid a:hover{opacity:1}
.lb{position:fixed;inset:0;z-index:60;background:color-mix(in srgb,var(--paper) 88%,#000);
  display:none;align-items:center;justify-content:center;cursor:zoom-out;padding:4vmin}
.lb.on{display:flex}
.lb img{max-width:100%;max-height:100%;object-fit:contain}
@media(max-width:700px){.mid{font-size:12px;gap:10px}.mid nav{gap:10px}}

/* The blend goes on the container, not on each mark. z-index makes these
   containers stacking contexts, and a blended child inside one has only its
   parent's empty backdrop to blend against -- so on a light ground every mark
   stayed near-white and disappeared. The container has the page behind it,
   which is the thing the marks need to be legible against. */
.mast{position:fixed;top:0;left:0;right:0;z-index:900;display:flex;
  align-items:center;justify-content:space-between;
  padding:15px 22px;pointer-events:none;
  font:400 13px/1 "Overused Grotesk",-apple-system,BlinkMacSystemFont,sans-serif;
  letter-spacing:-.012em;mix-blend-mode:difference;color:#f2efe9}
.corner{position:fixed;bottom:15px;z-index:900;pointer-events:none;
  font:400 13px/1 "Overused Grotesk",-apple-system,BlinkMacSystemFont,sans-serif;
  letter-spacing:-.012em;mix-blend-mode:difference;color:#f2efe9}
.corner.bl{left:22px;display:flex;align-items:center;gap:14px}
.corner.br{right:22px}
.mast a,.mast button,.corner .circ,.corner .plain,.corner .mail,.pbtn{
  pointer-events:auto;color:inherit;
  background:none;border:0;font:inherit;letter-spacing:inherit;
  cursor:pointer;text-decoration:none;padding:0}
.mast .home,.topnav a{font-weight:400}
.topnav{display:flex;gap:16px}
.topnav a[aria-current=page]{text-decoration:underline;text-underline-offset:.3em}

.corner .circ{width:26px;height:26px;border-radius:50%;display:inline-flex;
  align-items:center;justify-content:center;
  box-shadow:inset 0 0 0 1px rgba(128,128,128,.55);
  transition:box-shadow .18s ease}
.corner .circ:hover{box-shadow:inset 0 0 0 1px currentColor}
.corner .circ svg{width:13px;height:13px;display:block}
.corner .circs{display:flex;gap:8px}
.corner .plain,.corner .mail{opacity:.72;transition:opacity .18s ease}
.corner .plain:hover,.corner .mail:hover{opacity:1}
.corner .mail.copied .lbl:after{content:" copied";opacity:.5}
.corner .mail .ic{display:none}

.pbtn{opacity:.72;transition:opacity .18s ease}
.pbtn .aa{display:none}
@media(max-width:760px){.pbtn .lbl{display:none}.pbtn .aa{display:inline}}
.pbtn:hover,.pbtn[aria-expanded=true]{opacity:1}
/* the panel itself is a real surface, so it does not blend: square, hairline,
   opening upward out of the corner it belongs to */
.prefs{position:fixed;right:22px;bottom:46px;z-index:901;
  background:var(--paper,#0b0a09);color:var(--ink,#f2efe9);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink,#f2efe9) 14%,transparent);
  padding:15px 16px 14px;width:212px;pointer-events:auto;
  font:400 12.5px/1.4 "Overused Grotesk",-apple-system,BlinkMacSystemFont,sans-serif;
  letter-spacing:-.012em;
  opacity:0;transform:translateY(6px);pointer-events:none;
  transition:opacity .2s cubic-bezier(.2,.8,.2,1),transform .2s cubic-bezier(.2,.8,.2,1)}
.prefsopen .prefs{opacity:1;transform:none;pointer-events:auto}
.prefs h3{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  font-weight:400;opacity:.36;margin:0 0 7px}
.prefs .grp{margin:0 0 14px}
.prefs .grp:last-child{margin:0}
.prefs .set{display:flex;gap:13px;align-items:center;flex-wrap:wrap}
.prefs button{background:none;border:0;padding:0;font:inherit;color:inherit;
  cursor:pointer;opacity:.42;transition:opacity .18s ease}
.prefs button:hover,.prefs button[aria-pressed=true]{opacity:1}
.prefs kbd{font:inherit;font-size:.8em;opacity:.4;margin-left:5px}
.prefs .gr{gap:11px}
.prefs .sz button:nth-child(1){font-size:11px}
.prefs .sz button:nth-child(2){font-size:13.5px}
.prefs .sz button:nth-child(3){font-size:16px}

@media(max-width:760px){
  .mast{padding:13px 16px}
  /* One pill, centred, on its own ground.
     Two transparent corners over a scrolling document put the marks and the
     Display button straight on top of the text. Blending cannot fix that --
     the type behind them keeps moving. So on a phone they become a single
     opaque bar in the middle, and Display joins the marks as another circle. */
  .corner{bottom:14px;mix-blend-mode:normal;color:var(--ink,#f2efe9)}
  .corner.bl{left:50%;transform:translateX(-50%);gap:8px;
    padding:7px 9px;border-radius:100px;
    background:color-mix(in srgb,var(--paper,#0b0a09) 88%,var(--ink,#f2efe9));
    box-shadow:0 0 0 1px color-mix(in srgb,var(--ink,#f2efe9) 12%,transparent),
      0 6px 22px rgba(0,0,0,.34);
    backdrop-filter:blur(12px)}
  .corner.br{display:none}          /* its button has moved into the pill */
  .corner .plain{display:none}
  /* the address stays reachable, as a mark rather than a line of text */
  .corner .mail{width:30px;height:30px;border-radius:50%;
    display:inline-flex;align-items:center;justify-content:center;
    box-shadow:inset 0 0 0 1px rgba(128,128,128,.55);opacity:1;
    transition:box-shadow .18s ease,background .25s ease}
  .corner .mail .lbl{display:none}
  .corner .mail .ic{display:inline-flex;width:15px;height:15px}
  .corner .mail .ic svg{width:100%;height:100%;display:block}
  .corner .mail.copied{background:#00ff2a;color:#0b0b0b;
    box-shadow:inset 0 0 0 1px #00ff2a}
  .corner .circ{width:30px;height:30px}
  .corner .circ svg{width:14px;height:14px}
  /* Display, wearing the same circle as the marks */
  .corner.bl .pbtn{width:30px;height:30px;border-radius:50%;
    display:inline-flex;align-items:center;justify-content:center;
    box-shadow:inset 0 0 0 1px rgba(128,128,128,.55);opacity:1;
    font-size:12.5px;letter-spacing:-.02em}
  .corner.bl .pbtn:hover,.corner.bl .pbtn[aria-expanded=true]{
    box-shadow:inset 0 0 0 1px currentColor}
  .prefs{left:50%;right:auto;transform:translateX(-50%) translateY(6px);
    bottom:60px;width:min(260px,calc(100vw - 32px))}
  .prefsopen .prefs{transform:translateX(-50%)}
}

/* a fixed width, not min(100%,470px): the work block sizes to max-content, so
   a percentage here resolves against the plate itself and collapses it */
.h3 .plate{display:flex;align-items:center;justify-content:center;
  width:min(100%,var(--shot,470px));
  min-height:calc(var(--shot,470px) * 0.75);aspect-ratio:4/3;
  background:color-mix(in srgb,var(--ink) 7%,transparent)}
.h3 .plate .mark{font-size:1.45em;letter-spacing:.02em;line-height:1;
  color:color-mix(in srgb,var(--ink) 58%,transparent);text-align:center;
  padding:0 12%}
.h3 .plate svg{width:34%;height:auto;display:block;
  color:color-mix(in srgb,var(--ink) 58%,transparent);fill:currentColor}
@media(max-width:900px){.h3 .plate{width:100%}}

body.home3{overflow-x:hidden}
/* Measure drives this page too. It used to cap the text at 34ch and the media
   at 470px whatever the screen, so a wide display was mostly empty air beside
   three narrow columns. Now the caps are variables the Display panel moves:
   wide lets the text fill its column and the media fill the half it is given. */
/* --shot is always a real length, never a percentage. As 100% it resolved
   against a max-content parent -- circular -- and collapsed the logo plates to
   nothing. And 700 rather than "as wide as the column": the media runs 1000 to
   1400px at source, so on a 2x display anything past 700 is upscaled. */
.h3{display:grid;grid-template-columns:25% 25% 50%;align-items:start;
  --tx:34ch;--shot:470px}
:root[data-measure="n"] .h3{--tx:30ch;--shot:400px}
/* Wide cannot fill the third column with picture -- the sources top out
   around 1400px and 700 is as far as they go sharp at 2x. So the width is
   spent on air instead of upscaling: the gutters open up with the viewport,
   and the media centres in its column rather than leaving all the slack
   stacked against the right edge. */
:root[data-measure="w"] .h3{--tx:none;--shot:700px;--gut:clamp(26px,3.4vw,72px)}
:root[data-measure="w"] .h3 .samples{align-items:center}
/* column one: pinned */
.h3 .who{position:sticky;top:0;height:100svh;display:flex;flex-direction:column;
  justify-content:space-between;padding:56px var(--gut,26px) 64px;font-size:.92em}
.h3 .who p{margin:0 0 14px;max-width:var(--tx)}
/* column two: fixed, moved only by the page's own scroll */
/* overflow:hidden clips at the padding box, so the gutter alone will not keep
   the list off the masthead or the corner chrome. The rail is masked at both
   ends instead, which also stops rows being cut off mid-letter as they pass. */
.h3 .feed{position:fixed;top:0;left:25%;width:25%;height:100svh;overflow:hidden;
  padding:56px var(--gut,26px) 76px;font-size:.92em;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 44px,
    #000 calc(100% - 74px),transparent calc(100% - 34px));
  mask-image:linear-gradient(to bottom,transparent 0,#000 44px,
    #000 calc(100% - 74px),transparent calc(100% - 34px))}
.h3 .feed ol{will-change:transform;list-style:none;margin:0;padding:0}
/* As on the reference: the list rests, and one row at a time comes up -- the
   one whose work is on screen, or the one under the pointer. Every row lit at
   once gave the column no relationship to the samples beside it. */
.h3 .feed li{margin:0 0 14px;max-width:var(--tx);
  color:color-mix(in srgb,var(--ink) 34%,transparent);transition:color .2s ease}
.h3 .feed li.has{cursor:pointer}
.h3 .feed li.has:hover .nm{text-decoration-color:currentColor}
.h3 .feed li.has:hover,.h3 .feed li.cur{color:var(--ink)}
.h3 .feed li .nm{text-decoration:underline;text-underline-offset:.22em;
  text-decoration-color:color-mix(in srgb,currentColor 35%,transparent)}
.h3 .feed li a{color:inherit}
/* column three: the only thing that scrolls */
.h3 .samples{grid-column:3;padding:56px var(--gut,26px) 92vh;display:flex;
  flex-direction:column;gap:34px;align-items:flex-start}
.h3 .work{scroll-margin-top:20px;width:min(100%,var(--shot))}
/* one slide at a time. The others are not hidden with display:none, which
   would stop them decoding until first shown and give a blank frame on the
   first advance; they are taken out of flow and left to load. */
.h3>*{min-width:0}
/* One canvas per item.
   The feed mixed full-bleed photographs, portrait crops, phone screengrabs and
   flat logos, each arriving at its own size and its own edge -- so the column
   read as a pile rather than a set. Every item now sits on the same ground, in
   the same frame, inset from the edge. The ground is mixed from the theme's own
   ink, so it stays visible on Ink, Rose and Bone, light or dark, without ever
   being a colour the site does not already use. */
.h3 .stage{position:relative;line-height:0;width:min(100%,var(--shot));
  min-height:calc(var(--shot,470px) * 0.75);
  display:flex;align-items:center;justify-content:center;
  padding:var(--inset,26px);
  background:color-mix(in srgb,var(--ink) 7%,transparent)}
/* shrink-to-fit, not block. As a block the frame filled the sample column
   (668px) while the picture inside it was 470, so anything positioned against
   the frame -- the play button -- sat off to one side of the picture. */
.h3 .shot{display:inline-block;vertical-align:top;line-height:0;max-width:100%}
.h3 .shot[aria-hidden=true]{opacity:0;pointer-events:none}
/* The 470 cap lives on the frame, not the picture. As `min(100%,470px)` on
   the image it was ignored while the browser worked out the frame's intrinsic
   width -- a percentage inside min() counts as none there -- so the frame took
   the poster's full 1280 and settled at the column width instead. */
/* Addressed as a child of the stage so it outranks the plain `.h3 .shot`
   rule further down, which sets position:relative. With that winning, the
   frame took its size from an image that was sizing itself from the frame --
   circular, and it resolved differently in different renderers. */
/* The slide on show sits in flow, so a tall picture makes the canvas taller
   rather than being squeezed into a fixed frame. The rest are taken out of
   flow so they cannot add to that height. min-height keeps every canvas at
   least 4:3, which is what makes the column read as a set. */
.h3 .stage>.shot{display:flex;align-items:center;justify-content:center;
  width:100%;max-width:100%}
.h3 .stage>.shot[aria-hidden=true]{position:absolute;
  inset:var(--inset,26px);opacity:0;pointer-events:none}
.h3 .stage>.shot img,.h3 .stage>.shot video{width:auto;height:auto;
  display:block;max-width:100%;max-height:min(74vh,760px);
  margin:0 auto;object-fit:contain}
.h3 .work.multi .stage{cursor:pointer}
a.stage{display:block;text-decoration:none}
.h3 .cap .go{margin-left:auto;flex:0 0 auto;text-decoration:underline;
  text-underline-offset:.22em;
  text-decoration-color:color-mix(in srgb,currentColor 35%,transparent)}
.h3 .cap .go:hover{text-decoration-color:currentColor}
.h3 .cap .go+.dots{margin-left:11px}
/* sound, bottom left of the frame, in the manner of the dots */
.h3 .snd{position:absolute;left:10px;bottom:10px;width:22px;height:22px;
  padding:0;border:0;cursor:pointer;border-radius:50%;
  background:color-mix(in srgb,#000 42%,transparent);
  backdrop-filter:blur(6px);display:flex;align-items:center;
  justify-content:center;opacity:.85;transition:opacity .18s ease}
.h3 .snd:hover{opacity:1}
.h3 .snd span{display:block;width:9px;height:9px;
  border:1px solid #fff;border-radius:50%;position:relative}
.h3 .snd[aria-pressed=true] span{background:#fff}
.h3 .shot{position:relative}
.h3 .shot.yt{cursor:pointer}
.h3 .shot.yt iframe{display:block;border:0;width:100%;aspect-ratio:16/9}
.h3 .play{position:absolute;inset:0;margin:auto;width:52px;height:52px;
  padding:0;border:0;border-radius:50%;cursor:pointer;
  background:color-mix(in srgb,#000 46%,transparent);backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;
  opacity:.9;transition:opacity .18s ease}
.h3 .shot.yt:hover .play{opacity:1}
.h3 .play span{display:block;width:0;height:0;margin-left:3px;
  border-left:13px solid #fff;border-top:8px solid transparent;
  border-bottom:8px solid transparent}
/* the caption line, as on the reference: position, then what it is */
.h3 .cap{display:flex;align-items:center;gap:9px;margin:9px 0 0;
  font-size:.8em;color:var(--mute);line-height:1.4;flex-wrap:wrap}
.h3 .cap .ct{font-variant-numeric:tabular-nums;flex:0 0 auto}
.h3 .cap .cx{flex:0 1 auto;min-width:0}
.h3 .cap a{color:inherit}
.h3 .dots{display:flex;gap:5px;flex:0 0 auto}
.h3 .dots button{width:6px;height:6px;padding:0;border:0;border-radius:50%;
  background:color-mix(in srgb,var(--ink) 22%,transparent);cursor:pointer}
.h3 .dots button[aria-current=true]{background:var(--ink)}

/* stacked, one column, each sentence carrying its own media */
@media(max-width:900px){
  .h3{grid-template-columns:1fr}
  /* the same size the columns use on a wide screen -- it was stepping up to
     the full body size on a phone, which is the largest of the three */
  .h3 .who{position:static;height:auto;padding:70px 20px 30px;font-size:.92em}
  .h3 .who p{max-width:none}
  .h3 .feed{position:static;left:auto;width:auto;height:auto;overflow:visible;
    padding:0 20px 90px;font-size:.92em;-webkit-mask-image:none;mask-image:none}
  .h3 .feed ol{transform:none!important}
  .h3 .feed li{max-width:none;margin:0 0 30px;
    color:color-mix(in srgb,var(--ink) 62%,transparent)}
  .h3 .feed li.has{color:var(--ink)}
  .h3 .feed li.cur{color:inherit}
  .h3 .samples{display:none}
  .h3 .feed .work{margin:14px 0 0}
  .h3 .work,.h3 .stage{width:auto;max-width:100%}
  .h3 .stage{--inset:16px;min-height:min(66vw,320px)}
  .h3 .cap{font-size:.82em;max-width:none}
}
