Legacy

The colophon, expanded

How this site was made

Everything you just scrolled — the direction, the type, the palette, the 3D, the photograph, the voice, the deploy — was designed and built by Claude (Fable 5) in a single working session, from one written brief. This page is the recipe, so you can do the same.

The brief

The owner of this domain asked for a launch site for Legacy, an iPhone app for recording a loved one’s life story — and for the site itself to be a demonstration of what a frontier model can do with total creative freedom: “high-quality 3D tactics, otherworldly animations, exceptional color, novel type.” The model had access to a terminal, a browser for screenshots, an image/video generation service, a local text-to-speech server, GitHub, and Cloudflare. No human touched a file.

1 · Pick one idea and commit

Generic AI sites happen when nobody decides anything. So the first artifact wasn’t code — it was a sentence:

“The Grooves of a Life: a cinematic descent from parchment daylight into a candlelit family archive, built on concentric rings — tree rings, record grooves, sound waves.”

Every later decision — palette, particle motion, even the pricing section’s tone — had to serve that sentence or get cut. When you replicate this, spend real effort here. One committed idea beats ten tasteful defaults.

2 · A palette with a temperature, not a hue wheel

The site lives between two worlds: parchment (the present) and a warm near-black archive (memory). Both are tinted toward the same amber hue so the dissolve between them feels like dusk, not a theme toggle. Tokens are defined in oklch() so lightness steps are perceptually even — and contrast stays verifiable.

3 · Type that could not be Inter

Your voice is the heirloom.

Fraunces is a variable “wonky old-style” serif: at display sizes its optical-size axis sharpens the contrast, and its hidden WONK axis swaps in crooked, hand-set letterforms — used sparingly on emotional words. Body text is Newsreader, drawn for on-screen editorial reading. Both are self-hosted as variable woff2 files — four files, every weight and italic, zero layout shift.

4 · The 3D: 2,400 particles, zero libraries

The animated field behind every section is one <canvas> and ~150 lines of hand-rolled math. Particles live in polar coordinates; each “scene” is a small function that maps a particle to a 3D point. The page’s scroll position blends between scenes, then a shared projection applies pointer-parallax rotation and a perspective divide:

// rotate about Y by pointer, then perspective-project
const xr =  x * cosY + z * sinY;
const zr = -x * sinY + z * cosY;
const s  = f / (f + zr);            // perspective divide
px = cx + xr * R * s;
py = cy + y  * R * s;

Six scenes reuse the same particles: a leaning disc (a record on a turntable), a sagging thread, speaking rings, a live waveform, eight chapter arcs, and rising embers. Because the particles never die — they only re-map — transitions read as one continuous material. That’s the “motion dissolve”: geometry dissolves, the medium persists.

5 · The waveform is real

Press play in the listening room and the Web Audio API drives both the bar waveform and the background particles: an AnalyserNode samples the actual audio to 48 log-spaced bins each frame.

const src = actx.createMediaElementSource(audio);
analyser = actx.createAnalyser();
analyser.fftSize = 256;
src.connect(analyser);
analyser.connect(actx.destination);
// each frame: getByteFrequencyData → 48 bins → canvas + particles

6 · The photograph that breathes

“Henry” does not exist. His portrait was generated with Higgsfield’s Soul model (prompted as a 1958 silver-gelatin print, complete with scuffed edges), padded onto a black mat, then handed to Kling 3.0 with a cinemagraph prompt: hold almost perfectly still; blink once; let the light shift; keep the print border frozen. The 5-second loop only loads when you scroll near it, and never plays for visitors who prefer reduced motion.

7 · The voice

Henry’s answer was synthesized with a small local text-to-speech server (kyutai’s pocket-tts) and converted to AAC with macOS’s built-in afconvert — no cloud audio API involved. The transcript brightens word by word, timed against playback.

8 · Restraint is a feature

9 · Three iteration passes

After the first complete build, the model audited its own work three times with a headless browser — screenshotting desktop and mobile at every section, then fixing what it saw: spacing rhythm, contrast failures, orphaned lines, scenes that blended too early. Budget as much time for looking as for building. The gap between “generated” and “designed” is exactly this step.

10 · Ship it

# repo
git init && git add -A && git commit -m "Legacy launch site"
gh repo create legacyrecording-site --public --source=. --push

# deploy (Cloudflare Pages)
npx wrangler pages project create legacyrecording
npx wrangler pages deploy . --project-name=legacyrecording --branch=main
# then attach the custom domain in one API call

Do it yourself

  1. Write a brief with stakes: audience, tone, and “make it unforgettable.” Grant real creative freedom — and real tools.
  2. Demand a named design direction in one sentence before any code.
  3. Have the model generate its own assets: imagery, motion, voice. Everything custom, nothing stock.
  4. Insist on hand-rolled motion over library defaults — that’s where the signature lives.
  5. Require iteration passes with screenshots. Three, minimum.
  6. Let it deploy: GitHub → Cloudflare Pages → custom domain.

Built with Claude Code. Directed by one prompt. Return to the site ↩