Colophon
A portfolio should be a work sample, not just a brochure. This page documents how this site is engineered (the stack, the security posture, and the decisions behind them) the same way I'd document any production system.
| Framework | Next.js (App Router, static generation where possible) |
| UI | React 19, TypeScript, Tailwind CSS v4 |
| PWA | Serwist service worker, installable on iOS |
| Data | Supabase (Postgres + storage), Resend for transactional email |
| Infra | Vercel, with CI running lint, typecheck, and build on every push |
| Fonts | Inter and JetBrains Mono, self-hosted via next/font, so there are no third-party font requests |
A personal site is a small attack surface, but it handles real user input (the contact form), so it gets treated like a real system:
A single site-wide CSP locks scripts, styles, frames, and connections to an explicit allowlist (self, Supabase for media, YouTube for embeds). object-src is none, base-uri and form-action are restricted to self, and frame-ancestors is none.
HSTS with a two-year max-age, includeSubDomains, and preload. X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Cross-Origin-Opener-Policy: same-origin, a locked-down Permissions-Policy (no camera, microphone, geolocation, payment, or USB access), and the X-Powered-By header removed.
Submissions pass through schema validation (Zod), a honeypot field that silently accepts and discards bot traffic, per-IP rate limiting, and HTML escaping before any value is interpolated into the notification email. Failures return generic errors, so no stack traces or internals leak to the client.
There are no logins, accounts, or admin pages. The only public endpoint that accepts input is the contact form, and the service-role database key stays on the server, never in the browser bundle.
A security.txt lives at /.well-known/security.txt. If you find something, I want to hear about it.
Every public page is statically generated at build time and served from the edge. There is no client-side data fetching on the public site, no analytics script, no third-party JavaScript at all. The CSP enforces that last claim rather than just promising it. Images go through next/image with explicit sizes; fonts are self-hosted and subset.
Found a vulnerability? See security.txt or use the contact form.