Typer
A line that types itself in, each letter flickering through pills and highlights before it lands.

npx skills add https://design.how/vault/typerInstalls the template, the brief and a check script as one skill.
What it is
One line of semibold text sits in the middle of a coloured card. It types itself in: a wave runs across the line, and as it passes each letter, the letter rolls through three random states, a solid pill, an inverse block, a coloured accent, an accent pill or an outlined pill, before it lands on the plain letter. Every 1.8 seconds the card switches to another of thirteen looks, each its own palette, state pool and timing, and types the line in again.
The engine wraps each character in a span and runs a frame loop at the look's rate, 20 frames a second by default, for about a second plus one percent per letter. Progress is normalised across the line, and each character gets its own control point on a bezier, so the wave of state changes ripples instead of marching. Once the wave has passed a character it spends the first half of the remaining frames rolling through its states and the rest settled, and its progress is quantised so a glyph holds each state for a beat instead of flickering every frame.
All of the look is CSS. A state is a class, and the classes paint the pill, the inverse, the accent and the outline from four custom properties: the ink, the knockout inside a filled pill, the accent surface and the text on an accent. The merging is pure selectors: a filled character followed by another loses its right-hand radius, one preceded by another loses both, and the last of a run gets its right corners back, so a run reads as one rounded bar. The outlined pill drops the inner borders the same way.
How it works
- Split the line into words and characters, one span each, inside a [data-typer] element, and start it at opacity 0.
- Run a setInterval at fps for fps times (1 + 0.01 times the letter count) frames, and per frame give each character a class from its progress against its own bezier control point.
- For a character the wave has passed, pick cycles random states from the pool, quantised so each holds for a beat, then settle to plain text.
- Paint each state in CSS from --typer-fg, --typer-bg, --typer-accent and --typer-accent-ink, and merge runs with :has(+ .state) and .state + .state radius rules.
- Cascade several lines with a per-line delay of STAGGER seconds.
- Under reduced motion, build the line visible and never start the loop.
What you can change
LINES(["design engineered by hand :)"]): The text, one entry per line.PRESETS(13 looks): Each look's four colours, state pool, frame rate and number of states, in presets.ts.REPLAY_MS(1800): How long each look holds before the next types in.STAGGER(0.15): Seconds between lines starting.SIZE_CQW, SIZE_MIN(5.8, 16): The type size as a share of the card width, and its floor in px.FONT_VAR(--visual-sans): The CSS variable holding the family.