/writing
Rebuilding my personal site
· 3 min read
I rewrote my personal site. Every route had to score well on performance, accessibility, best practices and SEO, and the visual treatment was not allowed to get quieter to make that happen.
What came out is a small static site with a few interactive pieces, an animated backdrop that turns itself off under reduced motion, and a design system page that documents itself.
Static-first with no client framework
The site is mostly text with some decoration, so a static-first framework is the right shape. Every component renders to HTML by default, and the only JavaScript that ships is what a page explicitly mounts.
An earlier version used a thin client framework to wrap the heavy pieces, a rotating globe and a WebGL backdrop. The wrapper was doing nothing. The real work lived in libraries that were not framework-specific, and the wrapper only mounted them. Removing it dropped about ten kilobytes gzipped of runtime that no UI was using.
The interactive pieces now mount through plain script blocks, and each one gates itself. The globe waits until the hero scrolls into view. The backdrop checks prefers-reduced-motion and only imports its implementation if motion is allowed. The question is not how fast something loads. It is whether it should load at all for this person.
Reduced motion as a real signal
The backdrop is heavy. For anyone with prefers-reduced-motion set, none of it loads: the implementation sits behind a dynamic import gated on matchMedia, so that group pays zero bytes for something they will never see. Every other animation on the site has the same branch, gated as high up as the asset graph allows.
Build-time over runtime
Open Graph images, structured metadata, the RSS feed, the sitemap, image variants and the audit that gates each deploy all happen at build time. No headless browser in the pipeline, no fonts installed at deploy, no cold start on the first request.
There is also a /system page listing every color, font and motion curve in use. It reads from the same token source as the rest of the site, so the documentation cannot drift from the implementation.
A page for the music
There is a /music page with the tracks I keep nearby: what is on rotation, the all-time list, favorite mix compilations, and a separate cut of Brazilian songs from home. The data is a flat file and the rendering uses the same Section primitive as everything else.
Holding the line
The constraint held. Every route still audits at ninety-nine or better on performance and full marks on accessibility, best practices and SEO, and the audit runs on every deploy rather than when I remember to check. The visual treatment did not get quieter to make that happen, which was the part I was most worried about giving up.
What I cut
The client framework that wrapped canvas mounts and earned nothing. Hydration nobody would see. Shims for tools I do not use. Animations for people who asked not to have them. Convenience layers that pay off on a different shape of project.
The site is small, builds in three seconds, and audits in under a minute.
More writing
Rebuilding SentiNEO as a Desktop
Why I rebuilt an asteroid tracker from a scrolling list into a desktop of draggable windows, and why the phone version had to be a different interface.
· 3 min read
What My Thesis Assumed About Hardware
Five years on from my paper about coordinating jobs across weak devices. The hardware assumption aged badly. The reliability assumption did not age at all.
· 3 min read
Cutting Backend CI by 76%
A Django test pipeline went from a median of 18.5 minutes to 4.5. Almost none of it came from making tests faster. The last part was a connection budget.
· 6 min read