My personal website (profile, projects, resume, and an Impressum page).
- Frontend: React + Vite
- Routing: React Router (a small SPA with a few routes)
- Styling: hand-written CSS (
src/styles.css) using CSS custom properties and adata-themeattribute onindex.html - Icons:
react-icons - Content: mostly plain React components; the resume is driven by
src/data/timeline.js
src/main.jsxrenders<App />;src/App.jsxdefines the client-side routes and wraps everything insrc/components/Layout.jsx.src/components/Layout.jsxkeeps navigation and social links as simple arrays and maps them toNavLink/<a>elements.src/pages/Home.jsximplements the hero "typed command" effect with a smalluseEffect-driven timer (typing, then hiding the prompt).src/pages/Resume.jsxrenders the timeline by mappingtimelineItems; each item sets a CSS variable (--delay) for a staggered reveal animation.
index.html: HTML shell (loads the font, sets the initial theme, mounts#root)src/main.jsx: React entry point (renders<App />and imports global styles)src/App.jsx: route table (/,/projects,/resume,/impressum)src/components/Layout.jsx: shared page chrome (nav + footer +<Outlet />)src/pages/*: page componentssrc/data/timeline.js: resume timeline datasrc/assets/*andpublic/*: images and static assets (e.g.favicon.ico)
This repo also keeps the hosting setup I use for the site:
Dockerfile: builds the Vite app and serves it via Vite's preview serverdocker-compose.yml: wires the app container to Caddy (plus Watchtower)Caddyfile: reverse-proxy + compression + a small set of security headers