System · v2.0
The rules behind litt.design, this gallery and the player that runs it. Tokens live in src/design-system/tokens.css, primitives in src/design-system/primitives, the reasoning in DESIGN.md.
Principles
1An object, not a page
The home page is a player you could hold: a body in a machined frame, wells pressed into it, keys that sink 2px. A study is a part of the same instrument, never a card on a screen.
2An instrument's vocabulary
Takes, the tape, transport, slate, detents, scenes. Name things the way a field recorder would, and the interface explains itself.
3It runs by itself, and rewards the hand
Everything moves in its first four seconds, untouched: a rehearsal, a recall, a ghost typing. A hand takes over at once, and the motor lets go.
4It makes sound
Every press clicks, synthesized as it plays. What a study does by itself follows the player's tape; what the viewer does always sounds.
5Restraint, used as a signal
Monochrome, plus red for REC and the playhead, orange for HOLD and one blue on the screen. Figures are tabular. The work is the loudest thing here.
6Physics carry the feel
Springs that keep their velocity, motors against hands, detents, over-centre snaps, tape that winds by the square root and needles with VU ballistics. Where a mechanism exists, model it.
7Accessibility is native
Real roles and ARIA patterns, one tab stop per composite, focus that follows the hand, changes said in live regions. Reduced motion stops anything that loops by itself.
8Product patterns, with the player's polish
A study is something teams ship: a command menu, a 2FA field, a toast. The hardware is the polish; the pattern is the subject. The craft speaks for itself, with no explanatory chrome.
Colour
- Page ground
- Recessed areas, stages, code
- Raised objects: cards, menus, toasts
- Primary text and solid buttons
- Secondary text, meta, icons
- Decoration and disabled only
- Hairline borders and dividers
- Hover borders, inputs
- Blue fill: status dots, highlights
- Text on accent fills
- Accent as text or stroke
- Destructive and negative values
Signals
Colour is never decoration. Each of these means one thing, and a light that glows is a signal; a lit segment is not.
Type
Page titles, rarely
Component and section titles
Intro paragraphs
Default text
Dates, labels, captions
- Figures that change are tabular (
tabular-nums), on the screen and on the hardware, so a count never shuffles sideways. - The hardware has its own lettering, sized in em from its plate: engraved captions at 0.6em, semibold, capitals tracked 0.16em; key lettering at 0.8em, medium, tracked 0.03em; LCD figures in light (300) at −0.03em. See Materials.
Shape
On the hardware, radii are in em and nest: a plate at 1.25em, a well at 1.05em, a key or an LCD at 0.7em, the chip at 0.4em. Elevation is light, not drop: a lit top edge, a recess for anything pressed in, a 2px base under every key.
Materials
00M14S06F
take_04.wav

- Off
- On
- Rec
- Hold
Hold to erase1 kHz · reads 0 VU
Lettering · label, quiet- Plate
- The body's bead-blasted finish: a lit top edge, soft-light noise over a vertical gradient. Every study sits on one.
- Frame
- The player's machined frame: a band a shade darker than the body (lighter, in dark), lit along its top edge.
- Bezel
- Black, round LCD cells, dot-matrix strips and a second screen, its polished edge catching the light.
- Well
- Anything pressed into the plate: the readout, the key row, a fader's slot, a collar.
- Key
- A raised key on a 2px base it sinks onto. Both shadows keep the same five layers, so they interpolate.
- Cap
- Round caps and the dial: lit from above, seated in a collar cut from the well.
- LCD
- Black glass with a diagonal sheen. Light figures, a white chip for the state, dim units.
- Window
- Smoked glass set deeper than the LCD: the maker's window, the reels, a fine grille behind it.
- Lights
- Monochrome when lit, red for REC and the playhead, orange for a hand on it. Signal colours glow; meter segments don't.
- Lettering
- Tiny tracked capitals printed on the body, with a 1px highlight on the side away from the light.
- Glass
- Over a screen: a sheen where the light catches it, and the backlight's bloom as it wakes.
- Drawing
- A study taken apart, drawn: hairlines and lettering over the canvas, the picked layer in the hand's orange.
- Plate, then well, then part: wells are pressed into the plate; keys, LCDs and collars sit in wells; caps sit in collars. Grain goes on the plate only, as
.device-grainat--device-grain(0.3). - Size it all in em from one font size on the plate, so the object scales as one piece. Keys sink 2px onto their base in 75ms and come back at
--duration-exit. - The LCD carries a white chip with a glyph for its state (a red dot that pulses for play), light figures and dim units. Signal lights glow with a shadow in their own colour; unlit ones are
--device-meter-off.
<div className="@container w-full max-w-[360px]">
<div className="relative isolate overflow-hidden rounded-[1.25em] p-[0.9em]
text-[clamp(11px,4cqw,14px)] [background:var(--device-body)]
shadow-[var(--device-body-edge),0_1px_2px_rgb(0_0_0/0.06),0_16px_32px_-18px_rgb(0_0_0/0.3)]">
<div aria-hidden className="device-grain pointer-events-none absolute inset-0 -z-10 rounded-[inherit]" />
<div className="rounded-[1.05em] bg-(--device-well) p-[0.45em] shadow-(--device-recess)">…</div>
</div>
</div>Motion
Springs
Use a spring when motion follows the pointer or can be interrupted: magnetic elements, indicators, anything dragged. Values go straight to the DOM through createSpring, so nothing re-renders.
Physics
Where a study stands in for a mechanism, it models the mechanism: a small integrator or a spring with real numbers, not a duration and a curve.
Motor and hand
Values set from outside travel on a spring (the Knob on springs.gentle in degrees, the Fader on k 240 · c 30 in permille); the hand's land at once. A hand on the cap stops the motor; let go, and it takes the cap to wherever the value moved on to.
Detents
A click for every detent the spring passes, pitched with the value. The dial clicks every 15°, a reel every 30°. The Fader's unity detent catches within 1.2% of the range and lets go 3.5% clear.
Over-centre
The cap lags the finger toward the centre (3% breakout, the snap at 72% of finger travel), then a spring of 40 preload plus 260 at its peak throws it to a hard stop (k 16000). Release projects the cap 150 ms ahead at the finger's speed: a flick decides by velocity.
Tape
A pack's radius grows with the square root of the tape on it, and each reel's angle comes out in closed form, θ = 2(r − r_hub) / k. Progress eases in on k 140 · c 24, critically damped: the reels have mass.
VU ballistics
99% of a steady tone in about 300 ms with about 1.5% overshoot (k 166 · c 20.2). The peak light holds 600 ms past +3 VU. 0 VU is the slate tone, as measured leaving the bus.
Counter drums
Each drum turns on its own spring (k 150 · c 21) and clicks for every figure that passes. Counting up, drums carry forward through 9 to 0, 45 ms apart from the right.
- Stagger siblings that enter together by
--stagger(50ms), capped at 8, so a long list never waits on its last item. Motors that move one after another wait longer: 120ms between a desk's knobs. - Agent states:
animate-shimmerfor a working label,animate-waveandanimate-hopfor pixels and dots,animate-caretwhile text streams. Announce phases to screen readers, not tokens. - Agent shapes:
animate-stretchfor rays,animate-traceto run a dash along a path (setpathLength={1}),animate-morphfor a form changing shape,animate-assemblefor tiles folding out along--fx/--fy,animate-twistto turn a layer a quarter at a time, andanimate-build, which runs a shared--buildvalue from 0 to 1 and back for children to read. Offset siblings with negative delays so a loop never starts at rest. - Press feedback: hardware keys sink 2px in 75ms; flat controls take
active:scale-[0.97]. - Hover in at enter speed, out at exit speed, so the UI never lags behind the pointer.
- Never animate from
scale(0). Start at 0.95 or more with opacity. - Respect reduced motion: transitions collapse to instant, motors jump, rehearsals don't start, autoplay media shows a still.
Primitives
<Button variant="primary"><IconButton label="Search"><Badge variant="accent"><Kbd>⌘</Kbd>Sound
- Fire and forget:
play("select")from@/lib/sound. It never throws, and stays silent until the first press or key. - Keys sound by themselves:
ButtonandButtonLinkpress and release, ghost buttons tick. Opt out withdata-sound="off". - Quiet and dry: one bus at a conservative level (peaks near -18 dBFS), a faint room and a compressor; 2.5 dB lower on touch screens; never more than eight voices at once. Volume moves the bus in 2 dB steps around 7, the level every sound was tuned at.
- In time: sequencers pass
{ delay }to schedule a note up to 0.5 s ahead on the audio clock. The rate limit counts when a sound will be heard, and scheduled notes never take the last two voices, so a key press always clicks. slateis the recorder's line-up tone: 1 kHz held for most of a second, which a VU meter reads as 0.readLevels()returns what leaves the bus, for meters.- Vary a repeated sound with pitch and gain (a detent at 0.97 to 1.03), never with new sounds. Mute is remembered per device and follows across tabs.
The transport rule
On the player, the running study carries the tape's transport as data-transport; hostTransport(el) reads it. Sounds a study makes by itself ask first. Sounds from the viewer's own input always play.
- Aloud.
- Runs, but quiet until the viewer works it (a pointerdown or keydown on the study).
- Stays put. STOP remounts the study at its first frame; it doesn't start by itself.
- Component pages and capture frames read play.
Studies
1Moves in its first four seconds
Untouched: a rehearsal, a recall, a ghost typing, automation playing back, a self-test. Never still for more than half a second at the start. Then the hand takes over.
2Fits 282 × 332
A root
@container w-full max-w-[…], acqw-clamped font size on its child, everything else in em. Size to the container, never the viewport. Touch targets 24px or more.3Built from the materials, and marks them
A plate of the body's finish with wells, keys, caps, an LCD and lights. Never a second player, never a flat
shadow-mdcard. Both themes look intentional. Each part carriesdata-part, so its page can take it apart.4Sounds through play()
Existing sounds only, varied with pitch and gain. What it plays by itself follows the transport rule; what the viewer does always sounds.
5Turns without transforms
Rotation is
conic-gradient(from var(--a))or SVG attributes, or a transform inside anoverflow-hiddenwrapper, so a turning part never spills its stage.6Rounds its trigonometry
Coordinates rendered on the server are rounded to two decimals, so the browser's Math agrees when it hydrates.
7Passes the React Compiler rules
No
ref.currentduring render, no synchronoussetStatein an effect body, noMath.randomorperformance.nowin component-scope helpers.useEffectEventfor what effects call.8Accessible from the start
Native roles, one tab stop per composite, focus that follows the hand (no ring on pointerdown), live regions for changes, and reduced motion respected.
9Draws without React
Per-frame work writes CSS variables and attributes, and springs come from
createSpring. React hears about commits, not frames.10One file
A real, controlled component and a default
Demowith a single root, importing react,@/lib/soundand@/design-systemonly. It never takes focus on mount.
Run npm run check:fit before pushing: it loads every component page, the player's screen and the capture frame at six widths and fails if anything spills its stage. npm run check:anatomy takes every study apart on its page and fails if anything flattens the 3D or spills.
Writing
Sentence case everywhere
“Selected work”, not “SELECTED WORK” or “Selected Work”.
Labels say what happens
“Copy command”, then “Copied”. Not “Submit” or “OK”.
Short and plain
Write it the way you'd say it to someone at the next desk.
Parentheses for status
“Carson (In progress)”. A blue dot comes with it.
British spelling, with -ize
“Colour”, “centre”, “dialled”; but “synthesized”, “motorized”. Oxford spelling.
Say it once
If the screen already says it, the LCD doesn't. Repeats are taken out, not restyled.
Units and real symbols
“−3.5 dB”, “48 kHz · 24 bit”, “282 × 332”: a true minus, a times sign, a middle dot.
Capitals belong to the hardware
Lettering on the body is set in capitals by CSS. The source and screen readers keep sentence case: “Hold to erase”.
The recorder's world, in demos
take_04.wav, Export, Slate, Scene A. The component stays general; its demo speaks the instrument's language.