grep -rn 'prefers-reduced-motion' web/src web/index.html → zero hits. Every animation runs unconditionally for users who've asked the OS for reduced motion:
AlertDialog zoom/fade, Drawer slide, Menu/Select fade (data-open:animate-in … in src/components/ui/)
animate-pulse skeletons
the sidebar transition-[width] expand/collapse (src/shell/sidebar.tsx)
(or the more surgical Tailwind motion-safe:/motion-reduce: prefixes on the data-open/data-closed animation classes — the global rule is less churn and covers future additions.)
Modal surfaces don't contain overscroll
grep -rn overscroll web/src → zero hits. On touch devices, scrolling past the end of the drawer body or a scrollable dialog chains to the page beneath, breaking the modal illusion:
web/src/components/ui/drawer.tsx — add overscroll-y-contain to the DrawerContent popup (the detail drawer scrolls long object records).
web/src/components/ui/alert-dialog.tsx — same on AlertDialogContent.
web/src/components/ui/combobox.tsx / menu.tsx / select.tsx popups (overflow-auto lists) — same, so flicking past the end of a long term list doesn't scroll the page.
Both changes are CSS-only inside src/components/ui/, no bundle-size impact.
## prefers-reduced-motion is not honored anywhere
`grep -rn 'prefers-reduced-motion' web/src web/index.html` → zero hits. Every animation runs unconditionally for users who've asked the OS for reduced motion:
- AlertDialog zoom/fade, Drawer slide, Menu/Select fade (`data-open:animate-in …` in `src/components/ui/`)
- `animate-pulse` skeletons
- the sidebar `transition-[width]` expand/collapse (`src/shell/sidebar.tsx`)
Simplest global fix in `src/index.css`:
```css
@media (prefers-reduced-motion: reduce) {
*, ::before, ::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
```
(or the more surgical Tailwind `motion-safe:`/`motion-reduce:` prefixes on the `data-open`/`data-closed` animation classes — the global rule is less churn and covers future additions.)
## Modal surfaces don't contain overscroll
`grep -rn overscroll web/src` → zero hits. On touch devices, scrolling past the end of the drawer body or a scrollable dialog chains to the page beneath, breaking the modal illusion:
- `web/src/components/ui/drawer.tsx` — add `overscroll-y-contain` to the `DrawerContent` popup (the detail drawer scrolls long object records).
- `web/src/components/ui/alert-dialog.tsx` — same on `AlertDialogContent`.
- `web/src/components/ui/combobox.tsx` / `menu.tsx` / `select.tsx` popups (`overflow-auto` lists) — same, so flicking past the end of a long term list doesn't scroll the page.
Both changes are CSS-only inside `src/components/ui/`, no bundle-size impact.
Global prefers-reduced-motion: reduce rule in index.css@layer base — collapses all animation/transition durations to 0.01ms, covering the kit's data-open/closed animations, animate-pulse skeletons, and the sidebar transition-[width] with one rule (and any future additions for free).
overscroll-y-contain on DrawerContent, SelectContent, and ComboboxPopup (the scrollable surfaces), plus AlertDialogContent defensively for when it gains scrollable content.
MenuPopup was skipped deliberately: it has no max-height/overflow, so it can never scroll — containment there would be a no-op.
Verified in the built output: dist/assets/*.css contains both the prefers-reduced-motion media query and overscroll-behavior-y:contain.
Fixed in 9a896bb (merged as 3a57c0a).
- Global `prefers-reduced-motion: reduce` rule in `index.css` `@layer base` — collapses all animation/transition durations to 0.01ms, covering the kit's `data-open/closed` animations, `animate-pulse` skeletons, and the sidebar `transition-[width]` with one rule (and any future additions for free).
- `overscroll-y-contain` on `DrawerContent`, `SelectContent`, and `ComboboxPopup` (the scrollable surfaces), plus `AlertDialogContent` defensively for when it gains scrollable content.
- `MenuPopup` was skipped deliberately: it has no `max-height`/`overflow`, so it can never scroll — containment there would be a no-op.
Verified in the built output: `dist/assets/*.css` contains both the `prefers-reduced-motion` media query and `overscroll-behavior-y:contain`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
prefers-reduced-motion is not honored anywhere
grep -rn 'prefers-reduced-motion' web/src web/index.html→ zero hits. Every animation runs unconditionally for users who've asked the OS for reduced motion:data-open:animate-in …insrc/components/ui/)animate-pulseskeletonstransition-[width]expand/collapse (src/shell/sidebar.tsx)Simplest global fix in
src/index.css:(or the more surgical Tailwind
motion-safe:/motion-reduce:prefixes on thedata-open/data-closedanimation classes — the global rule is less churn and covers future additions.)Modal surfaces don't contain overscroll
grep -rn overscroll web/src→ zero hits. On touch devices, scrolling past the end of the drawer body or a scrollable dialog chains to the page beneath, breaking the modal illusion:web/src/components/ui/drawer.tsx— addoverscroll-y-containto theDrawerContentpopup (the detail drawer scrolls long object records).web/src/components/ui/alert-dialog.tsx— same onAlertDialogContent.web/src/components/ui/combobox.tsx/menu.tsx/select.tsxpopups (overflow-autolists) — same, so flicking past the end of a long term list doesn't scroll the page.Both changes are CSS-only inside
src/components/ui/, no bundle-size impact.Fixed in
9a896bb(merged as3a57c0a).prefers-reduced-motion: reducerule inindex.css@layer base— collapses all animation/transition durations to 0.01ms, covering the kit'sdata-open/closedanimations,animate-pulseskeletons, and the sidebartransition-[width]with one rule (and any future additions for free).overscroll-y-containonDrawerContent,SelectContent, andComboboxPopup(the scrollable surfaces), plusAlertDialogContentdefensively for when it gains scrollable content.MenuPopupwas skipped deliberately: it has nomax-height/overflow, so it can never scroll — containment there would be a no-op.Verified in the built output:
dist/assets/*.csscontains both theprefers-reduced-motionmedia query andoverscroll-behavior-y:contain.