Built with
The tools
Everything below is in the site's package.json or source. Versions are read from package.json at build time.
Foundation
- Next.jsv16.2.4
App Router, server components for metadata and build-time data, route handlers for the APIs.
- Reactv19.2.4
All interactive UI, written as client components where state or motion is needed.
- TypeScriptv5
Strict mode across pages, data files and API routes.
- Zodv4.4.1
Validates every request body the APIs accept.
Styling & type
- Tailwind CSSv4
v4 utilities that only reference CSS custom properties (design tokens) defined in globals.css.
- Open Sans
The only typeface, loaded from Google Fonts in weights 300, 400, 600 and 700.
- Lucidev1.14.0
Line icons, marked aria-hidden when decorative.
Motion & charts
- Framer Motion / Motionv12.38.0
Scroll reveals, the tilt card and small transitions. Kept short and subtle.
- GSAPv3.15.0
The footer's ScrollTrigger animation and magnetic email link.
- Rechartsv3.8.1
The radar chart on the skills page.
State & theming
- Zustandv5.0.12
A tiny store for the active language, remembered only when you choose one explicitly.
- next-themesv0.4.6
Dark by default, light on request or from system preference, via a data-theme attribute.
Services & hosting
- Resendv6.12.4
Delivers messages sent through the contact form.
- Anthropic API
Writes the short pitch in the landing-page recon terminal. The prompt and model are fixed server-side.
- Vercel
Hosting and deployment.
- Vercel Analyticsv2.0.1
Page-view analytics, mounted once in the root layout.
- ESLintv9
eslint-config-next with the Core Web Vitals and TypeScript presets.
Design
Design decisions
Flat tokens
Colours, spacing, radii and motion live as CSS custom properties. No gradients, no glow, 1px borders, and shadows only where something floats (menus, modals).
6px radius cap
Cards and modals stop at 6px, buttons and badges at 4px, tags at 2px. Nothing is pill-shaped by accident.
One teal accent
#4a8f85 in dark mode, #3d7d74 in light. Everything else is a neutral grey scale, so the accent always means something.
Trilingual
Every page ships in English, French and European Portuguese, and the <html lang> attribute follows the choice for screen readers.
Reduced motion
Animations collapse to near-zero duration when the system asks for reduced motion.
Design system
The components and tokens are shown live on the design system page.
Security
Security by default
- Security headers on every response: X-Content-Type-Options, X-Frame-Options DENY, Referrer-Policy, Permissions-Policy and HSTS. The X-Powered-By header is turned off.
- Both API routes are rate limited per IP: the contact form accepts 3 messages per 10 minutes, the recon terminal 5 requests per minute.
- Request bodies are validated with Zod, and user input is HTML-escaped before it goes into an email.
- The AI route only accepts a few short, validated signals, so it cannot be used as a general proxy to the model.
- Pages that are still placeholders are served with X-Robots-Tag: noindex.