---
description: "UI/UX standards for LegacyApp — always applied"
alwaysApply: true
---

# UI / UX Standards — LegacyApp

## 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

