Colophon

This website was designed and developed from scratch. It serves as both a portfolio and an ongoing experiment in frontend engineering, interaction design, and systems thinking.

Architecture

Built on Next.js with the App Router. Every route is statically prerendered at build time, but most of the interface is client-rendered rather than server-rendered: the cursor, the scroll choreography and both particle fields all need the browser to exist.

Design & Styling

The interface is built using a hybrid approach of Vanilla CSS via custom variables and strict utility classes from Tailwind CSS. This allows for rigorous control over design tokens while retaining the speed of utility composition.

Typography is set entirely in Geist Sans and Geist Mono, an excellent typeface family engineered for high-density interfaces and code by Vercel.

Interactions

Fluid animations are powered by Framer Motion. The cursor is a hyper-minimal 5px dot with mix-blend-mode: difference, which inverts against any background, staying legible on dark or light sections without visual overhead. Position tracking uses raw DOM events mixed with React context at 60fps; the dot scales to 8px on hover via a 150ms spring.

WebGL & Physics

The two interactive particle fields are built on React Three Fiber and Three.js. Both use custom GLSL ShaderMaterials with a Gaussian falloff fragment (exp(−d²×9)) and THREE.AdditiveBlending so overlapping particles accumulate into luminous glowing pools rather than opaque masses.

Particle kinematics use an under-damped spring (stiffness=0.028, damping=0.91, ratio≈0.27) for organic overshoot and ring-down wobble. Mouse interaction applies a tangential force perpendicular to the particle→cursor vector, scaled by cursor velocity: a silk-vortex swirl rather than a rigid repulsion void.

The 5,000-particle silhouette uses area-weighted generation (r = R·√u) across four layered populations: disc haze, Fibonacci/Fermat spiral arms, sinuous filaments, and sparse cosmic dust. A per-particle aSize attribute creates a 70/30 grain-to-node size split, placing large particles precisely on dense strand intersections for maximum additive glow.

Source

I believe in learning through shared code. If you're curious about how specific components or animations were built, the full source code for this website is on GitHub.