All projects

Work · 2026

This portfolio

Successor to a 33,000-line PHP application, now static, bilingual and without a database.

Live

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.