docs(mockups): static HTML wireframes for Library scaling concepts
CI / test (push) Has been cancelled

Renders the five design concepts from
_bmad-output/planning-artifacts/library-many-frames-design-ideas.md as
standalone HTML so Matt can compare them in a browser without spinning
up the SPA. Mockups live at /mockups/library/ and reuse the project's
design tokens for visual consistency:

  index.html   landing page with concept links
  current.html the chip-explosion state we're shipping today
  concept-a.html  photo + status badge → DevicePicker sheet (recommended)
  concept-b.html  device-first tab
  concept-c.html  multi-select bulk action bar
  concept-d.html  device chip filter + photo dots

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 15:08:18 -04:00
parent a511b89564
commit 9854688a49
8 changed files with 1102 additions and 0 deletions
@@ -0,0 +1,159 @@
# Library page — scaling to many frames
**Date:** 2026-05-14
**Facilitated by:** BMAD design team
**Active personas:** 🎨 Sally (UX), 🎨 Maya (Design Thinking), 📋 John (PM), 🏗️ Winston (Architect)
**Brief from {{user_name}}:** Library doesn't scale beyond 1-2 frames. Need design ideas.
---
## 1. The problem, stated by the user reading the screen
🎨 **Sally:** *"Picture Aunt Carol. She's gifted PictureFrame units to her two grown kids and three grandkids — five frames in the wild. She opens the Library page, ready to approve last weekend's birthday photos. Each photo card stacks five 'Living Room', 'Kitchen', 'Bedroom', 'Mom's Place', 'Cabin' chips PLUS five lock chips. With twenty photos on screen that's two hundred buttons. She squints, taps the wrong one, undoes it. The page feels broken — and Aunt Carol is the literal target user."*
The current per-photo layout (`<button v-for="device in devicesStore.devices">` rendered **twice** — approval row + lock row) has O(photos × devices) chips on the page. Two of the most important user-facing screens (Library "My Photos" tab) breaks down at N=4+ frames.
---
## 2. Reframing — what job is the user really hiring this page for?
📋 **John:** *Cuts to the chase.* "Three jobs we keep conflating in the same view:
| # | Job | Frequency | Trigger |
|---|-----|-----------|---------|
| J1 | 'Send THIS new photo to ALL my family frames' | high | just uploaded |
| J2 | 'Send THIS photo to ONE specific frame' | medium | birthday card for Mom |
| J3 | 'What's on Grandma's frame right now? Lock it.' | medium | curating one frame |
| J4 | 'Remove this old photo from my frames' | low | cleanup |
J1 is the bulk action — currently requires N taps. J3 is the per-frame view — currently requires scanning the chip column. The Library only directly serves J2 well, and only at small N."
🎨 **Maya:** *Sketching in the air.* "We're solving a **many-to-many curation** problem with a **per-cell grid of toggles**. Toggle grids are the worst answer at scale — visual noise scales with N×M. We should split the matrix: either device-first, photo-first-with-summary, or operation-first (bulk)."
---
## 3. Five design concepts
### 🅐 Photo card → photo-only + status badge (recommended baseline)
🎨 **Sally:** "Strip the card to the photo, plus a single line of status: `✓ on 3 of 5 frames · 1 lock`. Tap the photo opens a bottom sheet with the full grid of approvals + locks. The DevicePicker bottom sheet we already use during upload IS this exact UI — reuse it."
```
┌───────────────┐
│ │
│ [ photo ] │
│ │
└───────────────┘
✓ 3/5 frames · 🔒 Mom's
[edit] [delete]
```
- **Pros:** O(photos) widgets, not O(photos × devices). Reuses existing DevicePicker. Grid scales arbitrarily.
- **Cons:** One more tap for the "approve to one specific frame" job (J2). One-frame and two-frame users see a regression.
- **Effort:** Small. Mostly CSS + reusing DevicePicker. ~1 day.
### 🅑 Device-first column ("Per frame" tab)
📋 **John:** "Add a top-level toggle to the Library: `My Photos` / `By Frame`. The `By Frame` view is a horizontal swipe-able stack — one card per frame, each card shows its approved photos and the locked photo highlighted. Lets users curate per-frame without scanning a chip column."
```
┌── Living Room (5 approved · 🔒 Birthday) ──┐
│ [photo][photo][photo][photo][photo] [+] │
└────────────────────────────────────────────┘
┌── Kitchen (12 approved · 🔒 none) ─────┐
│ [photo][photo][photo][photo][photo] [+] │
└────────────────────────────────────────────┘
```
- **Pros:** Native answer to J3 ("what's on Grandma's frame?"). Each card is bounded — no matrix blow-up.
- **Cons:** Doesn't help J1 (one photo → all frames) without leaving this view. Extra navigation cost.
- **Effort:** Medium. New route/component + API filter param. ~2-3 days.
### 🅒 Multi-select + bulk action bar
🎨 **Maya:** *Jazz hands.* "Tap-and-hold a photo to enter selection mode. Top bar morphs into 'N selected — Send to… / Lock to… / Delete'. Tap-and-pick more photos. One trip to DevicePicker covers any batch. J1 in two gestures."
```
[grid of photos with selection bubbles in corners]
─────────────────────────────────────────
3 selected [Send to →] [Cancel]
```
- **Pros:** Solves J1 efficiently. Familiar pattern (iOS Photos, Google Photos).
- **Cons:** Discoverability — first-time users won't know to long-press. Probably worth a hint on first run.
- **Effort:** Medium. Selection-state in store + bulk API endpoint. ~2 days.
### 🅓 Device chip filter + photo dots
🎨 **Sally:** "Top of the Library page: a horizontal scrolling row of device chips. Tap one → grid filters to photos approved on that frame. Each photo's bottom shows tiny initial-dots for the OTHER frames it's on. Tap a photo to manage."
```
[All] [Living Room ✓] [Kitchen] [Bedroom] [Mom's] [Cabin]
─────────────────────────────────────────
[photo · ●LR ●KT] [photo · ●LR]
[photo · ●LR ●KT] [photo · ●LR ●MP]
```
- **Pros:** Helpful for J3 by filter. Compact status without buttons. Works at any N.
- **Cons:** Filter is implicit — user might not realise. Initial-dots crowd at high N.
- **Effort:** Medium. Filter is purely client-side; dots are styling. ~1.5 days.
### 🅔 Device groups ("Family", "Kids", "All")
📋 **John:** *Skeptical.* "If users actually have 8 frames, they probably cluster: 'all kids' rooms', 'parents' places'. Let them define one-tap groups. Photo approval/lock takes group as a unit."
```
Groups: [All Frames] [Kids' Rooms] [Parents] [+ Group]
```
- **Pros:** Aligns to the user's mental model when they have many frames.
- **Cons:** New entity to model (Group → Device many-to-many). New CRUD. Premature without evidence of cluster usage.
- **Effort:** Large. Schema change + UI for group management. ~4-5 days.
---
## 4. Architect's gut-check
🏗️ **Winston:** *Pragmatic.* "From the data side:
- **🅐 (photo-only card + sheet)** — zero schema changes, zero API changes. Pure frontend refactor. Ships fastest. Lowest risk to existing 7.3" beta units.
- **🅑 (device-first tab)** — needs a `GET /api/devices/{id}/photos` endpoint. Trivial to add.
- **🅒 (multi-select bulk)** — needs `PATCH /api/images/bulk-approve` with `[imageIds]` × `[deviceIds]`. Small server lift.
- **🅓ⓔ** — purely frontend.
If we ship one thing, **🅐 is the foundation everything else builds on** — once the per-photo card is compact, layering bulk-select (🅒) or filtering (🅓) on top is additive, not a rewrite.
I would NOT do 🅔 yet — premature abstraction. Wait for actual users with 8+ frames asking for it."
---
## 5. Where the team lands
🎨 **Sally + 📋 John + 🏗️ Winston, in unison:**
**Ship 🅐 first.** It's the smallest change that unblocks scale and **costs nothing** for the existing 1-2-frame users (their card just looks cleaner). The DevicePicker sheet is already built — point the new "manage" tap at it.
**Then 🅒 (multi-select)** as a fast-follow for J1 efficiency. Tap-hold to enter selection, top action bar, batch send. Doesn't need a server endpoint immediately — can client-loop the existing per-image PATCH.
**Defer 🅑 (device-first tab)** until a user explicitly asks "how do I see what's on Grandma's frame?". The compact photo card + DevicePicker handles J3 well enough at N≤5.
**Defer 🅓 (chip filter) and 🅔 (groups)** until usage data says they're worth it.
---
## 6. Open questions for {{user_name}}
🎨 **Sally:** "Before we wireframe — three quick ones:
1. **Status badge wording.** `✓ on 3 of 5 frames` or `3 frames`? Subtle but it sets tone (`✓ on` reads as confirmation; bare `3 frames` reads as info).
2. **Lock indicator placement.** Inside the badge line (`✓ 3/5 · 🔒 Mom's`) or as a corner overlay on the photo (lock icon top-right)?
3. **Tap target.** Does tapping the *photo* open manage, or do we want a dedicated `Manage ▸` chip below it? Photo-tap is friendlier on mobile; dedicated chip is more discoverable."
🎨 **Maya:** "And one for after we wireframe — what's the maximum frame count we should *actually* design for? If it's 'family of five = five frames', design priorities differ from 'church group of forty'."
---
## 7. Next step
If you greenlight 🅐: I'll draft the wireframe + interaction spec, then implement. Estimated 1 working session for the refactor + DevicePicker rewiring.
If you want to riff on the concepts above first, just say the word — we can pull in Carson for a wild-ideas round, or Victor (Innovation Strategist) for a disruptive frame.