@font-face{font-family:"Plex Serif";font-weight:300;font-style:normal;font-display:swap;src:url("/assets/cbd12a0193c4dc74.woff2") format("woff2")}
@font-face{font-family:"Plex Sans";font-weight:400 500;font-display:swap;src:url("/assets/056e4e2459f57a00.woff2") format("woff2")}
@font-face{font-family:"Plex Cond";font-weight:400;font-display:swap;src:url("/assets/9427f9b040d9de07.woff2") format("woff2")}











:root {
  --paper:#fdf9f6; --ink:#1c1b1a; --mute:rgba(28,27,26,.64); --rule:rgba(28,27,26,.22);
  --serif:"Plex Serif",Georgia,serif; --sans:"Plex Sans",Arial,sans-serif; --cond:"Plex Cond",var(--sans);
  --display-size:clamp(40px,4.3vw,80px); --display-leading:1.055;
  --gutter:clamp(22px,5vw,80px); --band:34svh; --foot:52px; --head:clamp(112px,15svh,168px);
  --top-inset:env(safe-area-inset-top,0px); --bottom-inset:env(safe-area-inset-bottom,0px); --reading-gap:28px;
  --night:0; --tone:0; --ease:cubic-bezier(.22,.72,.18,1);
  --background:var(--paper); --foreground:var(--ink); --primary:var(--ink); --primary-foreground:var(--paper);
  --card:var(--paper); --card-foreground:var(--ink); --border:var(--rule); --ring:var(--ink);
}
*{box-sizing:border-box;margin:0;padding:0}
html{background:var(--paper);color-scheme:light;-webkit-text-size-adjust:100%;scroll-behavior:auto;scrollbar-width:none;scroll-padding:0}
html::-webkit-scrollbar{display:none}
body{font-family:var(--sans);color:var(--ink);background:var(--paper);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
a{color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
a:focus-visible{outline:2px solid currentColor;outline-offset:5px;border-radius:2px}
h1:focus,h2:focus{outline:none}
::selection{background:var(--ink);color:var(--paper)}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip{position:fixed;z-index:50;top:8px;left:var(--gutter);padding:12px;background:var(--paper);transform:translateY(-200%)}
.skip:focus{transform:none}

.top{position:fixed;inset:0 0 auto;z-index:30;display:flex;justify-content:space-between;align-items:center;padding:calc(var(--top-inset) + 20px) var(--gutter) 10px;background:var(--paper)}
.wordmark{font-size:22px;font-weight:500;letter-spacing:-.005em;min-height:44px;display:flex;align-items:center}
.wordmark span{font-weight:400;opacity:.72;margin-left:.3em}
.mail{width:44px;height:44px;display:grid;place-items:center;margin-right:-12px;opacity:.72;transition:opacity 180ms ease,transform 180ms ease}
.mail:hover{opacity:1;transform:translateY(-1px)}

.scenes{position:relative;z-index:5}
/* iOS Safari: chapters are 100svh, but with the toolbar collapsed the viewport
   is 100lvh, so the last chapter's start could not reach the top of the screen;
   the page bottomed out short and jumped when the toolbar returned. This spacer
   keeps the last anchor reachable in both toolbar states. Zero on desktop. */
.scenes::after{content:"";display:block;height:calc(100lvh - 100svh);pointer-events:none}
/* Sections already include the header inset; cancel the root's focus padding for hash links. */
.scene{position:relative;min-height:100svh;padding:calc(var(--head) + var(--top-inset)) var(--gutter) calc(var(--band) + var(--foot) + var(--bottom-inset) + 24px);display:block;scroll-margin:0;scroll-snap-align:start;scroll-snap-stop:always}
.copy{width:100%;max-width:1080px}
/* One native document scrolls over every surface. */


#work.is-split .copy{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);column-gap:clamp(40px,5vw,80px);row-gap:18px;align-items:start}
#work.is-split .display{grid-column:1;grid-row:1/span 2}
#work.is-split .block{grid-column:2;grid-row:1;margin-top:0}
#work.is-split .byline{grid-column:2;grid-row:2;margin-top:0}
@media(min-width:1440px){#work .block{margin-top:24px}}
h1,h2{font-family:var(--serif);font-weight:300;letter-spacing:-.014em;line-height:1.055;text-wrap:balance}
/* Opening and closing share one responsive headline scale in every layout. */
h1,.display{font-size:var(--display-size);line-height:var(--display-leading);max-width:16ch}
.display{max-width:26ch}
.lead{font-size:clamp(30px,2.9vw,54px);max-width:34ch;line-height:1.13}
h3{font-family:var(--sans);font-weight:400;font-size:14px;line-height:1.5;color:var(--mute)}
.block{margin-top:clamp(24px,2.5vw,36px);padding-top:16px;position:relative;max-width:70ch}
.block::before{content:"";position:absolute;top:0;left:0;width:40px;height:1px;background:currentColor;opacity:.65}
.list{list-style:none;margin-top:12px;display:grid;grid-template-columns:repeat(2,max-content);column-gap:clamp(32px,4vw,72px);row-gap:.35em;font-size:clamp(16px,1.15vw,18px);line-height:1.45}
.byline{margin-top:20px;font-size:13px;line-height:1.6;color:var(--mute);max-width:72ch}
.byline a{border-bottom:1px solid var(--rule);padding-bottom:2px;transition:border-color .2s}
.byline a:hover{border-color:currentColor}
.cue{margin-top:clamp(26px,4svh,44px);display:inline-flex;align-items:center;gap:14px;min-height:44px;font-size:13px;color:var(--mute)}
.cue{transition:color 180ms ease}
.cue:hover,.cue:focus-visible{color:var(--ink)}
.cue-arrow{display:block;flex:none;transition:transform 180ms ease}
.cue:hover .cue-arrow,.cue:focus-visible .cue-arrow{transform:translateY(2px)}
.cue-track{opacity:.3}
.cue-sweep{stroke-dasharray:24 24;animation:cue-draw 3s var(--ease) infinite}
@keyframes cue-draw{0%{stroke-dashoffset:24}50%,60%{stroke-dashoffset:0}100%{stroke-dashoffset:-24}}

/* The supplied panorama stays continuous. Only its position and light change. */
.band{position:fixed;inset:auto 0 calc(var(--foot) + var(--bottom-inset));height:calc(var(--band) + 16px);z-index:10;overflow:hidden;background:none;pointer-events:none}
.band::after{content:"";position:absolute;inset:auto 0 0;height:12px;background:linear-gradient(0deg,var(--paper),transparent);z-index:3}
/* Fade only the added sky ABOVE the panorama. Keep the original ridge and glow sharp.
   Use a smooth vector palette so compressed image grain cannot become vertical streaks.
   The cream backing and shared night opacity preserve the same day-to-night crossfade.
   Underlap the artwork by 2px so fractional layer edges cannot expose a dark seam.
   This stays behind the untouched landscape; the visible glow height is unchanged. */
.sky-wrap{position:fixed;inset:0;z-index:4;overflow:hidden;pointer-events:none}
.sky-extension{position:absolute;left:0;bottom:calc(var(--foot) + var(--bottom-inset) + var(--band) - 2px);width:var(--plate-width,max(100vw,187.33svh));height:calc(clamp(82px,15.3svh,170px) + 2px);background:#fdf9f6;transform:translate3d(var(--pan-x,0px),var(--art-offset,0px),0);mask-image:linear-gradient(transparent,rgba(0,0,0,.028) 10%,rgba(0,0,0,.104) 20%,rgba(0,0,0,.216) 30%,rgba(0,0,0,.352) 40%,rgba(0,0,0,.5) 50%,rgba(0,0,0,.648) 60%,rgba(0,0,0,.784) 70%,rgba(0,0,0,.896) 80%,rgba(0,0,0,.972) 90%,#000);will-change:transform}
.sky-extension svg{display:block;width:100%;height:100%;overflow:hidden;opacity:var(--night)}
.foot{position:fixed;inset:auto 0 0;height:calc(var(--foot) + var(--bottom-inset));background:var(--paper);z-index:20;pointer-events:none}
.plate{position:absolute;top:16px;left:0;width:max(100vw,187.33svh);height:max(18.15vw,34svh);will-change:transform}
.plate img{position:absolute;inset:0;width:100%;height:100%;display:block;user-select:none}
.plate .base{opacity:.18;transition:opacity 1000ms ease}
.plate.is-ready .base{opacity:1}
.plate .base,.plate .tone{mask-image:linear-gradient(90deg,#000 0 46%,transparent 54%);mask-size:220% 100%;mask-position:100% 0;transition:opacity 1000ms ease,mask-position 1800ms cubic-bezier(.4,0,.2,1)}
.plate.is-ready .base,.plate.is-ready .tone{mask-position:0 0}
.plate.is-instant .base,.plate.is-instant .tone{mask-position:0 0;transition:none}
.plate .tone{opacity:var(--tone)}
.ridge-bridge{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.ridge-bridge path{fill:none;stroke:rgba(28,27,26,.28);stroke-width:3;stroke-linecap:round}
/* A warm sun, with the strongest orange at its visible lower edge. It rests on the ridge, holds almost
   still while the land pans beneath it, arrives in the saddle where the dusk glow later
   sits, and sinks behind the ridge as night comes. Clipped to the sky; under the dusk plate. */
.sun{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;mix-blend-mode:multiply;opacity:0;transition:opacity 650ms ease 900ms}
.is-ready .sun{opacity:1}
.is-instant .sun{transition:none}
.sun circle{transform:translate(calc(var(--sun-x,0)*(1 - var(--pan,1))*1px),calc((var(--sun-y,0)*(1 - var(--pan,1)) + min(1,var(--night,0)*2)*132)*1px))}
@media(prefers-reduced-motion:reduce){.sun circle{transform:none}}
.plate .dusk-img{opacity:var(--night)}
.rotors,.lights{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.rotors{opacity:0;transition:opacity 650ms ease 900ms}
.is-ready .rotors{opacity:1}
.is-instant .rotors{transition:none}
.rotor path,.rotor circle{fill:var(--paper);stroke:var(--rotor-ink,var(--ink));stroke-width:3.6;stroke-linejoin:round}
.rotor .spin{transform-box:fill-box;transform-origin:center;animation:spin var(--period,11s) linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.lights{opacity:var(--night)}
.lights .bcn{fill:#ff5a4a;animation:blink 3.8s steps(1) infinite}
@keyframes blink{0%,78%{opacity:.85}79%,100%{opacity:.15}}
.lights .lamp{fill:#ffe1a8;opacity:.65}
.labels-wrap{position:fixed;left:0;right:0;bottom:calc(var(--foot) + var(--bottom-inset));height:calc(var(--band) + 16px);z-index:11;pointer-events:none;overflow:hidden}
.labels-wrap svg{position:absolute;top:16px;left:0;overflow:visible}
.lbl{opacity:0}
.lbl circle{fill:var(--ink)}
.lbl path{fill:none;stroke:var(--ink);stroke-width:3}
.lbl path.halo{stroke:var(--paper);stroke-width:11}
.lbl circle.halo{fill:var(--paper)}
.lbl text{font-family:var(--cond);font-size:56px;fill:var(--ink);letter-spacing:.01em;paint-order:stroke;stroke:var(--paper);stroke-width:8;stroke-linejoin:round}

.chapters{position:absolute;left:var(--gutter);right:var(--gutter);bottom:var(--bottom-inset);height:var(--foot);z-index:20;display:flex;align-items:center;gap:16px;pointer-events:none}
.chapters a{pointer-events:auto;min-height:44px;width:60px;display:flex;align-items:center;gap:8px;font-size:13px;white-space:nowrap;opacity:.55;transition:opacity .2s ease;color:var(--ink)}
.chapters a span:last-child{display:none}
.chapters a[aria-current],.chapters a:hover,.chapters a:focus-visible{opacity:1}
.chapters i{display:block;position:relative;width:28px;height:1px;background:currentColor;opacity:.7;transform:scaleX(.55);transform-origin:left;transition:transform 450ms var(--ease)}
.chapters a[aria-current] i{transform:scaleX(1);opacity:1}
.chapters .n{font-family:var(--cond);font-size:12px;font-variant-numeric:tabular-nums}
.chapters .cur{font-size:13px;white-space:nowrap;width:9em;color:var(--mute);pointer-events:none}
.wind{font-family:var(--cond);font-size:12px;color:var(--mute);margin-left:auto;white-space:nowrap;opacity:0;transition:opacity .5s ease}
.wind.on{opacity:1}
.wind .short{display:none}
.is-hidden .spin,.is-hidden .bcn,.is-hidden .cue-sweep{animation-play-state:paused}

@media(min-width:1100px) and (min-height:501px){
  .focus-list{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;padding:0;margin:0}
}
@media(max-width:1099px){.labels-wrap,.wind{display:none}}
@media(max-height:760px) and (min-width:768px){
  :root{--band:30svh;--head:94px;--foot:48px;--display-size:clamp(36px,3.9vw,56px)}
  h1{max-width:22ch}
  .lead{font-size:clamp(28px,2.9vw,46px)}
  .block{margin-top:22px;padding-top:12px}.list{margin-top:10px;row-gap:.2em}
  .byline{margin-top:18px}.signoff{margin-top:10px}
}
@media(max-width:767px){
  :root{--display-size:clamp(30px,8.7vw,38px);--display-leading:1.075;--band:29svh;--head:clamp(96px,13svh,122px);--foot:44px;--gutter:24px;--bottom-inset:min(8px,env(safe-area-inset-bottom,0px));--reading-gap:18px}
  .top{padding-top:calc(var(--top-inset) + 12px)}
  .wordmark{font-size:18px}
  .scene{padding-bottom:calc(var(--band) + var(--foot) + var(--bottom-inset) + 24px)}
  h1{max-width:16ch}
  .display{max-width:none}
  .lead{max-width:30ch;font-size:clamp(26px,6.85vw,34px);line-height:1.16}
  .block{margin-top:24px;padding-top:14px}
  .list{grid-template-columns:1fr;row-gap:.25em;font-size:16px;line-height:1.4}
  .focus-list .list{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);column-gap:12px;row-gap:.45em;font-size:15px}
  .byline{margin-top:22px;font-size:12px}
  #focus .cue{margin-top:14px}
  .signoff{margin-top:10px}
  #work{--head:80px}
  #work .block{margin-top:20px;padding-top:12px}
  #work .list{margin-top:10px;row-gap:3px}
  #work .byline{margin-top:16px}
  .chapters{gap:7px}.chapters a{width:48px;gap:5px}.chapters i{width:22px}.chapters .cur{font-size:12px;width:auto;margin-left:6px}
}
@media(max-width:767px) and (max-height:700px){
  :root{--band:24svh;--head:86px;--foot:44px}
  .lead{font-size:25px}.block{margin-top:20px}
  #work{--head:80px}
  #work .block{margin-top:16px;padding-top:10px}
  #work .list{margin-top:8px;row-gap:2px;line-height:1.35}
  #work .byline{margin-top:12px}
  #work .signoff{margin-top:8px}
}
@media(max-height:500px){:root{--band:22svh;--head:86px}.wind,.labels-wrap{display:none}.focus-list{position:relative;clip-path:none;width:auto;height:auto;white-space:normal;margin-top:20px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}.plate .base,.plate .tone{mask:none}}

/* Standalone apps keep the full home-indicator inset; Safari already has a toolbar. */
@media(max-width:767px) and (display-mode:standalone){:root{--bottom-inset:env(safe-area-inset-bottom,0px)}}

/* Only unusually constrained phones use the compact type and spacing tier. */
@media(max-width:767px){
  .scene.is-compact{--head:80px}
  #focus.is-compact .cue{margin-top:10px}
  .scene.is-compact .lead{font-size:24px;line-height:1.13}
  .scene.is-compact .block{margin-top:16px;padding-top:10px}
  .scene.is-compact .list{margin-top:8px;row-gap:2px}
  .scene.is-compact .byline{margin-top:12px}
  #work.is-compact .block{margin-top:14px;padding-top:8px}
  #work.is-compact .list{display:flex;flex-wrap:wrap;column-gap:20px;row-gap:3px;margin-top:8px}
  #work.is-compact .byline{margin-top:12px}
}
@media(max-width:359px){
  :root{--display-size:30px}
  #work.is-compact{--head:80px}
  #work.is-compact .block{margin-top:12px;padding-top:6px}
  #work.is-compact .list{margin-top:6px;row-gap:2px}
  #work.is-compact .byline{margin-top:8px}
}

/* Keep the header itself a solid paint surface: WebKit's top-color sampler
   can reject background images, including gradients. The fade belongs below it. */
.top::before{content:"";position:absolute;inset:auto 0 100%;height:100px;background:var(--paper);pointer-events:none}
.top::after{content:"";position:absolute;inset:100% 0 auto;height:16px;background:linear-gradient(var(--paper),transparent);pointer-events:none}

/* The navigation inherits a solid fixed footer, so Safari does not cache
   the sampled colour of a separate transparent fixed navigation layer. */

@media(min-width:768px){.scene.is-compact{--head:clamp(84px,10svh,120px)}.scene.is-compact .lead{font-size:clamp(26px,2.2vw,40px)}.scene.is-compact .block{margin-top:14px;padding-top:8px}.scene.is-compact .list{row-gap:2px}.scene.is-compact .byline{margin-top:10px}}

/* Every input uses native document scrolling; chapter links are explicit jumps. */
html[data-layout="panorama"]{scroll-snap-type:none;scroll-padding-bottom:max(0px,calc(100dvh - 100svh))}
#viewport-size{position:fixed;width:0;height:100svh;visibility:hidden;pointer-events:none;contain:strict}
.scene{min-height:100svh;padding-bottom:calc(var(--band) + var(--foot) + var(--bottom-inset) + var(--reading-gap) + 16px)}
#work{min-height:100dvh}
.copy{min-width:0;overflow-wrap:anywhere}
#work .list{grid-template-columns:1fr}
@media(max-width:767px){#work.is-compact .list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px 18px}}
@media(max-height:500px){.top{padding-top:calc(var(--top-inset) + 8px)}.scene{--head:76px}.cue{margin-top:16px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto;scroll-snap-type:none!important}.plate .base,.plate .tone{mask:none;transition:none}.rotors{transition:none}}

.copy [id],.byline,.copy li{scroll-margin-top:calc(var(--head) + var(--top-inset));scroll-margin-bottom:calc(var(--band) + var(--foot) + 32px)}

.band,.labels-wrap{transform:translate3d(0,var(--art-offset,0px),0);will-change:transform}

/* Give the closing headline its intended measure when the wide layout splits. */
@media(min-width:1440px){
  #work.is-split .copy{max-width:1440px;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}
  #work .display{max-width:28ch}
}

/* No CSS snapping: explicit links and completed touch drags share moveTo(). */
