BRIEF.interaction-motion.md — Pulse Family, Interaction Layer#
Project: relay-creative / brand motion exploration Status: exploration — nothing here is ratified until it lands in SPEC.pulse-motion.md Live lab: /brand/motion-lab.html (interactive demos of everything below) Gallery: /gallery.html (the riff wall — mastheads, animatics, eggs, motion, one room) Date: July 2026 · v3.5 neutral-first
Why#
SPEC.pulse-motion.md ratified six behaviours (heartbeat, receipt flash, send burst, awaiting, arrival ring, broadcast) and gave #00D9C8 its job: motion-only, event flashes, never static, never looping on product surfaces. BRIEF.animations.md covers the produced marketing motion (Lottie/MP4 stings, deck beats, social cuts).
The gap between them is the interaction layer: how creating, copying, sending, claiming, and waiting feel inside the app. This brief proposes eight additions to the pulse family to fill it. All obey the four hard rules unchanged.
The four hard rules (carried verbatim, not renegotiated)#
- One pulsing element per view, maximum.
- Product UI transitions stay ≤0.18s — pulse moments are event animations (once) or brand-surface loops, never product chrome.
- Everything disables under
prefers-reduced-motion. The static mark must carry the brand alone. - Never loop #00D9C8 on product surfaces. Looping pulses stay in system teal; #00D9C8 is reserved for event flashes.
Proposed additions (7–14)#
| # | Moment | Class | Behaviour | Loop? | Colour law | Where |
|---|---|---|---|---|---|---|
| 7 | Code materialize | .rly-materialize | Characters land top-down, 55ms stagger, 0.3s each | Once | system teal | The moment a relay is created and its Code is minted |
| 8 | Copy cascade | .rly-copy-cascade | Characters lift in a 28ms wave; one #00D9C8 underline sweep | Once | #00D9C8 · event | Code copied (the most repeated act in the product) |
| 9 | Claim unfold | .rly-unfold | Received card wipes open (clip-path), content lines stagger in 90ms apart | Once | system teal | Relay received / context loaded |
| 10 | Stream arrival | .rly-stream-in | Item slides in from above (0.4s out-expo); status dot carries one arrival ring | Once | #00D9C8 ring · event | Stream feed, new item |
| 11 | Routing spinner | .rly-routing | Mark rays chase clockwise, 1.1s, eight steps | Loop | system teal (rule 4) | Network waits over 400ms; replaces generic spinners |
| 12 | Shutter toggle | .rly-shutter | Rays open/close clockwise, 30ms steps, on a boolean setting | Once | system teal | Settings that turn a signal on: notifications, nudges, visibility |
| 13 | Nudge blink | .rly-nudge | Two soft border-and-dot beats, 1.1s total, then still | Once (2 beats) | system teal | A nudge arrives — a tap on the shoulder, not an alarm |
| 14 | In-flight travel | .rly-travel | Code chip crosses a dashed path through the mark; pulse-coloured while moving | Once, bounded | #00D9C8 · in motion | Brand surfaces + send confirmation; the lab's lifecycle hero |
Timing conventions across all eight: out-quart/out-expo easing, no bounce, no elastic; exits run ~75% of entrance duration; product-layer feedback stays ≤0.18s (press weight is 0.12s at scale 0.97).
Colour-law notes#
- 8, 10, 14 use #00D9C8 and all three are bounded events: a sweep that dies, one ring, one flight. None loops. Rule 4 holds.
- 11 (routing spinner) loops, so it stays system teal even though "something is happening right now" — the something is waiting, not arriving. When the wait resolves, the arrival moment (receipt flash, family 2) carries the #00D9C8.
- 13 (nudge) deliberately does NOT use #00D9C8: a nudge is a request, not a receipt. Keeping it system teal preserves the meaning "pulse colour = context crossed a boundary."
Relationship to the eggs (PR #34) and animatics#
- Egg D (Code scramble) stays as-is; materialize (7) is its creation-time cousin. Scramble is hover-play, materialize is a birth event. They never run on the same element at the same time.
- Egg E (status snap) and F (receive beam) already own the receive moment on their surfaces; claim unfold (9) is the app-card variant, not a replacement.
- The animatics (
/animatics.html) remain the produced marketing layer. 14 (in-flight travel) is the in-app, code-drawn cousin of the M06 Send→Route→Receive sting — same grammar, so the app and the marketing motion rhyme.
Ratification path#
- Team plays with
/brand/motion-lab.html(light + dark, desktop + mobile). - Cut or amend concepts; anything kept gets its row appended to the family table in
SPEC.pulse-motion.mdand its keyframes added tobrand/relay-pulse.css(bump to v3.5.1). - Product adoption lands via relay-app tickets referencing the class names above.
Open questions#
- Does the routing spinner replace all spinners, or only relay-specific waits? (Recommendation: relay-specific first; global adoption after it proves calm.)
- Should copy cascade fire on keyboard copy (Ctrl/Cmd-C on a focused Code) as well as click? (Recommendation: yes — same event, same acknowledgement.)
- Stream arrival under rapid bursts: cap at one ring per 2s per feed so a busy Stream never strobes. Needs a debounce rule in the spec if ratified.
relay-creative/briefs/BRIEF.interaction-motion.md · July 2026 · exploration