GANGLION

The four moves

Motion

Fire, rule, cell and fill: every component speaks with these.

Cell

Point, press, tab

Rule

The hairline develops from the pointer

Fire

Point at the bar

Contact me

Fill

Burn across a block; a pulse between peers

Point at the part
Clock
Motion
Theme

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.

  • Go

    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.