54c66efe9b
- Changed CLI usage instructions from `dart run cursor_gen` to `cursor_gen` for global activation. - Updated project-brief.yaml example and README to reflect new command usage. - Added app_context section in project-brief.yaml for theme variants and RBAC roles. - Fixed bundled template resolution for local and global installs to prevent 'Template not found' errors. - Version bump to 1.0.1 with corresponding updates in CHANGELOG and pubspec.yaml.
49 lines
2.3 KiB
Cheetah
49 lines
2.3 KiB
Cheetah
---
|
||
description: "UI/UX standards for {{PROJECT_NAME}} — always applied"
|
||
alwaysApply: true
|
||
---
|
||
|
||
# UI / UX Standards — {{PROJECT_NAME}}
|
||
|
||
## Theme & design tokens (single source of truth)
|
||
- Define **one** light/dark `ThemeData` (and optional `ThemeExtension`s for brand spacing, radii, semantic colors). Feature code reads `Theme.of(context)` only.
|
||
- **Colors:** `colorScheme` / extensions — never hex/`Color(...)` literals in widgets except inside the theme definition file(s).
|
||
- **Typography:** `textTheme` / `primaryTextTheme` — never raw `TextStyle(fontSize:, fontFamily:)` in feature UI.
|
||
- **Spacing & shapes:** `ThemeExtension` or documented constants consumed consistently — avoid one-off magic numbers for padding/radius.
|
||
|
||
## 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
|
||
{{HIGH_CONTRAST_UX_LINE}}
|