Studio Grotesk
← studiogrotesk site

The guide

How this page was designed and built — the concept, the system, and the code behind the poster wall. Written so you can reproduce the method, not just the look.

1 — Concept & art direction

Studio Grotesk is a fictional Zürich studio that designs only identity systems, for a design-literate audience. The page has one job: prove typographic mastery in a single scroll. So there are no photographs anywhere — the typography is the imagery, and the portfolio is literally a program: generative Swiss posters composed live in canvas.

The direction is Müller-Brockmann by way of the browser: a visible 12-column grid (press G on the home page), an 8 px baseline everything sits on, one grotesk family at exactly twelve sizes, and a single engineered red that has to be earned by spacing rather than decoration.

2 — Palette & type

Paper#FFFFFF
Ink#0E0E0E
Engineered red#E63312

Three colours, and the red is rationed: one dot, one full stop, one section, one accent per poster. #E63312 is the warm signal-red of Swiss rail and wayfinding — hotter than terracotta, calmer than vermilion neon.

Archivo

900 / width 112% — display & masthead

Archivo, the same file, at text sizes: a workhorse grotesk with a large x-height and real variable width and weight axes.

400–600 / width 100% — body & annotations

There is deliberately no pairing. One variable family carries all twelve sizes — the constraint the fictional studio sells is the constraint the page obeys. The twelve-step scale (11 → 240 px) is defined once as CSS custom properties and displayed as a specimen in "The scale."

3 — Techniques: the poster wall

Each poster is a DOM element with a canvas, drawn at A-series proportions (297 × 420 units) from a seeded random generator, so a given seed always reproduces the same poster. A seed picks a background (paper / ink / red), one of six layout archetypes — giant cropped glyph, diagonal word ladder, stacked words, concrete circle, timetable bars, type grid — then sets everything in Archivo from the same word list the studio would use.

// deterministic randomness: one seed, one poster, forever function mulberry32(a){ /* tiny seeded PRNG */ } var rnd = mulberry32(seed); var bg = r < .55 ? PAPER : r < .85 ? INK : RED; var layout = Math.floor(rnd() * 6); // six house archetypes

Dragging uses Pointer Events with capture; velocity is sampled between moves, and on release a requestAnimationFrame loop applies inertia with friction (×0.94 per frame) and a soft bounce off the stage walls:

p.x += p.vx; p.y += p.vy; p.vx *= 0.94; p.vy *= 0.94; // friction if (p.x < 0){ p.x = 0; p.vx *= -0.5; } // wall bounce

The grid overlay is two layers of pure CSS — a repeating-linear-gradient for the 8 px baseline and a 12-column CSS grid of tinted columns — toggled by a body class on G. Under prefers-reduced-motion, posters render in a calm ordered grid with no inertia, no rotation and no entrance animation.

4 — The three passes

  1. Pass 1 — correctness & composition. The first scatter clumped posters to the left and left dead space, so it became a shuffled-cell distribution (more cells than posters, Fisher–Yates, clamped 16 px from every edge). Fixed the mobile type-scale specimen truncating mid-word — samples below size 08 now wrap — and restored the lost line breaks in this page's code blocks.
  2. Pass 2 — elevate. Gave the drag real paper behaviour: posters lean up to 9° into the push velocity and settle flat on release. Added the variable-width micro-interaction on the scale ladder (hover a rung and Archivo stretches 100 → 125%), a hover lift shadow on posters, and randomised stacking order so the collage has depth.
  3. Pass 3 — taste. Chanel rule: a scroll-reveal on section titles was built in pass 2 and deleted — the grid does not need to fade in to be believed. Retuned the mobile thesis to clamp(40px, 13vw, 60px) so the three lines break exactly as written, and re-verified 390 px and the reduced-motion state (ordered wall, no inertia, no rotation).

5 — Do this yourself

  1. Give Claude a thesis, not a page list: "a studio whose portfolio is a program — typography is the only imagery." One sentence of intent beats ten of features.
  2. Fix the constraints first and make them checkable: one family, an explicit size ladder, a baseline unit, a 3-colour palette with hex values. Put them in CSS custom properties so drift is impossible.
  3. Pick ONE signature element and ask for it as a mechanism ("seeded canvas posters, six layout archetypes, drag with inertia"), so the code has rules instead of vibes.
  4. Make the system visible: ask for a grid-overlay toggle. If the overlay embarrasses the layout, the layout is wrong — it is a debugging tool for taste.
  5. Demand real copy in the brand's voice before styling. Placeholder text hides bad hierarchy; specific sentences expose it.
  6. Iterate with screenshots, three times minimum: correctness, then elevation, then subtraction. Tell Claude to critique the screenshot before touching code.
  7. Test 390 px and reduced-motion as design states of their own, not as things that merely shouldn't break.
  8. End by removing one thing you like. If the page survives, ship it.