States

Every state is a wash of the main ink, the keyboard has one ring, and a page with nothing to show says so in one sentence.

Rest, pointer over, pressed, selected, focus

Four parts, a list row, a rail row, an icon button and an action, each at rest, with the pointer over it, pressed, and with the keyboard focus ring.
The same states on four parts.
StateValue
RestNo wash
Pointer overA wash of the main ink at 5 %, in and out over 80 ms (the hover motion); 8 % on a small round target such as an icon button, where 5 % does not show on 36 pixels
Pressed22 % while held, then the selected 10 %
Selected10 %; 13 % with the pointer over it
Keyboard focusA 2-pixel ring in the accent, 2 pixels outside the item. It shows from the first key press until the next pointer press, for the whole app
DisabledThe faint ink, no wash, no pointer cursor and no stop for Tab. Opacity is never used

A Slab has no wash. Its fill under the pointer fades in over 140 ms (tone), and a press scales it to 0.97 over 120 ms (press) and back. A switch knob and a slider knob use the same two motions.

The rail's current row has a wash and an accent tick, as the one "you are here". The ring is shown only after a key because a pointer user does not need it, and it makes a press look like a request to type. Each kit part turns it on from its own key handler. An app that wants the first Tab to show it calls Kit.watchKeys(window) once for each window.

With Kit.reducedMotion on (set TACIT_REDUCED_MOTION=1) every one of these durations is 0 ms: the states change at once and nothing else about them differs. Motion lists every duration.

A run of selected rows

A run is one wash. Rows selected next to each other join: the wash is round only at the ends of the run. Separate pills for each row read as separate choices and make a selection of ten look like ten things.

Three selected rows in one wash, round at the top and bottom only, and an unselected row below.
DoA run is one wash.
Three selected rows each in its own rounded wash, with gaps between.
Don'tA pill for each row.

With the keyboard the selection jumps to the next row, so it keeps up with a held key. In a row list, joinAbove and joinBelow on the delegate make the join.

Empty and failed

One sentence where the content would be. It says what happened and what to do, with at most one action and no illustration. A failure carries the warning symbol in the risk ink. Put it where the first row would start, 40 in from the page and 104 down; never in the middle.

An empty page: Nothing here yet. Files you download land in this folder. And a failed one with the warning symbol: The drive was pulled out while it was being read. Plug it in and open it again, with a Try again button.
An empty page and a failed one.

Say the reason once, in the place the person is looking. In the music player a song that cannot play says why in the player's bar, and its row keeps only the symbol. Something that has gone, such as a drive that was pulled out, goes from the rail too.

Loading

Rows appear as they are read. While a folder is still being read, an accent stretch travels along the header's line (loading on PageHeader). There is no spinner in the middle of the page.

Experimental, in Tacit.Kit 0.1.