# Smart Intake Workflow — Screen Specification > **Screen ID:** FIL-003 > **Source of Truth:** [Material Design 3](https://m3.material.io/) > **Tone:** Modern Industrial/Maker > **Theme:** Dark Mode, High-Contrast > **Last Updated:** 2026-04-20 --- ## 1. Objective Design the primary filament intake experience — the "Smart Intake" workflow — optimized for both the kiosk (USB barcode scanner + touchscreen) and the mobile PWA (device camera + touch). This is the **most critical user flow** in Extrudex: every new spool enters the system through this workflow. The workflow follows a strict **3-state linear progression**: ``` SCAN ──→ IDENTIFY ──→ UPDATE ──→ ✓ Complete ``` Users must be able to: - **Scan:** Capture a barcode/QR code via camera (mobile) or USB scanner (kiosk). - **Identify:** Confirm or correct the scanned spool's identity (material, brand, color). - **Update:** Set initial weight and status, assign a location, and complete intake. The workflow must feel **fast, confident, and forgiving** — operators process many spools in a session and can't afford friction or ambiguity at any step. --- ## 2. Screen Inventory ### Shared Across All States | Element | MD3 Component | Notes | |---------|--------------|-------| | Top App Bar | `md-top-app-bar` (small) | Title + close/dismiss | | Step Indicator | Custom linear stepper | 3 dots/steps with active state | | Bottom Sheet | `md-bottom-sheet` | Contextual info/errors on mobile | ### Scan State (State 1 of 3) | Element | MD3 Component | Notes | |---------|--------------|-------| | Camera Viewport | Custom + `video` element | Full-bleed camera with scanning overlay | | Viewport Frame | Custom overlay | Animated scanning rectangle | | Scan Result Chip | `md-chip` (assist) | Shows last scanned code | | Manual Entry Link | `md-text-button` | Fallback for unreadable codes | | USB Scanner Badge | `md-chip` (status) | Kiosk only — "Scanner Connected ✓" | ### Identification State (State 2 of 3) | Element | MD3 Component | Notes | |---------|--------------|-------| | Spool Identity Card | `md-card` (filled) | Material, brand, color display | | Confidence Indicator | Custom bar | Match confidence (High/Medium/Low/Unknown) | | Material Selector | `md-dropdown-select` | If multiple matches or no match | | Brand Selector | `md-dropdown-select` | Brand selection | | Color Picker | Custom swatch grid | Filament color selection | | Finish + Modifier | `md-chip-set` (choice) | Material finish and modifier | | "Confirm" Button | `md-filled-button` | Primary CTA — proceed to Update | | "Rescan" Button | `md-outlined-button` | Go back to Scan state | ### Update State (State 3 of 3) | Element | MD3 Component | Notes | |---------|--------------|-------| | Weight Input | `md-filled-text-field` + stepper | Grams input with +/- buttons | | Location Selector | `md-dropdown-select` | Assign to AMS slot or shelf | | Status Toggle | `md-chip-set` (choice) | Available / In Use | | QR Preview | `md-card` | Generated QR code preview | | "Complete Intake" Button | `md-filled-button` | Primary CTA — finalize | | "Print Label" Toggle | `md-switch` | Auto-print QR label on completion | | Summary Card | `md-card` (outlined) | Final summary before submission | --- ## 3. Layout Specification ### Shared Layout #### Top App Bar (56dp mobile / 64dp kiosk) - **Leading:** Close (✕) → returns to Inventory List with unsaved-work confirmation if mid-flow - **Title:** "Smart Intake" (all states) - **Trailing:** None (deliberate — no distractions during intake) #### Step Indicator (40dp, below App Bar) ``` ● ───── ○ ───── ○ Scan Identify Update ``` - 3-step linear indicator - Active step: `primary` filled circle + `primary` connecting line - Completed step: `primary` filled circle + checkmark icon - Future step: `outline` circle + `outlineVariant` connecting line - Labels: `labelSmall` below each dot - Animation: Line fills with `primary` color as each step completes (300ms ease-out) --- ### STATE 1: SCAN **Title:** "Scan Spool" #### Layout — Mobile (Camera-based) ``` ┌──────────────────────────────────┐ │ ✕ Smart Intake │ │──────────────────────────────────│ │ ● ──── ○ ──── ○ │ │ Scan Identify Update │ │──────────────────────────────────│ │ │ │ ┌──────────────────────────┐ │ │ │ │ │ │ │ ┌────────────────┐ │ │ │ │ │ ╔════════════╗│ │ │ │ │ │ ║ VIEWPORT ║│ │ │ │ │ │ ║ FRAME ║│ │ │ │ │ │ ║ (animated) ║│ │ │ │ │ │ ╚════════════╝│ │ │ │ │ │ │ │ │ │ │ │ ▲ Align barcode │ │ │ │ │ │ within frame │ │ │ │ │ └────────────────┘ │ │ │ │ │ │ │ │ LIVE CAMERA FEED │ │ │ │ │ │ │ └──────────────────────────┘ │ │ │ │ [Last scan: 8901234567890] │ │ │ │ Can't scan? Enter manually │ │ │ └──────────────────────────────────┘ ``` - **Camera viewport:** Full-bleed video feed with 16:9 or 4:3 aspect ratio - **Scanning frame:** Animated rectangle (200dp × 120dp) centered in viewport - Corner brackets: `primary` color, 24dp corner length, 3dp stroke - Scan line: Horizontal `primary` line that sweeps top-to-bottom repeatedly (2s cycle) - On successful scan: Frame flashes `success` color (green) + brief haptic (mobile) - **Instruction text:** Below frame, `bodyMedium`, `onSurfaceVariant` - **Scan result chip:** Appears below camera when a code is detected - Shows scanned code value in monospace - Auto-advances to Identification state after 1.5s (with option to cancel) - **Manual entry link:** Text button below camera area for fallback #### Layout — Kiosk (USB Scanner-based) ``` ┌──────┬──────────────────────────────────────────────┐ │ NAV │ ✕ Smart Intake │ │ RAIL │──────────────────────────────────────────────│ │ │ ● ──── ○ ──── ○ │ │ │ Scan Identify Update │ │ │──────────────────────────────────────────────│ │ │ │ │ │ ┌──────────────────────┐ │ │ │ │ │ │ │ │ │ 📷 SCANNER READY │ │ │ │ │ │ │ │ │ │ USB Scanner: ✓ │ │ │ │ │ │ │ │ │ │ Scan a barcode or │ │ │ │ │ QR code now... │ │ │ │ │ │ │ │ │ │ ═══════════════ │ │ │ │ │ (pulse animation) │ │ │ │ │ │ │ │ │ └──────────────────────┘ │ │ │ │ │ │ Or: [Enter Barcode Manually] │ │ │ │ └──────┴──────────────────────────────────────────────┘ ``` - **No camera on kiosk** — USB HID barcode scanner is the primary input - **Scanner status card:** Shows connected/disconnected state - Connected: `success` icon + "Scanner Connected ✓" - Disconnected: `error` icon + "Scanner Not Found" + "Troubleshoot" button - **Pulse animation:** A horizontal line that pulses `primary` to indicate "waiting for scan" - **On scan:** The scanned code appears in a chip, auto-advances to Identification - **Manual entry:** Full keyboard (virtual) for typing barcode numbers #### Scan State Elements | Element | Description | |---------|-------------| | Primary CTA | None (scanning is automatic) — the camera/scanner IS the CTA | | Secondary Actions | Manual entry, close/dismiss | | Key Components | Camera viewport, scanning frame animation, scanner status (kiosk), scan result chip | | States | See below | | State | Visual | |-------|--------| | **Initializing camera** | Shimmer loading in viewport + "Starting camera…" label | | **Ready (waiting for scan)** | Live feed + animated scan line + "Align barcode within frame" | | **Scanning (code detected)** | Frame flashes green + scan result chip appears + "Identified!" text | | **No match found** | Frame flashes yellow + chip + "Unknown barcode" → still advances to Identify (manual) | | **Camera denied** | Error card: "Camera access denied" + "Enter manually" button + permission settings link | | **Scanner disconnected (kiosk)** | Error card: "Scanner not detected" + "Reconnect scanner" + "Enter manually" | | **Multiple codes detected** | Shows list of detected codes as selectable chips → user picks correct one | --- ### STATE 2: IDENTIFY **Title:** "Identify Spool" #### Layout (Both platforms) ``` ┌──────────────────────────────────┐ │ ✕ Smart Intake │ │──────────────────────────────────│ │ ✓ ────● ──── ○ │ │ Scan Identify Update │ │──────────────────────────────────│ │ │ │ ┌──────────────────────────┐ │ │ │ Scanned: 8901234567890 │ │ │ │ Match: HIGH CONFIDENCE │ │ │ │ ▓▓▓▓▓▓▓▓▓▓▓▓░░ 92% │ │ │ └──────────────────────────┘ │ │ │ │ Material │ │ ┌──────────────────────────┐ │ │ │ PLA Basic ▾│ │ │ └──────────────────────────┘ │ │ │ │ Brand │ │ ┌──────────────────────────┐ │ │ │ Bambu Lab ▾│ │ │ └──────────────────────────┘ │ │ │ │ Color │ │ ● ● ● ● ● ● ● ● ● [Custom] │ │ Bla Red Blu Grn Yel Org Pur Wh │ │ │ │ Finish Modifier │ │ [Basic][Matte][Silk] [None] │ │ │ │ [Rescan] [Confirm →] │ │ │ └──────────────────────────────────┘ ``` #### Confidence Indicator A horizontal bar showing match confidence from the barcode lookup: | Confidence | Visual | Color | Behavior | |-----------|--------|-------|----------| | **High** (≥80%) | Full green bar | `success` | Pre-fills all fields; user just confirms | | **Medium** (40-79%) | Yellow bar | `warning` | Pre-fills material/brand; color may need correction | | **Low** (<40%) | Orange bar | Custom orange | Pre-fills partial; more fields need manual input | | **Unknown** (0%) | Red bar | `error` | "Barcode not found" — all fields manual | #### Material Selector - `mat-select` dropdown with searchable options - Options sourced from normalized taxonomy (MaterialBase list) - If confidence is High: pre-selected, field is in confirmed state (slight green tint) - If confidence is Low/Unknown: field is empty, highlighted for input #### Brand Selector - `mat-select` dropdown with common brands - Searchable with "Other…" option that allows free-text entry #### Color Picker - **Swatch grid:** 2 rows of circular color swatches (24dp each) - Common colors: Black, White, Red, Blue, Green, Yellow, Orange, Purple, Grey, Brown, Pink, Transparent - Tap swatch → selected (ring indicator) - "Custom" option → opens free-text color name input - Selected color stored as both name + hex value #### Finish + Modifier Chips - **Finish (required):** `mat-chip-listbox` with single-select - Options: Basic, Matte, Silk, Sparkle, Metallic, Translucent - Default: "Basic" - **Modifier (optional):** `mat-chip-listbox` with single-select - Options: None, Carbon Fiber, Wood Fill, Glow-in-Dark, Marble, Gradient - Default: "None" #### Identify State Elements | Element | Description | |---------|-------------| | Primary CTA | **"Confirm"** filled button → advances to Update state | | Secondary Actions | **"Rescan"** outlined button → returns to Scan state | | Key Components | Confidence bar, Material dropdown, Brand dropdown, Color picker grid, Finish chips, Modifier chips | | Validation | Material and Brand are required. Color is required. Confirm button disabled until all required fields filled. | --- ### STATE 3: UPDATE **Title:** "Update Spool" #### Layout (Both platforms) ``` ┌──────────────────────────────────┐ │ ✕ Smart Intake │ │──────────────────────────────────│ │ ✓ ────✓ ──── ● │ │ Scan Identify Update │ │──────────────────────────────────│ │ │ │ Initial Weight │ │ ┌──────────────────────────┐ │ │ │ [-] 1000 [+] grams │ │ │ └──────────────────────────┘ │ │ Quick: [250] [500] [750] [1000] │ │ │ │ Assign Location │ │ ┌──────────────────────────┐ │ │ │ Select location... ▾│ │ │ └──────────────────────────┘ │ │ │ │ Status │ │ [● Available] [○ In Use] │ │ │ │ ┌──────────────────────────┐ │ │ │ Summary │ │ │ │ PLA Basic - Matte Black │ │ │ │ Bambu Lab • 1000g │ │ │ │ AMS 2, Slot A3 • Avail │ │ │ │ ID: EXT-2026-PLA-0043 │ │ │ │ │ │ │ │ ┌──────┐ Print Label │ │ │ │ │ QR │ [═══●═══] ON │ │ │ │ │Preview│ │ │ │ │ └──────┘ │ │ │ └──────────────────────────┘ │ │ │ │ [◀ Back] [✓ Complete Intake] │ │ │ └──────────────────────────────────┘ ``` #### Weight Input - **Stepper control:** Number input flanked by – and + buttons - Step size: 50g (adjustable via long-press to 10g/100g) - Minimum: 50g, Maximum: 5000g - Direct numeric keyboard input also available - **Quick-select chips:** Common spool sizes (250g, 500g, 750g, 1000g) — tap to set weight instantly - Active chip: `primaryContainer` fill - On kiosk: Larger chips (48dp height) for easy tapping - **Unit label:** "grams" suffix, non-editable, `onSurfaceVariant` #### Location Selector - `mat-select` dropdown organized hierarchically: - **AMS Units** → Slot A1, A2, A3, A4 - **External Holders** → Shelf B1, B2, B3 - **Unassigned** (default) - Only shows available (unoccupied) locations - Selected location shows printer/host info as hint text #### Status Toggle - `mat-chip-listbox` single-select: - **Available** (default): Green tonal chip + "Available" label - **In Use**: Blue tonal chip + "In Use" label - Most new spools are "Available" on intake — this is the safe default #### Summary Card - **Outlined card** showing all intake details for final review: - Material name, brand, weight, location, status, tracking ID - QR code preview (small, 80dp) — auto-generated from tracking ID - "Print Label" toggle switch (default: ON on kiosk, OFF on mobile) - When ON: Bluetooth thermal printer will produce label after completion - Kiosk default ON because label printer is always connected - Mobile default OFF because printer may not be available #### Update State Elements | Element | Description | |---------|-------------| | Primary CTA | **"Complete Intake"** filled button → finalizes spool creation | | Secondary Actions | **"Back"** outlined button → returns to Identify state | | Key Components | Weight stepper, Quick-select chips, Location dropdown, Status toggle, Summary card, Print label switch, QR preview | | Validation | Weight is required (>0). Location is optional. Confirm button always enabled once weight is set. | #### Completion Flow 1. User taps "Complete Intake" 2. API call creates spool record 3. If "Print Label" is ON: send QR to thermal printer 4. **Success state:** Step indicator animates all 3 steps complete + confetti-free success animation + "Spool Added ✓" snackbar 5. **Two options appear:** - "Add Another Spool" → resets to Scan state (fastest path for batch intake) - "View Spool" → navigates to Spool Detail View for the newly created spool 6. Auto-return to Inventory List after 10s if no action taken (kiosk only — prevents abandoned sessions) ### States | State | Visual | |-------|--------| | **Default** | All fields at defaults, "Complete Intake" enabled once weight is set | | **Weight invalid** | Error text "Enter a weight between 50g and 5000g", button disabled | | **Location unavailable** | Dropdown shows "No available locations" + "Add as Unassigned" option | | **Submitting** | "Complete Intake" shows `mat-spinner` inline, disabled. Other elements non-interactive. | | **Success** | Green check animation, "Spool Added ✓", two option buttons | | **Error (API)** | Error snackbar + "Retry" action button. Form state preserved. | | **Error (Printer)** | Success still shows, but printer error snackbar: "Label print failed — reprint from spool detail" | --- ## 4. UX Rationale ### Scan State 1. **Camera-first on mobile.** The phone's camera is the fastest barcode scanner available. No typing, no selecting — just point and scan. The animated viewport frame provides clear guidance on where to aim. 2. **USB scanner-first on kiosk.** The kiosk doesn't need a camera — the USB HID scanner is faster and more reliable than camera-based scanning. The "Scanner Ready" state gives immediate confidence that the hardware is working. 3. **Auto-advance after scan.** When a barcode is detected, the system should advance automatically. The 1.5s delay lets the user see what was scanned, but doesn't require a manual "next" tap. Speed matters when processing 20 spools in a row. 4. **Manual entry always available.** Barcodes get damaged. Camera angles are sometimes wrong. The manual fallback prevents workflow dead-ends. ### Identification State 5. **Confidence indicator reduces anxiety.** When a barcode is scanned, the user needs to know: "Did the system recognize this?" The confidence bar answers this instantly. High confidence → "just confirm." Low confidence → "you'll need to fill in details." This sets expectations. 6. **Pre-fill everything possible.** If the barcode matches a known product (UPC database or previous spools), pre-fill material, brand, and color. The user should confirm, not construct. Every pre-filled field is saved time. 7. **Color as swatches, not dropdown.** Filament color is visual — selecting from a text dropdown ("Red" vs "Crimson" vs "Scarlet") is ambiguous. Circular swatches are unambiguous and faster to scan. 8. **Finish/Modifier as chips.** These are small, mutually exclusive option sets. Chips are more glanceable and tappable than dropdowns for 2-6 options. ### Update State 9. **Weight stepper + quick-select.** Operators know spool weights (they're standard sizes). Quick-select chips (250g, 500g, 750g, 1000g) cover 90% of cases in a single tap. The stepper handles the remaining 10% where weight is non-standard. 10. **Location as optional.** New spools may not be immediately assigned to a printer. Forcing location assignment would create friction — some operators prefer to intake first, assign later. 11. **Summary card for confidence.** Before committing, the user sees everything in one place. This is the "receipt" pattern — it catches errors before they become data problems. The QR preview is especially important: operators verify the physical label will match. 12. **"Add Another" as primary post-completion action.** In a batch intake session (which is common), the operator wants to immediately scan the next spool. "Add Another" should be the most prominent post-completion option. 13. **Print label default differs by platform.** On kiosk, the thermal printer is connected and labels are expected. On mobile, the printer may be remote. The defaults reflect reality. --- ## 5. Visual Direction ### Typography (MD3 Type Scale) | Role | Token | Size | Weight | Line Height | |------|-------|------|--------|-------------| | App Bar Title | `titleLarge` | 22sp | 400 | 28sp | | Step Labels | `labelSmall` | 11sp | 500 | 16sp | | Section Headers | `titleSmall` | 14sp | 500 | 20sp | | Field Labels | `bodyMedium` | 14sp | 400 | 20sp | | Field Values | `bodyLarge` | 16sp | 400 | 24sp | | Weight Display | `headlineMedium` | 28sp | 400 | 36sp | | Confidence Label | `labelLarge` | 14sp | 500 | 20sp | | Confidence % | `titleMedium` | 16sp | 500 | 24sp | | Scanned Code | `labelMedium` (monospace) | 12sp | 500 | 16sp | | Summary Lines | `bodyMedium` | 14sp | 400 | 20sp | | Tracking ID | `labelMedium` (monospace) | 12sp | 500 | 16sp | | CTA Button | `labelLarge` | 14sp | 500 | 20sp | | Instruction Text | `bodyMedium` | 14sp | 400 | 20sp | | Quick-Select Chip | `labelLarge` | 14sp | 500 | 20sp | ### Spacing (MD3 8dp grid) | Element | Spacing | |---------|---------| | App Bar padding | 16dp horizontal, 12dp vertical | | Step indicator padding | 24dp horizontal, 12dp vertical | | Camera viewport | Full-bleed (0dp margin), 16dp rounded corners, overflow hidden | | Section gap | 16dp vertical | | Field label to input | 8dp | | Color swatch grid gap | 12dp | | Quick-select chip gap | 8dp | | Weight stepper internal | 12dp between elements | | Summary card padding | 16dp | | Button row gap | 12dp | | Bottom padding (before nav bar) | 16dp (mobile) / 0dp (kiosk — no bottom nav) | ### Color (MD3 Dark Theme — "Industrial Maker") Same base palette as FIL-001 and FIL-002. Screen-specific additions: | Role | Token | Value (Dark) | Usage | |------|-------|-------------|-------| | Camera Viewport BG | `surfaceContainerHighest` | `#36343B` | Camera area background (before camera starts) | | Scan Frame | `primary` | `#A8CEDA` | Animated scanning rectangle | | Scan Success Flash | Custom `success` | `#8BD0A0` | Flash on successful scan | | Confidence High | Custom `success` | `#8BD0A0` | High confidence bar | | Confidence High Container | Custom `successContainer` | `#00522E` | High confidence bar background | | Confidence Medium | Custom `warning` | `#FFD580` | Medium confidence bar | | Confidence Medium Container | Custom `warningContainer` | `#5D4200` | Medium confidence bar background | | Confidence Low | Custom orange | `#FFB784` | Low confidence bar | | Confidence Low Container | Custom orange container | `#5D3A00` | Low confidence bar background | | Confidence Unknown | `error` | `#F2B8B5` | Unknown/no match bar | | Confidence Unknown Container | `errorContainer` | `#8C1D18` | Unknown bar background | | Pre-filled Field Tint | `primaryContainer` | `#004D63` | Subtle green-blue tint on pre-filled inputs | | Quick-Select Active | `primaryContainer` | `#004D63` | Active chip fill | | Scanner Connected | Custom `success` | `#8BD0A0` | Kiosk scanner status | | Scanner Disconnected | `error` | `#F2B8B5` | Kiosk scanner status | ### Scan Frame Animation The scanning rectangle uses a **sweep line** animation: - Horizontal line travels from top to bottom of the frame over 2 seconds - Line color: `primary` (#A8CEDA) with 40% opacity - Line width: 2dp - Frame corner brackets: 3dp stroke, `primary` color - On code detected: Frame corners pulse green (#8BD0A0) once, scan line stops --- ## 6. Responsiveness ### Kiosk (800×480) — Scan State ``` ┌──────┬──────────────────────────────────────────────┐ │ NAV │ ✕ Smart Intake │ │ RAIL │──────────────────────────────────────────────│ │ │ ● ──── ○ ──── ○ │ │ │ Scan Identify Update │ │ │──────────────────────────────────────────────│ │ │ │ │ │ ┌──────────────────────────────────┐ │ │ │ │ │ │ │ │ │ 📷 SCANNER CONNECTED ✓ │ │ │ │ │ │ │ │ │ │ Scan a barcode or QR code... │ │ │ │ │ │ │ │ │ │ ═══════════════════ │ │ │ │ │ (pulsing line) │ │ │ │ │ │ │ │ │ └──────────────────────────────────┘ │ │ │ │ │ │ Or: [Enter Barcode Manually] │ │ │ │ └──────┴──────────────────────────────────────────────┘ ``` ### Kiosk (800×480) — Identify State ``` ┌──────┬──────────────────────────────────────────────┐ │ NAV │ ✕ Smart Intake │ │ RAIL │──────────────────────────────────────────────│ │ │ ✓ ────● ──── ○ │ │ │ Scan Identify Update │ │ │──────────────────────────────────────────────│ │ │ Scanned: 8901234567890 HIGH ▓▓▓▓▓▓▓▓ 92% │ │ │──────────────────────────────────────────────│ │ │ Material: [PLA Basic ▾] │ │ │ Brand: [Bambu Lab ▾] │ │ │ Color: ● ● ● ● ● ● ● ● ● [C] │ │ │ Finish: [Basic][Matte][Silk] Mod: [None] │ │ │ │ │ │ [Rescan] [Confirm →] │ └──────┴──────────────────────────────────────────────┘ ``` - **Two-column layout for Material/Brand** on kiosk (side by side to save vertical space) - **Finish/Modifier on same row** to save space - **Color picker horizontal** with wrapping ### Kiosk (800×480) — Update State ``` ┌──────┬──────────────────────────────────────────────┐ │ NAV │ ✕ Smart Intake │ │ RAIL │──────────────────────────────────────────────│ │ │ ✓ ────✓ ──── ● │ │ │ Scan Identify Update │ │ │──────────────────────────────────────────────│ │ │ Weight: [-] 1000 [+] g │ │ │ Quick: [250] [500] [750] [1000] │ │ │ Location: [AMS 2, Slot A3 ▾] │ │ │ Status: [● Available] [○ In Use] │ │ │──────────────────────────────────────────────│ │ │ ┌──────────────────────────────────┐ │ │ │ │ PLA Basic - Matte Black │ │ │ │ │ Bambu Lab • 1000g • Slot A3 │ │ │ │ │ EXT-2026-PLA-0043 QR ████ │ │ │ │ │ Print Label [═══●═══] ON │ │ │ │ └──────────────────────────────────┘ │ │ │ │ │ │ [◀ Back] [✓ Complete Intake] │ └──────┴──────────────────────────────────────────────┘ ``` - **All content fits above fold** on kiosk — no scrolling needed - **Summary card compact** — inline with QR preview - **Buttons full-width** in action row ### Mobile PWA (375×812) — Scan State As shown in Section 3 (full-bleed camera). Key differences: - Camera takes ~60% of screen height - Step indicator + instruction text in remaining space - Scan result chip floats above camera viewport ### Mobile PWA (375×812) — Identify State As shown in Section 3. Key differences: - **Single column** layout — all fields stack vertically - **Scrollable** — Identification form exceeds screen height on small phones - **Color picker** wraps to 2 rows - **Buttons** fixed at bottom (sticky) ### Mobile PWA (375×812) — Update State As shown in Section 3. Key differences: - **Scrollable** content - **Summary card** full-width - **Buttons** fixed at bottom (sticky) ### Key Adaptations | Property | Kiosk (800×480) | Mobile (375×812) | |----------|-----------------|-------------------| | Scan input method | USB HID scanner | Device camera | | Scanner status card | Yes (connected/disconnected) | No (camera instead) | | Camera viewport | None | Full-bleed, ~60% height | | Form layout | Two-column where possible | Single column, scrollable | | Color picker | Horizontal with wrapping | Horizontal with wrapping (narrower) | | Quick-select chips | Larger (48dp height) | Standard (36dp height) | | Print label default | ON | OFF | | Post-completion auto-return | 10s → Inventory | No auto-return | | Bottom navigation | No (has rail) | Yes (80dp) | | Sticky buttons | At bottom of content | At bottom above nav bar | --- ## 7. Developer Handoff Notes ### Angular Material Components | UI Element | Angular Material Component | Notes | |-----------|--------------------------|-------| | Top App Bar | `` | Simple, non-collapsible. Close button on left. | | Step Indicator | Custom component | 3-dot stepper with animated connecting lines. Use `@angular/animations` for line fill. | | Camera Viewport | `