fix(ui): default Reduced Motion on Calm and quiet decorative rails (#1622)

* fix(ui): default Reduced Motion on Calm and quiet decorative rails

Calm (and Reset to default) enables Reduced Motion; Signature clears it. Manual Motion stays independent of the visual-style card. Reduced Effects also stops decorative masthead rail animations. Related to #1614; does not close that issue.

* test(e2e): fix Calm Motion specs racing empty-create compose edit

Stop appearance init-script reseeding after mid-test mutations, and wait for Save and Deploy / mobile compose editor after empty create instead of assuming Anatomy Edit compose.
This commit is contained in:
Anso
2026-07-14 17:58:38 -04:00
committed by GitHub
parent b70a529656
commit c170c3f30c
13 changed files with 358 additions and 63 deletions
@@ -251,7 +251,7 @@ export function AppearanceSection() {
) : null}
<SettingsField
label="Reduced motion"
helper="Minimizes interface animations and transitions (dialogs, menus, expand and collapse). First control to try for high idle GPU use on constrained graphics. Toasts are unaffected."
helper="Minimizes interface animations and transitions (dialogs, menus, expand and collapse). Calm turns this on by default; choosing Signature turns it off. You can still toggle it independently afterward. First control to try for high idle GPU use on constrained graphics. Toasts are unaffected."
>
<TogglePill
checked={reducedMotion}
@@ -262,7 +262,7 @@ export function AppearanceSection() {
<SettingsField
label="Reduced effects"
helper="Flattens card bevels, the accent glow, and chart gradients, and turns off glass blur with solid chrome fills. Optional secondary material simplification; not a substitute for Reduced motion on reported idle GPU cost."
helper="Flattens card bevels, the accent glow, and chart gradients, and turns off glass blur with solid chrome fills. Also stops the decorative masthead rail animations even if Reduced motion is off. Optional secondary material simplification; not a substitute for Reduced motion on reported idle GPU cost."
>
<TogglePill
checked={effectiveReduced}
@@ -33,6 +33,36 @@ describe('AppearanceSection', () => {
fireEvent.click(screen.getByRole('button', { name: /Calm/i }));
expect(document.documentElement.dataset.headings).toBe('clean');
expect(document.documentElement.dataset.chartStyle).toBe('muted');
expect(document.documentElement.dataset.effects).toBe('reduced');
expect(document.documentElement.dataset.motion).toBe('reduced');
});
it('Calm and Signature preset apply write reducedMotion; Effects alone does not', () => {
render(<AppearanceSection />);
// Baseline Signature clears Motion.
expect(document.documentElement.dataset.motion).toBeUndefined();
fireEvent.click(screen.getByRole('switch', { name: 'Reduced motion' }));
expect(document.documentElement.dataset.motion).toBe('reduced');
// Re-applying Signature clears a manually enabled Motion.
fireEvent.click(screen.getByRole('button', { name: /Today's look|Signature/i }));
expect(document.documentElement.dataset.motion).toBeUndefined();
fireEvent.click(screen.getByRole('button', { name: /Calm|readable default/i }));
expect(document.documentElement.dataset.motion).toBe('reduced');
fireEvent.click(screen.getByRole('switch', { name: 'Reduced motion' }));
expect(document.documentElement.dataset.motion).toBeUndefined();
// Calm card stays selected with Motion off.
expect(screen.getByRole('button', { name: /readable default/i }).getAttribute('aria-pressed')).toBe('true');
// Re-applying Calm turns Motion back on.
fireEvent.click(screen.getByRole('button', { name: /readable default/i }));
expect(document.documentElement.dataset.motion).toBe('reduced');
// Individual Effects toggle preserves Motion.
fireEvent.click(screen.getByRole('switch', { name: 'Reduced motion' }));
expect(document.documentElement.dataset.motion).toBeUndefined();
fireEvent.click(screen.getByRole('switch', { name: 'Reduced effects' }));
expect(document.documentElement.dataset.motion).toBeUndefined();
});
it('shows the constrained-graphics callout when Reduced motion is off, and hides it when on', () => {
@@ -125,6 +155,7 @@ describe('AppearanceSection', () => {
fireEvent.click(screen.getByRole('button', { name: 'Reset to default' }));
expect(document.documentElement.dataset.headings).toBe('clean');
expect(document.documentElement.dataset.chartStyle).toBe('muted');
expect(document.documentElement.dataset.motion).toBe('reduced');
expect(screen.getByRole('button', { name: /readable default/i }).getAttribute('aria-pressed')).toBe('true');
fireEvent.click(screen.getByRole('switch', { name: 'Readability mode' }));