:root{--bg:#faf8f3;--ink:#0b0f1f;--mute:rgba(11,15,31,.55);--soft:rgba(11,15,31,.72);--rule:rgba(11,15,31,.1);--accent:var(--ink);--flash:rgba(11,15,31,.06)}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{scroll-behavior:smooth}
html,body{margin:0;background:var(--bg);color:var(--ink)}
body{font:16.5px/1.5 "EB Garamond",Georgia,serif}
.wrap{max-width:636px;margin:0 auto;padding:40px 24px 72px}
a{color:inherit;text-decoration:none}
/* top nav */
.nav{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 22px;font-size:16px;line-height:22px;margin:0 0 32px}
.nav .home{margin-right:auto}
/* directory-link hover (from his video): 1px ink underline across text+space+arrow, wipes in l→r ~250ms ease-out, retracts on leave; arrow stays put */
/* link hover (from his video): sibling opacity fade, 250ms ease. hovered/focused link → 1, its siblings → .45. nothing else moves or changes */
.fade :is(a,button){transition:opacity .25s ease}
.nav a:not([aria-current]){opacity:.45}
.dir{padding-bottom:1px}.dir[aria-current]{background:linear-gradient(currentColor,currentColor) 0 100%/100% 1px no-repeat}
@media (hover:hover){.fade:hover :is(a,button){opacity:.45}.fade :is(a,button):hover{opacity:1}}
.fade:has(:focus-visible) :is(a,button){opacity:.45}.fade :is(a,button):focus-visible{opacity:1;outline:none}
@media (min-width:1024px){.wrap{padding-top:56px}}
/* page enter: content below the nav blurs/fades up on load; nav stays put */
main{animation:enter .35s cubic-bezier(.22,1,.36,1) both}
@keyframes enter{from{opacity:0;transform:translateY(15px);filter:blur(8px)}to{opacity:1;transform:none;filter:none}}
/* home */
/* home greeting uses h1.big, same as subpage headings */
.bio{margin-top:12px;color:rgba(11,15,31,.92)}.bio p{margin:0}.bio p+p{margin-top:13px}
.bio a{text-decoration:underline;text-decoration-thickness:1px;text-decoration-color:rgba(11,15,31,.35);text-underline-offset:3px}
.touch{display:flex;flex-wrap:wrap;align-items:center;gap:8.75px;font-size:15px;line-height:21px;margin-top:28px}
.wipe{text-decoration:none}
.ph,.fill{font-size:12.5px;letter-spacing:.03em;color:var(--mute)}.ph{margin-left:6px}
.home-scene{margin-top:44px}
/* subpage headings */
.kicker{font-size:15px;color:var(--mute);font-variant:small-caps;letter-spacing:.04em;margin:0}
h1.big{font-size:34px;font-weight:400;line-height:1.15;margin:0 0 40px;letter-spacing:-.01em}
h1.title{font-size:22px;font-weight:600;margin:0 0 18px}
.u{border-bottom:1px solid rgba(11,15,31,.25);padding-bottom:1px}
.muted{color:var(--mute)}
.wip{margin:0}
/* work */
.rows{list-style:none;margin:0;padding:0}
.rows>li{display:grid;grid-template-columns:150px 1fr;gap:4px 24px;padding:20px 0;border-top:1px solid var(--rule)}
.rows>li:first-child{border-top:0;padding-top:0}
.rows .when{color:var(--mute);font-size:15px;padding-top:2px}
.rows .what{font-size:18px}.rows .desc{color:var(--soft);margin-top:4px}
@media (max-width:600px){.rows>li{grid-template-columns:1fr}}
/* projects */
.proj{list-style:none;margin:0;padding:0}
.proj>li{padding:22px 0;border-top:1px solid var(--rule)}.proj>li:first-child{border-top:0;padding-top:0}
.proj .name{font-size:19px}.proj .tags{color:var(--mute);margin-top:4px}.proj .desc{color:var(--soft);margin-top:6px;max-width:34em}
/* writing */
.tabs{display:flex;gap:6px;margin:0 0 22px}
.tabs button{-webkit-appearance:none;font:inherit;font-size:15px;color:var(--ink);background:none;border:0;padding:2px 9px;border-radius:2px;cursor:pointer}
.tabs button[aria-pressed=true]{background:var(--ink);color:var(--bg)}
.posts{list-style:none;margin:0;padding:0}
.posts li{display:flex;justify-content:space-between;gap:16px;align-items:baseline;padding:9px 0}
.posts a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}
.posts .date{color:var(--mute);font-size:15px;white-space:nowrap}
.post h1{font-size:26px;font-weight:500;margin:0}.post .date{color:var(--mute);margin:4px 0 26px}.post p{margin:0 0 14px}
/* ---- desk scene (from desk-stir.html, hat removed) ---- */
.desk{position:relative;width:min(100%,340px);padding-top:24px;user-select:none;-webkit-user-select:none;--line:var(--ink);--sw:2.6}
.desk svg{display:block;width:100%;height:auto;overflow:visible}
.ink{fill:none;stroke:var(--line);stroke-width:var(--sw);stroke-linecap:round;stroke-linejoin:round;transition:stroke .15s}
.dot{fill:var(--line);transition:fill .15s}
.hit{fill:transparent;stroke:none}
.obj{outline:none}
.obj:hover .ink,.obj.on .ink,.obj:focus-visible .ink{stroke:var(--accent)}
.obj:hover .dot,.obj.on .dot,.obj:focus-visible .dot{fill:var(--accent)}
.cursor{animation:blink 1.05s steps(1) infinite}@keyframes blink{50%{opacity:0}}
.steam .ink{opacity:.3}
.mug:hover .steam .ink,.mug.on .steam .ink{animation:rise 1.9s ease-in-out infinite}
.steam .ink:nth-child(2){animation-delay:-.6s!important}.steam .ink:nth-child(3){animation-delay:-1.25s!important}
@keyframes rise{0%{transform:translateY(8px);opacity:0}35%{opacity:.95}100%{transform:translateY(-12px);opacity:0}}
.bass:hover .str,.bass.on .str{animation:buzz .07s linear infinite alternate}
.str:nth-child(2){animation-delay:-.02s!important}.str:nth-child(3){animation-delay:-.05s!important}.str:nth-child(4){animation-duration:.09s!important}
@keyframes buzz{from{transform:translateX(-.6px)}to{transform:translateX(.6px)}}
.mug{touch-action:none}
.coffee{fill:var(--line);stroke:none}
#swirl{fill:none;stroke:var(--bg);stroke-linecap:round;stroke-linejoin:round}
.fine{stroke-width:calc(var(--sw) * .7)}
.str{stroke-width:1.3;opacity:.8}
@media (max-width:600px){.desk{--sw:2.8}.fine{stroke-width:2}}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*::before,*::after{animation:none!important;transition:none!important}}

/* hover animations */
.note{opacity:0;transform-box:fill-box;transform-origin:50% 50%}
.bass:hover .note,.bass.on .note{animation:note 1.8s ease-out infinite}
.bass .n1{animation-delay:.55s!important}.bass .n2{animation-delay:1.1s!important}
@keyframes note{0%{opacity:0;transform:translate(0,8px) rotate(-6deg)}20%{opacity:1}100%{opacity:0;transform:translate(10px,-34px) rotate(10deg)}}
.code{stroke-dasharray:1 1.02;stroke-dashoffset:0}
@keyframes ty0{0%,4%{stroke-dashoffset:1}13%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c0,.laptop.on .c0{animation:ty0 3.6s steps(7,end) infinite}
@keyframes ty1{0%,16%{stroke-dashoffset:1}25%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c1,.laptop.on .c1{animation:ty1 3.6s steps(7,end) infinite}
@keyframes ty2{0%,28%{stroke-dashoffset:1}37%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c2,.laptop.on .c2{animation:ty2 3.6s steps(7,end) infinite}
@keyframes ty3{0%,40%{stroke-dashoffset:1}49%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c3,.laptop.on .c3{animation:ty3 3.6s steps(7,end) infinite}
@keyframes ty4{0%,52%{stroke-dashoffset:1}61%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c4,.laptop.on .c4{animation:ty4 3.6s steps(7,end) infinite}
@keyframes ty5{0%,64%{stroke-dashoffset:1}73%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}
.laptop:hover .c5,.laptop.on .c5{animation:ty5 3.6s steps(7,end) infinite}

@media (prefers-reduced-motion:reduce){.dir{transition:none}.note{display:none}main{animation:none}}
