ML← Back to the site

Colophon

How it's made

A portfolio that is also a working sample: a talking avatar, a memory you can ask, and the engineering that keeps it light.

The avatar

Model
An Avaturn scan of me, rigged, with the collar and sleeves cleaned up by a one-time bake. Its geometry and face shapes are compressed with meshoptimizer, 5.8 MB down to 3.1 MB; browsers without WebAssembly get the plain file.
Voice
OpenAI Realtime over WebRTC. The server mints a short-lived key per conversation, so the real key never reaches the browser. The avatar can scroll the page and play a gesture when you ask.
Life
An idle loop with the head and eyes following your pointer on top of it, nine Mixamo moves retargeted onto my own skeleton, and a nod while it speaks. While it talks, the giant name behind it pulses with its voice.
The world
Play / explore opens a small 3D campus in the same canvas: Rapier physics, a follow camera, and the same avatar handed over from the hero pose without a cut.

Agent memory

Particles
16,000 points sampled on the avatar's surface in four poses, baked offline from the rig and stored one byte per axis: 192 KB. They take the avatar apart as you leave the hero, become a memory core, spell each project's name and come back together at the end to wave.
Cost
One draw call, shapes morphed on the GPU, a few rectangles read per frame. The layer loads after the page is idle, draws nothing while the hero is at rest, pauses with the tab and is skipped with reduced motion.
Ask my memory
The site's own content cut into short passages. Your question is embedded (text-embedding-3-small), ranked by cosine similarity, and a short answer is written from the top four passages only (gpt-4o-mini). Without the server it falls back to BM25 keyword ranking in your browser.

The rest

Stack
Next.js 14 App Router, React 18, TypeScript, Tailwind CSS, Framer Motion, Lenis, React Three Fiber and three.js.
Pages
Case studies are static pages, and moving to one never reloads the site: a client-side navigation inside a view transition morphs the card's title and screenshot into the page, and the way back keeps the home page's 3D in memory.
Quality
Around 1,400 Vitest tests, from the particle choreography and the retrieval handler to the game's physics, plus Playwright screenshots at desktop and phone widths for every change. The avatar is a still image in the first paint and the live one dissolves in over it; on a machine that draws WebGL without a GPU it wakes only when you reach for it, and then draws only when something changes.
Access
Reduced motion turns off the film, the particles, smooth scrolling and the hover effects. Everything works by keyboard, the hero controls are inert under the film, screenshots have alt text and the 3D hero has a label.
Type
Space Grotesk, a variable font whose weight follows your pointer, and JetBrains Mono. Ink and ember: near-black, cream and one orange.
Credits
Avatar by Avaturn, moves from Adobe Mixamo, fonts by Florian Karsten and JetBrains (both SIL Open Font License). Design, code and words by me.