S Motion language — prototype

Subtle, accessible motion for the Saga dashboard

Each block below is one interaction from the motion plan. Everything animates only transform & opacity (smooth on low-end Chromebooks), and the Reduced motion switch at the top shows exactly what ships to people who ask for less movement — motion drops to short fades, nothing disappears. Colored tag = which work-chunk it belongs to.

Part 1 — motion for things you did

You clicked, so something moved. These can be immediate and confident, because you already know what caused them.

Left-nav slice

Left-nav mode swap + active indicator

Entering program setup slides the whole nav in from the right; leaving slides it back. The active-item fill slides between rows within a mode — and note the shape shift: pill-shaped items in the normal nav, squared-off steps in configuration. The one "bigger" moment in the plan, still calm. Click Enter configuration mode, then click rows to move the indicator.

The whole panel slides as one unit, so no text ever crosses over other text. Reduced motion → instant swap, no slide.
Vocabulary slice

Dialogs — backdrop & panel move as one

The dim backdrop and the dialog share one timing, so they read as a single object arriving. Reduced motion → both just fade.

Vocabulary slice

Expand / collapse

Period rows and accordions open with a clip + fade instead of snapping. Reduced motion → instant, no size animation.

Period 2 · Rotation A
Pod 1 — 4 students
Pod 2 — 3 students
Pod 3 — 4 students
Vocabulary slice

Lists — gentle entrance & reorder

Session and pod cards fade up with a light stagger on load, and glide to new positions when sorted (FLIP) instead of jumping. Reduced motion → they just fade, no travel.

9:00 · Reading — Pod A
9:00 · Math — Pod B
9:40 · Reading — Pod C
9:40 · Math — Pod D
Foundation slice

Loading — skeletons & hold-and-dim

First load shows a shape-matched skeleton (a soft pulse, never a shimmer sweep). When you re-filter existing data, we hold the old rows and dim them while the new ones fetch — no blank flash, no layout jump. Reduced motion → skeleton is static.

Ada L. — present
Ben O. — present
Cy R. — absent
Part 2 — motion for things that happened without you

When the data changes on its own

Everything above is motion for something you did. This half is the missing other one: sessions start, sessions end, filters re-cut the list, notifications arrive — all on a 20-second poll, none of it asked for.

That difference sets the rules. A change you caused can be instant and confident. A change you didn't cause has to announce itself without interrupting, and it has to leave a mark that outlives the animation — because you were probably looking somewhere else when it happened.

How to read these three. Each has an orange fork box — those are the real design decisions still open, so flip them and pick. Everything else is a recommendation. Slow-mo makes the timing visible; Reduced motion shows the accessible fallback.
Ambient tier

Dashboard → Current sessions

Cards fill across, then wrap down (auto-fill, minmax(280px, 1fr)), so a card arriving in the middle reflows every card after it. Three separate problems: the newcomer, the survivors it displaced, and the gap a departure leaves.

Forks — pick one
Two-phase departure. A leaving card dissolves in place first (180ms); only then do the survivors close the gap (280ms). Doing it in one phase — yanking everything left the instant a card vanishes — is what makes live grids feel twitchy. Deliberately not proposed: a different exit for “session ended” vs “filtered out”. You already know if you changed the filter, and if you didn't you can't tell the two apart anyway — it would double the vocabulary to convey nothing.
Ambient tier

Sessions → Today

Status section → group container → session rows, each level with its own count and its own collapse. The whole design turns on one question: is the destination laid out right now? Collapsed bodies are display:none, so there is nothing to fly into and nothing to measure. That isn't an edge case — Ended is collapsed by default, which is exactly the blind spot this set out to fix.

Forks — pick one
The hand-off. When the destination isn't laid out, the card can't fly — so it fades and drifts ~22px toward where that section sits, and the section's header answers: a one-shot tint wash, a chevron nudge, and the count rolling. Direction alone carries “it went up there” without the target ever being on screen. This is the default, not the fallback.
Counts are post-filter. The badge shows matches, not the total. So a badge delta has two possible causes, and if one animation serves both, a single keystroke in the search box rolls every badge on the page at once. Roll on data, snap on filter.
Ambient tier

Notification bell

The badge only exists when the count is above zero, so 0→1 is an arrival and 1→0 a departure, while 2→3 is neither. Three different transitions wearing one number.

Reading intervention · Lincoln MS
Forks — pick one
One damped swing, not a shake. −9° → +6° → −3° → 0 over ~460ms, pivoting at the bell's crown. It's a bell; ringing once is the most obvious thing it can do, and a single decaying swing reads as restraint where a repeat would read as an alarm. That's the entire whimsy budget for this tier.
Ambient tier

What Part 2 asks of the token layer

Deliberately almost nothing. It reuses Part 1's durations and easings — the one genuinely new value is a decay window, which is a different kind of thing from a duration, not a fourth duration.

TokenValueUsed for
--motion-fast150msbadge pulse, chevron nudge (existing)
--motion-base210msdigit roll, exit dissolve, status-chip colour carry (existing)
--motion-slow280msarrivals, FLIP reflow, hand-off drift (existing)
--motion-residue2400msthe only new token — how long a “this is new” mark takes to fade
--motion-stagger32ms · cap 6existing value, new cap so a bulk change can't become a light show
--ease-out / --ease-over(.22,1,.36,1) / (.34,1.28,.5,1)everything / badge pop + bell swing (existing)

Rules the tier adds

Prerequisites found while building this