Files
tfm_ainventory/frontend/styles/DESIGN_SYSTEM.md
Daniel Bedeleanu efd8efb6ec 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.
2026-04-17 13:00:41 +03:00

5.5 KiB

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:

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

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