THE AWARD is one of 25 sites designed and built by Formwork to show what web craft looks like when it takes itself seriously. Here is exactly how this one was made.
Most "manifesto" pages are a stack of centered paragraphs. We wanted the opposite — a cinematic title sequence you scroll through, where five statements about craft slide past the frame like acts in a film. The page reads its own argument out loud: the prize was never the point, the work is. Editorial serif, a single vermilion, near-black grain — filmic on purpose.
#0a0a0a, bone #f2ede2, one vermilion #ff3b1d.main.The whole page pivots on one move: pin the acts section, then translate a horizontal
track as the reader scrolls vertically. A single scrubbed tween drives everything, and each
act's headline is wiped in with a clip-path as it crosses the frame — using that same
tween as its containerAnimation, so the reveal is locked to horizontal position, not scroll.
const horiz = gsap.to(track, {
x: () => -(track.scrollWidth - innerWidth), ease: 'none',
scrollTrigger: {
trigger: acts, start: 'top top', pin: true, scrub: 0.6,
end: () => '+=' + (track.scrollWidth - innerWidth),
onUpdate: self => { // progress bar + act counter
fill.style.transform = `scaleX(${self.progress})`;
curEl.textContent = ROMAN[Math.round(self.progress * (n - 1))];
}
}
});
gsap.fromTo(statement, { clipPath: 'inset(0 0 100% 0)' },
{ clipPath: 'inset(0 0 0% 0)', ease: 'none',
scrollTrigger: { trigger: panel, containerAnimation: horiz,
start: 'left 82%', end: 'left 34%', scrub: true } });
A thin progress bar and a roman-numeral counter are updated in the tween's onUpdate.
The marquee band is skewed live by scroll velocity — the classic
getVelocity() trick, applied to an outer wrapper so it never fights the CSS marquee
animation underneath.
prefers-reduced-motion forces all content visible,
kills the pin, the marquee, and the grain, and leaves the acts stacked vertically..loaded class on a double
requestAnimationFrame plus a 400ms failsafe, so it is never stuck blank.opsz axis is pinned to 144 on the giant
statements for razor-thin display contrast, and left automatic elsewhere.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-award --public --source=. --push
gh api --method POST /repos/OWNER/formwork-award/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 recipe: one pinned tween, five acts, a velocity-skewed marquee, and static hosting. The other 24 sites each swap the central technique, but the discipline is the same.