Eddie Jung

How this site was built.

You’re looking at it. Designed and shipped with Claude. Here’s the build, in the order you just experienced it, with each piece shown running.

01

The whole home is one 3D world

There are no sections stacked under a hero. The home is a single WebGL stage: the name EDDIE JUNG sits in soft clay-stone, and scrolling travels the camera through the whole story: an ethos line, the three cases, how I work, the numbers, contact. The name never leaves the frame; it reshapes. As you pass each station the stone letters morph into that station's word: AUTOCRM, PETLOVER, SUBLY, then PROCESS, then a single giant 3 for the three shipped products, taking on that case's colour, so the identity literally becomes the work.

One WebGL stage · scroll travels the camera
02

The name, hand-built in three.js

No 3D-library abstraction. React Three Fiber wouldn't size its canvas in this Next build, so the name is vanilla three.js: I own the sizing, the render loop, the cleanup, and the context-loss recovery. A self-hosted studio environment lights the stone, so nothing is fetched at runtime; letters are tracked apart so the chunky glyphs stay legible. The morph reuses one builder, the same bevelled extrusion re-running for every word, and a segment-based hand-off cross-fades between them so the letters swap cleanly instead of smearing through each other.

Vanilla three.js · soft stone, tracked
03

Every case shows the work

No raw screenshots. Each case rides into the stage with its product framed in a browser mockup, glowing on the dark ground: traffic lights, a URL, a page that looks open right now, and links out to a full case page for the depth. The proof is visible before you read a word.

Live · the actual component
autocrm.app
AutoCRM cockpit inside the browser mockup
04

Dark to enter, warm to read

The stage is a dark, immersive world; the case pages open dark to bridge it, then settle into a warm off-white for comfortable long-form reading. One blue means action, and each case spends a single accent of its own: AutoCRM indigo, Petlover amber, Subly blue. Type carries three roles: the chunky 3D name and Poppins nameplates for the cases, Instrument Serif for headlines, and the system SF stack for body, all self-hosted with next/font, nothing fetched at runtime.

Live · the actual component

Headline 600

PrimarySecondary
glass · chrome only

The invisible part

Then I made it behave.

The chrome name is WebGL, but it stays disciplined: a single draw, a self-hosted studio environment so nothing is fetched, and a proper cleanup on unmount. The abstraction (React Three Fiber) wouldn’t size its canvas in this Next build, so I dropped to vanilla three.js and took control of the sizing, the render loop, and context-loss recovery myself. On a machine without WebGL it falls back to the name in serif, which still reads, and prefers-reduced-motion stops the drift.

The stack

Framework
Next.js 16 · App Router
Language
TypeScript
Styling
Tailwind v4 · CSS-first design tokens
3D
vanilla three.js · clay-stone name, scroll-driven camera
Motion
three.js raf · scroll-linked stations morph the name · CSS keyframes · no motion library
Type
helvetiker (3D name) · Poppins (case nameplates) · Instrument Serif (headlines) · SF (body)
Cases
one data file per case · the renderer never changes

The process

Built with Claude: design and code in one loop.

To be clear, this isn’t an AI-generated template. I’m a product designer: every type choice, grid, and interaction here is a deliberate call, not a default. Claude is the tool that lets me move fast. The design judgment is mine.

I don’t hand a design to engineering and wait. I work in a tight loop: a direction is mocked up on the real page, compared against alternatives, and it doesn’t ship until it survives the screenshot test, the same way every case in this portfolio was made.

That’s the whole pitch: velocity and rigor, together. This site is the proof: designed, built, hardened, and shipped the same way I’d build for a team.