Work · 2026
This portfolio
Successor to a 33,000-line PHP application, now static, bilingual and without a database.
At a glance
- No backend, database or login, served entirely as static files
- Content as Markdown, checked by a Zod schema at build time
- Bilingual DE/EN, with German unprefixed at the root
- Interactive parts in vanilla TypeScript rather than a UI framework
Why rebuild
The previous version was a custom PHP MVC framework with eleven controllers, eight models and thirteen database tables. It handled user accounts with TOTP and passkeys, a ticketing system with an AI chatbot, four games with OpenAI opponents, and an EV charging calculator.
That left little room for what the site was actually for: showing projects. The portfolio was three of those pages, and the content lived in a MySQL table, so outside git and without any version history.
What is left
Authentication, tickets, games, calculators, the database and the server code are all gone.
What remains is a static site on the same Apache host as before, just as a dist/ folder
rather than a front controller.
Project content lives as Markdown in the repository, and a Zod schema in content.config.ts
checks every field at build time. A missing year, a malformed URL or a project that exists in
only one language fails npm run build before any of it goes live.
Why no CMS
An admin area would have meant a server, sessions and password handling again, which is exactly what the rebuild was meant to remove. A new project is one file per language and one commit instead. Rollback, diff and history come from git.
Frontend
The interactive parts are a few small TypeScript islands: filter and search on the project list, the command palette, the theme switch, and a spotlight effect that follows the pointer. That is too little to justify a UI framework. Without JavaScript the list simply stays unfiltered.
The three colour schemes from the old site are still there: noir by default, light and sakura
as alternatives. Every animation sits behind prefers-reduced-motion.