ATELIER NOIR is one of 25 sites designed and built by Formwork to demonstrate web design, motion and taste. Here is exactly how this one was made — and how you can do the same.
The brief was a high-fashion maison with no photography — a magazine that dresses itself in type and colour instead of images. So the "looks" are duotone gradient plates: each a full-height composition of an oversized Didone title, a line of editorial copy, and its credits. You don't scroll them; you drag them, the way you'd turn the pages of an oversized portfolio laid flat on a table.
The gallery viewport is a native overflow-x:auto container — which is the whole
trick to robustness: if the script never runs, all six looks are still reachable by ordinary
scrolling. JavaScript then enhances that base. A pointer drag writes
scrollLeft directly and records velocity; on release, that velocity decays frame by
frame for inertia. A single requestAnimationFrame loop also offsets each plate's
background and its type by different amounts, so the ground drifts against the title as a plate
crosses the screen.
The detail that makes it feel right is the wheel handler. A vertical wheel becomes a horizontal read — but only until you hit an edge, where the event is handed back to the page so the rest of the site scrolls normally:
vp.addEventListener('wheel', e => {
const max = maxScroll();
const delta = Math.abs(e.deltaY) >= Math.abs(e.deltaX) ? e.deltaY : e.deltaX;
const atStart = vp.scrollLeft <= 0;
const atEnd = vp.scrollLeft >= max - 1;
if ((delta < 0 && atStart) || (delta > 0 && atEnd)) return; // hand back to the page
e.preventDefault();
vp.scrollLeft += delta; // vertical wheel → horizontal read
}, { passive: false });
touch-action:pan-x so a vertical swipe still scrolls the page.prefers-reduced-motion the gallery collapses into a plain vertical stack, the cursor and parallax switch off, and every reveal is forced visible..loaded class added on a double rAF, with a 400ms failsafe.Every site here is static, so hosting is three commands:
git init -b main && git add -A && git commit -m "ship"
gh repo create formwork-atelier --public --source=. --push
gh api --method POST /repos/OWNER/formwork-atelier/pages \
-f 'source[branch]=main' -f 'source[path]=/'
Use relative paths (./main.js, not /main.js) because project
Pages live under /repo-name/. Add an empty .nojekyll file so every asset serves verbatim.
That's the whole recipe: one native scroll container, a little velocity maths, strong type and static hosting. The other 24 sites each swap the central technique — shaders, particles, kinetic type, isometric 3D — but the discipline is the same.