Uses
What I actually reach for, rather than everything I’ve touched. A tools page that lists a technology I used once is a tools page that costs credibility with the person who asks about it.
Language and framework
- TypeScript in strict mode, with noUncheckedIndexedAccess
- React 19 — Server Components first, client islands where interaction requires it
- Next.js App Router
- Zod for anything crossing a boundary
Data and state
- TanStack Query, seeded from the server rather than refetched on hydration
- Redux where genuinely shared mutable state exists, and not otherwise
- React Hook Form
Styling
- Tailwind CSS v4 with @theme tokens
- A constrained scale — few spacing steps, few type sizes, two radii
- Accessibility built into shared primitives, not retrofitted in QA
Real-time
- SIP.js and WebRTC for browser telephony
- Pusher for presence, delivery state and reconnection
Testing
- Vitest and React Testing Library
- Playwright for the paths that matter
- MSW as the mock backend, reused as the CI fixture layer
Elsewhere in the stack
- Go, working knowledge — enough to ship a gateway module
- PHP and Laravel
- Docker, GitHub Actions
This site, checked
I claim WCAG 2.1 AA and a performance budget, so here is the record. Every ticked line is something done on this site with the date it was done; anything not yet verified says so rather than being listed as an intention. The case studies explain the same approach applied to production work.
None of it is on my word. Every ticked line is a check that runs in this site’s CI and fails the build — the contrast script parses the palette, the axe and keyboard suites drive the production build in a real browser, and the bundle budget is measured per route against a recorded baseline. Clone the repository and they run the same way.
Accessibility
- Keyboard-complete — every tab stop on every page reached, in order, with a visible focus indicator and no trap. Both demos operable without a pointer — verified 16 August 2026
- WCAG 2.1 AA contrast — text 4.5:1, UI components 3:1, verified by script against the palette in both themes — verified 16 August 2026
- Reflow to 320 CSS pixels — the 1.4.10 floor, which is a 1280px window at 400% zoom — with no horizontal scroll and nothing hidden — verified 16 August 2026
- prefers-reduced-motion · prefers-contrast · forced-colors — each asserted to actually change the rendered page, not just to exist in the stylesheet — verified 16 August 2026
- axe-core across every route, in both themes and in forced-colors, failing the build on any violation — verified 16 August 2026
- Manual VoiceOver pass — not yet verified
Performance
- Lighthouse accessibility, best practices and SEO at 100 on five routes — home, a post, a case study, a demo and the résumé — gated in CI at 100 and failing the build below it. Those three do not move with machine noise; the performance score is reported rather than gated, because a number that swings with what else the machine is doing is not something to fail a build on — verified 16 August 2026
- No third-party runtime dependencies — next, react and react-dom, and the build fails if package.json gains a fourth. Every animation on the site is a CSS transition or a custom property written from a pointer handler; no motion library was needed, and that was checked after the work rather than assumed before it — verified 16 August 2026
- Bundle budget measured per route from a recorded baseline and enforced in CI — the build fails when a route exceeds it — verified 16 August 2026
- Field Core Web Vitals — LCP, INP, CLS — not yet verified
- Syntax highlighting ships zero client JavaScript — asserted against the emitted chunks, alongside every other build-time dependency — verified 16 August 2026
- Fonts self-hosted and subset, with matched fallback metrics so the swap does not shift layout — and every character the site renders is checked against the subset, so nothing silently falls back mid-word — verified 16 August 2026
- No layout shift: 0.000 on load and while the demos run, measured on a throttled mobile profile — verified 16 August 2026
- Interactive demos are code-split and mounted after hydration, so a post carries the cost of a demo only if it shows one — verified 16 August 2026