← 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">📷&nbsp;&nbsp;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…">📷&nbsp;&nbsp;Scan the label</button>
      <button class="big plain" data-toast="⌨️ Keyboard would open here">⌨️&nbsp;&nbsp;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">🔍&nbsp;&nbsp;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">▢&nbsp;&nbsp;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>