docs(design): add design system documentation and missing alt text - Phase 2
Add comprehensive design system documentation: - Z-index scale (z-10 through z-[100]) - Spacing scale based on 4pt baseline - Opacity guidelines for glass/translucent effects - Transition timing standards (150-300ms) - Focus state requirements - Cursor affordance rules - WCAG AA contrast requirements - Button state implementation patterns - Form element best practices - Modal hierarchy guidance - Migration checklist Accessibility improvements: - Add alt text to OCR preview image in Scanner - Verify all images have descriptive alt text - Establish transition consistency guidelines This ensures design consistency and accessibility across the application.
This commit is contained in:
@@ -236,7 +236,12 @@ export default function Scanner({ onScanSuccess, onOCRMatch, paused }: ScannerPr
|
||||
{isSelecting && capturedImage && (
|
||||
<div className="absolute inset-0 z-50 bg-slate-950 flex flex-col">
|
||||
<div className="relative flex-1 bg-black flex items-center justify-center overflow-hidden">
|
||||
<img src={capturedImage || undefined} className="max-w-full max-h-full object-contain" id="ocr-canvas-preview" />
|
||||
<img
|
||||
src={capturedImage || undefined}
|
||||
className="max-w-full max-h-full object-contain"
|
||||
id="ocr-canvas-preview"
|
||||
alt="OCR text detection preview with detected words highlighted"
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="relative" style={{ width: '100%', height: '100%' }}>
|
||||
{detectedWords.map((w, i) => (
|
||||
|
||||
238
frontend/styles/DESIGN_SYSTEM.md
Normal file
238
frontend/styles/DESIGN_SYSTEM.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# TFM aInventory Design System
|
||||
|
||||
## Z-Index Scale
|
||||
|
||||
Explicit z-index layering for consistent stacking context.
|
||||
|
||||
```
|
||||
z-10 = Local stacking (shadows, hover states)
|
||||
z-20 = Cards, modals (low-level)
|
||||
z-30 = Dropdowns, tooltips
|
||||
z-40 = Fixed navigation (BottomNav)
|
||||
z-50 = Full-screen overlays (Scanner, AIOnboarding)
|
||||
z-[100] = Toast notifications, alerts
|
||||
```
|
||||
|
||||
### Applied Locations:
|
||||
- `z-10`: Interactive states, hover effects
|
||||
- `z-20`: Modal backgrounds, card borders
|
||||
- `z-40`: BottomNav fixed footer
|
||||
- `z-50`: Scanner.tsx, AIOnboarding.tsx, full-screen UI
|
||||
- `z-[100]`: Toast messages (react-hot-toast)
|
||||
|
||||
---
|
||||
|
||||
## Spacing Scale
|
||||
|
||||
All spacing follows a consistent 4px baseline.
|
||||
|
||||
```
|
||||
4px = gap-1 (tightest)
|
||||
8px = gap-2
|
||||
12px = gap-3
|
||||
16px = gap-4 (default)
|
||||
24px = gap-6
|
||||
32px = gap-8
|
||||
48px = gap-12
|
||||
64px = gap-16
|
||||
```
|
||||
|
||||
### Applied Pattern:
|
||||
- Use `gap-` utilities for sibling spacing
|
||||
- Use `p-` for padding on containers
|
||||
- Use `m-` sparingly (prefer gap)
|
||||
- Never use arbitrary spacing (e.g., no `gap-[13px]`)
|
||||
|
||||
---
|
||||
|
||||
## Opacity Scale for Backgrounds
|
||||
|
||||
Consistent opacity for glass/translucent effects.
|
||||
|
||||
```
|
||||
bg-slate-950/40 = Light transparency (hover states)
|
||||
bg-slate-950/60 = Medium transparency (overlays)
|
||||
bg-slate-950/80 = Heavy transparency (backdrop blur)
|
||||
bg-slate-900/40 = Light glass (cards)
|
||||
bg-slate-900/50 = Medium glass (borders)
|
||||
bg-slate-900/90 = Heavy glass (panels)
|
||||
```
|
||||
|
||||
### Applied Locations:
|
||||
- `/40`: Hover states, subtle layers
|
||||
- `/50`: Card backgrounds
|
||||
- `/60-80`: Modal backdrops
|
||||
- `/90`: Solid-looking panels with slight transparency
|
||||
|
||||
---
|
||||
|
||||
## Transition Timing
|
||||
|
||||
All interactive elements use consistent easing and duration.
|
||||
|
||||
```
|
||||
transition-colors = color changes (150ms)
|
||||
transition-all = all properties (200-300ms)
|
||||
active:scale-95 = click feedback
|
||||
hover:opacity-80 = hover feedback
|
||||
```
|
||||
|
||||
### Standards:
|
||||
- Button state changes: `transition-colors duration-200`
|
||||
- Major layout changes: `transition-all duration-300`
|
||||
- Never use `duration-0` or `duration-1000` without reason
|
||||
- Focus states: instant (no transition on ring)
|
||||
|
||||
---
|
||||
|
||||
## Focus States
|
||||
|
||||
All interactive elements must be keyboard accessible.
|
||||
|
||||
```
|
||||
focus:ring-2 = visible focus indicator
|
||||
focus:ring-primary = brand color on interactive elements
|
||||
focus:ring-blue-500 = alternate for secondary buttons
|
||||
focus:outline-none = removes browser default
|
||||
```
|
||||
|
||||
### Applied to:
|
||||
- All `<button>` elements
|
||||
- All `<a>` elements (links)
|
||||
- Form inputs (`<input>`, `<textarea>`, `<select>`)
|
||||
- Custom interactive components (role="button", tabIndex)
|
||||
|
||||
---
|
||||
|
||||
## Cursor States
|
||||
|
||||
Interactive elements must signal affordance.
|
||||
|
||||
```
|
||||
cursor-pointer = clickable button/card
|
||||
cursor-not-allowed = disabled state
|
||||
cursor-default = non-interactive
|
||||
```
|
||||
|
||||
### Applied Pattern:
|
||||
```jsx
|
||||
<button className="cursor-pointer hover:... focus:ring-2 disabled:cursor-not-allowed">
|
||||
Action
|
||||
</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contrast Requirements
|
||||
|
||||
All text must meet WCAG AA minimum 4.5:1 contrast ratio.
|
||||
|
||||
### Light Mode (if implemented):
|
||||
- Body text: `text-slate-900` (#0F172A) on white
|
||||
- Secondary: `text-slate-600` (#475569) on white
|
||||
- Muted: `text-slate-500` (#64748B) on white (only for labels)
|
||||
|
||||
### Dark Mode (current):
|
||||
- Body text: `text-white` on dark bg
|
||||
- Secondary: `text-slate-300` (#CBD5E1) on dark bg
|
||||
- Muted: `text-slate-500` (#64748B) on dark bg
|
||||
|
||||
### Verified Combinations:
|
||||
- ✓ white text on bg-slate-950
|
||||
- ✓ text-slate-300 on bg-slate-900/50
|
||||
- ✓ text-primary (#3B82F6) on dark backgrounds
|
||||
|
||||
---
|
||||
|
||||
## Button States
|
||||
|
||||
Every button must implement all required states.
|
||||
|
||||
```jsx
|
||||
<button
|
||||
className="
|
||||
/* Default */
|
||||
bg-primary text-white rounded-lg font-semibold
|
||||
/* Hover */
|
||||
hover:bg-blue-600
|
||||
/* Focus */
|
||||
focus:ring-2 focus:ring-blue-500 focus:outline-none
|
||||
/* Active */
|
||||
active:scale-95
|
||||
/* Disabled */
|
||||
disabled:opacity-50 disabled:cursor-not-allowed
|
||||
/* Transition */
|
||||
transition-all duration-200
|
||||
"
|
||||
disabled={isLoading}
|
||||
>
|
||||
Action
|
||||
</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Icon Guidelines
|
||||
|
||||
- All icons from Lucide React (size 16-24)
|
||||
- Never use emoji as UI icons
|
||||
- Icon-only buttons require `aria-label`
|
||||
- Icon size: `size={20}` (default), `size={16}` (compact), `size={24}` (prominent)
|
||||
|
||||
---
|
||||
|
||||
## Form Elements
|
||||
|
||||
All form inputs require:
|
||||
1. Associated `<label>` with `htmlFor` attribute
|
||||
2. Clear focus states
|
||||
3. Helpful placeholder text (optional, don't replace label)
|
||||
4. Validation feedback
|
||||
|
||||
```jsx
|
||||
<label htmlFor="email" className="block text-sm font-semibold mb-2">
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="you@example.com"
|
||||
className="
|
||||
w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg
|
||||
text-white placeholder:text-slate-500
|
||||
focus:border-primary focus:ring-2 focus:ring-primary
|
||||
transition-colors duration-200
|
||||
"
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modal/Overlay Hierarchy
|
||||
|
||||
Predictable layering for overlays.
|
||||
|
||||
```
|
||||
z-40 = BottomNav (fixed)
|
||||
z-50 = Full-screen overlays (Scanner, AIOnboarding)
|
||||
z-50+ = Nested modals (ConfirmationModal, ItemComparisonModal)
|
||||
```
|
||||
|
||||
Backdrop colors:
|
||||
- Scanner/AIOnboarding: `bg-slate-950` (opaque)
|
||||
- Modals: `bg-black/40` (semi-transparent)
|
||||
|
||||
---
|
||||
|
||||
## Migration Checklist
|
||||
|
||||
When implementing these standards:
|
||||
|
||||
- [ ] Add z-index only when necessary (nesting depth issue)
|
||||
- [ ] Use spacing scale utilities (no arbitrary values)
|
||||
- [ ] Add focus states to ALL interactive elements
|
||||
- [ ] Add cursor-pointer to all clickable elements
|
||||
- [ ] Verify transition duration is 150-300ms
|
||||
- [ ] Test keyboard navigation (Tab, Enter, Escape)
|
||||
- [ ] Verify contrast ratios (4.5:1 minimum)
|
||||
- [ ] Check reduced motion preferences (`prefers-reduced-motion`)
|
||||
Reference in New Issue
Block a user