Badge trail
Tiny coloured badges of design terms that slam in behind the pointer and flick away.

npx skills add https://design.how/vault/badge-trailInstalls the template, the brief and a check script as one skill.
What it is
A plain white card. As the pointer moves, tiny badges drop behind it: an uppercase design term in black monospace at 11px on a vivid fill, 1px of vertical and 4px of horizontal padding, a 3px radius. Each lives 830ms. It slams in over 110ms from 5px back along the direction of travel, peaking at 3 percent over full size, holds for 480ms with a sub-pixel wobble and a 1 percent breath, then flicks out over 240ms, shrinking and turning 4 to 9 degrees. Its letters flicker through random characters for the first 130ms and lock left to right.
Badges never overlap. A candidate that would come within 3px of a live badge is skipped for that tick, and a badge drops only when 45ms and 14px have passed since the last, so a still pointer stacks nothing. Each new badge nudges neighbours within 64px up to 3px away; the push eases in and relaxes slowly, so the trail jostles instead of jumping. At most 22 are alive, older ones sit up to 6 percent smaller and 12 percent dimmer, and every fifteenth is an outline in its colour.
The colour walks. A hue advances 24 degrees per badge, so neighbours harmonise, and the pointer's speed sets saturation and lightness: a slow drag lays pale badges, a fast flick lays vivid ones. The words come from a shuffled bag of 24 terms, so none repeats until all have been used.
When nobody is pointing, a ghost cursor takes over 600ms after the pointer leaves, easing in over 420ms onto a broad loop with a faster, off-ratio doodle on each axis, so the card is alive before anyone reaches it. Every length is in design pixels at a 600px card and scales up with a wider one.
How it works
- Keep the badges in a plain array in a requestAnimationFrame loop and hand a copy to the view each frame; draw each as an absolutely placed span.
- Each frame, follow the real pointer, or after GHOST_IDLE_MS the ghost loop blended in from where the pointer left.
- Drop a badge centred on the point only after DROP_MS and MIN_TRAVEL, clamped inside the card, and skip it if its box inflated by GAP hits a live one.
- Colour it from a hue walker, with saturation and lightness from the point's speed, and shove live neighbours by raising a target their offset chases.
- Drive opacity, scale, rotation and offset from the badge's age alone: slam, hold with a wobble, flick out.
- Measure the monospace advance from the live face once, so the overlap test fits any font.
- Under reduced motion, show four still badges centred and never start the loop.
What you can change
WORDS(24 design terms): The vocabulary on the badges, in badges.ts.COLORS(10 vivid fills): The fills for the reduced-motion still, in badges.ts.GROUND(#ffffff): The card colour.FONT_PX(11): The badge text size in design pixels.DROP_MS, MIN_TRAVEL(45, 14): How often and how far apart badges drop.APPEAR_MS, HOLD_MS, FADE_MS(110, 480, 240): The three phases of a badge's life.MAX_LIVE(22): The most badges on the card at once.DESIGN_WIDTH(600): The card width the lengths are tuned at; wider cards scale up.FONT_VAR(--visual-mono): The CSS variable holding the monospace family.