diff --git a/frontend/src/App.css b/frontend/src/App.css index 9a6a0fda..8a58caee 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -3036,6 +3036,12 @@ body[data-theme='dark'] .gonavi-settings-center-entry:hover { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; } + + /* Loading indicators communicate ongoing work, rather than decorative motion. */ + .gonavi-settings-center-modal .ant-btn-loading-icon .anticon-spin { + animation-duration: 1s !important; + animation-iteration-count: infinite !important; + } } .gonavi-ai-settings-nav-description { diff --git a/frontend/src/App.tool-center.test.ts b/frontend/src/App.tool-center.test.ts index 6e626d71..0e3f61fe 100644 --- a/frontend/src/App.tool-center.test.ts +++ b/frontend/src/App.tool-center.test.ts @@ -6,6 +6,10 @@ const appSource = readFileSync( fileURLToPath(new globalThis.URL('./App.tsx', import.meta.url)), 'utf8', ); +const appCss = readFileSync( + fileURLToPath(new globalThis.URL('./App.css', import.meta.url)), + 'utf8', +); describe('settings center tool entries', () => { @@ -25,4 +29,10 @@ describe('settings center tool entries', () => { const minimiseProbeIndex = resizeHandlerSource.indexOf('rememberMinimisedStateSoon();'); const dprCheckIndex = resizeHandlerSource.indexOf("scheduleDevicePixelRatioCheck('resize');"); }); + + it('keeps button loading indicators animated when reduced motion is enabled', () => { + expect(appCss).toMatch( + /@media \(prefers-reduced-motion: reduce\) \{[\s\S]*?\.gonavi-settings-center-modal \.ant-btn-loading-icon \.anticon-spin \{[^}]*animation-duration: 1s !important;[^}]*animation-iteration-count: infinite !important;[^}]*\}/, + ); + }); });