← back to Dw Photo Capture
public/themes/v12-bottom-tabs.html
195 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v12 — Bottom Tabs</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#eef2f6;
--ink:#16202b;
--muted:#56616f; /* Figma #667383 @80% → darkened for 4.5:1 */
--red:#c8432e; /* Figma #e0533d → darkened so white text passes 4.5:1 */
--card:#ffffff;
--tab-ink:#555555;
--focus:#16202b;
}
*{box-sizing:border-box;}
html,body{margin:0;padding:0;background:#0a0a0a;font-family:'Inter',system-ui,sans-serif;}
.stage{
width:390px;height:780px;margin:24px auto;position:relative;
background:var(--bg);border-radius:36px;overflow:hidden;border:8px solid #000;
box-shadow:0 20px 60px rgba(0,0,0,.5);color:var(--ink);
display:flex;flex-direction:column;
}
@media (max-width:405.98px){
.stage{width:100%;margin:0;border:0;border-radius:0;height:100vh;height:100dvh;min-height:640px;}
}
.screens{flex:1;position:relative;min-height:0;}
.screen{
position:absolute;inset:0;display:none;flex-direction:column;gap:14px;
padding:22px 20px 12px;overflow-y:auto;
}
.screen.is-active{display:flex;}
.step{margin:0;font-size:13px;font-weight:600;color:var(--muted);}
h1{margin:0;font-size:32px;font-weight:700;text-align:center;color:var(--ink);}
h1:focus{outline:none;}
button{font:inherit;cursor:pointer;border:0;min-height:44px;min-width:44px;color:inherit;}
button:focus-visible{outline:3px solid var(--focus);outline-offset:3px;}
.camera{
flex:1;min-height:200px;background:#1c1c1e;border-radius:24px;
display:flex;align-items:center;justify-content:center;color:#fff;
font-size:18px;font-weight:600;position:relative;overflow:hidden;
}
.camera::after{
content:"";position:absolute;inset:18%;border:2px dashed rgba(255,255,255,.35);border-radius:14px;
}
.camera.flash{animation:flash .35s ease-out;}
@keyframes flash{0%{background:#fff;}100%{background:#1c1c1e;}}
.shutter-row{display:flex;justify-content:center;flex-shrink:0;}
.shutter{
width:96px;height:96px;border-radius:50%;background:#fff;padding:8px;
box-shadow:0 2px 8px rgba(0,0,0,.08);
}
.shutter span{display:block;width:100%;height:100%;border-radius:50%;background:var(--red);}
.big{
width:100%;min-height:76px;border-radius:20px;font-size:22px;font-weight:700;
padding:0 16px;flex-shrink:0;
}
.big.primary{background:var(--red);color:#fff;}
.big.plain{background:#fff;color:var(--ink);}
.search{min-height:60px;background:#fff;color:#56616f;}
.section-label{margin:0;font-size:18px;color:var(--muted);text-align:center;}
.card{
width:100%;display:flex;gap:14px;align-items:center;background:var(--card);
border-radius:20px;padding:14px;text-align:left;flex-shrink:0;
}
.sw{width:84px;height:84px;border-radius:14px;flex-shrink:0;}
.card .t{font-size:20px;font-weight:700;color:#222;display:block;}
.card .s{font-size:15px;color:#6b6b6b;display:block;margin-top:4px;} /* Figma #777 → #6b6b6b for 4.5:1 */
.spacer{flex:1;}
.tabbar{
flex-shrink:0;margin:0 20px 16px;background:#fff;border-radius:24px;padding:8px;
display:flex;gap:6px;
}
.tab{
flex:1;min-height:64px;border-radius:18px;background:transparent;color:var(--tab-ink);
font-size:14px;font-weight:700;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1.25;
}
.tab[aria-current="page"]{background:var(--red);color:#fff;}
.tab .ico{font-size:15px;}
.toast{
position:absolute;left:50%;bottom:120px;transform:translateX(-50%) translateY(10px);
background:#16202b;color:#fff;padding:12px 18px;border-radius:14px;font-size:15px;font-weight:600;
opacity:0;visibility:hidden;pointer-events:none;transition:opacity .2s,transform .2s,visibility 0s .2s;max-width:86%;text-align:center;
}
.toast.show{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);transition:opacity .2s,transform .2s,visibility 0s;}
@media (prefers-reduced-motion:reduce){ .toast,.toast.show{transition:none} }
</style>
</head>
<body>
<main class="stage" id="app">
<div class="screens">
<section class="screen is-active" data-screen="1" aria-labelledby="h1-1">
<p class="step">1 / 4 · New tab</p>
<h1 id="h1-1">New item</h1>
<div class="camera" id="cam1" role="img" aria-label="Camera viewfinder">📷 point at the sample</div>
<div class="shutter-row">
<button class="shutter" aria-label="Take photo" data-flash="cam1" data-toast="📸 Saved as a draft — nice!"><span></span></button>
</div>
</section>
<section class="screen" data-screen="2" aria-labelledby="h1-2">
<p class="step">2 / 4 · Fix tab</p>
<h1 id="h1-2">Fix an item</h1>
<button class="big primary" data-toast="📷 Scanning the label…">📷 Scan the label</button>
<button class="big plain" data-toast="⌨️ Keyboard would open here">⌨️ Type the code</button>
<p class="section-label">Recently fixed</p>
<div class="card">
<div class="sw" style="background:#c9a24b"></div>
<div><span class="t">Damask — Gold</span><span class="s">York · 2 min ago</span></div>
</div>
</section>
<section class="screen" data-screen="3" aria-labelledby="h1-3">
<p class="step">3 / 4 · Find tab</p>
<h1 id="h1-3">Find</h1>
<button class="big search" data-toast="🔍 Search would open here">🔍 Search…</button>
<button class="card" data-toast="Linen — Oat · Kravet">
<span class="sw" style="background:#d8cbb3"></span>
<span><span class="t">Linen — Oat</span><span class="s">Kravet</span></span>
</button>
<button class="card" data-toast="Stripe — Navy · Schumacher">
<span class="sw" style="background:#1f3a5f"></span>
<span><span class="t">Stripe — Navy</span><span class="s">Schumacher</span></span>
</button>
<button class="card" data-toast="Floral — Rose · Thibaut">
<span class="sw" style="background:#d98c9a"></span>
<span><span class="t">Floral — Rose</span><span class="s">Thibaut</span></span>
</button>
</section>
<section class="screen" data-screen="4" aria-labelledby="h1-4">
<p class="step">4 / 4 · Sample tab</p>
<h1 id="h1-4">Sample came in</h1>
<div class="camera" style="flex:0 0 auto;height:260px" role="img" aria-label="Camera viewfinder">▢ scan the box label</div>
<div class="card">
<div class="sw" style="background:#d8cbb3"></div>
<div><span class="t">Linen — Oat</span><span class="s">Kravet · waiting 3 days</span></div>
</div>
<button class="big primary" style="min-height:72px" data-toast="✓ Received — printing sticker 🖨️">Mark received ✓</button>
</section>
</div>
<nav class="tabbar" aria-label="Sections">
<button class="tab" data-go="1" aria-current="page"><span class="ico" aria-hidden="true">➕</span>New</button>
<button class="tab" data-go="2"><span class="ico" aria-hidden="true">🔄</span>Fix</button>
<button class="tab" data-go="3"><span class="ico" aria-hidden="true">🔍</span>Find</button>
<button class="tab" data-go="4"><span class="ico" aria-hidden="true">📦</span>Sample</button>
</nav>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
</main>
<script>
const screens = Array.from(document.querySelectorAll('[data-screen]'));
const tabs = Array.from(document.querySelectorAll('.tab'));
const toastEl = document.getElementById('toast');
let toastTimer = null;
function go(n){
n = String(n);
screens.forEach(s => s.classList.toggle('is-active', s.dataset.screen === n));
tabs.forEach(t => {
if (t.dataset.go === n) t.setAttribute('aria-current','page');
else t.removeAttribute('aria-current');
});
}
function toast(msg){
toastEl.textContent = msg;
toastEl.classList.add('show');
clearTimeout(toastTimer);
toastTimer = setTimeout(() => toastEl.classList.remove('show'), 1600);
}
document.addEventListener('click', (e) => {
const b = e.target.closest('button');
if (!b) return;
if (b.dataset.flash){
const cam = document.getElementById(b.dataset.flash);
cam.classList.remove('flash'); void cam.offsetWidth; cam.classList.add('flash');
}
if (b.dataset.toast) toast(b.dataset.toast);
if (b.dataset.go) go(b.dataset.go);
});
</script>
<script>window.__theme = {id:'v12', name:'Bottom Tabs', screens:4};</script>
</body>
</html>