The four moves
Fire, rule, cell and fill: every component speaks with these.
Cell
Point, press, tab
Fire
Point at the bar
Held
-
Fire
pointerenter
A flare at the point the interaction starts. It plays once; hold the clock to see it.
- Row
Rule
pointerenter, :focus-visible
Developed in --state the full length of a line already on the page.
-
Cell
hover
Hot: a --state fill that keeps moving.
-
Cell, selected
aria-current
A still --ink fill.
-
Fill, burnt
hover
--state burnt across the solid block from its cell.
- On
Fill, selected
aria-pressed
--ink is selected.
Anatomy
| Fire | a square-banded flare of grain where an interaction starts, on the firing’s envelope: a 90ms rise and an exponential fall, over in 510ms (--duration-fire, 510ms); its front travels at one speed |
|---|---|
| Rule | develops in --state from the pointer, both ways, in 140ms (--duration-develop, 140ms); retracts in 100ms; the front travels on --ease-front (cubic-bezier(0.5, 1, 0.89, 1)), its spark streaked over the ground it covered each frame |
| Cell | a --tissue ring at rest, --state and firing when hot, its edge wobbling while hot, --ink when selected |
| Fill | a solid button burns --state from its cell in 160ms (--duration-burn) on --ease-front; a choice between peers pulses along their rule in 200ms (--duration-pulse), a head streaked over the ground it covered each frame with a tail over its last 37.5ms of travel |
| Dot | 2px, through the 8×8 Bayer screen |
| Where a move starts | at the pointer on broad surfaces, at the control’s own cell on compact ones |
| Reduced motion | every state lands at once and nothing fires |
Timings are read from rule.ts, ui.ts and global.css at build time.
Decisions
-
One interaction, one flare
Where a rule starts at a cell, the cell fires and the rule only develops out of it (Oct 2026). Until then a control with a label fired twice.
-
Faster rules
The rule went from ~260ms to 140ms in Oct 2026: Shan asked for it faster, snappier and more luminant, like the cursor firing.
-
Nothing slides or fades
Panels and slides change by a hard cut. Each element gets its own canvas behind its content, drawing only while something moves.
-
The flare is a firing
Until Nov 2026 the flare was 280ms, full on its first frame and draining in a straight line: the step and drain the hero had dropped for the shutter, so beside a culture that fired a hover read as a flash. It now fades on the firing’s own envelope from tissue.ts, ended at 6% of its peak, where its last dots on bare paper stopped sitting still as dirt, and its front travels at one speed, since an eased front stopped by half way and parked the grain.
-
Fronts on the firing’s rise
A rule developing, a solid button’s burn and the lab’s fibre advanced at one speed and read as linear (Nov 2026). They travel on --ease-front, the quadratic ease-out that is the firing’s rise: speed up front and a soft landing.
-
Pulses through the shutter
A rule’s click pulse was a four-dot head that moved past its own width every frame and strobed, and the tabs’ pulse left a 35% line behind it (Nov 2026). Every pulse now draws what moved during the frame: a solid streak over the ground it covered and a tail continuous over its last 37ms of travel, three dots tall so it shows on a rule already developed in the same red.
-
Mirrored timings
The --duration-* tokens and the constants in rule.ts and ui.ts move together, and --ease-front mirrors frontEase in tissue.ts; the figures above are read from both at build time.