Toast
Live demo
Section titled “Live demo”The page below is the real demo.html from the kit. Use its “Toggle dark” button for the dark theme.
Current rule (v2.0.1, 2026-11-13): Success expires after 8,000 ms of reading time (UX P30); errors never expire automatically. Hover, focus and awaited Undo pause expiry. Undo failure persists and can be retried; Dismiss preserves focus. Use toast.js or react/ToastDemo.tsx for the complete portable lifecycle; ToastHost.tsx is an app integration reference. Entrance/exit use base and base × .75 (180/135 ms), from the same 12 px origin. Supersedes the retained implementation/timing claims below; see docs/current-rules.md#cr-motion-01 and motion-flow.
A status toast arrives from just below its slot (12 px, fading in) and leaves by dropping 8 px while fading. It never steals focus; the message is announced through a polite live region (errors through an alert region).
Open demo.html in a browser (it links ../../tokens/tokens.css) and use “Toggle dark” to check both themes.
| File | What it is |
|---|---|
toast.css |
The sw-fx-toast rule and its two keyframes, copied unchanged from styles/motionOverlay.css. |
demo.html |
A standalone page with the live animation in light and dark, replayable. |
react/ |
Copies of the real app files (see react/README.md for the imports to replace). |
previews/ |
Animated WebP and GIF previews, light and dark (regenerated by scripts/make-previews.mjs). |
Where the app uses it
Section titled “Where the app uses it”components/ui/ToastHost.tsx(the one host mounted by the app shell): every save, undo, error and result message in staff, member and public flows.lib/motion/usePresence.ts(useExitingItems) keeps a dismissed toast on screen, inert, while its exit plays.
Status appears without taking focus or moving anything else, and its short exit confirms the dismissal. The tone (error colour) is carried by colour and text, never by shaking or bouncing.
Timing, easing and distance
Section titled “Timing, easing and distance”Current rule (v2.0.1, 2026-11-13): The retained table/snippet below records the original app copy. Use the current executable files and the complete flow recipe for decision 399; see current rules.
| Phase | Value |
|---|---|
| In | --sw-dur-base 180 ms, --sw-ease-enter, translateY 1.5 x --sw-enter-y (12 px) and opacity |
| Out | --sw-dur-fast 120 ms, --sw-ease-exit, translateY --sw-enter-y (8 px) and opacity |
Trigger
Section titled “Trigger”A toast is added to the store (data-state="open") or dismissed (data-state="closed" plus inert, removed on animation end).
Reduced motion
Section titled “Reduced motion”Inside no-preference: the toast appears and disappears instantly; the live region still announces it.
Dark theme
Section titled “Dark theme”Colour-neutral; the panel, border and error text colours are tokens.
Do and don’t
Section titled “Do and don’t”- Do announce through
role="status"(polite) orrole="alert"for errors. - Do keep the toast out of the focus order while it leaves (
inert). - Do not shake, bounce or auto-focus a toast.
- Do not add sound.
Copy-paste usage
Section titled “Copy-paste usage”Current rule (v2.0.1, 2026-11-13): The retained table/snippet below records the original app copy. Use the current executable files and the complete flow recipe for decision 399; see current rules.
<link rel="stylesheet" href="../../tokens/tokens.css"><link rel="stylesheet" href="toast.css"><div class="sw-fx-toast" data-state="open" role="status">Saved.</div>To dismiss: set data-state="closed" and inert, then remove the element on animationend.
Every other animation in the product, and the rules behind them: ../../docs/motion.md. Index of the kit: ../README.md.
Flow contract (decision 399)
Section titled “Flow contract (decision 399)”Success expires after 8,000 ms of reading time (UX P30); errors never expire automatically. Hover, focus and awaited Undo pause expiry. Undo failure persists and can be retried; Dismiss preserves focus. Use toast.js or react/ToastDemo.tsx for the complete portable lifecycle; ToastHost.tsx is an app integration reference. Entrance/exit use base and base × .75 (180/135 ms), from the same 12 px origin.
Complete rules, sequencing, keyboard and verification. The demo includes real static posters and explicit image Play/Pause controls.
Local token steps for batch 1B
Section titled “Local token steps for batch 1B”These aliases are local additions; global tokens are unchanged. Promote through the token batch when adopted.
| Local custom property | Definition |
|---|---|
--sw-menu-exit |
calc(var(--sw-dur-fast) * .75) |
--sw-overlay-exit |
calc(var(--sw-dur-base) * .75) |
Source
Section titled “Source”Copied from motion/toast/ on every build: the stylesheet, demo.html, react/ copies of the app files and the previews/.

