Compare commits

...

1 Commits

Author SHA1 Message Date
cubecraft-agents[bot]
d93c6cd919 CUB-71: Add mobile-first design system document 2026-05-01 12:58:15 -04:00

View File

@@ -0,0 +1,517 @@
# Extrudex Mobile-First Design System
> **Project:** CUB-71 — Mobile-First Touch-Optimized UI Design
> **Parent:** CUB-67 — Extrudex Mobile-First PWA Implementation
> **Date:** 2026-05-01
> **Author:** Sketch
> **Status:** In Progress
---
## 1. Design Philosophy
### Mobile-First, Touch-Always
- **Minimum touch target:** 44×44px (Apple HIG) / 48×48dp (Material Design)
- **Thumb-friendly zones:** Primary actions in bottom 25% of screen
- **Gesture support:** Swipe, pull-to-refresh, pinch-to-zoom on relevant screens
- **One-handed use:** All critical actions reachable within thumb zone
### Workshop-Ready
- **High contrast:** WCAG AA minimum (4.5:1) — workshop lighting varies
- **Large text:** 16sp minimum body, 20sp+ for primary info
- **Glanceable:** Key info visible at arm's length (3ft)
- **Glove-compatible:** Larger tap targets for operators wearing work gloves
### Speed Over Complexity
- **Sub-second load:** Cached assets, skeleton screens
- **Minimal taps:** Every flow optimized for fewest interactions
- **Smart defaults:** Pre-filled forms based on context
---
## 2. Color System
### Primary Palette (Dark Theme — Default)
| Token | Hex | Usage |
|-------|-----|-------|
| `surface` | `#1C1B1F` | Screen background |
| `onSurface` | `#E6E1E5` | Primary text |
| `surfaceContainer` | `#211F26` | Cards, app bar |
| `surfaceContainerHigh` | `#2B2930` | Elevated cards |
| `primary` | `#A8CEDA` | FAB, active states, links |
| `onPrimary` | `#00303E` | Text on primary |
| `primaryContainer` | `#004D63` | Chip fills, tonal buttons |
| `onPrimaryContainer` | `#A8CEDA` | Text on primary container |
| `secondary` | `#B1CCC7` | Secondary actions |
| `error` | `#F2B8B5` | Critical stock, errors |
| `errorContainer` | `#8C1D18` | Error backgrounds |
| `warning` | `#FFD580` | Low stock warning |
| `warningContainer` | `#5D4200` | Warning backgrounds |
| `success` | `#8BD0A0` | Available, success states |
| `successContainer` | `#00522E` | Success backgrounds |
| `outline` | `#938F99` | Borders, dividers |
| `outlineVariant` | `#49454F` | Subtle borders |
### Light Theme (Optional)
| Token | Hex | Usage |
|-------|-----|-------|
| `surface` | `#F8FAFC` | Screen background |
| `surfaceContainer` | `#FFFFFF` | Cards |
| `primary` | `#2563EB` | Primary actions |
| `onSurface` | `#0F172A` | Primary text |
---
## 3. Typography Scale
### Mobile Type Scale
| Role | Token | Size | Weight | Line Height | Letter Spacing |
|------|-------|------|--------|-------------|----------------|
| Display Large | `displayLarge` | 57sp | 400 | 64sp | -0.25px |
| Display Medium | `displayMedium` | 45sp | 400 | 52sp | 0 |
| Headline Large | `headlineLarge` | 32sp | 400 | 40sp | 0 |
| Headline Medium | `headlineMedium` | 28sp | 400 | 36sp | 0 |
| Headline Small | `headlineSmall` | 24sp | 400 | 32sp | 0 |
| Title Large | `titleLarge` | 22sp | 400 | 28sp | 0 |
| Title Medium | `titleMedium` | 16sp | 500 | 24sp | 0.15px |
| Title Small | `titleSmall` | 14sp | 500 | 20sp | 0.1px |
| Body Large | `bodyLarge` | 16sp | 400 | 24sp | 0.5px |
| Body Medium | `bodyMedium` | 14sp | 400 | 20sp | 0.25px |
| Label Large | `labelLarge` | 14sp | 500 | 20sp | 0.1px |
| Label Medium | `labelMedium` | 12sp | 500 | 16sp | 0.5px |
| Label Small | `labelSmall` | 11sp | 500 | 16sp | 0.5px |
### Font Stack
```css
--font-sans: 'Inter', 'Roboto', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Roboto Mono', monospace;
```
---
## 4. Spacing System
### 8dp Grid Base
| Token | Value | Usage |
|-------|-------|-------|
| `space-1` | 4dp | Tight padding, icon gaps |
| `space-2` | 8dp | Default gap, small padding |
| `space-3` | 12dp | Card padding (compact) |
| `space-4` | 16dp | Standard padding, section gaps |
| `space-5` | 20dp | Large padding |
| `space-6` | 24dp | Section margins, hero padding |
| `space-8` | 32dp | Large section gaps |
| `space-10` | 40dp | Major section spacing |
| `space-12` | 48dp | Touch target minimum |
| `space-16` | 64dp | App bar height |
### Border Radius
| Token | Value | Usage |
|-------|-------|-------|
| `radius-sm` | 4dp | Small buttons, chips |
| `radius-md` | 8dp | Cards, inputs |
| `radius-lg` | 12dp | Modals, bottom sheets |
| `radius-xl` | 16dp | Large cards, dialogs |
| `radius-full` | 9999px | Pills, circular elements |
---
## 5. Component Specifications
### 5.1 Bottom Navigation Bar
**Height:** 80dp
**Background:** `surfaceContainer` with 1dp top outline
**Layout:** 4-5 icon+label items, evenly distributed
**Active state:** Icon filled + `primary` color, label `primary`
**Inactive state:** Icon outlined + `onSurfaceVariant` color
**Touch target:** Full 80dp height, icon+label centered
```
┌─────────────────────────────────────┐
│ 📦 🖨️ 📋 ⚙️ │
│Inventory Printers Jobs Settings │
└─────────────────────────────────────┘
```
**Destinations:**
- Inventory (spools list) — default active
- Printers (printer fleet status)
- Jobs (print job history)
- Settings (app configuration)
---
### 5.2 QR Scanner Interface
**Layout:** Full-bleed camera viewport with overlay
```
┌─────────────────────────────────────┐
│ ✕ Scan Spool [⚡] │ ← App Bar (56dp)
├─────────────────────────────────────┤
│ │
│ ┌─────────────────────────────┐ │
│ │ │ │
│ │ ┌───────────────────┐ │ │
│ │ │ ╔═══════════════╗ │ │ │
│ │ │ ║ ▄▄▄▄▄▄▄▄▄▄▄ ║ │ │ │
│ │ │ ║ █ VIEWPORT █ ║ │ │ │
│ │ │ ║ █ FRAME █ ║ │ │ │
│ │ │ ║ ▀▀▀▀▀▀▀▀▀▀▀ ║ │ │ │
│ │ │ ║ (scan line) ║ │ │ │
│ │ └───────────────────┘ │ │
│ │ │ │
│ │ LIVE CAMERA FEED │ │
│ │ │ │
│ └─────────────────────────────┘ │
│ │
│ [Last scan: 8901234567890] │
│ │
│ Can't scan? Enter manually │
│ │
└─────────────────────────────────────┘
```
**Elements:**
- **Camera viewport:** Full width, 60% screen height, `surfaceContainerHighest` background before camera starts
- **Scanning frame:** 200dp × 120dp centered, corner brackets (3dp stroke, `primary`)
- **Scan line:** Horizontal 2dp line, sweeps top→bottom (2s cycle), `primary` at 40% opacity
- **Scan result chip:** Appears below viewport, monospace text, auto-advances in 1.5s
- **Manual entry:** Text button fallback
**States:**
| State | Visual |
|-------|--------|
| Initializing | Shimmer loading + "Starting camera…" |
| Ready | Live feed + animated scan line |
| Scanning | Frame flashes `success` green |
| No match | Frame flashes `warning` yellow |
| Camera denied | Error card + "Enter manually" button |
---
### 5.3 Spool Detail View (Mobile)
**Layout:** Scrollable vertical stack
```
┌─────────────────────────────────────┐
│ ← PLA Basic — Matte Black [✏] │ ← App Bar
├─────────────────────────────────────┤
│ │
│ ┌──────┐ │
│ │SWATCH│ PLA Basic — Matte │
│ │ 80dp │ Black [Avail] │
│ └──────┘ Bambu Lab │
│ │
│ ◉ 842g / 1000g (67%) │ ← Circular progress
│ │
├─────────────────────────────────────┤
│ Total Weight │ Remaining │
│ 1,000g │ 842g (67%) │
├─────────────────────────────────────┤
│ Diameter │ Density │
│ 1.75mm │ 1.24 g/cm³ │
├─────────────────────────────────────┤
│ Date Added │ Last Used │
│ Mar 12, 2026 │ Apr 18, 2026 │
├─────────────────────────────────────┤
│ 📍 AMS Unit 2, Slot A3 [Move] │
├─────────────────────────────────────┤
│ ┌──────────┐ │
│ │ QR CODE │ │
│ │ 160dp │ EXT-2026-PLA-0042 │
│ └──────────┘ [Reprint] │
├─────────────────────────────────────┤
│ Recent Usage │
│ Print #1847 — Benchy -32g │
│ Print #1842 — Housing -18g │
│ [View Full History →] │
├─────────────────────────────────────┤
│ │
│ [Depleted] [Move] [Print] │ ← Sticky action row
│ │
├─────────────────────────────────────┤
│ 📦 🖨️ 📋 ⚙️ │ ← Bottom nav
└─────────────────────────────────────┘
```
**Hero Section:**
- Color swatch: 80dp circle, `outlineVariant` border
- Material name: `headlineMedium` (28sp)
- Brand: `bodyLarge` (16sp), `onSurfaceVariant`
- Status badge: Tonal chip
- Circular progress: 96dp diameter, dynamic color based on percentage
**Metrics Grid:**
- 2-column grid on mobile, 3-column on kiosk
- Label: `labelMedium` (12sp)
- Value: `titleMedium` (16sp)
**Action Row (Sticky):**
- Height: 64dp minimum
- Buttons: 48dp height minimum
- Deplete: Outlined, `error` color
- Move: Tonal, `secondary` color
- Print: Filled, `primary` color
---
### 5.4 Print-Log Form (Quick Entry)
**Layout:** Bottom sheet or full-screen
```
┌─────────────────────────────────────┐
│ ✕ Log Print Usage │
├─────────────────────────────────────┤
│ │
│ Spool: PLA Basic — Matte Black │
│ Remaining: 842g │
│ │
│ Weight Used │
│ ┌─────────────────────────────┐ │
│ │ [] 32 [+] grams │ │ ← Stepper
│ └─────────────────────────────┘ │
│ │
│ Quick: [10] [25] [50] [100] │
│ │
│ Print Job (optional) │
│ ┌─────────────────────────────┐ │
│ │ Select or enter job name... │ │
│ └─────────────────────────────┘ │
│ │
│ Notes (optional) │
│ ┌─────────────────────────────┐ │
│ │ ... │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ ✓ Log Print (842→810g) │ │
│ └─────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
**Design Principles:**
- **Number pad first:** Show numeric keyboard by default
- **Quick-select chips:** Common values (10g, 25g, 50g, 100g)
- **Stepper control:** ± buttons flanking input
- **Live preview:** Show remaining weight after deduction
- **Single-tap complete:** Primary action always visible
---
### 5.5 Status Badges
| Status | Background | Text | Icon |
|--------|-----------|------|------|
| Available | `successContainer` | `success` | check_circle |
| In Use | `primaryContainer` | `primary` | print |
| Low Stock | `warningContainer` | `warning` | warning |
| Critical | `errorContainer` | `error` | error |
| Depleted | `errorContainer` | `error` | remove_circle |
---
### 5.6 Touch Targets & Accessibility
**Minimum Sizes:**
- Interactive elements: 48×48dp
- List items: 56dp height minimum
- Buttons: 48dp height, 88dp minimum width
- Chips: 32dp height, 48dp minimum width
- Input fields: 56dp height
**Focus States:**
- 2dp outline, `primary` color, 2dp offset
- Visible on keyboard navigation
**Motion:**
- Respect `prefers-reduced-motion`
- Disable animations when set
- Use opacity fades instead of transforms
---
## 6. Responsive Breakpoints
| Breakpoint | Width | Target |
|-----------|-------|--------|
| Compact | 0-599dp | Mobile phones |
| Medium | 600-839dp | Large phones, small tablets |
| Expanded | 840-1199dp | Tablets, small desktops |
| Large | 1200dp+ | Desktops, kiosks |
### Layout Adaptations
| Property | Compact (Mobile) | Large (Kiosk) |
|----------|-----------------|---------------|
| Navigation | Bottom bar (80dp) | Rail (80dp, left) |
| Content padding | 16dp | 24dp |
| Grid columns | 1-2 | 2-3 |
| Card padding | 16dp | 20dp |
| Typography scale | Standard | +10% for distance viewing |
| Touch targets | 48dp | 56dp (glove-friendly) |
---
## 7. Animation & Motion
### Principles
- **Purposeful:** Every animation guides attention or provides feedback
- **Fast:** 200-300ms standard duration
- **Easing:** `ease-out` for entrances, `ease-in-out` for transitions
### Patterns
| Animation | Duration | Easing | Use Case |
|-----------|----------|--------|----------|
| Slide in | 300ms | ease-out | Screen transitions |
| Fade | 200ms | ease-in-out | Modal/dialog |
| Scale | 200ms | ease-out | Button presses |
| Shimmer | 1.5s | linear | Loading skeletons |
| Pulse | 2s | ease-in-out | Scan line, critical alerts |
| Progress | 600ms | ease-out | Circular progress fill |
### Interaction Feedback
- **Button press:** Scale to 0.96, 100ms
- **Chip select:** Background color transition, 150ms
- **List item tap:** Ripple effect, `primary` at 12% opacity
- **Success:** Green flash + haptic (mobile)
- **Error:** Red flash + shake animation
---
## 8. Assets & Icons
### Icon Set
- **Library:** Material Symbols (rounded)
- **Size:** 24dp default, 20dp in dense areas
- **Weight:** 400 (regular), filled for active states
### Required Icons
| Icon | Name | Usage |
|------|------|-------|
| 📦 | inventory_2 | Inventory nav |
| 🖨️ | print | Printers nav |
| 📋 | assignment | Jobs nav |
| ⚙️ | settings | Settings nav |
| ✕ | close | Close/dismiss |
| ← | arrow_back | Navigate back |
| ✏ | edit | Edit action |
| 🔍 | search | Search toggle |
| + | add | Add/create |
| 🗑 | delete | Delete action |
| 📷 | photo_camera | Scan action |
| ⚠ | warning | Warning states |
| ✓ | check_circle | Success states |
| 📍 | location_on | Location |
| 📶 | signal_cellular_alt | SignalR status |
---
## 9. Developer Handoff Checklist
- [x] Color tokens defined (dark theme)
- [x] Typography scale specified
- [x] Spacing system documented
- [x] Component specifications written
- [x] Touch targets validated (≥48dp)
- [x] Responsive breakpoints defined
- [x] Animation patterns documented
- [x] Icon set specified
- [ ] Mockup images generated (blocked — image generation unavailable)
- [ ] Figma/Sketch file created (optional)
- [ ] Design tokens exported to CSS/SCSS
---
## 10. Implementation Notes for Rex
### Priority Order
1. Bottom navigation component
2. QR scanner interface (camera + overlay)
3. Spool detail view (scrollable)
4. Print-log form (bottom sheet)
5. Status badges and indicators
### Angular Material Components Needed
```typescript
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatToolbarModule } from '@angular/material/toolbar';
```
### QR Scanning Libraries
- **Mobile:** `html5-qrcode` or `@zxing/browser`
- **Camera access:** `navigator.mediaDevices.getUserMedia({ facingMode: 'environment' })`
### Key Files to Create
```
frontend/src/app/
├── components/
│ ├── bottom-nav/
│ │ ├── bottom-nav.component.ts
│ │ ├── bottom-nav.component.html
│ │ └── bottom-nav.component.scss
│ ├── qr-scanner/
│ │ ├── qr-scanner.component.ts
│ │ ├── qr-scanner.component.html
│ │ └── qr-scanner.component.scss
│ ├── spool-detail/
│ │ ├── spool-detail.component.ts
│ │ ├── spool-detail.component.html
│ │ └── spool-detail.component.scss
│ └── print-log-form/
│ ├── print-log-form.component.ts
│ ├── print-log-form.component.html
│ └── print-log-form.component.scss
├── design-system/
│ ├── _colors.scss
│ ├── _typography.scss
│ ├── _spacing.scss
│ └── _mixins.scss
└── models/
└── mobile-ui.model.ts
```
---
## 11. File Locations
| File | Path | Purpose |
|------|------|---------|
| Design System | `design/mobile-design-system.md` | This document |
| Inventory Spec | `design/01-filament-inventory-list.md` | Existing — inventory screen |
| Spool Detail Spec | `design/02-spool-detail-view.md` | Existing — detail screen |
| Smart Intake Spec | `design/03-smart-intake-workflow.md` | Existing — intake flow |
| Identify Spec | `design/smart-intake-identify-spec.md` | Existing — identify state |
| Mockup Images | `design/mockup-*.png/jpg` | Visual references |
---
**Next Steps:**
1. Review design system with stakeholders
2. Generate mockup images (when image generation is available)
3. Export design tokens to SCSS
4. Hand off to Rex for implementation
5. Create interactive prototype (optional)
**Status:** Design system document complete. Ready for implementation handoff.