Five years into leading engineering teams, I know the warning sign: you stop shipping things yourself. You review PRs instead of writing them. You run retros instead of debugging production. You describe what good code looks like instead of writing it. The job pulls you toward that and if you don't notice, you eventually find yourself credentialing yourself on work you're no longer doing.
This site is a small hedge against that.
I could have used a template. Framer, Webflow, a polished Next.js starter, any of them would have had me live in an afternoon. I chose not to, partly because the site is itself a portfolio piece that engineers and hiring managers will inspect, and a Framer template doesn't tell them much about how I think. Partly because I wanted the satisfaction of building something end-to-end again.
The choices that were interesting
Next.js 16 and React 19, not something more conservative. The App Router's server/client split is still genuinely new territory at production scale. I wanted firsthand time with RSC behaviour, Turbopack's HMR quirks, and the Suspense patterns that are hard to replicate against a version most teams are actually running. The site is small enough that I could absorb the sharp edges without consequences.
Tailwind v4, not v3. Tailwind v4 is a near-complete rewrite, CSS custom
properties instead of generated utility classes, a new configuration model, no
tailwind.config.ts. It's not what your team is running today, but it will be
in 18 months. The mental model shifts enough that I wanted to build with it at
full depth, not dip in on a production codebase where the gap between v3
intuition and v4 reality would be someone else's problem.
Vanilla i18n, no library. English and German from launch, with no
third-party i18n dependency. Two locale dictionaries as TypeScript modules,
one middleware file that reads Accept-Language and redirects. The type
system catches missing translation keys at compile time. Three extra days of
work compared to reaching for a library, but I understand every line of it,
which matters when you're debugging locale negotiation in production and a
library's abstractions are the thing in the way.
An AI playground backed by the same architecture I use at work. The CV chatbot on this site isn't decoration. It's the same pattern I shipped for a natural-language SQL product at work: a grounded system prompt, an explicit refusal policy, prompt caching to hold down token costs, a per-IP rate limiter, and a hard daily budget cap. The playground is the closest thing this site has to showing its working.
What I'm planning to write here
The same things I keep finding myself explaining to engineers I work with:
- How to replatform a public GraphQL API without a cutover, strangler-fig, shadow-diff, schema-drift on two rails, the parts the post-mortem leaves out
- Which AI-augmented delivery bets paid off in production, which I deleted, and what the surviving ones have in common
- The boring technical work behind a p50 latency reduction, the measurements, not the dramatic moments
- What mentoring an engineer to a promotion actually looks like, versus how it tends to get described in a performance review
The aim is not war stories. It's the trade-off reasoning that rarely makes it into a postmortem or a case study but is the part most worth writing down.
RSS feed is live if you'd rather read in your reader.