Case study 04Personal2026
mikeyd.xyz — Portfolio
This site: a scroll-driven portfolio where a 3D room rises out of the fog and projects its case studies onto the back wall — built to stay accessible, crawlable and light on the GPU.

The idea
A portfolio that feels like walking into a screening room. As you scroll, a self-lit room tilts up out of the fog and a projector throws each case study onto the back wall; step through them with the arrows, a swipe, or click the screen to open the study.
Before that, a pinned physics section drops the slogan apart letter by letter — then puts it back together if you scroll up.
What I built
- A scroll-scrubbed 3D scene in React Three Fiber, with the room’s rise and the fog both driven by GSAP ScrollTrigger over Lenis smooth scroll
- Projector slides painted to canvas textures with the site’s own fonts, crossfading like a projector changing slides
- One typed content model per case study, rendered on the wall, in a modal and as a static, indexable page
- A scaffolding script and a registry test that catches unregistered files, duplicate slugs, bad colours and missing alt text
- Matter.js physics type that sleeps until it scrolls into view and pauses when the tab is hidden
- Structured data, per-study metadata and a sitemap generated from the same content
Accessible by default
A canvas isn’t a link, so every 3D control has a DOM twin: real buttons for the arrows, a crawlable link for each slide, and a live region that announces slide changes. The case-study modal traps focus, restores it on close and closes on Escape.
Reduced-motion preferences are respected throughout — crossfades become cuts and the hero wave is skipped.
Easy on the GPU
The scene only renders continuously while the room can be on screen; the rest of the time it renders on demand, so scrolling past costs nothing. The room is a single GLB whose baked textures double as emissive maps — no real-time lights required.
By the numbers
- Surfaces from one content model
- 3
- 3D scenes prototyped
- 4
- Components honouring reduced motion
- 14