/* Apfel Grotezk by Collletttivo, self-hosted (SIL Open Font License). Regular is the only weight used. */
@font-face{font-family:"Apfel Grotezk";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/site-font-400.32b27faf00.woff2) format("woff2")}
:root{
  --bg:#EEEEE5; --ink:#262626; --black:#000000; --pill:#373737; --pill-ink:#D9D9D9; --reel-ink:#2F3028; --grey-ink:#373737; --panel:#D0D0D0;
  --yellow:#F4FF9D; --red:#FF2D55; --violet:#8E82F1; --white:#FFFFFF; --rule:rgba(38,38,38,.28);
  --font:"Apfel Grotezk",ui-sans-serif,system-ui,sans-serif;
  /* the ✳ as an SVG: the character itself has no glyph in most fonts, so browsers fall back to the colour emoji (a green block) */
  --star-img:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M0 12h24M12 0v24M3.5 3.5l17 17M20.5 3.5l-17 17' stroke='%23000' stroke-width='1.6'/%3E%3C/svg%3E");--star-ratio:.7;
  --u:1px;
  color-scheme:light;
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
.t40{font-size:calc(40*var(--u));line-height:1.225;letter-spacing:0;font-weight:400;margin:0}
.t20{font-size:max(13px,calc(20*var(--u)))}
.t16{font-size:max(11px,calc(16*var(--u)))}
.abs{position:absolute;left:calc(var(--x)*var(--u));top:calc(var(--y)*var(--u));width:calc(var(--w)*var(--u))}
/* a link button never breaks (nowrap): a text box narrower than its longest button grows to fit it, so the words after it
   don't get pushed under it one per line */
@media (min-width:900px){p.abs{min-width:min-content}}
.abs.img{height:calc(var(--h)*var(--u))}
.abs.img img{width:100%;height:100%;object-fit:cover}
.abs.img[data-video]{overflow:hidden}
.abs.img video,.abs.img canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .4s;pointer-events:none}
.abs.img video.on,.abs.img canvas.on{opacity:1}
:focus-visible{outline:2px solid var(--black);outline-offset:3px}

/* ---------- hero ---------- */
.hero{position:sticky;top:0;z-index:0;background:color-mix(in srgb,var(--bg),var(--white) calc(var(--hw,0)*100%));height:100vh;height:100svh;min-height:520px;overflow:hidden;touch-action:pan-y;}
.hero .name{position:absolute;top:calc(50% - 15*var(--u));margin:0;z-index:2;pointer-events:none}
.hero .n-left{left:calc(30*var(--u))}
.hero .n-mid{left:calc(486*var(--u))}
/* the title fades up like the rest of the homepage text, word by word, alongside the black squares popping in */
.rv-on .hero .n-mid .wi{opacity:0;transform:translateY(40%)}
.rv-on .hero .n-mid.in .wi{opacity:1;transform:none;transition:opacity .35s calc(var(--i,0)*90ms),transform .5s cubic-bezier(.22,1,.36,1) calc(var(--i,0)*90ms)}
.hero .n-right{right:calc(30*var(--u))}
/* the loader (html.ld: the first homepage visit of a session, set in <head>; site.js runs it): the curve fills up with its white squares
   while stars circle the name, which waits in the middle; then the name slides out to the sides and the title comes in */
.ld{overflow:hidden;scrollbar-gutter:stable}
.ld:not(.ldp) .hero .names,.ld .hero .n-mid,.ld .hero .down{visibility:hidden}   /* the name shows once it's been moved to the middle */
.ld .hero .trail{transition:scale .4s cubic-bezier(.34,1.56,.64,1)}
.ld .hero .trail:not(.lit){scale:0}
.ld-star{position:absolute;left:0;top:0;width:var(--ss);height:var(--ss);margin:calc(var(--ss)/-2) 0 0 calc(var(--ss)/-2);background:var(--ink);-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat;pointer-events:none;will-change:transform,opacity}
.trail{position:absolute;left:0;top:0;width:var(--ts);height:var(--ts);background:var(--white) center/cover no-repeat;z-index:1;pointer-events:none;will-change:transform}
.trail::after{content:'';position:absolute;inset:0;background:var(--pic) center/cover no-repeat;opacity:0;transition:opacity .5s ease-out}   /* the hover picture: in with a fast fade, out in a slower one */
.trail.pic::after{opacity:1;transition:opacity .12s ease-out}
/* it zooms in slightly as it fades in, always filling the square: the square clips it, and the zoom holds until the fade-out is done
   (not on the story homepage, whose pictures reach past their squares) */
.hero:not(.story) .trail{overflow:hidden;transition:scale .5s cubic-bezier(.22,1,.36,1)}
.hero:not(.story) .trail.pic{scale:1.12;transition:scale .6s cubic-bezier(.22,1,.36,1)}   /* the white square grows a little too (on top of the wave's own scaling, set inline), keeping its place in the stack */
.hero:not(.story) .trail::after{transition:opacity .5s ease-out,transform 0s .5s}
.hero:not(.story) .trail.pic::after{transform:scale(1.08);transition:opacity .12s ease-out,transform .6s cubic-bezier(.22,1,.36,1)}
.glow{position:absolute;border-radius:50%;pointer-events:none;z-index:5;
  background:radial-gradient(circle,rgba(244,255,157,1) 0,rgba(244,255,157,.85) 18%,rgba(244,255,157,.35) 38%,rgba(244,255,157,0) 62%)}

/* scroll-down arrow: bottom centre, bobs gently, fades out with the name as you scroll (site.js) */
.hero .down{position:absolute;left:50%;bottom:calc(64*var(--u));z-index:6;width:max(28px,calc(36*var(--u)));height:max(28px,calc(36*var(--u)));margin-left:calc(max(28px,calc(36*var(--u)))/-2);color:var(--ink);display:grid;place-items:center}
.hero .down svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;animation:down-bob 2.4s cubic-bezier(.45,0,.55,1) infinite}
.hero .down:hover svg{animation-play-state:paused}
.hero .down span{position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);white-space:nowrap;line-height:1}   /* the word sits above the arrow and stays still while the arrow bobs */
@keyframes down-bob{0%,100%{transform:translateY(-12%)}50%{transform:translateY(12%)}}

/* ---------- content ---------- */
/* everything after the hero is one sheet that slides up over it */
.content{position:relative;z-index:1;margin-top:0;background:var(--bg);border-top:1px solid var(--rule);overflow:clip}   /* its glows stay inside it (clip, not hidden: the sticky bar inside still sticks) */
nav.bar{--n:4;position:sticky;top:env(safe-area-inset-top,0px);z-index:20;height:calc(42*var(--u));min-height:34px;margin-left:calc((13 - 2*var(--n))*142.3333*var(--u));width:calc((1728 - (13 - 2*var(--n))*142.3333)*var(--u));background:var(--bg);display:flex;align-items:center;justify-content:space-between;padding:0 calc(20*var(--u))}
/* n items span 2n−1 grid columns, ending on the grid's right edge: the first item's text starts on a column (column 13−2n; 142.33 = column + gutter) */
nav.bar:has(> a:nth-child(2):last-child){--n:2}
nav.bar:has(> a:nth-child(3):last-child){--n:3}
nav.bar:has(> a:nth-child(5):last-child){--n:5}
nav.bar:has(> a:nth-child(6):last-child){--n:6}
/* menu items: every item is padded out like the active tab (margin cancels it, so nothing moves) and clips its own fill.
   --sp opens the letters either side of the "o"; the item's margin gives the same amount back, so the other items never shift */
@property --sp{syntax:"<length>";inherits:true;initial-value:0px}
nav.bar a{--pad:calc(20*var(--u));--sp:0px;position:relative;isolation:isolate;overflow:hidden;align-self:stretch;display:flex;align-items:center;padding:0 var(--pad);margin:0 calc(-1*var(--pad) - var(--sp));color:var(--black);text-decoration:none;transition:--sp .22s cubic-bezier(.4,0,.2,1)}
nav.bar a:hover,nav.bar a:focus-visible,nav.bar a.go,nav.bar a[aria-current]{--sp:.14em;transition-delay:.08s}
/* the "o" fades out first, then the letters part and the yellow dot grows in its place; leaving runs it backwards */
nav.bar .o{position:relative;margin:0 var(--sp);transition:color .12s .2s}
nav.bar a:hover .o,nav.bar a:focus-visible .o,nav.bar a.go .o,nav.bar a[aria-current] .o{color:transparent;transition-delay:0s}
/* a click grows the dot until it fills the item, the active page keeps it grown */
nav.bar .o::before{content:"";position:absolute;z-index:-1;left:50%;top:50%;width:.6em;height:.6em;margin:-.26em 0 0 -.3em;border-radius:50%;background:var(--yellow);transform:scale(0);transition:transform .2s cubic-bezier(0,0,.58,1)}
nav.bar a:hover .o::before,nav.bar a:focus-visible .o::before{transform:scale(1);transition-delay:.08s}
nav.bar a.go .o::before,nav.bar a[aria-current] .o::before{transform:scale(24)}
nav.bar a.go .o::before{transition:transform .38s cubic-bezier(.4,0,.2,1)}
/* active page: its "o" becomes the ✳ from the intro; the o stays in the text for screen readers and width */
nav.bar .o::after{content:"";position:absolute;left:50%;top:50%;width:.7em;height:.7em;margin-top:-.35em;transform:translateX(-50%) scale(.4);opacity:0;background:var(--black);-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat;transition:opacity .2s,transform .2s cubic-bezier(0,0,.58,1)}
nav.bar a.go .o::after,nav.bar a[aria-current] .o::after{opacity:1;transform:translateX(-50%)}
nav.bar a.go .o::after{transition-delay:.12s}
/* the intro runs a screen tall from its text, so with the text at the top of the screen the projects just peek in (140 units) below */
.intro{position:relative;height:max(calc(800*var(--u)),calc(100vh + (18 - 140)*var(--u)));height:max(calc(800*var(--u)),calc(100svh + (18 - 140)*var(--u)));margin-top:calc(-42*var(--u))}
.intro p{position:absolute;left:calc(20*var(--u));top:calc(18*var(--u));width:calc(834*var(--u));color:var(--black)}   /* on the grid: from the first column, 6 columns wide */
.star{display:inline-block;width:.7em;height:.7em;margin:0 .05em;background:currentColor;-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat}
/* sits at the foot of the intro, its bottom edge level with the bottom of the Projects title's yellow square */
.pill{position:absolute;left:calc(1189*var(--u));top:calc(100% - (14.6 + 325)*var(--u));width:calc(517*var(--u));height:calc(325*var(--u));border-radius:calc(60*var(--u));background:var(--yellow);color:var(--reel-ink);border:0;font-family:inherit;cursor:pointer;overflow:hidden;padding:0;display:grid;place-items:center}
.pill span{position:relative;z-index:1}
/* on hover a ✳ (the site's star) grows in before the label, making room for itself */
.pill span::before{content:"";display:inline-block;width:0;height:.7em;margin-right:0;background:currentColor;-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat;opacity:0;transform:scale(.4);transition:width .35s cubic-bezier(.22,1,.36,1),margin .35s cubic-bezier(.22,1,.36,1),opacity .2s,transform .35s cubic-bezier(.22,1,.36,1)}
.pill:hover span::before,.pill:focus-visible span::before{width:.7em;margin-right:.3em;opacity:1;transform:scale(1)}

.work{scroll-margin-top:calc(42*var(--u));position:relative;isolation:isolate;height:calc(var(--work-h,4733)*var(--u))}   /* ends where the free-time panel ends, so the sign-off follows straight on; --work-h comes from home.md's rows */
/* last screen: exactly one viewport tall, so at the bottom of the page the line sits in the top-left corner */
.endscreen{position:relative;height:100vh;height:100svh;min-height:420px;color:var(--black)}
.endscreen .foot{position:absolute;left:calc(20.2*var(--u));top:calc(18*var(--u));width:calc(529*var(--u))}
.endscreen .ephoto{position:absolute;left:calc(20.2*var(--u));bottom:calc(34*var(--u));width:calc(299*var(--u))}
.endscreen .ephoto img{width:100%;height:auto}
.endscreen .sign{position:absolute;right:calc(21.5*var(--u));bottom:calc(34*var(--u));width:calc(547.2*var(--u));margin:0}
/* captions under the work images: yellow dot, then name / category / year 20px apart, from the image's left edge, 13px below it */
.cap{display:flex;align-items:center;gap:calc(20*var(--u));white-space:nowrap}
.dot{width:calc(8*var(--u));height:calc(8*var(--u));min-width:5px;min-height:5px;border-radius:50%;background:var(--dot,var(--yellow));transition:transform .25s}
.cap .nm{transition:text-decoration-color .2s;text-decoration:underline;text-decoration-color:transparent;text-underline-offset:.2em}
.proj{cursor:pointer}
.work.row-hot{cursor:pointer}   /* the whole lit row is clickable */
/* row hover: the pictures lift a touch off a yellow card that stays put; the row's main (biggest) picture also tilts */
.proj{--tilt:-1.2deg}   /* yellow card hidden for now: add background:var(--yellow) back to show it */
.proj.tilt-r{--tilt:1.2deg}
.proj img{display:block;transition:transform .45s cubic-bezier(.22,1,.36,1),border-radius .45s cubic-bezier(.22,1,.36,1)}
.proj.lift{z-index:2}
.proj.lift img,.proj.lift video,.proj.lift canvas,.proj.lift .wvid{transform:translateY(calc(-10*var(--u)))}
.proj.main.lift img,.proj.main.lift video,.proj.main.lift canvas,.proj.main.lift .wvid{transform:translateY(calc(-10*var(--u))) rotate(var(--tilt)) scale(.98)}
.abs.img.proj[data-video]{overflow:visible}   /* a loop over its still (fomo's small one) moves with it instead of being cropped */
.abs.img.proj video{transition:opacity .4s,transform .45s cubic-bezier(.22,1,.36,1),border-radius .45s cubic-bezier(.22,1,.36,1)}
.proj.bare{background:none}   /* transparent cut-outs (the Klarity hand) lift with the row but have no card behind them */
.small-img img{transition:transform .45s cubic-bezier(.22,1,.36,1),border-radius .45s cubic-bezier(.22,1,.36,1)}
.small-img.lift img,.small-img.lift video,.small-img.lift canvas,.small-img.lift .wvid{transform:translateY(calc(-10*var(--u)))}
/* Wistia loops sit over their still in an iframe: it moves with the still and isn't cropped by its box */
.proj .wvid,.small-img .wvid{transition:opacity .4s,transform .45s cubic-bezier(.22,1,.36,1),border-radius .45s cubic-bezier(.22,1,.36,1)}
/* a lit row's pictures round their corners a little (canvas: a playing video frozen into the page-change copy, see float() in site.js) */
.lift img,.lift video,.lift canvas,.lift .wvid{border-radius:calc(12*var(--u))}
.proj[data-wistia],.small-img[data-wistia]{overflow:visible}
@media (prefers-reduced-motion:reduce){.proj .wvid,.small-img .wvid,.proj.lift .wvid,.proj.main.lift .wvid,.small-img.lift .wvid,.proj img,.proj.lift img,.proj.main.lift img,.abs.img.proj video,.proj.lift video,.proj.main.lift video,.small-img img,.small-img.lift img{transition:none;transform:none}}
.hot .dot{transform:scale(1.8)}
.hot .nm{text-decoration-color:currentColor}
.btn{position:absolute;display:inline-flex;align-items:center;gap:calc(9*var(--u));background:none;border:0;padding:0;font-family:inherit;color:var(--black);cursor:pointer;text-align:left}
.btn i{position:absolute;left:0;top:50%;height:calc(40*var(--u));width:calc(40*var(--u));transform:translateY(-50%) translateZ(0);will-change:width;background:var(--yellow);border-radius:calc(10*var(--u));transition:width .2s cubic-bezier(0,0,.58,1)}
.btn b{font-weight:400;position:relative;padding-left:calc(49*var(--u));padding-right:calc(12*var(--u))}
.btn:hover i,.btn:focus-visible i{width:100%}
/* hover state from the Figma button component: fill runs to the end of the label, the ✳ fades into the centre of the square (200ms, ease-out); the same ✳ SVG as the intro */
.btn i::before{content:"";position:absolute;left:0;top:0;width:calc(40*var(--u));height:calc(40*var(--u));background:var(--star-img,none) center/auto calc(40*var(--star-ratio,.7)*var(--u)) no-repeat;opacity:0;transform:translateZ(0) scale(.6);will-change:transform,opacity;backface-visibility:hidden;transition:opacity .2s cubic-bezier(0,0,.58,1),transform .2s cubic-bezier(0,0,.58,1)}
.btn:hover i::before,.btn:focus-visible i::before{opacity:1;transform:translateZ(0) scale(1)}
.btn.small{height:calc(40*var(--u))}
/* a lone square in the hero that rolls out into the contact button: the inline button at the project-list title size;
   the label is clipped to the square until hover (clip-path, so no letter can peek past it), and the fill follows it */
/* three of them: --rl (left) and --ry (from the middle, in 1728-frame units) place the others; without them it sits where Contact always has */
.hero .roll{position:absolute;left:var(--rl,calc(50% - 40*var(--u)));top:calc(50% + var(--ry,200)*var(--u));z-index:6;font-size:max(17px,calc(24*var(--u)));line-height:1.2}
/* it pops in and rises on scroll like the black squares (site.js) */
.hero .roll{transform:scale(0);transform-origin:.5em 50%;transition:transform .25s cubic-bezier(.2,0,0,1)}
.hero .roll.on{transform:none}
.roll i{transition:none}
.hero .roll i::before{opacity:1;transform:scale(1)}   /* the hero squares show their ✳ from the start, not only on hover */
.roll b{display:inline-block;box-sizing:border-box;max-width:1em;overflow:hidden;clip-path:inset(0);white-space:nowrap;vertical-align:top;transition:max-width .25s cubic-bezier(0,0,.58,1)}
.roll:hover b,.roll:focus-visible b{max-width:calc(1.225em + 5em)}
/* .btn inside running text: same yellow square that fills in on hover, sized in em so it follows the sentence */
.nowrap{white-space:nowrap}
.ibtn{position:relative;display:inline-block;color:inherit;text-decoration:none;white-space:nowrap}
.ibtn i{position:absolute;left:0;top:50%;width:1em;height:1em;transform:translateY(-50%) translateZ(0);background:var(--yellow);border-radius:.25em;transition:width .2s cubic-bezier(0,0,.58,1)}
.ibtn i::before{content:"";position:absolute;left:0;top:0;width:1em;height:1em;background:var(--star-img,none) center/auto calc(1em*var(--star-ratio,.7)) no-repeat;opacity:0;transform:translateZ(0) scale(.6);will-change:transform,opacity;backface-visibility:hidden;transition:opacity .2s cubic-bezier(0,0,.58,1),transform .2s cubic-bezier(0,0,.58,1)}   /* kept on its own layer, like .btn's: otherwise it snaps to the pixel grid (a small jump right) when the scale-up ends */
.ibtn b{position:relative;font-weight:400;padding-left:1.225em}
.ibtn .wi{text-decoration:none}
/* .hot: lit by hovering anywhere in its row (data-row) */
.ibtn:hover i,.ibtn:focus-visible i,.ibtn.hot i{width:calc(100% + .1em)}
.ibtn:hover i::before,.ibtn:focus-visible i::before,.ibtn.hot i::before{opacity:1;transform:translateZ(0) scale(1)}
.panel{height:calc(var(--h)*var(--u));background:var(--panel);opacity:.3;border-radius:calc(20*var(--u))}
/* trial: a row's smaller picture (.minor) sits under the white cursor glow (.pglow, z-index -1); the panel goes under both so the
   pictures inside it aren't tinted by it. Delete these two lines to put them back on top */
.free{display:contents}   /* the free-time section's box: only a box on phones (below); on desktop its parts are placed in .work as before */
.work .panel{z-index:-4}
.work .minor,.work .minor.lift{z-index:-2}
/* trial: the glow behind a lit row's pictures (site.js glowRow): above the panel, under everything else; desktop only */
.row-glow{position:absolute;z-index:-3;pointer-events:none;border-radius:50%;opacity:0;filter:blur(calc(40*var(--u)));
  background:radial-gradient(closest-side,rgba(244,255,157,.5),rgba(244,255,157,.2) 55%,rgba(244,255,157,0));
  transition:opacity .5s ease,left .6s cubic-bezier(.22,1,.36,1),top .6s cubic-bezier(.22,1,.36,1),width .6s cubic-bezier(.22,1,.36,1),height .6s cubic-bezier(.22,1,.36,1)}
.row-glow.on{opacity:1}
@media (max-width:899px),(prefers-reduced-motion:reduce){.row-glow{display:none}}
.stack{display:flex;flex-direction:column;align-items:flex-start;gap:calc(44*var(--u))}
.stack .btn{position:relative;left:auto!important;top:auto!important}
.ttl{position:absolute;display:flex;align-items:center;margin:0;font-weight:400;color:var(--black)}
.ttl i{position:absolute;left:0;top:50%;height:calc(40*var(--u));width:calc(40*var(--u));transform:translateY(-50%);background:var(--yellow);border-radius:calc(10*var(--u))}
.ttl b{font-weight:400;position:relative;padding-left:calc(49*var(--u))}
.ttl-star .star{position:absolute;left:calc(4*var(--u));top:50%;width:calc(32*var(--u));height:calc(32*var(--u));margin:0;transform:translateY(-50%)}   /* a title that isn't a link: a star where the square was */
.content .glow{width:calc(var(--d)*3*var(--u));height:calc(var(--d)*3*var(--u));left:calc((var(--x) - var(--d))*var(--u));top:calc((var(--y) - var(--d))*var(--u));animation:breathe 7s ease-in-out infinite alternate;animation-delay:var(--dl,0s)}
@keyframes breathe{from{transform:translate(0,0) scale(.92)}to{transform:translate(calc(18*var(--u)),calc(-14*var(--u))) scale(1.06)}}


/* scroll reveal: each line of text fades up into place, unclipped */
.w{display:inline-block}
.wi{display:inline-block;will-change:transform,opacity}
.rv-on .rv .wi{opacity:0;transform:translateY(40%)}
.rv-on .rv .ibtn > i{opacity:0;translate:0 40%}   /* the yellow box waits for its line too (setLine) */
.rv-on .rvb{opacity:0;transform:translateY(10px);transition:opacity .2s,transform .2s}
.rv-on .rvb.in{opacity:1;transform:none;transition:opacity .4s,transform .6s cubic-bezier(.22,1,.36,1)}   /* played on trigger, not tied to the scroll */
/* project sentences: the second half (.more) keeps its space but waits, then rolls out line by line while the row is hovered; touch screens just show it */
@media (hover:hover){
  .more{transition:opacity .25s}
  html:not(.rv-on) .more{opacity:0}
  html:not(.rv-on) .open .more,html:not(.rv-on) :has(> .ibtn:focus-visible) .more{opacity:1}
  .rv-on .more .wi{opacity:0;transform:translateY(40%);transition:opacity .2s,transform .2s}
  .rv-on .open .more .wi,.rv-on :has(> .ibtn:focus-visible) .more .wi{opacity:1;transform:none;transition:opacity .35s calc(var(--d,0ms) + var(--i,0)*90ms),transform .5s cubic-bezier(.22,1,.36,1) calc(var(--d,0ms) + var(--i,0)*90ms)}   /* --d: wait for the rest of the sentence's reveal (finishReveal) */
}


/* layout grid overlay: press G. 12 columns, 20px margin, 20px gutter at 1728 */

/* reel overlay */
.reel{position:fixed;inset:0;z-index:50;color:var(--pill-ink);display:grid;place-items:center}
/* while the reel is open a dark layer covers the page, fading in and out (@starting-style: the reel has only just appeared) */
.reel::before{content:"";position:fixed;inset:0;background:#000;opacity:0;transition:opacity .4s}
.reel-open .reel::before{opacity:.9}
@starting-style{.reel-open .reel::before{opacity:0}}
/* the frame the pill grows into: exactly the video's size, the page stays visible around it */
.reel-box{position:relative;width:min(calc(100vw - 40px),calc((100vh - 120px)*16/9));aspect-ratio:16/9;background:var(--yellow);overflow:hidden;transform-origin:0 0}
.reel .x{position:absolute;right:20px;top:calc(16px + env(safe-area-inset-top,0px));font:inherit;font-size:16px;background:var(--yellow);color:var(--black);border:0;padding:8px 14px;cursor:pointer}
.toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom,0px));transform:translate(-50%,20px);opacity:0;background:var(--black);color:var(--bg);font-size:15px;padding:10px 14px;z-index:60;transition:opacity .25s,transform .25s;pointer-events:none;max-width:calc(100vw - 32px)}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* page change: the yellow sheet (see go() in site.js). It waits above the page, hidden, until a link sends it up */
html::after{content:"";position:fixed;inset:0;z-index:1000;background:var(--yellow);transform:translateY(-100%);visibility:hidden;pointer-events:none}
html.wipe-out::after,html.wipe-in::after{transform:translateY(0);visibility:visible;pointer-events:auto}
html.wipe-out::after{transition:transform .48s cubic-bezier(.7,0,.3,1)}
html.wipe-in.wipe-reveal::after{transform:translateY(100%);pointer-events:none;transition:transform .6s cubic-bezier(.7,0,.3,1)}

/* the clicked thing, floated above the sheet while it passes (see float() in site.js); it fades out on the yellow, then the page changes */
.float{position:fixed;z-index:1001;pointer-events:none;transition:opacity .32s cubic-bezier(.4,0,.2,1)}
.float.out{opacity:0}
/* a floated menu item starts from its hover state: letters already apart, o already gone */
.float nav.bar a{--sp:.14em;transition:none}
.float nav.bar .o{color:transparent;transition:none}
.float nav.bar .o::before{transform:scale(1)}
.float nav.bar a.go .o::before{transform:scale(24)}
.btn.hot i{width:100%}
.btn.hot i::before{opacity:1;transform:translateZ(0) scale(1)}

/* ---------- phone ---------- */
@media (max-width:899px){
  .t40{font-size:26px;line-height:1.2}
  .t20{font-size:16px}.t16{font-size:13px}
  .hero{height:auto;min-height:100vh;min-height:100svh;padding-inline:16px;padding-block:18px 28px;display:flex;flex-direction:column;justify-content:center}
  .hero .name{position:relative;top:auto;left:auto;right:auto}
  .hero .names{display:flex;justify-content:center;gap:.3em;position:relative;margin-bottom:14px;z-index:2;pointer-events:none}   /* the name reads as one, centred just above the title */
  .hero .n-left::after{content:'';display:inline-block;width:.7em;height:.7em;margin:0 .05em 0 .3em;background:currentColor;-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat}   /* jakub ✳ svehla: the intro's star */
  .hero .n-mid{order:3;text-align:center}
  .content{margin-top:0}
  .hero .down{bottom:32px}
  nav.bar{margin-left:0;width:100%;height:46px;padding:0 16px}
  nav.bar a{--pad:12px}
  .intro,.work{height:auto;margin-top:0;padding:24px 16px 56px;display:flex;flex-direction:column;gap:14px}
  .intro p,.pill,.abs{position:relative;left:auto;top:auto;width:100%}
  .pill{height:auto;aspect-ratio:740/433;margin-top:18px}
  .abs.img{height:auto}
  .abs.img img{height:auto;aspect-ratio:var(--w)/var(--h)}
  .abs.img[role="img"]{aspect-ratio:var(--w)/var(--h)}   /* a video without a still (role=img) has no picture to size it: its box keeps the design's shape */
  .work .gap{height:34px}
  .work{padding-bottom:0}
  .work > .gap:last-child{display:none}   /* the spacer goes between rows, not after the last section (the sign-off has its own space) */
  .cap{flex-wrap:wrap;gap:4px 12px}
  .cap .yr{margin-left:auto}
  .btn{position:relative;left:auto!important;top:auto!important}
  /* the three buttons keep the desktop's triangle: Projects left, Random right and a little lower, Contact centred below */
  .hero .roll{position:relative;left:auto;top:auto;order:5;align-self:flex-start;margin:18px 0 0 8%}
  .hero .roll+.roll{align-self:flex-end;margin:-.6em 8% 0 0}
  .hero .roll+.roll+.roll{align-self:center;margin:22px 0 0}
  .roll b{max-width:none;clip-path:inset(0);transition:clip-path .25s cubic-bezier(0,0,.58,1)}   /* no hover on phones: the button is simply out at the top… */
  .hero.furled .roll b{clip-path:inset(0 calc(100% - 1em) 0 0)}
  .hero .roll i{transition:width .25s cubic-bezier(0,0,.58,1)}
  .hero.furled .roll i{width:1em}   /* the yellow box draws back into the star square with the label */   /* …and furls into its star once you scroll (site.js): clipped, not narrowed, so the button keeps its width and the star stays put */
  .btn i{height:30px;width:30px;border-radius:7px}
  .btn i::before{width:30px;height:30px;background-size:auto calc(29px*var(--star-ratio,.7))}
  .btn b{padding-left:40px}
  .btn.small{height:30px}
  .work .panel{display:none}
  .work .free{display:flex;flex-direction:column;gap:14px;padding:20px 16px;background:var(--free-bg,color-mix(in srgb,var(--panel) 30%,transparent));border-radius:16px}   /* the free-time section's grey panel on phones */
    .ttl{position:relative;left:auto!important;top:auto!important;height:auto!important;margin-top:28px}
  .ttl i{height:30px;width:30px;border-radius:7px}
  .ttl b{padding-left:40px}
  .ttl-star .star{left:3px;width:24px;height:24px}
  .small-img:not(.proj){width:60% !important}
  .work .proj:not(.main){display:none}   /* a project row shows only its main picture on phones */   /* the free-time one; a row's small picture (.proj) fills the width like the rest */
  .content .glow{display:none}
  .sign{text-align:right}
  .endscreen{display:flex;flex-direction:column;justify-content:space-between;gap:20px;padding:18px 16px 28px}   /* the sign-off starts 18 under the free-time panel, as on desktop */
  .endscreen .foot,.endscreen .ephoto,.endscreen .sign{position:static;width:auto}
  .endscreen .ephoto{width:60%;margin-top:auto}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .content .glow,.hero .down svg{animation:none}
  nav.bar a,nav.bar .o,nav.bar .o::before,nav.bar .o::after,.btn i,.ibtn i,.toast{transition:none}
}

/* ---------- public-web basics ---------- */
/* only Apfel Grotezk Regular ships: never let the browser fake a bold */
b,strong,h1,h2,h3,h4,th{font-weight:400}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:fixed;left:12px;top:-60px;z-index:100;background:var(--yellow);color:var(--black);padding:10px 14px;text-decoration:none;transition:top .15s}
.skip:focus-visible{top:12px}   /* keyboard only: a click or a script moving focus doesn't show it */
a.btn,a.pill{text-decoration:none}
.reel .reel-vid{position:absolute;inset:0;width:100%;height:100%;border:0;background:#000;opacity:0;transition:opacity .4s}
.reel .reel-vid.on{opacity:1}
.reel .reel-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}   /* a case study's poster, under the player until it loads */
.case ~ .reel .reel-box{background:#000}
/* a case study's film: its close sits in the middle, clear of the page's Close; that one stays away until the film has shrunk back */
.case ~ .reel .x{right:auto;left:50%;translate:-50% 0}
.reel-open .case ~ .reel .x{animation:reel-x .4s .35s both}   /* fades in as the frame finishes growing */
@keyframes reel-x{from{opacity:0}}
/* its "o" turns into the star on hover, as in the bar's Close */
.reel .x{--sp:0px;transition:opacity .2s,--sp .22s cubic-bezier(.4,0,.2,1)}
.reel .x:hover,.reel .x:focus-visible{--sp:.14em;transition-delay:0s,.08s}
.reel .x .o{position:relative;margin:0 var(--sp);transition:color .12s .2s}
.reel .x:hover .o,.reel .x:focus-visible .o{color:transparent;transition-delay:0s}
.reel .x .o::after{content:"";position:absolute;left:50%;top:50%;width:.7em;height:.7em;margin-top:-.35em;transform:translateX(-50%) scale(.4);opacity:0;background:var(--black);-webkit-mask:var(--star-img) center/contain no-repeat;mask:var(--star-img) center/contain no-repeat;transition:opacity .2s,transform .2s cubic-bezier(0,0,.58,1)}
.reel .x:hover .o::after,.reel .x:focus-visible .o::after{opacity:1;transform:translateX(-50%)}
html:not(.reel-open) .reel .x{opacity:0;pointer-events:none}
.case .closebar{transition:opacity .4s}
.reel-on .case .closebar{opacity:0}

/* touch screens can't hover: buttons sit in their hover state from the start, so they read as buttons */
@media (hover:none){
  .btn i,.ibtn i{width:100%}
  .ibtn i{width:calc(100% + .1em)}
  .btn i::before{opacity:1;transform:translateZ(0) scale(1)}
  .ibtn i::before{opacity:1;transform:translateZ(0) scale(1)}
}


/* ================= site: views ================= */
.view{position:relative}
.page{min-height:100vh;min-height:100svh;background:var(--bg)}
.canvas{position:relative;height:calc(var(--h)*var(--u))}
.page .glow{width:calc(var(--d)*3*var(--u));height:calc(var(--d)*3*var(--u));left:calc((var(--x) - var(--d))*var(--u));top:calc((var(--y) - var(--d))*var(--u));animation:breathe 7s ease-in-out infinite alternate;animation-delay:var(--dl,0s)}
.page .abs.img img{border-radius:calc(var(--r,0)*var(--u))}
.cph-clock{font-variant-numeric:tabular-nums}
.about{height:auto}
.about .ab-note{color:var(--ink);opacity:.6;line-height:1.2;margin:5px calc(20*var(--u)) 5px 0;text-align:right}   /* the small line under the pictures (note: in about.md), 5px above and below */
.about .ab-photos img{display:block}
/* the first screen: title and intro (with its links) top left, the drawing in the free space on the right, the clock (bottom right) just
   above the photos. Like the homepage's first projects, the photos peek in 140 units from the bottom of the
   screen (never higher than 799); a longer intro makes the first screen taller and push them down */
@media (min-width:900px){
  .about{--fold:max(calc(799*var(--u)),calc(100vh - 140*var(--u)));--fold:max(calc(799*var(--u)),calc(100svh - 140*var(--u)))}
  .about .ab-top{display:grid;grid-template-columns:calc(711.7*var(--u)) 1fr;grid-template-rows:auto 1fr auto;min-height:var(--fold);padding:calc(20*var(--u)) calc(20*var(--u)) 0}
  .about [style*="--w"]{width:calc(var(--w)*var(--u))}
  .about .ab-text{grid-area:1/1/4/2;margin-bottom:calc(20*var(--u))}   /* down the whole left side: a long intro's last line sits on the clock's line, 20 above the photos */
  .about .ab-text p{margin-top:calc(31*var(--u))}   /* the intro starts 100 down, under the title */
  .about .scragg{grid-area:1/2/3/3;place-self:center;width:calc(709*var(--u));margin:calc(22*var(--u)) 0 calc(49*var(--u))}
  .about .ab-clock{grid-area:3/2;justify-self:end;align-self:end;margin-bottom:calc(20*var(--u));max-width:calc(var(--mw)*var(--u))}   /* lines above the clock's wrap at the intro's width */
  .about .ab-photos{display:flex;height:calc(645*var(--u))}
  .about .ab-photos .bleed:first-child{flex:0 0 calc(574*var(--u))}
  .about .ab-photos .bleed:last-child{flex:1}
}
.scragg svg{display:block;width:100%;height:auto;color:var(--black)}
.bleed img{width:100%;height:100%;object-fit:cover}

/* projects list — the projects-row component: image grows one column to the left, description slides up (200ms ease-out) */
.pfilter button{font:inherit;background:none;border:0;padding:0;color:var(--ink);cursor:pointer;text-underline-offset:.2em}
.pfilter button[aria-pressed="true"]{text-decoration:underline}
.pfilter button:hover{text-decoration:underline}
.plist{position:relative;isolation:isolate;display:flex;flex-direction:column;gap:calc(20*var(--u))}
/* test: a big soft yellow glow behind the rows; site.js eases it after the cursor */
.pglow{position:absolute;z-index:-1;left:0;top:0;width:calc(1200*var(--u));height:calc(1200*var(--u));border-radius:50%;pointer-events:none;opacity:.45;filter:blur(calc(60*var(--u)));will-change:transform;
  background:radial-gradient(circle,rgba(244,255,157,1) 0,rgba(244,255,157,.6) 25%,rgba(244,255,157,0) 65%)}
.pglow.white{opacity:.9;background:radial-gradient(circle,#fff 0,rgba(255,255,255,.6) 25%,rgba(255,255,255,0) 65%)}   /* the homepage one: white on the off-white page */
.prow{position:relative;display:block;height:calc(430*var(--u));color:var(--ink);text-decoration:none}
.prow[hidden]{display:none}
/* projects-row-2: resting = one thumb, the other two wait off the right edge; hover fans all three in */
.prow-img{position:absolute;inset:0;overflow:hidden;pointer-events:none}
.pc{position:absolute;left:calc((var(--x) - var(--w)/2)*var(--u));top:calc((var(--y) - var(--h)/2)*var(--u));width:calc(var(--w)*var(--u));height:calc(var(--h)*var(--u));transform:rotate(calc(var(--r)*1deg));object-fit:cover;transition:left .45s var(--fan),top .45s var(--fan),width .45s var(--fan),height .45s var(--fan),transform .45s var(--fan);--fan:cubic-bezier(.22,1,.36,1)}
.pc1{--x:1349;--y:216.8;--w:750;--h:426.5;--r:0}
.pc2{--x:2020.3;--y:235;--w:552.2;--h:310.9;--r:-8.61;transition-delay:.03s}
.pc3{--x:2598.6;--y:239.5;--w:520.2;--h:292.9;--r:10.3;transition-delay:.06s}
.prow:hover .pc1,.prow:focus-visible .pc1,.prow.hot .pc1{--x:1090.1;--y:226.4;--w:540.6;--h:296;--r:11.33}
.prow:hover .pc2,.prow:focus-visible .pc2,.prow.hot .pc2{--x:1440.3;--y:142.6}
.prow:hover .pc3,.prow:focus-visible .pc3,.prow.hot .pc3{--x:1724.4;--y:243.1;--w:510.2;--h:287.2}
.prow-txt{position:absolute;left:calc(20*var(--u));bottom:0;width:calc(549.3*var(--u));display:flex;flex-direction:column}
.pm{font-size:max(11px,calc(10*var(--u)));line-height:1.4;margin-bottom:calc(8*var(--u))}
.pn{font-size:max(17px,calc(24*var(--u)));line-height:1.2}
.pd{font-size:max(15px,calc(24*var(--u)));line-height:1.2;max-height:0;opacity:0;overflow:hidden;transition:max-height .45s cubic-bezier(.22,1,.36,1),opacity .3s,margin .45s cubic-bezier(.22,1,.36,1)}
/* with the reveal on, each line of the description fades up in turn (the homepage .more beat: 90ms a line) */
@media (hover:hover) and (min-width:900px){
  .rv-on .pd .wi{opacity:0;transform:translateY(40%);transition:opacity .2s,transform .2s}
  .rv-on .prow:hover .pd .wi,.rv-on .prow:focus-visible .pd .wi,.rv-on .prow.hot .pd .wi{opacity:1;transform:none;transition:opacity .35s calc(var(--i,0)*90ms),transform .5s cubic-bezier(.22,1,.36,1) calc(var(--i,0)*90ms)}
}
.pd.todo{color:var(--grey-ink);font-style:italic}
/* the title is the inline yellow button; hovering the row fills it */
/* the fill and star settle with the same soft ease-out as the pictures and description */
.pn .ibtn i{transition:width .45s cubic-bezier(.22,1,.36,1)}
.pn .ibtn i::before{transition:opacity .45s cubic-bezier(.22,1,.36,1),transform .45s cubic-bezier(.22,1,.36,1)}
.prow:hover .pn .ibtn i,.prow:focus-visible .pn .ibtn i,.prow.hot .pn .ibtn i{width:calc(100% + .1em)}
.prow:hover .pn .ibtn i::before,.prow:focus-visible .pn .ibtn i::before,.prow.hot .pn .ibtn i::before{opacity:1;transform:translateZ(0) scale(1)}
.prow:hover .pd,.prow:focus-visible .pd,.prow.hot .pd{max-height:6em;opacity:1;margin-top:calc(6*var(--u))}

/* case study */
.case{background:var(--black);padding-bottom:calc(54*var(--u))}
/* case studies: "Close" is a menu item (nav.bar styles) in its own bar, flush top-right, filled like the current page's tab */
nav.bar.closebar{margin-left:auto;width:max-content;background:none;justify-content:flex-end}
nav.bar.closebar a{background:var(--yellow);margin:0 calc(-1*var(--pad)) 0 calc(-1*var(--pad) - 2*var(--sp))}   /* stays flush right; parting letters grow it leftward */
nav.bar.closebar a:hover .o::after,nav.bar.closebar a:focus-visible .o::after{opacity:1;transform:translateX(-50%)}
.credits{line-height:1.2}

/* random: every piece opens big */
.loose{padding:0;border:0;background:none;cursor:zoom-in}
.loose img{width:100%;height:100%;object-fit:cover}
/* hover: like the homepage's pictures (tilt and shrink a touch), lighter; every other one tilts the other way */
.loose{--tilt:-.6deg;transition:transform .45s cubic-bezier(.22,1,.36,1)}
.loose:nth-of-type(even){--tilt:.6deg}
.loose:hover,.loose:focus-visible{transform:rotate(var(--tilt)) scale(.985)}
@media (prefers-reduced-motion:reduce){.loose{transition:none}.loose:hover,.loose:focus-visible{transform:none}}
/* random: the Loosies pieces scattered on the 12-column grid */
.page .abs.img.loose{overflow:hidden}
.loose video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .4s;pointer-events:none}
.loose video.on{opacity:1}
.lightbox{position:fixed;inset:0;z-index:55;background:rgba(20,20,20,.92);display:grid;place-items:center;padding:calc(56px + env(safe-area-inset-top,0px)) 16px calc(24px + env(safe-area-inset-bottom,0px))}
.lightbox img{max-width:100%;max-height:100%;object-fit:contain}
.lightbox .x{position:absolute;right:20px;top:calc(16px + env(safe-area-inset-top,0px));font-family:inherit;background:var(--yellow);color:var(--black);border:0;padding:8px 14px;cursor:pointer}

@media (max-width:899px){
  .canvas{height:auto;padding:24px 16px 40px;display:flex;flex-direction:column;gap:16px;margin-top:0!important}
  .canvas .abs{position:relative;left:auto;top:auto;width:100%}
  .canvas .abs.img{height:auto}
  .page .glow{display:none}
  .pfilter{margin-top:8px}
  .plist{gap:36px;padding:0 16px}
  .pglow{display:none}
  .prow{height:auto;display:flex;flex-direction:column-reverse;gap:10px}
  .prow-img,.prow-txt{position:relative;right:auto;left:auto;width:100%}
  .prow-img{aspect-ratio:750/427;height:auto;inset:auto}
  .pc1,.prow:hover .pc1{position:static;width:100%;height:100%;transform:none}
  .pc2,.pc3{display:none}
  .pd,.prow:hover .pd,.prow:focus-visible .pd{max-height:none;opacity:1;margin-top:4px}   /* blurbs are always shown here; hover mustn't resize the row */
  .collage{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:start}
  .collage .abs.img{width:100%;aspect-ratio:var(--w)/var(--h)}
  .bleed{width:100%}
  .about .ab-top,.about .ab-text,.about .ab-photos{display:contents}   /* one column: everything in the page's own order and gaps */
  .about .ab-photos img{height:auto}
  .about .scragg{margin:32px 0}   /* the drawing gets room above and below on phones */
  .about{padding-bottom:16px}   /* the last photo (or the note under it) sits as far from the bottom as from the sides */
  .about .ab-note{margin:-11px 0 0}   /* 5px under the photo (the column's gap is 16) */
  .about:has(.ab-note){padding-bottom:5px}
  nav.bar.closebar{width:max-content;margin-left:auto;padding:0 12px}   /* = the item padding, so the tab sits flush in the corner */
}
@media (prefers-reduced-motion:reduce){
  .pc,.pd,.loose img,.pn .ibtn i,.pn .ibtn i::before{transition:none}
  .page .glow{animation:none}
}

/* Wistia loops: an iframe laid over the still, which stays underneath as the poster */
[data-wistia]{overflow:hidden}
.wvid{position:absolute;inset:0;width:100%;height:100%;border:0;pointer-events:none;opacity:0;transition:opacity .4s}
.wvid.on{opacity:1}
.lightbox .lbvid{width:min(100%,calc((100vh - 120px)*16/9));aspect-ratio:16/9;border:0;background:#000}
.lightbox video.lbvid{width:auto;max-width:100%;max-height:100%;aspect-ratio:auto;background:none}

/* ================= Legend case study (Figma auto layout → flow layout in design px) ================= */
.lg{background:var(--black);color:var(--white);padding-bottom:calc(140*var(--u))}
.lg figure{margin:0}
.lg-m{position:relative;width:100%;aspect-ratio:var(--ar);overflow:hidden;background:#111}
.lg-m img,.lg-m video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.lg-m video{opacity:0;transition:opacity .4s}.lg-m video.on{opacity:1}
.lg-hero{position:relative;margin-top:calc(-1*max(34px,42*var(--u)))}   /* pulled up by the bar's height (its min-height included), so it starts under the Close tab */
.lg-hero > .lg-m{max-height:100vh;max-height:100svh}   /* the header never runs past the first screen: the picture crops instead */
.lg-hero .lg-overlay{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;z-index:1}
.lg-info{background:var(--white);color:var(--black);min-height:calc(509*var(--u));display:grid;grid-template-columns:calc(549.3*var(--u)) 1fr;column-gap:calc(20*var(--u));padding:calc(30*var(--u)) calc(20*var(--u))}
.lg-col{display:flex;flex-direction:column;justify-content:space-between;gap:calc(40*var(--u))}
.lg-info h1,.lg-info p,.lg p,.lg h2{margin:0;font-weight:400}
.lg p.t40{max-width:calc(1119.3*var(--u))}
.lg .star{line-height:1}  /* the symbol font's tall line box would push the first line down */  /* case-study text never runs wider than 8 columns, the measure of the intro paragraph */
.lg-info .light{opacity:.6}
.lg-info .credits{line-height:1.2}
.lg-sec,.lg-row{display:flex;gap:calc(20*var(--u));padding:calc(var(--pt,0)*var(--u)) calc(var(--px,20)*var(--u)) calc(var(--pb,0)*var(--u))}
.lg-c4{flex:0 0 calc(549.3*var(--u))}
.lg-c8{flex:1;display:flex;flex-direction:column;gap:calc(40*var(--u))}
.lg-sq{display:flex;align-items:center;gap:calc(9*var(--u))}
.lg-sq i{flex:0 0 auto;width:calc(40*var(--u));height:calc(40*var(--u));border-radius:calc(10*var(--u));background:var(--yellow)}
.lg-spacer{height:calc(306*var(--u))}
.lg-process{padding:calc(50*var(--u)) calc(40*var(--u));display:flex;flex-direction:column;gap:calc(20*var(--u))}
.lg-ptitle{display:flex;flex-direction:column;gap:calc(12*var(--u))}
.lg-dim{opacity:.7}
.lg-prow{display:flex;gap:calc(20*var(--u));align-items:flex-start}
/* the end of a case study: previous and next project, each centred in its half of the page */
.lg-pn{position:relative;display:grid;grid-template-columns:1fr 1fr;margin-top:calc(20*var(--u));background:var(--bg);color:var(--ink);border-top:1px solid var(--rule)}   /* a band in the homepage colours, to the bottom of the page */
.lg-pn::after{content:"";position:absolute;left:50%;top:0;bottom:0;width:1px;background:var(--rule)}   /* the line between the two */
.lg-pn.one{grid-template-columns:1fr}.lg-pn.one::after{display:none}   /* just one link (only two projects) */
.lg:has(> .lg-pn){padding-bottom:0;overflow:clip}   /* clip: the band sliding up from below doesn't make the page longer (sticky bar still sticks) */
.lg-pn{will-change:transform}
.lg-process:has(+ .lg-pn){padding-bottom:0}   /* a page ending on its process section: the same 20 */
.lg-pn-i{justify-self:center;padding:calc(100*var(--u)) 0;display:flex;flex-direction:column;align-items:flex-start;gap:calc(10*var(--u))}   /* the label and button together are centred; the label starts where the yellow square does */
.lg-pn .light{opacity:.6}
.lg-pn .ibtn b{transition:color .2s cubic-bezier(0,0,.58,1)}
.lg-pn .ibtn:hover b,.lg-pn .ibtn:focus-visible b{color:var(--black)}   /* dark on the yellow fill, on dark pages too */
/* Box case study: same building blocks as Legend */
.bx{background:#45403D}
.bx .lg-m{background:#2f2b29}
/* case-study film: "Watch the film" is the homepage .btn, centred on the poster; the player replaces the poster on click */
.cs-watch.btn{position:absolute;z-index:2;left:50%;top:50%;transform:translate(-50%,-50%);color:var(--white);text-decoration:none;transition:color .2s cubic-bezier(0,0,.58,1)}
.cs-watch.btn:hover,.cs-watch.btn:focus-visible{color:var(--black)}
.cs-watch .wi{text-decoration:none}
.cs-film iframe{position:absolute;inset:0;width:100%;height:100%;border:0;z-index:3}
/* text block that sits on the bottom of a 511px band */
.cs-poem{height:calc(511*var(--u));align-items:flex-end}
.bx-credits{display:flex;flex-direction:column;gap:calc(24*var(--u))}
.bx-credits p{margin:0}
.bx-process{padding:calc(160*var(--u)) calc(20*var(--u)) 0}
/* Within case study: white page, ink text, film button centred on the light poster */
.wn{background:var(--white);color:var(--ink)}
.wn .lg-m{background:#FCF4F0}
.wn .cs-watch.btn{color:var(--black)}
/* Klarity Automate case study: white page, ink text; film button in the poster's bottom-left corner with a dark label */
.ka{background:var(--white);color:var(--ink)}
.ka .lg-m{background:#E9ECF7}
.ka .cs-watch.btn{color:#141414}
.ka-purpose p.t40{max-width:calc(834*var(--u))}
/* Markdown case studies (content/projects/): page and picture-tile colours come from the front matter */
.md{background:var(--md-bg)}
.md .lg-m{background:var(--md-tile)}
.lg-m.clear,.md .lg-m.clear{background:none}   /* transparent pictures sit straight on the page colour */
.md-light{color:var(--ink)}
.md-light .cs-watch.btn{color:var(--black)}
/* film_label: light or dark "Watch the film" text, when the hero picture needs the other one */
.md.md-film-dark .cs-watch.btn{color:#141414}
.md.md-film-light .cs-watch.btn{color:var(--white)}
.md.md-film-light .cs-watch.btn:hover,.md.md-film-light .cs-watch.btn:focus-visible{color:var(--black)}
/* film_box: the button sits in a white box, for heroes where plain text gets lost; the yellow square still runs out on hover */
.md.md-film-box .cs-watch.btn{--pad:max(4px,calc(6*var(--u)));--sq:calc(40*var(--u));height:calc(var(--sq) + 2*var(--pad));padding:0 var(--pad);background:var(--white);color:var(--black);border-radius:max(7px,calc(10*var(--u)))}   /* the same corners as the yellow square */
.md.md-film-box .cs-watch.btn i{left:var(--pad)}
.md.md-film-box .cs-watch.btn:hover i,.md.md-film-box .cs-watch.btn:focus-visible i{width:calc(100% - 2*var(--pad))}
.md-row{--pt:20;align-items:flex-start}
.md-text{--pt:120;--pb:100}
/* a picture with text beside it: picture first = half width, text right next to it; text first = 4 columns of text + picture */
.md-end{justify-content:flex-end}  /* a narrower picture on the right */
/* a row whose slots mix pictures, videos and text: equal columns unless a slot has its own width */
.md-cols>*{flex:1 1 0;min-width:0}
.md-col p.t40{max-width:none}
.md-cap{--pt:20;align-items:flex-start}
.md-cap-pic .lg-m{flex:0 0 calc(834.8*var(--u))}
.md-cap-pic p{width:calc(563.4*var(--u))}
.md-cap-txt p{flex:0 0 calc(549.3*var(--u))}
.md-cap-txt{justify-content:space-between}  /* text on the left edge, picture on the right (Legend's quote) */
.md-cap-txt .lg-m{flex:1}
/* an empty slot: holds its column's width so the other columns keep their size; no height, nothing to see */
.md-gap{width:100%;height:0;align-self:flex-start;visibility:hidden}
.md-cols>.md-gap{flex:1 1 0}
/* {valign=…}: where text sits against the picture or column beside it */
@media (min-width:900px){
  .md-v-top{align-items:flex-start}
  .md-v-center{align-items:center}
  .md-v-bottom{align-items:flex-end}
}
/* two-slot layouts for any content: ½ + ⅓ (half, then a third) and ⅓ + ⅔ (a third, then the rest) */
.md-half-third>:nth-child(1){flex:0 0 calc(834.8*var(--u))}
.md-half-third>:nth-child(2){flex:0 0 calc(563.4*var(--u))}
.md-third-two{justify-content:space-between}
.md-third-two>:nth-child(1){flex:0 0 calc(549.3*var(--u))}
.md-third-two>:nth-child(2){flex:1 1 0}
/* start=…: where text begins on the 12-column grid (left edge, 4, 6 or 8 columns in); desktop only */
@media (min-width:900px){
  .md-text.md-start-1-3 p{margin-left:calc(569.3*var(--u))}
  .md-text.md-start-1-2 p{margin-left:calc(854*var(--u))}
  .md-text.md-start-2-3 p{margin-left:calc(1138.7*var(--u))}
  .md-side.md-start-0 .lg-c4{display:none}
  .md-side.md-start-1-2 .lg-c4{flex:0 0 calc(834*var(--u))}
  .md-side.md-start-2-3 .lg-c4{flex:0 0 calc(1118.7*var(--u))}
}

@media (max-width:899px){
  .lg{padding-bottom:60px}
  .md .lg-m,.md-cap p,.md-cols>*{flex:none!important;width:100%}  /* side-by-side slots and captions stack */
  .md-gap{display:none}                                            /* stacked: an empty column is just skipped */
  .lg p.t40{max-width:none}
  .cs-watch.btn{position:absolute;left:50%!important;top:50%!important}
  .md.md-film-box .cs-watch.btn{--sq:30px}   /* the yellow square's size on phones */
  .cs-poem{height:auto}
  .bx-credits{gap:16px}
  .bx-process{padding:48px 16px 0}
  .lg-info{grid-template-columns:1fr;row-gap:56px;padding:24px 16px}   /* stacked: the credits and the category line need air between them */
  .lg-info h1{margin-bottom:32px}   /* on top of the column gap, so the credits sit clear of the title */
  .lg-hero{margin-top:-46px}   /* = the phone bar's height */
  .md-col{padding-top:32px}   /* text in a stacked row: 16px of row padding or gap + this = 48px above it, like every other text block */
  .lg-sec,.lg-row,.lg-prow{flex-direction:column;padding:16px 16px 0;gap:16px}
  .lg-sec{padding-top:48px}
  .lg-pn{grid-template-columns:1fr;margin-top:16px}
  .lg-pn::after{display:none}
  .lg-pn-i{justify-self:stretch;padding:40px 16px}
  .lg-pn-i + .lg-pn-i{border-top:1px solid var(--rule)}   /* stacked: the dividing line turns sideways */
  .lg-c4{flex:none;width:100%;margin-left:0}
  .lg-c4:empty{display:none}
  .lg-spacer{height:24px}
  .lg-process{padding:48px 16px 0}
  .lg-sq i{width:30px;height:30px;border-radius:7px}
}

/* 404 */
.nf{min-height:100vh;min-height:100svh}
.nf-body{padding:calc(120*var(--u)) calc(20*var(--u));max-width:calc(1118.7*var(--u));display:flex;flex-direction:column;gap:calc(40*var(--u))}
.nf-body h1,.nf-body p{margin:0}
@media (max-width:899px){.nf-body{padding:48px 16px;gap:20px}}
/* touch screens: the film button sits in its hover state, like the others (base.css) */
@media (hover:none){
  .cs-watch.btn,.md.md-film-light .cs-watch.btn{color:var(--black)}
  .md.md-film-box .cs-watch.btn i{width:calc(100% - 2*var(--pad))}
}
