← Back

05

Marcus Henri Studio

A design-led second portfolio built under my studio brand, Marcus Henri. One fixed viewport, no scrolling, featuring a raw WebGL noise shader, generative Canvas 2D artwork, and a runtime-switchable background.

Next.jsTypeScriptTailwind 4WebGLCanvas 2DVercel
Marcus Henri Studio screenshot 1
Overview

Marcus Henri Studio is my second portfolio, a design-led, single-page site live at marcushenri.studio. The whole site lives in one fixed viewport box with no scrolling or routing: the name and nav anchor the top-left, content fades between sections in the bottom-right, and the background is rendered by one of two switchable engines: a domain-warped simplex noise shader written in raw WebGL, or a Canvas 2D generative piece that rotates between a recursive tree, a radial burst, and a sine-wave seascape.

The problem

One portfolio can't serve two audiences. This site is deliberately conventional so recruiters scanning dozens of portfolios get their answers in seconds, but for freelance and direct outreach, a conventional layout undersells the craft. I wanted a second surface that demonstrates design and front-end finish by being the demonstration, without compromising the recruiter-friendly one.

My approach

Built with Next.js 16 (App Router, React 19) and TypeScript, styled with Tailwind 4's CSS-first configuration, where design tokens live entirely in globals.css with no tailwind.config file. Typography is self-hosted PP Neue Montreal via next/font/local. The noise background is written against the raw WebGL API, and the geometric background is hand-rolled Canvas 2D. Deployed on Vercel behind a custom domain.

Key decisions

The biggest decision was strategic rather than technical: two portfolios under two brands. This one stays the conventional application URL; the studio site carries the Marcus Henri brand and a 'Designer & Developer' framing aimed at freelance clients. Technically, the key choice was the box-in-viewport layout, where the heading top-left and content bottom-right share one full-viewport space rather than splitting into columns, so the layout survives a 375px phone with no structural media queries. I also chose raw WebGL over three.js, since pulling in a full 3D library for a single fragment shader wasn't worth the dependency.

What I learned

This was my first time writing WebGL by hand: compiling shaders, wiring up uniforms and textures, and re-reading CSS custom properties each frame so the shader tracks the active theme. I also learned Tailwind 4's CSS-first configuration and font self-hosting with next/font/local, plus a lesson in positioning: designing one artefact for one specific audience produces a sharper result than trying to serve everyone with a single site.

PreviousMarcus Henri AINextPoEProfessor