Personal portfolio of Nicolas Huber — aspiring code alchemist. Turning raw data into elegant, meaningful systems.
Built with Vue 3 + Vite. A single, clean, dark-themed page with a bilingual (EN / DE) toggle. No CSS framework — a small hand-rolled design system instead.
- Vue 3 (
<script setup>SFCs) - Vite for dev server & build
- Vanilla CSS design system (
src/styles/main.css) - Fonts: Space Grotesk + JetBrains Mono (Google Fonts)
npm install
npm run dev # local dev server
npm run build # production build → dist/
npm run preview # preview the production buildAll copy lives in one place: src/data/content.js.
It holds an en and a de object with identical shapes, plus a shared meta
block (name, links, CV paths). Change text there — no need to touch components.
- Add your CV PDFs to
public/cv/(nicolas-huber-cv-en.pdf,nicolas-huber-cv-de.pdf) — paths are configured inmeta.cv. - The language is remembered via
localStorageand reflected in a?lang=URL parameter, so links can deep-link into a language.
src/
├─ data/content.js # all bilingual copy + meta (single source of truth)
├─ composables/
│ ├─ useLang.js # language state, toggle, persistence
│ └─ useReveal.js # scroll-reveal via IntersectionObserver
├─ styles/main.css # design tokens + global styles
├─ components/ # Nav, Hero, Stats, Work, Projects, Publication,
│ # Journey, About, Footer
├─ App.vue
└─ main.js
A GitHub Actions workflow (.github/workflows/deploy.yml) builds and deploys to
GitHub Pages on every push to main.
- Custom domain (e.g.
nicolas-huber.dev): keepbase: '/'invite.config.jsand add aCNAMEfile topublic/. - Project page (
hubernicolas.github.io/portfolio/): build withDEPLOY_BASE=/portfolio/ npm run build(the workflow sets this automatically when no custom domain is used).
GPL-3.0-or-later © Nicolas Huber