/* E: the page both hero variants share. Every colour and size is a design-system token. */
html{scroll-behavior:smooth}
body{overflow-x:clip}
.skip{position:absolute;left:16px;top:-60px;background:var(--focus);color:var(--on-focus);padding:8px 12px;border-radius:var(--r2);z-index:9}
.skip:focus{top:12px}
::-webkit-scrollbar-thumb:hover{background-color:var(--c5)}

/* The dots draw above the page (a pinned picture's paper hides the text that scrolls under it, not the dots). */
#field{position:fixed;inset:0;width:100%;height:100%;z-index:3;pointer-events:none}
.lb{position:fixed;left:0;top:0;width:120px;height:120px;margin:-60px 0 0 -60px;border-radius:50%;border:1.5px solid var(--c5);pointer-events:none;z-index:4;opacity:0;transition:opacity .3s}
.lb.on{opacity:.9}

/* The header is solid paper with a hairline: the text scrolling under it never shows through (a see-through header let
   it, most of all on a phone, where every section's text passes under it). */
.top{position:fixed;inset:0 0 auto;z-index:5;display:flex;justify-content:space-between;align-items:center;gap:1rem;padding:14px clamp(16px,4vw,48px);background:var(--paper);border-bottom:1px solid var(--line)}
.brand b{color:var(--c5)}
.top nav{display:flex;gap:1.2rem;align-items:center;font-size:var(--fs-sm)}
.top nav a{text-decoration:none;color:var(--muted)} .top nav a:hover{color:var(--ink)}

main{position:relative;z-index:2}
section{min-height:100vh;padding:clamp(96px,14vh,140px) clamp(16px,4vw,48px) clamp(56px,10vh,96px)}
.sec-h{font:800 var(--fs-display-1)/.82 var(--display);letter-spacing:-.06em;margin:0 0 1.2rem}
@supports (animation-timeline:view()){
  .sec-h{animation:wake linear both;animation-timeline:view();animation-range:entry 0% cover 40%}
  @keyframes wake{from{font-weight:200;letter-spacing:.02em;opacity:.3}}
}
.sec-lede{font-size:var(--fs-lg);color:var(--muted);max-width:52ch;margin:0 0 .6rem}
.help{font:500 var(--fs-xs)/1.5 var(--mono);color:var(--muted);margin:0 0 1rem;max-width:72ch}
.status{font:500 var(--fs-xs)/1.5 var(--mono);color:var(--ink);min-height:1.5em;margin:0}
.panel{max-width:1100px;background:color-mix(in srgb,var(--paper) 84%,transparent);border-radius:var(--r4);padding:clamp(16px,3vw,32px);border:1px solid color-mix(in srgb,var(--line) 70%,transparent)}

/* ---------- shared session pieces ---------- */
.tools{list-style:none;margin:0;padding:0;font:400 var(--fs-xs)/1.45 var(--mono);color:var(--muted)}
.tools .st{font-weight:500;color:var(--ok)}
.tools .st::before{content:"ok"}
.tools li.is-run .st{color:var(--c1)} .tools li.is-run .st::before{content:"···"}
.tools code{color:var(--ink);background:none;padding:0;font-size:1em;overflow-wrap:anywhere}
.tools .ms{font-variant-numeric:tabular-nums}
.tk{animation:tk .7s ease-out both} /* a streamed token fades in; no colour of its own */
@keyframes tk{from{opacity:0;filter:blur(4px)}}
.caret{display:inline-block;width:.08em;min-width:3px;height:.9em;background:var(--c5);vertical-align:-.08em;margin-left:3px;animation:blink 1s steps(2) infinite}
@keyframes blink{50%{opacity:.2}}
.meters{font:500 var(--fs-2xs)/1.5 var(--mono);color:var(--muted);margin:0;display:flex;flex-wrap:wrap;gap:.2rem 1rem}
.meters b{color:var(--ink);font-weight:500;font-variant-numeric:tabular-nums}
.turn{margin-top:1.6rem}
.turn .you{font:500 var(--fs-sm)/1.5 var(--mono);color:var(--muted);margin:0 0 .4rem}
.turn .you::before{content:"› ";color:var(--c5)}
.turn .answer p{font:700 var(--fs-xl)/1.35 var(--display);letter-spacing:-.01em;max-width:44ch;margin:0 0 .4rem}
.turn .more{font:500 var(--fs-sm) var(--body)!important;letter-spacing:0!important}
.note{font:500 var(--fs-xs)/1.5 var(--mono)!important;color:var(--ink);display:flex;gap:.6rem;align-items:center;flex-wrap:wrap}
.runs-log{font:400 var(--fs-2xs)/1.5 var(--mono);color:var(--muted);display:grid;gap:.1rem;margin-top:.6rem}

/* ---------- hero variant 1: the session dissolves into the field ---------- */
.hero1{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);grid-template-areas:"main stage" "trace trace";gap:1.5rem clamp(24px,4vw,64px);align-content:center;max-width:1320px;margin:0 auto;padding-top:104px;transition:opacity .8s ease}
.intro .hero1{opacity:0}
.hero1 .main{grid-area:main;min-width:0}
.hero1 .q{font:500 var(--fs-md)/1.5 var(--mono);color:var(--muted);margin:0 0 1.2rem;min-height:1.5em}
.hero1 .q::before{content:"› ";color:var(--c5)}
.hero1 h1{font:800 var(--fs-display-2)/.95 var(--display);letter-spacing:-.05em;margin:0 0 1.2rem;max-width:16ch}
.hero1 .lede{font-size:var(--fs-xl);line-height:1.5;max-width:40ch;margin:0}
.stage1{grid-area:stage;position:relative;min-height:clamp(300px,52vh,520px)}
.stage1 .dots{position:absolute;inset:0}
.js .stage1 .tools li{position:absolute;left:calc(var(--sx) * 100%);top:calc(var(--sy) * 100%);transform:translate(-50%,34px);text-align:center;width:max-content;max-width:48%;display:grid;gap:.1rem;transition:opacity .4s}
.js .stage1 .tools li.is-pre{opacity:0}
.stage1 .tools .out{font-size:var(--fs-2xs)}
.trace1{grid-area:trace;min-width:0}
/* The trace is one thin line of coloured spans; the names sit under it as a legend. */
.trace1 .spans{list-style:none;margin:.6rem 0 0;padding:14px 0 0;position:relative;display:flex;flex-wrap:wrap;gap:.3rem 1.2rem;border-top:1px solid var(--line);font:500 var(--fs-2xs)/1.4 var(--mono);color:var(--muted)}
.trace1 .spans li{display:flex;gap:.4em;align-items:center}
.trace1 .spans li::before{content:"";position:absolute;top:-2px;left:var(--l);width:var(--w);min-width:3px;height:3px;background:var(--k)}
.trace1 .spans li::after{content:"";order:-1;width:.6em;height:.6em;border-radius:50%;background:var(--k)}
.trace1 .spans .nm{color:var(--ink)}
.trace1 .spans .track{display:none}
.composer1{margin-top:1.8rem;display:grid;gap:.9rem;max-width:680px}
.chips{display:flex;flex-wrap:wrap;gap:.4rem 1.1rem}
.chip-q{font:600 var(--fs-sm)/1.3 var(--body);background:none;border:0;border-bottom:1.5px solid var(--line);color:var(--ink);padding:.1em 0;cursor:pointer}
.chip-q:hover{border-color:var(--c5)}
.ask{display:flex;gap:.6rem;align-items:center;border-bottom:2px solid var(--line)}
.ask:focus-within{border-color:var(--c5)}
.ask input{flex:1;min-width:0;background:none;border:0;padding:.55em 0;color:var(--ink);font:400 var(--fs-md) var(--mono)}
.ask input:focus-visible{outline:none}
.ask input::placeholder{color:var(--muted)}

/* ---------- hero variant 2: a command bar, editorial answer, marginalia ---------- */
.hero2{max-width:1320px;margin:0 auto;padding-top:120px;display:grid;grid-template-columns:minmax(0,1fr) 280px;grid-template-areas:"bar bar" "main margin";gap:0 clamp(24px,5vw,72px);align-content:start;transition:opacity .8s ease}
.intro .hero2 .main2,.intro .hero2 .margin{opacity:0}
.hero2 .main2,.hero2 .margin{transition:opacity .8s ease .2s}
.bar{grid-area:bar;justify-self:center;width:min(760px,100%);position:relative;z-index:3;display:flex;align-items:center;gap:.6rem;background:var(--surface);border:1.5px solid var(--line);border-radius:var(--pill);padding:.45rem .45rem .45rem 1.1rem;box-shadow:var(--shadow);margin-bottom:clamp(110px,16vh,150px)}
.bar:focus-within{border-color:var(--c5)}
.bar:has(input:focus-visible){outline:3px solid var(--ring);outline-offset:3px}
.bar input{flex:1;min-width:0;border:0;background:none;font:500 var(--fs-lg)/1.3 var(--body);color:var(--ink);padding:.35em 0}
.bar input:focus-visible{outline:none}
.bar input::placeholder{color:var(--muted)}
.bar kbd{flex:none}
@media (pointer:coarse){.bar kbd{display:none}}
.bar-mark{font:800 var(--fs-xl)/1 var(--display);color:var(--c5)}
.sugg{position:absolute;top:calc(100% + 8px);left:0;right:0;list-style:none;margin:0;padding:.4rem;background:var(--surface);border:1px solid var(--line);border-radius:var(--r3);box-shadow:var(--shadow)}
.sugg li{padding:.55em .9em;border-radius:var(--r2);cursor:pointer;font-size:var(--fs-sm);display:flex;justify-content:space-between;gap:1rem}
.sugg li small{font:500 var(--fs-2xs) var(--mono);color:var(--muted)}
.sugg li[aria-selected=true]{background:var(--soft)}
.main2{grid-area:main;min-width:0}
.main2 h1{font:800 var(--fs-display-wide)/.95 var(--display);letter-spacing:-.05em;max-width:15ch;margin:0 0 1.4rem}
.main2 .lede{font-size:var(--fs-xl);line-height:1.55;max-width:42ch;margin:0}
.margin{grid-area:margin;border-left:1px solid var(--line);padding-left:1.2rem;font:500 var(--fs-2xs)/1.5 var(--mono);color:var(--muted);align-self:start;min-width:0;display:grid;gap:1rem}
.margin h2{font:500 var(--fs-2xs)/1.4 var(--mono);letter-spacing:0;margin:0;color:var(--muted)}
.margin .tools{counter-reset:tool;font-size:var(--fs-2xs)}
.margin .tools li{counter-increment:tool;position:relative;padding:.45rem 0 .45rem 1.4em;border-bottom:1px dashed var(--line)}
.margin .tools li::before{content:counter(tool);position:absolute;left:0;color:var(--c5);font-weight:500}
.margin .tools .out,.margin .tools .ms{display:block}
.margin .tools li.is-pre{opacity:.35}
.margin .spans{list-style:none;margin:0;padding:0;display:grid;gap:.45rem}
.margin .spans li{display:grid;grid-template-columns:1fr auto;gap:.15rem .5rem}
.margin .spans .nm{color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.margin .spans .track{grid-column:1 / -1;height:5px;border-radius:3px;background:var(--soft);position:relative;overflow:hidden}
.margin .spans .track i{position:absolute;top:0;bottom:0;left:var(--l,0%);width:var(--w,0%);border-radius:3px;background:var(--k)}
/* The portrait: his face in dots beside the heading, pinned while the answer and its trace scroll past; the trace
   moves under the answer to make the room. On a phone it sits between the bar and the heading, and the text scrolls
   under it. Its box only places the picture: the dots fit inside it, whole. */
.js .hero2{grid-template-columns:minmax(0,1fr) clamp(200px,33vw,760px);grid-template-areas:"bar bar" "main portrait" "margin portrait";grid-template-rows:auto auto 1fr}
.js .hero2 .bar{margin-bottom:clamp(40px,7vh,88px)}
.js .portrait{grid-area:portrait;aspect-ratio:5/4;align-self:start}
.js .hero2 .margin{border-left:0;border-top:1px solid var(--line);padding:1rem 0 0;margin-top:2rem;max-width:760px}
@media (min-width:900px){
  .js .hero2 .margin{grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:clamp(24px,3vw,48px);align-items:start}
  .js .hero2 .margin>[data-js]{grid-column:2;grid-row:1 / span 2}
}
@media (max-width:599px){
  .js .hero2{display:block}
  .js .hero2 .bar{margin-bottom:.8rem}
  .js .portrait{aspect-ratio:auto;height:clamp(180px,32svh,300px);margin-bottom:1rem}
}

/* ---------- pinned pictures: each section's picture stays below the header while its text scrolls past ---------- */
/* --hdr is the header's measured height and --pin-b the pinned picture's bottom edge, both set by home.js. A control
   in the text that scrolls under a picture keeps --pin-b clear of it when focus scrolls it into view. */
.js .pin{position:sticky;top:var(--hdr,56px);z-index:1;background:var(--paper)}
.js section>:not(.pin):is(a,button,input,[tabindex]),.js section>:not(.pin) :is(a,button,input,[tabindex]){scroll-margin-top:var(--pin-b,0px)}
/* A short screen (a phone held sideways) has no room to pin: a picture would take over half of what is left under
   the header (the tallest, the Now graph, is max(300px,42svh): half from 656px), so every picture scrolls with its text. */
@media (max-height:655px){.js .pin{position:relative;top:auto!important}} /* !important: the wide layouts set each pin's top by id */

/* ---------- Now: the orchestrator graph ---------- */
.graph{position:relative;display:flex;flex-wrap:wrap;gap:.5rem;margin:1rem 0 1.4rem}
.js .graph{display:block;height:clamp(380px,56vh,560px);margin:0 0 .8rem}
.node{font:600 var(--fs-xs)/1 var(--body);color:var(--ink);background:color-mix(in srgb,var(--paper) 78%,transparent);border:1px solid var(--line);border-radius:var(--pill);padding:.4em .75em;white-space:nowrap}
.js .node{position:absolute;left:calc(var(--x) * 100%);top:calc(var(--y) * 100%);transform:translate(-50%,24px);cursor:grab;touch-action:none}
.js .node.core{transform:translate(-50%,44px);font-weight:800}
.node:hover{border-color:var(--c5)}
.node.is-drag{cursor:grabbing;border-color:var(--c5)}
.node[aria-pressed=true]{color:var(--muted);text-decoration:line-through;border-style:dashed}
.lanes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2.5vw,32px);margin-top:1.4rem}
.lanes h3{font:800 var(--fs-xl)/1.15 var(--display);margin:0 0 .5rem;display:flex;gap:.5rem;align-items:center}
.lanes h3::before{content:"";width:14px;height:14px;border-radius:3px;background:var(--k);flex:none}
.lanes p{margin:0;color:var(--muted)}

/* ---------- Work: the jobs scroll past the helix, which spells the one in the middle of the screen ---------- */
.js .helix{height:clamp(240px,40vh,380px)}
.story{margin:0 0 2rem}
.years{position:relative;height:1.4em;margin-top:.4rem;font:500 var(--fs-2xs) var(--mono);color:var(--muted)}
.years span{position:absolute;left:calc((var(--y) - 2016) / 10.75 * 100%);transform:translateX(-50%)}
.jobs{list-style:none;margin:0;display:grid;gap:1.8rem}
.jobs>li{display:grid;grid-template-columns:minmax(0,220px) minmax(0,1fr);gap:.3rem 2rem;transition:opacity .4s}
.jobs>li.is-dim{opacity:.4}
.when{font:500 var(--fs-xs)/1.5 var(--mono);color:var(--muted);background:none;border:0;padding:0;text-align:left;align-self:start}
.jobs h3{font:800 var(--fs-display-3)/1 var(--display);letter-spacing:-.03em;margin:0 0 .5rem}
.jobs h3 small{display:block;font:500 var(--fs-md)/1.4 var(--body);letter-spacing:0;color:var(--muted);margin-top:.35rem}
.jobs ul{margin:0;padding-left:1.1rem;color:var(--muted)}
.jobs ul li{margin:.25rem 0}
.jobs ul li::marker{color:var(--c5)}
.jobs strong{color:var(--ink);font-weight:600}

/* ---------- Stack: the sphere left, the list right ---------- */
.js #skills{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:auto auto auto 1fr;gap:0 clamp(24px,4vw,64px);align-items:start}
.js #skills>*{grid-column:2}
/* Shorter than its section, so there is room to pin: the list scrolls, the sphere stays. */
.js #skills>.sphere{grid-column:1;grid-row:1 / span 4;height:min(64vh,640px);top:clamp(96px,14vh,140px)}
.skill-filters{display:flex;flex-wrap:wrap;gap:.4rem;margin:0 0 1.4rem}
.cats{display:grid;gap:1rem;margin:0}
.cats>div{display:grid;grid-template-columns:7.5rem minmax(0,1fr);gap:.2rem 1rem;align-items:baseline}
.cats dt{font:500 var(--fs-xs) var(--mono);color:var(--muted)}
.cats dd{margin:0;display:flex;flex-wrap:wrap;gap:.2rem .3rem}
.skill{font:600 var(--fs-md)/1.3 var(--body);background:none;border:0;padding:.15em .4em;border-radius:var(--r1);color:var(--ink);cursor:pointer;transition:opacity .3s,background-color .2s}
.skill.is-dim{opacity:.35}
.skill:hover,.skill.is-on{background:color-mix(in srgb,var(--c5) 18%,transparent)}

/* ---------- Things I run: shapes, tilt, previews ---------- */
.runs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(12px,2vw,24px);max-width:1300px;margin-top:1rem}
.run{position:relative;display:flex;flex-direction:column;padding:clamp(18px,2.4vw,28px);border-radius:var(--r4);text-decoration:none;border:1.5px solid var(--k);background:none;transition:background-color .3s}
.js .run{min-height:clamp(440px,64vh,580px)}
/* The dots draw the shape on the canvas under the page: a card's fill must stay see-through, or it hides them. */
.run:hover,.run:focus-visible{background:color-mix(in srgb,var(--k) 10%,transparent)}
.run .shape{flex:1;min-height:40px}
.js .run .shape{min-height:200px}
.run .pv{font:400 var(--fs-xs)/1.6 var(--mono);color:var(--muted);border-top:1px solid var(--line);padding:.6rem 0 .8rem;height:4.4em;overflow:hidden;position:relative}
.run .word{font:800 var(--fs-display-2)/.85 var(--display);letter-spacing:-.06em;color:var(--k)}
.run .dom{font:500 var(--fs-xs) var(--mono);color:var(--ink);margin:.8rem 0 .4rem}
.run p{margin:0;color:var(--muted)}
.run .flag{position:absolute;top:18px;left:clamp(18px,2.4vw,28px);font:500 var(--fs-2xs) var(--mono);color:var(--muted)}
.pv-til{display:flex;align-items:center;gap:.5rem;height:100%}
.pv-til span{border:1px solid var(--line);border-radius:var(--r1);padding:.1em .5em;color:var(--ink)}
.pv-til i{flex:1;height:2px;background:var(--line);position:relative;overflow:hidden}
.pv-til i::after{content:"";position:absolute;inset:0 auto 0 0;width:30%;background:var(--c1);animation:slide 1.6s linear infinite}
@keyframes slide{from{transform:translateX(-100%)}to{transform:translateX(340%)}}
.pv-sh div{white-space:nowrap;overflow:hidden;width:0;animation:type 4.5s steps(26) infinite}
.pv-sh div+div{animation-name:type2;color:var(--ink)}
@keyframes type{0%{width:0}35%,100%{width:26ch}}
@keyframes type2{0%,45%{width:0}75%,100%{width:32ch}}
.pv-lo .tags{display:flex;flex-wrap:wrap;gap:.3rem;margin-top:.3rem}
.pv-lo .tags span{border:1px solid var(--c3);color:var(--ink);border-radius:var(--pill);padding:0 .55em;animation:sprout 5s infinite both}
.pv-lo .tags span:nth-child(2){animation-delay:.3s}.pv-lo .tags span:nth-child(3){animation-delay:.6s}
/* sprout moves its text: home.js reads it each frame (LIVE) so no dot covers it */
@keyframes sprout{0%,20%{opacity:0;transform:translateY(6px)}35%,90%{opacity:1;transform:none}100%{opacity:0}}

/* ---------- Contact: type your name ---------- */
.js .hey{height:clamp(200px,34vh,340px)}
.fly{display:flex;flex-wrap:wrap;gap:.8rem;align-items:center;margin:.4rem 0 .6rem}
.fly input{font:600 var(--fs-lg)/1.3 var(--body);background:transparent;border:0;border-bottom:2px solid var(--line);padding:.3em .1em;color:var(--ink);width:min(320px,100%)}
.fly input:focus-visible{outline:none;border-color:var(--c5)}
.big{display:inline-block;margin-top:2rem;font:800 var(--fs-display-3)/1 var(--display);letter-spacing:-.04em;overflow-wrap:anywhere;text-decoration-color:var(--c5)}
.links{list-style:none;margin:1.4rem 0 0;padding:0;display:flex;flex-wrap:wrap;gap:.6rem 1.4rem;font-size:var(--fs-lg)}
footer{position:relative;z-index:2;padding:24px clamp(16px,4vw,48px) 40px;color:var(--muted);font-size:var(--fs-sm)}

@media (max-width:900px){
  .top nav a{display:none}
  .hero1{grid-template-columns:minmax(0,1fr);grid-template-areas:"stage" "main" "trace";padding-top:84px}
  .stage1{min-height:0}
  .stage1 .dots{position:relative;inset:auto;height:190px}
  .js .stage1 .tools li{position:static;transform:none;text-align:left;width:auto;max-width:none;display:flex;flex-wrap:wrap;gap:0 .6rem;padding:.2rem 0}
  .stage1 .tools li>*{min-width:0;overflow-wrap:anywhere}
  .js .stage1 .tools li.is-pre{display:none}
  .hero2{grid-template-columns:minmax(0,1fr);grid-template-areas:"bar" "main" "margin";padding-top:96px}
  .bar{margin-bottom:90px}
  .margin{border-left:0;border-top:1px solid var(--line);padding:1rem 0 0;margin-top:2rem}
  .lanes,.runs{grid-template-columns:minmax(0,1fr)}
  .jobs>li{grid-template-columns:minmax(0,1fr)}
  .js #skills{display:block}
  .js #skills>.sphere{top:var(--hdr,56px);height:max(240px,34svh)}
  .js #now>.graph{height:max(300px,42svh)}
  .js .story .helix{height:max(150px,22svh)}
  .cats>div{grid-template-columns:minmax(0,1fr)}
  .js .run{min-height:400px}
}
@media (max-width:600px){
  .story{padding-inline:1rem} /* the first and last year labels centre on the ends: keep them off the screen's edge */
}
/* Phones: the headings, the ledes and the short lines round them centre on the narrow column, and so do the skills and
   the contact block. What is read line by line stays left: the jobs' bullets, the lanes, the site cards with their
   terminal previews, and the tool calls and the trace. */
@media (max-width:599px){
  .main2,.sec-h,.sec-lede,.help,.status,.jobs .when,.jobs h3,.cats,#contact,footer{text-align:center}
  .main2 h1,.main2 .lede,.turn .answer p,.sec-lede{margin-inline:auto}
  .note,.skill-filters,.cats dd,.fly,.links{justify-content:center}
  .fly input{text-align:center}
}

/* Wider screens pin each section's picture while its text scrolls past, so a small scroll leaves the dots still. */
@media (min-width:900px){
  .js #work{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);column-gap:clamp(24px,4vw,72px);align-items:start}
  .js #work>.sec-h{grid-column:1 / -1}
  .js #work>.story{top:clamp(88px,16vh,180px)}
  .js .jobs>li{grid-template-columns:minmax(0,1fr);min-height:50vh;align-content:start} /* a job stays in the middle for half a screen */
}
/* Laptop and wider: the Now graph is pinned beside its text and the three lanes, which point at its services. */
@media (min-width:1200px){
  .js #now{display:grid;grid-template-columns:minmax(360px,.9fr) minmax(0,2fr);grid-template-rows:repeat(5,auto) 1fr;column-gap:clamp(32px,4vw,72px);align-items:start}
  .js #now>*{grid-column:1}
  .js #now>.graph{grid-column:2;grid-row:1 / -1;height:min(72vh,720px);margin:0;top:clamp(80px,14vh,140px)}
  .js #now>.status{margin-top:1rem}
  .js #now>.lanes{grid-template-columns:minmax(0,1fr)}
}

/* Wide screens: one centred frame for every section, and the width used instead of a lone column. */
@media (min-width:1600px){
  .top,section,footer{padding-inline:max(48px,calc((100vw - 2160px)/2))}
  .hero2{max-width:none;grid-template-columns:minmax(0,1fr) 360px}
  .bar{width:min(960px,100%)}
  .main2 h1{max-width:16ch}
  .main2 .lede{font-size:var(--fs-2xl);max-width:40ch}
  .panel,.runs{max-width:none}
  .js .helix{height:min(50vh,560px)}
  /* The list centres on the sphere: two elastic rows around it take the spare height. */
  .js #skills{grid-template-rows:1fr repeat(4,auto) 1fr}
  .js #skills>.sphere{grid-row:1 / -1;height:min(66vh,900px)}
  .js #skills>.sec-h{grid-row:2} .js #skills>.sec-lede{grid-row:3} .js #skills>.skill-filters{grid-row:4} .js #skills>.cats{grid-row:5}
  .js #contact{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);column-gap:clamp(32px,4vw,96px);align-content:center}
  .js #contact>*{grid-column:1}
  .js #contact>.hey{grid-column:2;grid-row:1 / span 5;height:min(56vh,560px);align-self:center}
}
@media (prefers-reduced-motion:reduce){.sec-h,.tk{animation:none!important}}

/* Colours by data attribute, not style="" (the CSP allows no inline styles): an element's
   data-k names the token its --k takes. */
[data-k=c1]{--k:var(--c1)}[data-k=c2]{--k:var(--c2)}[data-k=c3]{--k:var(--c3)}[data-k=c4]{--k:var(--c4)}[data-k=c5]{--k:var(--c5)}[data-k=new]{--k:var(--new)}
.debug{position:fixed;left:8px;right:8px;bottom:8px;z-index:50;margin:0;padding:8px 10px;border-radius:8px;background:rgba(0,0,0,.82);color:#9fef9f;font:11px/1.45 ui-monospace,Menlo,monospace;white-space:pre-wrap;pointer-events:none}
