From d93c6cd9195a6d49278e45e6a63555dfc008242f Mon Sep 17 00:00:00 2001 From: "cubecraft-agents[bot]" <3458173+cubecraft-agents[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 12:58:15 -0400 Subject: [PATCH] CUB-71: Add mobile-first design system document --- design/mobile-design-system.md | 517 +++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 design/mobile-design-system.md diff --git a/design/mobile-design-system.md b/design/mobile-design-system.md new file mode 100644 index 0000000..9aaf41f --- /dev/null +++ b/design/mobile-design-system.md @@ -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. \ No newline at end of file