Files
Extrudex/design/homepage-spec.md

510 lines
27 KiB
Markdown
Raw Permalink Normal View History

2026-04-25 18:51:05 +00:00
# Extrudex — Homepage (Main Hub) UI/UX Specification
> **Author:** Sketch (Design Lead)
> **Date:** April 20, 2026
> **Version:** 1.0
> **Status:** Ready for Review → Implementation Handoff
---
## 1. Objective
**Who is it for?**
Workshop operators and print managers who interact with Extrudex primarily on a Raspberry Pi 5 kiosk touchscreen (arm's length, greasy hands, ambient workshop lighting) and secondarily via a mobile PWA browser for remote monitoring.
**What task are they completing?**
The Homepage serves as the **command center** — the single screen where a user can, at a glance:
1. **Assess the fleet** — See the real-time status of every printer (printing, idle, paused, error, offline).
2. **Spot problems fast** — Instantly identify which machines need attention (errors, paused jobs, low filament).
3. **Take action** — Navigate to a specific printer, spool, or print job with minimal taps.
4. **Monitor inventory** — Get a quick read on filament stock levels and recent consumption.
5. **Recent activity** — See the last few completed or failed prints for situational awareness.
**Success metric:** A user walking past the kiosk can determine fleet health in under 2 seconds without touching the screen.
---
## 2. Screen Inventory
The Homepage/Main Hub is a **single screen** that serves as the root of the navigation tree. It does not itself contain sub-screens, but it is the gateway to:
| Destination Screen | Triggered By | Priority |
|---|---|---|
| **Printer Detail** | Tapping any printer card | Primary |
| **Spool Inventory** | Nav tab "Spools" | Primary |
| **Print Jobs** | Nav tab "Prints" | Primary |
| **Materials DB** | Nav tab "Materials" | Secondary |
| **Settings** | Nav tab "Settings" | Secondary |
| **Quick Scan** | Floating action button (FAB) | Primary |
The Homepage itself contains these **in-page sections** (not separate screens):
1. **Status Summary Bar** — Fleet-wide health at a glance
2. **Printer Fleet Grid** — Live status cards for each printer
3. **Filament Stock Snapshot** — Inventory overview with low-stock alerts
4. **Recent Activity Feed** — Last 5 print events
---
## 3. Layout Specification
### Page Title
**"Extrudex"** — Always visible in the top app bar. No subtitle needed; this is the root screen.
### Navigation Structure
**Primary Navigation: Bottom Navigation Bar (Mobile/Kiosk)**
Material Design 3 bottom navigation with 5 destinations:
| Tab | Icon (Material Symbols) | Label | Badge? |
|---|---|---|---|
| **Hub** | `dashboard` | Hub | — (active by default) |
| **Printers** | `print` | Printers | Error count badge |
| **Spools** | `inventory_2` | Spools | Low-stock badge |
| **Prints** | `receipt_long` | Prints | — |
| **Settings** | `settings` | Settings | — |
**Rationale for bottom nav:**
- Touch-first: bottom nav is the easiest reach zone on a touchscreen kiosk or phone.
- 5 tabs is the MD3 maximum — keeps things scannable.
- "Hub" is the homepage; the other four are top-level destinations.
- Badges on Printers/Spools draw attention to problems without requiring navigation.
**Desktop/Navigation Rail (Future)**
On wider screens (browser dashboard), the bottom nav converts to a Material 3 Navigation Rail on the left edge with the same 5 destinations. This is a responsive transformation, not a separate navigation system.
### Main Sections (Top to Bottom)
#### A. Top App Bar
- **Leading:** Extrudex logo mark (gear icon + "EXTRUDEX" in Inter Bold)
- **Trailing:**
- Connection status indicator (green dot = SignalR connected, red dot = disconnected)
- Clock (kiosk mode — always visible so users know the time without looking at their phone)
- **Style:** MD3 medium top app bar, `surface` color background, no elevation (flat)
- **Height:** 64px kiosk / 56px mobile
#### B. Status Summary Bar
A horizontal strip below the app bar showing fleet-wide metrics in a single row:
| Metric | Format | Color Logic |
|---|---|---|
| Printers Active | `4 / 7` | Text only, neutral |
| Printers in Error | `1` | Red if > 0, hidden if 0 |
| Low Filament Spools | `2` | Yellow if > 0, hidden if 0 |
| Prints Today | `12` | Neutral |
- **Layout:** Horizontal flex row, evenly spaced, each metric in a compact chip/badge
- **Kiosk override:** Larger font (20px), more spacing between metrics
- **Mobile:** Compact chips with icons, horizontally scrollable if overflow
- **Tap behavior:** Tapping "Printers in Error" navigates to Printers tab filtered to errors. Tapping "Low Filament" navigates to Spools tab filtered to low stock.
#### C. Printer Fleet Grid
The **heart of the homepage**. A responsive grid of printer status cards.
**Card Layout (each printer):**
```
┌─────────────────────────────┐
│ [Status Dot] Printer Name │ ← Header row
│─────────────────────────────│
│ Current Job: Benchy #3 │ ← Job name or "Idle"
│ [████████░░] 72% │ ← Progress bar + percentage
│ Filament: PLA Silk │ ← Active material
│ Remaining: ~142g │ ← Spool remaining
│ ETA: 0h 23m │ ← Time remaining
│─────────────────────────────│
│ [View Detail →] │ ← Tap target / CTA
└─────────────────────────────┘
```
**Status Dot Colors:**
- 🟢 Green (`#4ADE70` kiosk / `#16A34A` light) — Printing / Active
- 🟡 Yellow (`#FACC15` kiosk / `#CA8A04` light) — Paused
- 🔴 Red (`#F87171` kiosk / `#DC2626` light) — Error / Failed
- ⚪ Gray (`#64748B`) — Idle / Offline
**Grid Behavior:**
- Kiosk (800×480 Pi 5): 2 columns, 34 rows (scrollable)
- Tablet (768px+): 3 columns
- Mobile (< 480px): 1 column, list view
**Card Dimensions:**
- Kiosk: Full-width within column, min-height 180px
- Mobile: Full-width, min-height 140px, slightly denser
**Important States:**
- **Printing (active):** Progress bar animates, card has subtle left-border accent in green
- **Paused:** Yellow left border, progress bar frozen, "PAUSED" badge overlaid
- **Error:** Red left border, card background shifts to `error-container` token, error message shown
- **Idle:** Gray left border, dimmed progress area, "Ready" label
- **Offline:** Fully dimmed card, "OFFLINE" badge, no real-time data
#### D. Filament Stock Snapshot
A compact section showing inventory health:
**Layout:** Horizontal scrolling row of small cards or a mini-list
```
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ PLA │ │ PETG │ │ TPU │
│ ████████░░ 80% │ │ ████░░░░░ 40% │ │ ██░░░░░░░ 20% │
│ 23 spools │ │ 8 spools │ │ 3 spools ⚠️ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
```
- Each card shows: Material base name, stock percentage bar, spool count
- Cards with < 25% stock get a `⚠️` warning indicator and yellow-tinted background
- **Kiosk:** 23 cards visible, swipe to see more
- **Mobile:** Horizontal scroll carousel
- **Tap:** Navigates to Spools tab filtered by that material
#### E. Recent Activity Feed
The last 5 print events in a compact list:
```
┌────────────────────────────────────────────────────┐
│ ✓ Benchy #3 · PLA Silk · 23g · 0h45m │
│ ✓ Gear Set v2 · PETG Basic · 87g · 2h12m │
│ ✗ Phone Case · TPU Basic · — · Failed │
│ ✓ Calibration · PLA Basic · 4g · 0h05m │
│ ✓ Bracket x4 · ASA Matte · 156g · 4h30m │
└────────────────────────────────────────────────────┘
```
- Each row: Status icon, job name, material, weight used, duration
- Failed prints show `✗` in red with "Failed" label
- **Kiosk:** Larger text, comfortable row height (56px)
- **Mobile:** Standard list density (48px rows)
- **Tap a row:** Navigates to that print's detail view
- **"View All" link:** At bottom, navigates to Prints tab
### Primary CTA
**Floating Action Button (FAB):** "Quick Scan" — a prominent FAB in the bottom-right corner with a `qr_code_scanner` icon. This triggers the barcode/USB scanner workflow for spool check-in/check-out.
- Kiosk: Extended FAB with label "Scan" + icon, 56×56px minimum
- Mobile: Standard FAB, icon only, 56×56px
- Positioned above the bottom nav, with 16px margin from edges
### Secondary Actions
- Tap any printer card → Printer Detail
- Tap any stock card → Spools filtered
- Tap any activity row → Print detail
- Tap error/low badges in summary bar → Filtered navigation
### Key Components (MD3)
| Component | Usage | Notes |
|---|---|---|
| Bottom Navigation | Primary nav | 5 destinations |
| Top App Bar (Medium) | App header | Logo + status + clock |
| Cards (Elevated) | Printer status | Real-time content |
| Cards (Filled/outlined) | Filament stock | Compact, scrollable |
| List | Activity feed | 3-line items |
| FAB (Extended/Regular) | Quick Scan | Always accessible |
| Badge | Nav tabs, status | Error count, low stock |
| Linear Progress Indicator | Print progress | On printer cards |
| Chip | Status summary | Compact metrics |
### Important States
| State | Visual Treatment |
|---|---|
| Loading (initial) | Skeleton screens for printer cards, shimmer animation |
| SignalR disconnected | Red dot in app bar, banner: "Live updates paused — reconnecting..." |
| No printers registered | Empty state illustration + "Add your first printer" CTA |
| No spools registered | Stock section shows "No inventory — add spools to start tracking" |
| All printers idle | Fleet grid shows all gray cards, summary bar shows "0 active" |
| Critical error (printer) | Card pulses red border once, then steady red left border |
---
## 4. UX Rationale
### Why This Layout Supports the Task
1. **Fleet health at a glance:** The Status Summary Bar + Printer Fleet Grid are visible immediately on load. No scrolling required on kiosk to see if something is wrong. Color-coded status dots and left-border accents make the visual scan instantaneous.
2. **Progressive detail:** The homepage gives you "enough" — status, progress, material. You only tap into a printer card when you need details (temps, G-code, history). This avoids information overload while keeping critical data surface-level.
3. **Inventory awareness without navigation:** The Filament Stock Snapshot means operators don't need to leave the homepage to know if they're running low. The warning state (yellow + ⚠️) is visible without interpreting numbers.
4. **Activity context:** The Recent Activity Feed gives "what just happened" situational awareness — useful when returning to the kiosk after being away. It answers "did that print finish?" without requiring navigation.
5. **Scan-first workflow:** The FAB for Quick Scan is always accessible from the homepage, which is the most common action for spool check-in during workshop operations. Placed bottom-right — the natural resting thumb zone.
### Hierarchy (What matters most → least)
1. **Printer errors** (red, draws the eye immediately)
2. **Active printers with progress** (green accent, animated progress bars)
3. **Paused printers** (yellow accent, needs attention)
4. **Low filament warnings** (yellow indicators in stock section)
5. **Idle printers** (gray, calm, no action needed)
6. **Recent activity** (informational, below the fold on mobile)
### Tradeoffs
| Decision | Benefit | Cost | Mitigation |
|---|---|---|---|
| Bottom nav over side nav | Touch-friendly, MD3 standard, always visible | Takes screen space at bottom | Acceptable on touch-first device |
| Cards over table | Glanceable, status-colorable, touch-friendly | Less dense (can't see 7 printers at once) | Grid layout maximizes visible count; scroll for 6+ printers |
| Summary bar metrics | Fleet health without scrolling | Adds cognitive load if too many metrics | Keep to 4 max, hide zero-value metrics |
| Horizontal scroll for stock cards | Saves vertical space, works well for 36 materials | Hidden cards require swipe | First 3 most-used materials visible; swipe for rest |
| FAB for scan | Always accessible, one-tap | Covers content behind it | Standard FAB behavior; scrolls away on mobile |
| No sidebar on kiosk | Maximizes kiosk screen real estate | No persistent deep-nav | Bottom nav is sufficient for 5 top-level destinations |
---
## 5. Visual Direction
### Tone
**Modern Industrial/Maker** — Dark mode by default on kiosk. Professional workshop vibe. High contrast. Think: a CNC control panel, not a social media app. The aesthetic should feel like a tool you trust, not an app you browse.
### Dark Mode Palette (Kiosk Default)
| Token | Value | Usage |
|---|---|---|
| `md.sys.color.background` | `#0F172A` | Page background |
| `md.sys.color.surface` | `#1E293B` | Card backgrounds, nav bar |
| `md.sys.color.surface-container` | `#334155` | Elevated cards, containers |
| `md.sys.color.surface-container-high` | `#475569` | Hover/pressed states |
| `md.sys.color.primary` | `#60A5FA` | Primary actions, links, active tab |
| `md.sys.color.on-primary` | `#0F172A` | Text on primary |
| `md.sys.color.primary-container` | `#1E3A5F` | Subtle primary tinted containers |
| `md.sys.color.error` | `#F87171` | Error states, failed prints |
| `md.sys.color.error-container` | `#450A0A` | Error card backgrounds |
| `md.sys.color.on-error` | `#FFFFFF` | Text on error |
| `md.sys.color.on-surface` | `#F1F5F9` | Primary text |
| `md.sys.color.on-surface-variant` | `#94A3B8` | Secondary text |
| `md.sys.color.outline` | `#334155` | Borders, dividers |
| `md.sys.color.outline-variant` | `#1E293B` | Subtle borders |
### Light Mode Palette (Dashboard/Future)
| Token | Value | Usage |
|---|---|---|
| `md.sys.color.background` | `#F8FAFC` | Page background |
| `md.sys.color.surface` | `#FFFFFF` | Card backgrounds |
| `md.sys.color.primary` | `#2563EB` | Primary actions |
| `md.sys.color.on-surface` | `#0F172A` | Primary text |
| `md.sys.color.on-surface-variant` | `#475569` | Secondary text |
### Typography
| Role | Font | Weight | Size (Kiosk) | Size (Mobile) |
|---|---|---|---|---|
| App Title | Inter | Bold | 22px | 20px |
| Card Title (Printer Name) | Inter | SemiBold | 20px | 18px |
| Section Heading | Inter | SemiBold | 18px | 16px |
| Body Text | Inter | Regular | 18px | 16px |
| Metric Value | Inter | Bold | 28px | 24px |
| Metric Label | Inter | Medium | 14px | 12px |
| Mono Values (weight, time, %) | JetBrains Mono | Medium | 18px | 16px |
| Caption / Timestamp | Inter | Regular | 14px | 12px |
**Rationale for oversized metrics:** The kiosk is viewed at arm's length or further. A 28px bold metric is legible from 34 feet away. Monospace for numeric values ensures columns align and feels "instrument-like."
### Spacing / Density
| Token | Kiosk | Mobile |
|---|---|---|
| Page padding | 24px | 16px |
| Card padding | 20px | 16px |
| Grid gap | 16px | 12px |
| Section gap | 32px | 24px |
| Row height (lists) | 56px | 48px |
| FAB margin from edge | 16px | 16px |
| Touch target minimum | 48px | 44px |
### Component Behavior
- **Printer cards:** Update in real-time via SignalR. Progress bar animates smoothly (CSS transition 300ms). Status changes trigger a brief highlight flash (200ms background shift) to draw attention.
- **Bottom nav:** Active tab has `primary` color icon + label. Inactive tabs use `on-surface-variant`. Badges are small circles positioned at the icon's top-right.
- **FAB:** Elevated with shadow-3. On tap, ripple effect. Extended label appears on kiosk (wider screen), icon-only on mobile.
- **Status summary bar:** Metric chips are non-scrolling on kiosk (fits in one row at 800px width), horizontally scrolling on mobile if needed.
- **Activity feed:** List items have subtle divider lines (`outline-variant`). Failed items have `error-container` background tint.
- **Skeleton loading:** Cards show shimmer placeholder during initial load (1.5s max before content appears).
### Color Usage Guidelines
1. **Color is information, not decoration.** Every colored element must communicate state.
2. **Red = immediate attention.** Only use for errors, failures, disconnections. Never for decoration.
3. **Yellow = needs attention soon.** Paused printers, low filament, warnings.
4. **Green = operating normally.** Active printing, completed, connected.
5. **Blue = interactive.** Links, buttons, active navigation, primary CTAs.
6. **Gray = neutral/idle.** Offline printers, inactive states, secondary info.
7. **Never use color alone to convey meaning.** Always pair with icon + text label (accessibility).
---
## 6. Responsiveness
### Breakpoints
| Breakpoint | Width | Layout |
|---|---|---|
| Kiosk | 480800px (Pi 5 typical: 800×480) | 2-col grid, bottom nav, extended FAB |
| Mobile (compact) | < 480px | 1-col list, bottom nav, standard FAB |
| Tablet | 7681024px | 3-col grid, bottom nav, extended FAB |
| Desktop | 1024px+ | 3-col grid, nav rail, extended FAB |
### Layout Changes by Device
#### Pi 5 Kiosk (800×480, Landscape)
- **Top app bar:** 64px height, clock always visible
- **Status summary:** 4 metrics in a single row (fits 800px)
- **Printer grid:** 2 columns × N rows, scrollable vertically
- **Stock snapshot:** 3 cards visible, no scroll needed (most common materials first)
- **Activity feed:** 3 rows visible, "View All" link
- **Bottom nav:** Full 5 tabs
- **FAB:** Extended with "Scan" label
#### Mobile PWA (< 480px, Portrait)
- **Top app bar:** 56px height, no clock (use phone clock)
- **Status summary:** 23 metrics visible, horizontal scroll for more
- **Printer grid:** 1 column list view (cards become horizontal list items)
- **Stock snapshot:** Horizontal carousel, 2 cards visible
- **Activity feed:** 35 rows, compact density
- **Bottom nav:** 5 tabs (may collapse labels on very narrow screens)
- **FAB:** Icon only, standard 56px
#### Tablet / Desktop Browser
- **Bottom nav → Navigation Rail** (left side, 80px wide)
- **Printer grid:** 3 columns
- **Stock snapshot:** 45 cards visible in row
- **Activity feed:** 5 rows
- **Additional whitespace** — dashboard mode can breathe more
### Kiosk-Specific Considerations
- **No hover states** — all interactions are tap/click only
- **No tooltips** — information must be visible inline
- **Larger touch targets** — 48px minimum (4px above MD3 default)
- **No right-click context menus** — all actions are explicit buttons/links
- **Screen wake** — kiosk should not sleep; CSS `animation` on a subtle element to prevent screen burn-in (shift a 1px element every 60s)
- **Overshoot scroll** — prevent pull-to-refresh or browser gestures (PWA `overscroll-behavior: none`)
---
## 7. Developer Handoff Notes
### Reusable Components to Build
| Component | Type | Props/Inputs | Notes |
|---|---|---|---|
| `<ex-printer-card>` | Standalone | `printer: Printer`, `status: PrinterStatus`, `job?: PrintJob` | Left-border color computed from status. SignalR drives re-renders. |
| `<ex-status-dot>` | Atom | `status: 'active' \| 'paused' \| 'error' \| 'idle' \| 'offline'` | Small colored circle (12px) with aria-label for accessibility |
| `<ex-metric-chip>` | Atom | `label: string`, `value: string \| number`, `variant: 'default' \| 'error' \| 'warning'` | Used in Status Summary Bar |
| `<ex-stock-card>` | Standalone | `material: string`, `percentage: number`, `spoolCount: number`, `lowStock: boolean` | Horizontal scroll child |
| `<ex-activity-item>` | List Item | `job: PrintEvent` | 3-line list item with status icon |
| `<ex-progress-bar>` | Atom | `value: number`, `status: PrinterStatus` | MD3 linear progress, color matches status |
| `<ex-fleet-summary>` | Composite | `printers: Printer[]`, `spools: Spool[]` | Renders metric chips row |
| `<ex-connection-indicator>` | Atom | `connected: boolean` | Green/red dot in app bar |
### Angular Material Components Used
- `MatBottomNavigation` (or custom bottom nav — MD3 bottom nav is not yet in Angular Material; implement with `MatTabNav` + custom styling)
- `MatCard` → Styled with custom dark tokens
- `MatProgressBar` → Custom color per status
- `MatFabButton` / `MatMiniFabButton`
- `MatBadge` → For nav tab badges
- `MatList` → Activity feed
- `MatChip` → Status summary metrics
- `MatIcon` → Material Symbols throughout
- `MatToolbar` → Top app bar
### Interaction Notes
1. **SignalR subscriptions:** The homepage must subscribe to `PrinterHub` on mount. Each printer card re-renders on status/progress push events. Unsubscribe on navigate-away.
2. **Optimistic updates:** Progress bars should animate smoothly — use CSS transitions, not discrete jumps. If SignalR sends a progress update every 5s, interpolate between values.
3. **FAB scan action:** On tap, immediately focus a hidden text input that captures USB HID barcode scanner output ( scanners type characters + Enter). This is a capture-only input — no keyboard should appear on mobile. Use `<input readonly>` or intercept `keydown` globally.
4. **Pull-to-refresh:** Disabled on kiosk. On mobile PWA, consider enabling for manual data refresh.
5. **Navigation:** Use Angular Router with bottom nav tabs bound to routerLinkActive. Highlight active tab. Preserve scroll position when returning to Hub.
6. **Skeleton screens:** On initial load, show 6 skeleton printer cards (matching grid layout). Use `@angular/material` skeleton patterns or custom shimmer CSS.
### Accessibility
| Requirement | Implementation |
|---|---|
| Screen reader | All status indicators have `aria-label` (e.g., "Printer Elegoo-1: Printing, 72% complete") |
| Color blindness | Never color-only — always icon + text + color. Status dots have aria-labels |
| Keyboard nav | Tab order: top bar → summary metrics → printer cards (grid order) → stock → activity → FAB → bottom nav |
| Focus management | After navigation, focus lands on the page title. After FAB tap, focus returns to FAB |
| Touch target | 48px minimum on kiosk, 44px minimum on mobile — all interactive elements |
| Contrast | All text on dark background meets WCAG AA (4.5:1 for body, 3:1 for large text) |
| Motion | Respect `prefers-reduced-motion` — disable progress bar animation and shimmer if set |
| Live regions | Printer status changes announced via `aria-live="polite"` on the card region |
### Performance Notes
- **OnPush change detection** for all components receiving SignalR data
- **TrackBy** on printer grid `*ngFor` to avoid re-rendering unchanged cards
- **Virtual scrolling** for activity feed if it grows beyond 20 items (use `@angular/cdk ScrollingModule`)
- **Lazy load** Spools, Prints, Materials, Settings tabs — only Hub is eager-loaded
- **Image optimization:** Use inline SVG for status icons, not raster images. Logo should be SVG.
### File Structure Suggestion
```
src/app/
├── pages/
│ └── hub/
│ ├── hub.component.ts
│ ├── hub.component.html
│ ├── hub.component.scss
│ └── hub.component.spec.ts
├── components/
│ ├── printer-card/
│ ├── status-dot/
│ ├── metric-chip/
│ ├── stock-card/
│ ├── activity-item/
│ ├── progress-bar/
│ ├── fleet-summary/
│ └── connection-indicator/
├── layout/
│ ├── bottom-nav/
│ ├── top-app-bar/
│ └── nav-rail/
└── shared/
└── tokens/
└── _extrudex-tokens.scss
```
---
## Appendix: Navigation Map
```
┌──────────────────────────────────────────────────────────────┐
│ EXTRUDEX │
│ │
│ ┌─ Hub (Home) ──────────────────────────────────────────┐ │
│ │ • Fleet Status Grid │ │
│ │ • Filament Snapshot │ │
│ │ • Recent Activity │ │
│ │ • [FAB: Quick Scan] │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Printers ────────┐ ┌─ Spools ─────────────────────┐ │
│ │ Printer List │ │ Spool Inventory │ │
│ │ → Printer Detail │ │ → Spool Detail │ │
│ │ → Job History │ │ → Check-in/Check-out │ │
│ │ → Controls │ │ → Link to Printer │ │
│ └────────────────────┘ └─────────────────────────────┘ │
│ │
│ ┌─ Prints ──────────┐ ┌─ Settings ───────────────────┐ │
│ │ Print Job List │ │ System Configuration │ │
│ │ → Print Detail │ │ Printer Management │ │
│ │ → COGS Report │ │ User Preferences │ │
│ └────────────────────┘ └──────────────────────────────┘ │
│ │
│ ══════════════════════════════════════════════════════════ │
│ [Hub] [Printers] [Spools] [Prints] [Settings] │
│ ══════════════════════════════════════════════════════════ │
└──────────────────────────────────────────────────────────────┘
```
---
*End of Specification — Ready for Stuart (mockup generation) and Rex (implementation handoff)*