/* Fonts - self-hosted, SIL Open Font License (licences in assets/fonts) */
@font-face{font-family:'Archivo';src:url(../fonts/archivo-var.woff) format('woff');font-weight:100 900;font-stretch:62% 125%;font-style:normal;font-display:swap}
@font-face{font-family:'Archivo';src:url(../fonts/archivo-italic-var.woff) format('woff');font-weight:100 900;font-stretch:62% 125%;font-style:italic;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url(../fonts/plexmono-400.woff) format('woff');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url(../fonts/plexmono-400i.woff) format('woff');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url(../fonts/plexmono-500.woff) format('woff');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url(../fonts/plexmono-600.woff) format('woff');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url(../fonts/plexmono-700.woff) format('woff');font-weight:700;font-style:normal;font-display:swap}

/* =====================================================================
   TIM LENKIEWICZ - THEME STYLESHEET (from design prototype v146)
   One stylesheet, one section per part of the page. Within a section the
   general rule comes first, then its states, then its narrower layouts.

   Layout classes on <html>, set in script from the window width:
     .hamb   ≤1080px  the right column becomes a drawer behind the burger
     .vert   ≤820px   the nav blocks stack
     .novid  ≤640px   the reel gives way to a plain masthead panel
     .m      the phone layout (chosen by device: a phone-sized touch screen)
     .preview  the phone layout shown inside a frame on a desktop screen
   State classes on <body>:
     .menu (drawer open) · .about (About list open) · .page-open (content pane)
     .lang (language list open) · .np-on (nav page open) · .np-lang (language
     mark moved into the nav page) · .bp-on (blog pane open) · .reelpaused
     .entered (phone: past the landing reel)
   ===================================================================== */

/* ================= TOKENS ================= */
:root{
  /* accent - Bern Red (decided) */
  --acc:#e20909; --acc-on:#ffffff; --acc-text:color-mix(in srgb,var(--acc) 85%,#000);
  /* what accent blocks are painted with: the flat accent, or the field image
     (see GRADIENT FIELD) */
  --accbg:var(--acc);
  --ground:#f4f3ef; --ink:#15151a; --dim:#6b6b72; --rule:#cfcec8;
  --gutter:54px;   /* divider bar, desktop */
  --mgut:46px;     /* divider bar, phone */
  --pad:22px;
  /* Archivo variable (SIL OFL): one file carrying wdth 62-125 and wght
     100-900. IBM Plex Mono for small print. Both self-hosted in the build. */
  --d:'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif;
  --m:'IBM Plex Mono',ui-monospace,monospace;
  /* masthead panel, where the reel gives way (narrowest desktop, phone) -
     a Customizer colour or image; decided: ink */
  --mastbg:#101014; --mastimg:none;
  /* nav pages: inset from the window, inner padding, card bleed, ground */
  --npi:clamp(14px,3.3vw,64px); --nppad:28px; --npbleed:26px; --npbg:#fff;
  /* type on the D grid (decided 23 Oct; prototype: Type panel in the dev
     bar). Large, by the pane's width: 760+ · 480-759 · under 480.
     Small: desktop, and phone. */
  --L1:19px; --LL1:29px; --L2:17px; --LL2:27px; --L3:15px; --LL3:25px;
  --Sd:14px; --SLd:20px; --Sm:12px; --SLm:17px;
  --S:var(--Sd); --SL:var(--SLd);
}
html.m{--S:var(--Sm);--SL:var(--SLm)}
html.m{--nppad:14px;--npbleed:14px}
html.m.pv{--mgut:34px}           /* phone held upright: a narrower bar */

/* ================= BASE ================= */
*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%;overflow:hidden}
body{background:var(--ground);color:var(--ink);font-family:var(--d);-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
a:focus-visible,button:focus-visible{outline:2px solid var(--acc-text);outline-offset:3px}
/* nothing re-anchors the scroll position when content above it changes;
   the script corrects the position itself where that matters */
html,body,.left,.nps{overflow-anchor:none}

/* ================= LAYOUT =================
   Left pane · divider bar · right column, each scrolling on its own. */
.stage{display:grid;grid-template-columns:1fr var(--gutter) minmax(330px,29vw);height:100vh}
.left{overflow-y:auto}
html.hamb .stage{grid-template-columns:var(--gutter) 1fr}
html.hamb .left{grid-column:2;grid-row:1}

/* ================= MASTHEAD AND REEL ================= */
.videobox{position:relative;isolation:isolate;background:#000;overflow:hidden;aspect-ratio:16/9;
  container-type:inline-size;
  --cut:96px; --nameTop:34px; --sm:clamp(9px,1.45cqw,15px);}
.cover{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);border:0;
  width:max(100%,177.78cqh);height:max(100%,56.25cqw)}
/* stand-in reel (prototype): drifting blurred shapes */
.fake{position:absolute;inset:0;background:#2a2a2a;overflow:hidden}
.fake i{position:absolute;display:block;border-radius:50%;filter:blur(14px)}
.fake .a{width:52%;height:120%;left:-10%;top:-10%;background:#f4f4f4;animation:dr1 13s ease-in-out infinite alternate}
.fake .b{width:44%;height:110%;right:-6%;top:-5%;background:#080808;animation:dr2 17s ease-in-out infinite alternate}
.fake .c{width:34%;height:80%;left:38%;top:20%;background:#cfcfcf;animation:dr3 11s ease-in-out infinite alternate}
@keyframes dr1{to{transform:translate(46%,12%) scale(1.25)}}
@keyframes dr2{to{transform:translate(-52%,-8%) scale(1.3)}}
@keyframes dr3{to{transform:translate(-30%,18%) scale(.8)}}
@media(prefers-reduced-motion:reduce){.fake i{animation:none}}
body.reelpaused .fake i{animation-play-state:paused}
/* prototype: the stand-in plays; the build shows the real reel (.vid) */
body.vimeo .fake{display:none}
body:not(.vimeo) .vid{display:none}

/* the name is drawn as the difference against the reel beneath it */
.mtx{position:absolute;color:#fff;mix-blend-mode:difference;text-transform:uppercase;line-height:1;white-space:nowrap}
/* the four titles each sit on their own accent block, outside the blend.
   Right padding is reduced by the trailing letterspace so the text centres. */
.m-line{top:11px;right:1.8cqw;font-weight:200;font-size:var(--sm);letter-spacing:.34em;
  mix-blend-mode:normal;color:var(--acc-on);display:flex;gap:.45em}
.m-line span{background:var(--accbg);padding:.42em .2em .42em .54em}
/* narrow mastheads: tracking eased so the four blocks fit on one line */
@container (max-width:560px){
  .m-line{letter-spacing:.12em;gap:.35em}
  .m-line span{padding:.42em .3em .42em .42em}
}
/* longer words (translations): the same easing, chosen in script, and
   then a smaller size if need be */
.m-line.tight{letter-spacing:.12em;gap:.35em}
.m-line.tight span{padding:.42em .3em .42em .42em}
.m-name{top:var(--nameTop);left:1.6cqw;font-weight:700;font-stretch:100%;font-size:11.5cqw;letter-spacing:-.005em}
.m-year{right:1.8cqw;top:calc(var(--cut) + 1.2cqw);display:flex;flex-direction:column;align-items:center;
  font-weight:200;font-size:var(--sm);letter-spacing:.06em;line-height:1.5}
@supports not (mix-blend-mode:difference){
  .m-name,.m-year{mix-blend-mode:normal;color:#fff;text-shadow:0 0 14px rgba(0,0,0,.5)}
}
/* the panel that replaces the reel at the narrowest widths */
.mastpanel{display:none;position:absolute;top:0;left:0;right:0;bottom:0;
  background-color:var(--mastbg);background-image:var(--mastimg);
  background-size:cover;background-position:center}

/* reel controls, bottom right */
.vctl{position:absolute;right:12px;bottom:12px;z-index:6;display:flex;gap:7px}
.vctl button,.vctl a{border:1px solid rgba(255,255,255,.5);background:rgba(0,0,0,.36);color:#fff;
  font-family:var(--m);font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:8px 13px;
  cursor:pointer;backdrop-filter:blur(3px)}
.vctl a{text-decoration:none;display:block;line-height:normal}
.vctl button:hover,.vctl a:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
/* Play: shown once the reel has been paused (drawer, About, a pane or a nav
   page opened); only it resumes the reel. The symbol alone, centred. */
.rplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:6;display:none;
  align-items:center;border:0;padding:0;background:none;color:#fff;font-size:0;line-height:normal;cursor:pointer}
.rplay svg{display:block;width:24px;height:28px;fill:currentColor}
.rplay:hover{color:var(--acc)}
body.reelpaused .rplay,body.reelended .rplay{display:flex}
/* the reel plays once and ends on its last frame (stand-in here) */
.reelend{position:absolute;inset:0;display:none;background:linear-gradient(118deg,#4a4a4a,#1c1c1c 60%,#0a0a0a)}
.reelend span{position:absolute;left:1.6cqw;bottom:14px;font-family:var(--m);font-size:10px;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.55)}
body.reelended .reelend{display:block}
body.reelended .fake i{animation-play-state:paused}
html.novid .reelend,html.m .videobox .reelend{display:none !important}

/* narrower layouts: the cut line rises to stay in the upper third */
html.hamb .videobox{--cut:72px}
/* narrowest desktop and phone: no reel - the name over the masthead panel */
html.novid .videobox,html.m .videobox{aspect-ratio:auto;height:0;
  padding-bottom:calc(var(--nameTop) + 11% + 5px);background:var(--ground); --cut:58px}
html.novid .mastpanel,html.m .videobox .mastpanel{display:block}
html.novid .cover,html.novid .fake,html.novid .vctl,html.novid .rplay,
html.m .videobox .cover,html.m .videobox .fake,html.m .videobox .vctl,html.m .videobox .rplay{display:none !important}
html.novid .m-year,html.m .videobox .m-year{display:none}

/* ================= NAV BLOCKS ================= */
.blocks{display:flex;border-top:1px solid var(--ink);border-bottom:1px solid var(--ink)}
.blk{border-right:1px solid var(--ink);padding:13px 14px 12px;min-width:0;display:block;position:relative}
.blk:last-child{border-right:0}
.blk .w{display:block;font-weight:200;font-stretch:100%;text-transform:uppercase;line-height:.9;letter-spacing:-.005em;font-size:clamp(14px,2.4vw,32px)}
.blk.b1{flex:3.4}.blk.b2{flex:2.4}.blk.b3{flex:1.7}
.blk:hover{background:var(--accbg);color:var(--acc-on)}
/* ≤820px and phone: stacked */
html.vert .blocks,html.m .blocks{flex-direction:column}
html.vert .blk,html.m .blk{border-right:0;border-bottom:1px solid var(--ink)}
html.vert .blk:last-child,html.m .blk:last-child{border-bottom:0}
html.vert .blk .w,html.m .blk .w{font-size:26px}
/* CONTACT AS A FOURTH BLOCK - a CMS switch (dev bar: Contact · Featured).
   Off, or at full width: no block, Contact in the menu only. On, once the
   right column has collapsed: a fourth block, lettering set right. In the
   row (above the stacking width) it stands lit, as if hovered, a weight
   heavier than the others. Contact stays in the menu as well. */
.blk.b4{display:none;flex:1.6;text-align:right}
html[data-contact="nav"].hamb .blk.b4,html[data-contact="nav"].m .blk.b4{display:block}
/* v129: no lit style in the row or the stack (V5) */
/* the featured Contact lettering: semibold, between the nav blocks'
   weight (200) and the masthead name's (700) */
html[data-contact="nav"] .blk.b4 .w{font-weight:600}
/* stacked: no block - the lettering alone carries it: the accent when the
   accent is a flat colour, ink when it is an image */
html[data-contact="nav"].hamb .blk.b4:not(:hover),html[data-contact="nav"].m .blk.b4:not(:hover){color:var(--acc)}
html[data-field="on"][data-contact="nav"].hamb .blk.b4:not(:hover),
html[data-field="on"][data-contact="nav"].m .blk.b4:not(:hover){color:var(--ink)}
/* while there is no fourth block, Teaching closes the row or the stack */
html:not([data-contact="nav"]) .blk.b3,
html[data-contact="nav"]:not(.hamb):not(.m) .blk.b3{border-right:0;border-bottom:0}

/* =====================================================================
   INSTAGRAM HIGHLIGHTS
   Zero point = the width at which the video is dropped. There every box
   is visible, centres evenly pitched, gaps equal, nothing touching.
   Narrower: the row scrolls. Wider: box width grows faster than the pitch,
   so boxes grow from their own centres and eventually meet. Every box is
   centred on one horizontal axis; captions sit beneath.
   CMS: show/hide, left pane or top of the right column, square or circle,
   border on or off; per highlight a cover image, title and its media.
   ===================================================================== */
.hlwrap{position:relative;isolation:isolate}
html[data-hlshow="off"] .hlwrap{display:none}
.hl{display:flex;align-items:flex-start;gap:8px;padding:12px var(--pad) 0;isolation:isolate;
  container-type:inline-size;overflow-x:auto;scrollbar-width:none;
  --boxw:max(80px, calc(100cqw / var(--n,6) * 1.18 - 26px))}
.hl::-webkit-scrollbar{display:none}
.hl a{flex:1 1 0;min-width:82px;position:relative;display:block;text-align:center}
/* fixed-height band, tall enough for the tallest box - this is what puts
   every box centre on the same horizontal */
.hl .bw{display:flex;align-items:center;justify-content:center;height:var(--boxw)}
.hl .box{display:block;position:relative;width:var(--boxw);aspect-ratio:1/1;border:1px solid var(--ink);
  background-color:var(--ground);background-size:cover;background-position:center;
  transition:background .14s}
.hl a:hover .box{background:var(--accbg)}
/* the cover image is drawn again on a layer that carries the image treatment;
   a second layer washes it toward the ground when the row is held back */
.hl .box::before,.hl .box::after{content:'';position:absolute;inset:0}
.hl .box::before{background:inherit;filter:var(--imgf,none)}
.hl a:hover .box::before{display:none}
.hl .box::after{background:var(--ground);opacity:0;transition:opacity .16s}
/* stand-in covers - replaced by the uploaded, cropped image */
.hl a:nth-child(4n+1) .box{background-image:linear-gradient(140deg,#d9a35f,#8a4b3c 55%,#2b1f2a)}
.hl a:nth-child(4n+2) .box{background-image:linear-gradient(200deg,#5fa3b4,#2f5a7a 55%,#141e2c)}
.hl a:nth-child(4n+3) .box{background-image:linear-gradient(160deg,#c46a8a,#5a3a6a 60%,#1c1424)}
.hl a:nth-child(4n+4) .box{background-image:linear-gradient(120deg,#9fbf6a,#4a6a3a 58%,#1a2418)}
.hl .cap{display:block;margin-top:12px;font-family:var(--m);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim);line-height:1.35;position:relative;z-index:21}
.hl a:hover .cap{color:var(--acc-text)}
/* stacking order repeats every six */
.hl a:nth-child(6n+1){z-index:4}
.hl a:nth-child(6n+2){z-index:2}
.hl a:nth-child(6n+3){z-index:3}
.hl a:nth-child(6n+4){z-index:1}
.hl a:nth-child(6n+5){z-index:3}
.hl a:nth-child(6n+6){z-index:2}
html[data-hlshape="circle"] .hl .box{border-radius:50%;overflow:hidden}
html[data-hlborder="off"] .hl .box{border:0}
/* the label: a slim accent block laid over the boxes from the pane's left
   edge, 3/4 of the pane wide but never narrower than its lettering. Its
   height is set in script, two thirds of the way up the boxes. */
.hllabel{position:absolute;left:0;top:0;width:75%;min-width:max-content;z-index:1;
  pointer-events:none;background:var(--accbg);color:var(--acc-on);
  font-weight:300;font-stretch:100%;text-transform:uppercase;
  font-size:clamp(11px,1.2vw,15px);letter-spacing:.22em;line-height:1;
  padding:.62em 1.2em .62em var(--alignI,var(--align,16px))}
html.m .hllabel,html.novid .hllabel{width:85%}
/* collapsed widths: the first box lines up with the D of "Directing" */
.left .hl{padding-left:var(--hlpad,16px)}

/* placed at the top of the right column, beneath the menu: the block starts
   at the column's left edge, its lettering in line with the menu text.
   Widths are fractions of the whole column, padding included. */
.right .hlwrap{margin-bottom:13px}
.right .hl{padding-left:0;padding-right:0}
html:not(.hamb):not(.m) .right .hllabel{left:calc(-1 * var(--pad));
  width:calc((100% + 2 * var(--pad)) * .75);padding-left:calc(var(--pad) + 5px)}
html.hamb .right .hllabel,html.m .right .hllabel{padding-left:5px;
  width:calc((100% + var(--pad)) * .75)}
html.m .right .hllabel,html.novid .right .hllabel{width:calc((100% + var(--pad)) * .85)}
/* in the open drawer the captions sit on the accent */
body.menu .right .hl .cap{color:var(--acc-on)}
/* with the About list open over it, the row is held back like the cards -
   lettering and borders only, so the boxes keep their ground */
html.hamb body.about .right .hl .cap,html.m body.about .right .hl .cap{opacity:.12}
html.hamb body.about .right .hllabel,html.m body.about .right .hllabel{visibility:hidden}
html.hamb body.about .right .hl .box::after,html.m body.about .right .hl .box::after{opacity:.75}
html.hamb body.about .right .hl .box,html.m body.about .right .hl .box{
  border-color:color-mix(in srgb,var(--ink) 30%,var(--ground))}

/* ================= STORY VIEWER =================
   Plays through a highlight, then rolls into the next. Tapping the sides
   steps through one highlight's items; the arrows on the frame (desktop)
   or a swipe (phone) jump to the next or previous highlight. */
.viewer{position:fixed;inset:0;z-index:200;background:rgba(12,12,14,.88);display:flex;
  align-items:center;justify-content:center;padding:18px}
.viewer[hidden]{display:none}
html.preview .viewer{position:absolute}
.vbox{position:relative;width:min(430px,92vw);aspect-ratio:9/16;max-height:88vh;isolation:isolate;
  background:#111;border:3px solid var(--ink);overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.5);
  touch-action:none}
/* chrome: white (decided) */
.vbars{position:absolute;top:9px;left:9px;right:9px;display:flex;gap:4px;z-index:3}
.vbars i{flex:1;height:3px;background:rgba(255,255,255,.3);display:block}
.vbars i b{display:block;height:100%;width:0;background:#fff}
.vt{position:absolute;top:22px;left:11px;z-index:3;font-family:var(--m);font-size:10.5px;
  letter-spacing:.16em;text-transform:uppercase;color:#fff;pointer-events:none}
.vc{position:absolute;top:17px;right:10px;z-index:5;border:2px solid #fff;background:transparent;color:#fff;
  width:32px;height:32px;font-size:17px;line-height:1;cursor:pointer;font-family:var(--d)}
.vc:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
.vstage{position:absolute;inset:0}
.vslide{position:absolute;inset:0;display:none;align-items:center;justify-content:center;flex-direction:column;gap:12px}
.vslide.on{display:flex}
.vslide .lbl{font-weight:700;font-stretch:100%;text-transform:uppercase;font-size:30px;letter-spacing:-.03em;
  line-height:.9;text-align:center;padding:0 22px}
.vslide .sub{font-family:var(--m);font-size:10px;letter-spacing:.18em;text-transform:uppercase;opacity:.7}
.vnav{position:absolute;top:0;bottom:0;width:34%;border:0;background:transparent;cursor:pointer;z-index:2}
.vnav.prev{left:0}.vnav.next{right:0;width:66%}
.vhint{position:absolute;left:0;right:0;bottom:12px;z-index:3;text-align:center;
  font-family:var(--m);font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.6)}
/* whole-highlight arrows, above the tap zones */
.vgrp{position:absolute;top:50%;transform:translateY(-50%);z-index:4;width:40px;height:58px;
  padding:0;border:0;background:none;color:#fff;cursor:pointer;
  display:flex;align-items:center;justify-content:center}
.vgrp.prev{left:0}.vgrp.next{right:0}
.vgrp svg{width:14px;height:24px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:square;
  opacity:.72;transition:opacity .18s;filter:drop-shadow(0 1px 3px rgba(0,0,0,.65))}
.vgrp:hover svg{opacity:1}
html.m .vgrp{display:none}

/* =====================================================================
   PROJECT CARDS - home feed and nav pages
   Each card carries its own background image, chosen and cropped in the
   CMS. Every line of text sits on its own opaque white block, sized to
   that line (box-decoration-break:clone gives a wrapped line its own block).
   The whole card opens and closes its project space.
   ===================================================================== */
.feed{padding:28px var(--pad) 26px}
/* section title above the projects */
.sectitle{margin:0;font-weight:300;font-stretch:100%;text-transform:uppercase;
  font-size:clamp(11px,1.2vw,15px);letter-spacing:.22em;line-height:1;color:var(--ink)}
.it{position:relative;display:block;padding:20px 18px 24px;margin-top:14px;isolation:isolate;
  background-color:#cfceca;background-position:center;background-size:cover;background-repeat:no-repeat}
.feed .it,.np .it{cursor:pointer}
.feed .it:focus-visible,.np .it:focus-visible{outline:2px solid var(--acc-text);outline-offset:2px}
.it .knock{background:#fff;box-decoration-break:clone;-webkit-box-decoration-break:clone;
  padding:.16em .4em;display:inline}
.meta{font-family:var(--m);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink);line-height:1.9;margin:0 0 7px}
.ttl{margin:0;font-weight:700;font-stretch:100%;text-transform:uppercase;line-height:1.16;
  letter-spacing:-.005em;font-size:clamp(22px,3.3vw,44px)}
.it:hover .ttl .knock,.it.open .ttl .knock{background:var(--accbg);color:var(--acc-on)}
.blurb{margin:9px 0 0;font-size:14.5px;line-height:1.85;color:#2c2c30;max-width:52ch}
/* stand-in imagery - replaced by the uploaded, cropped photograph */
.it:nth-of-type(4n+1){background-image:linear-gradient(118deg,#7fa2bf,#3b5470 62%,#1a2330)}
.it:nth-of-type(4n+2){background-image:linear-gradient(196deg,#d8b07a,#8a5f3e 58%,#3a2618)}
.it:nth-of-type(4n+3){background-image:linear-gradient(152deg,#8fc0a0,#3f6a55 60%,#1a2a22)}
.it:nth-of-type(4n+4){background-image:linear-gradient(210deg,#c48aa8,#6a3f5a 60%,#2a1824)}
/* the photograph is drawn again on a layer under the lettering that carries
   the image treatment - a CMS setting: colour, greyscale, cross-processed */
.it::before{content:'';position:absolute;inset:0;z-index:-1;background:inherit;filter:var(--imgf,none)}
html[data-img="grey"]{--imgf:grayscale(1)}
html[data-img="xpro"]{--imgf:url(#xpro)}
/* collapsed widths: the cards' left edge sits on the D of "Directing";
   --align is measured in script */
.left .feed{padding-left:var(--align,16px)}
html.hamb .feed,html.m .feed{padding-right:0}

/* =====================================================================
   PROJECT SPACES - a card opens a space downward with more detail and
   media. Only one is open at a time. Once it has scrolled wholly above the
   top of its scroller it closes by itself, and the scroll position is
   corrected so nothing on screen moves.
   ===================================================================== */
.pd{position:relative;height:0;overflow:hidden;background:var(--pdbg,#fff);container-type:inline-size}
.pd[hidden]{display:none}
.feed .pd{--pdbg:#fff}
.np .pd{--pdbg:var(--ground)}
/* while a space opens, this stands in for the height it has yet to take,
   so the length of the page never changes and nothing drifts */
.pdspacer{flex:none}
.pdin{padding:24px 26px 32px}
.np .pdin{padding-right:calc(var(--nppad) + var(--npbleed) + 26px)}
html.m .pdin{padding:20px 14px 28px}
.pdrole{margin:0 0 18px;font-family:var(--m);font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;line-height:1.6;color:var(--ink)}
.pdcols{display:grid;grid-template-columns:minmax(0,1fr);gap:18px 36px}
@container (min-width:640px){.pdcols{grid-template-columns:minmax(0,1.7fr) minmax(0,1fr)}}
.pdtxt p{margin:0 0 1em;font-size:14.5px;line-height:1.7;color:#2c2c30;max-width:62ch}
.pdfacts{margin:0;font-family:var(--m);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;line-height:1.55}
.pdfacts div{display:grid;grid-template-columns:8.6em minmax(0,1fr);gap:12px;padding:7px 0;border-top:1px solid var(--rule)}
.pdfacts div:last-child{border-bottom:1px solid var(--rule)}
.pdfacts dt{color:var(--dim)}
.pdfacts dd{margin:0;color:var(--ink)}
.pdmedia{margin-top:24px;display:grid;gap:12px}
.pd figure{margin:0}
.pd figcaption{margin-top:6px;font-family:var(--m);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim)}
.pdv .img{position:relative;aspect-ratio:16/9;background:linear-gradient(146deg,#5d6772,#2a3036 60%,#14171b);
  display:flex;align-items:center;justify-content:center}
.pdv .img i{width:58px;height:58px;border:1px solid rgba(255,255,255,.75);display:flex;
  align-items:center;justify-content:center}
.pdv .img svg{width:14px;height:16px;fill:#fff;margin-left:3px}
.pdst{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.pdst .img{aspect-ratio:4/3}
.pdst figure:nth-child(1) .img{background:linear-gradient(130deg,#a9b6c2,#56677a 60%,#26303a)}
.pdst figure:nth-child(2) .img{background:linear-gradient(200deg,#d9bf98,#8f6a48 60%,#3e2c1d)}
.pdst figure:nth-child(3) .img{background:linear-gradient(160deg,#a8cdb3,#4d7863 60%,#1f3129)}
html.m .pdst{grid-template-columns:repeat(2,minmax(0,1fr))}
html.m .pdst figure:nth-child(3){display:none}
.pdcues{display:grid;gap:14px}
.pdcl{margin:0 0 6px;font-family:var(--m);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink)}
.pdq{margin:28px 0 0;padding:14px 0 0;border-top:1px solid var(--ink);max-width:34em;
  font-weight:300;font-size:clamp(18px,1.8vw,25px);line-height:1.3;color:var(--ink)}
.pdq cite{display:block;margin-top:9px;font-style:normal;font-family:var(--m);font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}

/* =====================================================================
   AUDIO PLAYBACK LINE - play/pause, elapsed time, waveform and length on
   one white block. The waveform fills with the accent as it plays; click
   or drag along it to move the playhead. One track plays at a time.
   On a closed card it carries the track's name: each audio file on a
   project has a "show on the closed card" checkbox in the CMS, so a card
   may carry none, one or several of its tracks.
   ===================================================================== */
.ap{display:flex;align-items:center;gap:10px;margin-top:10px;height:44px;padding:0 12px 0 7px;
  background:#fff;max-width:100%;cursor:default}
.pd .ap{margin-top:0}
.it .ap{margin-top:14px}
.it .ap + .ap{margin-top:8px}
.feed .pd .ap{background:var(--ground)}
.apb{flex:none;width:30px;height:30px;padding:0;border:1px solid var(--ink);background:transparent;
  color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.apb:hover,.ap.playing .apb{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
.apb svg{width:10px;height:11px;fill:currentColor;display:block}
.apl{flex:none;max-width:34%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--m);font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink)}
html.m .apl{max-width:28%}
.apt,.apd{flex:none;font-family:var(--m);font-size:10px;letter-spacing:.06em;color:var(--ink);
  min-width:2.9em;font-variant-numeric:tabular-nums}
.apd{color:var(--dim);text-align:right}
.apw{flex:1;min-width:0;height:28px;position:relative;cursor:pointer;touch-action:none}
.apw canvas{position:absolute;inset:0;width:100%;height:100%;display:block}

/* =====================================================================
   DIVIDER BAR - language at the top, the burger in the middle once the
   right column has collapsed, social links at the foot.
   ===================================================================== */
.gutter{position:relative;background:var(--ground);border-right:1px solid var(--ink);
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:0}
html.hamb .gutter{grid-column:1;grid-row:1;border-right:0;z-index:80}

/* language lives in the top third of the bar and expands downward */
.langzone{height:33.333%;width:100%;display:flex;flex-direction:column;align-items:center;
  gap:9px;padding-top:14px;overflow:hidden}
.langbtn{position:relative;width:30px;height:30px;flex:none;border:0;padding:0;
  cursor:pointer;color:var(--ink);background:var(--ground);border-radius:50%}
.langbtn svg{position:absolute;inset:0;width:100%;height:100%;opacity:.32}
.langbtn .cja{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:700;letter-spacing:-.03em;
  text-shadow:0 0 4px var(--ground),0 0 4px var(--ground),0 0 4px var(--ground),0 0 2px var(--ground)}
.langrest{display:none;flex-direction:column;align-items:center;gap:8px}
body.lang .langrest{display:flex}
.arrow{width:14px;flex:none}
.langs{display:flex;flex-direction:column;gap:5px;font-family:var(--m);font-size:10px;letter-spacing:.1em;text-align:center}
.langs a{color:var(--dim)}.langs a.on{color:var(--ink);font-weight:400}
/* full width: hovering the language mark fills the bar, and it stays filled
   while the list is open - until a language is chosen */
html:not(.hamb):not(.m) .gutter:has(.langbtn:hover),
html:not(.hamb):not(.m) body.lang .gutter{background:var(--accbg)}
html:not(.hamb):not(.m) .gutter:has(.langbtn:hover) .langs a,
html:not(.hamb):not(.m) .gutter:has(.langbtn:hover) .arrow,
html:not(.hamb):not(.m) body.lang .langs a,
html:not(.hamb):not(.m) body.lang .arrow{color:var(--acc-on)}
/* collapsed: only the mark's own disc fills, globe and characters unchanged */
html.hamb .langbtn:hover svg,html.m .langbtn:hover svg{opacity:1}
/* full width: the mark stays in view above an open menu pane; opening
   the list closes the pane, so the list runs down an uncovered bar */

/* the burger: unframed, centred on the bar */
.gburger{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  border:0;background:none;padding:0;width:26px;cursor:pointer}
html.hamb .gburger,html.m body.entered .gburger{display:block}
.gburger i{display:block;width:22px;height:2px;background:var(--ink);margin:6px auto;
  transition:transform .2s,opacity .2s,background .14s}
body.menu .gburger i:nth-child(1){transform:translateY(8px) rotate(45deg)}
body.menu .gburger i:nth-child(2){opacity:0}
body.menu .gburger i:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
/* hovering the burger fills the whole bar, leaving the language mark alone;
   once the menu is open the bar stays filled */
.gutter:has(.gburger:hover),body.menu .gutter{background:var(--accbg)}
.gutter:has(.gburger:hover) .gburger i,body.menu .gburger i{background:var(--acc-on)}
.gutter:has(.gburger:hover) .langs a,body.menu .langs a{color:var(--acc-on)}
.gutter:has(.gburger:hover) .arrow,body.menu .arrow{color:var(--acc-on)}

/* social links: a CMS list, stacked at the foot of the bar */
.gsoc{position:absolute;left:0;right:0;bottom:16px;display:flex;flex-direction:column;
  align-items:center;gap:13px}
.gsoc a{display:block;width:19px;height:19px;color:var(--acc)}
.gsoc svg{display:block;width:100%;height:100%}
.gsoc a:hover{color:var(--ink)}
/* on the filled bar the marks invert with everything else */
.gutter:has(.gburger:hover) .gsoc a,body.menu .gsoc a,
html:not(.hamb):not(.m) .gutter:has(.langbtn:hover) .gsoc a,
html:not(.hamb):not(.m) body.lang .gsoc a{color:var(--acc-on)}
body.menu .gsoc a:hover{color:var(--ink)}

/* =====================================================================
   RIGHT COLUMN - menu (About · CV · Contact, order set in the CMS), the
   "Latest" blog cards, and a footer. The whole column scrolls, so its
   scrollbar runs the full height; header and footer stay put over the
   cards. At ≤1080px it becomes a drawer opened from the burger.
   ===================================================================== */
.right{position:relative;z-index:5;display:flex;flex-direction:column;min-height:0;overflow:visible}
html.hamb .right{position:fixed;top:0;left:var(--gutter);right:auto;bottom:0;width:min(430px,84vw);z-index:70;
  background:var(--ground);transform:translateX(-100%);
  transition:transform .26s cubic-bezier(.3,.7,.3,1)}
html.hamb body.menu .right{transform:none}
/* the scroller is an inner column, so the content pane - a sibling of it,
   not a child - is never clipped by its overflow (WebKit clips fixed
   descendants of a scroller to it) */
.rcol{position:absolute;inset:0;overflow-y:auto;display:flex;flex-direction:column;min-height:0}

/* Three things share the top of the column, each on its own level: an
   opaque band (so the cards scrolling under the header never show through),
   the content pane above it, and the menu handles above that - a pane hangs
   from the handle that opened it. The handles live inside the header, so
   the band is drawn on the column itself; script keeps it the header's
   height (--rhh) and clear of the column's scrollbar (--rsb). */
.right::before{content:'';position:absolute;left:0;right:var(--rsb,0px);top:0;z-index:2;
  height:var(--rhh,89px);background:var(--ground)}
html.hamb body.menu .right::before,
html.m body.entered.menu .right::before{background:var(--accbg)}
html.m body:not(.entered) .right::before{display:none}
.rhead{position:sticky;top:0;z-index:5}

/* the menu. The negative inset on the container cancels the items' own
   padding, so the text edges - top level and dropdown alike - line up on
   one left margin. Each item keeps its own top: a selected one grows
   downward and the others stay put. */
.rnav{position:relative;z-index:2;display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start;
  padding:18px 0 11px var(--pad);
  font-family:var(--m);font-size:15.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase}
html.hamb .rnav,html.m body.entered .rnav{padding-top:20px;padding-left:0}
.rnav a,.rnav button{color:#3d3d44;padding:.28em .4em;display:inline-block}
.rnav button{border:0;background:none;cursor:pointer;
  font:inherit;letter-spacing:inherit;text-transform:inherit}
.rnav a:hover,.rnav button:hover,.rsub a:hover,
.rnav a.sel,.rsub a.sel{background:var(--accbg);color:var(--acc-on)}
/* Showreel: in the menu only where the masthead has no reel controls
   (phone, narrowest desktop); opens the full reel on Vimeo in a new tab */
.rnav a.rshow{display:none}
html.m .rnav a.rshow,html.novid .rnav a.rshow{display:inline-block}
/* About opens a short list beneath the row, on the same left margin, laid
   over the cards rather than displacing them */
.rsub{position:absolute;top:100%;left:var(--pad);z-index:3;
  display:none;list-style:none;margin:0;padding:2px 10px 12px 0;
  font-family:var(--m);font-size:14.7px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}
html.hamb .rsub,html.m body.entered .rsub{left:0}
body.about .rsub{display:block}
.rsub li{padding:4px 0}
.rsub a{color:var(--dim);padding:.28em .4em;display:inline-block;background:var(--ground)}
/* full width: the handles carry a white block, with a page open or without */
html:not(.hamb):not(.m) .rnav a,html:not(.hamb):not(.m) .rnav button,
html:not(.hamb):not(.m) .rsub a{background:#fff}
html:not(.hamb):not(.m) .rnav a:hover,html:not(.hamb):not(.m) .rnav button:hover,
html:not(.hamb):not(.m) .rsub a:hover,
html:not(.hamb):not(.m) .rnav a.sel,html:not(.hamb):not(.m) .rsub a.sel,
html:not(.hamb):not(.m) body.page-open .rnav a:hover,
html:not(.hamb):not(.m) body.page-open .rnav button:hover,
html:not(.hamb):not(.m) body.page-open .rsub a:hover,
html:not(.hamb):not(.m) body.page-open .rnav a.sel,
html:not(.hamb):not(.m) body.page-open .rsub a.sel{
  background:var(--accbg);color:var(--acc-on)}

/* featured Contact, full width: the menu's Contact moves to the right-hand
   side of the column, in line with the cards' right edge, and stands lit
   as if hovered - hovering it turns it back to the plain white block */
html[data-contact="nav"]:not(.hamb):not(.m) .rnav a[data-page="Contact"]{
  margin-left:auto;margin-right:var(--pad);background:var(--accbg);color:var(--acc-on);font-weight:700}
html[data-contact="nav"]:not(.hamb):not(.m) .rnav a[data-page="Contact"]:hover:not(.sel){
  background:#fff;color:#3d3d44}

/* section title: "Latest", under a rule spanning the cards */
.rtitle{margin:0 var(--pad);padding:10px 5px 12px;border-top:1px solid var(--ink);
  font-weight:300;font-stretch:100%;text-transform:uppercase;
  font-size:clamp(11px,1.2vw,15px);letter-spacing:.22em;line-height:1;color:var(--ink);
  transition:opacity .16s}
html.hamb .rtitle,html.m body.entered .rtitle{margin-left:0}
body.page-open .rtitle{visibility:hidden}

/* the cards' scroller content */
.rscroll{padding:0 var(--pad) 10px;flex:1 0 auto;min-height:auto;overflow:visible;transition:opacity .16s}
/* drawer: the cards start at the bar's edge */
html.hamb .rscroll,html.m body.entered .rscroll{padding-left:0}

/* footer: copyright left, Privacy right; its rule spans the cards only */
.rfoot{position:sticky;bottom:0;z-index:0;display:flex;justify-content:space-between;align-items:center;
  margin:0 var(--pad);padding:11px 5px 15px;background:var(--ground);border-top:1px solid var(--ink);
  font-family:var(--m);font-size:10px;letter-spacing:.09em;text-transform:uppercase}
html.hamb .rfoot,html.m body.entered .rfoot{margin-left:0}

/* ---------------------------------------------------------------------
   LATEST - blog cards, newest first: a small label, a 66px image strip
   cropped to fit, then title and excerpt clamped to two lines. CMS, per
   post: compact card or feature card; which one image (if any) shows on
   the closed card.
   --------------------------------------------------------------------- */
#posts > article{cursor:pointer}
.post{position:relative;background:var(--ground);border:1px solid transparent;margin-bottom:11px}
/* full width: plain cards are pure white against the warm ground */
html:not(.hamb):not(.m) .post{background:#fff}
.post .pl{display:block;padding:13px;color:var(--ink)}
.post .pmeta{font-family:var(--m);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--dim);line-height:1.3;margin:0 0 10px}
.post .pimg{margin:0 0 10px;height:66px;background:#cfceca;overflow:hidden}
.post .pimg img{display:block;width:100%;height:100%;object-fit:cover;filter:var(--imgf,none)}
.post .pt{margin:0;max-width:90%;font-weight:700;font-stretch:100%;text-transform:uppercase;
  font-size:13.5px;line-height:1.25;letter-spacing:0;color:var(--ink);
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
.post .pt span{box-decoration-break:clone;-webkit-box-decoration-break:clone}
.post .pl:hover .pt span{background:var(--accbg);color:var(--acc-on)}
.post .px{margin:5px 0 0;max-width:90%;font-size:12.5px;line-height:1.5;color:#2c2c30;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
/* feature card: the project card carried over - the image fills the card
   and every line sits on its own white block, type scaled to the column */
.right .it.pfeat{margin:0 0 11px;padding:0}
.pfeat .pl{display:block;padding:18px 15px 21px;color:var(--ink)}
.pfeat .ttl{font-size:clamp(20px,2.1vw,30px);color:var(--ink)}
.pfeat .blurb{font-size:13.5px;line-height:1.85;color:#2c2c30;max-width:none}
.pfeat .pl:hover .ttl .knock{background:var(--accbg);color:var(--acc-on)}

/* ---------------------------------------------------------------------
   OPEN DRAWER - the drawer takes the accent, with its menu inverted onto it.
   Cards keep their own colours.
   --------------------------------------------------------------------- */
html.hamb body.menu .right,
html.m body.entered.menu .right{background:var(--accbg)}
body.menu .right{color:var(--acc-on)}
body.menu .right a{color:var(--acc-on)}
body.menu .rnav a,body.menu .rnav button,body.menu .rsub a{
  color:var(--acc-on)}
body.menu .rnav a:hover,body.menu .rnav button:hover,body.menu .rsub a:hover,
body.menu .rnav a.sel,body.menu .rsub a.sel{
  background:var(--ground);color:var(--ink);opacity:1}
body.menu .rsub a{background:var(--accbg)}
body.menu .rtitle{color:var(--acc-on);border-top-color:var(--acc-on)}
body.menu .rfoot{border-top-color:var(--acc-on)}
html.hamb body.menu .rfoot,html.m body.entered.menu .rfoot{background:var(--accbg)}
body.menu .right .post .pl,body.menu .right .pfeat .pl{color:var(--ink)}

/* what sits behind the About list or an open pane is held back. Full
   width: the whole card column fades. Drawer: only the card contents fade,
   so the cards stay opaque and the accent never shows through them. */
html:not(.hamb):not(.m) body.about .rscroll,
html:not(.hamb):not(.m) body.page-open .rscroll{opacity:.28}
html:not(.hamb):not(.m) body.about .rtitle{opacity:.28}
html.hamb body.about .rtitle,html.m body.about .rtitle{opacity:.3}
html.hamb body.about .post .pl,html.m body.about .post .pl,
html.hamb body.about .pfeat .pl,html.m body.about .pfeat .pl,
html.hamb body.page-open .right .pl,html.m body.page-open .right .pl{opacity:.3}

/* keyboard focus: white where the ground is the red accent (the open
   drawer and its bar), red everywhere else (decided 1 Nov) */
body.menu .right :focus-visible:not(.page *):not(.bobody *),
body.menu .gutter :focus-visible,
body.lang .gutter :focus-visible{outline-color:var(--acc-on)}

/* =====================================================================
   CONTENT PANE - opened from a menu handle (Contact, the About items).
   No frame, a brighter white than the ground, height set by its contents.
   Placed from the selected handle's block: at full width that block's
   top-right corner is the pane's top-right corner; once collapsed it
   becomes the pane's top-left. Text is one column on the D grid
   (multi-column text dropped 20 Oct).
   ===================================================================== */
.page{position:fixed;z-index:3;background:#fff;border:0;overflow-y:auto;overscroll-behavior:contain;
  padding:24px 28px 32px}
.page[hidden]{display:none}
.page h2{margin:0 0 14px;font-weight:700;font-stretch:100%;text-transform:uppercase;
  letter-spacing:-.005em;line-height:1.1;font-size:clamp(20px,2.6vw,34px)}
.page p{margin:0 0 1em;font-size:14.5px;line-height:1.7;color:#2c2c30;
  break-inside:avoid-column}
.page figure{margin:0 0 1.1em;break-inside:avoid}
.page figure .img{aspect-ratio:4/3;background:linear-gradient(146deg,#9aa3ab,#4a525a 62%,#262b30)}
.page figcaption{margin-top:6px;font-family:var(--m);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim)}

/* collapsed: no heading inside the pane - the selected handle grows to act
   as one, its cap tops kept level with the other handles (script) */
html.hamb .page h2,html.m .page h2{display:none}
/* CREDITS - one list; the filter row and the Selected / Full list switch
   show and hide entries in place */
.crbar{column-span:all;display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 18px;margin:0 0 18px}
.crf,.crsel{display:flex;flex-wrap:wrap;gap:4px}
.crbar button{border:0;background:none;padding:3px 6px;font-family:var(--m);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);cursor:pointer}
.crbar button:hover{background:var(--ground)}
.crbar button.on{background:var(--accbg);color:var(--acc-on)}
.crg{break-inside:auto;margin:0 0 6px;color:var(--ink)}
.crg[hidden],.cr[hidden]{display:none}
.crera{margin:0 0 10px;padding-top:8px;border-top:1px solid var(--ink);font-weight:300;font-stretch:100%;
  text-transform:uppercase;letter-spacing:.22em;font-size:11px;line-height:1.4;break-after:avoid}
.cr{break-inside:avoid;margin:0 0 15px}
.crm{font-family:var(--m);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--dim);line-height:1.5}
.crt{margin:2px 0 1px;font-weight:700;font-stretch:100%;text-transform:uppercase;font-size:14px;line-height:1.2;letter-spacing:-.005em}
.crr{font-size:13px;line-height:1.5;color:var(--ink)}
.crn{font-size:12.5px;line-height:1.55;color:#2c2c30;margin-top:2px}
/* prototype only: what still needs checking */
.crk{margin-top:3px;font-family:var(--m);font-size:9.5px;letter-spacing:.06em;color:var(--acc-text)}
.page p.crfoot{column-span:all;margin:14px 0 0;font-size:9.5px}
html.hamb .rnav a.sel,html.hamb .rsub a.sel,
html.m .rsub a.sel{
  font-family:var(--d);font-weight:700;font-stretch:100%;
  font-size:28px;letter-spacing:-.005em;padding:.2em .4em}
/* phone: the title is a block of its own at the first dropdown item's
   place; the selected top-level handle stays in its slot, its lettering in
   the accent so it vanishes into the drawer */
.ptitle{position:fixed;z-index:4;cursor:pointer;background:var(--accbg);color:var(--acc-on);
  font-family:var(--d);font-weight:700;font-stretch:100%;text-transform:uppercase;
  font-size:28px;letter-spacing:-.005em;line-height:normal;
  padding:.2em .4em;white-space:nowrap}
.ptitle[hidden]{display:none}
html.m body.page-open .rnav > a.sel,
html.hamb.vert body.page-open .rnav > a.sel{background:transparent;color:var(--acc)}

/* drawer with a pane open: the white sheet is behind the menu, so normal
   colours return. A handle still above the sheet is on the accent (.onacc,
   set in script) and keeps the colour that reads against it. */
body.menu.page-open .rnav a,body.menu.page-open .rnav button,body.menu.page-open .rsub a{
  color:var(--dim);opacity:1}
body.menu.page-open .rnav a.onacc,body.menu.page-open .rnav button.onacc,
body.menu.page-open .rsub a.onacc{color:var(--acc-on)}
body.menu.page-open .rnav a:hover,body.menu.page-open .rnav button:hover,
body.menu.page-open .rsub a:hover{background:var(--ground);color:var(--ink)}
body.menu.page-open .rnav a.sel,body.menu.page-open .rsub a.sel{
  background:var(--accbg);color:var(--acc-on)}
/* narrower desktop: a handle over the sheet (.overpane) takes an accent
   block on hover, at its normal size */
html.hamb body.page-open .rnav > a.overpane:hover,
html.hamb body.page-open .rnav > button.overpane:hover{
  background:var(--accbg);color:var(--acc-on)}
/* phone: About items other than the selected one keep white lettering on
   the red block, including those below the sheet's top edge */
html.m body.menu.page-open .rsub a:not(.sel){background:var(--accbg);color:var(--acc-on)}
html.m body.menu.page-open .rsub a:not(.sel):hover{background:var(--ground);color:var(--ink)}

/* =====================================================================
   NAV PAGES - Directing · Music & Sound · Teaching: an intro, then the
   projects (and free text blocks between them).
   The home feed first scrolls back to its top. Desktop: a white sheet over
   the window with no border, its top at the foot of the masthead's accent
   blocks, its right edge at the rightmost accent block's and its left edge
   as far from the window's edge as the right edge is from the divider bar
   (script), so it stays within the left pane; it scrolls
   inside and the panes behind it dim, all but the accent blocks.
   Phone: the same edges; the page takes the home feed's place, in the
   document flow, laid over the masthead.
   Its masthead is the name in ink at the home name's size and place, over
   the section word in the accent fitted to the name's width (script).
   ===================================================================== */
.np{display:none;background:var(--npbg);color:var(--ink)}
body.np-on .np{display:block}
html:not(.m) .np{position:fixed;z-index:60;top:var(--npi);left:var(--npi);right:var(--npi);bottom:0}
html.hamb:not(.m) .np{left:var(--gutter)}
html:not(.m) .nps{position:absolute;inset:0;overflow-y:auto;overflow-x:clip;
  overscroll-behavior:contain;scrollbar-width:none}
html:not(.m) .nps::-webkit-scrollbar{width:0;height:0}
html.m .np{position:relative;z-index:7;overflow-x:clip}
/* phone: the home feed steps aside while a page is open; the masthead
   stays, the sheet laid over it below the accent blocks */
html.m body.np-on .left > :not(.np):not(.viewer):not(.videobox){display:none}
/* the panes beneath the sheet stop scrolling and fade back - all but the
   masthead's accent blocks; the right column's ground stays solid, only
   its contents fade */
html:not(.m) body.np-on .left,html.hamb body.np-on .rcol{overflow-y:hidden}
body.np-on .left{background:color-mix(in srgb,var(--ground) 30%,#000)}
body.np-on .left > :not(.np):not(.viewer):not(.videobox),
body.np-on .left .videobox > :not(.m-line){filter:brightness(.3)}
.npin{padding:0 var(--nppad) 72px}
html.m .npin{padding:0 var(--nppad) 52px}
.npbar{height:62px}
html.m .npbar{height:58px}
/* the close mark: a cross the height of the intro's capitals, on its first
   line, flush with the masthead lettering's right edge (sized and placed in
   script). It holds near the top once the page scrolls, drawn as the
   difference against whatever passes beneath so it never disappears. */
.npxw{position:sticky;top:12px;height:0;z-index:7;mix-blend-mode:difference}
.npxw:has(.npx:hover){mix-blend-mode:normal}
.npx{position:absolute;display:block;padding:0;border:0;background:none;color:#fff;cursor:pointer}
.npx::after{content:'';position:absolute;inset:-12px}
.npx svg{display:block;width:100%;height:100%;overflow:visible;fill:none;stroke:currentColor;
  stroke-width:2px;vector-effect:non-scaling-stroke}
.npx svg path{vector-effect:non-scaling-stroke}
.npx:hover{color:var(--acc-text)}
/* keeps the intro's first line clear of the cross */
.npxsp{float:right;height:1px}

/* language in the sheet - shown only while the sheet covers the mark in
   the divider bar (full width, depending on the window). It sits in the
   sheet's top left corner and opens to the right. */
.nplang{position:absolute;left:12px;top:12px;z-index:6;height:auto;width:auto;
  flex-direction:row;align-items:center;gap:10px;padding:0;overflow:visible;display:none}
body.np-lang .nplang{display:flex}
body.np-lang .gutter .langzone{visibility:hidden}
.nplang .langbtn{background:var(--npbg)}
.nplang .langbtn:hover svg{opacity:1}
.nplang .langrest{flex-direction:row;align-items:center;gap:10px}
.nplang .arrow{width:26px;height:16px;flex:none}
.nplang .langs{flex-direction:row;gap:12px}
/* the copy in the sheet sits on white, so it keeps the page's colours, and
   opening it leaves the divider bar its own colour */
html:not(.hamb):not(.m) body.lang .nplang .langs a,
html:not(.hamb):not(.m) body.menu .nplang .langs a{color:var(--dim)}
html:not(.hamb):not(.m) body.lang .nplang .langs a.on,
html:not(.hamb):not(.m) body.menu .nplang .langs a.on{color:var(--ink)}
html:not(.hamb):not(.m) body.lang .nplang .arrow,
html:not(.hamb):not(.m) body.menu .nplang .arrow{color:var(--ink)}
html:not(.hamb):not(.m) body.np-lang.lang .gutter{background:var(--ground)}
html:not(.hamb):not(.m) body.np-lang.lang .gsoc a{color:var(--acc)}

/* masthead: font size, height and the lettering's offset are set in script */
.npm{margin:0 calc(-1 * var(--nppad)) 34px}
.npl{display:block;white-space:nowrap;text-transform:uppercase;letter-spacing:-.005em;
  font-family:var(--d);font-stretch:100%}
.npl span{position:relative}
/* the name is the way home */
.npl.n1{font-weight:700;color:var(--ink);cursor:pointer}
/* a heavier cut of the same face. The two lines all but touch, so the
   section word passes its clicks through to the name above it. */
.npl.n2{font-weight:800;color:var(--acc);pointer-events:none}
/* the rule under the intro runs out to the cards' edge; the text keeps
   the column width */
.npintro{margin:0 calc(-1 * var(--nppad) - var(--npbleed)) 30px 0;
  padding:0 calc(var(--nppad) + var(--npbleed)) 26px 0;border-bottom:1px solid var(--ink)}
/* a page with nothing after its intro (Contact) has no rule beneath it */
.npintro:last-child{border-bottom:0}
.npintro p{margin:0 0 .85em;max-width:62ch;font-size:clamp(16px,1.3vw,19px);line-height:1.6;color:#2c2c30}
.npintro .npnote{margin:20px 0 0;font-family:var(--m);font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;line-height:1.9;color:var(--dim)}
.npnote a{color:var(--ink);border-bottom:1px solid var(--rule)}
.npnote a:hover{background:var(--accbg);color:var(--acc-on);border-color:transparent}
.npc .sectitle ~ .sectitle{margin-top:46px}
/* cards and their spaces run off the right edge of the sheet and are cut */
.npg{margin-right:calc(-1 * var(--nppad) - var(--npbleed))}
.np .it{padding-right:calc(var(--nppad) + var(--npbleed) + 18px)}

/* text block between cards - a rich text field the CMS can place anywhere
   in the run: headings, rules and inline media */
.npblk{margin-top:30px;padding:26px calc(var(--nppad) + var(--npbleed)) 0 0;
  border-top:1px solid var(--rule)}
.npblkt{margin:0 0 14px;font-weight:300;font-stretch:100%;text-transform:uppercase;
  font-size:clamp(11px,1.2vw,15px);letter-spacing:.22em;line-height:1;color:var(--ink)}
.npblkc p{margin:0 0 1em;font-size:14.5px;line-height:1.8;color:#2c2c30}
.npblk figure{margin:18px 0 0;max-width:62ch}
.npblk figcaption{margin-top:6px;font-family:var(--m);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim)}
.npblk .img{aspect-ratio:16/9;background:linear-gradient(142deg,#b9c3cc,#5e6b78 58%,#232a31);
  display:flex;align-items:center;justify-content:center}
.npblk .img i{width:58px;height:58px;border:1px solid rgba(255,255,255,.75);display:flex;
  align-items:center;justify-content:center}
.npblk .img svg{width:14px;height:16px;fill:#fff;margin-left:3px}

/* =====================================================================
   BLOG PANE (desktop) - a postcard centred on the window, pure white,
   above everything (the drawer included). The first scroll grows it
   downward, as far as the content needs or the window allows.
   ===================================================================== */
.bp{position:fixed;z-index:95;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(690px,86vw);height:min(calc(0.69 * min(690px,86vw)),76vh);
  background:#fff;color:var(--ink)}
.bp[hidden]{display:none}
html.m .bp{display:none}
.bpc{position:absolute;inset:0;overflow-y:auto;overflow-x:clip;overscroll-behavior:contain;
  scrollbar-width:none;padding:34px 40px 40px}
.bpc::-webkit-scrollbar{width:0;height:0}
/* a white wedge in the top right corner, fixed to the frame: the close and
   share marks keep a clear ground as text and media scroll up into it */
.bp::before{content:'';position:absolute;right:0;top:0;width:164px;height:92px;background:#fff;z-index:2;
  clip-path:polygon(0 0,100% 0,100% 100%)}
.bpx{position:absolute;top:9px;right:11px;z-index:3;width:32px;height:32px;padding:0;border:0;
  display:flex;align-items:center;justify-content:center;background:#fff;color:var(--ink);
  font:300 27px/1 var(--d);cursor:pointer}
.bpx:hover{color:var(--acc-text)}
/* what is behind it darkens 70% toward black, as behind a nav page */
.bpshade{position:fixed;inset:0;z-index:94;background:rgba(0,0,0,.7);display:none}
body.bp-on .bpshade{display:block}

/* POST CONTENT - shared by the blog pane and the phone's open card. The
   body is one CMS field: paragraphs (each with its own justification),
   images, video and audio, in any order. */
.pomet{margin:0 0 10px;font-family:var(--m);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim)}
/* the headline keeps clear of the wedge */
.potl{margin:0 0 20px;padding-right:104px;font-weight:700;font-stretch:100%;text-transform:uppercase;line-height:1.1;
  letter-spacing:-.005em;font-size:clamp(21px,2.5vw,34px);color:var(--ink)}
.pob p{margin:0 0 1.1em;font-size:14.5px;line-height:1.75;color:#2c2c30}
.pob p.r{text-align:right}
.pob figure{margin:0 0 1.3em}
.pob figcaption{margin-top:6px;font-family:var(--m);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim)}
.pob .img{aspect-ratio:16/9;background:linear-gradient(142deg,#b9c3cc,#5e6b78 58%,#232a31);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.pob .img img{width:100%;height:100%;object-fit:cover;display:block}
.pob .vid i{width:58px;height:58px;border:1px solid rgba(255,255,255,.75);display:flex;
  align-items:center;justify-content:center}
.pob .vid svg{width:14px;height:16px;fill:#fff;margin-left:3px}
.pob .ap{background:var(--ground);margin:0 0 1.3em}

/* PHONE - the card in the drawer grows downward in place, pushing the
   cards below it down. One open at a time. While open: an edge, a bare
   close cross, its ground washed to white, the closed card's picture and
   excerpt gone (the body carries them) and the title shown in full. */
/* each card is a layer of its own beneath the header's band, so nothing in
   an open card can rise through the band as it scrolls up under it */
html.cardopen #posts > article{z-index:0}
html.cardopen .post.bopen,html.cardopen .pfeat.bopen{border:1px solid var(--ink)}
.bocl{display:none;position:absolute;top:7px;right:9px;z-index:4;width:30px;height:30px;padding:0;
  border:0;background:none;color:var(--ink);font:300 27px/1 var(--d);cursor:pointer;
  align-items:center;justify-content:center}
.bocl:hover{color:var(--acc-text)}
html.cardopen .bopen .bocl{display:flex}
.bobody{display:none;padding:2px 13px 16px}
html.cardopen .bopen .bobody{display:block}
html.cardopen .pfeat.bopen .bobody{padding:14px 15px 18px}
html.cardopen .bopen .pl{pointer-events:none}
.bowash{position:absolute;inset:0;z-index:0;background:#fff;pointer-events:none}
html.cardopen .bopen > .pl,html.cardopen .bopen > .bobody{position:relative;z-index:1}
html.cardopen .post.bopen .pimg,html.cardopen .post.bopen .px,html.cardopen .pfeat.bopen .blurb{display:none}
html.cardopen .post.bopen .pt{display:block;-webkit-line-clamp:unset;overflow:visible;max-width:none;padding-right:30px}
/* the share mark alone at the foot, on the right */
.poend{margin:26px 0 0;padding:14px 0 0;display:flex;align-items:center;justify-content:flex-end;gap:16px}
/* drawer open: links in an open post are on white, so they keep the page's colours.
   html.cardopen: every width but full width */
html.cardopen body.menu .bobody a{color:var(--ink)}

/* =====================================================================
   SHARE - a mark on every project space and blog post; it opens one sheet
   beside whichever mark was pressed (the phone's own share sheet there).
   ===================================================================== */
.shb{width:30px;height:30px;padding:0;border:0;background:none;color:var(--ink);cursor:pointer;
  display:flex;align-items:center;justify-content:center;flex:none}
.shb svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.6}
.shb:hover{color:var(--acc-text)}
.bp .shb{position:absolute;top:10px;right:46px;z-index:3;background:#fff}
.pd .shb{position:absolute;top:18px;right:14px;z-index:3;color:var(--ink)}
.np .pd .shb{right:calc(var(--nppad) + var(--npbleed) + 14px)}
.bobody .shb{position:static;margin:0 -6px 0 0}
.shs{position:fixed;z-index:400;width:252px;background:#fff;border:1px solid var(--ink);
  padding:12px;color:var(--ink)}
.shs[hidden]{display:none}
.shurl{display:flex;gap:7px;margin-bottom:10px}
.shurl input{flex:1;min-width:0;border:1px solid var(--rule);background:var(--ground);padding:6px 8px;
  font-family:var(--m);font-size:10px;color:var(--ink)}
.shurl button{flex:none;border:1px solid var(--ink);background:#fff;padding:6px 9px;cursor:pointer;
  font-family:var(--m);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
.shurl button:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
.shrow{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.shrow a{display:block;padding:7px 9px;border:1px solid var(--rule);text-align:center;
  font-family:var(--m);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink)}
.shrow a:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}

/* =====================================================================
   GRADIENT FIELD - a CMS setting: flat accent, or an uploaded image that
   shows wherever the accent would. The image is one field the size of the
   screen; each accent block is a window onto its own part of it. Script
   writes each block's offset (--fx/--fy) and the field's size (--fw/--fh),
   which also works on iPhone, where fixed backgrounds are ignored.
   ===================================================================== */
html[data-field="on"]{--accbg:var(--field) var(--acc)}
html[data-field="on"] .fx:not(.box),
html[data-field="on"] .hl a:hover .box.fx,
html[data-field="on"] .right::before{
  background-size:var(--fw) var(--fh) !important;
  background-position:var(--fx,0px) var(--fy,0px) !important;
  background-repeat:repeat-x !important}
/* the pathfinder shape behind a wrapped title (script) */
.ttl,.post .pt{position:relative;isolation:isolate}
.fpath{display:none;position:absolute;z-index:-1;pointer-events:none;background:var(--accbg)}
html[data-field="on"] .it:hover .ttl .fpath,html[data-field="on"] .it.open .ttl .fpath,
html[data-field="on"] .pfeat .pl:hover .ttl .fpath,html[data-field="on"] .post .pl:hover .pt .fpath{display:block}
html[data-field="on"] .it:hover .ttl .knock.fpd,html[data-field="on"] .it.open .ttl .knock.fpd,
html[data-field="on"] .pfeat .pl:hover .ttl .knock.fpd,html[data-field="on"] .post .pl:hover .pt span.fpd{background:transparent !important}
/* the play mark: on hover the field shows through the triangle */
html[data-field="on"] .rplay:hover svg{visibility:hidden}
html[data-field="on"] .rplay:hover::before{content:'';position:absolute;inset:0;
  background:var(--field) var(--acc);background-size:var(--fw) var(--fh);
  background-position:var(--fx,0px) var(--fy,0px);background-repeat:repeat-x;
  clip-path:polygon(0 0,100% 50%,0 100%)}
/* keyboard focus with the image accent: where the outline would be drawn
   in the accent, a ring cut from the field image is drawn instead (script);
   the element's own outline turns transparent, but forced-colours mode
   still draws it in the system colour, and the ring steps aside there */
#fring{position:fixed;z-index:2147483000;pointer-events:none;display:none;box-sizing:border-box;padding:3px;
  background:var(--field) var(--acc);background-size:var(--fw) var(--fh);background-repeat:repeat-x;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0)}
html[data-field="on"] .fring-on:focus-visible{outline-color:transparent !important}
@media (forced-colors:active){ #fring{display:none !important} }
/* the section word in a nav sheet's masthead: the field shows through the
   lettering */
html[data-field="on"] .npl.n2 span{background-image:var(--field) !important;
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent}
/* the CV download link in Contact */
.cvdl a{font-family:var(--m);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink);border-bottom:1px solid var(--rule);text-decoration:none}
.cvdl a:hover{background:var(--accbg);color:var(--acc-on);border-color:transparent}
/* in the open drawer links turn to the drawer's lettering; this one sits on the white pane */
.right .page .cvdl a{color:var(--ink)}
.right .page .cvdl a:hover{color:var(--acc-on)}
/* lettering on the field: a per-image choice */
html[data-field="on"][data-ftext="ink"]{--acc-on:#15151a}
html[data-field="on"][data-ftext="white"]{--acc-on:#ffffff}
/* outlines that were drawn in the flat accent step aside */
html[data-field="on"] .vctl button:hover,html[data-field="on"] .vctl a:hover,html[data-field="on"] .vc:hover,
html[data-field="on"] .apb:hover,html[data-field="on"] .ap.playing .apb,
html[data-field="on"] .shurl button:hover,html[data-field="on"] .shrow a:hover{border-color:transparent}
/* the hidden phone handle can't vanish by colour against an image */
html[data-field="on"].m body.page-open .rnav > a.sel,
html[data-field="on"].hamb.vert body.page-open .rnav > a.sel{visibility:hidden}

/* =====================================================================
   PHONE
   ===================================================================== */
.takeover{display:none}
.entergrp{display:none}
html.m,html.m body{overflow:auto;height:auto}
html.m .stage{display:block;height:auto;padding-left:var(--mgut);overflow-x:clip}
/* the cards' bleed must not turn into a sideways scroll */
html.m .left{position:relative;overflow:visible;overflow-x:clip}
html.m .right{position:static;transform:none;width:auto;border-left:0;box-shadow:none}

/* LANDING SCREEN - EVERYTHING FIXED TO THE GLASS
   .glass is the phone's screen as it is when held upright: portrait-shaped,
   with its top at the phone's top. When the phone is turned, the browser
   turns the page; .glass is turned back by the same amount (--ca), so the
   reel, masthead and button never move on the glass. Inside it, the reel
   lies along the long edge (reading upright once the phone is turned
   clockwise), and the button has one spot, top right of the glass. Only
   the button's lettering turns, in 90-degree steps (--ba), so it always
   reads upright. html[data-turn]: up · cw · down · ccw. */
html.m .takeover{display:block;position:fixed;inset:0;z-index:50;background:#000;overflow:hidden;
  container-type:size;touch-action:none;overscroll-behavior:none}
html.m .glass{position:absolute;left:50%;top:50%;
  width:min(100cqw,100cqh);height:max(100cqw,100cqh);
  transform:translate(-50%,-50%) rotate(var(--ca,0deg));
  container-type:size;
  /* the button's inset on the long side: the width of the capital I in the
     landscape masthead (name at 11.5 x width, I about 0.24em), min 16px */
  --IwL:max(16px,calc(11.5cqh * .24))}
html.m[data-turn="up"]  {--ca:0deg;   --ba:0deg}
html.m[data-turn="cw"]  {--ca:90deg;  --ba:-90deg}
html.m[data-turn="down"]{--ca:180deg; --ba:180deg}
html.m[data-turn="ccw"] {--ca:-90deg; --ba:90deg}
html.m .rotor{position:absolute;top:0;left:0;transform-origin:top left;
  isolation:isolate;container-type:size;
  width:100cqh;height:100cqw;transform:rotate(-90deg) translateX(-100%)}
html.m .rotor .cover{width:max(100cqw,177.78cqh);height:max(100cqh,56.25cqw)}
html.m .strip{position:absolute;top:0;left:0;width:100%;container-type:inline-size;
  --cut:96px; --nameTop:34px; --sm:clamp(9px,1.45cqw,15px)}
/* the button's one spot, top right of the glass. Its box is the footprint
   of the button and the full-reel link above it at the current turn (--bw/--bh measured in script), so the
   turned button always fits the corner. Upright or upside-down it sits
   40px down, clear of the masthead's year; on its side, an I-width in. */
html.m .enterspot{position:absolute;z-index:60;top:40px;right:16px;
  width:var(--bw,216px);height:var(--bh,63px)}
html.m[data-turn="cw"] .enterspot,html.m[data-turn="ccw"] .enterspot{
  top:var(--IwL);right:var(--IwL);width:var(--bh,63px);height:var(--bw,216px)}
/* the button and, directly above it, the link to the full reel turn
   together as one group */
html.m .entergrp{display:flex;flex-direction:column;gap:8px;position:absolute;left:50%;top:50%;z-index:60;
  transform:translate(-50%,-50%) rotate(var(--ba,0deg))}
html.m .enter{display:block;white-space:nowrap;
  border:0;background:var(--ground);color:var(--ink);font-family:var(--m);font-size:12px;
  letter-spacing:.2em;text-transform:uppercase;padding:17px 26px;cursor:pointer;box-shadow:0 6px 26px rgba(0,0,0,.45)}
html.m .efull{display:block;text-align:center;white-space:nowrap;text-decoration:none;
  border:1px solid rgba(255,255,255,.5);background:rgba(0,0,0,.36);color:#fff;
  font-family:var(--m);font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:8px 13px;
  backdrop-filter:blur(3px)}
html.m .efull:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
html.m .enter b{display:block;font-size:9.5px;letter-spacing:.14em;opacity:.6;font-weight:400;margin-top:4px}
html.m body.entered .takeover,html.m body.entered .entergrp{display:none}
html.m body:not(.entered){overflow:hidden;height:100%}
/* until the reel is dismissed the page background is black, so the margins
   a phone keeps clear around its camera cut-out and rounded corners blend
   with the reel instead of showing the warm white ground */
html.m:not(.preview) body:not(.entered){background:#000}

/* AFTER ENTRY - the collapsed desktop layout: bar on the left, burger
   centred on it, drawer sliding out from the bar's edge. The bar is fixed
   to the viewport, so it holds its place while the page scrolls. */
html.m .gutter{position:fixed;top:0;left:0;right:auto;bottom:0;width:var(--mgut);z-index:80;
  flex-direction:column;justify-content:flex-start;gap:0;padding:0;border:0}
html.m body:not(.entered) .gutter,html.m body:not(.entered) .gsoc{display:none}
html.m .langs{flex-direction:column;gap:6px}
html.m .langs a{font-weight:500}
html.m .langs a.on{font-weight:600}
html.m.pv .langs{font-size:9px;gap:13px}
html.m.pv .arrow{width:13px}
/* the zone grows with the list instead of clipping it on short screens */
html.m body.lang .langzone{height:auto;min-height:33.333%;overflow:visible;padding-bottom:14px}
html.m body.entered .right{position:fixed;top:0;left:var(--mgut);right:auto;bottom:0;width:85%;z-index:70;
  display:flex;flex-direction:column;min-height:0;
  background:var(--ground);border-left:0;border-right:0;transform:translateX(-100%);
  transition:transform .26s cubic-bezier(.3,.7,.3,1)}
html.m body.entered.menu .right{transform:none}

/* DRAWER OPEN - the home feed beside it is darkened, 70% of the way to
   black, fading in with the drawer's slide; on a phone it also stops
   scrolling (touches outside the drawer are held in script) */
.scrim{position:fixed;inset:0;z-index:65;background:#000;opacity:0;pointer-events:none;
  transition:opacity .26s cubic-bezier(.3,.7,.3,1)}
html.hamb body.menu .scrim,html.m body.entered.menu .scrim{opacity:.7;pointer-events:auto}
html.m body.entered.menu,html.m:has(body.entered.menu){overflow:hidden}
html.preview.m body.entered.menu .left{overflow-y:hidden}
html.m .rcol{overscroll-behavior:contain}

/* =====================================================================
   SCROLLBARS - desktop: thin, full height (left pane, right column), and
   only the topmost one shows: the drawer hides the left pane's; an open
   pane or nav page stops the columns beneath it scrolling. The gutter
   stays reserved, so nothing reflows. Phone: none; scrolling is by touch.
   ===================================================================== */
.left,.rcol{scrollbar-width:thin}
/* menu panes: no scrollbar at any width */
.page{scrollbar-width:none}
.page::-webkit-scrollbar{display:none}
html:not(.m) .left{overflow-x:clip}
html:not(.m) .rcol,html:not(.m) .left{scrollbar-gutter:stable}
html.hamb body.menu .left,body.page-open .left,body.page-open .rcol{
  scrollbar-color:transparent transparent}
html.hamb body.menu .left,html:not(.m) body.page-open .left{overflow-y:hidden}
html:not(.m) body.page-open .rcol{overflow-y:hidden}
html.m,html.m body,html.m .left,html.m .rcol,html.m .page{scrollbar-width:none}
html.m::-webkit-scrollbar,html.m body::-webkit-scrollbar,html.m .left::-webkit-scrollbar,
html.m .rcol::-webkit-scrollbar,html.m .page::-webkit-scrollbar{display:none}

/* =====================================================================
   TYPOGRAPHY D - index and field, two sizes (typography canvas, D row)
   The grid is set by the PANE's width, not the window's:
     pane 760+     12 columns · gutter 24 · margin 28 · index 1-3 · field 4-12
     pane 600-759   6 columns · gutter 20 · margin 24 · index 1-2 · field 3-6
     pane < 600    the index becomes a line above its block; margin 24,
                   16 under 480
   The grid lives inside the pane and never changes the pane's size.
   Large: Archivo expanded 19/29, 17/27 under 760, 15/25 under 480 - field
   only. Small: IBM Plex Mono 14/20 on desktop, 12/17 on a phone.
   (Sizes are tokens on :root, --L1 ... --SLm.)
   ===================================================================== */
.page,.np,.bp,.right .bobody,.feed{container-type:inline-size}
.pd{container-type:normal}
.dgw{--dn:4;--dix:0;--fs:1;--gm:16px;--gg:16px;--L:var(--L3);--LL:var(--LL3);--pqb:0px;
  --col:calc((100cqw - 2 * var(--gm) - (var(--dn) - 1) * var(--gg)) / var(--dn));
  --ixw:calc(var(--dix) * var(--col) + (var(--dix) - 1) * var(--gg));
  --b6:calc(6 * var(--col) + 5 * var(--gg))}
@container (min-width:480px){.dgw{--gm:24px;--L:var(--L2);--LL:var(--LL2)}}
@container (min-width:600px){.dgw{--dn:6;--dix:2;--fs:3;--gg:20px;--pqb:calc(-1 * (var(--col) + var(--gg)))}}
@container (min-width:760px){.dgw{--dn:12;--dix:3;--fs:4;--gm:28px;--gg:24px;--L:var(--L1);--LL:var(--LL1);
  --pqb:calc(-2 * (var(--col) + var(--gg)))}}
.feed .dgw{--gm:0px}

.dg{display:grid;grid-template-columns:repeat(var(--dn),minmax(0,1fr));column-gap:var(--gg);padding:0 var(--gm)}
.dg > .ix{grid-column:1 / span var(--dix)}
.dg > .fd{grid-column:var(--fs) / -1}
@container (max-width:599px){.dg{display:block}}
.dgw [hidden]{display:none !important}

/* type */
.dgw .ts{margin:0 0 24px;font-family:var(--m);font-weight:400;font-size:var(--S);line-height:var(--SL);color:#2c2c30;max-width:none}
.dgw .ts:last-child{margin-bottom:0}
.dgw .tsc{margin:0;font-family:var(--m);font-weight:500;font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.dgw .ts6{margin:0;font-family:var(--m);font-weight:600;font-size:var(--S);line-height:var(--SL);letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
.dgw .tcap{margin:0;font-family:var(--m);font-weight:400;font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase;color:#6b6b72}
.dgw .tl{margin:0;font-family:var(--d);font-weight:300;font-stretch:112.5%;font-size:var(--L);line-height:var(--LL);letter-spacing:-.005em;color:var(--ink);max-width:none}
.dgw .tt{margin:0;font-family:var(--d);font-weight:700;font-stretch:112.5%;font-size:var(--L);line-height:var(--LL);letter-spacing:-.005em;text-transform:uppercase;color:var(--ink)}
.dgw .tr{text-align:right}
@container (min-width:760px){.dgw .bw{max-width:var(--b6)}}
/* menu panes: body paragraphs fill the whole field (the 6-column cap is for nav-page text) */
.page .dgw .bw{max-width:none}
/* links: ink on a fine grey line; hover takes the accent block */
.dgw .ts a,.dgw .tl a,.dgw .tsc a,.dgw .co a,.dgw .crdl a,.dgw .cvdl a{color:var(--ink);text-decoration:none;border-bottom:1px solid #b9b8b2}
.dgw .ts a:hover,.dgw .tl a:hover,.dgw .tsc a:hover,.dgw .co a:hover,.dgw .crdl a:hover,.dgw .cvdl a:hover{
  background:var(--accbg);color:var(--acc-on);border-color:transparent}
.dgw .cvdl{margin:0;font-family:var(--m);font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.dgw .cvdl a{font-family:var(--m);font-size:var(--S);line-height:var(--SL);letter-spacing:.08em}
html:not([data-contact="nav"]) .cvdl-cv{display:none}

/* figures: the caption sits in the index, level with the image's foot */
.dgw .frow{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;align-items:end;margin:6px 0 24px}
.dgw .frow > *{grid-row:1;margin:0}
.dgw .frow > .ix{grid-column:1 / span var(--dix)}
.dgw .frow > .fd{grid-column:var(--fs) / -1}
@container (max-width:599px){.dgw .frow{display:block}.dgw .frow .tcap{margin-top:6px}}
.dgw .pfig{margin:0}
.dgw .img{aspect-ratio:16/9;background:linear-gradient(146deg,#b4b4b4,#5a5a5a 62%,#2a2a2a);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.dgw .img img{width:100%;height:100%;object-fit:cover;display:block}
.dgw .img i{width:58px;height:58px;border:1px solid rgba(255,255,255,.75);display:flex;align-items:center;justify-content:center}
.dgw .img i svg{width:14px;height:16px;fill:#fff;margin-left:3px}
/* inline media beside text (panes 760+): left or right edge of the field */
.dgw .ilm{display:grid;grid-template-columns:subgrid;align-items:start}
.dgw .ilm > *{grid-row:1}
.dgw .ilf{grid-column:1 / span 4;margin:0}
.dgw .ilt{grid-column:5 / -1}
.dgw .ilr .ilt{grid-column:1 / -4}
.dgw .ilr .ilf{grid-column:-4 / -1}
.dgw .ilf .img{aspect-ratio:4/3;background:linear-gradient(130deg,#b9b9b9,#616161 60%,#262626)}
.dgw .ilr .ilf .img{aspect-ratio:3/4}
.dgw .ilf figcaption{margin-top:6px}
@container (max-width:759px){.dgw .ilm{display:block}.dgw .ilf{margin:0 0 18px}}
/* CAPTIONS - a CMS choice on each image: in the index, or under the image.
   (dev bar: Captions - every image at once.) In the index the caption sits
   level with the image's foot - for an inline image on either side of the
   field (on the right, the caption crosses the text column to the index).
   Where the index is narrow or gone, captions go under. */
/* a caption in the index lines up with the image's foot or its top - a
   second choice on each image (dev bar: Caption align) */
html[data-capal="top"] .dgw .frow,
html[data-capal="top"][data-cap="ix"] .dgw .ilm .ilf.ilf{align-items:start}
html[data-cap="under"] .dgw .frow > .ix{grid-column:var(--fs) / -1;grid-row:2;margin-top:6px}
@container (min-width:760px){
  html[data-cap="ix"] .dg > .ilm:not(.ilr){grid-column:1 / -1}
  html:not([data-npfull="on"])[data-cap="ix"] .npblk > .ilm:not(.ilr){grid-row:1}
  html:not([data-npfull="on"])[data-cap="ix"] .npblk > .ix{grid-row:1}
  html[data-cap="ix"] .dgw .ilm:not(.ilr) .ilf{grid-column:1 / span 7;display:grid;
    grid-template-columns:subgrid;align-items:end}
  html[data-cap="ix"] .dgw .ilm:not(.ilr) .ilf > .img{grid-column:4 / span 4;grid-row:1}
  html[data-cap="ix"] .dgw .ilm:not(.ilr) .ilf > figcaption{grid-column:1 / span 3;grid-row:1;margin:0}
  html[data-cap="ix"] .dgw .ilm:not(.ilr) .ilt{grid-column:8 / -1}
  /* on the right: text in columns 4-9, image 10-12. The figure spans the
     row so its caption can sit in the index; it lets clicks through to the
     text beneath it */
  html[data-cap="ix"] .dg > .ilm.ilr{grid-column:1 / -1}
  html:not([data-npfull="on"])[data-cap="ix"] .npblk > .ilm.ilr{grid-row:1}
  html[data-cap="ix"] .dgw .ilm.ilr .ilt{grid-column:4 / -4}
  html[data-cap="ix"] .dgw .ilm.ilr .ilf{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;
    align-items:end;pointer-events:none}
  html[data-cap="ix"] .dgw .ilm.ilr .ilf > *{pointer-events:auto}
  html[data-cap="ix"] .dgw .ilm.ilr .ilf > .img{grid-column:-4 / -1;grid-row:1}
  html[data-cap="ix"] .dgw .ilm.ilr .ilf > figcaption{grid-column:1 / span 3;grid-row:1;margin:0}
  /* the rule above the text still starts at the field */
  html[data-cap="ix"] .dgw .pgl > .tl + .ilm{border-top:0;position:relative}
  html[data-cap="ix"] .dgw .pgl > .tl + .ilm::before{content:'';position:absolute;top:0;right:0;
    left:calc(var(--ixw) + var(--gg));border-top:2px solid var(--ink)}
}
/* the one break in the grid: a pull quote reaching back into the index */
.dgw .pq{margin:12px 0 24px;padding-top:18px;border-top:1px solid var(--ink)}
.dgw .pq .tcap{margin-top:6px}
.dg > .pq{grid-column:2 / -1}
@container (min-width:760px){.dg > .pq{grid-column:2 / span 9}}

/* ---------- menu panes: a locked head, the reading scrolls beneath ---------- */
.right .page{color:var(--ink)}
body.menu .right .page a{color:var(--ink)}
.phead{position:sticky;top:0;z-index:3;background:#fff;padding-bottom:24px}
/* the pane's own scroll position is managed in script while the menu
   scrolls away, so nothing may re-anchor it */
.page{overflow-anchor:none}
/* Credits: the list starts just below the PDF link */
.page.crp .phead{padding-bottom:12px}
.page.crp .pbody > .crhead{padding-bottom:12px}
.page.crp .pbody > .crg:not([hidden]):not(.crg:not([hidden]) ~ *) .crera{margin-top:0}
/* MENU SCROLL: SCROLL AWAY (dev bar: Menu scroll), narrower widths. As the
   pane scrolls, the dropdown items scroll up with it and disappear; the
   selected one rises only as far as the first item's place and stays as
   the title (script). The selected item passes over the others. */
.page.awmode{background:transparent}
/* the real list stands aside so its copies in the pane take the clicks */
body.awon .rhead{pointer-events:none}
body.awon .rnav > a,body.awon .rnav > button{pointer-events:auto}
.page.awmode .dgw{background:#fff}
.page.awmode .awcap{position:sticky;top:0;z-index:4;background:#fff}
.page.awmode .phead{background:transparent;pointer-events:none}
.page.awmode .phead .crhead{background:#fff;pointer-events:auto;box-shadow:0 -12px 0 #fff,0 12px 0 #fff}
.page.awmode .awi{position:absolute;z-index:2;display:block;box-sizing:border-box;margin:0;
  white-space:nowrap;overflow:hidden;text-decoration:none}
.page.awmode .awi:not(.awt):hover{background:var(--ground) !important;color:var(--ink) !important}
.dgw .ph1{align-items:start}
.dgw .phl{color:#6b6b72;padding-top:6px}
html.hamb .page .ph1,html.m .page .ph1{display:none !important}
.pbody{padding-bottom:48px}
.dgw .pgl > .tl{margin-bottom:18px}
.dgw .pgl > .tl + .ts,.dgw .pgl > .tl + .ilm{margin-top:12px;padding-top:18px;border-top:2px solid var(--ink);margin-bottom:24px}
.dgw .pgl > .fd > .cvdl{margin-bottom:24px}

/* ---------- Credits ---------- */
.dgw .crhead{row-gap:24px;align-items:start}
.crsw{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.crsel{display:flex;gap:6px;margin-left:-6px}
.fb{border:0;background:none;padding:0 6px;font-family:var(--m);font-weight:500;font-size:var(--S);line-height:var(--SL);
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink);cursor:pointer;white-space:nowrap}
.fb:hover{background:var(--ground)}
.fb.on{background:var(--accbg);color:var(--acc-on)}
.crf{display:flex;flex-wrap:wrap;gap:6px 0;margin-left:-6px;align-self:start}
.crf .pair{display:flex;white-space:nowrap}
.dgw .crdl{text-align:right}
.ln{display:none}
@container (max-width:599px){
  .crsw{flex-direction:row;flex-wrap:wrap;align-items:baseline;gap:6px 18px}
  .crf{margin-top:24px}
  .dgw .crdl{margin-top:24px}
  .lw{display:none}.ln{display:inline}
}
.dgw .crera{margin:36px 0 0;padding:18px var(--gm) 12px;border:0;position:relative;
  font:inherit;letter-spacing:normal;text-transform:none}
.dgw .crera::before,.dgw .ent::before{content:'';position:absolute;left:var(--gm);right:var(--gm);top:0}
.dgw .crera::before{border-top:2px solid var(--ink)}
.dgw .ent::before{border-top:1px solid #e3e2dd}
.dgw .ent{position:relative;padding:12px var(--gm);margin:0}
.dgw .crg{margin:0}
.dgw .t{margin:0;font-family:var(--m);font-weight:600;font-size:var(--S);line-height:var(--SL);color:var(--ink)}
.dgw .r{margin:0;font-family:var(--m);font-weight:400;font-size:var(--S);line-height:var(--SL);color:var(--ink)}
.dgw .co{margin:0;font-family:var(--m);font-weight:400;font-size:var(--S);line-height:var(--SL);color:#6b6b72}
.d-year,.co-d,.co-donly{display:none}
@container (max-width:599px){.d-tags{display:none}}

/* MENU PANES BY BREAKPOINT. Below full width the index follows the window,
   not the pane: nav blocks stacked (<=820) - a one-column index; reel gone
   (<=640) and phone - no index, its contents on a line above their block.
   With one column the index carries only short things (a credit's year);
   the Credits controls and figure captions take the no-index layout. */
html.vert:not(.novid):not(.m) .page .dgw{--dn:6;--dix:1;--fs:2;--gg:20px}
html.vert:not(.novid):not(.m) .page .dg{display:grid}
html.vert:not(.novid):not(.m) .page .dg.crhead,
html.novid .page .dg,html.m .page .dg{display:block}
html.vert .page .dgw .frow,html.m .page .dgw .frow{display:block}
html.vert .page .dgw .frow .tcap,html.m .page .dgw .frow .tcap{margin-top:6px}
html.vert .page .crsw,html.m .page .crsw{flex-direction:row;flex-wrap:wrap;align-items:baseline;gap:6px 18px}
html.vert .page .crf,html.m .page .crf{margin-top:24px}
html.vert .page .dgw .crdl,html.m .page .dgw .crdl{margin-top:24px}
html.vert .page .lw,html.m .page .lw{display:none}
html.vert .page .ln,html.m .page .ln{display:inline}
html.vert .page .d-tags,html.m .page .d-tags{display:none}
html.vert:not(.novid):not(.m) .page .d-full{display:none}
html.vert:not(.novid):not(.m) .page .d-year{display:block}

/* ---------- nav pages ---------- */
.np .npin{padding:0 0 72px}
html.m .np .npin{padding-bottom:54px}
.np .npm{margin:0 0 34px}
.np .npintro{margin:0 0 30px;padding:0 var(--gm) 30px;border:0;position:relative}
.np .npintro::after{content:'';position:absolute;left:var(--gm);right:0;bottom:0;border-top:2px solid var(--ink)}
.np .npintro:last-child::after{display:none}
.np .npintro .fd{display:flex;flex-direction:column;gap:18px}
.np .npintro .tl{margin:0;max-width:none;font-size:var(--L);line-height:var(--LL);color:var(--ink)}
.np .npintro .npnote{margin:0;color:#6b6b72}
.np .npsec2{margin-top:36px;padding-top:18px;position:relative}
.np .npsec2::before{content:'';position:absolute;left:var(--gm);right:0;top:0;border-top:2px solid var(--ink)}
.np .npg{margin-right:0;padding-left:var(--gm)}
/* text blocks between the cards */
.np .npblk{margin:36px 0 0 calc(-1 * var(--gm));padding:18px var(--gm) 0;border:0;position:relative;row-gap:18px}
.np .npblk::before{content:'';position:absolute;left:var(--gm);right:0;top:0;border-top:2px solid var(--ink)}
.np .npg > .npblk + .it{margin-top:36px}
@container (max-width:599px){.np .npblk .ts6{margin-bottom:18px}}
/* full-width paragraphs: a CMS checkbox on each text block (the intro and
   every block between the cards) sets its text across index and field
   together; a block's label then sits on its own line above
   (dev bar: Nav text - all blocks at once) */
html[data-npfull="on"] .np .npintro > .fd,
html[data-npfull="on"] .np .npblk > .fd,
html[data-npfull="on"] .np .npblk > .ix{grid-column:1 / -1}
html[data-npfull="on"] .np .bw{max-width:none}
/* the same per-block option in the menu panes (About items, Contact) */
html[data-npfull="on"] .page .pgl > p.fd,
html[data-npfull="on"] .page .pgl > div.fd:not(.ilm){grid-column:1 / -1}

/* ---------- project cards: meta stacked in the index, title in the field ---------- */
.feed .it,.np .it{padding:18px 18px 24px;margin-top:18px}
.ci{display:grid;grid-template-columns:calc(var(--ixw) - 18px) minmax(0,1fr);column-gap:var(--gg);align-items:start}
@container (max-width:599px){.ci{display:block}.ci .meta{margin-bottom:6px}}
.ci .meta{margin:0;font-family:var(--m);font-weight:500;font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.feed .ci .ttl,.np .ci .ttl{font-family:var(--d);font-weight:700;font-stretch:112.5%;font-size:var(--L);line-height:var(--LL);letter-spacing:-.005em}
.ci .blurb{margin:6px 0 0;font-family:var(--m);font-size:var(--S);line-height:var(--SL);color:#2c2c30;max-width:none}
@container (min-width:760px){.ci .blurb{max-width:var(--b6)}}

/* ---------- project spaces: facts in the index, reading in the field;
   desktop: the field stops where column 12 begins ---------- */
.feed .pdin,.np .pdin{padding:24px var(--gm) 36px 18px}
.feed .pdin{padding-right:18px}
.dgw .pdg{display:grid;grid-template-columns:calc(var(--ixw) - 18px) minmax(0,1fr);column-gap:var(--gg);row-gap:24px;align-items:start}
@container (min-width:760px){.dgw .pdg{grid-template-columns:calc(var(--ixw) - 18px) calc(8 * var(--col) + 7 * var(--gg))}}
.dgw .pdg > .pdfacts,.dgw .pdg > .pdcap{grid-column:1}
.dgw .pdg > .pdf{grid-column:2}
.dgw .pdcap{align-self:end}
.dgw .pdfacts{margin:0;display:flex;flex-direction:column;gap:12px;font-family:var(--m);font-weight:500;font-size:var(--S);
  line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase}
.dgw .pdfacts div{display:block;padding:0;border:0}
.dgw .pdfacts dt{color:#6b6b72}
.dgw .pdfacts dd{margin:0;color:var(--ink)}
.dgw .pdrole{margin:0 0 18px}
.dgw .pdq{margin:0 0 0 var(--pqb);padding-top:18px;border-top:1px solid var(--ink);max-width:none}
.dgw .pdq .tcap{margin-top:6px}
.dgw .pdcl{margin:0 0 6px}
.dgw .pdcues{display:grid;gap:12px}
.dgw .pdst{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.dgw .pdst .img{aspect-ratio:4/3}
.dgw .pdst .img:nth-child(2){background:linear-gradient(200deg,#c2c2c2,#707070 60%,#2e2e2e)}
.dgw .pdst .img:nth-child(3){background:linear-gradient(160deg,#b8b8b8,#646464 60%,#282828)}
@container (max-width:599px){
  .dgw .pdg{display:block}
  .dgw .pdg > * + *{margin-top:18px}
  .dgw .pdg > .pdcap + .pdf{margin-top:6px}
}
.feed .pd .shb,.np .pd .shb{right:calc(var(--gm) + 4px)}

/* ---------- blog posts: the postcard and the phone's open card ---------- */
.bp .bpc{padding:34px 0 40px}
.bp .pohead{row-gap:12px;margin-bottom:24px;align-items:start}
.dgw .pob2 .poap .ap{background:var(--ground);margin:0 0 24px}
.right .bobody{padding:2px 0 16px}
html.cardopen .right .pfeat.bopen .bobody{padding:14px 0 18px}
.dgw .poend{margin:26px 0 0;padding:14px var(--gm) 0}

/* ---------- back to top ---------- */
/* the symbol alone, no block: drawn as the difference against whatever
   lies beneath, like the close crosses */
.btt{position:fixed;z-index:150;width:36px;height:36px;padding:0;border:0;background:none;color:#fff;
  mix-blend-mode:difference;display:none;align-items:center;justify-content:center;cursor:pointer}
html.m .btt{width:44px;height:44px}
html.preview .btt{position:absolute}
.btt svg{width:11px;height:23px;overflow:visible;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:square}
.btt:hover{mix-blend-mode:normal;color:var(--acc-text)}
.btt.on{display:flex;animation:bttin 1s cubic-bezier(.2,.7,.2,1) both}
.btt.on .stem{transform-origin:8px 8px;animation:bttstem 1s linear both}
@keyframes bttin{from{opacity:0;transform:rotate(-720deg)}20%{opacity:1}to{opacity:1;transform:none}}
@keyframes bttstem{0%,55%{transform:scaleY(0)}100%{transform:scaleY(1)}}
@media(prefers-reduced-motion:reduce){.btt.on,.btt.on .stem{animation:none}}

/* MEDIA - no saving from the page: no long-press save sheet (iOS), no
   dragging an image out, no right-click Save (script) */
img,video,.img,.pimg,.hl .box,.it,.vstage{-webkit-touch-callout:none;-webkit-user-drag:none;user-select:none}

/* phone: with a menu pane open, the cards behind it hold still */
html.m body.page-open .rcol{overflow-y:hidden}

/* =====================================================================
   PROTOTYPE ONLY - the phone preview frame and the dev bar
   ===================================================================== */
/* On a real phone the document scrolls, which lets the browser collapse
   its address bar, and the bar is genuinely fixed to the viewport. The
   preview frame carries a transform (that is what pins fixed children to
   the frame), which demotes position:fixed to absolute - so inside the
   preview only, the left pane scrolls internally instead. */
html.preview body{background:#26262a;display:flex;align-items:center;justify-content:center;overflow:hidden}
/* the bezel is drawn outside the box, so it doesn't eat into the frame */
html.preview #app{position:relative;overflow:hidden;background:var(--ground);border:0;
  box-shadow:0 0 0 11px #101014;border-radius:30px;transform:translate(0);
  width:800px;height:390px;max-width:92vw;max-height:92vh}
html.preview.pport #app{width:390px;height:800px}
html.preview #app::-webkit-scrollbar{width:0}
html.preview .takeover{position:absolute}
html.preview body:not(.entered) #app{overflow:hidden}
html.preview.m body.entered{overflow:hidden;height:100%}
html.preview.m body.entered .stage{height:100%;overflow:hidden}
html.preview.m body.entered .left{height:100%;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch}
/* a dark pill marking where the top of the phone is */
.notch{display:none}
html.preview.m .notch{display:block;position:absolute;z-index:95;background:#101014;
  border-radius:14px;pointer-events:none}
html.preview.m[data-turn="up"] .notch{top:9px;left:50%;width:92px;height:26px;transform:translateX(-50%)}
html.preview.m[data-turn="down"] .notch{bottom:9px;left:50%;width:92px;height:26px;transform:translateX(-50%)}
html.preview.m[data-turn="cw"] .notch{right:9px;top:50%;width:26px;height:92px;transform:translateY(-50%)}
html.preview.m[data-turn="ccw"] .notch{left:9px;top:50%;width:26px;height:92px;transform:translateY(-50%)}
/* one line; on narrow windows it scrolls sideways rather than wrapping */

/* ================= CMS CONTENT (theme additions) ================= */
/* section label: Plex Mono 600 caps under a 2px rule */
.dgw .tsl{margin:28px 0 0;padding-top:10px;border-top:2px solid var(--ink);font-family:var(--m);font-weight:600;
  font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;text-transform:uppercase}
/* a block ticked "full width" runs across the index and the field */
.dgw .fw{grid-column:1 / -1;max-width:none}
.dgw .tr{text-align:right}
.dgw .pfig img{display:block;width:100%;height:auto}
/* WordPress's own alignment and screen-reader helpers */
.screen-reader-text{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);white-space:nowrap}
/* the language mark stays out of sight until a translation is published */
html.nolang .langzone{visibility:hidden}
/* a page at its own address: the grid on the ground, no panes */
html.doc,html.doc body{overflow:auto;height:auto}
.docpage{box-sizing:border-box;width:100%;max-width:1100px;margin:0 auto;padding:28px 0 72px;container-type:inline-size;background:#fff;min-height:100vh}
.dochome{margin:0 0 40px;padding:0 28px;font-family:var(--d);font-weight:700;font-size:28px;text-transform:uppercase;letter-spacing:-.01em}
.dochome a{color:var(--ink);text-decoration:none}
.dochome a{display:inline-block;padding:4px 8px;margin:-4px -8px}
/* hover: the accent block, as on every other link - flat colour or the field image */
.dochome a:hover{background:var(--accbg);background-size:cover;background-position:left top;color:var(--acc-on)}
/* "Back to / TIM LENKIEWICZ.com": the small lines in Plex Mono caps */
.dochome .dbk{display:block;font-family:var(--m);font-weight:500;font-size:var(--S);line-height:var(--SL);letter-spacing:.08em;margin-bottom:2px}
.dochome .dnm{display:block}
.dochome small{font-family:var(--m);font-weight:500;font-size:var(--S);letter-spacing:.08em;text-transform:none}

/* =====================================================================
   HOLDING PAGE - Private until launch. The masthead as the site draws it
   where the reel gives way (ink panel, buzz words on accent blocks, the
   name), a line of news, and the social links as nav blocks.
   ===================================================================== */
html.hold,html.hold body{margin:0;background:var(--ground)}
.hold{min-height:100vh;min-height:100svh;display:flex;flex-direction:column;color:var(--ink);font-family:var(--d)}
.hmast{position:relative;flex:none;background:var(--mastbg);container-type:inline-size;overflow:hidden;
  padding:11px 0 1.4vw}
.hline{display:flex;justify-content:flex-end;gap:.45em;margin:0 1.8cqw 0 0;font-weight:200;
  font-size:clamp(9px,1.45cqw,15px);letter-spacing:.34em;line-height:1;text-transform:uppercase;color:var(--acc-on);white-space:nowrap}
.hline span{background:var(--accbg);padding:.42em .2em .42em .54em}
@container (max-width:560px){
  .hline{letter-spacing:.12em;gap:.35em}
  .hline span{padding:.42em .3em .42em .42em}
}
.hname{margin:max(6px,.5cqw) 0 0 1.6cqw;color:#fff;font-weight:700;font-stretch:100%;
  font-size:11.5cqw;line-height:.8;letter-spacing:-.005em;text-transform:uppercase;white-space:nowrap}
.hname span,.hmsg span{display:inline-block}
/* the message: as wide as the name, in the accent (the field image where it is on) */
.hmsg{margin:0;padding:1.4vw 0 0 1.6vw;visibility:hidden;white-space:nowrap;
  font-weight:200;font-stretch:100%;font-size:40px;line-height:1;letter-spacing:-.005em;text-transform:uppercase}
.hmsg span{color:var(--acc);background:var(--accbg);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
html.hold[data-field="on"] .hmsg span{background-size:100vw 100vh;background-attachment:fixed;background-position:0 0;background-repeat:no-repeat}
.hlinks{display:flex;margin-top:auto;border-top:1px solid var(--ink);border-bottom:1px solid var(--ink)}
.hblk{flex:1;display:flex;justify-content:space-between;align-items:center;gap:10px;min-width:0;
  padding:13px 14px 12px;border-right:1px solid var(--ink);color:var(--ink)}
.hblk:last-child{border-right:0}
.hblk .w{font-weight:200;font-stretch:100%;text-transform:uppercase;line-height:.9;letter-spacing:-.005em;
  font-size:clamp(22px,3.4vw,46px)}
.hblk .ic{flex:none;width:clamp(20px,1.9vw,28px);height:clamp(20px,1.9vw,28px);color:var(--acc)}
.hblk .ic svg{display:block;width:100%;height:100%}
.hblk:hover .ic,.hblk:focus-visible .ic{color:var(--acc-on)}
html.hold[data-field="on"] .hblk:not(:hover):not(:focus-visible) .ic{color:var(--ink)}
.hblk:hover,.hblk:focus-visible{background:var(--accbg);color:var(--acc-on)}
.hblk:focus-visible{outline-color:var(--acc-on);outline-offset:-5px}
.hcopy{margin:0;padding:12px var(--pad) 14px;font-family:var(--m);font-size:11px;letter-spacing:.08em;color:var(--dim)}
/* the field image: one picture the size of the window behind every block */
html.hold[data-field="on"] .hline span,html.hold[data-field="on"] .hblk:hover,html.hold[data-field="on"] .hblk:focus-visible{
  background-size:100vw 100vh;background-attachment:fixed;background-position:0 0;background-repeat:no-repeat}
@media (max-width:820px){
  .hlinks{flex-direction:column}
  .hblk{border-right:0;border-bottom:1px solid var(--ink);padding:14px var(--pad) 13px}
  .hblk:last-child{border-bottom:0}
  .hblk .w{font-size:30px}
}
/* a section label straight after a post's headline sits close under it */
.dgw .pob2 > .tsl:first-child{margin-top:0}

/* PRIVACY NOTICE - its text one step below the post size; tables across
   the index and the field, ruled like the rest of the type */
.privdoc{--S:13px;--SL:19px}
html.m .privdoc{--S:11px;--SL:16px}
.dgw .ptab{margin:0 0 24px;overflow-x:auto}
.dgw .ptab figure{margin:0}
.dgw .ptab table{width:100%;border-collapse:collapse;font-family:var(--m);font-size:var(--S);line-height:var(--SL);color:#2c2c30}
.dgw .ptab table,.dgw .ptab thead,.dgw .ptab tfoot,.dgw .ptab tr,.dgw .ptab th,.dgw .ptab td{border:0}
.dgw .ptab th,.dgw .ptab td{text-align:left;vertical-align:top;padding:8px 14px 8px 0;border-bottom:1px solid var(--rule)}
.dgw .ptab th:last-child,.dgw .ptab td:last-child{padding-right:0}
.dgw .ptab th{font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink);border-bottom-color:var(--ink)}
.dgw .ptab table{border-top:2px solid var(--ink)}
/* in the postcard, a heading sits in the index beside its first paragraph,
   and the pair carries the section rule */
.dgw .pob2 > .pvix,.dgw .pob2 > .pvix + .fd{margin-top:28px;padding-top:10px;border-top:2px solid var(--ink)}
.dgw .pob2 > .pvix:first-child,.dgw .pob2 > .pvix:first-child + .fd{margin-top:0}
.dgw .pob2 > .pvix{margin-bottom:0;font-size:11px}
.dgw .ptab figcaption{margin-top:8px;font-family:var(--m);font-size:var(--S);color:var(--dim)}
.dgw .pob2 > .pvix + .ptab table{border-top:0}

/* =====================================================================
   STAGE 2 - projects from the CMS
   ===================================================================== */
/* card photographs (the gradients above stand in where a card has none);
   the phone takes its own crop where there is one */
/* the picture: covering the card, framed in the CMS (x %, y %, zoom),
   the desktop framing or the phone's own */
.it.hasimg{background-image:none}
.cimg{position:absolute;inset:0;z-index:-1;overflow:hidden;filter:var(--imgf,none);pointer-events:none}
.cimg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;max-width:none}
.cimg .cimm,html.m .cimg .cimd{display:none}
html.m .cimg .cimm{display:block}
/* image treatment, per card, over the site setting */
.it[data-treat="colour"] .cimg{filter:none}
.it[data-treat="grey"] .cimg{filter:grayscale(1)}
.it[data-treat="xpro"] .cimg{filter:url(#xpro)}
/* a fourth or later nav block */
.blk.bx{flex:1.7}
/* media in panes, spaces and posts: always full colour */
.pfig video{display:block;width:100%;height:auto;background:#000}
.img.vidr{aspect-ratio:auto;background:#000}
.pdv .img.pimg2{aspect-ratio:auto;background:none}
.pdv .img.pimg2 img{display:block;width:100%;height:auto}
.pdh{margin:0 0 24px}
/* facade: the site's own still, play mark and title until pressed */
.emb{position:relative;display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:16/9;
  padding:0;border:0;overflow:hidden;cursor:pointer;color:#fff;
  background:linear-gradient(146deg,#5d6772,#2a3036 60%,#14171b)}
.emb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.emb i{position:relative;z-index:1;width:58px;height:58px;border:1px solid rgba(255,255,255,.75);display:flex;
  align-items:center;justify-content:center;background:rgba(0,0,0,.25)}
.emb i svg{width:14px;height:16px;fill:#fff;margin-left:3px}
.emb:hover i,.emb:focus-visible i{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
.emb:hover i svg,.emb:focus-visible i svg{fill:var(--acc-on)}
.embt{position:absolute;left:0;bottom:0;z-index:1;max-width:100%;padding:6px 9px;background:#fff;color:var(--ink);
  font-family:var(--m);font-size:10px;letter-spacing:.1em;text-transform:uppercase;line-height:1.4;text-align:left;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.emb-soundcloud{aspect-ratio:3/1}
.embf{position:relative;width:100%;aspect-ratio:16/9;background:#000}
.embf.embsc{aspect-ratio:auto;height:300px;background:none}
.embf iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
/* SoundCloud's widget, out of sight - or in the player's place when a
   phone won't let the site start it */
iframe.scw{position:fixed;left:-9999px;top:0;width:10px;height:10px;border:0}
iframe.scw.scvis{position:static;width:100%;height:120px;margin-top:8px}
.ap.scshow{height:auto;flex-wrap:wrap;padding-bottom:8px}
/* related posts: compact lines, newest 3 (pinned first), then the rest */
.pdrel ul{margin:0;padding:0;list-style:none;border-top:1px solid var(--rule)}
.pdrel li{border-bottom:1px solid var(--rule)}
.pdrel li[hidden]{display:none}
.pdrel a{display:flex;gap:14px;align-items:baseline;padding:8px 0;color:var(--ink)}
.rld{flex:none;width:7.5em;font-family:var(--m);font-size:var(--S);letter-spacing:.06em;color:var(--dim);text-transform:uppercase}
.rlt{font-weight:700;font-stretch:100%;text-transform:uppercase;font-size:14px;line-height:1.3;letter-spacing:-.005em}
.pdrel a:hover .rlt{background:var(--accbg);color:var(--acc-on);box-decoration-break:clone;-webkit-box-decoration-break:clone}
.relall{margin:10px 0 0;padding:6px 10px;border:1px solid var(--ink);background:none;cursor:pointer;color:var(--ink);
  font-family:var(--m);font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.relall:hover{background:var(--accbg);border-color:var(--acc);color:var(--acc-on)}
html[data-capal="top"] .dgw .pdcap{align-self:start}
/* an open card: its photograph in full colour, whatever the treatment */
.it.open::before,.it.open .cimg{filter:none}

/* =====================================================================
   PLACEMENT AND CAPTIONS - set per image or media item in the editor
   (assets/js/editor.js): across the field, or inline at the field's left
   or right edge 3, 4 or 5 columns wide; caption in the index at the top or
   foot, or under the picture
   ===================================================================== */
.dgw .img.real{aspect-ratio:auto;background:none}
.dgw .img.real img{display:block;width:100%;height:auto}
.dgw .ilm .ilf .img.real{aspect-ratio:auto;background:none}
.dgw .ilm .ilf .img.vidr{aspect-ratio:auto;background:#000}
.dgw .ilm .ilf .emb{aspect-ratio:16/9}
.dgw .ilm .ilf .emb-soundcloud{aspect-ratio:3/1}
html .dgw .frow.cb{align-items:end}
html .dgw .frow.cu > .ix{grid-column:var(--fs) / -1;grid-row:2;margin-top:6px}
html[data-capal="top"][data-cap="ix"] .dgw .ilm.cb .ilf.ilf{align-items:end}
@container (min-width:760px){
  html[data-cap="ix"] .dgw .ilm.ic3:not(.ilr) .ilf{grid-column:1 / span 6}
  html[data-cap="ix"] .dgw .ilm.ic3:not(.ilr) .ilf > .img{grid-column:4 / span 3}
  html[data-cap="ix"] .dgw .ilm.ic3:not(.ilr) .ilt{grid-column:7 / -1}
  html[data-cap="ix"] .dgw .ilm.ic3.ilr .ilt{grid-column:4 / -4}
  html[data-cap="ix"] .dgw .ilm.ic3.ilr .ilf > .img{grid-column:-4 / -1}
  html[data-cap="ix"] .dgw .ilm.ic3.cu:not(.ilr) .ilf > figcaption{grid-column:4 / span 3;grid-row:2;margin-top:6px}
  html[data-cap="ix"] .dgw .ilm.ic3.cu.ilr .ilf > figcaption{grid-column:-4 / -1;grid-row:2;margin-top:6px}
  html[data-cap="ix"] .dgw .ilm.ic4:not(.ilr) .ilf{grid-column:1 / span 7}
  html[data-cap="ix"] .dgw .ilm.ic4:not(.ilr) .ilf > .img{grid-column:4 / span 4}
  html[data-cap="ix"] .dgw .ilm.ic4:not(.ilr) .ilt{grid-column:8 / -1}
  html[data-cap="ix"] .dgw .ilm.ic4.ilr .ilt{grid-column:4 / -5}
  html[data-cap="ix"] .dgw .ilm.ic4.ilr .ilf > .img{grid-column:-5 / -1}
  html[data-cap="ix"] .dgw .ilm.ic4.cu:not(.ilr) .ilf > figcaption{grid-column:4 / span 4;grid-row:2;margin-top:6px}
  html[data-cap="ix"] .dgw .ilm.ic4.cu.ilr .ilf > figcaption{grid-column:-5 / -1;grid-row:2;margin-top:6px}
  html[data-cap="ix"] .dgw .ilm.ic5:not(.ilr) .ilf{grid-column:1 / span 8}
  html[data-cap="ix"] .dgw .ilm.ic5:not(.ilr) .ilf > .img{grid-column:4 / span 5}
  html[data-cap="ix"] .dgw .ilm.ic5:not(.ilr) .ilt{grid-column:9 / -1}
  html[data-cap="ix"] .dgw .ilm.ic5.ilr .ilt{grid-column:4 / -6}
  html[data-cap="ix"] .dgw .ilm.ic5.ilr .ilf > .img{grid-column:-6 / -1}
  html[data-cap="ix"] .dgw .ilm.ic5.cu:not(.ilr) .ilf > figcaption{grid-column:4 / span 5;grid-row:2;margin-top:6px}
  html[data-cap="ix"] .dgw .ilm.ic5.cu.ilr .ilf > figcaption{grid-column:-6 / -1;grid-row:2;margin-top:6px}
}
/* inside a project space: the field is 8 columns */
.pdil{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));column-gap:var(--gg);align-items:start}
.pdil > *{grid-row:1;min-width:0}
.pdcu{margin-top:6px}
.dgw .pdcap.cb{align-self:end}
@container (max-width:599px){.pdil{display:block}.pdil figure{margin-bottom:18px}}
.pdil.ic3 > figure{grid-column:1 / span 3}
.pdil.ic3 > .pdilt{grid-column:4 / -1}
.pdil.ic3.ilr > figure{grid-column:-4 / -1}
.pdil.ic3.ilr > .pdilt{grid-column:1 / -4}
.pdil.ic4 > figure{grid-column:1 / span 4}
.pdil.ic4 > .pdilt{grid-column:5 / -1}
.pdil.ic4.ilr > figure{grid-column:-5 / -1}
.pdil.ic4.ilr > .pdilt{grid-column:1 / -5}
.pdil.ic5 > figure{grid-column:1 / span 5}
.pdil.ic5 > .pdilt{grid-column:6 / -1}
.pdil.ic5.ilr > figure{grid-column:-6 / -1}
.pdil.ic5.ilr > .pdilt{grid-column:1 / -6}
html .dgw .pdcap.cb{align-self:end}

/* =====================================================================
   DEVICE SETTINGS, FULL WIDTH AND INLINE PICTURES (editor toolbar)
   ===================================================================== */
/* shown on desktop only / phone only; a paragraph's own alignment on the phone */
html:not(.m) .dgw .hd{display:none !important}
html.m .dgw .hm{display:none !important}
html.m .dgw .mr{text-align:right}
html.m .dgw .ml{text-align:left}
/* Full width: across the index and the field */
.dgw .pdg > .pdfw{grid-column:1 / -1}
.np .npintro > .npfw{grid-column:1 / -1}
.np .npintro > .fd:empty{display:none}
/* inline: the picture floats at the field's edge; the text wraps around
   it and carries on below it at the field's full width */
html .dgw .frow.ilw{align-items:start}
.dgw .ilb{display:flow-root}
.dgw .ilb > p:last-child{margin-bottom:0}
.dgw .ilf2{margin:4px 0 12px}
.dgw .ilf2.fl-l{float:left;margin-right:var(--gg)}
.dgw .ilf2.fl-r{float:right;margin-left:var(--gg)}
.dgw .ilf2 .ilcu{margin-top:6px}
.dgw .ilf2 .ilcu.ilalt{display:none}
.dgw .ilf2.ic3{width:calc(3 * var(--col) + 2 * var(--gg))}
.dgw .ilf2.ic4{width:calc(4 * var(--col) + 3 * var(--gg))}
.dgw .ilf2.ic5{width:calc(5 * var(--col) + 4 * var(--gg))}
@container (max-width:759px){.dgw .ilf2.ic3,.dgw .ilf2.ic4,.dgw .ilf2.ic5{width:calc(50% - var(--gg) / 2)}}
/* narrow panes and the phone: the picture takes the full width, before its
   text (or after it, set for the phone), its caption under it */
@container (max-width:599px){
  .dgw .ilf2{float:none;width:auto !important;margin:0 0 18px}
  .dgw .ilcx{display:none}
  .dgw .ilf2 .ilcu.ilalt{display:block}
}
html.m .dgw .ilf2{float:none;width:auto !important;margin:0 0 18px}
html.m .dgw .ilcx{display:none}
html.m .dgw .ilf2 .ilcu.ilalt{display:block}
html.m .dgw .ilb{display:flex;flex-direction:column}
html.m .dgw .ilb.pm-after > .ilf2{order:2;margin:6px 0 18px}
