The design system

The machine, in parts

Every value below is read off the live stylesheet, and the groups come from ui/theme-contract.json. Change the machine or the lamp on the left and the whole page moves with it. That includes its own type and panels, which come from the same tokens as the app.

Primitives

The raw palette, and the only place a colour is written down. Named for what they are and never for what they do: the number is the L* of the colour, so a theme may give --p-warm-15 any hue it likes and it will still be lighter than --p-warm-09.

No component may read one. That rule is what makes a new amp possible at all. A component that reaches past the contract to a raw colour is one the theme cannot reach, and it will be the single part that stays the old machine after everything around it has changed.

The contract

What a theme rebinds, in whole groups. A theme that only fits a new bulb defines the lamp group and nothing else. What it must not do is define half of one.

Half a group is the failure mode worth naming. A new --lit with the old --lit-rgb leaves the canvases painting the previous colour, so the roll stays the old machine while the fascia around it changes. The rule is checked rather than remembered, and it has caught exactly that.

Components

The app's real markup under the app's real rules. This page loads the same stylesheet, so what is below is what is on the machine, not a drawing of it.

Every part here is shaped by the same constraint: it is worked while someone is singing. That is why a key holds a solid side in every state, why the press is sold by the face inverting rather than by movement, and why a readout is a lit window rather than a number on a background. Nothing moves. The light does.

Several of these are not standalone. .btn--icon takes its width from .panel-head .btn--icon or .mix-keys .btn--icon, and has none of its own; a knob is sized by --dial on a parent. Shown in the container they need, and labelled. A component library that hides that teaches the wrong thing. The first version of this page rendered both as slivers.

Keys that stand alone

Keys that need a container (.panel-head)

Knob, which needs --dial on a parent

050100
88860 The singer

Readouts

88860 888-- 888802:38

Type on the glass

pixel face on glass dimmed a song title

Glass

no song loaded

what the machine says, lit from behind the panel

State

lit finished recording delete this?

Patterns

Not parts, but the rules the parts are arranged by. Every one of these answers the same question: what can someone actually do while they are singing? Their hands are not on the mouse, their eyes are on the roll, and they are often a few feet back from the screen. A pattern that ignores that is wrong however well it is drawn, which is why these are worth as much as the tokens.

The panel is a real object

This is the rule the rest of them come from. The machine is built to behave like a piece of equipment on a shelf, so the fascia holds still. A control that is there is there, in the same place, whether or not it is any use to you at this moment. Nothing appears when it becomes relevant and nothing is taken away when it stops being.

An amp does not grow a button. It has the buttons it has, and what changes is what they are connected to and whether they are lit. So a key that cannot do anything right now stays on the panel and goes dark. That costs a little space and buys the thing an instrument is for: you learn where a control is once, with your hands, and it is still there the next time you reach for it without looking.

One move is allowed. A whole section can be brought in or taken away as a unit, the way a rack module slides into a bay. The difference is that a module is a piece of the machine and arrives complete, with its own edges, and you can see it is a different part. A button appearing inside a panel you were already looking at is the machine changing shape under your hands, and that is the thing this rule exists to forbid.

Asking on its own glass

A dialog is the forbidden move in its purest form. It appears from nowhere, over the one thing you were looking at, and it has to be dismissed with a pointer before the machine will go on. So the question takes the display instead, which is already there and is already where the machine speaks. It is answered with the arrows and OK you are holding, which means a destructive choice never needs a different input from an ordinary one.

The whole screen goes to the alarm colour. That is the part doing the real work: you know what kind of question this is from across the room, before you have read a word, and the safe answer is the one already under the pointer.

remove this song?

08 - Gone With The Sin. Stems, pitch, lyrics and every take go with it.

keep it remove

A readout that has stopped reading

A dimmed readout is ambiguous at a glance. It could mean "unavailable", or "less important", or simply that you are seeing it at an angle. None of those is what happened here. The knob works. There is just nothing on the other end of it.

So it goes dark rather than dim. The window drops to --, the segments go out, and the bead on the cap goes with them. Unlit is a state you can read in a quarter of a second while your attention is somewhere else, which is the only kind of reading that happens during a take.

88860 reading
888-- not connected

Nothing floats over the machine

The same rule again, for things that are only trying to be helpful. A toast in the corner is a message posted where nobody is looking, and it is still something that appeared over the panel and will vanish on its own. While you are singing your eyes are on the roll and the words, so a notice that arrives and expires somewhere else has told you nothing.

So the machine says it on the display, in the pixel font, for as long as it takes to read. It arrives where you were already looking and nothing has to be dismissed.

“Hollow Man” is ready. 176 notes mapped, 42 lines of words.

no song loaded

press songs to pick one, or + to add one. headphones on. through speakers the mic hears the song and scores it as if it were you.

A list on the glass answers to arrows and OK

Four different lists, one shape. Takes, songs, inputs and the answers to a question are all rows lit behind glass with a pointer in the margin, worked by the three keys under the screen.

The point is that you learn it once. Whatever the machine puts in front of you, the arrows move and OK commits, so nothing here needs a scrollbar, a pointer, or a second look to work out how it is operated.

The words keep their times while you edit them

One field for the whole lyric, so fixing a word is ordinary typing rather than editing a row in a table. The times live in the gutter beside it and stay attached to their words through every edit, including re-flowing a line that ran long.

A time is two different jobs, so it is two targets. The number plays from there, which is how you check whether it is right. The mark beside it moves the line to where the playhead is, which is how you fix it. One control doing both would mean the only way to correct a timing was typing, and a wrong time is not visible in a text field.

I love your skin, ohooo so white I love your touch, cold as ice And I love every single tear you cry

Type

A machine's period is mostly its type. Swapping the segment face for the pixel one moves what era the thing is from more cheaply than any amount of recolouring. So a theme may leave two of these pointing at the same family. Each specimen says what it actually resolves to, so a collapsed face reads as a decision rather than a fault.

The scales

The contract lists these as names and numbers, which is what a validator needs and not what a person does. Here they are as the thing itself. Set a step against its neighbours and you can see whether the gap between them is a step or a rounding error. Everything below is drawn from the live tokens, so it follows the machine picker.

Typescale on the glass

Typescale on the panel

Leading

The same sentence at each step. Flush is 1 and means it: a readout is one line of lit glass, and any leading at all pushes it off its own centre.

Tracking

Spacing

Nine steps on a 2px base, because this is an instrument fascia and the four most-used values in it are 4, 10, 5 and 9. Not a migration target. 67 uses stay off it on purpose, and the validator holds that number down rather than to zero.

Cast

The only three shadows that mean height. Of the 36 box-shadows on this machine, 33 are glyph art, lamp light, or a surface's own form. Nothing here floats, which is the point of it.

Motion

Hover a bar to run it. Transitions answer you and are on a scale; animations play at you and are choreographed, so they are not.