The entrance motion added in the previous rounds was too loud. Softened at
the token level and removed at the call sites where it replayed repeatedly.
Tokens (styles/main.css):
- fade-in 0.3s -> 0.15s
- fade-in-up 0.4s / 8px rise -> 0.2s / 3px rise
- check-pop 0.35s / 0.6-1.15-1 overshoot -> 0.2s / 0.92-1.02-1
Call sites, which mattered more than the token tuning:
- message-card: dropped animate-fade-in. Message history refetches on filter
change, pagination and auto-refresh, so every row replayed its fade on
every tick.
- get-started: dropped the per-index animationDelay stagger. The card polls
every 10s, so any remount replayed a cascading six-row stagger.
- empty-state: dropped animate-fade-in from a static block.
- community-links: hover:scale-105 -> border and shadow change.
- onboarding progress bars: duration-500 -> duration-300.
Radix enter/exit animations on dialogs, dropdowns, selects, toasts and the
accordion are unchanged: they are short, conventional and expected. The
prefers-reduced-motion guard is unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- promote the message-history EmptyState into components/shared/empty-state
and use it for the bare "No devices found" / "No API keys found"
placeholders (icon + title + actionable hint, fade-in)
- button primitive: subtle active:scale press state (transition covers
transform; the global prefers-reduced-motion guard still disables it)
- finish the deferred bg-gradient-to-* -> bg-linear-to-* rename (Tailwind v4
canonical utility) across the remaining four alert/modal components
Build, 25 unit tests, and 6 e2e green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>