How this site is built
For a frontend developer the portfolio is itself a work sample, so the numbers are here rather than implied. Open dev tools; that's the point.
What it ships
| Metric | Budget | Actual |
|---|---|---|
| JavaScript, gzipped | 10kb | 1.2kb |
| CSS, gzipped | 14kb | 5.4kb |
| Fonts | 90kb | 69kb |
The heaviest page is 6.1kb of gzipped HTML, and no page loads an external JavaScript file.
Lighthouse
- Performance
- ≥ 95
- Accessibility
- 100
- LCP
- < 1.5s
- CLS
- < 0.01
Budget agreed before the first line of CSS. `bundle` is measured from the production build and is real. `lighthouse` stays null until an actual run — see README. A performance claim without a run behind it is the thing this page exists to argue against.
Stack, and why
- Astro
- Zero JavaScript by default. The scoreboard is won by construction rather than by optimising a framework back down afterwards.
- No UI framework
- The assistant on /ai is the only interactive piece on the site, and it is a plain script — 1.2kb gzipped, inlined, 0 external JS files. Preact with its renderer, hooks and signals measured 11.3kb for the same form, so it came out.
- Cloudflare Workers
- Edge delivery, and the KV counter that rate-limits the assistant endpoint.
- Self-hosted fonts
- 69kb of latin-subset woff2. Static instances, not variable files — pinning Archivo to one width and weight took it from 88kb to 14kb. No third-party font request.
- No analytics, no cookie banner
- Nothing is collected, so there is no consent dialog to dismiss.
Decisions people ask about
- Why no contact form?
- A form is another endpoint, another abuse surface, and one more thing that can silently fail to deliver. A visible email address cannot break.
- Why is there no dark mode?
- A second palette I would maintain half as carefully. The one palette here is contrast-checked; a second one would be a claim I have not tested.
- Why does the AI section fail so loudly?
- It does the opposite — the endpoint fails closed and the section degrades to static links. If the key is missing, the rate limiter is unbound, or the upstream is down, the page still answers the question with links to the same content.
- What is the animation budget?
- One orchestrated sequence on the hero, and nothing else. Scroll-triggered reveals were built and then removed: content that waits at opacity zero for an observer can render washed out, and a page that might look half-faded to a reviewer is a bad trade for a fade-in. Nothing below the fold depends on JavaScript to be visible, and prefers-reduced-motion renders the hero at its final state too.
Accessibility
- Semantic landmarks, one h1 per page, headings in order.
- Every interactive element reachable by keyboard with a visible focus ring.
- The ledger is a real table: values are text, the bars are decoration and hidden from assistive tech.
- The Liquid-tag eyebrows are aria-hidden — a screen reader gets the real heading instead.
- Colour is never the only signal; amber and teal fill bars and never set text.