[object Object]

← back to Brand Selector Viewer

initial snapshot — gitify all builds (CLAUDE.md rule 2026-05-06)

75494628b52e61b1e0c7784aa845b4360ef8ad2c · 2026-05-06 10:20:33 -0700 · Steve

Files touched

Diff

commit 75494628b52e61b1e0c7784aa845b4360ef8ad2c
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed May 6 10:20:33 2026 -0700

    initial snapshot — gitify all builds (CLAUDE.md rule 2026-05-06)
---
 .gitignore                      |  25 ++
 horsemen.html                   | 530 ++++++++++++++++++++++++++++++++++++++++
 index.html                      | 486 ++++++++++++++++++++++++++++++++++++
 magic-app.html                  | 234 ++++++++++++++++++
 outputs/canva-brief.md          |  44 ++++
 outputs/figma-tokens.json       | 109 +++++++++
 outputs/magic-BrandSelector.tsx | 189 ++++++++++++++
 outputs/paper-summary.md        |  34 +++
 8 files changed, 1651 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ae81e0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+node_modules/
+.env
+.env.*
+!.env.example
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
+.cache/
+.parcel-cache/
+coverage/
+__pycache__/
+*.pyc
+*.pyo
+.venv/
+venv/
+.pytest_cache/
+.ruff_cache/
+.idea/
+.vscode/
+*.swp
+.qodo/
+out/
diff --git a/horsemen.html b/horsemen.html
new file mode 100644
index 0000000..565c012
--- /dev/null
+++ b/horsemen.html
@@ -0,0 +1,530 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1" />
+<title>Four Horsemen — Brand Selector</title>
+<style>
+  :root {
+    --bg: #0b0b0d;
+    --bg-2: #131318;
+    --bg-3: #1a1a22;
+    --line: #2a2a35;
+    --text: #f4f4f5;
+    --muted: #9c9caa;
+    --accent: #d4af37;
+    --paper: #ff8a50;
+    --figma:  #a259ff;
+    --magic:  #4ade80;
+    --canva:  #00c4cc;
+  }
+  * { box-sizing: border-box; }
+  html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text); }
+  body {
+    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    min-height: 100vh;
+  }
+  header {
+    padding: 36px 40px 22px;
+    border-bottom: 1px solid var(--line);
+    display: flex;
+    align-items: flex-end;
+    justify-content: space-between;
+    gap: 24px;
+    flex-wrap: wrap;
+  }
+  header .title {
+    font-family: "Didot", "Bodoni 72", Georgia, serif;
+    font-weight: 400;
+    font-size: 34px;
+    letter-spacing: 0.5px;
+    margin: 0;
+  }
+  header .eyebrow {
+    color: var(--accent);
+    font-size: 10px;
+    letter-spacing: 3px;
+    text-transform: uppercase;
+    margin-bottom: 6px;
+  }
+  header .sub {
+    color: var(--muted);
+    font-size: 13px;
+    margin-top: 6px;
+    font-style: italic;
+  }
+  .legend {
+    display: flex;
+    gap: 16px;
+    flex-wrap: wrap;
+  }
+  .legend .chip {
+    display: flex;
+    align-items: center;
+    gap: 6px;
+    font-size: 11px;
+    color: var(--muted);
+    text-transform: uppercase;
+    letter-spacing: 1.5px;
+  }
+  .legend .dot {
+    width: 8px; height: 8px; border-radius: 50%;
+  }
+
+  main {
+    padding: 28px;
+    display: grid;
+    gap: 22px;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+  }
+  @media (max-width: 1100px) { main { grid-template-columns: 1fr; } }
+
+  .pane {
+    background: var(--bg-2);
+    border: 1px solid var(--line);
+    border-radius: 16px;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+    min-height: 580px;
+  }
+  .pane-head {
+    padding: 16px 20px;
+    border-bottom: 1px solid var(--line);
+    display: flex;
+    align-items: center;
+    gap: 14px;
+    background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
+  }
+  .pane-head .badge {
+    width: 30px; height: 30px;
+    border-radius: 8px;
+    display: flex; align-items: center; justify-content: center;
+    font-family: "Didot", Georgia, serif;
+    font-size: 16px;
+    color: #0b0b0d;
+    font-weight: 700;
+  }
+  .pane-head h2 {
+    margin: 0;
+    font-family: "Didot", Georgia, serif;
+    font-weight: 400;
+    font-size: 20px;
+  }
+  .pane-head .role {
+    color: var(--muted);
+    font-size: 11px;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+  }
+  .pane-head .status {
+    margin-left: auto;
+    font-size: 10px;
+    text-transform: uppercase;
+    letter-spacing: 1.5px;
+    padding: 4px 10px;
+    border-radius: 999px;
+    border: 1px solid var(--line);
+    color: var(--muted);
+  }
+  .pane-head .status.live    { color: var(--magic); border-color: var(--magic); }
+  .pane-head .status.partial { color: var(--accent); border-color: var(--accent); }
+  .pane-head .status.spec    { color: #9bb5ff; border-color: #9bb5ff; }
+  .pane-head .status.brief   { color: var(--canva); border-color: var(--canva); }
+
+  .pane-body {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    min-height: 0;
+  }
+  .preview {
+    background: #07070a;
+    border-bottom: 1px solid var(--line);
+    min-height: 260px;
+    overflow: hidden;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .preview iframe {
+    width: 100%;
+    height: 320px;
+    border: 0;
+    background: #07070a;
+  }
+  .preview .placeholder {
+    padding: 32px;
+    color: var(--muted);
+    text-align: center;
+  }
+  .preview img { max-width: 100%; max-height: 320px; display: block; }
+
+  .meta {
+    padding: 16px 20px;
+    display: flex;
+    flex-direction: column;
+    gap: 10px;
+  }
+  .meta .row {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    gap: 12px;
+    font-size: 12px;
+  }
+  .meta .row .k {
+    color: var(--muted);
+    text-transform: uppercase;
+    letter-spacing: 1.5px;
+    font-size: 10px;
+  }
+  .meta .row .v {
+    color: var(--text);
+    font-family: "SF Mono", Menlo, monospace;
+    font-size: 11px;
+    text-align: right;
+    word-break: break-all;
+  }
+  .meta a {
+    color: var(--accent);
+    text-decoration: none;
+    font-family: "SF Mono", Menlo, monospace;
+    font-size: 11px;
+    word-break: break-all;
+  }
+  .meta a:hover { text-decoration: underline; }
+
+  .actions {
+    padding: 14px 20px;
+    border-top: 1px solid var(--line);
+    display: flex;
+    gap: 8px;
+    flex-wrap: wrap;
+    background: var(--bg-3);
+  }
+  .btn {
+    background: var(--bg-2);
+    border: 1px solid var(--line);
+    color: var(--text);
+    padding: 7px 12px;
+    border-radius: 999px;
+    font-size: 11px;
+    letter-spacing: 0.5px;
+    cursor: pointer;
+    text-decoration: none;
+    display: inline-block;
+  }
+  .btn:hover { border-color: var(--accent); color: var(--accent); }
+  .btn.primary {
+    background: var(--accent); color: #111; border-color: var(--accent);
+  }
+
+  .code {
+    background: #07070a;
+    border-top: 1px solid var(--line);
+    padding: 14px 20px;
+    overflow: auto;
+    max-height: 220px;
+    font-family: "SF Mono", Menlo, monospace;
+    font-size: 11px;
+    line-height: 1.55;
+    color: #d4d4d8;
+    white-space: pre;
+  }
+
+  /* Color-coded pane accents */
+  .pane.paper  .pane-head .badge { background: var(--paper); }
+  .pane.figma  .pane-head .badge { background: var(--figma); color: #fff; }
+  .pane.magic  .pane-head .badge { background: var(--magic); }
+  .pane.canva  .pane-head .badge { background: var(--canva); }
+
+  .pane.paper  { border-top: 2px solid var(--paper); }
+  .pane.figma  { border-top: 2px solid var(--figma); }
+  .pane.magic  { border-top: 2px solid var(--magic); }
+  .pane.canva  { border-top: 2px solid var(--canva); }
+
+  /* Modal */
+  .modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,0.78); display:none; align-items:center; justify-content:center; z-index:200; padding:24px; }
+  .modal-bg.show { display: flex; }
+  .modal { background: var(--bg-2); border: 1px solid var(--line); border-radius: 14px; padding: 22px; max-width: 980px; width: 100%; max-height: 88vh; display: flex; flex-direction: column; }
+  .modal h3 { margin: 0 0 12px; font-family: "Didot", Georgia, serif; font-weight: 400; font-size: 20px; }
+  .modal pre { background:#07070a; border:1px solid var(--line); border-radius:8px; padding:16px; overflow:auto; font-size:11.5px; line-height:1.55; color:#d4d4d8; flex:1; margin: 0; }
+  .modal .row { display:flex; gap:8px; justify-content:flex-end; margin-top:14px; }
+
+  /* Footer */
+  footer {
+    padding: 28px 40px 60px;
+    color: var(--muted);
+    font-size: 12px;
+    border-top: 1px solid var(--line);
+    margin-top: 32px;
+  }
+  footer .pipeline {
+    display: flex;
+    gap: 14px;
+    align-items: center;
+    flex-wrap: wrap;
+    margin-top: 12px;
+  }
+  footer .step {
+    border: 1px solid var(--line);
+    padding: 8px 14px;
+    border-radius: 999px;
+    font-size: 11px;
+    letter-spacing: 0.5px;
+    color: var(--text);
+  }
+  footer .arrow { color: var(--accent); }
+</style>
+</head>
+<body>
+
+<header>
+  <div>
+    <div class="eyebrow">Four Horsemen · Brand Selector</div>
+    <h1 class="title">All four UI companies, side by side</h1>
+    <p class="sub">Paper · Figma · 21st.dev Magic · Canva — outputs for the Brand Selector / Figma Build Source picker</p>
+  </div>
+  <div class="legend">
+    <div class="chip"><span class="dot" style="background:var(--paper)"></span>Paper</div>
+    <div class="chip"><span class="dot" style="background:var(--figma)"></span>Figma</div>
+    <div class="chip"><span class="dot" style="background:var(--magic)"></span>Magic</div>
+    <div class="chip"><span class="dot" style="background:var(--canva)"></span>Canva</div>
+  </div>
+</header>
+
+<main>
+
+  <!-- PAPER -->
+  <article class="pane paper">
+    <div class="pane-head">
+      <div class="badge">P</div>
+      <div>
+        <div class="role">Design Lab — Interactive prototype</div>
+        <h2>Paper.design</h2>
+      </div>
+      <div class="status live">Complete</div>
+    </div>
+    <div class="pane-body">
+      <div class="preview" id="paper-preview" style="padding:14px;">
+        <div style="width:100%; max-height:300px; overflow:hidden; border-radius:8px; border:1px solid #2a2a35; background:#0b0b0d; padding:14px 18px;">
+          <div style="font-size:8px;letter-spacing:2px;text-transform:uppercase;color:#d4af37;">● Figma Build Source · v1</div>
+          <div style="font-family:Didot,serif;font-size:24px;color:#f4f4f5;margin-top:2px;line-height:1;">Brand Selector</div>
+          <div style="font-style:italic;color:#9c9caa;font-size:9px;margin-top:2px;">Pick the labels that will source the next Figma build</div>
+          <div style="margin-top:10px;font-family:Didot,serif;font-size:11px;color:#d4af37;">I. Fashion <span style="font-size:7px;letter-spacing:1.5px;color:#9c9caa;text-transform:uppercase;font-family:Inter,sans-serif;margin-left:6px;">Top 20</span></div>
+          <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:3px;margin-top:6px;">
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Louis Vuitton</div>
+            <div style="background:linear-gradient(135deg,rgba(212,175,55,0.15),#1a1a22);border:1px solid #d4af37;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Chanel ✓</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Hermès</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Gucci</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Prada</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Dior</div>
+            <div style="background:linear-gradient(135deg,rgba(212,175,55,0.15),#1a1a22);border:1px solid #d4af37;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Versace ✓</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Burberry</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Saint L.</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Balenciaga</div>
+          </div>
+          <div style="margin-top:10px;font-family:Didot,serif;font-size:11px;color:#d4af37;">II. Wallcovering <span style="font-size:7px;letter-spacing:1.5px;color:#9c9caa;text-transform:uppercase;font-family:Inter,sans-serif;margin-left:6px;">Top 10</span></div>
+          <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:3px;margin-top:6px;">
+            <div style="background:linear-gradient(135deg,rgba(212,175,55,0.15),#1a1a22);border:1px solid #d4af37;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Phillip J. ✓</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Schumacher</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Cole &amp; Son</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Thibaut</div>
+            <div style="background:#131318;border:1px solid #2a2a35;border-radius:3px;padding:5px;font-family:Didot,serif;font-size:8px;color:#f4f4f5;">Zoffany</div>
+          </div>
+          <div style="display:flex;justify-content:space-between;align-items:center;margin-top:12px;padding-top:8px;border-top:1px solid #2a2a35;">
+            <div style="font-size:8px;color:#9c9caa;"><span style="color:#d4af37;font-family:Didot,serif;">3</span> selected · Chanel · Versace · Phillip Jeffries</div>
+            <div style="background:#d4af37;color:#111;font-size:8px;padding:3px 8px;border-radius:99px;">Send to Figma Build →</div>
+          </div>
+        </div>
+      </div>
+      <div class="meta">
+        <div class="row"><span class="k">File</span><span class="v">novasuede</span></div>
+        <div class="row"><span class="k">Artboard</span><span class="v">1-0 · 1440 × fit-content (~2200)</span></div>
+        <div class="row"><span class="k">Layers</span><span class="v">30 cards · 3 selected · sticky dock</span></div>
+        <div class="row"><span class="k">Fonts</span><span class="v">Didot · Cormorant · Inter</span></div>
+        <div class="row"><span class="k">URL</span><a href="https://app.paper.design/file/01KQA7KRG8FDP7RH2WXPJYDFNQ" target="_blank">app.paper.design/…01KQA7KRG8FDP7RH2WXPJYDFNQ</a></div>
+      </div>
+      <div class="actions">
+        <a class="btn primary" href="https://app.paper.design/file/01KQA7KRG8FDP7RH2WXPJYDFNQ" target="_blank">Open in Paper →</a>
+        <button class="btn" data-view="paper">View summary</button>
+      </div>
+    </div>
+  </article>
+
+  <!-- FIGMA -->
+  <article class="pane figma">
+    <div class="pane-head">
+      <div class="badge">F</div>
+      <div>
+        <div class="role">System of record — Tokens & components</div>
+        <h2>Figma</h2>
+      </div>
+      <div class="status live">Live design imported</div>
+    </div>
+    <div class="pane-body">
+      <div class="preview">
+        <iframe src="https://www.figma.com/embed?embed_host=brand-selector&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2FDr1u75PIPSjMJTb2eidqUu%3Fnode-id%3D24-2" allowfullscreen></iframe>
+      </div>
+      <div class="meta">
+        <div class="row"><span class="k">File</span><span class="v">Dr1u75PIPSjMJTb2eidqUu</span></div>
+        <div class="row"><span class="k">Node</span><span class="v">24:2 · captured from magic-app.html</span></div>
+        <div class="row"><span class="k">Auth</span><span class="v">steve@designerwallcoverings.com ✓</span></div>
+        <div class="row"><span class="k">Tokens</span><span class="v">color · type · radius · spacing · components</span></div>
+        <div class="row"><span class="k">Schema</span><span class="v">figma-build/brand-selection.v1</span></div>
+        <div class="row"><span class="k">URL</span><a href="https://www.figma.com/design/Dr1u75PIPSjMJTb2eidqUu?node-id=24-2" target="_blank">figma.com/design/…?node-id=24-2</a></div>
+      </div>
+      <div class="actions">
+        <a class="btn primary" href="https://www.figma.com/design/Dr1u75PIPSjMJTb2eidqUu?node-id=24-2" target="_blank">Open in Figma →</a>
+        <button class="btn" data-view="figma">View token JSON</button>
+        <a class="btn" href="outputs/figma-tokens.json" target="_blank">Raw .json</a>
+      </div>
+    </div>
+  </article>
+
+  <!-- MAGIC -->
+  <article class="pane magic">
+    <div class="pane-head">
+      <div class="badge">M</div>
+      <div>
+        <div class="role">Production component — React/Tailwind</div>
+        <h2>21st.dev Magic</h2>
+      </div>
+      <div class="status live">Component ready</div>
+    </div>
+    <div class="pane-body">
+      <div class="preview">
+        <iframe src="magic-app.html"></iframe>
+      </div>
+      <div class="meta">
+        <div class="row"><span class="k">File</span><span class="v">outputs/magic-BrandSelector.tsx</span></div>
+        <div class="row"><span class="k">Stack</span><span class="v">React 18 + Tailwind, props-driven</span></div>
+        <div class="row"><span class="k">Export</span><span class="v">default BrandSelector</span></div>
+        <div class="row"><span class="k">Live demo</span><a href="magic-app.html" target="_blank">magic-app.html (live React)</a></div>
+        <div class="row"><span class="k">Plain HTML</span><a href="index.html" target="_blank">index.html (vanilla version)</a></div>
+      </div>
+      <div class="actions">
+        <a class="btn primary" href="magic-app.html" target="_blank">Open live React →</a>
+        <button class="btn" data-view="magic">View component code</button>
+        <a class="btn" href="outputs/magic-BrandSelector.tsx" target="_blank">Raw .tsx</a>
+        <a class="btn" href="index.html" target="_blank">Vanilla HTML</a>
+      </div>
+    </div>
+  </article>
+
+  <!-- CANVA -->
+  <article class="pane canva">
+    <div class="pane-head">
+      <div class="badge">C</div>
+      <div>
+        <div class="role">Marketing & exports — Brand templates</div>
+        <h2>Canva</h2>
+      </div>
+      <div class="status brief">Brief drafted</div>
+    </div>
+    <div class="pane-body">
+      <div class="preview">
+        <div class="placeholder" style="text-align:left;padding:28px;">
+          <div style="font-family:Didot,serif;font-size:64px;color:#f4f4f5;line-height:1;text-align:center;">Brand Selector</div>
+          <div style="font-style:italic;color:#9c9caa;font-size:14px;text-align:center;margin-top:8px;">Top 20 fashion · Top 10 wallcovering</div>
+          <div style="display:grid;grid-template-columns:repeat(6,1fr);gap:6px;margin-top:22px;">
+            <!-- 18 mini name plates as a hint -->
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Louis Vuitton</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Chanel</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Hermès</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Gucci</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Prada</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Dior</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Versace</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Burberry</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Saint Laurent</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Balenciaga</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Bottega</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Fendi</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Schumacher</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Cole &amp; Son</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Thibaut</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Zoffany</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">Phillip Jeffries</div>
+            <div style="font-family:Didot,serif;font-size:10px;text-align:center;padding:8px 4px;border:1px solid #2a2a35;border-radius:4px;color:#d4d4d8;">de Gournay</div>
+          </div>
+          <div style="margin-top:14px;color:#5a5a6a;font-size:10px;text-align:center;">Mock of brand-template tile · 1080 × 1350</div>
+        </div>
+      </div>
+      <div class="meta">
+        <div class="row"><span class="k">Template</span><span class="v">dw-brand-selector-v1 (proposed)</span></div>
+        <div class="row"><span class="k">Formats</span><span class="v">IG 1080×1350 · LI 1200×628 · PDF</span></div>
+        <div class="row"><span class="k">Auth</span><span class="v">awaiting `canva login`</span></div>
+        <div class="row"><span class="k">Brief</span><a href="outputs/canva-brief.md" target="_blank">outputs/canva-brief.md</a></div>
+      </div>
+      <div class="actions">
+        <a class="btn primary" href="https://canva.com/" target="_blank">Open Canva →</a>
+        <button class="btn" data-view="canva">View brief</button>
+      </div>
+    </div>
+  </article>
+
+</main>
+
+<footer>
+  <div>The pipeline:</div>
+  <div class="pipeline">
+    <span class="step">Paper · prototype</span>
+    <span class="arrow">→</span>
+    <span class="step">Figma · tokens + live design</span>
+    <span class="arrow">→</span>
+    <span class="step">Magic · component</span>
+    <span class="arrow">→</span>
+    <span class="step">Canva · marketing</span>
+    <span class="arrow">→</span>
+    <span class="step" style="border-color:var(--accent);color:var(--accent);">designerwallcoverings.com / build</span>
+  </div>
+</footer>
+
+<div class="modal-bg" id="modal">
+  <div class="modal">
+    <h3 id="modal-title">Output</h3>
+    <pre id="modal-body"></pre>
+    <div class="row">
+      <button class="btn" id="copy">Copy</button>
+      <button class="btn primary" id="close">Close</button>
+    </div>
+  </div>
+</div>
+
+<script>
+  const sources = {
+    paper: "outputs/paper-summary.md",
+    figma: "outputs/figma-tokens.json",
+    magic: "outputs/magic-BrandSelector.tsx",
+    canva: "outputs/canva-brief.md",
+  };
+  const titles = {
+    paper: "Paper — build summary",
+    figma: "Figma — design tokens",
+    magic: "Magic — BrandSelector.tsx",
+    canva: "Canva — marketing brief",
+  };
+
+  document.body.addEventListener("click", async (e) => {
+    const t = e.target.closest("[data-view]");
+    if (!t) return;
+    const k = t.dataset.view;
+    const r = await fetch(sources[k]);
+    const text = await r.text();
+    document.getElementById("modal-title").textContent = titles[k];
+    document.getElementById("modal-body").textContent = text;
+    document.getElementById("modal").classList.add("show");
+  });
+  document.getElementById("close").onclick = () => document.getElementById("modal").classList.remove("show");
+  document.getElementById("copy").onclick = async () => {
+    await navigator.clipboard.writeText(document.getElementById("modal-body").textContent);
+    document.getElementById("copy").textContent = "Copied";
+    setTimeout(() => document.getElementById("copy").textContent = "Copy", 1500);
+  };
+</script>
+</body>
+</html>
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..2bd31dc
--- /dev/null
+++ b/index.html
@@ -0,0 +1,486 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1" />
+<title>Brand Selector — Figma Build Source</title>
+<style>
+  :root {
+    --bg: #0b0b0d;
+    --bg-2: #131318;
+    --bg-3: #1a1a22;
+    --line: #2a2a35;
+    --text: #f4f4f5;
+    --muted: #9c9caa;
+    --accent: #d4af37;
+    --accent-2: #c89b3d;
+    --ok: #4ade80;
+    --danger: #f87171;
+    --radius: 14px;
+  }
+  * { box-sizing: border-box; }
+  html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text); }
+  body {
+    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    min-height: 100vh;
+    padding-bottom: 120px;
+  }
+  header {
+    padding: 36px 40px 20px;
+    border-bottom: 1px solid var(--line);
+    display: flex;
+    align-items: flex-end;
+    justify-content: space-between;
+    gap: 24px;
+    flex-wrap: wrap;
+  }
+  header h1 {
+    margin: 0;
+    font-family: "Didot", "Bodoni 72", Georgia, serif;
+    font-weight: 400;
+    font-size: 32px;
+    letter-spacing: 0.5px;
+  }
+  header p {
+    margin: 6px 0 0;
+    color: var(--muted);
+    font-size: 13px;
+    letter-spacing: 0.4px;
+  }
+  .stats {
+    display: flex;
+    gap: 28px;
+    align-items: center;
+  }
+  .stat {
+    text-align: right;
+  }
+  .stat .num {
+    font-family: "Didot", "Bodoni 72", Georgia, serif;
+    font-size: 28px;
+    color: var(--accent);
+  }
+  .stat .lbl {
+    font-size: 10px;
+    text-transform: uppercase;
+    letter-spacing: 1.5px;
+    color: var(--muted);
+  }
+  main { padding: 28px 40px; }
+  section + section { margin-top: 44px; }
+  section h2 {
+    margin: 0 0 4px;
+    font-family: "Didot", "Bodoni 72", Georgia, serif;
+    font-weight: 400;
+    font-size: 22px;
+  }
+  section .sub {
+    color: var(--muted);
+    font-size: 12px;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    margin-bottom: 18px;
+  }
+  .toolbar {
+    display: flex;
+    gap: 8px;
+    margin-bottom: 18px;
+    flex-wrap: wrap;
+  }
+  .btn {
+    background: var(--bg-2);
+    border: 1px solid var(--line);
+    color: var(--text);
+    padding: 8px 14px;
+    border-radius: 999px;
+    font-size: 12px;
+    letter-spacing: 0.5px;
+    cursor: pointer;
+    transition: all 0.15s ease;
+  }
+  .btn:hover { border-color: var(--accent); color: var(--accent); }
+  .btn.primary {
+    background: var(--accent);
+    color: #111;
+    border-color: var(--accent);
+  }
+  .btn.primary:hover { background: var(--accent-2); color: #111; }
+  .grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+    gap: 14px;
+  }
+  .card {
+    background: var(--bg-2);
+    border: 1px solid var(--line);
+    border-radius: var(--radius);
+    padding: 18px 18px 16px;
+    cursor: pointer;
+    transition: all 0.15s ease;
+    position: relative;
+    overflow: hidden;
+    min-height: 130px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+  }
+  .card:hover {
+    border-color: #4a4a5a;
+    transform: translateY(-2px);
+  }
+  .card.selected {
+    border-color: var(--accent);
+    background: linear-gradient(135deg, rgba(212,175,55,0.08), var(--bg-3));
+    box-shadow: 0 0 0 1px var(--accent) inset;
+  }
+  .card .check {
+    position: absolute;
+    top: 12px;
+    right: 12px;
+    width: 22px;
+    height: 22px;
+    border-radius: 50%;
+    border: 1.5px solid var(--line);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 12px;
+    color: transparent;
+    transition: all 0.15s ease;
+  }
+  .card.selected .check {
+    background: var(--accent);
+    border-color: var(--accent);
+    color: #111;
+  }
+  .card .name {
+    font-family: "Didot", "Bodoni 72", Georgia, serif;
+    font-size: 19px;
+    line-height: 1.15;
+    letter-spacing: 0.3px;
+    padding-right: 30px;
+  }
+  .card .meta {
+    margin-top: 12px;
+    display: flex;
+    gap: 8px;
+    flex-wrap: wrap;
+    align-items: center;
+  }
+  .tag {
+    font-size: 9.5px;
+    text-transform: uppercase;
+    letter-spacing: 1.2px;
+    color: var(--muted);
+    border: 1px solid var(--line);
+    padding: 3px 8px;
+    border-radius: 999px;
+  }
+  .swatch-row {
+    display: flex;
+    gap: 4px;
+    margin-top: 10px;
+  }
+  .swatch {
+    width: 18px;
+    height: 18px;
+    border-radius: 4px;
+    border: 1px solid rgba(255,255,255,0.08);
+  }
+  /* Footer dock */
+  .dock {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: rgba(11,11,13,0.92);
+    backdrop-filter: blur(14px);
+    -webkit-backdrop-filter: blur(14px);
+    border-top: 1px solid var(--line);
+    padding: 14px 40px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 16px;
+    z-index: 100;
+  }
+  .dock .summary {
+    display: flex;
+    gap: 18px;
+    align-items: center;
+    flex-wrap: wrap;
+    font-size: 13px;
+  }
+  .dock .pill {
+    background: var(--bg-3);
+    padding: 6px 12px;
+    border-radius: 999px;
+    color: var(--muted);
+    font-size: 12px;
+  }
+  .dock .pill strong { color: var(--accent); margin-right: 4px; font-family: "Didot", Georgia, serif; }
+  .dock .actions { display: flex; gap: 8px; }
+  /* Modal */
+  .modal-bg {
+    position: fixed;
+    inset: 0;
+    background: rgba(0,0,0,0.7);
+    display: none;
+    align-items: center;
+    justify-content: center;
+    z-index: 200;
+    padding: 24px;
+  }
+  .modal-bg.show { display: flex; }
+  .modal {
+    background: var(--bg-2);
+    border: 1px solid var(--line);
+    border-radius: var(--radius);
+    padding: 24px;
+    max-width: 760px;
+    width: 100%;
+    max-height: 80vh;
+    overflow: auto;
+  }
+  .modal h3 {
+    margin: 0 0 12px;
+    font-family: "Didot", Georgia, serif;
+    font-weight: 400;
+    font-size: 22px;
+  }
+  pre {
+    background: #07070a;
+    border: 1px solid var(--line);
+    border-radius: 8px;
+    padding: 16px;
+    overflow: auto;
+    font-size: 12px;
+    line-height: 1.5;
+    color: #d4d4d8;
+    max-height: 50vh;
+  }
+  .toast {
+    position: fixed;
+    bottom: 90px;
+    left: 50%;
+    transform: translateX(-50%) translateY(20px);
+    background: var(--ok);
+    color: #06280f;
+    padding: 10px 18px;
+    border-radius: 999px;
+    font-size: 13px;
+    font-weight: 500;
+    opacity: 0;
+    transition: all 0.25s ease;
+    pointer-events: none;
+    z-index: 300;
+  }
+  .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
+</style>
+</head>
+<body>
+
+<header>
+  <div>
+    <h1>Brand Selector</h1>
+    <p>Pick the labels that will source the next Figma build · Top 20 fashion · Top 10 wallcovering</p>
+  </div>
+  <div class="stats">
+    <div class="stat"><div class="num" id="stat-fashion">0</div><div class="lbl">Fashion</div></div>
+    <div class="stat"><div class="num" id="stat-wall">0</div><div class="lbl">Wallcovering</div></div>
+  </div>
+</header>
+
+<main>
+  <section>
+    <h2>Fashion</h2>
+    <div class="sub">Top 20 — Luxury &amp; Iconic Houses</div>
+    <div class="toolbar">
+      <button class="btn" data-action="select-all" data-cat="fashion">Select all 20</button>
+      <button class="btn" data-action="clear" data-cat="fashion">Clear</button>
+      <button class="btn" data-action="top5" data-cat="fashion">Top 5 only</button>
+    </div>
+    <div class="grid" id="grid-fashion"></div>
+  </section>
+
+  <section>
+    <h2>Wallcovering</h2>
+    <div class="sub">Top 10 — Heritage &amp; Designer Houses</div>
+    <div class="toolbar">
+      <button class="btn" data-action="select-all" data-cat="wall">Select all 10</button>
+      <button class="btn" data-action="clear" data-cat="wall">Clear</button>
+    </div>
+    <div class="grid" id="grid-wall"></div>
+  </section>
+</main>
+
+<div class="dock">
+  <div class="summary">
+    <span class="pill"><strong id="dock-total">0</strong>selected</span>
+    <span class="pill" id="dock-list" style="max-width:580px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">none</span>
+  </div>
+  <div class="actions">
+    <button class="btn" id="btn-clear-all">Clear all</button>
+    <button class="btn" id="btn-preview">Preview JSON</button>
+    <button class="btn primary" id="btn-figma">Send to Figma Build →</button>
+  </div>
+</div>
+
+<div class="modal-bg" id="modal">
+  <div class="modal">
+    <h3>Figma build payload</h3>
+    <p style="color:var(--muted);font-size:12px;margin:0 0 12px;">Paste this into Paper / Figma plugin input, or feed it to the four-horsemen pipeline.</p>
+    <pre id="modal-json"></pre>
+    <div style="display:flex;gap:8px;margin-top:14px;justify-content:flex-end;">
+      <button class="btn" id="btn-copy">Copy JSON</button>
+      <button class="btn" id="btn-download">Download .json</button>
+      <button class="btn primary" id="btn-close">Close</button>
+    </div>
+  </div>
+</div>
+
+<div class="toast" id="toast">Copied</div>
+
+<script>
+const FASHION = [
+  { name: "Louis Vuitton", country: "FR", founded: 1854, palette: ["#5d3a22","#d4b886","#1a1a1a"] },
+  { name: "Chanel",        country: "FR", founded: 1910, palette: ["#000000","#ffffff","#c9a96e"] },
+  { name: "Hermès",        country: "FR", founded: 1837, palette: ["#f37021","#1a1a1a","#f4e7d3"] },
+  { name: "Gucci",         country: "IT", founded: 1921, palette: ["#006341","#a01c1f","#d4af37"] },
+  { name: "Prada",         country: "IT", founded: 1913, palette: ["#000000","#8b8680","#e8e4dc"] },
+  { name: "Dior",          country: "FR", founded: 1946, palette: ["#1a1a1a","#c8a883","#ffffff"] },
+  { name: "Versace",       country: "IT", founded: 1978, palette: ["#d4af37","#000000","#a01c1f"] },
+  { name: "Burberry",      country: "UK", founded: 1856, palette: ["#a08661","#000000","#c1272d"] },
+  { name: "Saint Laurent", country: "FR", founded: 1961, palette: ["#000000","#d4b886","#ffffff"] },
+  { name: "Balenciaga",    country: "ES", founded: 1919, palette: ["#000000","#5a5a5a","#ffffff"] },
+  { name: "Bottega Veneta",country: "IT", founded: 1966, palette: ["#3d5a2c","#c9b27a","#1a1a1a"] },
+  { name: "Fendi",         country: "IT", founded: 1925, palette: ["#5d3a22","#f0e6d2","#000000"] },
+  { name: "Givenchy",      country: "FR", founded: 1952, palette: ["#000000","#d4af37","#a01c1f"] },
+  { name: "Valentino",     country: "IT", founded: 1960, palette: ["#a01c1f","#1a1a1a","#f0e6d2"] },
+  { name: "Armani",        country: "IT", founded: 1975, palette: ["#1a1a2e","#8b8680","#000000"] },
+  { name: "Ralph Lauren",  country: "US", founded: 1967, palette: ["#1a3a6c","#a01c1f","#f0e6d2"] },
+  { name: "Tom Ford",      country: "US", founded: 2005, palette: ["#000000","#5d3a22","#d4af37"] },
+  { name: "Celine",        country: "FR", founded: 1945, palette: ["#000000","#d4b886","#ffffff"] },
+  { name: "Loewe",         country: "ES", founded: 1846, palette: ["#5d3a22","#d4b886","#1a1a1a"] },
+  { name: "Alexander McQueen", country: "UK", founded: 1992, palette: ["#000000","#a01c1f","#8b8680"] }
+];
+
+const WALL = [
+  { name: "Phillip Jeffries", country: "US", founded: 1976, palette: ["#d4b886","#5d3a22","#f0e6d2"] },
+  { name: "Schumacher",       country: "US", founded: 1889, palette: ["#a01c1f","#3d5a2c","#d4af37"] },
+  { name: "Cole & Son",       country: "UK", founded: 1875, palette: ["#1a3a6c","#c9a96e","#f0e6d2"] },
+  { name: "Thibaut",          country: "US", founded: 1886, palette: ["#3d5a2c","#c9a96e","#1a1a1a"] },
+  { name: "Zoffany",          country: "UK", founded: 1895, palette: ["#5d3a22","#d4b886","#3d5a2c"] },
+  { name: "Farrow & Ball",    country: "UK", founded: 1946, palette: ["#1a3a3a","#e8e4dc","#5d3a22"] },
+  { name: "Brunschwig & Fils",country: "US", founded: 1909, palette: ["#a01c1f","#1a3a6c","#d4b886"] },
+  { name: "de Gournay",       country: "UK", founded: 1986, palette: ["#c9a96e","#5d3a22","#3d5a2c"] },
+  { name: "Fromental",        country: "UK", founded: 2005, palette: ["#1a3a6c","#d4af37","#5d3a22"] },
+  { name: "Pierre Frey",      country: "FR", founded: 1935, palette: ["#a01c1f","#d4b886","#1a3a6c"] }
+];
+
+const state = { fashion: new Set(), wall: new Set() };
+
+function render() {
+  const make = (cat, list) => list.map((b,i) => {
+    const sel = state[cat].has(b.name) ? "selected" : "";
+    const swatches = b.palette.map(c => `<span class="swatch" style="background:${c}"></span>`).join("");
+    return `
+      <div class="card ${sel}" data-cat="${cat}" data-name="${b.name}">
+        <div class="check">✓</div>
+        <div>
+          <div class="name">${b.name}</div>
+          <div class="meta">
+            <span class="tag">${b.country}</span>
+            <span class="tag">est. ${b.founded}</span>
+          </div>
+        </div>
+        <div class="swatch-row">${swatches}</div>
+      </div>
+    `;
+  }).join("");
+
+  document.getElementById("grid-fashion").innerHTML = make("fashion", FASHION);
+  document.getElementById("grid-wall").innerHTML = make("wall", WALL);
+
+  document.getElementById("stat-fashion").textContent = state.fashion.size;
+  document.getElementById("stat-wall").textContent = state.wall.size;
+
+  const total = state.fashion.size + state.wall.size;
+  document.getElementById("dock-total").textContent = total;
+  const all = [...state.fashion, ...state.wall];
+  document.getElementById("dock-list").textContent = all.length ? all.join(" · ") : "none";
+}
+
+document.body.addEventListener("click", (e) => {
+  const card = e.target.closest(".card");
+  if (card) {
+    const cat = card.dataset.cat, name = card.dataset.name;
+    if (state[cat].has(name)) state[cat].delete(name); else state[cat].add(name);
+    render();
+    return;
+  }
+  const tb = e.target.closest("[data-action]");
+  if (tb) {
+    const cat = tb.dataset.cat, action = tb.dataset.action;
+    const list = cat === "fashion" ? FASHION : WALL;
+    if (action === "select-all") list.forEach(b => state[cat].add(b.name));
+    if (action === "clear") state[cat].clear();
+    if (action === "top5") { state[cat].clear(); list.slice(0,5).forEach(b => state[cat].add(b.name)); }
+    render();
+  }
+});
+
+document.getElementById("btn-clear-all").onclick = () => {
+  state.fashion.clear(); state.wall.clear(); render();
+};
+
+function buildPayload() {
+  const get = (cat, list) => list.filter(b => state[cat].has(b.name));
+  return {
+    schema: "figma-build/brand-selection.v1",
+    generated_at: new Date().toISOString(),
+    counts: { fashion: state.fashion.size, wallcovering: state.wall.size, total: state.fashion.size + state.wall.size },
+    fashion: get("fashion", FASHION),
+    wallcovering: get("wall", WALL)
+  };
+}
+
+document.getElementById("btn-preview").onclick = () => {
+  document.getElementById("modal-json").textContent = JSON.stringify(buildPayload(), null, 2);
+  document.getElementById("modal").classList.add("show");
+};
+document.getElementById("btn-figma").onclick = () => {
+  const payload = buildPayload();
+  if (payload.counts.total === 0) { toast("Select at least one brand", true); return; }
+  document.getElementById("modal-json").textContent = JSON.stringify(payload, null, 2);
+  document.getElementById("modal").classList.add("show");
+};
+document.getElementById("btn-close").onclick = () => document.getElementById("modal").classList.remove("show");
+document.getElementById("btn-copy").onclick = async () => {
+  await navigator.clipboard.writeText(document.getElementById("modal-json").textContent);
+  toast("Copied to clipboard");
+};
+document.getElementById("btn-download").onclick = () => {
+  const blob = new Blob([document.getElementById("modal-json").textContent], { type: "application/json" });
+  const url = URL.createObjectURL(blob);
+  const a = document.createElement("a");
+  a.href = url;
+  a.download = `brand-selection-${new Date().toISOString().slice(0,10)}.json`;
+  a.click();
+  URL.revokeObjectURL(url);
+};
+
+function toast(msg, isError) {
+  const t = document.getElementById("toast");
+  t.textContent = msg;
+  t.style.background = isError ? "var(--danger)" : "var(--ok)";
+  t.style.color = isError ? "#3a0d0d" : "#06280f";
+  t.classList.add("show");
+  setTimeout(() => t.classList.remove("show"), 1800);
+}
+
+render();
+</script>
+</body>
+</html>
diff --git a/magic-app.html b/magic-app.html
new file mode 100644
index 0000000..2a34c45
--- /dev/null
+++ b/magic-app.html
@@ -0,0 +1,234 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1" />
+<title>Magic · BrandSelector — live React</title>
+<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
+<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
+<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
+<script src="https://cdn.tailwindcss.com"></script>
+<script src="https://mcp.figma.com/mcp/html-to-design/capture.js" async></script>
+<style>
+  body { margin: 0; background: #0b0b0d; }
+  .font-serif { font-family: "Didot", "Bodoni 72", Georgia, serif; }
+  .font-sans  { font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; }
+</style>
+</head>
+<body>
+<div id="root"></div>
+
+<script type="text/babel" data-presets="env,react">
+const FASHION_20 = [
+  { name: "Louis Vuitton", country: "FR", founded: 1854, palette: ["#5d3a22", "#d4b886", "#1a1a1a"] },
+  { name: "Chanel",        country: "FR", founded: 1910, palette: ["#000000", "#ffffff", "#c9a96e"] },
+  { name: "Hermès",        country: "FR", founded: 1837, palette: ["#f37021", "#1a1a1a", "#f4e7d3"] },
+  { name: "Gucci",         country: "IT", founded: 1921, palette: ["#006341", "#a01c1f", "#d4af37"] },
+  { name: "Prada",         country: "IT", founded: 1913, palette: ["#000000", "#8b8680", "#e8e4dc"] },
+  { name: "Dior",          country: "FR", founded: 1946, palette: ["#1a1a1a", "#c8a883", "#ffffff"] },
+  { name: "Versace",       country: "IT", founded: 1978, palette: ["#d4af37", "#000000", "#a01c1f"] },
+  { name: "Burberry",      country: "UK", founded: 1856, palette: ["#a08661", "#000000", "#c1272d"] },
+  { name: "Saint Laurent", country: "FR", founded: 1961, palette: ["#000000", "#d4b886", "#ffffff"] },
+  { name: "Balenciaga",    country: "ES", founded: 1919, palette: ["#000000", "#5a5a5a", "#ffffff"] },
+  { name: "Bottega Veneta",country: "IT", founded: 1966, palette: ["#3d5a2c", "#c9b27a", "#1a1a1a"] },
+  { name: "Fendi",         country: "IT", founded: 1925, palette: ["#5d3a22", "#f0e6d2", "#000000"] },
+  { name: "Givenchy",      country: "FR", founded: 1952, palette: ["#000000", "#d4af37", "#a01c1f"] },
+  { name: "Valentino",     country: "IT", founded: 1960, palette: ["#a01c1f", "#1a1a1a", "#f0e6d2"] },
+  { name: "Armani",        country: "IT", founded: 1975, palette: ["#1a1a2e", "#8b8680", "#000000"] },
+  { name: "Ralph Lauren",  country: "US", founded: 1967, palette: ["#1a3a6c", "#a01c1f", "#f0e6d2"] },
+  { name: "Tom Ford",      country: "US", founded: 2005, palette: ["#000000", "#5d3a22", "#d4af37"] },
+  { name: "Celine",        country: "FR", founded: 1945, palette: ["#000000", "#d4b886", "#ffffff"] },
+  { name: "Loewe",         country: "ES", founded: 1846, palette: ["#5d3a22", "#d4b886", "#1a1a1a"] },
+  { name: "Alexander McQueen", country: "UK", founded: 1992, palette: ["#000000", "#a01c1f", "#8b8680"] },
+];
+
+const WALL_10 = [
+  { name: "Phillip Jeffries",  country: "US", founded: 1976, palette: ["#d4b886", "#5d3a22", "#f0e6d2"] },
+  { name: "Schumacher",        country: "US", founded: 1889, palette: ["#a01c1f", "#3d5a2c", "#d4af37"] },
+  { name: "Cole & Son",        country: "UK", founded: 1875, palette: ["#1a3a6c", "#c9a96e", "#f0e6d2"] },
+  { name: "Thibaut",           country: "US", founded: 1886, palette: ["#3d5a2c", "#c9a96e", "#1a1a1a"] },
+  { name: "Zoffany",           country: "UK", founded: 1895, palette: ["#5d3a22", "#d4b886", "#3d5a2c"] },
+  { name: "Farrow & Ball",     country: "UK", founded: 1946, palette: ["#1a3a3a", "#e8e4dc", "#5d3a22"] },
+  { name: "Brunschwig & Fils", country: "US", founded: 1909, palette: ["#a01c1f", "#1a3a6c", "#d4b886"] },
+  { name: "de Gournay",        country: "UK", founded: 1986, palette: ["#c9a96e", "#5d3a22", "#3d5a2c"] },
+  { name: "Fromental",         country: "UK", founded: 2005, palette: ["#1a3a6c", "#d4af37", "#5d3a22"] },
+  { name: "Pierre Frey",       country: "FR", founded: 1935, palette: ["#a01c1f", "#d4b886", "#1a3a6c"] },
+];
+
+function Tag({ children }) {
+  return (
+    <span className="text-[9.5px] tracking-[1.2px] uppercase text-zinc-500 border border-zinc-800 px-2 py-0.5 rounded-full font-sans">
+      {children}
+    </span>
+  );
+}
+
+function BrandCard({ brand, selected, onClick }) {
+  return (
+    <button
+      onClick={onClick}
+      className={[
+        "relative text-left rounded-2xl p-5 min-h-[140px] flex flex-col justify-between transition border",
+        selected
+          ? "border-amber-400 shadow-[inset_0_0_0_1px_rgba(212,175,55,1)]"
+          : "bg-zinc-900 border-zinc-800 hover:border-zinc-600 hover:-translate-y-0.5",
+      ].join(" ")}
+      style={selected ? { background: "linear-gradient(135deg, rgba(212,175,55,0.10), #1a1a22)" } : {}}
+    >
+      <span
+        className={[
+          "absolute top-3 right-3 w-5 h-5 rounded-full border flex items-center justify-center text-[11px]",
+          selected ? "bg-amber-400 border-amber-400 text-zinc-900" : "border-zinc-700 text-transparent",
+        ].join(" ")}
+      >
+        ✓
+      </span>
+      <div>
+        <div className="font-serif text-lg leading-tight pr-7 text-zinc-100">{brand.name}</div>
+        <div className="flex gap-1.5 mt-2.5">
+          <Tag>{brand.country}</Tag>
+          <Tag>est. {brand.founded}</Tag>
+        </div>
+      </div>
+      <div className="flex gap-1 mt-3">
+        {brand.palette.map((c) => (
+          <span key={c} className="w-4 h-4 rounded border border-white/10" style={{ background: c }} />
+        ))}
+      </div>
+    </button>
+  );
+}
+
+function Stat({ n, label }) {
+  return (
+    <div>
+      <div className="font-serif text-3xl text-amber-400 leading-none">{n}</div>
+      <div className="text-[10px] tracking-[2px] uppercase text-zinc-500 mt-1 font-sans">{label}</div>
+    </div>
+  );
+}
+
+function Section({ index, title, sub, brands, picked, onToggle, toolbar }) {
+  return (
+    <section className="px-10 pt-10">
+      <div className="flex items-end justify-between gap-5 mb-5">
+        <div>
+          <div className="text-[10px] tracking-[3px] uppercase text-amber-400 font-sans">{index}</div>
+          <h2 className="font-serif text-3xl mt-1 text-zinc-100">{title}</h2>
+          <div className="italic text-zinc-500 text-sm tracking-wide font-serif">{sub}</div>
+        </div>
+        {toolbar}
+      </div>
+      <div className="grid gap-3" style={{ gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))" }}>
+        {brands.map((b) => (
+          <BrandCard key={b.name} brand={b} selected={!!picked[b.name]} onClick={() => onToggle(b.name)} />
+        ))}
+      </div>
+    </section>
+  );
+}
+
+function Pill({ children, onClick, primary }) {
+  return (
+    <button
+      onClick={onClick}
+      className={[
+        "text-xs tracking-[0.5px] px-4 py-2 rounded-full font-sans transition",
+        primary
+          ? "bg-amber-400 text-zinc-900 hover:bg-amber-300 font-medium"
+          : "bg-zinc-900 border border-zinc-800 text-zinc-300 hover:border-zinc-600",
+      ].join(" ")}
+    >
+      {children}
+    </button>
+  );
+}
+
+function App() {
+  const [picked, setPicked] = React.useState({ Chanel: true, Versace: true, "Phillip Jeffries": true });
+  const [showJson, setShowJson] = React.useState(false);
+
+  const toggle = (name) => setPicked((p) => ({ ...p, [name]: !p[name] }));
+
+  const fashionPicked = FASHION_20.filter((b) => picked[b.name]);
+  const wallPicked = WALL_10.filter((b) => picked[b.name]);
+  const total = fashionPicked.length + wallPicked.length;
+  const all = [...fashionPicked, ...wallPicked];
+  const summary = all.length ? all.map((b) => b.name).join(" · ") : "none";
+
+  const buildPayload = () => ({
+    schema: "figma-build/brand-selection.v1",
+    generated_at: new Date().toISOString(),
+    counts: { fashion: fashionPicked.length, wallcovering: wallPicked.length, total },
+    fashion: fashionPicked,
+    wallcovering: wallPicked,
+  });
+
+  const fashionToolbar = (
+    <div className="flex gap-2">
+      <Pill onClick={() => setPicked((p) => { const n = { ...p }; FASHION_20.forEach((b) => (n[b.name] = true)); return n; })}>Select all 20</Pill>
+      <Pill onClick={() => setPicked((p) => { const n = { ...p }; FASHION_20.forEach((b) => (n[b.name] = false)); return n; })}>Clear</Pill>
+      <Pill onClick={() => setPicked((p) => { const n = { ...p }; FASHION_20.forEach((b, i) => (n[b.name] = i < 5)); return n; })}>Top 5 only</Pill>
+    </div>
+  );
+  const wallToolbar = (
+    <div className="flex gap-2">
+      <Pill onClick={() => setPicked((p) => { const n = { ...p }; WALL_10.forEach((b) => (n[b.name] = true)); return n; })}>Select all 10</Pill>
+      <Pill onClick={() => setPicked((p) => { const n = { ...p }; WALL_10.forEach((b) => (n[b.name] = false)); return n; })}>Clear</Pill>
+    </div>
+  );
+
+  return (
+    <div className="min-h-screen bg-[#0b0b0d] pb-32 font-sans">
+      <header className="px-10 pt-12 pb-6 border-b border-zinc-800 flex flex-wrap items-end justify-between gap-6">
+        <div>
+          <div className="flex items-center gap-2.5">
+            <span className="w-1.5 h-1.5 rounded-full bg-amber-400 inline-block" />
+            <span className="text-[10px] tracking-[3px] uppercase text-amber-400/90">Figma Build Source · v1 · live React</span>
+          </div>
+          <h1 className="font-serif text-5xl tracking-tight mt-2 text-zinc-100">Brand Selector</h1>
+          <p className="italic text-zinc-400 mt-1 font-serif">Pick the labels that will source the next Figma build · Top 20 fashion · Top 10 wallcovering</p>
+        </div>
+        <div className="flex gap-12 text-right">
+          <Stat n={fashionPicked.length} label="Fashion" />
+          <Stat n={wallPicked.length} label="Wallcovering" />
+        </div>
+      </header>
+
+      <Section index="I."  title="Fashion"      sub="Top 20 — Luxury & Iconic Houses"  brands={FASHION_20} picked={picked} onToggle={toggle} toolbar={fashionToolbar} />
+      <Section index="II." title="Wallcovering" sub="Top 10 — Heritage & Designer Houses" brands={WALL_10}    picked={picked} onToggle={toggle} toolbar={wallToolbar} />
+
+      <div className="fixed bottom-0 inset-x-0 backdrop-blur border-t border-zinc-800 px-10 py-3 flex items-center justify-between gap-4" style={{ background: "rgba(11,11,13,0.92)" }}>
+        <div className="flex gap-3 items-center text-sm">
+          <span className="bg-zinc-900 px-3 py-1.5 rounded-full text-zinc-400">
+            <b className="text-amber-400 font-serif text-base mr-1">{total}</b>selected
+          </span>
+          <span className="text-zinc-500 truncate max-w-[600px]">{summary}</span>
+        </div>
+        <div className="flex gap-2">
+          <Pill onClick={() => setPicked({})}>Clear all</Pill>
+          <Pill onClick={() => setShowJson(true)}>Preview JSON</Pill>
+          <Pill primary onClick={() => setShowJson(true)}>Send to Figma Build →</Pill>
+        </div>
+      </div>
+
+      {showJson && (
+        <div className="fixed inset-0 z-50 bg-black/75 flex items-center justify-center p-6" onClick={() => setShowJson(false)}>
+          <div className="bg-zinc-900 border border-zinc-800 rounded-xl p-6 max-w-3xl w-full max-h-[85vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
+            <h3 className="font-serif text-xl text-zinc-100 mb-3">Figma build payload</h3>
+            <pre className="bg-black border border-zinc-800 rounded p-4 overflow-auto text-xs leading-relaxed text-zinc-300 flex-1">{JSON.stringify(buildPayload(), null, 2)}</pre>
+            <div className="flex gap-2 justify-end mt-4">
+              <Pill onClick={() => navigator.clipboard.writeText(JSON.stringify(buildPayload(), null, 2))}>Copy JSON</Pill>
+              <Pill primary onClick={() => setShowJson(false)}>Close</Pill>
+            </div>
+          </div>
+        </div>
+      )}
+    </div>
+  );
+}
+
+ReactDOM.createRoot(document.getElementById("root")).render(<App />);
+</script>
+</body>
+</html>
diff --git a/outputs/canva-brief.md b/outputs/canva-brief.md
new file mode 100644
index 0000000..3aee305
--- /dev/null
+++ b/outputs/canva-brief.md
@@ -0,0 +1,44 @@
+# Canva Brief — Brand Selector Launch Tile
+
+**Project:** Brand Selector — Figma Build Source
+**Channels:** Instagram (1080×1350), LinkedIn (1200×628), Email header (1200×400)
+**Brand template:** create new template `dw-brand-selector-v1` once Connect API auth is live.
+
+## Composition
+
+- **Background:** flat `#0b0b0d` with subtle 1% film grain.
+- **Headline (centered, top third):** "Brand Selector" — Didot, 96 px, `#f4f4f5`.
+- **Eyebrow above headline:** "Figma Build Source · v1" — Inter, 12 px, 3 px tracking, `#d4af37`.
+- **Subhead:** "Top 20 fashion · Top 10 wallcovering" — Cormorant Garamond Italic, 24 px, `#9c9caa`.
+- **Visual core:** 6×5 grid of brand-name plates (no logos — typographic wordmarks only, see Note).
+- **Footer ribbon:** thin `#2a2a35` rule + `#d4af37` dot + "designerwallcoverings.com / build" — Inter, 11 px.
+
+## Autofill fields (Connect API · `create-design-autofill-job`)
+
+| Field            | Type   | Source                                            |
+|------------------|--------|---------------------------------------------------|
+| `headline`       | text   | "Brand Selector"                                  |
+| `eyebrow`        | text   | static "Figma Build Source · v1"                  |
+| `count_fashion`  | text   | `payload.counts.fashion`                          |
+| `count_wall`     | text   | `payload.counts.wallcovering`                     |
+| `selected_list`  | text   | join `payload.fashion.name + payload.wallcovering.name` with " · " |
+| `accent_color`   | color  | static `#d4af37`                                  |
+
+## Asset list (export job)
+
+| Format | Size       | Purpose                |
+|--------|------------|------------------------|
+| PNG    | 1080×1350  | Instagram feed         |
+| PNG    | 1080×1920  | Story / Reel cover     |
+| JPG    | 1200×628   | LinkedIn / OG image    |
+| PDF    | letter     | Internal one-pager     |
+
+## Note on logos
+
+Canva, Magic, and most logo libraries do **not** carry trademarked luxury brand wordmarks (LV, Chanel, Hermès, etc.). We render brand names as **Didot wordmarks** at the same color as body copy — the typography itself becomes the visual signature. This is also the cleanest path through Canva brand-template review.
+
+## Status
+
+- `canva login` not yet confirmed for this machine. Run `canva login` in terminal to enable Connect API calls.
+- Once authenticated, this brief becomes a `POST /v1/autofills` payload against template `dw-brand-selector-v1`.
+- Source of truth for colors/type stays in `outputs/figma-tokens.json`. Don't redefine in the Canva template.
diff --git a/outputs/figma-tokens.json b/outputs/figma-tokens.json
new file mode 100644
index 0000000..34b3c9b
--- /dev/null
+++ b/outputs/figma-tokens.json
@@ -0,0 +1,109 @@
+{
+  "$schema": "https://schemas.figma.com/tokens/v1.json",
+  "name": "Brand Selector — Figma Build Source",
+  "description": "Design tokens for the Brand Selector. Paste into Figma Tokens / Variables plugin.",
+  "version": "1.0.0",
+  "color": {
+    "bg": {
+      "base":   { "value": "#0b0b0d" },
+      "panel":  { "value": "#131318" },
+      "raised": { "value": "#1a1a22" }
+    },
+    "line":     { "value": "#2a2a35" },
+    "text": {
+      "primary":   { "value": "#f4f4f5" },
+      "secondary": { "value": "#9c9caa" },
+      "inverse":   { "value": "#111111" }
+    },
+    "accent": {
+      "gold":     { "value": "#d4af37" },
+      "goldDeep": { "value": "#c89b3d" }
+    },
+    "state": {
+      "success": { "value": "#4ade80" },
+      "danger":  { "value": "#f87171" }
+    }
+  },
+  "typography": {
+    "display": {
+      "family":   { "value": "Didot" },
+      "weight":   { "value": 400 },
+      "size":     { "value": "48px" },
+      "tracking": { "value": "-0.5px" },
+      "leading":  { "value": "1.05" }
+    },
+    "title": {
+      "family":  { "value": "Didot" },
+      "weight":  { "value": 400 },
+      "size":    { "value": "32px" },
+      "leading": { "value": "1.1" }
+    },
+    "subhead": {
+      "family":  { "value": "Cormorant Garamond" },
+      "weight":  { "value": 400 },
+      "italic":  { "value": true },
+      "size":    { "value": "16px" }
+    },
+    "eyebrow": {
+      "family":   { "value": "Inter" },
+      "weight":   { "value": 500 },
+      "size":     { "value": "10px" },
+      "tracking": { "value": "3px" },
+      "case":     { "value": "uppercase" }
+    },
+    "body": {
+      "family":  { "value": "Inter" },
+      "weight":  { "value": 400 },
+      "size":    { "value": "13px" },
+      "leading": { "value": "1.5" }
+    },
+    "tag": {
+      "family":   { "value": "Inter" },
+      "weight":   { "value": 500 },
+      "size":     { "value": "9.5px" },
+      "tracking": { "value": "1.2px" },
+      "case":     { "value": "uppercase" }
+    }
+  },
+  "radius": {
+    "card":   { "value": "14px" },
+    "pill":   { "value": "999px" },
+    "swatch": { "value": "4px" }
+  },
+  "spacing": {
+    "xs":  { "value": "4px" },
+    "sm":  { "value": "8px" },
+    "md":  { "value": "14px" },
+    "lg":  { "value": "24px" },
+    "xl":  { "value": "40px" },
+    "2xl": { "value": "64px" }
+  },
+  "components": {
+    "BrandCard": {
+      "default": {
+        "background": "{color.bg.panel}",
+        "border":     "1px solid {color.line}",
+        "radius":     "{radius.card}",
+        "padding":    "18px"
+      },
+      "selected": {
+        "background": "linear-gradient(135deg, rgba(212,175,55,0.08), {color.bg.raised})",
+        "border":     "1px solid {color.accent.gold}",
+        "shadow":     "inset 0 0 0 1px {color.accent.gold}"
+      }
+    },
+    "Dock": {
+      "background": "rgba(11,11,13,0.92)",
+      "blur":       "14px",
+      "border":     "1px solid {color.line}",
+      "padding":    "14px 40px"
+    },
+    "PrimaryCTA": {
+      "background": "{color.accent.gold}",
+      "color":      "{color.text.inverse}",
+      "radius":     "{radius.pill}",
+      "padding":    "8px 14px"
+    }
+  },
+  "schema_handoff": "figma-build/brand-selection.v1"
+}
diff --git a/outputs/magic-BrandSelector.tsx b/outputs/magic-BrandSelector.tsx
new file mode 100644
index 0000000..da5a23d
--- /dev/null
+++ b/outputs/magic-BrandSelector.tsx
@@ -0,0 +1,189 @@
+// Generated via 21st.dev Magic — Brand Selector
+// Drop into a React/Tailwind project. Self-contained; props-driven.
+// Pairs with Paper editorial spec + Figma design tokens.
+
+import { useMemo, useState } from "react";
+
+export type Brand = {
+  name: string;
+  country: string;
+  founded: number;
+  palette: [string, string, string];
+};
+
+export type BrandPayload = {
+  schema: "figma-build/brand-selection.v1";
+  generated_at: string;
+  counts: { fashion: number; wallcovering: number; total: number };
+  fashion: Brand[];
+  wallcovering: Brand[];
+};
+
+export const FASHION_20: Brand[] = [
+  { name: "Louis Vuitton", country: "FR", founded: 1854, palette: ["#5d3a22", "#d4b886", "#1a1a1a"] },
+  { name: "Chanel",        country: "FR", founded: 1910, palette: ["#000000", "#ffffff", "#c9a96e"] },
+  { name: "Hermès",        country: "FR", founded: 1837, palette: ["#f37021", "#1a1a1a", "#f4e7d3"] },
+  { name: "Gucci",         country: "IT", founded: 1921, palette: ["#006341", "#a01c1f", "#d4af37"] },
+  { name: "Prada",         country: "IT", founded: 1913, palette: ["#000000", "#8b8680", "#e8e4dc"] },
+  { name: "Dior",          country: "FR", founded: 1946, palette: ["#1a1a1a", "#c8a883", "#ffffff"] },
+  { name: "Versace",       country: "IT", founded: 1978, palette: ["#d4af37", "#000000", "#a01c1f"] },
+  { name: "Burberry",      country: "UK", founded: 1856, palette: ["#a08661", "#000000", "#c1272d"] },
+  { name: "Saint Laurent", country: "FR", founded: 1961, palette: ["#000000", "#d4b886", "#ffffff"] },
+  { name: "Balenciaga",    country: "ES", founded: 1919, palette: ["#000000", "#5a5a5a", "#ffffff"] },
+  { name: "Bottega Veneta",country: "IT", founded: 1966, palette: ["#3d5a2c", "#c9b27a", "#1a1a1a"] },
+  { name: "Fendi",         country: "IT", founded: 1925, palette: ["#5d3a22", "#f0e6d2", "#000000"] },
+  { name: "Givenchy",      country: "FR", founded: 1952, palette: ["#000000", "#d4af37", "#a01c1f"] },
+  { name: "Valentino",     country: "IT", founded: 1960, palette: ["#a01c1f", "#1a1a1a", "#f0e6d2"] },
+  { name: "Armani",        country: "IT", founded: 1975, palette: ["#1a1a2e", "#8b8680", "#000000"] },
+  { name: "Ralph Lauren",  country: "US", founded: 1967, palette: ["#1a3a6c", "#a01c1f", "#f0e6d2"] },
+  { name: "Tom Ford",      country: "US", founded: 2005, palette: ["#000000", "#5d3a22", "#d4af37"] },
+  { name: "Celine",        country: "FR", founded: 1945, palette: ["#000000", "#d4b886", "#ffffff"] },
+  { name: "Loewe",         country: "ES", founded: 1846, palette: ["#5d3a22", "#d4b886", "#1a1a1a"] },
+  { name: "Alexander McQueen", country: "UK", founded: 1992, palette: ["#000000", "#a01c1f", "#8b8680"] },
+];
+
+export const WALL_10: Brand[] = [
+  { name: "Phillip Jeffries",  country: "US", founded: 1976, palette: ["#d4b886", "#5d3a22", "#f0e6d2"] },
+  { name: "Schumacher",        country: "US", founded: 1889, palette: ["#a01c1f", "#3d5a2c", "#d4af37"] },
+  { name: "Cole & Son",        country: "UK", founded: 1875, palette: ["#1a3a6c", "#c9a96e", "#f0e6d2"] },
+  { name: "Thibaut",           country: "US", founded: 1886, palette: ["#3d5a2c", "#c9a96e", "#1a1a1a"] },
+  { name: "Zoffany",           country: "UK", founded: 1895, palette: ["#5d3a22", "#d4b886", "#3d5a2c"] },
+  { name: "Farrow & Ball",     country: "UK", founded: 1946, palette: ["#1a3a3a", "#e8e4dc", "#5d3a22"] },
+  { name: "Brunschwig & Fils", country: "US", founded: 1909, palette: ["#a01c1f", "#1a3a6c", "#d4b886"] },
+  { name: "de Gournay",        country: "UK", founded: 1986, palette: ["#c9a96e", "#5d3a22", "#3d5a2c"] },
+  { name: "Fromental",         country: "UK", founded: 2005, palette: ["#1a3a6c", "#d4af37", "#5d3a22"] },
+  { name: "Pierre Frey",       country: "FR", founded: 1935, palette: ["#a01c1f", "#d4b886", "#1a3a6c"] },
+];
+
+type Props = {
+  fashion?: Brand[];
+  wallcovering?: Brand[];
+  onSubmit?: (payload: BrandPayload) => void;
+};
+
+export default function BrandSelector({
+  fashion = FASHION_20,
+  wallcovering = WALL_10,
+  onSubmit,
+}: Props) {
+  const [picked, setPicked] = useState<Record<string, boolean>>({});
+
+  const toggle = (name: string) =>
+    setPicked((p) => ({ ...p, [name]: !p[name] }));
+
+  const buildPayload = (): BrandPayload => {
+    const f = fashion.filter((b) => picked[b.name]);
+    const w = wallcovering.filter((b) => picked[b.name]);
+    return {
+      schema: "figma-build/brand-selection.v1",
+      generated_at: new Date().toISOString(),
+      counts: { fashion: f.length, wallcovering: w.length, total: f.length + w.length },
+      fashion: f,
+      wallcovering: w,
+    };
+  };
+
+  const summary = useMemo(() => {
+    const all = [...fashion, ...wallcovering].filter((b) => picked[b.name]);
+    return { count: all.length, names: all.map((b) => b.name).join(" · ") || "none" };
+  }, [picked, fashion, wallcovering]);
+
+  return (
+    <div className="min-h-screen bg-[#0b0b0d] text-zinc-100 pb-32 font-sans">
+      <header className="px-10 pt-12 pb-6 border-b border-zinc-800 flex flex-wrap items-end justify-between gap-6">
+        <div>
+          <div className="text-[10px] tracking-[3px] uppercase text-amber-400/80">Figma Build Source · v1</div>
+          <h1 className="font-serif text-5xl tracking-tight mt-2">Brand Selector</h1>
+          <p className="italic text-zinc-400 mt-1">Pick the labels that will source the next Figma build · Top 20 fashion · Top 10 wallcovering</p>
+        </div>
+        <div className="flex gap-12 text-right">
+          <Stat n={fashion.filter((b) => picked[b.name]).length} label="Fashion" />
+          <Stat n={wallcovering.filter((b) => picked[b.name]).length} label="Wallcovering" />
+        </div>
+      </header>
+
+      <Section index="I." title="Fashion" sub="Top 20 — Luxury & Iconic Houses" brands={fashion} picked={picked} onToggle={toggle} />
+      <Section index="II." title="Wallcovering" sub="Top 10 — Heritage & Designer Houses" brands={wallcovering} picked={picked} onToggle={toggle} />
+
+      <div className="fixed bottom-0 inset-x-0 bg-[#0b0b0d]/90 backdrop-blur border-t border-zinc-800 px-10 py-3 flex items-center justify-between gap-4">
+        <div className="flex gap-3 items-center text-sm">
+          <span className="bg-zinc-900 px-3 py-1.5 rounded-full"><b className="text-amber-400 font-serif mr-1">{summary.count}</b> selected</span>
+          <span className="text-zinc-500 truncate max-w-[600px]">{summary.names}</span>
+        </div>
+        <button
+          onClick={() => onSubmit?.(buildPayload())}
+          className="bg-amber-400 text-zinc-900 px-5 py-2 rounded-full text-sm font-medium hover:bg-amber-300 transition"
+        >
+          Send to Figma Build →
+        </button>
+      </div>
+    </div>
+  );
+}
+
+function Stat({ n, label }: { n: number; label: string }) {
+  return (
+    <div>
+      <div className="font-serif text-3xl text-amber-400 leading-none">{n}</div>
+      <div className="text-[10px] tracking-[2px] uppercase text-zinc-500 mt-1">{label}</div>
+    </div>
+  );
+}
+
+function Section({
+  index, title, sub, brands, picked, onToggle,
+}: { index: string; title: string; sub: string; brands: Brand[]; picked: Record<string, boolean>; onToggle: (n: string) => void; }) {
+  return (
+    <section className="px-10 pt-12">
+      <div className="mb-5">
+        <div className="text-[10px] tracking-[3px] uppercase text-amber-400">{index}</div>
+        <h2 className="font-serif text-3xl mt-1">{title}</h2>
+        <div className="italic text-zinc-500 text-sm tracking-wide">{sub}</div>
+      </div>
+      <div className="grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-3">
+        {brands.map((b) => (
+          <BrandCard key={b.name} brand={b} selected={!!picked[b.name]} onClick={() => onToggle(b.name)} />
+        ))}
+      </div>
+    </section>
+  );
+}
+
+function BrandCard({ brand, selected, onClick }: { brand: Brand; selected: boolean; onClick: () => void }) {
+  return (
+    <button
+      onClick={onClick}
+      className={[
+        "relative text-left rounded-2xl p-5 min-h-[140px] flex flex-col justify-between transition border",
+        selected
+          ? "bg-gradient-to-br from-amber-400/10 to-zinc-900 border-amber-400 shadow-[inset_0_0_0_1px_rgba(212,175,55,1)]"
+          : "bg-zinc-900 border-zinc-800 hover:border-zinc-600 hover:-translate-y-0.5",
+      ].join(" ")}
+    >
+      <span className={[
+        "absolute top-3 right-3 w-5 h-5 rounded-full border flex items-center justify-center text-[11px]",
+        selected ? "bg-amber-400 border-amber-400 text-zinc-900" : "border-zinc-700 text-transparent",
+      ].join(" ")}>✓</span>
+      <div>
+        <div className="font-serif text-lg leading-tight pr-7">{brand.name}</div>
+        <div className="flex gap-1.5 mt-2.5">
+          <Tag>{brand.country}</Tag>
+          <Tag>est. {brand.founded}</Tag>
+        </div>
+      </div>
+      <div className="flex gap-1 mt-3">
+        {brand.palette.map((c) => (
+          <span key={c} className="w-4 h-4 rounded border border-white/10" style={{ background: c }} />
+        ))}
+      </div>
+    </button>
+  );
+}
+
+function Tag({ children }: { children: React.ReactNode }) {
+  return (
+    <span className="text-[9.5px] tracking-[1.2px] uppercase text-zinc-500 border border-zinc-800 px-2 py-0.5 rounded-full">
+      {children}
+    </span>
+  );
+}
diff --git a/outputs/paper-summary.md b/outputs/paper-summary.md
new file mode 100644
index 0000000..bbc064a
--- /dev/null
+++ b/outputs/paper-summary.md
@@ -0,0 +1,34 @@
+# Paper Output
+
+**File:** novasuede
+**File URL:** https://app.paper.design/file/01KQA7KRG8FDP7RH2WXPJYDFNQ
+**Artboard:** "Brand Selector — Figma Build Source" (1440 × fit-content, dark editorial)
+**Status:** Complete
+
+## What's on the canvas
+
+- **Header** (60 px / 64 px padding, hairline rule): gold dot eyebrow `Figma Build Source · v1`, Didot 64 display title, Cormorant Garamond italic subhead, two right-aligned stats (`20 Fashion`, `10 Wallcovering`) in Didot 48 / `#d4af37`.
+- **Section I — Fashion**: gold roman numeral `I.`, Didot 36 title, italic subhead, toolbar (`Select all 20` · `Clear` · `Top 5 only` highlighted gold). Grid of 20 brand cards in 4 rows × 5 cols (or wrap-flex, ~262 px wide each, gap 14). **Chanel** and **Versace** rendered in selected state (gold border + gradient + filled checkmark).
+- **Section II — Wallcovering**: matching `II.` eyebrow, title, subhead, toolbar (`Select all 10` · `Clear`). Grid of 10 brand cards in 2 rows × 5 cols. **Phillip Jeffries** rendered in selected state.
+- **Sticky dock** at the bottom: dark glass panel, two pills (`3 selected` with gold count, `Chanel · Versace · Phillip Jeffries` truncating list), three actions (`Clear all` · `Preview JSON` · `Send to Figma Build →` filled gold).
+
+## Brand cards on the canvas (30)
+
+**Fashion (20):** Louis Vuitton · Chanel ✓ · Hermès · Gucci · Prada · Dior · Versace ✓ · Burberry · Saint Laurent · Balenciaga · Bottega Veneta · Fendi · Givenchy · Valentino · Armani · Ralph Lauren · Tom Ford · Celine · Loewe · Alexander McQueen
+
+**Wallcovering (10):** Phillip Jeffries ✓ · Schumacher · Cole & Son · Thibaut · Zoffany · Farrow & Ball · Brunschwig & Fils · de Gournay · Fromental · Pierre Frey
+
+Each card carries: Didot 19 brand name (right-padded for the check circle), country pill, founding-year pill, and a 3-swatch palette row at the bottom drawn from the brand's signature colors.
+
+## Token alignment
+
+The artboard reads exactly the same tokens as `outputs/figma-tokens.json`:
+- `#0b0b0d` artboard, `#131318` card, `#1a1a22` raised
+- `#2a2a35` line, `#9c9caa` muted text, `#f4f4f5` primary
+- `#d4af37` gold accent (selected border + dock CTA + numerals)
+- 14 px card radius, 999 px pill radius, 4 px swatch radius
+- Didot for display/title/card name, Cormorant Garamond italic for subheads, Inter for tags + body
+
+## Why Paper, not Figma, owns this stage
+
+Paper is the prototype-velocity tool — the artboard was built incrementally so the user saw real-time visual progress. Now that the layout is settled, Figma will own the design tokens (`figma-tokens.json`), Magic owns the production component (`magic-BrandSelector.tsx`), and Canva owns the marketing exports (`canva-brief.md`). Paper is the design lab; the others are the systems of record.

(oldest)  ·  back to Brand Selector Viewer  ·  Remove unused index param from card render map 53e8749 →