/* Self-hosted Inter (subset to the glyphs this site actually uses, 344KB -> 42KB).
   Previously loaded from rsms.me, which cost a third-party DNS+TLS handshake and
   a render-blocking stylesheet that only THEN revealed the font URL - two serial
   round-trips before first paint on every navigation. swap lets text paint
   immediately in the fallback instead of blocking on the font. */
@font-face{
  font-family:'InterVariable';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/InterVariable.woff2') format('woff2-variations');
}
/* the non-variable fallback stack still names plain "Inter"; point it at the
   same self-hosted file so no browser silently drops to a system font */
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/InterVariable.woff2') format('woff2-variations');
}
:root{
  /* ---- measured from the reference ---- */
  --shell-bg:#F6F6F4;      /* body, behind the page field */
  --paper:#FDFDFC;         /* the page field itself */
  --ink:#212223;
  --body:#363636;
  --ink2:#595959;
  --dim:#74767C;
  --faint:#A0A2A6;
  --hair:#E9E9E4;
  --hover:rgba(73,73,73,.04);
  --blue:#60B5FF;
  --link:#1D93D2;
  --teal:#0EB3C9;
  --strip-bg:rgba(73,73,73,.03);
  --strip-line:rgba(73,73,73,.34);
  --grid-line:rgba(73,73,73,.1);
  --sans:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fig:#0D99FF;           /* Figma's selection blue, for the editable heading */
  --container:1024px; --measure:64ch;
  --space-page-top:clamp(44px,5vw,68px);
  --space-header-after:clamp(26px,3vw,36px);
  /* Heading colour is picked as a hue only. Lightness and chroma are fixed per
     theme, so every hue on the wheel lands at the same contrast against the
     page - the slider cannot be dragged into an illegible colour. */
  --hl:46%; --hchroma:.15;
  --slid:rgba(73,73,73,.3);        /* slider track pill */
}
[data-theme="dark"]{
  --hl:84%; --hchroma:.13;
  --slid:rgba(255,255,255,.26);
  --shell-bg:#0E0E0F;
  --paper:#131314;
  --ink:#EDEDEA;
  --body:#C9C9C4;
  --ink2:#A5A5A0;
  --dim:#83837E;
  --faint:#5C5C58;
  --hair:#26262A;
  --hover:rgba(255,255,255,.045);
  --blue:#60B5FF;
  --link:#5FBEEE;
  --teal:#2DD4E8;
  --strip-bg:rgba(255,255,255,.028);
  --strip-line:rgba(255,255,255,.24);
  --grid-line:rgba(255,255,255,.08);
}
[data-theme="dark"] .btn-primary{
  background:linear-gradient(rgb(246,246,243) 0%,rgb(214,214,209) 100%);color:#17171A;
  box-shadow:rgba(0,0,0,.45) 0 1px 2px, rgba(255,255,255,.3) 0 1px inset}
[data-theme="dark"] .btn-primary .bt{color:#17171A}
[data-theme="dark"] .btn-primary::after{background:rgba(0,0,0,.07)}
[data-theme="dark"] .btn-primary:hover .bt{
  background:linear-gradient(90deg,#17171A 0%,#17171A 35%,rgba(23,23,26,.45) 50%,#17171A 65%,#17171A 100%) 0 0/250% 100% text}
[data-theme="dark"] .th{background:#1B1B1D}
[data-theme="dark"] .sw{background:#2A2A2E;border-color:rgba(255,255,255,.16)}
[data-theme="dark"] [data-theme="dark"] input,[data-theme="dark"] .cl{box-shadow:none}
[data-theme="dark"] .ico{box-shadow:0 1px 2px rgba(0,0,0,.45)}
@supports (font-variation-settings:normal){
  :root{--sans:InterVariable,Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;background:var(--shell-bg)}
body{background:var(--shell-bg);color:var(--body);font-family:var(--sans);font-size:14px;line-height:1.55;
 -webkit-font-smoothing:antialiased;letter-spacing:-.006em;
 font-feature-settings:'liga' 1,'calt' 1;font-optical-sizing:auto}
a{color:inherit;text-decoration:none}

/* Keep browser zoom available for reading, but prevent accidental double-tap
   zooming on controls where a second tap is almost always unintentional. */
a,button{touch-action:manipulation}

/* ---------- background: exact reference geometry ---------- */
.pagewrap{background-color:var(--paper);min-height:100vh;position:relative;overflow-x:clip;z-index:0}
.strip{position:fixed;top:-50px;bottom:-50px;width:40px;z-index:1;pointer-events:none;
 background:var(--strip-bg);border-right:1px dashed var(--strip-line)}
.strip.l{left:0}
.strip.r{left:auto;right:0}
.gl{position:fixed;top:0;bottom:0;width:1px;z-index:90;pointer-events:none;border-right:1px dashed var(--grid-line)}
.gl.gA{left:calc(50% - 512px)}   /* container edge */
.gl.gC{left:calc(50% + 512px)}   /* container edge */

.shell{position:relative;z-index:2;width:var(--container);margin:0 auto;padding:0 32px;display:block}

.rv{opacity:0;transform:translateY(14px);transition:opacity .7s cubic-bezier(.16,1,.3,1),transform .7s cubic-bezier(.16,1,.3,1)}
@media(prefers-reduced-motion:reduce){.rv{transition:none;opacity:1;transform:none}}
.rv.in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
}


/* ---------- theme crossfade ----------
   Every surface eases between palettes instead of snapping. The rule is only
   live while .theming is set (a few hundred ms around the switch), so it never
   interferes with hover timing the rest of the time. */
@media(prefers-reduced-motion:no-preference){
  .theming,.theming *,.theming *::before,.theming *::after{
    transition:background-color .34s ease,color .34s ease,border-color .34s ease,
               fill .34s ease,stroke .34s ease,box-shadow .34s ease,
               outline-color .34s ease!important}
}

/* ---------- buttons: exact reference replication ---------- */
.btn-primary{
  cursor:pointer;color:#fff;letter-spacing:-.065px;box-sizing:border-box;
  background:linear-gradient(rgb(35,35,38) 0%,rgb(66,67,71) 100%);
  border:none;border-radius:8px;
  justify-content:center;align-items:center;gap:6px;
  height:40px;padding:0 16px;
  font-family:var(--sans);font-size:13px;font-weight:500;line-height:20px;
  text-decoration:none;display:inline-flex;position:relative;overflow:hidden;
  box-shadow:rgba(64,65,69,.1) 0 1px 2px, rgba(63,64,68,.05) 0 -1px inset;
  transition:color .15s;
}
.btn-primary::after{content:"";border-radius:inherit;opacity:0;pointer-events:none;
 background:rgba(255,255,255,.1);transition:opacity .3s;position:absolute;inset:0}
.btn-primary:hover::after{opacity:1}
.btn-primary .bt{z-index:1;color:#fff;position:relative}
.btn-primary:hover .bt{
  background:linear-gradient(90deg,#fff 0%,#fff 35%,rgba(255,255,255,.5) 50%,#fff 65%,#fff 100%) 0 0/250% 100% text;
  -webkit-text-fill-color:transparent;
  animation:btnTextShimmer .6s ease}
@keyframes btnTextShimmer{0%{background-position:100% 0}100%{background-position:0 0}}

.btn-secondary{
  cursor:pointer;color:var(--ink);letter-spacing:-.065px;box-sizing:border-box;
  background:transparent;border:1px solid var(--hair);border-radius:8px;
  justify-content:center;align-items:center;gap:8px;
  height:40px;padding:0 16px;
  font-family:var(--sans);font-size:13px;font-weight:500;line-height:20px;
  text-decoration:none;transition:background .2s ease-out,border-color .2s ease-out;display:inline-flex;
}
.btn-secondary:hover{background:var(--hover);border-color:var(--faint)}

/* ---------- left nav ---------- */
.nav{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;padding:150px 32px 46px}
.logo{display:block;width:96px;margin-bottom:34px;transition:opacity .22s}
.logo img,.flogo img{display:block;width:100%;height:auto}
/* the source art is a white path, so brightness(0) gives ink and none gives white */
.logo img,.flogo img{filter:brightness(0)}
[data-theme="dark"] .logo img,[data-theme="dark"] .flogo img{filter:none}
.logo:hover{opacity:.62}
.flogo{display:block;width:46px;transition:opacity .22s}
.flogo:hover{opacity:.62}
.nav a.item{display:inline-flex;align-items:center;color:var(--body);font-size:15px;padding:3px 0;width:fit-content;position:relative;transition:color .18s}
.nav a.item:hover{color:var(--ink)}
.nav a.item.mut{color:var(--faint)}
.soon{color:var(--teal);margin-left:8px;position:relative}
.scribble{position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:76px;height:32px;overflow:visible;pointer-events:none}
.scribble path{fill:none;stroke:var(--teal);stroke-width:2;stroke-linecap:round;
 stroke-dasharray:240;stroke-dashoffset:240;animation:draw 1.1s .9s cubic-bezier(.16,1,.3,1) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
.navfoot{margin-top:auto;font-size:14px}
.navfoot .k{color:var(--dim)}
.navfoot a{color:var(--ink);border-bottom:1px solid var(--hair);transition:border-color .25s,color .25s}
.navfoot a:hover{border-color:var(--link);color:var(--link)}

/* ---------- right rail ---------- */
.sw{width:34px;height:19px;border-radius:100px;background:#E4E4DF;border:1px solid rgba(73,73,73,.18);position:relative;cursor:pointer;transition:background .3s}
.sw i{position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.22);transition:transform .3s cubic-bezier(.16,1,.3,1)}
.sw.on{background:var(--blue)}
.sw.on i{transform:translateX(15px)}

/* ---------- content ---------- */
main{padding:150px 0 0}
.greet{display:flex;align-items:center;gap:8px;color:var(--dim);font-size:13px;margin-bottom:20px}
.greet svg{width:14px;height:14px;stroke:var(--dim);fill:none;stroke-width:1.5}

h1{font-size:44px;font-weight:600;letter-spacing:-.015em;line-height:1.02;color:var(--ink)}
h1 span.b{color:var(--blue)}

.lede{margin-top:18px;font-size:15px;line-height:1.6}
.lede .strong{color:var(--ink);font-weight:500}
.lede p+p{margin-top:14px;color:var(--ink2)}

.cta{display:flex;align-items:center;gap:10px;margin-top:26px}

form{display:flex;gap:8px;margin-top:22px}
input{flex:1;background:var(--paper);border:1px solid var(--hair);border-radius:8px;height:40px;padding:0 13px;font:inherit;font-size:13px;color:var(--ink);outline:0;
 box-shadow:rgba(64,65,69,.05) 0 1px 2px;transition:border-color .2s,box-shadow .2s}
input::placeholder{color:var(--faint)}
input:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(96,181,255,.2)}
.fine{margin-top:10px;font-size:11px;line-height:18px;color:var(--ink2)}
.ok{margin-top:9px;font-size:12px;color:var(--link);opacity:0;transform:translateY(-3px);transition:.4s}
.ok.show{opacity:1;transform:none}

hr.sep{border:0;border-top:1px solid var(--hair);margin:44px 0 0;
 width:100vw;position:relative;left:50%;transform:translateX(-50%)}
section{padding:30px 0 0;scroll-margin-top:30px}
.sl{color:var(--dim);font-size:13px;margin-bottom:14px}
.sl a{color:var(--link)}
.sl-with-link{display:flex;align-items:center;justify-content:space-between;gap:16px}

/* list rows */
.row{display:grid;grid-template-columns:36px 1fr auto;gap:13px;align-items:center;padding:9px 10px;margin:0 -10px;border-radius:9px;transition:background .25s}
.ico{width:36px;height:36px;border-radius:9px;display:grid;place-items:center;font-size:11px;font-weight:500;color:#fff;
 box-shadow:0 1px 2px rgba(0,0,0,.12);transition:transform .35s cubic-bezier(.16,1,.3,1)}
.row:hover .ico{transform:scale(1.06) rotate(-3deg)}
.row .t{display:block;font-size:14px;color:var(--ink);line-height:1.35}
.row .s{display:block;font-size:13px;color:var(--dim)}
.row .yr{font-size:13px;color:var(--dim);white-space:nowrap}

/* simple rows */
.line{display:grid;grid-template-columns:1fr auto;gap:14px;align-items:baseline;padding:10px;margin:0 -10px;border-radius:9px;transition:background .25s}
.line:hover{background:var(--hover)}
.line .t{font-size:14px;color:var(--ink);transition:color .2s;line-height:1.4}
.line:hover .t{color:var(--link)}
.line .d{font-size:13px;color:var(--dim);white-space:nowrap}

/* chips */
.chips{display:flex;flex-wrap:wrap;gap:7px}
.cl{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--hair);background:var(--paper);border-radius:100px;padding:4px 14px 4px 5px;font-size:13px;color:var(--ink2);
 box-shadow:rgba(64,65,69,.05) 0 1px 2px;
 transition:border-color .25s,transform .3s cubic-bezier(.16,1,.3,1),color .25s}
.cl:hover{border-color:var(--blue);color:var(--ink);transform:translateY(-2px)}
/* The box is a fixed 28px slot; the artwork inside is sized per logo so they
   all carry the same optical weight. The slot does no clipping and no
   rounding - a tile already has its own corner radius baked in, and clipping
   it again to a different radius is what made the corners read wrong. */
.cl i{width:28px;height:28px;flex:none;display:grid;place-items:center;
 background:none;overflow:visible}
.cl i img,.cl i svg{display:block;width:var(--s,25px);height:var(--s,25px);
 object-fit:contain}
/* a solid filled tile reads larger than an open mark at the same measurement,
   so the tiles sit smaller to match the glyphs optically */
/* the chip is a pill, so the tiles get a rounder corner than their artwork
   ships with - clipping tighter than the baked radius keeps it clean */
.cl i.tile img{--s:23px;border-radius:31%;overflow:hidden}
/* Wix ships a single fixed brand blue; it is legible in light mode but sinks
   against the dark background, so lift it rather than swap files for one icon */
[data-theme="dark"] .cl i img[src$="wix.svg"]{filter:brightness(1.7) saturate(1.15)}
[data-theme="dark"] .cl i img[src*="mobbin"]{filter:invert(1)}
[data-theme="dark"] .cl i img[src$="framer.svg"]{filter:invert(1)}
/* single-colour marks follow the ink, so they stay legible in either theme */
.cl i.mono svg{fill:var(--ink)}
/* per-logo optical trims: wordmarks and wide marks need more room, dense or
   heavy marks need less, to land on the same apparent size */
.cl i img[src*="wix"]{--s:27px}
.cl i img[src*="mobbin"]{--s:26px}
.cl i img[src*="relume"]{--s:24px}
.cl i img[src*="brilliant"]{--s:24px}
.cl i.mono svg{--s:24px}
/* the marks sit on a neutral plate so dark wordmarks survive dark mode */
.cl.ghost{border-style:dashed;color:var(--faint);background:transparent;box-shadow:none}
.cl.flat{padding:4px 12px}

/* cards */
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
.card{display:block;transition:transform .38s cubic-bezier(.16,1,.3,1)}
.card:hover{transform:translateY(-4px)}
.th{aspect-ratio:16/10;border-radius:8px;overflow:hidden;position:relative;border:1px solid var(--hair);background:#F2F2EF}
.th i{position:absolute;inset:0;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.th b{position:absolute;inset:0;display:grid;place-items:center;z-index:2}
.th.play b::after{content:"";width:0;height:0;border-left:10px solid #fff;border-top:6.5px solid transparent;border-bottom:6.5px solid transparent;
 filter:drop-shadow(0 1px 3px rgba(0,0,0,.45));transition:transform .3s cubic-bezier(.16,1,.3,1)}
.card:hover .th.play b::after{transform:scale(1.25)}
.th .dur{position:absolute;right:6px;bottom:6px;z-index:3;background:rgba(0,0,0,.74);color:#fff;font-size:10px;border-radius:4px;padding:1px 5px}
.card .t{font-size:14px;color:var(--ink);margin-top:9px;line-height:1.35}
.card .s{font-size:13px;color:var(--dim)}
.anything-thumb{isolation:isolate;display:grid;place-items:end start;padding:18px;background:linear-gradient(145deg,#DDE7FF 0%,#B4CAFF 48%,#718DF1 100%);color:#102760}
.anything-thumb::before{content:"";position:absolute;width:65%;aspect-ratio:1;border-radius:28%;right:-5%;top:-18%;background:rgba(255,255,255,.48);box-shadow:-38px 55px 0 rgba(255,255,255,.2);transform:rotate(26deg)}
.anything-thumb span{position:relative;z-index:2;font-size:clamp(25px,3vw,42px);font-weight:600;letter-spacing:-.06em;line-height:.9}
.anything-thumb i{position:absolute;z-index:1;left:18px;top:18px;width:34px;height:34px;border-radius:11px;background:#fff;box-shadow:0 8px 18px rgba(25,52,122,.2)}
.anything-thumb b{inset:auto 22px 18px auto;width:38px;height:38px;place-items:center;border-radius:50%;background:#192F7A;color:#fff;font-size:27px;font-weight:400;line-height:1}

/* photo strip */
.photos{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.ph{aspect-ratio:3/4;border-radius:8px;overflow:hidden;position:relative;border:1px solid var(--hair);display:block}
.ph i{position:absolute;inset:0;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.ph span{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:16px 8px 7px;font-size:12px;color:#fff;
 background:linear-gradient(transparent,rgba(0,0,0,.55))}

.final{padding:30px 0 0}
.final h2{font-size:26px;font-weight:600;letter-spacing:-.02em;line-height:1.1;color:var(--ink)}
.final h2 span{color:var(--blue)}
.final p{color:var(--ink2);margin-top:8px;font-size:15px}

footer{margin-top:44px;padding:18px 0 60px;border-top:1px solid var(--hair);display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;font-size:13px;color:var(--dim)}
footer a{transition:color .2s}
footer a:hover{color:var(--ink)}
footer .fl{display:flex;gap:14px}

/* =======================================================================
   RESPONSIVE
   >1100  three columns, full dashed grid
   1100-880  nav + content, grid lines drop away
   <=880  single column, fixed top bar + slide-in drawer
   ======================================================================= */
@media(max-width:1100px){
  :root{--container:100%;--nav:250px}
  /* the shell drops to two columns here, so the rail must go with it or it
     overflows into the nav. The Mode toggle moves into the nav footer. */
  .gl,  .navmode{display:flex!important}
  /* 56px keeps the nav clear of the 40px edge strip */
  .shell{grid-template-columns:var(--nav) minmax(0,1fr);padding:0 56px}
  main{max-width:640px}
}
@media(max-width:880px){
  .strip{display:none}
  .shell{grid-template-columns:minmax(0,1fr);padding:0 22px}
  main{padding:80px 0 0;max-width:none}
  .mobilebar{display:flex}
  .navmode{display:none}
}
@media(max-width:560px){
  .cta{flex-wrap:wrap;gap:8px}
  .cta .btn-primary,.cta .btn-secondary{flex:1 1 auto;justify-content:center}
  .row{grid-template-columns:32px minmax(0,1fr);row-gap:2px}
  .row .yr{grid-column:2;font-size:12px}
  .ico{width:32px;height:32px}
  .line{grid-template-columns:minmax(0,1fr);row-gap:3px}
  .line .d{font-size:12px}
  .pj .pm{flex-wrap:wrap;gap:4px}
  .pj .pm .yr{width:100%}
  .yrhead{margin-top:26px}
}
@media(max-width:420px){
  form{flex-wrap:wrap}
  form input{flex:1 1 100%}
  form .btn-primary{width:100%;justify-content:center}
  .pagehead h1{font-size:27px}
  h1{font-size:30px}
  }

/* ---------- active nav state ---------- */
.nav a.item.active{color:var(--ink);font-weight:500}
.nav a.item.active::before{content:"";position:absolute;left:-14px;top:50%;width:5px;height:5px;border-radius:50%;
 background:var(--blue);transform:translateY(-50%)}

/* ---------- subpage rhythm ----------
   Standard content pages begin with enough runway below the fixed nav for the
   title to read as a page opening. Their next block stays related, but never
   crowds the header. Hero-led pages retain their own calibrated spacing. */
main:has(.pagehead){padding-top:var(--space-page-top)}
.pagehead{margin-bottom:var(--space-header-after)}
.pagehead:has(.about){margin-bottom:8px}
.pagehead h1{font-size:34px;font-weight:600;letter-spacing:-.022em;line-height:1.08;color:var(--ink)}
.pagehead .sub{margin-top:12px;font-size:15px;line-height:1.6;color:var(--ink2);max-width:44ch}

/* two-role headline: each role wears the mark of the tool it lives in */
.headline{font-size:clamp(30px,5vw,52px);font-weight:700;letter-spacing:-.035em;line-height:1.02;color:var(--ink);max-width:none}
.roles{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;margin-top:16px;
 font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.05;color:var(--ink2)}
.role{display:inline-flex;align-items:center;white-space:nowrap}
.rdot{color:var(--faint)}
.about{margin:20px 0 34px;max-width:60ch}
.about p{font-size:17px;line-height:1.65;color:var(--ink2)}
.about p+p{margin-top:14px}
.ricon{width:.98em;height:.98em;flex:none;display:grid;place-items:center;border-radius:22%}
.ricon svg{width:100%;height:100%;display:block}
.ricon.fig svg{width:66%;height:auto}          /* the Figma mark is tall and needs breathing room */
.ricon.yt{background:#fff;padding:0}
.ricon.yt svg{width:96%;height:auto}
.rimg{height:1.5em;width:auto;flex:none;display:block}   /* landscape PNG icons: size by height, keep aspect ratio */
.rimg.fig{height:1.55em}
.rimg.yt{height:1.25em}
.pagehead .loc{margin-top:16px;font-size:15px;color:var(--dim)}
.count{color:var(--faint)}

/* ---------- year grouping on list pages ---------- */
.yrhead{display:flex;align-items:center;gap:12px;margin:34px 0 6px;color:var(--dim);font-size:13px}
.yrhead::after{content:"";flex:1;border-top:1px solid var(--hair)}
.yrhead:first-of-type{margin-top:8px}

/* ---------- wide project rows (design page) ---------- */
/* two-up: these thumbnails carry plenty at half width, and the grid lets the
   set be scanned rather than scrolled one screen-height at a time */
.proj{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:32px 26px;margin-top:18px}
.pj{display:block;padding:0;border-bottom:0}
@media(max-width:760px){.proj{grid-template-columns:1fr;gap:26px}}
.pj .pth{aspect-ratio:16/9;border-radius:8px;overflow:hidden;position:relative;border:1px solid var(--hair);background:#F2F2EF}
[data-theme="dark"] .pj .pth{background:#1B1B1D}
.pj .pth i{position:absolute;inset:0;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.pj .pm{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-top:11px}
.pj .pm .t{font-size:15px;color:var(--ink);font-weight:500}
.pj .pm .yr{font-size:13px;color:var(--dim);white-space:nowrap}
.pj .pm .s{font-size:13.5px;color:var(--dim);margin-top:3px}
.pj .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.content-page{max-width:920px;margin:0 auto;padding:clamp(54px,8vw,104px) 0}.back-link{display:inline-block;color:var(--link);font-size:14px;margin-bottom:clamp(32px,5vw,58px)}.content-hero{display:grid;grid-template-columns:minmax(0,1fr) 240px;gap:clamp(32px,7vw,100px);padding-bottom:clamp(42px,7vw,84px);border-bottom:1px solid var(--hair)}.eyebrow{margin:0 0 12px;color:var(--dim);font-size:14px}.content-page h1{margin:0;max-width:780px;font-size:clamp(42px,6vw,74px);letter-spacing:-.055em;line-height:.98}.lead{max-width:680px;margin:23px 0 0;color:var(--ink2);font-size:clamp(19px,2.2vw,25px);line-height:1.45;letter-spacing:-.02em}.content-hero aside{align-self:end;padding-left:20px;border-left:1px solid var(--hair)}.content-hero aside span{display:block;margin-top:20px;color:var(--dim);font-size:12px;text-transform:uppercase;letter-spacing:.07em}.content-hero aside span:first-child{margin-top:0}.content-hero aside p,.content-hero aside strong{display:block;margin:6px 0 0;font-size:14px;line-height:1.5}.longform,.article-body{max-width:680px;padding-top:clamp(42px,7vw,82px)}.longform section,.article-body h2{margin-top:clamp(34px,5vw,58px)}.longform section:first-child{margin-top:0}.longform h2,.article-body h2{margin-bottom:12px;font-size:clamp(25px,3vw,34px);letter-spacing:-.04em}.longform p,.article-body p{margin:0;color:var(--ink2);font-size:18px;line-height:1.7}.article-page>header{padding-bottom:clamp(34px,6vw,68px);border-bottom:1px solid var(--hair)}.article-page h1{font-size:clamp(42px,6vw,68px)}@media(max-width:700px){.content-hero{grid-template-columns:1fr}.content-hero aside{padding:18px 0 0;border-left:0;border-top:1px solid var(--hair)}}

.article-page h1{max-width:720px;font-size:clamp(36px,4.5vw,54px);line-height:1.02}.article-page .lead{font-size:18px;line-height:1.7;letter-spacing:0}.article-body a{color:var(--link);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;overflow-wrap:anywhere}

/* Article continuation */
.article-pager{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:clamp(48px,8vw,72px);padding-top:20px;border-top:1px solid var(--hair)}
.article-pager-link{position:relative;display:flex;min-height:132px;flex-direction:column;justify-content:center;gap:7px;padding:20px 48px 20px 20px;border:1px solid var(--hair);border-radius:10px;color:var(--ink);transition:border-color .2s,background .2s}
.article-pager-link:hover{border-color:var(--link);background:color-mix(in srgb,var(--link) 6%,transparent)}
.article-pager-link span{color:var(--link);font-size:13px;font-weight:500}.article-pager-link strong{font-size:16px;line-height:1.28;letter-spacing:-.02em}.article-pager-link b{position:absolute;right:20px;top:50%;font-size:20px;font-weight:400;transform:translateY(-50%);color:var(--link)}
.article-pager-link.next{text-align:right;padding:20px 20px 20px 48px}.article-pager-link.next b{right:auto;left:20px}
@media(max-width:700px){.article-pager{grid-template-columns:1fr}.article-pager-link,.article-pager-link.next{text-align:left;padding:18px 46px 18px 18px}.article-pager-link.next b{left:auto;right:18px}}

/* ---------- photo page ---------- */
.gal{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
.gal .ph{aspect-ratio:1}
.gal .ph.tall{grid-row:span 2;aspect-ratio:1/2}
@media(max-width:820px){.gal{grid-template-columns:repeat(2,1fr)}}

/* ---------- photography page: filters + masonry gallery ---------- */
.pfilters{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 16px}
.pchip{font:inherit;font-size:14px;font-weight:500;color:var(--ink2);background:none;
 border:1px solid var(--hair);border-radius:999px;padding:8px 16px;cursor:pointer;
 transition:color .2s,background .2s,border-color .2s}
.pchip:hover{color:var(--ink);border-color:var(--faint)}
.pchip.active{color:var(--paper);background:var(--ink);border-color:var(--ink)}
/* CSS-columns masonry: mixed portrait/landscape frames pack tightly */
.pgal{columns:3 240px;column-gap:10px}
.gph{display:block;margin-bottom:10px;border-radius:8px;overflow:hidden;position:relative;
 border:1px solid var(--hair);break-inside:avoid;background:#F2F2EF}
[data-theme="dark"] .gph{background:#1B1B1D}
.gph img{display:block;width:100%;height:100%;object-fit:cover;
 transition:transform .6s cubic-bezier(.16,1,.3,1)}
@media(hover:hover) and (pointer:fine){.gph:hover img{transform:scale(1.03)}}
@media(max-width:600px){.pgal{columns:2 150px;column-gap:8px}.gph{margin-bottom:8px}}

/* =======================================================================
   REAL IMAGERY
   ======================================================================= */
.th img,.ph img,.pj .pth img,.avatar img,.portrait img{
 position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
 transition:transform .7s cubic-bezier(.16,1,.3,1)}
.th::after{content:"";position:absolute;inset:0;box-shadow:inset 0 0 0 1px rgba(73,73,73,.06);border-radius:inherit;pointer-events:none;z-index:1}
[data-theme="dark"] .th::after{box-shadow:inset 0 0 0 1px rgba(255,255,255,.05)}

/* hero portrait */
.hero{display:flex;align-items:flex-start;gap:18px}
.hero .portrait{width:78px;height:78px;border-radius:10px;overflow:hidden;position:relative;flex:none;
 border:1px solid var(--hair);background:#F2F2EF;transition:transform .45s cubic-bezier(.16,1,.3,1)}
[data-theme="dark"] .hero .portrait{background:#1B1B1D}
@media(max-width:560px){.hero{gap:14px}.hero .portrait{width:60px;height:60px}}


/* =======================================================================
   MOBILE BAR + DRAWER
   ======================================================================= */
.mobilebar{display:none;position:fixed;top:0;left:0;right:0;height:58px;z-index:95;
 align-items:center;justify-content:space-between;padding:0 22px;
 background:var(--paper);border-bottom:1px solid var(--hair)}
.mobilebar .logo{margin:0;width:80px;height:18px}
.burger{position:relative;width:40px;height:40px;margin-right:-10px;cursor:pointer;
 background:none;border:0;border-radius:8px;color:var(--ink);transition:background .2s}
.burger:hover{background:var(--hover)}
/* both bars share one centre, so rotating to 0 offset forms a true X */
.burger span{position:absolute;left:50%;top:50%;width:19px;height:1.5px;margin-left:-9.5px;
 background:currentColor;border-radius:2px;transition:transform .34s cubic-bezier(.16,1,.3,1)}
.burger span:first-child{transform:translateY(-3.5px)}
.burger span:last-child{transform:translateY(3.5px)}
.burger[aria-expanded="true"] span:first-child{transform:rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:rotate(-45deg)}


@media(max-width:880px){
  /* declared here, after the base .mobilebar{display:none}, so it wins on source order */
  .mobilebar{display:flex}
  .nav{position:fixed;top:58px;bottom:0;left:0;width:min(82vw,310px);z-index:90;
   background:var(--paper);border-right:1px solid var(--hair);
   padding:24px 26px 30px;height:calc(100% - 58px);overflow-y:auto;
   transform:translateX(-102%);transition:transform .38s cubic-bezier(.16,1,.3,1);
   box-shadow:0 0 40px rgba(0,0,0,.14)}
  .nav.open{transform:none}
  .nav .logo{display:none}   /* the fixed bar already shows it */
  .nav a.item{font-size:16px;padding:7px 0}
  .navfoot{margin-top:auto;padding-top:26px}
  }

/* mode toggle parked in the drawer / nav footer on inner pages */
.navmode{display:flex;align-items:center;gap:9px;margin-top:20px;padding-top:18px;
 border-top:1px solid var(--hair);color:var(--dim);font-size:13px}
body.home .navmode{display:none}
@media(max-width:880px){.navmode{display:flex!important}}

/* focus visibility */
a:focus-visible,button:focus-visible,input:focus-visible,.sw:focus-visible{
 outline:2px solid var(--blue);outline-offset:2px;border-radius:6px}

/* stop the drawer transition from firing on load */
.nav.preload{transition:none}

/* ---------- stats strip ---------- */
.stats{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--hair);border-radius:12px;
 overflow:hidden;background:var(--paper);margin-top:4px}
.stats>div{padding:18px 16px;border-right:1px solid var(--hair);transition:background .25s}
.stats>div:last-child{border-right:0}
.stats .n{font-size:26px;font-weight:600;letter-spacing:-.04em;line-height:1;color:var(--ink)}
.stats .l{font-size:13px;color:var(--dim);margin-top:5px}
@media(max-width:560px){.stats{grid-template-columns:1fr}
 .stats>div{border-right:0;border-bottom:1px solid var(--hair)}
 .stats>div:last-child{border-bottom:0}}


/* =======================================================================
   HERO - portrait beside the text, with a pointer-reactive shader
   ======================================================================= */
.hero{display:grid;grid-template-columns:150px minmax(0,1fr);gap:30px;align-items:center;
 padding:52px 0 60px;min-height:300px}
.herotext{min-width:0}
.herotext .cta{margin-top:22px}
/* The portrait is a duotone built from a subject cutout, so each theme gets its
   own mask from the same crop: light mode inks the DARK tones on a light plate,
   dark mode inks the LIGHT tones on a dark plate. Using one mask for both would
   render dark mode as a negative, because a light face is simply less ink. */
.portrait.dither{width:100%;height:auto;aspect-ratio:1/1;
  border-radius:10px;overflow:hidden;
  position:relative;border:0;flex:none;box-shadow:none}
/* the duotone plate stays light in both themes - defended at matching
   specificity so it can't be overridden by the generic dark-mode .hero
   .portrait background rule above. Kept separate from the sizing rule so
   width/aspect-ratio stay at plain specificity and the mobile breakpoints
   below can still override them (bundling this into the sizing rule was
   why the mobile width overrides silently lost in dark mode). */
.portrait.dither,
[data-theme="dark"] .hero .portrait.dither{background:#F0F5FE}
.portrait.dither .ink{position:absolute;inset:0;display:block;
  background:var(--pc,#0939DB);
  -webkit-mask:url(portrait-ink.png) center/cover no-repeat;
  mask:url(portrait-ink.png) center/cover no-repeat;
  transition:background .3s ease}
@media(max-width:760px){
  .hero{grid-template-columns:1fr;gap:22px}
  .portrait.dither{width:112px}
}

/* ---------- home hero: automatic layer selection ---------- */
.hero-select{--h1s:clamp(38px,4.6vw,58px);--hero-weight:500;position:relative;display:inline-block;font-size:var(--h1s);font-weight:var(--hero-weight);letter-spacing:-.025em;line-height:1.06;color:var(--ink);font-variation-settings:'wght' var(--hero-weight)}
.hero-select-text{display:block;transition:font-weight .08s linear}.hero-select::before{content:"";position:absolute;inset:-6px -8px;border:1px solid transparent;border-radius:2px;pointer-events:none;opacity:0;transform:scale(.985);transition:border-color .36s ease,opacity .36s ease,transform .36s cubic-bezier(.16,1,.3,1)}.hero-select.is-selected::before{border-color:var(--fig);opacity:1;transform:none}
.hero-name{position:relative;display:inline-block;font:inherit;transition:color .38s ease,font-weight .12s linear}.hero-name::before{content:"";position:absolute;inset:-6px -7px -6px -.17em;border:1px solid transparent;border-radius:2px;pointer-events:none;opacity:0;transform:scale(.985);transition:border-color .34s ease,opacity .34s ease,transform .34s cubic-bezier(.16,1,.3,1)}.hero-name.is-selected::before{border-color:var(--fig);opacity:1;transform:none}.hero-name.is-emphasized{color:var(--fig)}
.hero-layer-tag,.hero-handle{font-family:var(--sans);font-weight:400;letter-spacing:normal;line-height:1;pointer-events:none}.hero-layer-tag{position:absolute;bottom:calc(100% + 9px);left:-8px;height:17px;padding:0 6px;display:flex;align-items:center;border-radius:3px;background:var(--fig);color:#fff;font-size:10px;font-weight:500;opacity:0;transform:translateY(4px);transition:opacity .32s ease,transform .32s cubic-bezier(.16,1,.3,1)}.hero-select.is-selected .hero-layer-tag{opacity:1;transform:none}
.hero-handle{position:absolute;width:7px;height:7px;background:var(--paper);border:1px solid var(--fig);border-radius:1px;opacity:0;transform:scale(.7);transition:opacity .32s ease,transform .32s cubic-bezier(.16,1,.3,1)}.hero-select.is-selected .hero-handle{opacity:1;transform:none}.hero-handle.tl{top:-9px;left:-11px}.hero-handle.tr{top:-9px;right:-11px}.hero-handle.bl{bottom:-9px;left:-11px}.hero-handle.br{bottom:-9px;right:-11px}
.hero-name-handle{position:absolute;width:7px;height:7px;background:var(--paper);border:1px solid var(--fig);border-radius:1px;opacity:0;transform:scale(.7);transition:opacity .32s ease,transform .32s cubic-bezier(.16,1,.3,1);pointer-events:none}.hero-name.is-selected .hero-name-handle{opacity:1;transform:none}.hero-name-handle.tl{top:-9px;left:calc(-.17em - 4px)}.hero-name-handle.tr{top:-9px;right:-10px}.hero-name-handle.bl{bottom:-9px;left:calc(-.17em - 4px)}.hero-name-handle.br{bottom:-9px;right:-10px}
@media(max-width:560px){.hero-select{font-size:clamp(22px,8vw,34px);letter-spacing:-.045em;white-space:nowrap}.hero-select-text{white-space:nowrap}}
@media(prefers-reduced-motion:reduce){.hero-select::before,.hero-layer-tag,.hero-handle,.hero-name::before,.hero-name-handle{display:none}.hero-select,.hero-select-text,.hero-name{transition:none!important}}

/* -----------------------------------------------------------------------
   EDITABLE HEADING - the h1 behaves like a Figma text layer: hover shows the
   pick outline, click selects it (handles + layer tag) and opens a panel that
   shuffles the typeface and colour. Chrome is drawn by JS into .layer.
   ----------------------------------------------------------------------- */
.layer{--h1s:clamp(38px,4.6vw,58px);
 position:relative;display:inline-block;cursor:pointer;
 /* it's a click target, so dragging across it shouldn't select the words */
 -webkit-user-select:none;user-select:none;
 font-family:var(--ff,var(--sans));font-weight:var(--lw,600);
 font-size:calc(var(--h1s) * var(--fs,1));
 letter-spacing:var(--ls,-.025em);
 /* line box is pinned to the base size, so swapping faces never reflows the hero */
 line-height:calc(var(--h1s) * 1.06);
 color:var(--lc,var(--ink));transition:color .3s ease}
.layer::before{content:"";position:absolute;inset:-6px -8px;border:1px solid transparent;
 border-radius:2px;pointer-events:none;transition:border-color .15s}
.layer:hover::before,.layer:focus-visible::before{border-color:var(--fig)}
.layer:focus-visible{outline:none}
.layer.sel::before{border-color:var(--fig)}

/* corner handles + layer name tag */
.layer .hnd{position:absolute;width:7px;height:7px;background:var(--paper);
 border:1px solid var(--fig);border-radius:1px;pointer-events:none;
 opacity:0;transition:opacity .15s}
.layer.sel .hnd{opacity:1}
.layer .hnd.tl{top:-9px;left:-11px}.layer .hnd.tr{top:-9px;right:-11px}
.layer .hnd.bl{bottom:-9px;left:-11px}.layer .hnd.br{bottom:-9px;right:-11px}
.layer .tag{position:absolute;bottom:calc(100% + 9px);left:-8px;display:flex;align-items:center;gap:4px;
 height:17px;padding:0 6px;border-radius:3px;background:var(--fig);color:#fff;
 font-size:10px;font-weight:500;letter-spacing:.01em;line-height:1;white-space:nowrap;
 pointer-events:none;opacity:0;transform:translateY(3px);transition:opacity .15s,transform .15s}
.layer.sel .tag{opacity:1;transform:none}
.layer .tag svg{width:8px;height:8px;fill:#fff}

/* the chrome lives inside the h1, so it has to opt out of heading typography */
.layer .tag,.figpanel{font-family:var(--sans);font-weight:400;letter-spacing:normal;
 line-height:1;font-variation-settings:normal;font-style:normal;cursor:default}
.layer .tag{font-size:10px;font-weight:500;letter-spacing:.01em}

/* properties panel - two shuffles rather than a wall of options */
/* max-content, so the panel sizes to itself rather than to the layer box it
   sits in - that box changes width with every typeface */
.figpanel{position:absolute;top:calc(100% + 16px);left:-8px;z-index:40;
 width:max-content;max-width:calc(100vw - 44px);
 display:flex;flex-wrap:wrap;align-items:center;gap:12px;
 padding:9px 10px;border-radius:11px;border:1px solid var(--hair);
 background:var(--paper);box-shadow:0 8px 26px rgba(0,0,0,.13),0 1px 2px rgba(0,0,0,.07);
 opacity:0;transform:translateY(-5px) scale(.985);transform-origin:top left;
 pointer-events:none;transition:opacity .16s ease,transform .16s ease}
[data-theme="dark"] .figpanel{background:#1B1B1E;border-color:#303036;
 box-shadow:0 10px 30px rgba(0,0,0,.6)}
.layer.sel .figpanel{opacity:1;transform:none;pointer-events:auto}
.figpanel .grp{display:flex;align-items:center;gap:8px}
.figpanel .lb{font-size:10px;font-weight:500;letter-spacing:.05em;text-transform:uppercase;
 color:var(--dim)}

/* sliders: weight is a real axis on most of the pool, hue rides the fixed
   lightness/chroma above so every position stays legible */
.figpanel input[type=range]{-webkit-appearance:none;appearance:none;background:transparent;
 width:104px;height:22px;margin:0;cursor:pointer}
.figpanel input[type=range]::-webkit-slider-runnable-track{height:10px;border-radius:999px;background:var(--trk)}
.figpanel input[type=range]::-moz-range-track{height:10px;border-radius:999px;background:var(--trk)}
/* a white knob riding a solid pill, sized past the track like a physical control */
.figpanel input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;
 border-radius:50%;background:#fff;border:1px solid rgba(0,0,0,.13);
 box-shadow:0 1px 3px rgba(0,0,0,.22);margin-top:-4px}
.figpanel input[type=range]::-moz-range-thumb{width:18px;height:18px;border-radius:50%;
 background:#fff;border:1px solid rgba(0,0,0,.13);box-shadow:0 1px 3px rgba(0,0,0,.22)}
.figpanel input[type=range]:focus-visible{outline:2px solid var(--fig);outline-offset:3px}
.figpanel input[type=range]:disabled{opacity:.35;cursor:not-allowed}
.figpanel .wt{--trk:var(--slid)}
.figpanel .hue{--trk:linear-gradient(90deg,
  oklch(var(--hl) var(--hchroma) 0),oklch(var(--hl) var(--hchroma) 40),
  oklch(var(--hl) var(--hchroma) 80),oklch(var(--hl) var(--hchroma) 120),
  oklch(var(--hl) var(--hchroma) 160),oklch(var(--hl) var(--hchroma) 200),
  oklch(var(--hl) var(--hchroma) 240),oklch(var(--hl) var(--hchroma) 280),
  oklch(var(--hl) var(--hchroma) 320),oklch(var(--hl) var(--hchroma) 360))}

/* the control doubles as the readout: it shows the current pick and reshuffles */
.figpanel .pick{display:flex;align-items:center;gap:8px;cursor:pointer;
 height:30px;padding:0 8px 0 10px;border-radius:8px;border:1px solid var(--hair);
 background:transparent;color:var(--ink);font-family:var(--sans);font-size:13px;
 transition:background .15s,border-color .15s}
.figpanel .pick:hover{background:var(--hover);border-color:var(--faint)}
.figpanel .pick:active{transform:scale(.975)}
/* fixed, not min-width: the names are set in their own faces and run from 31px
   (Inter) to 117px (Martian Mono), so anything elastic resizes on every shuffle */
.figpanel .pick .v{width:126px;text-align:left;white-space:nowrap;overflow:hidden;
 font-family:var(--pf,var(--sans));font-weight:var(--pw,500);font-size:14px}
.figpanel .pick .sw{width:17px;height:17px;border-radius:50%;background:var(--c,var(--ink));
 border:1px solid rgba(120,120,120,.3);transition:background .3s}
.figpanel .pick svg{width:13px;height:13px;fill:none;stroke:var(--dim);stroke-width:1.7;
 stroke-linecap:round;stroke-linejoin:round;flex:none}
.figpanel .pick:hover svg{stroke:var(--ink)}
.figpanel .pick.busy{opacity:.55;pointer-events:none}
.figpanel .reset{cursor:pointer;border:0;background:transparent;color:var(--dim);
 font-family:var(--sans);font-size:12px;padding:4px 2px;transition:color .15s}
.figpanel .reset:hover{color:var(--ink)}
@media(max-width:560px){
  .figpanel{gap:9px;padding:8px 9px}
}
@media(prefers-reduced-motion:reduce){
  .layer,.figpanel,.layer .tag,.layer .hnd,.figpanel .pick{transition:none}
}

/* -----------------------------------------------------------------------
   INSPECT MODE - hold Option for Figma's redline measurements, press G for
   the layout grid. Both overlays are inert; they only ever draw.
   ----------------------------------------------------------------------- */
#redlines{position:fixed;pointer-events:none;display:none}
#redlines{inset:0;z-index:200}
body.measuring #redlines{display:block}
body.measuring,body.measuring *{cursor:crosshair!important}
#redlines .box{position:absolute;border:1px solid var(--fig);border-radius:1px}
/* anchored to the corner, not centred - the gap labels own the centre axes */
#redlines .dim{position:absolute;background:var(--fig);color:#fff;padding:3px 5px;border-radius:3px;
 font:500 10px/1 var(--sans);letter-spacing:.02em;white-space:nowrap}
#redlines .ln{position:absolute;background:#F24822}      /* Figma's redline red */
#redlines .lbl{position:absolute;background:#F24822;color:#fff;padding:2px 4px;border-radius:2px;
 font:500 10px/1 var(--sans);white-space:nowrap;transform:translate(-50%,-50%)}


/* hero subheader - a vertical roll through several lines. The window is one
   line tall and clips, so each line rises out as the next rises in. */
.subhead{margin-top:11px;font-size:18px;font-weight:400;color:var(--ink2);letter-spacing:-.012em;line-height:1.35}
/* every line is absolutely positioned, so the window needs a real width of its
   own - fit-content here collapses the whole subhead to zero */
#subroll{position:relative;cursor:pointer;width:100%;transition:color .2s;
 -webkit-user-select:none;user-select:none}
#subroll:hover,#subroll:focus-visible{color:var(--ink)}
#subroll:focus-visible{outline:none}
/* the lines stack on top of each other rather than sitting in flow - in flow
   the incoming line rests a full line below the window and only looks right
   once the outgoing node is removed, which is what made it snap */
.sr-win{position:relative;display:block;width:100%;overflow:hidden;height:1.35em}
.sr-t{position:absolute;left:0;top:0;width:100%;display:block;
 backface-visibility:hidden;transform:translateZ(0)}
.subhead .b{color:var(--blue);font-weight:500}
@media(max-width:420px){.subhead{font-size:16px}}

@media(max-width:560px){.now .r{grid-template-columns:minmax(0,1fr);row-gap:2px}}

/* video thumbnails are 1280x720, so give them a true 16:9 box */
.th.play{aspect-ratio:16/9}

/* ---------- post rows with thumbnails, stacked vertically ---------- */
.posts{display:block}
.prow{display:grid;grid-template-columns:108px minmax(0,1fr);gap:16px;align-items:center;
 padding:12px 10px;margin:0 -10px;border-radius:10px;transition:background .25s}
.prow+.prow{border-top:1px solid var(--hair)}
.prow:hover{background:var(--hover)}
.prow .pth{aspect-ratio:16/9;border-radius:6px;overflow:hidden;position:relative;
 border:1px solid var(--hair);background:#F2F2EF}
[data-theme="dark"] .prow .pth{background:#1B1B1D}
.prow .pth img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
 transition:transform .6s cubic-bezier(.16,1,.3,1)}
.prow .t{display:block;font-size:15px;color:var(--ink);line-height:1.35;transition:color .2s}
.prow:hover .t{color:var(--link)}
.prow .d{display:block;font-size:13px;color:var(--dim);margin-top:4px}
@media(max-width:560px){.prow{grid-template-columns:84px minmax(0,1fr);gap:13px}.prow .t{font-size:14px}}

/* ---------- footer ---------- */
/* footer's own rules are full-bleed like hr.sep, so every horizontal line on
   the page runs edge to edge. Drawn as pseudo-elements so the content stays
   inside the shell. */
footer{margin-top:52px;padding:26px 0 64px;display:block;position:relative}
footer::before,.fbot::before{content:"";position:absolute;top:0;left:50%;
 transform:translateX(-50%);width:100vw;border-top:1px solid var(--hair)}
.fhead{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}
.ftop{display:block}
.fcols{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:22px}
.fcols h5{font-size:12px;font-weight:500;color:var(--dim);margin-bottom:10px}
.fcols a{display:block;font-size:14px;color:var(--ink2);margin-bottom:7px;width:fit-content;transition:color .2s}
.fcols a:hover{color:var(--link)}
.fbot{display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;align-items:center;
 margin-top:28px;padding-top:18px;font-size:13px;color:var(--dim);position:relative}
.totop{display:inline-flex;align-items:center;gap:6px;color:var(--ink2);transition:color .2s}
.totop:hover{color:var(--link)}
@media(max-width:560px){.fcols{grid-template-columns:repeat(2,1fr)}}

/* ---------- click-to-play YouTube embeds ---------- */
.video{display:block}
.video .vthumb{display:block;position:relative;aspect-ratio:16/9;border-radius:8px;overflow:hidden;
 border:1px solid var(--hair);background:#F2F2EF;transition:border-color .3s}
[data-theme="dark"] .video .vthumb{background:#1B1B1D}
.video .vthumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
 transition:transform .6s cubic-bezier(.16,1,.3,1)}
.vthumb:hover{border-color:var(--faint)}
.vplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
 width:52px;height:37px;border-radius:9px;background:rgba(18,18,18,.72);backdrop-filter:blur(3px);
 display:grid;place-items:center;transition:background .25s,transform .25s cubic-bezier(.16,1,.3,1)}
.vplay::after{content:"";width:0;height:0;border-left:13px solid #fff;
 border-top:8px solid transparent;border-bottom:8px solid transparent;margin-left:3px}
.vthumb:hover .vplay{background:#FF0033;transform:translate(-50%,-50%) scale(1.06)}
.video .t{font-size:15px;color:var(--ink);margin-top:10px;line-height:1.35}
/* the thumbnail plays here, the title opens it on YouTube - two different
   actions, so the title carries its own hover */
.video .t a{color:inherit;transition:color .2s}
.video .t a:hover,.video .t a:focus-visible{color:var(--link)}
.video iframe{width:100%;aspect-ratio:16/9;border:0;border-radius:8px;display:block;background:#000}


/* =======================================================================
   TOP NAV
   Replaces the 284px sidebar + 284px rail. Content goes from 456px wide to
   960px, which is the whole point: the work gets to be the size of the work.
   ======================================================================= */
/* The bar's opaque plate stops at the inner edge of the edge strips, so the
   page's outer rules stay visible past it while scrolling. The container rules
   (.gl) are lifted above the bar so they run unbroken top to bottom. */
/* transform+will-change promote the bar to its own compositor layer, so
   mobile Safari/Chrome composites it while scrolling instead of repainting
   it every frame - without this a sticky header stutters/tears on scroll
   on iOS in particular */
.topbar{position:sticky;top:0;z-index:80;background:transparent;
 transform:translateZ(0);will-change:transform;-webkit-backface-visibility:hidden}
.topbar::before{content:"";position:absolute;inset:0 41px;z-index:-1;
 background:var(--paper);border-bottom:1px solid var(--hair)}
.tb{width:1024px;max-width:100%;margin:0 auto;padding:0 32px;height:64px;
 display:flex;align-items:center;gap:26px}
.topbar .logo{margin:0;width:62px;flex:none}
.topnav{display:flex;align-items:center;justify-content:center;gap:32px;flex:1}
.topnav .item{font-size:15px;color:var(--ink2);position:relative;padding:4px 0;transition:color .18s}
.topnav .item:hover{color:var(--ink)}
.topnav .item.active{color:var(--ink)}
.topnav .item.active::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:1.5px;
 border-radius:2px;background:var(--blue)}
.topactions{display:flex;align-items:center;gap:16px;flex:none}
/* sun that eclipses into a crescent */
.themetoggle{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;cursor:pointer;
 background:none;border:0;color:var(--ink2);transition:background .2s,color .2s}
.themetoggle:hover{background:var(--hover);color:var(--ink)}
.themetoggle:active{transform:scale(.92)}
.themetoggle svg{width:19px;height:19px;overflow:visible;display:block}
.themetoggle .core{fill:currentColor;transition:r .4s cubic-bezier(.16,1,.3,1)}
.themetoggle .mc{fill:#000;transition:cx .45s cubic-bezier(.16,1,.3,1),cy .45s cubic-bezier(.16,1,.3,1)}
.themetoggle .rays{stroke:currentColor;stroke-width:1.7;stroke-linecap:round;fill:none;
 transform-origin:12px 12px;transition:transform .55s cubic-bezier(.16,1,.3,1),opacity .3s}
/* the icon shows the mode you'll get: moon while light, sun while dark */
.themetoggle .core{r:6.6px}
.themetoggle .mc{cx:17px;cy:7px}
.themetoggle .rays{opacity:0;transform:rotate(-140deg) scale(.35)}
[data-theme="dark"] .themetoggle .core{r:5px}
[data-theme="dark"] .themetoggle .mc{cx:26px;cy:6px}
[data-theme="dark"] .themetoggle .rays{opacity:1;transform:none}

/* content rhythm at the new width */
main{padding:8px 0 0;max-width:none}
h1{font-size:clamp(38px,4.6vw,58px);line-height:1.02;letter-spacing:-.025em}
.subhead{font-size:20px}
.lede,.ssub,.pagehead .sub,.fine,.quote p{max-width:var(--measure)}
.pagehead h1{font-size:clamp(32px,3.8vw,44px)}
.grid2{gap:20px}
.prow{grid-template-columns:168px minmax(0,1fr);gap:20px}
.stats .n{font-size:30px}
.fcols{grid-template-columns:repeat(4,1fr)}


/* the burger only exists below the breakpoint */
.burger{display:none}
.navtheme{display:none}

@media(max-width:1100px){
  :root{--container:100%}
  .gl{display:none}
  .shell{padding:0 56px}
  .tb{padding:0 56px;width:100%}
}
@media(max-width:880px){
  .strip{display:none}
  /* Use a fixed, opaque layer on touch devices. Sticky headers combined with
     compositor transforms can tear during momentum scrolling in mobile Safari. */
  .topbar{position:fixed;inset:0 0 auto;width:100%;height:64px;background:var(--paper);
    border-bottom:1px solid var(--hair);transform:none;will-change:auto;-webkit-backface-visibility:visible}
  .topbar::before{display:none}
  .shell{padding:64px 22px 0}
  .tb{padding:0 22px;gap:14px}
  .topactions{margin-left:auto}   /* nav is an absolute dropdown here, so push the burger to the right edge */
  main{padding:32px 0 0}
  .burger{display:grid}
  /* Keep the theme control beside the hamburger so it is available without
     opening the mobile navigation panel. */
  .topactions .themetoggle{display:grid}
  .navtheme{display:none}
  .navtheme:hover{color:var(--ink)}
  .navtheme:last-child{border-bottom:0}
  .navtheme svg{width:19px;height:19px;flex:none;overflow:visible}
    /* links collapse into a panel that drops out of the bar */
  .topnav{position:absolute;left:0;right:0;top:64px;flex-direction:column;align-items:stretch;gap:0;
   background:var(--paper);border-bottom:1px solid var(--hair);padding:6px 22px 14px;
   transform-origin:top;transform:scaleY(0);opacity:0;pointer-events:none;
   transition:transform .28s cubic-bezier(.16,1,.3,1),opacity .2s}
  .topnav.open{transform:scaleY(1);opacity:1;pointer-events:auto}
  .topnav .item{font-size:16px;padding:11px 0;border-bottom:1px solid var(--hair)}
  .topnav .item:last-child{border-bottom:0}
  .topnav .item.active::after{display:none}
  .topnav .item.active{font-weight:500}
  .prow{grid-template-columns:120px minmax(0,1fr)}
  .fcols{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:560px){
  .grid2{grid-template-columns:1fr}
  .prow{grid-template-columns:96px minmax(0,1fr);gap:14px}
  .hero .portrait.dither{width:96px}
}

/* a partner chip with no available mark still needs the same left inset */
.cl:not(:has(i)){padding-left:12px}

/* =======================================================================
   CURRENTLY - four variants shown together for a pick
   ======================================================================= */

@keyframes nowpulse{50%{opacity:.4;box-shadow:0 0 0 6px rgba(47,191,113,0)}}

/* Currently - two cards */
.nowcards{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
.nowcard{border:1px solid var(--hair);border-radius:10px;padding:16px 18px;background:var(--paper);
 transition:border-color .25s,transform .35s cubic-bezier(.16,1,.3,1)}
.nowcard .h{display:flex;align-items:center;gap:7px;font-size:12px;letter-spacing:.1em;
 text-transform:uppercase;color:var(--dim);margin-bottom:9px}
.nowcard .h svg{width:15px;height:15px;flex:none;fill:none;stroke:var(--blue);
 stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.nowcard p{font-size:15px;color:var(--ink);line-height:1.45}
.nowcard .meta{font-size:13px;color:var(--dim);margin-top:8px}
@media(max-width:640px){.nowcards{grid-template-columns:1fr}}

@media(max-width:640px){.nowledger .e{grid-template-columns:26px minmax(0,1fr)}.nowledger .w{display:none}}

/* ---------- experience rows ----------
   The familiar LinkedIn shape - logo tile, role, org, dates, one supporting
   line - but held two-up rather than stacked, because these are two parallel
   tracks running at once, not a history. The full chronology lives on /about.
   No section label: both rows say "Present", so "Currently" only repeated it. */
.xp{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px}
.xrow{display:grid;grid-template-columns:48px minmax(0,1fr);gap:14px;align-items:start}
.xlogo{width:48px;height:48px;border-radius:12px;overflow:hidden;flex:none;
 display:grid;place-items:center;background:#EDEDE8;padding:8px}
/* the tile has to stay dark enough for the white marks it holds, so it shifts
   between near-black on paper and a lifted surface on the dark page */
/* the tile is a surface in each theme, and the GW mark - white source art -
   is inverted to suit whichever it sits on */
.xlogo img[src$="gw-logo.svg"]{filter:brightness(0)}
[data-theme="dark"] .xlogo{background:#2C2C31;box-shadow:inset 0 0 0 1px rgba(255,255,255,.06)}
[data-theme="dark"] .xlogo img[src$="gw-logo.svg"]{filter:none}
.xlogo img{width:100%;height:100%;object-fit:contain;display:block}
.xt{font-size:15px;font-weight:600;color:var(--ink);letter-spacing:-.012em;line-height:1.3}
.xs{font-size:13.5px;color:var(--ink2);margin-top:2px}
.xd{font-size:13px;color:var(--dim);margin-top:2px;font-variant-numeric:tabular-nums}
.xn{font-size:13.5px;color:var(--ink2);margin-top:9px;line-height:1.5}
.xn a{color:var(--link);transition:opacity .2s}
.xn a:hover{opacity:.7}
@media(max-width:760px){.xp{grid-template-columns:1fr;gap:24px}}

/* ---------- contact form ---------- */
.cwrap{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:44px;margin-top:26px;align-items:start}
.cform{display:block}
/* author display rule beats the hidden attribute's UA display:none, so the
   success state could not hide the form without this */
.cform[hidden]{display:none}
.frow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.fld{display:block;margin-top:16px;position:relative}
.frow .fld{margin-top:0}
.field-label{display:block;font-size:13px;color:var(--ink2);margin-bottom:6px}
.fld input,.fld select,.fld textarea{
  width:100%;font-family:var(--sans);font-size:14px;color:var(--ink);
  background:var(--paper);border:1px solid var(--hair);border-radius:8px;
  padding:10px 12px;transition:border-color .18s,box-shadow .18s}
.fld textarea{resize:vertical;min-height:120px;line-height:1.55}
.fld input::placeholder,.fld textarea::placeholder{color:var(--faint)}
.fld input:hover,.fld select:hover,.fld textarea:hover{border-color:var(--faint)}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:none;border-color:var(--link);
  box-shadow:0 0 0 3px color-mix(in oklab,var(--link) 18%,transparent)}
.fld.bad input,.fld.bad textarea{border-color:#C4362F}
.err{display:none;font-size:12px;color:#C4362F;margin-top:5px}
.fld.bad .err{display:block}
.hint{position:absolute;right:2px;top:0;font-size:11px;color:var(--faint)}
/* the honeypot must be reachable by bots and invisible to everyone else */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cform .cta{margin-top:22px;align-items:center;gap:14px}
.fstatus{font-size:13px;color:var(--dim)}
.fstatus.ok{color:#1F8C4A}
.fstatus.bad{color:#C4362F}
.cform.sending .btn-primary{opacity:.6;pointer-events:none}
.cside .sl{margin-bottom:10px}
.cside .fine{margin-top:14px}
@media(max-width:880px){
  .cwrap{grid-template-columns:1fr;gap:30px}
}
@media(max-width:560px){.frow{grid-template-columns:1fr;gap:16px}.frow .fld+.fld{margin-top:16px}}

/* ---------- about collage ----------
   Scattered prints in the scrapbook manner of the reference, taped at the
   outer corners. Each print is a button: click flips it over to a handwritten
   note on the back, so hover states are earned here. */
.collage{position:relative;width:100%;max-width:960px;aspect-ratio:940/920;margin-top:14px}
.ci{position:absolute;display:block;padding:0;border:0;background:none;cursor:pointer;
 transform:rotate(var(--r,0deg));perspective:900px;
 -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.ci:focus-visible{outline:2px solid var(--fig);outline-offset:4px}
.ci .card{position:relative;display:block;width:100%;transform-style:preserve-3d;
 transition:transform .65s cubic-bezier(.2,.8,.25,1)}
.ci.flipped .card{transform:rotateY(180deg)}
.ci .card:hover{transform:rotateY(0deg)}
.ci.flipped .card:hover{transform:rotateY(180deg)}
.face{display:block;border-radius:3px;backface-visibility:hidden;-webkit-backface-visibility:hidden;
 box-shadow:0 1px 3px rgba(20,21,24,.14),0 12px 28px rgba(20,21,24,.12);transition:box-shadow .25s ease}
[data-theme="dark"] .face{box-shadow:0 1px 3px rgba(0,0,0,.5),0 14px 34px rgba(0,0,0,.45)}
.ci:hover .face{box-shadow:0 3px 7px rgba(20,21,24,.18),0 18px 38px rgba(20,21,24,.2)}
[data-theme="dark"] .ci:hover .face{box-shadow:0 3px 7px rgba(0,0,0,.62),0 20px 42px rgba(0,0,0,.6)}
.face.front{position:relative;background:#fff;padding:5px}
.face.front img{display:block;width:100%;height:auto;border-radius:1.5px}
/* the handwritten back of the print */
.face.back{position:absolute;inset:0;transform:rotateY(180deg);
 background:repeating-linear-gradient(transparent 0 24px,rgba(63,94,184,.10) 24px 25px),#FFFDF6;
 display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
 padding:12px;text-align:center;
 font-family:'Bradley Hand','Segoe Script','Comic Sans MS',cursive;color:#33406E}
[data-theme="dark"] .face.back{background:repeating-linear-gradient(transparent 0 24px,rgba(63,94,184,.14) 24px 25px),#F4EFE3}
.face.back .bk-t{font-size:17px;line-height:1.3;transform:rotate(-1.5deg)}
.face.back .bk-d{font-size:12.5px;opacity:.66;transform:rotate(-1.5deg)}

/* desktop: three-ish across, prints overlapping like a real pile */
.p-beach{left:0;top:0;width:30%;--r:-2.5deg;z-index:1}
.p-family{left:27%;top:2%;width:34%;--r:2deg;z-index:2}
.p-cat{left:58.5%;top:0.5%;width:28%;--r:-2deg;z-index:1}
.p-chair{left:2%;top:32%;width:36%;--r:1.6deg;z-index:2}
.p-selfie{left:33%;top:24%;width:35%;--r:2.2deg;z-index:3}
.p-club{left:63%;top:30%;width:28%;--r:2.4deg;z-index:2}
.p-grad{left:1%;top:56%;width:28%;--r:-2.2deg;z-index:4}
.p-boat{left:27%;top:53%;width:30%;--r:-2.6deg;z-index:2}
.p-stadium{left:56%;top:54%;width:36%;--r:-1.8deg;z-index:3}

/* washi tape pinning the four outer corners */
.tape{position:absolute;width:11%;height:2.4%;z-index:6;pointer-events:none;border-radius:1px;
 background:linear-gradient(rgba(255,255,255,.30),rgba(120,110,80,.06)),rgba(229,222,203,.78);
 box-shadow:0 1px 2px rgba(20,21,24,.14)}
[data-theme="dark"] .tape{background:linear-gradient(rgba(255,255,255,.16),rgba(0,0,0,.05)),rgba(210,203,184,.62)}
/* desktop: each tape hugs the corner of the print that actually forms that
   corner, and stays clear of the text above and below the collage */
.t-tl{left:-1.4%;top:1.5%;transform:rotate(-42deg)}      /* pins the beach print's top-left corner */
.t-tr{right:11%;top:-.2%;transform:rotate(40deg)}        /* pins the cat print's top-right corner */
.t-bl{left:-1%;bottom:1.2%;transform:rotate(38deg)}      /* pins the grad print's bottom-left corner */
.t-br{left:85.5%;top:79.5%;transform:rotate(-40deg)}     /* pins the stadium print's bottom-right corner */

/* app-icon marks scattered over the pile like little stickers */
.mark{position:absolute;z-index:7;height:auto;pointer-events:none;border-radius:22%;
 filter:drop-shadow(0 5px 12px rgba(20,21,24,.28));transform:rotate(var(--mr,0deg))}
[data-theme="dark"] .mark{filter:drop-shadow(0 6px 16px rgba(0,0,0,.5))}
/* widths tuned so the visible glyph is the same height on all three
   (figma canvas carries right-side padding; yt is a wide rounded-rect) */
.m-claude{left:30%;top:27%;width:8%;--mr:9deg}      /* seam by the sunset's top-left */
.m-figma{left:65%;top:42%;width:8%;--mr:-8deg}     /* matches the Claude sticker size */
.m-yt{left:24%;top:60%;width:8.6%;--mr:6deg}         /* matches the Figma sticker's displayed height */
.m-claude,.m-figma{box-sizing:border-box;border:2px solid #fff}

/* hand-drawn marks */
.doodle{position:absolute;pointer-events:none;overflow:visible}
.doodle path{fill:none;stroke-linecap:round}
.arc{width:20%;opacity:.75}
.arc path{stroke:var(--faint);stroke-width:2.5;stroke-dasharray:1 7}
.a1{left:76%;top:-3%}
.a2{left:-4%;top:36%;transform:scaleX(-1) rotate(14deg)}
@media(prefers-reduced-motion:reduce){
  .ci,.ci .card{transition:none}
}
@media(max-width:760px){
  .collage{max-width:600px;aspect-ratio:620/1424}
  .p-beach{left:1%;top:0;width:45%;z-index:2}
  .p-family{left:45.5%;top:1.4%;width:48%;z-index:3}
  .p-cat{left:57%;top:18.1%;width:35%;z-index:3}
  .p-chair{left:0;top:27%;width:56%;z-index:1}
  .p-selfie{left:54%;top:39.3%;width:38%;z-index:2}
  .p-boat{left:2%;top:44.2%;width:40%;z-index:1}
  .p-club{left:44%;top:55%;width:50%;z-index:3}
  .p-grad{left:4%;top:68.7%;width:38%;z-index:2}
  .p-stadium{left:40%;top:76.5%;width:56%;z-index:3}
  .tape{width:15%;height:3%}
  .t-tl{left:-3%;top:1.6%}
  .t-tr{right:-3.5%;top:1.4%}
  .t-bl{left:-2%;bottom:5.6%}
  .t-br{left:auto;top:auto;right:-3.2%;bottom:3.2%}
  /* bigger scattered icons, tucked into the black seams between prints */
  .m-claude{left:42%;top:22%;width:15%}    /* beach / cat / photobooth seam */
  .m-figma{left:43%;top:47%;width:15%}     /* matches the Claude sticker size */
  .m-yt{left:38%;top:72%;width:15%}        /* matches the Figma sticker's displayed height */
}
@media(max-width:560px){
  .face.front{padding:4px}
}

/* ---------- about: story + beliefs ----------
   The career reads as chapters rather than job rows - years in the margin,
   sentences instead of titles. The formal record lives in the resume link. */
/* the career as a drawn timeline: a spine down the gutter, a node per chapter,
   the latest one lit in the accent so "Now" reads as the live end */
.story{position:relative}
.story::before{content:"";position:absolute;left:69px;top:9px;bottom:14px;width:2px;
 background:linear-gradient(var(--hair),var(--hair) 82%,transparent)}
.st{position:relative;display:grid;grid-template-columns:56px minmax(0,1fr);gap:30px;padding:0 0 30px}
.st:last-child{padding-bottom:0}
.st::before{content:"";position:absolute;left:62px;top:3.5px;width:12px;height:12px;border-radius:50%;
 background:var(--paper);border:2px solid var(--faint);z-index:1;transition:background .3s,border-color .3s}
[data-theme="dark"] .st:not(:last-child)::before{border-color:var(--ink2)}
.st:last-child::before{border-color:var(--blue);background:var(--blue);
 box-shadow:0 0 0 5px color-mix(in oklab,var(--blue) 20%,transparent)}
.st .yr{font-size:14px;font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums;padding-top:1px;letter-spacing:-.01em}
.st:last-child .yr{color:var(--link)}
.st p{font-size:14.5px;line-height:1.62;color:var(--ink2);font-weight:400;max-width:56ch}
.st p .k{color:var(--ink);font-weight:500}
.employer{color:var(--ink);font-weight:500;white-space:nowrap;text-decoration:none;border-bottom:1px solid transparent;transition:border-color .18s}
.employer:hover,.employer:focus-visible{border-bottom-color:currentColor}
.company-logo{display:inline-block;height:1em;width:auto;max-width:5.8em;margin:0 .25em 0 .08em;vertical-align:-.13em;object-fit:contain}
.marklogic-logo,.aryaka-logo{width:1em;border-radius:.22em}
.mashgin-logo{width:1em;margin-left:.08em}

/* ---------- media kit ---------- */
.mk-hero{display:grid;grid-template-columns:minmax(0,1fr) 236px;gap:clamp(32px,7vw,92px);align-items:end;padding:clamp(46px,8vw,90px) 0 clamp(42px,7vw,70px)}
.mk-kicker{font-size:13px;color:var(--link);font-weight:500;letter-spacing:.02em;margin-bottom:18px}
.mk-hero h1{max-width:13ch;font-size:clamp(40px,5.3vw,65px);font-weight:600;letter-spacing:-.045em;line-height:.98;color:var(--ink)}
.mk-hero p{max-width:54ch;margin-top:22px;font-size:17px;line-height:1.62;color:var(--ink2)}
.mk-profile{display:flex;align-items:center;gap:13px;padding:14px 0;border-top:1px solid var(--hair)}
.mk-profile img{width:54px;height:54px;border-radius:50%;object-fit:cover;filter:grayscale(1)}
.mk-profile strong,.mk-profile span,.mk-profile a{display:block}.mk-profile strong{font-size:14px;color:var(--ink);font-weight:500}.mk-profile span,.mk-profile a{font-size:12px;color:var(--dim);margin-top:1px}.mk-profile a{color:var(--link);margin-top:4px}
.mk-performance{padding:29px 0 26px;border-top:1px solid var(--hair);border-bottom:1px solid var(--hair)}
.mk-section-head{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-bottom:24px}.mk-section-head .sl{margin-bottom:6px}.mk-section-head h2,.mk-two-col h2{font-size:clamp(24px,3vw,34px);line-height:1.08;letter-spacing:-.03em;color:var(--ink);font-weight:550}.mk-section-head>p{font-size:12px;color:var(--dim);padding-bottom:3px}
.mk-metrics{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--hair);border-bottom:1px solid var(--hair)}.mk-metrics>div{padding:20px 18px 18px;border-left:1px solid var(--hair)}.mk-metrics>div:first-child{border-left:0}.mk-metrics strong{display:block;font-size:clamp(29px,3.6vw,44px);font-weight:600;line-height:1;letter-spacing:-.055em;color:var(--ink)}.mk-metrics span{display:block;margin-top:8px;font-size:13px;color:var(--dim)}
.mk-realtime{display:flex;align-items:baseline;gap:7px;margin-top:15px;font-size:13px;color:var(--dim)}.mk-realtime strong{font-weight:500;color:var(--ink)}.mk-dot{width:7px;height:7px;border-radius:50%;background:var(--teal);display:inline-block;box-shadow:0 0 0 4px color-mix(in srgb,var(--teal) 17%,transparent)}
.mk-two-col{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(34px,10vw,132px);padding:42px 0 24px}.mk-two-col .sl{margin-bottom:8px}.mk-copy{max-width:58ch;color:var(--ink2);font-size:15px;line-height:1.65}.mk-copy p+p{margin-top:14px}.mk-copy ul{list-style:none;margin-top:20px;border-top:1px solid var(--hair)}.mk-copy li{padding:10px 0;border-bottom:1px solid var(--hair);color:var(--ink)}.mk-copy li::before{content:'↗';display:inline-block;width:20px;color:var(--link)}.mk-copy .cta{margin-top:25px}.mk-partnerships{padding:40px 0 16px}.mk-partnerships .mk-section-head{margin-bottom:20px}.mk-partnerships .chips{margin-bottom:23px}.mk-partnerships .mk-copy{max-width:46ch}
.mk-top-content{padding:8px 0 8px}.mk-text-link{font-size:13px;color:var(--link);padding-bottom:3px}.mk-video-list{list-style:none;border-top:1px solid var(--hair)}.mk-video-list li{display:grid;grid-template-columns:46px 112px minmax(0,1fr) auto;align-items:center;gap:14px;padding:15px 0;border-bottom:1px solid var(--hair)}.mk-video-list>li>span{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}.mk-video-list strong{display:block;color:var(--ink);font-size:14px;font-weight:500;line-height:1.4}.mk-video-list a{display:block;width:fit-content}.mk-video-list a:hover strong,.mk-video-list a:focus-visible strong{color:var(--link)}.mk-video-thumb{width:112px!important;aspect-ratio:16/9;overflow:hidden;border-radius:4px;background:var(--hair)}.mk-video-thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .2s ease}.mk-video-thumb:hover img,.mk-video-thumb:focus-visible img{transform:scale(1.035)}.mk-video-list small{display:block;color:var(--dim);font-size:12px;margin-top:3px}.mk-video-list b{font-size:12px;font-weight:500;color:var(--dim);white-space:nowrap}.mk-note{max-width:64ch;margin:34px 0 10px;color:var(--dim);font-size:12px;line-height:1.55}
@media(max-width:760px){.mk-hero{grid-template-columns:1fr;padding-top:50px;gap:30px}.mk-profile{max-width:280px}.mk-metrics{grid-template-columns:repeat(2,1fr)}.mk-metrics>div:nth-child(3){border-left:0;border-top:1px solid var(--hair)}.mk-metrics>div:nth-child(4){border-top:1px solid var(--hair)}.mk-two-col{grid-template-columns:1fr;gap:24px}.mk-section-head{align-items:start;flex-direction:column;gap:9px}.mk-section-head>p{padding-bottom:0}.mk-video-list li{grid-template-columns:30px 96px minmax(0,1fr);gap:10px}.mk-video-thumb{width:96px!important}.mk-video-list b{grid-column:3}.mk-hero .cta{flex-wrap:wrap}}
.beliefs{display:grid;gap:16px;max-width:60ch}
.belief .b-t{font-size:15px;font-weight:500;color:var(--ink);letter-spacing:-.01em}
.belief p{margin-top:3px;font-size:14px;color:var(--ink2);line-height:1.55}
@media(max-width:560px){
  .st{grid-template-columns:44px minmax(0,1fr);gap:32px}
  .story::before{left:52px}
  .st::before{left:45px}   /* -2px vs the line to offset the dot's 2px border (content-box) */
}

/* restored article/case-study imagery from the original site */
.content-fig{margin:clamp(24px,4vw,40px) 0 0}
.content-fig img{display:block;width:100%;height:auto;border-radius:10px;border:1px solid var(--hair)}
.article-body p+p,.longform p+p{margin-top:18px}

/* ---------- project case studies ---------- */
.longform{max-width:720px;padding-top:clamp(48px,8vw,92px)}
.longform .content-section{margin-top:clamp(52px,6vw,76px)}
.longform .content-section:first-child{margin-top:0}
.longform .content-section--visual{max-width:none;margin-top:0}
.longform .content-section--visual .content-fig{margin:0}
.longform .content-section--visual .content-fig img{border-radius:12px}
.longform .content-section h2{max-width:15ch;margin:0 0 16px;font-size:clamp(28px,3.4vw,40px);font-weight:550;line-height:1.05;letter-spacing:-.045em}
.longform .content-section p{max-width:65ch;font-size:clamp(16px,1.35vw,18px);line-height:1.72}
.longform .content-section p+p{margin-top:19px}
.longform .content-list{max-width:62ch;display:grid;gap:10px;margin:20px 0 0;padding:0;list-style:none}
.longform .content-list li{position:relative;padding:0 0 0 20px;color:var(--ink2);font-size:clamp(16px,1.35vw,18px);line-height:1.6}
.longform .content-list li::before{content:'';position:absolute;left:0;top:.66em;width:6px;height:6px;border-radius:50%;background:var(--link)}
.longform .content-list + p{margin-top:22px}
.longform .content-section .content-fig:first-of-type{margin-top:clamp(28px,4vw,46px)}
.longform .content-fig + .content-fig{margin-top:14px}
.longform .content-section:not(.content-section--visual) .content-fig img{border-radius:12px}
.longform .content-section--visual .content-fig:first-of-type{margin-top:0}
.longform .content-fig--tall{width:min(100%,380px);margin-right:auto;margin-left:auto}
.longform .content-fig--tall img{max-height:680px;object-fit:contain;object-position:top}
@media(max-width:700px){
  .longform{padding-top:46px}
  .longform .content-section{margin-top:52px}
  .longform .content-section h2{max-width:18ch;font-size:30px;margin-bottom:14px}
  .longform .content-section p,.longform .content-list li{font-size:16px;line-height:1.68}
  .longform .content-list{gap:12px;margin-top:18px}
  .longform .content-fig--tall{width:min(100%,300px)}
  .longform .content-fig--tall img{max-height:540px}
}

/* contact form success state - replaces the form so it can't be missed */
.fdone{border:1px solid var(--hair);border-radius:12px;padding:clamp(26px,4vw,38px);
 background:var(--paper);animation:fdone-in .4s cubic-bezier(.16,1,.3,1) both}
@keyframes fdone-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.fdone-mark{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;
 background:rgba(31,140,74,.12);margin-bottom:18px}
.fdone-mark svg{width:22px;height:22px;fill:none;stroke:#1F8C4A;stroke-width:2.4;
 stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:26;
 animation:fdone-tick .5s .15s cubic-bezier(.16,1,.3,1) both}
@keyframes fdone-tick{from{stroke-dashoffset:26}to{stroke-dashoffset:0}}
.fdone h3{margin:0 0 10px;font-size:22px;letter-spacing:-.025em;color:var(--ink)}
.fdone p{margin:0 0 22px;max-width:46ch;font-size:15px;line-height:1.6;color:var(--ink2)}
.fdone p strong{color:var(--ink);font-weight:500}
@media(prefers-reduced-motion:reduce){
  .fdone,.fdone-mark svg{animation:none}
}

/* ---------- photo lightbox ---------- */
body.lb-open{overflow:hidden}
.lb{position:fixed;inset:0;z-index:200;display:grid;place-items:center;
 padding:clamp(16px,4vw,56px);background:rgba(8,8,9,.94);
 -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
 animation:lb-fade .18s ease-out both}
.lb[hidden]{display:none}
@keyframes lb-fade{from{opacity:0}to{opacity:1}}
.lb-stage{margin:0;display:grid;place-items:center;gap:14px;max-width:100%;max-height:100%}
.lb-img{display:block;max-width:min(100%,1600px);max-height:82vh;width:auto;height:auto;
 border-radius:8px;box-shadow:0 30px 90px rgba(0,0,0,.6);
 animation:lb-pop .22s cubic-bezier(.16,1,.3,1) both}
@keyframes lb-pop{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:none}}
.lb.loading .lb-img{opacity:.25}
.lb-count{color:rgba(255,255,255,.62);font-size:13px;letter-spacing:.01em;
 font-variant-numeric:tabular-nums}
/* controls */
.lb-close,.lb-nav{position:absolute;display:grid;place-items:center;cursor:pointer;
 border:0;border-radius:999px;background:rgba(255,255,255,.1);color:#fff;
 -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
 transition:background .18s,transform .18s}
.lb-close:hover,.lb-nav:hover{background:rgba(255,255,255,.2)}
.lb-close:active,.lb-nav:active{transform:scale(.94)}
.lb-close{top:clamp(12px,2.4vw,26px);right:clamp(12px,2.4vw,26px);width:42px;height:42px}
.lb-nav{top:50%;transform:translateY(-50%);width:46px;height:46px}
.lb-nav:active{transform:translateY(-50%) scale(.94)}
.lb-nav.prev{left:clamp(10px,2vw,26px)}
.lb-nav.next{right:clamp(10px,2vw,26px)}
.lb-nav[hidden]{display:none}
.lb svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;
 stroke-linecap:round;stroke-linejoin:round}
.lb :focus-visible{outline:2px solid #fff;outline-offset:3px}
/* the tile itself should read as expandable rather than a link-out */
.gph{cursor:zoom-in}
/* On phones the side arrows sit on top of the photo and are awkward to hit,
   so the controls move to a bottom bar: [<] 2/69 [>]. Swipe still works;
   the bar makes it discoverable and gives 48px touch targets. */
@media(max-width:600px){
  .lb{padding:14px 10px 96px}
  .lb-img{max-height:68vh}
  .lb-close{width:44px;height:44px;top:10px;right:10px}
  .lb-nav{top:auto;bottom:26px;transform:none;width:48px;height:48px}
  .lb-nav:active{transform:scale(.94)}
  .lb-nav.prev{left:50%;margin-left:-104px}
  .lb-nav.next{right:50%;margin-right:-104px}
  .lb-count{position:fixed;left:0;right:0;bottom:41px;text-align:center;
   font-size:14px;color:rgba(255,255,255,.8);pointer-events:none}
  .lb svg{width:22px;height:22px}
}
/* one-time nudge that the gallery is swipeable */
.lb-hint{position:fixed;left:50%;bottom:96px;transform:translateX(-50%);
 padding:7px 14px;border-radius:999px;font-size:12.5px;color:#fff;white-space:nowrap;
 background:rgba(255,255,255,.14);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
 animation:lb-hint-out 2.8s ease-out both;pointer-events:none}
@keyframes lb-hint-out{0%,60%{opacity:1}100%{opacity:0;visibility:hidden}}
@media(prefers-reduced-motion:reduce){.lb-hint{animation:none;opacity:.9}}
@media(prefers-reduced-motion:reduce){
  .lb,.lb-img{animation:none}
  .lb-close,.lb-nav{transition:none}
}
