Skip to content

Add reduced-motion, forced-colors, and high-contrast accessibility support - #558

Merged
james2177 merged 4 commits into
stellar-vortex-protocol:mainfrom
aishabellova:drips/492-493-494
Sep 30, 2026
Merged

james2177 merged 4 commits into
stellar-vortex-protocol:mainfrom
aishabellova:drips/492-493-494

Conversation

@aishabellova

Copy link
Copy Markdown

Summary

Add reduced-motion, forced-colors, and high-contrast accessibility support

What was solved

#492 — [High] Audit and complete reduced-motion, forced-colors and high-contrast support

Audit and complete reduced-motion, forced-colors, and high-contrast support across the app: centralize motion preference handling (user setting + OS media query), wire framer-motion MotionConfig, gate CSS animations, replace/pause infinite animations, add forced-colors and prefers-contrast styles, and add Playwright emulation tests plus accessibility docs.

Addressed:

  • Changed: src/app/globals.css, src/components/SettingsPanel.tsx, src/components/Skeleton.tsx, src/components/IntentStatusBadge.tsx
  • Create a central useMotionPreference() hook combining the user data-motion setting with the OS prefers-reduced-motion media query
  • Wire framer-motion MotionConfig reducedMotion to the resolved preference
  • Gate CSS animations (shimmer, flow, fade-up) via [data-motion="reduce"] and @media (prefers-reduced-motion: reduce), setting durations to 0.01ms under reduce

#493 — [High] Implement a user-selectable theme system (Light/Dark/System) with no-flash SSR and persisted preference

Implement a user-selectable Light/Dark/System theme system with SSR-injected no-flash initialization, persisted preference via the storage facade, data-theme-driven CSS variables (light palette defined once), dynamic theme-color meta, Storybook toolbar integration, and a pure resolveTheme helper with system-change listeners.

Addressed:

  • Changed: src/app/globals.css, src/app/layout.tsx, src/components/SettingsPanel.tsx, src/lib/theme.ts
  • Add a System/Light/Dark theme setting to SettingsPanel, persisted through the existing storage facade.
  • Drive CSS variables from a data-theme attribute on <html>; define the light palette once (not duplicated inside prefers-color-scheme media queries).
  • Inject an inline blocking script (CSP-nonce compatible) that sets data-theme before paint to prevent FOUC, with a safe fallback when storage is blocked.

#494 — [High] Add locale routing and SSR-aware i18n: cookie/Accept-Language detection, dynamic <html lang> and persisted preference

Implement SSR-aware locale resolution for the App Router: a pure negotiateLocale() helper, middleware that resolves locale from URL prefix/?lang= → vortex-locale cookie → Accept-Language → default and sets a request header plus Vary, server-side /dir and I18nProvider initialization from the resolved locale, and SettingsPanel locale changes that persist the cookie and update the route while preserving page state.

Addressed:

  • Changed: src/app/layout.tsx, src/lib/i18n/index.ts, src/lib/i18n/server.ts, middleware.ts
  • Locale resolution order must be: explicit URL prefix (/es/...) or ?lang= → cookie (vortex-locale) → Accept-Language negotiation → default, implemented in middleware with a pure negotiateLocale() function.
  • Middleware must coordinate with existing CSP middleware and set Vary: Accept-Language/Cookie for correct cache keys.
  • Document and implement the routing strategy (path prefix via App Router [locale] segment or cookie-based without prefix) with justification, including hreflang alternates and canonical URLs in metadata.

Changes

  • src/app/globals.css (modify)
  • src/components/IntentStatusBadge.tsx (modify)
  • src/lib/i18n/index.ts (modify)
  • src/components/SettingsPanel.tsx (modify)
  • src/app/layout.tsx (modify)
  • src/lib/i18n/server.ts (modify)
  • src/components/Skeleton.tsx (modify)
  • src/lib/theme.ts (create)
  • middleware.ts (create)

Approach

  1. [High] Audit and complete reduced-motion, forced-colors and high-contrast support #492 — [High] Audit and complete reduced-motion, forced-colors and high-contrast support (Changed: src/app/globals.css, src/components/SettingsPanel.tsx, src/components/Skeleton.tsx, src/components/IntentStatusBadge.tsx)
  2. [High] Implement a user-selectable theme system (Light/Dark/System) with no-flash SSR and persisted preference #493 — [High] Implement a user-selectable theme system (Light/Dark/System) with no-flash SSR and persisted preference (Changed: src/app/globals.css, src/app/layout.tsx, src/components/SettingsPanel.tsx, src/lib/theme.ts)
  3. [High] Add locale routing and SSR-aware i18n: cookie/Accept-Language detection, dynamic <html lang> and persisted preference #494 — [High] Add locale routing and SSR-aware i18n: cookie/Accept-Language detection, dynamic <html lang> and persisted preference (Changed: src/app/layout.tsx, src/lib/i18n/index.ts, src/lib/i18n/server.ts, middleware.ts)

Issues

Closes #492
Closes #493
Closes #494

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@aishabellova Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

# Conflicts:
#	src/app/layout.tsx
#	src/components/IntentStatusBadge.tsx
#	src/components/SettingsPanel.tsx
#	src/components/Skeleton.tsx
@james2177
james2177 merged commit 534541d into stellar-vortex-protocol:main Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants