v3.5 bans shadows, gradients, and glow, so motion is the only channel for warmth. This lab extends the ratified pulse family into the interaction layer: how creating, sending, claiming, and waiting should feel in the app. Every demo runs on the real tokens, the real mark, and the real colour law. Nothing here is ratified until it lands in SPEC.pulse-motion.md.
The whole loop, as one sequence. Press Create relay.
The product layer. Everything here stays at or under 0.18s, runs once, and reads as acknowledgement, not decoration. The Code gets the most care: it is the artifact, so it gets the most tactile feedback in the system.
Click the Code: characters lift in a 28ms wave and a pulse underline sweeps once. Copying is the most repeated act in the product; it should feel like picking the Code up.
A fresh Code lands character by character, 55ms apart, like it is being minted. Runs once at creation, then the Code holds still forever. Click to replay.
A switch built from the mark: off is the core alone, on opens the rays clockwise in 30ms steps. For settings that turn a signal on: notifications, nudges, public visibility.
Buttons compress to 0.97 on press and release on a 120ms out-curve. In dark mode the fill keeps the ink-flip: bright teal, near-black label. No lift, no shadow; weight comes from scale alone.
Event moments. Something crossed a boundary right now, and #00D9C8 is allowed exactly here: once, briefly, in motion. Loops never qualify.
The moment a relay is received, a pulse ring expands off the Code container and dies in 0.9s. Family behaviour 2, shown here on the claim surface. Click to replay.
A new Stream item slides in from above while the feed settles beneath it; its dot carries one arrival ring, then the item is ordinary.
A nudge is a tap on the shoulder, not an alarm: two soft border-and-dot beats in system teal, then still. Never repeats on its own.
Notifications enter with the family arrival ring on their status dot: one emanating pulse, 0.9s, done. The toast itself slides 10px on an out-expo, no bounce.
Loops. Anything that repeats stays in system teal, breathes slowly, and obeys the one-pulsing-element rule. Waiting states admit that time is passing without demanding attention.
The mark as the loading indicator: rays light clockwise in an eight-step chase. Replaces generic spinners anywhere the app waits on the network for more than 400ms.
A sent relay that has not been claimed yet breathes at 4.2s: slow enough to read as patience. Family behaviour 4, applied to the status dot in list rows.
No relays yet. Create one and the Code lands here.
Family behaviour 1 on its home surface: an empty list is a brand surface, so the mark may live there and beat at 2.8s. The copy does the reassuring; the pulse does the inviting.
The four hard rules from SPEC.pulse-motion.md carry unchanged. Below them, the additions this lab proposes for ratification into the family.
| # | Moment | Class | Behaviour | Loop? | Colour law |
|---|---|---|---|---|---|
| 7 | Code materialize | .rly-materialize | Characters land top-down, 55ms stagger, at relay creation | Once | system teal |
| 8 | Copy cascade | .rly-copy-cascade | Character wave + single underline sweep on Code copy | Once | #00D9C8 · event |
| 9 | Claim unfold | .rly-unfold | Received card wipes open, content lines stagger in 90ms apart | Once | system teal |
| 10 | Stream arrival | .rly-stream-in | Item slides in from above; status dot carries one arrival ring | Once | #00D9C8 ring · event |
| 11 | Routing spinner | .rly-routing | Rays chase clockwise while waiting on the network | Loop | system teal (rule 4) |
| 12 | Shutter toggle | .rly-shutter | Rays open and close clockwise on a boolean setting | Once | system teal |
| 13 | Nudge blink | .rly-nudge | Two soft border-and-dot beats when a nudge arrives | Once (2 beats) | system teal |
| 14 | In-flight travel | .rly-travel | Code chip crosses a dashed path through the mark; pulse-coloured while moving | Once, bounded | #00D9C8 · in motion |