Personal portfolio and resume — built as a premium PWA
- Dark / Light theme with smooth transitions (next-themes)
- Internationalization — English & French with localStorage persistence
- PWA — installable on mobile with offline support
- Print-friendly CV — dedicated
/cvpage optimized for print - CSS animations — smooth micro-interactions and page transitions
- WCAG 2.1 AA compliant — accessible by design
- SEO optimized — dynamic sitemap, meta tags, structured data
- Responsive — mobile-first design
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, React 19) |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS v4 + CSS variables (OKLCH) |
| Components | shadcn/ui + Radix UI |
| Animations | CSS transitions + keyframes |
| Icons | Lucide React |
| Theme | next-themes |
| PWA | @ducanh2912/next-pwa |
| Testing | Vitest + Testing Library |
| Font | Inter (Google Fonts) |
app/
├── layout.tsx # Root layout with providers
├── page.tsx # Home — Hero, About, Skills, Experience
├── cv/page.tsx # Resume — print-optimized
├── projects/page.tsx # Projects showcase
├── contact/page.tsx # Contact form
├── globals.css # Theme tokens (OKLCH, CSS variables)
└── sitemap.ts # Dynamic sitemap
components/
├── ui/ # Design system (shadcn/ui)
├── layout/ # Header, Footer, PageContainer
└── sections/ # Hero, About, Skills, Experience, etc.
lib/
├── utils.ts # cn() utility
├── i18n.tsx # i18n hook and provider
└── constants.ts # Site data (experience, projects, skills)
content/
├── en.json # English translations
└── fr.json # French translations
This portfolio showcases ClairLab, a Turborepo monorepo powering 2 financial simulator apps:
| App | Description | URL |
|---|---|---|
| SalaireClair | Gross-to-net salary simulator (FR, BE, CH, LU) | salaireclair.fr |
| PrêtClair | Mortgage loan simulator (FR) | pretclair.fr |
Highlights: 47 shared UI components, 249 unit tests, Lighthouse 100/100/100/100, 63 SEO blog articles, 120+ PRs, automated SEO monitoring (GSC + Umami → Slack).
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Run tests
pnpm test
# Type check
pnpm type-check
# Production build
pnpm buildOpen http://localhost:3000 to view the site.
content/en.json/content/fr.json— translationslib/constants.ts— skills, experience, projects, education, contact info
Color palette defined in app/globals.css using CSS custom properties (OKLCH). Dark mode handled via .dark class.
Update public/manifest.json for PWA settings. Icons in public/icons/.
Push to a Git repository connected to Vercel for automatic deployments.
MIT