9854688a49
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>
197 lines
7.2 KiB
HTML
197 lines
7.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>Concept 🅐 — Photo + badge</title>
|
|
<link rel="stylesheet" href="shared.css">
|
|
<style>
|
|
.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); padding: var(--space-4); }
|
|
.item { display: flex; flex-direction: column; gap: var(--space-1); }
|
|
.item__photo { position: relative; }
|
|
.item__photo .corner-lock {
|
|
position: absolute; top: var(--space-2); right: var(--space-2);
|
|
background: var(--color-lock); color: white; border-radius: var(--radius-full);
|
|
width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
|
|
font-size: 14px; box-shadow: 0 1px 2px rgba(0,0,0,0.25);
|
|
}
|
|
.item__status {
|
|
display: flex; align-items: center; gap: var(--space-2);
|
|
padding: var(--space-1) var(--space-1);
|
|
font-size: var(--text-xs);
|
|
color: var(--color-text-muted);
|
|
}
|
|
.item__status b { color: var(--color-text); font-weight: 600; }
|
|
.item__status .lock { color: #6b5210; }
|
|
.item__row {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: 2px var(--space-1);
|
|
}
|
|
.item__manage {
|
|
background: transparent; border: 0;
|
|
color: var(--color-primary); font-size: var(--text-xs); font-weight: 600;
|
|
}
|
|
|
|
/* Sheet mock — pinned bottom panel showing the DevicePicker reuse */
|
|
.sheet {
|
|
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
|
|
width: 100%; max-width: 420px;
|
|
background: var(--color-surface);
|
|
border-top: 1px solid var(--color-border);
|
|
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
box-shadow: 0 -8px 24px rgba(58,46,34,0.18);
|
|
padding: var(--space-4);
|
|
transform: translate(-50%, 0);
|
|
transition: transform var(--duration-fast);
|
|
}
|
|
.sheet__handle {
|
|
width: 36px; height: 4px; background: var(--color-border);
|
|
border-radius: 2px; margin: 0 auto var(--space-4);
|
|
}
|
|
.sheet__title {
|
|
font-weight: 700; margin: 0 0 var(--space-3); font-size: var(--text-md);
|
|
}
|
|
.sheet__row {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: var(--space-3) 0; border-bottom: 1px solid var(--color-border);
|
|
}
|
|
.sheet__row:last-child { border-bottom: 0; }
|
|
.sheet__device { font-weight: 600; }
|
|
.sheet__device small { color: var(--color-text-muted); font-weight: 400; }
|
|
.toggle {
|
|
width: 44px; height: 26px; background: var(--color-border);
|
|
border-radius: var(--radius-full); position: relative; transition: background 0.15s;
|
|
border: 0;
|
|
}
|
|
.toggle::after {
|
|
content: ''; position: absolute; top: 3px; left: 3px;
|
|
width: 20px; height: 20px; border-radius: 50%; background: white;
|
|
transition: left 0.15s;
|
|
}
|
|
.toggle--on { background: var(--color-primary); }
|
|
.toggle--on::after { left: 21px; }
|
|
.lock-toggle {
|
|
background: transparent; border: 1px solid var(--color-border);
|
|
color: var(--color-text-muted); padding: 4px 10px;
|
|
border-radius: var(--radius-full); font-size: var(--text-xs);
|
|
}
|
|
.lock-toggle--on { background: var(--color-lock); color: white; border-color: var(--color-lock); }
|
|
.sheet__done {
|
|
background: var(--color-primary); color: var(--color-primary-fg);
|
|
width: 100%; border: 0; padding: 12px;
|
|
border-radius: var(--radius-full); font-weight: 700;
|
|
margin-top: var(--space-4);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="frame">
|
|
<header class="topbar">
|
|
<h1>Library</h1>
|
|
<div class="topbar__tabs">
|
|
<button class="topbar__tab topbar__tab--active">My Photos</button>
|
|
<button class="topbar__tab">Shared</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="note">
|
|
<b>🅐</b> Each photo card is just the image + a one-line status. The lock
|
|
is a corner badge on the photo (lock-icon). Tap any photo to open the
|
|
bottom sheet with device approvals + per-device lock — same UI we already
|
|
use for upload.
|
|
</div>
|
|
|
|
<div class="grid">
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p1"></div>
|
|
<div class="corner-lock" title="Locked on Living Room">🔒</div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>3</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p2"></div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>2</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p3"></div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>5</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p4"></div>
|
|
<div class="corner-lock" title="Locked on Mom's Place">🔒</div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>2</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p5"></div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>2</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
<div class="item">
|
|
<div class="item__photo">
|
|
<div class="photo photo--p6"></div>
|
|
</div>
|
|
<div class="item__row">
|
|
<span class="item__status"><b>3</b>/5 frames</span>
|
|
<button class="item__manage">Manage ▸</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sheet mock (always visible to demo reuse) -->
|
|
<div class="sheet">
|
|
<div class="sheet__handle"></div>
|
|
<div class="sheet__title">Manage frames for this photo</div>
|
|
<div class="sheet__row">
|
|
<div class="sheet__device">Living Room<br><small>Online · last sync 2m ago</small></div>
|
|
<button class="lock-toggle lock-toggle--on">🔒 Locked</button>
|
|
<button class="toggle toggle--on" aria-label="Approved"></button>
|
|
</div>
|
|
<div class="sheet__row">
|
|
<div class="sheet__device">Kitchen<br><small>Online · last sync 5m ago</small></div>
|
|
<button class="lock-toggle">🔓 Rotate</button>
|
|
<button class="toggle toggle--on" aria-label="Approved"></button>
|
|
</div>
|
|
<div class="sheet__row">
|
|
<div class="sheet__device">Bedroom<br><small>Online · last sync 1m ago</small></div>
|
|
<span></span>
|
|
<button class="toggle" aria-label="Not approved"></button>
|
|
</div>
|
|
<div class="sheet__row">
|
|
<div class="sheet__device">Mom's Place<br><small>Online · last sync 3m ago</small></div>
|
|
<button class="lock-toggle">🔓 Rotate</button>
|
|
<button class="toggle toggle--on" aria-label="Approved"></button>
|
|
</div>
|
|
<div class="sheet__row">
|
|
<div class="sheet__device">Cabin<br><small>Offline · last seen 2h ago</small></div>
|
|
<span></span>
|
|
<button class="toggle" aria-label="Not approved"></button>
|
|
</div>
|
|
<button class="sheet__done">Done</button>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|