42 lines
1.7 KiB
Cheetah
42 lines
1.7 KiB
Cheetah
---
|
||
description: "UI/UX standards for {{PROJECT_NAME}} — always applied"
|
||
alwaysApply: true
|
||
---
|
||
|
||
# UI / UX Standards — {{PROJECT_NAME}}
|
||
|
||
## Loading states
|
||
- Every async operation MUST show a loading skeleton (shimmer), NOT a spinner unless < 300ms
|
||
- Use `shimmer` package with a shimmer that matches the final layout shape
|
||
- Never show a blank screen during loading — skeleton must fill the same space as the content
|
||
|
||
## Empty states
|
||
- Every list/grid MUST have a distinct empty state widget: illustration + headline + CTA
|
||
- Empty state is different from error state — never reuse the same widget for both
|
||
- Empty state copy: positive framing ("No items yet — add your first one")
|
||
|
||
## Error states
|
||
- Every async failure MUST show: error message + retry button
|
||
- Never swallow errors silently
|
||
- Error text: user-friendly, never expose stack traces or raw API messages
|
||
|
||
## Navigation & transitions
|
||
- Use `IndexedStack` for bottom nav tabs — preserves scroll position
|
||
- Named routes only — never `Navigator.push(context, MaterialPageRoute(...))`
|
||
- Page transitions: use `CustomTransitionPage` with `FadeTransition` for modal sheets
|
||
|
||
## Responsive layout
|
||
- Use `LayoutBuilder` or `MediaQuery` for breakpoints, not hardcoded pixel values
|
||
- Minimum touch target: 48×48 logical pixels (Material guideline)
|
||
- Test on 375px (iPhone SE) and 414px (iPhone Pro Max) widths minimum
|
||
|
||
## Haptics
|
||
- Use `HapticFeedback.lightImpact()` on primary CTAs
|
||
- Use `HapticFeedback.selectionClick()` on toggle/checkbox interactions
|
||
- Never add haptics to destructive actions without confirmation
|
||
|
||
## Accessibility
|
||
- All interactive widgets must have a `Semantics` label or `tooltip`
|
||
- Minimum contrast ratio: 4.5:1 (WCAG AA)
|
||
- Test with TalkBack / VoiceOver before each release
|