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>
The Get Started card is the activation funnel; this makes it exceptional:
- animated progress bar + "x of 6" + momentum copy that changes with
progress; per-step time-estimate chips; benefit-led step copy
- focus model: completed steps collapse to compact checked rows (check-pop
animation), only the active step expands with one primary CTA; staggered
entrance; auto-advance when the poll detects a step completed
- register_device is now self-serve inline: numbered instructions beside an
in-place generate-key + QR panel (reuses the existing key mutation and
react-qr-code); help dialog demoted to a "Need help?" fallback
- verify_email shows the actual email and an inline resend with a 60s
cooldown via the existing sendEmailVerificationEmail endpoint
- completion is celebrated (one-time success state with "Send a message"
CTA) instead of the card vanishing mid-glance
- minimize control collapses the card to a slim resumable progress pill
(localStorage), so setup never nags
Fail-closed states (bug fixes):
- previously a backend failure rendered the checklist from missing data,
showing verified users stuck on "Verify your email"; now a status machine
(loading/error/ready/hidden/celebrate) only renders the checklist when all
three queries succeeded; error shows a quiet retry row
- the full-height 6-row loading skeleton is replaced by a compact ~90px
placeholder; background poll failures keep last-good data
Tests: MSW handlers for onboarding PATCH + resend; RTL tests for the error
policy, mid-funnel progress, and all-done progress; e2e asserts the progress
bar on Home. Build, 28 unit tests, and 13 e2e green; verified at 375px.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root causes of the sideways-scroll blank strip at 375px:
- fixed-width auth cards (w-[400px]/w-[450px]) -> w-full + max-w so they
shrink on small screens
- min-w-[500px] on the community-links dialog -> removed
- webhooks section header: two w-full buttons in a non-wrapping flex row
(403px wide) -> stacks on mobile
- devices/api-keys cards blown past the grid track by min-content sizing
-> min-w-0 max-w-full on the cards
- api-guide SyntaxHighlighter blocks get overflowX auto + maxWidth 100%
- safety net: overflow-x clip on body
Adds e2e/mobile-overflow.spec.ts: at 375px, scrollWidth must not exceed the
viewport on home, messaging, webhooks, account, and login. This guard caught
the webhooks-header and card offenders during the fix.
Build, 25 unit tests, and 11 e2e green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- new primary accent: warm orange #EA580C (hsl 21 90% 48%) in light + dark,
with the matching Tailwind-orange brand-* ramp; focus ring now uses the
accent, and the primary-on-color foreground is white for contrast
- refine dark mode into layered neutrals (background below cards/popovers,
clearer borders) instead of the previous flat gray
- warm the accent token and align chart-1 to the brand
- adopt Inter via next/font (--font-inter -> font-sans), antialiased body
- motion foundation: fade-in / fade-in-up keyframes as theme animations plus
a prefers-reduced-motion guard; drop dead imports from the root layout
Build, 19 unit tests, and e2e green; dashboard visually verified in the new orange.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CSS-first config: @import "tailwindcss" + @theme inline mapping the
shadcn HSL tokens; colors unchanged (rebrand lands in the design part)
- switch postcss to @tailwindcss/postcss, drop autoprefixer
- replace tailwindcss-animate with tw-animate-css for the animate-in /
data-state utilities the Radix primitives rely on
- remove tailwind.config.js (v4 auto-detects content) and point
components.json at the CSS
- suppressHydrationWarning on <html> for the next-themes class swap
Build, unit tests, and e2e all green; generated CSS verified to contain
bg-primary, the brand ramp, border-border, and the accordion/animate utilities.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>