Built with
How this site is built
A fully static Next.js 16 export deployed to Cloudflare Pages — no runtime server, content sourced at build time, and motion kept deliberately light. Here is the stack, the open-source projects it stands on, and the effects harvested from them.
The stack
- Next.js 16
- App Router with output: 'export' — fully static, no runtime server.
- React 19 + TypeScript
- Components and strict types end to end.
- Tailwind CSS v4
- Design tokens and utility styling, zero hand-written CSS frameworks.
- Satori + resvg
- Build-time Open Graph image generation per page.
- Notion
- Headless CMS for blog, prompts, and skills — fetched at build, degrades to samples.
- pnpm 10 · Node 22
- Fast, strict installs and the build runtime.
- Cloudflare Pages · Wrangler
- Global edge hosting, deployed from GitHub Actions.
8 open-source projects, credited
Standing on a lot of excellent work. What each one earns its weight for:
- framer-motion ↗The gesture and transition vocabulary that inspired the in-house reveal-on-scroll primitive (kept tiny by not shipping the full lib on every page).
- gsap ↗Timeline-style choreography for the heavier, opt-in hero animations.
- lenis ↗Smooth, inertial scrolling that the scroll-reveal timing is tuned against.
- three.js + @react-three/fiber ↗The lazy-loaded WebGL background, gated behind a capability check so it never costs mobile users.
- @react-three/drei ↗Ready-made R3F helpers (controls, loaders) that keep the 3D scene small.
- embla-carousel ↗The accessible, swipeable carousel powering the case-study galleries.
- cmdk ↗The ⌘K command palette for keyboard-first navigation.
- minisearch ↗Fully client-side fuzzy search over content — no search server required.
Effects harvested
Reimplemented small and on-purpose, so the page weight stays honest.
Reveal-on-scroll
IntersectionObserver + a CSS class toggle. Reduced-motion aware, ~30 lines, no library at runtime.
Count-up metrics
rAF-driven number animation gated on viewport entry, used in the case-study results.
Lazy WebGL background
Loaded only on capable devices (cores, memory, pointer, save-data) and never under reduced motion.
Build-time OG + JSON-LD
Every page ships a generated social image and structured data for clean link previews.