Skip to content

Feedback: stamp, result, confetti

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): Feedback is caused by a completed action. The demo initial Verified label is still, active replays are ignored, confetti cannot overlap, and status is announced without moving focus. Bursts remove themselves after actual animation completion. All durations/easings are token-derived; decorative success moments do not block input. Supersedes the retained implementation/timing claims below; see docs/current-rules.md#cr-motion-01 and motion-flow.

How the product confirms something worked. A valid card check lands with one stamp; a result panel arrives with a small scale-in; a pass tears in from above; the workshop logbook opens like a cover; a completed return fires one confetti burst (only with interface effects on). Errors do not bounce or shake: they appear.

Open demo.html in a browser (it links ../../tokens/tokens.css) and use “Toggle dark” to check both themes.

File What it is
feedback.css sw-verify-stamp (card verify), sw-confetti-* (return burst), sw-result-arrive, sw-pass-tear, sw-logbook-open, copied unchanged.
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).
  • Stamp: features/cards/CardVerifyPage.tsx, cardVerify.css (valid card check).
  • Confetti: components/delight/ReturnConfetti.tsx inside SuccessCard.tsx after a return is confirmed.
  • Result, pass, logbook: components/delight/delight.css on ResultPanel / PassState.tsx / WorkshopLogbook.tsx.
  • The primary success feedback everywhere else is a status toast (see toast).

A confirmed result should feel confirmed, once, without delaying anyone. The stamp echoes a physical handover; the confetti is a rare celebration of a completed return. None of it carries information the text does not already carry.

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.

Animation Duration Easing
sw-verify-stamp 420 ms, once cubic-bezier(0.32,0.72,0,1); scale 1.35 to 0.96 to 1, rotate -8 deg to 1 deg to 0
sw-confetti-burst 1100 ms, per piece delay 0, 30, 60, 90 ms cubic-bezier(0.2,0.7,0.3,1); 16 pieces in a fixed fan
sw-result-arrive 360 ms ease-out; scale .96 to 1
sw-pass-tear 360 ms ease-out; translateY -8 px to 0
sw-logbook-open 360 ms ease-out; rotateY -8 deg to 0 (perspective 600 px)

Mount of the result. Confetti is gated: interface effects on, motion allowed, and never on kiosk, scanner, checkout or payment paths. The stamp is also gated by effects on.

Everything is off: the stamp is inside no-preference, the delight classes set animation: none, confetti is display: none. The text and colour of the result carry the meaning.

Confetti colours are brand tokens (--color-accent, --color-emphasis, --color-success, --color-warn, --color-info); on a citron or yellow panel two of them swap for the panel’s ink so pieces never vanish. The stamp follows the result colours.

  • Do keep it once and under half a second (the burst is the one longer piece).
  • Do make it decorative and aria-hidden.
  • Do not use confetti in staff, kiosk, scanner, checkout or payment flows.
  • Do not animate validation errors (they appear, they do not bounce).
  • Do not add sound.

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="feedback.css">
<span class="sw-verify-stamp">Verified</span>
<div class="sw-delight-result">…result…</div>

Confetti: demo.html builds the 16 pieces (.sw-confetti-piece with --dx, --dy, --spin, --piece) exactly as ReturnConfetti.tsx does.

Every other animation in the product, and the rules behind them: ../../docs/motion.md. Index of the kit: ../README.md.

Feedback is caused by a completed action. The demo initial Verified label is still, active replays are ignored, confetti cannot overlap, and status is announced without moving focus. Bursts remove themselves after actual animation completion. All durations/easings are token-derived; decorative success moments do not block input.

Complete rules, sequencing, keyboard and verification. The demo includes real static posters and explicit image Play/Pause controls.

These aliases are local additions; global tokens are unchanged. Promote through the token batch when adopted.

Local custom property Definition
--sw-local-duration-1100 calc(var(--sw-dur-slow) * 4.58333333)
--sw-local-duration-360 calc(var(--sw-dur-slow) * 1.50000000)
--sw-local-duration-4000 calc(var(--sw-dur-slow) * 16.66666667)
--sw-local-duration-420 calc(var(--sw-dur-slow) * 1.75000000)

Copied from motion/feedback/ on every build: the stylesheet, demo.html, react/ copies of the app files and the previews/.