BUILD NOTES · 02 / 25
HOW IT'S MADE.
GROTESK™ is a specimen site for a foundry that treats letters like structural steel. Everything on it is hand-rolled: no animation libraries, no physics libraries, no images. Three colors, two families, one variable font under stress.
01 — THE WARP
DRAG A HEADLINE, BEND AN AXIS
The headline is set in Anybody, a variable font served by the Google Fonts css2 API with two exposed axes. Dragging maps the pointer straight onto them: vertical position drives wght (100–900), horizontal drives wdth (50–150), written per letter through font-variation-settings every frame.
The trick that makes it feel physical is a Gaussian falloff field: each letter's pull toward the pointer target is scaled by exp(−dx²) of its distance from the cursor, so weight piles up under your hand and decays across the word. Each axis on each letter runs through a hand-rolled damped spring (semi-implicit Euler: accelerate toward target, bleed velocity, integrate), so releasing a drag wobbles once and settles. Idle, the springs chase a slow sine wave — the word breathes so a screen recording is never static. Pointer Events plus setPointerCapture make the same gesture work with mouse and thumb.
02 — THE MOTION SYSTEM
EASE ONLY ON ARRIVAL
Brutalism here means motion is either a slam or a snap. Entrances use one steep curve, cubic-bezier(.05,.92,.1,1) — fast in, dead stop — staggered per letter and per block via IntersectionObserver. The red load wipe collapses in four hard jumps using steps(4, end). Hover states in the A–Z grid have transition: none on purpose: the invert must hit like a switch, and each entry re-rolls random axis values so no two hovers match.
The glyph marquee runs in the same single requestAnimationFrame loop as the warp. Scroll velocity is measured per frame, smoothed, and fed into a skewX transform — scroll hard and the strip leans like it took a hit. The loop pauses on document.hidden, and prefers-reduced-motion swaps all of it for a static, fully legible page.
03 — THE PASSES
BUILT IN LAYERS, LIKE A SLAB
Pass one poured the structure: palette, 8px borders, block underlines, the warp engine, marquee, specimen grid, waterfall, license table, cropped footer wordmark. Pass two pushed the motion — the idle wave was widened to sweep the full published 100–900 / 50–150 range instead of idling near the middle, hard-snap invert reached the pricing cards, and the crosshair cursor learned to relabel itself per zone: DRAG, INVERT, SCAN. Pass three was the tightening pass — contrast checked, license buttons given distinct names for screen readers, a mobile headline that was silently clipping off-screen fixed at the root (a grid item's min-width: auto, not just its font-size), and a stray per-frame layout read cut from the idle loop. Screenshot audits ran at 1440×900 and 390×844 throughout — critiquing renders, not intent. Nothing decorative was added at any point. That was the point.