diff --git a/studio/frontend/src/index.css b/studio/frontend/src/index.css index 7afa87f597..8f132cd95b 100644 --- a/studio/frontend/src/index.css +++ b/studio/frontend/src/index.css @@ -1187,3 +1187,34 @@ color: var(--popover-foreground) !important; border-color: var(--border) !important; } + +/* + * prefers-reduced-motion: honour the OS-level "reduce motion" preference. + * Tailwind animate-in/out, Radix open/close transforms, infinite shine/pulse + * keyframes, and Framer Motion layout transitions all ignore the media query + * by default. Forcing every animation/transition to ~0ms collapses zoom-ins, + * slide-ins, and continuous shimmers to a single frame without removing the + * end state. Hover colour changes become instant rather than fading, which is + * the documented WCAG outcome (motion is "minimised, not removed"). + * + * .animate-spin is the exception: loading spinners are essential progress + * indicators across Studio (tool execution loaders, sonner toasts, Tauri + * startup / update screens, the primitive). Freezing them + * removes the only visual signal that work is in flight, so they keep + * animating but at a slower, less aggressive 1.5s cadence. + */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } + + .animate-spin { + animation-duration: 1.5s !important; + animation-iteration-count: infinite !important; + } +}